import { XCircleFillIcon } from '@primer/octicons-react'; import { type LoaderFunctionArgs, redirect } from 'react-router'; import { Outlet, useLoaderData } from 'react-router'; import { ErrorPopup } from '~/components/Error'; import type { LoadContext } from '~/server'; import ResponseError from '~/server/headscale/api-error'; import cn from '~/utils/cn'; import log from '~/utils/log'; export async function loader({ request, context, }: LoaderFunctionArgs) { const healthy = await context.client.healthcheck(); const session = await context.sessions.auth(request); // We shouldn't session invalidate if Headscale is down // TODO: Notify in the logs or the UI that OIDC auth key is wrong if enabled if (healthy) { try { await context.client.get('v1/apikey', session.get('api_key')!); } catch (error) { if (error instanceof ResponseError) { log.debug('api', 'API Key validation failed %o', error); return redirect('/login', { headers: { 'Set-Cookie': await context.sessions.destroy(session), }, }); } } } return { healthy, }; } export default function Layout() { const { healthy } = useLoaderData(); return ( <> {!healthy ? (
Headscale is unreachable
) : undefined}
); } export function ErrorBoundary() { return ; }