mirror of
https://github.com/tale/headplane.git
synced 2026-09-03 10:48:17 +00:00
feat: update to the v8 middleware api
This commit is contained in:
@@ -1,18 +1,29 @@
|
||||
import { data } from "react-router";
|
||||
|
||||
import {
|
||||
authContext,
|
||||
headscaleConfigContext,
|
||||
headscaleContext,
|
||||
integrationContext,
|
||||
} from "~/server/context";
|
||||
import { Capabilities } from "~/server/web/roles";
|
||||
|
||||
import type { Route } from "./+types/overview";
|
||||
|
||||
export async function dnsAction({ request, context }: Route.ActionArgs) {
|
||||
const principal = await context.auth.require(request);
|
||||
const check = context.auth.can(principal, Capabilities.write_network);
|
||||
const auth = context.get(authContext);
|
||||
const headscale = context.get(headscaleContext);
|
||||
const headscaleConfig = context.get(headscaleConfigContext);
|
||||
const integration = context.get(integrationContext);
|
||||
|
||||
const principal = await auth.require(request);
|
||||
const check = auth.can(principal, Capabilities.write_network);
|
||||
|
||||
if (!check) {
|
||||
return data({ success: false }, 403);
|
||||
}
|
||||
|
||||
if (!context.hs.writable()) {
|
||||
if (!headscaleConfig.writable()) {
|
||||
return data({ success: false }, 403);
|
||||
}
|
||||
|
||||
@@ -29,14 +40,14 @@ export async function dnsAction({ request, context }: Route.ActionArgs) {
|
||||
return data({ success: false }, 400);
|
||||
}
|
||||
|
||||
await context.hs.patch([
|
||||
await headscaleConfig.patch([
|
||||
{
|
||||
path: "dns.base_domain",
|
||||
value: newName,
|
||||
},
|
||||
]);
|
||||
|
||||
await context.integration?.onConfigChange(context.headscale);
|
||||
await integration?.onConfigChange(headscale);
|
||||
return { message: "Tailnet renamed successfully" };
|
||||
}
|
||||
case "toggle_magic": {
|
||||
@@ -45,18 +56,18 @@ export async function dnsAction({ request, context }: Route.ActionArgs) {
|
||||
return data({ success: false }, 400);
|
||||
}
|
||||
|
||||
await context.hs.patch([
|
||||
await headscaleConfig.patch([
|
||||
{
|
||||
path: "dns.magic_dns",
|
||||
value: newState === "enabled",
|
||||
},
|
||||
]);
|
||||
|
||||
await context.integration?.onConfigChange(context.headscale);
|
||||
await integration?.onConfigChange(headscale);
|
||||
return { message: "Magic DNS state updated successfully" };
|
||||
}
|
||||
case "remove_ns": {
|
||||
const config = context.hs.c!;
|
||||
const config = headscaleConfig.c!;
|
||||
const ns = formData.get("ns")?.toString();
|
||||
const splitName = formData.get("split_name")?.toString();
|
||||
|
||||
@@ -67,7 +78,7 @@ export async function dnsAction({ request, context }: Route.ActionArgs) {
|
||||
if (splitName === "global") {
|
||||
const servers = config.dns.nameservers.global.filter((i) => i !== ns);
|
||||
|
||||
await context.hs.patch([
|
||||
await headscaleConfig.patch([
|
||||
{
|
||||
path: "dns.nameservers.global",
|
||||
value: servers,
|
||||
@@ -77,7 +88,7 @@ export async function dnsAction({ request, context }: Route.ActionArgs) {
|
||||
const splits = config.dns.nameservers.split;
|
||||
const servers = splits[splitName].filter((i) => i !== ns);
|
||||
|
||||
await context.hs.patch([
|
||||
await headscaleConfig.patch([
|
||||
{
|
||||
path: `dns.nameservers.split."${splitName}"`,
|
||||
value: servers.length > 0 ? servers : null,
|
||||
@@ -85,11 +96,11 @@ export async function dnsAction({ request, context }: Route.ActionArgs) {
|
||||
]);
|
||||
}
|
||||
|
||||
await context.integration?.onConfigChange(context.headscale);
|
||||
await integration?.onConfigChange(headscale);
|
||||
return { message: "Nameserver removed successfully" };
|
||||
}
|
||||
case "add_ns": {
|
||||
const config = context.hs.c!;
|
||||
const config = headscaleConfig.c!;
|
||||
const ns = formData.get("ns")?.toString();
|
||||
const splitName = formData.get("split_name")?.toString();
|
||||
|
||||
@@ -101,7 +112,7 @@ export async function dnsAction({ request, context }: Route.ActionArgs) {
|
||||
const servers = config.dns.nameservers.global;
|
||||
servers.push(ns);
|
||||
|
||||
await context.hs.patch([
|
||||
await headscaleConfig.patch([
|
||||
{
|
||||
path: "dns.nameservers.global",
|
||||
value: servers,
|
||||
@@ -112,7 +123,7 @@ export async function dnsAction({ request, context }: Route.ActionArgs) {
|
||||
const servers = splits[splitName] ?? [];
|
||||
servers.push(ns);
|
||||
|
||||
await context.hs.patch([
|
||||
await headscaleConfig.patch([
|
||||
{
|
||||
path: `dns.nameservers.split."${splitName}"`,
|
||||
value: servers,
|
||||
@@ -120,29 +131,29 @@ export async function dnsAction({ request, context }: Route.ActionArgs) {
|
||||
]);
|
||||
}
|
||||
|
||||
await context.integration?.onConfigChange(context.headscale);
|
||||
await integration?.onConfigChange(headscale);
|
||||
return { message: "Nameserver added successfully" };
|
||||
}
|
||||
case "remove_domain": {
|
||||
const config = context.hs.c!;
|
||||
const config = headscaleConfig.c!;
|
||||
const domain = formData.get("domain")?.toString();
|
||||
if (!domain) {
|
||||
return data({ success: false }, 400);
|
||||
}
|
||||
|
||||
const domains = config.dns.search_domains.filter((i) => i !== domain);
|
||||
await context.hs.patch([
|
||||
await headscaleConfig.patch([
|
||||
{
|
||||
path: "dns.search_domains",
|
||||
value: domains,
|
||||
},
|
||||
]);
|
||||
|
||||
await context.integration?.onConfigChange(context.headscale);
|
||||
await integration?.onConfigChange(headscale);
|
||||
return { message: "Domain removed successfully" };
|
||||
}
|
||||
case "add_domain": {
|
||||
const config = context.hs.c!;
|
||||
const config = headscaleConfig.c!;
|
||||
const domain = formData.get("domain")?.toString();
|
||||
if (!domain) {
|
||||
return data({ success: false }, 400);
|
||||
@@ -151,14 +162,14 @@ export async function dnsAction({ request, context }: Route.ActionArgs) {
|
||||
const domains = config.dns.search_domains;
|
||||
domains.push(domain);
|
||||
|
||||
await context.hs.patch([
|
||||
await headscaleConfig.patch([
|
||||
{
|
||||
path: "dns.search_domains",
|
||||
value: domains,
|
||||
},
|
||||
]);
|
||||
|
||||
await context.integration?.onConfigChange(context.headscale);
|
||||
await integration?.onConfigChange(headscale);
|
||||
return { message: "Domain added successfully" };
|
||||
}
|
||||
case "remove_record": {
|
||||
@@ -170,7 +181,7 @@ export async function dnsAction({ request, context }: Route.ActionArgs) {
|
||||
}
|
||||
|
||||
// Value is not needed for removal
|
||||
const restart = await context.hs.removeDNS({
|
||||
const restart = await headscaleConfig.removeDNS({
|
||||
name: recordName,
|
||||
type: recordType,
|
||||
value: "",
|
||||
@@ -180,7 +191,7 @@ export async function dnsAction({ request, context }: Route.ActionArgs) {
|
||||
return;
|
||||
}
|
||||
|
||||
await context.integration?.onConfigChange(context.headscale);
|
||||
await integration?.onConfigChange(headscale);
|
||||
return { message: "DNS record removed successfully" };
|
||||
}
|
||||
case "add_record": {
|
||||
@@ -192,7 +203,7 @@ export async function dnsAction({ request, context }: Route.ActionArgs) {
|
||||
return data({ success: false }, 400);
|
||||
}
|
||||
|
||||
const restart = await context.hs.addDNS({
|
||||
const restart = await headscaleConfig.addDNS({
|
||||
name: recordName,
|
||||
type: recordType,
|
||||
value: recordValue,
|
||||
@@ -202,7 +213,7 @@ export async function dnsAction({ request, context }: Route.ActionArgs) {
|
||||
return;
|
||||
}
|
||||
|
||||
await context.integration?.onConfigChange(context.headscale);
|
||||
await integration?.onConfigChange(headscale);
|
||||
return { message: "DNS record added successfully" };
|
||||
}
|
||||
case "override_dns": {
|
||||
@@ -212,14 +223,14 @@ export async function dnsAction({ request, context }: Route.ActionArgs) {
|
||||
}
|
||||
|
||||
const overrideValue = override === "true";
|
||||
await context.hs.patch([
|
||||
await headscaleConfig.patch([
|
||||
{
|
||||
path: "dns.override_local_dns",
|
||||
value: overrideValue,
|
||||
},
|
||||
]);
|
||||
|
||||
await context.integration?.onConfigChange(context.headscale);
|
||||
await integration?.onConfigChange(headscale);
|
||||
return { message: "DNS override updated successfully" };
|
||||
}
|
||||
default:
|
||||
|
||||
+14
-10
@@ -1,12 +1,13 @@
|
||||
import type { ActionFunctionArgs, LoaderFunctionArgs } from "react-router";
|
||||
import type { ActionFunctionArgs } from "react-router";
|
||||
import { useLoaderData } from "react-router";
|
||||
|
||||
import Code from "~/components/code";
|
||||
import Notice from "~/components/notice";
|
||||
import PageError from "~/components/page-error";
|
||||
import type { AppContext } from "~/server/context";
|
||||
import { authContext, headscaleConfigContext } from "~/server/context";
|
||||
import { Capabilities } from "~/server/web/roles";
|
||||
|
||||
import type { Route } from "./+types/overview";
|
||||
import ManageDomains from "./components/manage-domains";
|
||||
import ManageNS from "./components/manage-ns";
|
||||
import ManageRecords from "./components/manage-records";
|
||||
@@ -15,13 +16,16 @@ import ToggleMagic from "./components/toggle-magic";
|
||||
import { dnsAction } from "./dns-actions";
|
||||
|
||||
// We do not want to expose every config value
|
||||
export async function loader({ request, context }: LoaderFunctionArgs<AppContext>) {
|
||||
if (!context.hs.readable()) {
|
||||
export async function loader({ request, context }: Route.LoaderArgs) {
|
||||
const auth = context.get(authContext);
|
||||
const headscaleConfig = context.get(headscaleConfigContext);
|
||||
|
||||
if (!headscaleConfig.readable()) {
|
||||
throw new Error("No configuration is available");
|
||||
}
|
||||
|
||||
const principal = await context.auth.require(request);
|
||||
const check = context.auth.can(principal, Capabilities.read_network);
|
||||
const principal = await auth.require(request);
|
||||
const check = auth.can(principal, Capabilities.read_network);
|
||||
if (!check) {
|
||||
// Not authorized to view this page
|
||||
throw new Error(
|
||||
@@ -29,9 +33,9 @@ export async function loader({ request, context }: LoaderFunctionArgs<AppContext
|
||||
);
|
||||
}
|
||||
|
||||
const writablePermission = context.auth.can(principal, Capabilities.write_network);
|
||||
const writablePermission = auth.can(principal, Capabilities.write_network);
|
||||
|
||||
const config = context.hs.c!;
|
||||
const config = headscaleConfig.c!;
|
||||
const dns = {
|
||||
prefixes: config.prefixes,
|
||||
magicDns: config.dns.magic_dns,
|
||||
@@ -40,13 +44,13 @@ export async function loader({ request, context }: LoaderFunctionArgs<AppContext
|
||||
splitDns: config.dns.nameservers.split,
|
||||
searchDomains: config.dns.search_domains,
|
||||
overrideDns: config.dns.override_local_dns,
|
||||
extraRecords: context.hs.d,
|
||||
extraRecords: headscaleConfig.d,
|
||||
};
|
||||
|
||||
return {
|
||||
...dns,
|
||||
access: writablePermission,
|
||||
writable: context.hs.writable(),
|
||||
writable: headscaleConfig.writable(),
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user