Add admin setup page

This commit is contained in:
2026-09-20 18:15:51 +01:00
parent 27676c5a3f
commit f05384d8fe
21 changed files with 1318 additions and 4 deletions
@@ -0,0 +1,91 @@
import checkUserAccess from "@/src/functions/backend/auth/check-user-access";
import userAuth from "@/src/functions/backend/auth/user-auth";
import grabSystemSetupStatus from "@/src/functions/backend/setup/grab-system-setup-status";
import { execSync } from "node:child_process";
import type { APIResponseObject, BunextAPIRouteHandler } from "@moduletrace/bunext/types";
const restart_service = ({
command,
}: {
command: string;
}): APIResponseObject => {
try {
const output = execSync(command, {
encoding: "utf-8",
stdio: "pipe",
timeout: 30000,
});
return {
success: true,
msg: String(output).trim() || `Restarted service successfully`,
};
} catch (error: any) {
const stdout = error?.stdout ? String(error.stdout).trim() : "";
const stderr = error?.stderr ? String(error.stderr).trim() : "";
return {
success: false,
msg: `${error.message}\n${[stdout, stderr]
.filter(Boolean)
.join("\n")
.trim()}`.trim(),
};
}
};
export const handler: BunextAPIRouteHandler<APIResponseObject> = async ({
req,
}) => {
if (req.method !== "POST") {
return {
success: false,
};
}
const { user, user_types } = await userAuth({ req });
if (!user?.logged_in_status) {
return {
success: false,
msg: `Unauthorized`,
logoutUser: true,
};
}
const is_super_admin = checkUserAccess({ user_types });
if (!is_super_admin.success) {
return {
success: false,
msg: `Unauthorized`,
};
}
const setup_status = grabSystemSetupStatus();
if (setup_status.is_dev) {
return {
success: false,
msg: `Development mode — the wg-ui server is run manually. Restart it yourself (e.g. Ctrl+C then run the dev command again).`,
};
}
switch (setup_status.init_system) {
case "systemd":
return restart_service({
command: `systemctl restart ${setup_status.service_name}`,
});
case "openrc":
return restart_service({
command: `rc-service ${setup_status.service_name} restart`,
});
default:
return {
success: false,
msg: `No supported init system detected — restart the wg-ui process manually.`,
};
}
};
@@ -0,0 +1,46 @@
import checkUserAccess from "@/src/functions/backend/auth/check-user-access";
import userAuth from "@/src/functions/backend/auth/user-auth";
import runSetupScript from "@/src/functions/backend/setup/run-setup-script";
import type { APIResponseObject, BunextAPIRouteHandler } from "@moduletrace/bunext/types";
const SETUP_WIREGUARD_SCRIPT = `setup-wireguard.sh`;
const SETUP_WIREGUARD_TIMEOUT_MS = 15 * 60 * 1000;
export const handler: BunextAPIRouteHandler<APIResponseObject> = async ({
req,
}) => {
if (req.method !== "POST") {
return {
success: false,
};
}
const { user, user_types } = await userAuth({ req });
if (!user?.logged_in_status) {
return {
success: false,
msg: `Unauthorized`,
logoutUser: true,
};
}
const is_super_admin = checkUserAccess({ user_types });
if (!is_super_admin.success) {
return {
success: false,
msg: `Unauthorized`,
};
}
const { success, output } = runSetupScript({
script: SETUP_WIREGUARD_SCRIPT,
timeout_ms: SETUP_WIREGUARD_TIMEOUT_MS,
});
return {
success,
msg: output,
};
};
@@ -0,0 +1,43 @@
import checkUserAccess from "@/src/functions/backend/auth/check-user-access";
import userAuth from "@/src/functions/backend/auth/user-auth";
import grabSystemSetupStatus, {
type SystemSetupStatus,
} from "@/src/functions/backend/setup/grab-system-setup-status";
import type {
APIResponseObject,
BunextAPIRouteHandler,
} from "@moduletrace/bunext/types";
export const handler: BunextAPIRouteHandler<
APIResponseObject<SystemSetupStatus>
> = async ({ req }) => {
if (req.method !== "GET") {
return {
success: false,
};
}
const { user, user_types } = await userAuth({ req });
if (!user?.logged_in_status) {
return {
success: false,
msg: `Unauthorized`,
logoutUser: true,
};
}
const is_super_admin = checkUserAccess({ user_types });
if (!is_super_admin.success) {
return {
success: false,
msg: `Unauthorized`,
};
}
return {
success: true,
singleRes: grabSystemSetupStatus(),
};
};
+61
View File
@@ -0,0 +1,61 @@
import checkUserAccess from "@/src/functions/backend/auth/check-user-access";
import userAuth from "@/src/functions/backend/auth/user-auth";
import grabSystemSetupStatus from "@/src/functions/backend/setup/grab-system-setup-status";
import runSetupScript from "@/src/functions/backend/setup/run-setup-script";
import type { ApiReqParams } from "@/src/types";
import type { APIResponseObject, BunextAPIRouteHandler } from "@moduletrace/bunext/types";
const INSTALL_WG_UI_SCRIPT = `install-wg-ui.sh`;
const INSTALL_WG_UI_TIMEOUT_MS = 20 * 60 * 1000;
export const handler: BunextAPIRouteHandler<APIResponseObject> = async (
params,
) => {
const req = params.req;
const body = params.body as ApiReqParams;
if (req.method !== "POST") {
return {
success: false,
};
}
const { user, user_types } = await userAuth({ req });
if (!user?.logged_in_status) {
return {
success: false,
msg: `Unauthorized`,
logoutUser: true,
};
}
const is_super_admin = checkUserAccess({ user_types });
if (!is_super_admin.success) {
return {
success: false,
msg: `Unauthorized`,
};
}
const setup_status = grabSystemSetupStatus();
const { success, output } = runSetupScript({
script: INSTALL_WG_UI_SCRIPT,
timeout_ms: INSTALL_WG_UI_TIMEOUT_MS,
env: {
NODE_ENV: setup_status.is_dev ? "development" : "production",
REPO_URL:
body.repo_url?.trim() || setup_status.repo_url || "",
BRANCH:
body.branch?.trim() || setup_status.repo_branch || "main",
SERVICE_NAME: setup_status.service_name,
},
});
return {
success,
msg: output,
};
};