diff --git a/app/routes/acls/acl-action.ts b/app/routes/acls/acl-action.ts index 3cf680b..bd946ae 100644 --- a/app/routes/acls/acl-action.ts +++ b/app/routes/acls/acl-action.ts @@ -1,40 +1,35 @@ -import { ActionFunctionArgs, data } from 'react-router'; -import { LoadContext } from '~/server'; +import { data } from 'react-router'; import ResponseError from '~/server/headscale/api/response-error'; import { Capabilities } from '~/server/web/roles'; -import { data400, data403 } from '~/utils/res'; +import type { Route } from './+types/overview'; // We only check capabilities here and assume it is writable // If it isn't, it'll gracefully error anyways, since this means some // fishy client manipulation is happening. -export async function aclAction({ - request, - context, -}: ActionFunctionArgs) { +export async function aclAction({ request, context }: Route.ActionArgs) { const session = await context.sessions.auth(request); const check = await context.sessions.check( request, Capabilities.write_policy, ); if (!check) { - throw data403('You do not have permission to write to the ACL policy'); + throw data('You do not have permission to write to the ACL policy', { + status: 403, + }); } // Try to write to the ACL policy via the API or via config file (TODO). const formData = await request.formData(); const policyData = formData.get('policy')?.toString(); if (!policyData) { - throw data400('Missing `policy` in the form data.'); + throw data('Missing `policy` in the form data.', { + status: 400, + }); } + const api = context.hsApi.getRuntimeClient(session.api_key); try { - const { policy, updatedAt } = await context.client.put<{ - policy: string; - updatedAt: string; - }>('v1/policy', session.api_key, { - policy: policyData, - }); - + const { policy, updatedAt } = await api.setPolicy(policyData); return data({ success: true, error: undefined, @@ -50,7 +45,7 @@ export async function aclAction({ // https://github.com/juanfont/headscale/blob/main/hscontrol/types/policy.go if (message.includes('update is disabled')) { // This means the policy is not writable - throw data403('Policy is not writable'); + throw data('Policy is not writable', { status: 403 }); } // https://github.com/juanfont/headscale/blob/main/hscontrol/policy/v1/acls.go#L81 diff --git a/app/routes/acls/acl-loader.ts b/app/routes/acls/acl-loader.ts index 3bbe91f..e8c7bea 100644 --- a/app/routes/acls/acl-loader.ts +++ b/app/routes/acls/acl-loader.ts @@ -1,8 +1,7 @@ -import { LoaderFunctionArgs } from 'react-router'; -import { LoadContext } from '~/server'; +import { data } from 'react-router'; import ResponseError from '~/server/headscale/api/response-error'; import { Capabilities } from '~/server/web/roles'; -import { data403 } from '~/utils/res'; +import type { Route } from './+types/overview'; // The logic for deciding policy factors is very complicated because // there are so many factors that need to be accounted for: @@ -11,15 +10,13 @@ import { data403 } from '~/utils/res'; // 3. Is the Headscale policy in file or database mode? // If database, we can read/write easily via the API. // If in file mode, we can only write if context.config is available. -// TODO: Consider adding back file editing mode instead of database -export async function aclLoader({ - request, - context, -}: LoaderFunctionArgs) { +export async function aclLoader({ request, context }: Route.LoaderArgs) { const session = await context.sessions.auth(request); const check = await context.sessions.check(request, Capabilities.read_policy); if (!check) { - throw data403('You do not have permission to read the ACL policy.'); + throw data('You do not have permission to read the ACL policy.', { + status: 403, + }); } const flags = { @@ -30,11 +27,9 @@ export async function aclLoader({ }; // Try to load the ACL policy from the API. + const api = context.hsApi.getRuntimeClient(session.api_key); try { - const { policy, updatedAt } = await context.client.get<{ - policy: string; - updatedAt: string | null; - }>('v1/policy', session.api_key); + const { policy, updatedAt } = await api.getPolicy(); // Successfully loaded the policy, mark it as readable // If `updatedAt` is null, it means the policy is in file mode. diff --git a/app/routes/acls/components/cm.client.tsx b/app/routes/acls/components/cm.client.tsx index d35b945..cf54c8c 100644 --- a/app/routes/acls/components/cm.client.tsx +++ b/app/routes/acls/components/cm.client.tsx @@ -38,14 +38,14 @@ export function Editor(props: EditorProps) { }> {() => ( props.onChange(value)} + readOnly={props.isDisabled} style={{ height: '100%' }} theme={light ? xcodeLight : xcodeDark} - onChange={(value) => props.onChange(value)} + value={props.value} /> )} @@ -92,14 +92,14 @@ export function Differ(props: DifferProps) { {() => ( )} diff --git a/app/routes/acls/components/fallback.tsx b/app/routes/acls/components/fallback.tsx index de6b24c..aa79ed1 100644 --- a/app/routes/acls/components/fallback.tsx +++ b/app/routes/acls/components/fallback.tsx @@ -23,12 +23,12 @@ export default function Fallback({ acl }: Props) { />