Refactor main host setup
This commit is contained in:
@@ -1,9 +1,5 @@
|
||||
import { useAdminCrudGet } from "@/src/hooks/use-admin-crud-get";
|
||||
import type {
|
||||
BUN_SQLITE_WGUI_CLIENTS,
|
||||
BUN_SQLITE_WGUI_HOSTS,
|
||||
BUN_SQLITE_WGUI_VARIABLES,
|
||||
} from "@/db/types/db";
|
||||
import type { BUN_SQLITE_WGUI_CLIENTS, BUN_SQLITE_WGUI_HOSTS } from "@/db/types/db";
|
||||
|
||||
export default function useDashboardData() {
|
||||
const clients_res = useAdminCrudGet<BUN_SQLITE_WGUI_CLIENTS>({
|
||||
@@ -19,13 +15,8 @@ export default function useDashboardData() {
|
||||
limit: 100,
|
||||
});
|
||||
|
||||
const variables_res = useAdminCrudGet<BUN_SQLITE_WGUI_VARIABLES>({
|
||||
table: "variables",
|
||||
});
|
||||
|
||||
return {
|
||||
clients: clients_res.res,
|
||||
hosts: hosts_res.res,
|
||||
variables: variables_res.res,
|
||||
};
|
||||
}
|
||||
@@ -2,20 +2,15 @@ import StatCard from "../(partials)/stat-card";
|
||||
import type {
|
||||
BUN_SQLITE_WGUI_CLIENTS,
|
||||
BUN_SQLITE_WGUI_HOSTS,
|
||||
BUN_SQLITE_WGUI_VARIABLES,
|
||||
} from "@/db/types/db";
|
||||
|
||||
type Props = {
|
||||
clients?: BUN_SQLITE_WGUI_CLIENTS[];
|
||||
hosts?: BUN_SQLITE_WGUI_HOSTS[];
|
||||
variables?: BUN_SQLITE_WGUI_VARIABLES[];
|
||||
};
|
||||
|
||||
export default function KpiSecondarySection({
|
||||
clients,
|
||||
hosts,
|
||||
variables,
|
||||
}: Props) {
|
||||
export default function KpiSecondarySection({ clients, hosts }: Props) {
|
||||
const main_host = hosts?.find((h) => h.id === 0);
|
||||
const kpis = [
|
||||
{
|
||||
key: "k-clients",
|
||||
@@ -25,14 +20,12 @@ export default function KpiSecondarySection({
|
||||
{
|
||||
key: "k-hosts",
|
||||
label: "Total hosts",
|
||||
value: String(hosts?.length || 1),
|
||||
value: String(hosts?.length),
|
||||
},
|
||||
{
|
||||
key: "k-host-address",
|
||||
label: "Main host address",
|
||||
value:
|
||||
variables?.find((v) => v.key == "main_host_wg_ip_address")
|
||||
?.value || "—",
|
||||
value: main_host?.wg_ip_address || "—",
|
||||
},
|
||||
];
|
||||
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
import type { BUN_SQLITE_WGUI_HOSTS } from "@/db/types/db";
|
||||
import { AppData } from "@/src/data/app-data";
|
||||
import type { PagePropsType, PageQueryObject, TableType } from "@/src/types";
|
||||
import BunSQLite from "@moduletrace/bun-sqlite";
|
||||
import type { BunextPageServerFn } from "@moduletrace/bunext/types";
|
||||
|
||||
const server: BunextPageServerFn<PagePropsType> = async ({ query }) => {
|
||||
const main_host_record_res = await BunSQLite.select<
|
||||
BUN_SQLITE_WGUI_HOSTS,
|
||||
TableType
|
||||
>({
|
||||
table: "hosts",
|
||||
targetId: AppData["WireguardMainHostID"],
|
||||
});
|
||||
|
||||
const main_host_record = main_host_record_res.singleRes || null;
|
||||
|
||||
if (!main_host_record?.name) {
|
||||
return {
|
||||
redirect: {
|
||||
destination: `/admin/hosts/add`,
|
||||
permanent: false,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
props: {},
|
||||
};
|
||||
};
|
||||
|
||||
export default server;
|
||||
@@ -1,27 +1,18 @@
|
||||
import { AppData } from "@/src/data/app-data";
|
||||
import deriveWireguardInterfaceName from "@/src/utils/derive-wireguard-interface-name";
|
||||
import type {
|
||||
BUN_SQLITE_WGUI_CLIENTS,
|
||||
BUN_SQLITE_WGUI_VARIABLES,
|
||||
} from "@/db/types/db";
|
||||
import type { BUN_SQLITE_WGUI_CLIENTS } from "@/db/types/db";
|
||||
import type { BUN_SQLITE_WGUI_HOSTS_JOIN } from "@/src/types/sql-joins";
|
||||
|
||||
type Params = {
|
||||
host?: BUN_SQLITE_WGUI_HOSTS_JOIN;
|
||||
variables?: BUN_SQLITE_WGUI_VARIABLES[];
|
||||
clients?: BUN_SQLITE_WGUI_CLIENTS[];
|
||||
};
|
||||
|
||||
export default function deriveHostConfig({ host, variables, clients }: Params) {
|
||||
const host_id = host?.id || AppData["WireguardHostID"];
|
||||
export default function deriveHostConfig({ host, clients }: Params) {
|
||||
const host_id = host?.id || AppData["WireguardMainHostID"];
|
||||
|
||||
const wg_ip_address =
|
||||
host?.wg_ip_address ||
|
||||
variables?.find((v) => v.key == "main_host_wg_ip_address")?.value;
|
||||
|
||||
const public_key =
|
||||
host?.public_key ||
|
||||
variables?.find((v) => v.key == "main_host_wg_public_key")?.value;
|
||||
const wg_ip_address = host?.wg_ip_address;
|
||||
const public_key = host?.public_key;
|
||||
|
||||
const interface_name = deriveWireguardInterfaceName({ host_id });
|
||||
|
||||
|
||||
@@ -2,27 +2,27 @@ import { useAdminCrudGet } from "@/src/hooks/use-admin-crud-get";
|
||||
import type {
|
||||
BUN_SQLITE_WGUI_CLIENTS,
|
||||
BUN_SQLITE_WGUI_HOSTS,
|
||||
BUN_SQLITE_WGUI_VARIABLES,
|
||||
} from "@/db/types/db";
|
||||
import { useContext } from "react";
|
||||
import { AppContext } from "@/src/pages/__root";
|
||||
|
||||
export default function useHostData() {
|
||||
const { pageProps } = useContext(AppContext);
|
||||
|
||||
const hosts_res = useAdminCrudGet<BUN_SQLITE_WGUI_HOSTS>({
|
||||
table: "hosts",
|
||||
limit: 100,
|
||||
});
|
||||
|
||||
const variables_res = useAdminCrudGet<BUN_SQLITE_WGUI_VARIABLES>({
|
||||
table: "variables",
|
||||
initial_res: pageProps?.hosts || undefined,
|
||||
});
|
||||
|
||||
const clients_res = useAdminCrudGet<BUN_SQLITE_WGUI_CLIENTS>({
|
||||
table: "clients",
|
||||
limit: 100,
|
||||
initial_res: pageProps?.clients || undefined,
|
||||
});
|
||||
|
||||
return {
|
||||
hosts: hosts_res.res,
|
||||
variables: variables_res.res,
|
||||
clients: clients_res.res,
|
||||
};
|
||||
}
|
||||
|
||||
+30
-18
@@ -1,28 +1,32 @@
|
||||
import { Server } from "lucide-react";
|
||||
import type { BUN_SQLITE_WGUI_HOSTS } from "@/db/types/db";
|
||||
import { GlobeCheck, Server } from "lucide-react";
|
||||
import AdminCard from "@/src/components/general/admin-card";
|
||||
import DeleteHostButton from "@/src/components/general/delete-host-button";
|
||||
import Button from "@/src/components/twui/layout/Button";
|
||||
import Row from "@/src/components/twui/layout/Row";
|
||||
import Span from "@/src/components/twui/layout/Span";
|
||||
import Stack from "@/src/components/twui/layout/Stack";
|
||||
import Tag from "@/src/components/twui/elements/Tag";
|
||||
import type { BUN_SQLITE_WGUI_HOSTS } from "@/db/types/db";
|
||||
import { AppData } from "@/src/data/app-data";
|
||||
|
||||
type Props = {
|
||||
host: BUN_SQLITE_WGUI_HOSTS;
|
||||
client_count?: number;
|
||||
};
|
||||
|
||||
export default function OtherHostCard({ host, client_count }: Props) {
|
||||
export default function HostCard({ host, client_count }: Props) {
|
||||
const host_id = host.id || 0;
|
||||
|
||||
const title = host_id == 0 ? "Main Host" : ` Host #${host_id}`;
|
||||
|
||||
return (
|
||||
<AdminCard className="w-full p-5 flex flex-col gap-4">
|
||||
<Row className="justify-between items-center gap-3 flex-wrap">
|
||||
<Stack className="gap-0.5">
|
||||
<Stack className="gap-2">
|
||||
<Row className="gap-2 items-center">
|
||||
<Server size={15} className="opacity-50" />
|
||||
<GlobeCheck size={15} className="opacity-50" />
|
||||
<Span className="text-[14px] font-semibold leading-none">
|
||||
Host #{host_id}
|
||||
{title}
|
||||
</Span>
|
||||
</Row>
|
||||
<Span className="font-mono text-[12.5px] text-foreground-light/45 dark:text-foreground-dark/45">
|
||||
@@ -46,23 +50,31 @@ export default function OtherHostCard({ host, client_count }: Props) {
|
||||
>
|
||||
Edit
|
||||
</Button>
|
||||
<Button
|
||||
title="Host Clients"
|
||||
size="small"
|
||||
variant="outlined"
|
||||
href={`/admin/hosts/${host_id}/clients`}
|
||||
>
|
||||
Clients
|
||||
</Button>
|
||||
<DeleteHostButton host_id={host_id} />
|
||||
</Row>
|
||||
</Row>
|
||||
<Row className="gap-2 items-center flex-wrap">
|
||||
<Tag variant="outlined" color="gray">
|
||||
{host.public_ip_address ? (
|
||||
<Span size="smaller">
|
||||
<code className="text-xs">
|
||||
{host.public_ip_address} :{" "}
|
||||
{host.listen_port || AppData["DefaultWGListenPort"]}
|
||||
</code>
|
||||
</Span>
|
||||
) : null}
|
||||
<Span size="smaller">
|
||||
{client_count || 0}{" "}
|
||||
{client_count == 1 ? "client" : "clients"}
|
||||
</Tag>
|
||||
{host.public_ip_address ? (
|
||||
<Tag
|
||||
variant="outlined"
|
||||
color="success"
|
||||
className="outline-success/50 bg-success/5!"
|
||||
>
|
||||
{host.public_ip_address}
|
||||
</Tag>
|
||||
) : null}
|
||||
</Span>
|
||||
</Row>
|
||||
</AdminCard>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -8,11 +8,7 @@ import Row from "@/src/components/twui/layout/Row";
|
||||
import Span from "@/src/components/twui/layout/Span";
|
||||
import Stack from "@/src/components/twui/layout/Stack";
|
||||
import deriveHostConfig from "../(functions)/derive-host-config";
|
||||
import type {
|
||||
BUN_SQLITE_WGUI_CLIENTS,
|
||||
BUN_SQLITE_WGUI_HOSTS,
|
||||
BUN_SQLITE_WGUI_VARIABLES,
|
||||
} from "@/db/types/db";
|
||||
import type { BUN_SQLITE_WGUI_CLIENTS } from "@/db/types/db";
|
||||
import Divider from "@/src/components/twui/layout/Divider";
|
||||
import H3 from "@/src/components/twui/layout/H3";
|
||||
import type { BUN_SQLITE_WGUI_HOSTS_JOIN } from "@/src/types/sql-joins";
|
||||
@@ -21,13 +17,11 @@ import { AppContext } from "@/src/pages/__root";
|
||||
|
||||
type Props = {
|
||||
host?: BUN_SQLITE_WGUI_HOSTS_JOIN;
|
||||
variables?: BUN_SQLITE_WGUI_VARIABLES[];
|
||||
clients?: BUN_SQLITE_WGUI_CLIENTS[];
|
||||
};
|
||||
|
||||
export default function InterfaceConfigSection({
|
||||
host,
|
||||
variables,
|
||||
clients,
|
||||
}: Props) {
|
||||
const { pageProps } = useContext(AppContext);
|
||||
@@ -38,7 +32,7 @@ export default function InterfaceConfigSection({
|
||||
dir_names: pageProps?.main_host_dir_names || undefined,
|
||||
};
|
||||
|
||||
const config = deriveHostConfig({ host: final_host, variables, clients });
|
||||
const config = deriveHostConfig({ host: final_host, clients });
|
||||
|
||||
const rows = [
|
||||
{ keyName: "Address", value: config.address || "—" },
|
||||
|
||||
@@ -5,20 +5,16 @@ import Span from "@/src/components/twui/layout/Span";
|
||||
import Stack from "@/src/components/twui/layout/Stack";
|
||||
import deriveHostConfig from "../(functions)/derive-host-config";
|
||||
import { twMerge } from "tailwind-merge";
|
||||
import type {
|
||||
BUN_SQLITE_WGUI_CLIENTS,
|
||||
BUN_SQLITE_WGUI_VARIABLES,
|
||||
} from "@/db/types/db";
|
||||
import type { BUN_SQLITE_WGUI_CLIENTS } from "@/db/types/db";
|
||||
import type { BUN_SQLITE_WGUI_HOSTS_JOIN } from "@/src/types/sql-joins";
|
||||
|
||||
type Props = {
|
||||
host?: BUN_SQLITE_WGUI_HOSTS_JOIN;
|
||||
variables?: BUN_SQLITE_WGUI_VARIABLES[];
|
||||
clients?: BUN_SQLITE_WGUI_CLIENTS[];
|
||||
};
|
||||
|
||||
export default function MainHostStatusSection({ host, variables, clients }: Props) {
|
||||
const config = deriveHostConfig({ host, variables, clients });
|
||||
export default function MainHostStatusSection({ host, clients }: Props) {
|
||||
const config = deriveHostConfig({ host, clients });
|
||||
|
||||
const stats = [
|
||||
{
|
||||
|
||||
@@ -28,14 +28,12 @@ const server: BunextPageServerFn<PagePropsType> = async ({ query }) => {
|
||||
const client = client_res.singleRes || null;
|
||||
|
||||
const host_id = Number(
|
||||
client?.host_id ||
|
||||
page_query.host_id ||
|
||||
AppData["WireguardHostID"],
|
||||
client?.host_id || page_query.host_id || AppData["WireguardMainHostID"],
|
||||
);
|
||||
|
||||
let host: BUN_SQLITE_WGUI_HOSTS | null = null;
|
||||
|
||||
if (host_id && host_id != AppData["WireguardHostID"]) {
|
||||
if (host_id && host_id != AppData["WireguardMainHostID"]) {
|
||||
const host_res = await BunSQLite.select<
|
||||
BUN_SQLITE_WGUI_HOSTS,
|
||||
TableType
|
||||
@@ -72,4 +70,4 @@ const server: BunextPageServerFn<PagePropsType> = async ({ query }) => {
|
||||
};
|
||||
};
|
||||
|
||||
export default server;
|
||||
export default server;
|
||||
|
||||
+3
-3
@@ -21,7 +21,7 @@ export default async function grabNextAvailableClientIp({
|
||||
},
|
||||
);
|
||||
|
||||
if (!res?.success || !res.msg) {
|
||||
if (!res?.success || !res.stringRes) {
|
||||
return {
|
||||
success: false,
|
||||
msg: res?.msg || `Couldn't grab the next available client IP`,
|
||||
@@ -30,8 +30,8 @@ export default async function grabNextAvailableClientIp({
|
||||
|
||||
setForm((prev) => ({
|
||||
...prev,
|
||||
wg_ip_address: res.msg,
|
||||
allowed_ips: `${res.msg}/24`,
|
||||
wg_ip_address: res.stringRes || "",
|
||||
allowed_ips: `${res.stringRes}/24`,
|
||||
}));
|
||||
|
||||
return {
|
||||
|
||||
+3
@@ -24,6 +24,7 @@ export default async function submitAddClientForm(
|
||||
form,
|
||||
existing_full,
|
||||
app_context,
|
||||
clearLocalForm,
|
||||
}: ReturnType<typeof useFormInit<BUN_SQLITE_WGUI_CLIENTS>>,
|
||||
{ host_id, rules }: Params,
|
||||
) {
|
||||
@@ -113,6 +114,8 @@ export default async function submitAddClientForm(
|
||||
}
|
||||
|
||||
if (res.success) {
|
||||
clearLocalForm();
|
||||
|
||||
if (existing_full?.id) {
|
||||
window.location.pathname = `/admin/hosts/${final_host_id}/clients/${existing_full.id}`;
|
||||
} else {
|
||||
|
||||
+9
@@ -38,6 +38,15 @@ export default function AddClientForm({
|
||||
existing: existing_client,
|
||||
existing_full: existing_client_full,
|
||||
title: "Add Client",
|
||||
async before_ready_function(params) {
|
||||
params.setForm((prev) => ({
|
||||
...prev,
|
||||
wg_ip_address:
|
||||
existing_client_full?.wg_ip_address ||
|
||||
params.app_context.pageProps?.next_available_client_ip ||
|
||||
"",
|
||||
}));
|
||||
},
|
||||
});
|
||||
|
||||
const [rules, setRules] = useState<ClientRuleDraft[]>(
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import type { BUN_SQLITE_WGUI_HOSTS } from "@/db/types/db";
|
||||
import grabNextAvailableClientIPAddress from "@/src/functions/backend/setup/grab-next-available-client-ip";
|
||||
import type { PagePropsType, PageQueryObject, TableType } from "@/src/types";
|
||||
import BunSQLite from "@moduletrace/bun-sqlite";
|
||||
import type { BunextPageServerFn } from "@moduletrace/bunext/types";
|
||||
@@ -11,9 +12,27 @@ const server: BunextPageServerFn<PagePropsType> = async ({ query }) => {
|
||||
TableType
|
||||
>({ table: "hosts", targetId: page_query.host_id });
|
||||
|
||||
const host_record = host_record_res.singleRes || null;
|
||||
|
||||
if (!host_record) {
|
||||
return {
|
||||
redirect: {
|
||||
destination: `/admin/hosts`,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
const next_available_client_ip_res = await grabNextAvailableClientIPAddress(
|
||||
{
|
||||
host: host_record,
|
||||
},
|
||||
);
|
||||
|
||||
return {
|
||||
props: {
|
||||
host: host_record_res.singleRes || null,
|
||||
host: host_record,
|
||||
next_available_client_ip:
|
||||
next_available_client_ip_res.stringRes || null,
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,8 +1,4 @@
|
||||
import type {
|
||||
BUN_SQLITE_WGUI_HOSTS,
|
||||
BUN_SQLITE_WGUI_VARIABLES,
|
||||
} from "@/db/types/db";
|
||||
import { AppData } from "@/src/data/app-data";
|
||||
import type { BUN_SQLITE_WGUI_HOSTS } from "@/db/types/db";
|
||||
import type { PagePropsType, PageQueryObject, TableType } from "@/src/types";
|
||||
import BunSQLite from "@moduletrace/bun-sqlite";
|
||||
import type { BunextPageServerFn } from "@moduletrace/bunext/types";
|
||||
@@ -10,9 +6,7 @@ import type { BunextPageServerFn } from "@moduletrace/bunext/types";
|
||||
const server: BunextPageServerFn<PagePropsType> = async ({ query }) => {
|
||||
const page_query = query as PageQueryObject;
|
||||
|
||||
const host_id = Number(
|
||||
page_query.host_id || AppData["WireguardHostID"],
|
||||
);
|
||||
const host_id = Number(page_query.host_id || 0);
|
||||
|
||||
const host_res = await BunSQLite.select<
|
||||
BUN_SQLITE_WGUI_HOSTS,
|
||||
@@ -22,31 +16,7 @@ const server: BunextPageServerFn<PagePropsType> = async ({ query }) => {
|
||||
targetId: host_id,
|
||||
});
|
||||
|
||||
let host = host_res.singleRes || null;
|
||||
|
||||
if (!host && host_id == AppData["WireguardHostID"]) {
|
||||
const variables_res = await BunSQLite.select<
|
||||
BUN_SQLITE_WGUI_VARIABLES,
|
||||
TableType
|
||||
>({
|
||||
table: "variables",
|
||||
});
|
||||
|
||||
const variables = variables_res.payload || [];
|
||||
|
||||
host = {
|
||||
id: AppData["WireguardHostID"],
|
||||
wg_ip_address:
|
||||
variables.find((v) => v.key == "main_host_wg_ip_address")
|
||||
?.value || "",
|
||||
public_ip_address:
|
||||
variables.find((v) => v.key == "main_host_public_ip_address")
|
||||
?.value || "",
|
||||
public_key:
|
||||
variables.find((v) => v.key == "main_host_wg_public_key")
|
||||
?.value || "",
|
||||
};
|
||||
}
|
||||
const host = host_res.singleRes || null;
|
||||
|
||||
return {
|
||||
props: {
|
||||
@@ -55,4 +25,4 @@ const server: BunextPageServerFn<PagePropsType> = async ({ query }) => {
|
||||
};
|
||||
};
|
||||
|
||||
export default server;
|
||||
export default server;
|
||||
|
||||
@@ -1,8 +1,4 @@
|
||||
import type {
|
||||
BUN_SQLITE_WGUI_CLIENTS,
|
||||
BUN_SQLITE_WGUI_HOSTS,
|
||||
BUN_SQLITE_WGUI_VARIABLES,
|
||||
} from "@/db/types/db";
|
||||
import type { BUN_SQLITE_WGUI_CLIENTS, BUN_SQLITE_WGUI_HOSTS } from "@/db/types/db";
|
||||
import grabHostDirnames from "@/src/functions/backend/setup/grab-host-dir-names";
|
||||
import type { PagePropsType, PageQueryObject, TableType } from "@/src/types";
|
||||
import BunSQLite from "@moduletrace/bun-sqlite";
|
||||
@@ -43,18 +39,12 @@ const server: BunextPageServerFn<PagePropsType> = async ({
|
||||
},
|
||||
});
|
||||
|
||||
const variables_res = await BunSQLite.select<
|
||||
BUN_SQLITE_WGUI_VARIABLES,
|
||||
TableType
|
||||
>({ table: "variables" });
|
||||
|
||||
return {
|
||||
props: {
|
||||
host,
|
||||
clients: host_clients.payload || null,
|
||||
variables: variables_res.payload || null,
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
export default server;
|
||||
export default server;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import type { BunextPageModuleMeta } from "@moduletrace/bunext/types";
|
||||
import { useContext } from "react";
|
||||
import AdminHero from "@/src/components/general/admin-hero";
|
||||
import DeleteHostButton from "@/src/components/general/delete-host-button";
|
||||
import { SiteData } from "@/src/data/site-data";
|
||||
import Button from "@/src/components/twui/layout/Button";
|
||||
import Divider from "@/src/components/twui/layout/Divider";
|
||||
@@ -17,11 +18,8 @@ export default function AdminSingleHostPage() {
|
||||
const host_id = Number(query?.host_id || pageProps?.host?.id || 0);
|
||||
|
||||
const host = pageProps?.host || undefined;
|
||||
const variables = pageProps?.variables || [];
|
||||
const clients = pageProps?.clients || [];
|
||||
|
||||
const is_main_host = !host || host_id == 0;
|
||||
|
||||
if (!pageProps?.host && host_id != 0) {
|
||||
return (
|
||||
<>
|
||||
@@ -37,13 +35,23 @@ export default function AdminSingleHostPage() {
|
||||
);
|
||||
}
|
||||
|
||||
const title = host_id == 0 ? "Main Host" : `Host #${host_id}`;
|
||||
|
||||
return (
|
||||
<>
|
||||
<AdminHero
|
||||
title={is_main_host ? "Host" : `Host #${host_id}`}
|
||||
title={host ? title : "Host"}
|
||||
description="WireGuard server configuration and interface details"
|
||||
buttons={
|
||||
<>
|
||||
<Button
|
||||
title="Edit Host"
|
||||
size="small"
|
||||
variant="outlined"
|
||||
href={`/admin/hosts/${host_id}/edit`}
|
||||
>
|
||||
Edit Host
|
||||
</Button>
|
||||
<Button
|
||||
title="View Clients"
|
||||
size="small"
|
||||
@@ -54,21 +62,13 @@ export default function AdminSingleHostPage() {
|
||||
View Clients
|
||||
</Button>
|
||||
<Button
|
||||
title="Edit Host"
|
||||
title="Add Client"
|
||||
size="small"
|
||||
variant="outlined"
|
||||
href={`/admin/hosts/${host_id}/edit`}
|
||||
href={`/admin/hosts/${host_id}/clients/add-client`}
|
||||
>
|
||||
Edit Host
|
||||
</Button>
|
||||
<Button
|
||||
title="Add New Host"
|
||||
size="small"
|
||||
variant="outlined"
|
||||
href="/admin/hosts/add"
|
||||
>
|
||||
Add New Host
|
||||
Add Client
|
||||
</Button>
|
||||
<DeleteHostButton host_id={host_id} />
|
||||
</>
|
||||
}
|
||||
/>
|
||||
@@ -76,26 +76,12 @@ export default function AdminSingleHostPage() {
|
||||
<Divider className="mb-6" />
|
||||
|
||||
<Stack className="w-full px-6 pb-8 gap-5 items-stretch">
|
||||
<MainHostStatusSection
|
||||
host={host}
|
||||
variables={variables}
|
||||
clients={clients}
|
||||
/>
|
||||
<MainHostStatusSection host={host} clients={clients} />
|
||||
<HostPublicIpSection
|
||||
host_id={host_id}
|
||||
current_ip={
|
||||
host?.public_ip_address ||
|
||||
variables.find(
|
||||
(v) => v.key == "main_host_public_ip_address",
|
||||
)?.value ||
|
||||
""
|
||||
}
|
||||
/>
|
||||
<InterfaceConfigSection
|
||||
host={host}
|
||||
variables={variables}
|
||||
clients={clients}
|
||||
current_ip={host?.public_ip_address || ""}
|
||||
/>
|
||||
<InterfaceConfigSection host={host} clients={clients} />
|
||||
</Stack>
|
||||
</>
|
||||
);
|
||||
@@ -104,4 +90,4 @@ export default function AdminSingleHostPage() {
|
||||
export const meta: BunextPageModuleMeta = {
|
||||
title: `Host | ${SiteData["SiteName"]}`,
|
||||
description: `WireGuard host page`,
|
||||
};
|
||||
};
|
||||
|
||||
@@ -8,6 +8,8 @@ export default async function submitAddHostForm({
|
||||
setLoading,
|
||||
setStatus,
|
||||
form,
|
||||
app_context,
|
||||
clearLocalForm,
|
||||
}: ReturnType<typeof useFormInit<BUN_SQLITE_WGUI_HOSTS>>) {
|
||||
try {
|
||||
if (!window.confirm("Create this new host?")) {
|
||||
@@ -26,12 +28,17 @@ export default async function submitAddHostForm({
|
||||
interface: form.interface || "",
|
||||
name: form.name || "",
|
||||
short_description: form.short_description || "",
|
||||
listen_port: form.listen_port != null ? Number(form.listen_port) : null,
|
||||
listen_port:
|
||||
form.listen_port != null
|
||||
? Number(form.listen_port)
|
||||
: null,
|
||||
is_main_host: app_context.pageProps?.is_main_host,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
if (res.success && res.numberRes) {
|
||||
if (res.success) {
|
||||
clearLocalForm();
|
||||
window.location.pathname = `/admin/hosts/${res.numberRes}`;
|
||||
return;
|
||||
}
|
||||
@@ -46,4 +53,4 @@ export default async function submitAddHostForm({
|
||||
|
||||
setLoading(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ export default function AddHostFormName({ form, setForm }: Props) {
|
||||
name: v,
|
||||
}));
|
||||
}}
|
||||
required
|
||||
/>
|
||||
</Stack>
|
||||
);
|
||||
|
||||
@@ -1,16 +1,31 @@
|
||||
import type { BUN_SQLITE_WGUI_HOSTS } from "@/db/types/db";
|
||||
import { AppData } from "@/src/data/app-data";
|
||||
import getNextAvailableListenPort from "@/src/functions/backend/setup/get-next-available-listen-port";
|
||||
import grabHostNetworkInterfaces from "@/src/functions/backend/setup/grab-host-network-interfaces";
|
||||
import type { PagePropsType } from "@/src/types";
|
||||
import type { PagePropsType, TableType } from "@/src/types";
|
||||
import BunSQLite from "@moduletrace/bun-sqlite";
|
||||
import type { BunextPageServerFn } from "@moduletrace/bunext/types";
|
||||
|
||||
const server: BunextPageServerFn<PagePropsType> = async ({ req }) => {
|
||||
const network_interfaces = await grabHostNetworkInterfaces();
|
||||
const next_listen_port = await getNextAvailableListenPort();
|
||||
|
||||
const main_host_record_res = await BunSQLite.select<
|
||||
BUN_SQLITE_WGUI_HOSTS,
|
||||
TableType
|
||||
>({
|
||||
table: "hosts",
|
||||
targetId: AppData["WireguardMainHostID"],
|
||||
});
|
||||
|
||||
const main_host_record = main_host_record_res.singleRes || null;
|
||||
|
||||
return {
|
||||
props: {
|
||||
network_interfaces,
|
||||
next_listen_port,
|
||||
is_main_host:
|
||||
main_host_record?.id !== AppData["WireguardMainHostID"],
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
@@ -6,13 +6,30 @@ import Divider from "@/src/components/twui/layout/Divider";
|
||||
import Stack from "@/src/components/twui/layout/Stack";
|
||||
import { ArrowLeft } from "lucide-react";
|
||||
import AddHostFormSection from "./(sections)/add-host-form-section";
|
||||
import { useContext } from "react";
|
||||
import { AppContext } from "@/src/pages/__root";
|
||||
|
||||
export default function AdminAddHostPage() {
|
||||
const { pageProps } = useContext(AppContext);
|
||||
|
||||
return (
|
||||
<>
|
||||
<AdminHero
|
||||
title="Add New Host"
|
||||
description="Create a new WireGuard host with a dedicated private subnet"
|
||||
title={
|
||||
pageProps?.is_main_host
|
||||
? "Create Main Host"
|
||||
: "Add New Host"
|
||||
}
|
||||
description={
|
||||
pageProps?.is_main_host ? (
|
||||
<span>
|
||||
Create the main wireguard host <code>(wgui0)</code>{" "}
|
||||
for this server
|
||||
</span>
|
||||
) : (
|
||||
"Create a new WireGuard host with a dedicated private subnet"
|
||||
)
|
||||
}
|
||||
buttons={
|
||||
<Button
|
||||
title="Back to Hosts"
|
||||
@@ -37,4 +54,4 @@ export default function AdminAddHostPage() {
|
||||
export const meta: BunextPageModuleMeta = {
|
||||
title: `Add New Host | ${SiteData["SiteName"]}`,
|
||||
description: `WireGuard add host page`,
|
||||
};
|
||||
};
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
import type {
|
||||
BUN_SQLITE_WGUI_CLIENTS,
|
||||
BUN_SQLITE_WGUI_HOSTS,
|
||||
} from "@/db/types/db";
|
||||
import type { PagePropsType, PageQueryObject, TableType } from "@/src/types";
|
||||
import BunSQLite from "@moduletrace/bun-sqlite";
|
||||
import type { BunextPageServerFn } from "@moduletrace/bunext/types";
|
||||
|
||||
const server: BunextPageServerFn<PagePropsType> = async (ctx) => {
|
||||
const props = ctx.props as PagePropsType;
|
||||
|
||||
if (!props.main_host?.name) {
|
||||
return {
|
||||
redirect: {
|
||||
destination: `/admin/hosts/add`,
|
||||
permanent: false,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
const hosts_res = await BunSQLite.select<BUN_SQLITE_WGUI_HOSTS, TableType>({
|
||||
table: "hosts",
|
||||
});
|
||||
|
||||
const clients_res = await BunSQLite.select<
|
||||
BUN_SQLITE_WGUI_CLIENTS,
|
||||
TableType
|
||||
>({
|
||||
table: "clients",
|
||||
});
|
||||
|
||||
return {
|
||||
props: {
|
||||
hosts: hosts_res.payload || null,
|
||||
clients: clients_res.payload || null,
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
export default server;
|
||||
@@ -3,46 +3,13 @@ import AdminHero from "@/src/components/general/admin-hero";
|
||||
import Stack from "@/src/components/twui/layout/Stack";
|
||||
import { SiteData } from "@/src/data/site-data";
|
||||
import useHostData from "./(hooks)/use-host-data";
|
||||
import InterfaceConfigSection from "./(sections)/interface-config-section";
|
||||
import Button from "@/src/components/twui/layout/Button";
|
||||
import MainHostStatusSection from "./(sections)/main-host-status-section";
|
||||
import H2 from "@/src/components/twui/layout/H2";
|
||||
import Divider from "@/src/components/twui/layout/Divider";
|
||||
import EmptyContent from "@/src/components/twui/elements/EmptyContent";
|
||||
import Span from "@/src/components/twui/layout/Span";
|
||||
import checkIfMainHostIsSet from "@/src/functions/check-if-main-host-is-set";
|
||||
import SetupMainHostButton from "@/src/components/general/setup-main-host-button";
|
||||
import Row from "@/src/components/twui/layout/Row";
|
||||
import { Plus } from "lucide-react";
|
||||
import HostPublicIpSection from "./(sections)/host-public-ip-section";
|
||||
import OtherHostCard from "./(partials)/other-host-card";
|
||||
import HostCard from "./(partials)/host-card";
|
||||
|
||||
export default function AdminHostPage() {
|
||||
const { hosts, variables, clients } = useHostData();
|
||||
|
||||
const other_hosts = (hosts || []).filter((host) => (host.id || 0) != 0);
|
||||
|
||||
const main_host_public_ip = variables?.find(
|
||||
(v) => v.key == "main_host_public_ip_address",
|
||||
)?.value;
|
||||
|
||||
const is_main_host_set = checkIfMainHostIsSet({ variables });
|
||||
|
||||
if (!is_main_host_set) {
|
||||
return (
|
||||
<>
|
||||
<AdminHero
|
||||
title="Hosts"
|
||||
description="WireGuard server configuration and interface details"
|
||||
/>
|
||||
|
||||
<Stack className="w-full px-6 pb-8 gap-5 items-stretch">
|
||||
<Span variant="faded">Main Host Not Set up</Span>
|
||||
<SetupMainHostButton />
|
||||
</Stack>
|
||||
</>
|
||||
);
|
||||
}
|
||||
const { hosts, clients } = useHostData();
|
||||
|
||||
return (
|
||||
<>
|
||||
@@ -51,19 +18,7 @@ export default function AdminHostPage() {
|
||||
description="WireGuard server configuration and interface details"
|
||||
buttons={
|
||||
<>
|
||||
<Button
|
||||
title="View Hosts"
|
||||
variant="outlined"
|
||||
href="/admin/hosts"
|
||||
color="gray"
|
||||
>
|
||||
View Hosts
|
||||
</Button>
|
||||
<Button
|
||||
title="Add New Host"
|
||||
variant="outlined"
|
||||
href="/admin/hosts/add"
|
||||
>
|
||||
<Button title="Add New Host" href="/admin/hosts/add">
|
||||
Add New Host
|
||||
</Button>
|
||||
</>
|
||||
@@ -73,49 +28,10 @@ export default function AdminHostPage() {
|
||||
<Divider className="mb-6" />
|
||||
|
||||
<Stack className="w-full px-6 pb-8 gap-5 items-stretch">
|
||||
<Row className="w-full justify-between">
|
||||
<H2>Main Host</H2>
|
||||
|
||||
<Row>
|
||||
<Button
|
||||
title="View Clients"
|
||||
size="small"
|
||||
variant="outlined"
|
||||
color="primary"
|
||||
href={`/admin/hosts/0/clients`}
|
||||
>
|
||||
View Clients
|
||||
</Button>
|
||||
<Button
|
||||
title="Add Client"
|
||||
beforeIcon={<Plus />}
|
||||
size="small"
|
||||
href={`/admin/hosts/0/clients/add-client`}
|
||||
>
|
||||
Add Client
|
||||
</Button>
|
||||
</Row>
|
||||
</Row>
|
||||
<MainHostStatusSection
|
||||
variables={variables}
|
||||
clients={clients}
|
||||
/>
|
||||
<HostPublicIpSection
|
||||
host_id={0}
|
||||
current_ip={main_host_public_ip || ""}
|
||||
/>
|
||||
<InterfaceConfigSection
|
||||
variables={variables}
|
||||
clients={clients}
|
||||
/>
|
||||
</Stack>
|
||||
<Divider className="mb-6" />
|
||||
<Stack className="w-full px-6 pb-8 gap-5 items-stretch">
|
||||
<H2>Other Hosts</H2>
|
||||
{other_hosts[0] ? (
|
||||
{hosts?.[0] ? (
|
||||
<Stack className="w-full gap-4 items-stretch">
|
||||
{other_hosts.map((host) => (
|
||||
<OtherHostCard
|
||||
{hosts.map((host) => (
|
||||
<HostCard
|
||||
key={host.id}
|
||||
host={host}
|
||||
client_count={
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
import type { PagePropsType } from "@/src/types";
|
||||
import type { BunextPageServerFn } from "@moduletrace/bunext/types";
|
||||
|
||||
const server: BunextPageServerFn<PagePropsType> = async (ctx) => {
|
||||
const props = ctx.props as PagePropsType;
|
||||
|
||||
if (!props.main_host?.name) {
|
||||
return {
|
||||
redirect: {
|
||||
destination: `/admin/hosts/add`,
|
||||
permanent: false,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
props: {},
|
||||
};
|
||||
};
|
||||
|
||||
export default server;
|
||||
@@ -8,7 +8,7 @@ import KpiSecondarySection from "./(sections)/kpi-secondary-section";
|
||||
import PeersTableSection from "./(sections)/peers-table-section";
|
||||
|
||||
export default function AdminDashboardPage() {
|
||||
const { clients, hosts, variables } = useDashboardData();
|
||||
const { clients, hosts } = useDashboardData();
|
||||
|
||||
return (
|
||||
<>
|
||||
@@ -21,7 +21,6 @@ export default function AdminDashboardPage() {
|
||||
<KpiSecondarySection
|
||||
clients={clients}
|
||||
hosts={hosts}
|
||||
variables={variables}
|
||||
/>
|
||||
<PeersTableSection clients={clients} />
|
||||
</Stack>
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
import type { BunextPageModuleMeta } from "@moduletrace/bunext/types";
|
||||
import AdminHero from "@/src/components/general/admin-hero";
|
||||
import { SiteData } from "@/src/data/site-data";
|
||||
import Divider from "@/src/components/twui/layout/Divider";
|
||||
import Stack from "@/src/components/twui/layout/Stack";
|
||||
|
||||
export default function AdminWireguardSetupPage() {
|
||||
return (
|
||||
<>
|
||||
<AdminHero
|
||||
title="Setup"
|
||||
description="Setup wireguard and wg-ui. Check if dependencies are installed. Update wg-ui and related packages. Etc."
|
||||
/>
|
||||
<Divider className="mb-6" />
|
||||
<Stack className="w-full px-6 pb-8 gap-5 items-stretch"></Stack>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export const meta: BunextPageModuleMeta = {
|
||||
title: `Admin Wireguard Setup | ${SiteData["SiteName"]}`,
|
||||
description: `Setup wireguard and wg-ui. Check if dependencies are installed. Update wg-ui and related packages. Etc.`,
|
||||
};
|
||||
Reference in New Issue
Block a user