import { type ActionFunctionArgs } from '@remix-run/node' import { json, useLoaderData } from '@remix-run/react' import Code from '~/components/Code' import Notice from '~/components/Notice' import { loadContext } from '~/utils/config/headplane' import { loadConfig, patchConfig } from '~/utils/config/headscale' import { getSession } from '~/utils/sessions' import { useLiveData } from '~/utils/useLiveData' import DNS from './dns' import Domains from './domains' import MagicModal from './magic' import Nameservers from './nameservers' import RenameModal from './rename' // We do not want to expose every config value export async function loader() { const context = await loadContext() if (!context.config.read) { throw new Error('No configuration is available') } const config = await loadConfig() const dns = { prefixes: config.prefixes, magicDns: config.dns.magic_dns, baseDomain: config.dns.use_username_in_magic_dns ? `[user].${config.dns.base_domain}` : config.dns.base_domain, nameservers: config.dns.nameservers.global, splitDns: config.dns.nameservers.split, searchDomains: config.dns.search_domains, extraRecords: config.dns.extra_records, } return { ...dns, ...context, } } export async function action({ request }: ActionFunctionArgs) { const session = await getSession(request.headers.get('Cookie')) if (!session.has('hsApiKey')) { return send({ success: false }, 401) } const context = await loadContext() if (!context.config.write) { return send({ success: false }, 403) } const data = await request.json() as Record await patchConfig(data) if (context.integration?.onConfigChange) { await context.integration.onConfigChange(context.integration.context) } return { success: true } } export default function Page() { useLiveData({ interval: 5000 }) const data = useLoaderData() const allNs: Record = {} for (const key of Object.keys(data.splitDns)) { allNs[key] = data.splitDns[key] } allNs.global = data.nameservers return (
{data.config.write ? undefined : ( The Headscale configuration is read-only. You cannot make changes to the configuration )}

Magic DNS

Automatically register domain names for each device on the tailnet. Devices will be accessible at {' '} [device]. {data.baseDomain} {' '} when Magic DNS is enabled.

) }