mirror of
https://github.com/wireadmin/wireadmin
synced 2025-04-26 00:50:37 +00:00
update
This commit is contained in:
parent
3fa6e3e63e
commit
2f2f0eac39
@ -1,11 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<svg width="36px" height="36px" viewBox="0 0 36 36" version="1.1" xmlns="http://www.w3.org/2000/svg"
|
|
||||||
>
|
|
||||||
<!-- Generator: Sketch 62 (91390) - https://sketch.com -->
|
|
||||||
<title>vps</title>
|
|
||||||
<desc>Created with Sketch.</desc>
|
|
||||||
<g id="vps" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
|
||||||
<path d="M33,26 L33,31 C33,32.6568542 31.6568542,34 30,34 L6,34 C4.34314575,34 3,32.6568542 3,31 L3,26 L33,26 Z M30,29 L6,29 L6,31 L30,31 L30,29 Z M33,15 L33,23 L3,23 L3,15 L33,15 Z M30,18 L6,18 L6,20 L30,20 L30,18 Z M30,4 C31.6568542,4 33,5.34314575 33,7 L33,12 L3,12 L3,7 C3,5.34314575 4.34314575,4 6,4 L30,4 Z M30,7 L6,7 L6,9 L30,9 L30,7 Z"
|
|
||||||
fill="#991b1b"></path>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 751 B |
@ -1,12 +1,36 @@
|
|||||||
import type { Actions } from '@sveltejs/kit';
|
import { type Actions, error } from '@sveltejs/kit';
|
||||||
import type { PageServerLoad } from './$types';
|
import type { PageServerLoad } from './$types';
|
||||||
|
import { findServer, getServers, WGServer } from '$lib/wireguard';
|
||||||
|
import { superValidate } from 'sveltekit-superforms/server';
|
||||||
|
import { CreateServerSchema } from './schema';
|
||||||
|
import { NameSchema } from '$lib/wireguard/schema';
|
||||||
|
|
||||||
export const load: PageServerLoad = () => {
|
export const load: PageServerLoad = async () => {
|
||||||
return {};
|
return {
|
||||||
|
servers: (await getServers()).map((s) => s),
|
||||||
|
form: superValidate(CreateServerSchema),
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export const actions: Actions = {
|
export const actions: Actions = {
|
||||||
default: async ({ request, cookies }) => {
|
rename: async ({ request, params }) => {
|
||||||
return { message: 'Success!' };
|
const form = await request.formData();
|
||||||
|
const serverId = (form.get('id') ?? '').toString();
|
||||||
|
const name = (form.get('name') ?? '').toString();
|
||||||
|
|
||||||
|
const server = await findServer(serverId ?? '');
|
||||||
|
if (!server) {
|
||||||
|
console.error('Server not found');
|
||||||
|
return error(404, 'Not found');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!NameSchema.safeParse(name).success) {
|
||||||
|
console.error('Peer name is invalid');
|
||||||
|
return error(400, 'Bad Request');
|
||||||
|
}
|
||||||
|
|
||||||
|
await WGServer.update(server.id, { name });
|
||||||
|
|
||||||
|
return { ok: true };
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -1,20 +1,62 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Button } from '$lib/components/ui/button';
|
import { Button } from '$lib/components/ui/button';
|
||||||
import BasePage from '$lib/components/page/BasePage.svelte';
|
import BasePage from '$lib/components/page/BasePage.svelte';
|
||||||
import * as Card from '$lib/components/ui/card';
|
import type { PageData } from './$types';
|
||||||
|
import CreateServerDialog from './CreateServerDialog.svelte';
|
||||||
|
import Server from './Server.svelte';
|
||||||
|
import { Card, CardHeader, CardTitle } from '$lib/components/ui/card';
|
||||||
|
import fetchAction from '$lib/fetch-action';
|
||||||
|
|
||||||
|
export let data: PageData;
|
||||||
|
export let isOpen = false;
|
||||||
|
|
||||||
|
const handleRename = async (id: string, name: string) => {
|
||||||
|
const resp = await fetchAction({
|
||||||
|
action: '?/rename',
|
||||||
|
method: 'POST',
|
||||||
|
form: { id, name },
|
||||||
|
});
|
||||||
|
if (resp.statusText !== 'OK') {
|
||||||
|
console.error('err: failed to rename server');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
data.servers = data.servers.map((server) => {
|
||||||
|
if (server.id === id) {
|
||||||
|
server.name = name;
|
||||||
|
}
|
||||||
|
return server;
|
||||||
|
});
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<BasePage showLogout={true}>
|
<BasePage showLogout={true}>
|
||||||
<div class={'flex items-center justify-between py-3 px-2'}>
|
<div class={'flex items-center justify-between py-3 px-2'}>
|
||||||
<h2 class={'font-bold text-xl'}>Hello there 👋</h2>
|
<h2 class={'font-bold text-xl'}>Hello there 👋</h2>
|
||||||
|
<Button on:click={() => (isOpen = true)}>
|
||||||
|
<i class="fas fa-plus mr-2"></i>
|
||||||
|
Create Server
|
||||||
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Card.Root>
|
<div class="space-y-3.5">
|
||||||
<Card.Content>
|
{#if data.servers?.length < 1}
|
||||||
<h1>Welcome to SvelteKit</h1>
|
<Card>No Servers Found</Card>
|
||||||
<p>Visit <a href="https://kit.svelte.dev">kit.svelte.dev</a> to read the documentation</p>
|
{:else}
|
||||||
|
<Card>
|
||||||
<Button variant="outline">Button</Button>
|
<CardHeader>
|
||||||
</Card.Content>
|
<CardTitle>Servers</CardTitle>
|
||||||
</Card.Root>
|
</CardHeader>
|
||||||
|
{#each data.servers as server}
|
||||||
|
<Server
|
||||||
|
{server}
|
||||||
|
on:rename={({ detail }) => {
|
||||||
|
handleRename(server.id.toString(), detail);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
{/each}
|
||||||
|
</Card>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
</BasePage>
|
</BasePage>
|
||||||
|
|
||||||
|
<CreateServerDialog {isOpen} />
|
||||||
|
61
web/src/routes/Server.svelte
Normal file
61
web/src/routes/Server.svelte
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import { Button } from '$lib/components/ui/button';
|
||||||
|
import type { WgServer } from '$lib/typings';
|
||||||
|
import { EditableText } from '$lib/components/editable-text';
|
||||||
|
import { CopiableText } from '$lib/components/copiable-text';
|
||||||
|
import { NameSchema } from '$lib/wireguard/schema';
|
||||||
|
import { Badge } from '$lib/components/ui/badge';
|
||||||
|
import { createEventDispatcher } from 'svelte';
|
||||||
|
import { cn } from '$lib/utils';
|
||||||
|
|
||||||
|
export let server: WgServer;
|
||||||
|
export let addressPort: string = `${server.address}:${server.listen}`;
|
||||||
|
|
||||||
|
const dispatch = createEventDispatcher();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class="flex items-center justify-between p-4 gap-x-4">
|
||||||
|
<div class="w-full md:w-2/3 flex items-center gap-x-2">
|
||||||
|
<div class="flex grow">
|
||||||
|
<div class={'w-12 aspect-square flex items-center justify-center mr-4 rounded-full bg-gray-200 max-md:hidden'}>
|
||||||
|
<i class={'fa-solid fa-server text-gray-400 text-xl'} />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="h-full flex flex-col justify-between col-span-4 gap-y-1.5">
|
||||||
|
<EditableText
|
||||||
|
value={server.name}
|
||||||
|
schema={NameSchema}
|
||||||
|
rootClass="font-medium"
|
||||||
|
inputClass="w-full max-w-[120px]"
|
||||||
|
on:change={({ detail }) => {
|
||||||
|
dispatch('rename', detail.value.toString());
|
||||||
|
}}
|
||||||
|
let:editMode
|
||||||
|
asChild
|
||||||
|
>
|
||||||
|
<a href={`/${server.id}`} title="Manage the Server" class={cn({ hidden: editMode })}>
|
||||||
|
<span class="text-lg md:text-base hover:text-primary hover:font-medium"> {server.name} </span>
|
||||||
|
</a>
|
||||||
|
</EditableText>
|
||||||
|
<CopiableText value={addressPort} class="text-sm" showInHover={true}>
|
||||||
|
<span class={'font-mono text-gray-400 text-xs'}> {addressPort} </span>
|
||||||
|
</CopiableText>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class={'flex col-span-4 justify-end'}>
|
||||||
|
<Badge variant={server.status === 'up' ? 'success' : 'destructive'}>
|
||||||
|
{#if server.status === 'up'}
|
||||||
|
<span class="hidden md:inline">Online</span>
|
||||||
|
<span class="inline md:hidden">Up</span>
|
||||||
|
{:else}
|
||||||
|
<span class="hidden md:inline">Offline</span>
|
||||||
|
<span class="inline md:hidden">Down</span>
|
||||||
|
{/if}
|
||||||
|
</Badge>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<a href={`/${server.id}`} title="Manage the Server" class="hidden md:block">
|
||||||
|
<Button variant="ghost" class="px-3 text-sm">Manage</Button>
|
||||||
|
</a>
|
||||||
|
</div>
|
19
web/src/routes/[serverId]/+layout.svelte
Normal file
19
web/src/routes/[serverId]/+layout.svelte
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
<script>
|
||||||
|
import { Button } from '$lib/components/ui/button';
|
||||||
|
import BasePage from '$lib/components/page/BasePage.svelte';
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<BasePage showLogout={true}>
|
||||||
|
<div class="py-3 px-2">
|
||||||
|
<a href="/" title="Home">
|
||||||
|
<Button variant="outline" class="leading-none px-3 space-x-2.5">
|
||||||
|
<i class="far fa-arrow-left"></i>
|
||||||
|
<span> Back to Home </span>
|
||||||
|
</Button>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="space-y-3.5">
|
||||||
|
<slot />
|
||||||
|
</div>
|
||||||
|
</BasePage>
|
46
web/src/routes/[serverId]/+page.server.ts
Normal file
46
web/src/routes/[serverId]/+page.server.ts
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
import { type Actions, error } from '@sveltejs/kit';
|
||||||
|
import type { PageServerLoad } from './$types';
|
||||||
|
import { findServer, WGServer } from '$lib/wireguard';
|
||||||
|
import { NameSchema } from '$lib/wireguard/schema';
|
||||||
|
|
||||||
|
export const load: PageServerLoad = async ({ params }) => {
|
||||||
|
const { serverId } = params;
|
||||||
|
const server = await findServer(serverId);
|
||||||
|
|
||||||
|
if (server) {
|
||||||
|
return { server };
|
||||||
|
}
|
||||||
|
|
||||||
|
throw error(404, 'Not found');
|
||||||
|
};
|
||||||
|
|
||||||
|
export const actions: Actions = {
|
||||||
|
rename: async ({ request, params }) => {
|
||||||
|
const { serverId } = params;
|
||||||
|
|
||||||
|
const server = await findServer(serverId ?? '');
|
||||||
|
if (!server) {
|
||||||
|
console.error('Server not found');
|
||||||
|
return error(404, 'Not found');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const form = await request.formData();
|
||||||
|
const peerId = (form.get('id') ?? '').toString();
|
||||||
|
const peer = server.peers.find((p) => p.id === peerId);
|
||||||
|
if (!peer) {
|
||||||
|
console.error('Peer not found');
|
||||||
|
return error(404, 'Not found');
|
||||||
|
}
|
||||||
|
|
||||||
|
const name = (form.get('name') ?? '').toString();
|
||||||
|
if (!NameSchema.safeParse(name).success) {
|
||||||
|
console.error('Peer name is invalid');
|
||||||
|
return error(400, 'Bad Request');
|
||||||
|
}
|
||||||
|
|
||||||
|
await WGServer.updatePeer(server.id, peer.publicKey, { name });
|
||||||
|
|
||||||
|
return { ok: true };
|
||||||
|
},
|
||||||
|
};
|
82
web/src/routes/[serverId]/+page.svelte
Normal file
82
web/src/routes/[serverId]/+page.svelte
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import type { PageData } from './$types';
|
||||||
|
import { Card } from '$lib/components/ui/card';
|
||||||
|
import CreatePeerDialog from './CreatePeerDialog.svelte';
|
||||||
|
import { CardContent, CardFooter, CardHeader, CardTitle } from '$lib/components/ui/card/index.js';
|
||||||
|
import { Button } from '$lib/components/ui/button';
|
||||||
|
import Peer from './Peer.svelte';
|
||||||
|
import fetchAction from '$lib/fetch-action';
|
||||||
|
|
||||||
|
export let data: PageData;
|
||||||
|
export let dialogOpen: boolean = false;
|
||||||
|
|
||||||
|
const handleRename = async (peerId: string, name: string) => {
|
||||||
|
const resp = await fetchAction({
|
||||||
|
action: '?/rename',
|
||||||
|
method: 'POST',
|
||||||
|
form: {
|
||||||
|
id: peerId,
|
||||||
|
name,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
if (resp.statusText !== 'OK') {
|
||||||
|
console.error('err: failed to change peer name.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
data.server.peers = data.server.peers.map((peer) => {
|
||||||
|
if (peer.id === peerId) {
|
||||||
|
peer.name = name;
|
||||||
|
}
|
||||||
|
return peer;
|
||||||
|
});
|
||||||
|
console.info('peer name changed!');
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleRemove = async (peerId: string) => {
|
||||||
|
const form = new FormData();
|
||||||
|
form.set('id', peerId);
|
||||||
|
|
||||||
|
const resp = await fetchAction({
|
||||||
|
action: '?/remove',
|
||||||
|
method: 'POST',
|
||||||
|
body: form,
|
||||||
|
});
|
||||||
|
if (resp.statusText !== 'OK') {
|
||||||
|
console.error('err: failed to remove peer.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
data.server.peers = data.server.peers.filter((peer) => peer.id !== peerId);
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<CreatePeerDialog serverId={data.server.id} open={dialogOpen} />
|
||||||
|
|
||||||
|
<Card>Hello there!</Card>
|
||||||
|
|
||||||
|
<Card>
|
||||||
|
<CardHeader class="flex flex-row items-center justify-between">
|
||||||
|
<CardTitle>Clients</CardTitle>
|
||||||
|
<span> </span>
|
||||||
|
</CardHeader>
|
||||||
|
<CardContent>
|
||||||
|
{#each data.server.peers as peer}
|
||||||
|
<Peer
|
||||||
|
{peer}
|
||||||
|
serverKey={data.server.publicKey}
|
||||||
|
serverPort={data.server.listen}
|
||||||
|
serverDNS={data.server.dns}
|
||||||
|
on:rename={({ detail }) => {
|
||||||
|
handleRename(peer.id.toString(), detail);
|
||||||
|
}}
|
||||||
|
on:remove={() => {
|
||||||
|
handleRemove(peer.id.toString());
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
{/each}
|
||||||
|
</CardContent>
|
||||||
|
{#if data.server.peers.length > 0}
|
||||||
|
<CardFooter>
|
||||||
|
<Button class="btn btn-primary" on:click={() => (dialogOpen = true)}>Add Client</Button>
|
||||||
|
</CardFooter>
|
||||||
|
{/if}
|
||||||
|
</Card>
|
97
web/src/routes/[serverId]/Peer.svelte
Normal file
97
web/src/routes/[serverId]/Peer.svelte
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import type { Peer } from '$lib/typings';
|
||||||
|
import { CopiableText } from '$lib/components/copiable-text';
|
||||||
|
import { EditableText } from '$lib/components/editable-text';
|
||||||
|
import { NameSchema } from '$lib/wireguard/schema';
|
||||||
|
import PeerActionButton from './PeerActionButton.svelte';
|
||||||
|
import { createEventDispatcher, onMount } from 'svelte';
|
||||||
|
import { getPeerConf } from '$lib/wireguard/utils';
|
||||||
|
|
||||||
|
export let peer: Peer;
|
||||||
|
|
||||||
|
export let serverKey: string;
|
||||||
|
export let serverPort: number;
|
||||||
|
export let serverDNS: string | null;
|
||||||
|
|
||||||
|
export let conf: string | undefined = undefined;
|
||||||
|
|
||||||
|
export let isLoading: boolean = false;
|
||||||
|
|
||||||
|
onMount(async () => {
|
||||||
|
conf = await getPeerConf({
|
||||||
|
...peer,
|
||||||
|
serverPublicKey: serverKey,
|
||||||
|
port: serverPort,
|
||||||
|
dns: serverDNS,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
const dispatch = createEventDispatcher();
|
||||||
|
|
||||||
|
const handleDownload = () => {
|
||||||
|
if (!conf) {
|
||||||
|
console.error('conf is null');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
console.log('conf', conf);
|
||||||
|
// create a blob
|
||||||
|
const blob = new Blob([conf], { type: 'text/plain' });
|
||||||
|
// create a link
|
||||||
|
const link = document.createElement('a');
|
||||||
|
link.href = window.URL.createObjectURL(blob);
|
||||||
|
link.download = `${peer.name}.conf`;
|
||||||
|
// click the link
|
||||||
|
link.click();
|
||||||
|
// remove the link
|
||||||
|
link.remove();
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleQRCode = async () => {};
|
||||||
|
|
||||||
|
const handleRename = (value: string) => {
|
||||||
|
dispatch('rename', value);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleRemove = () => {
|
||||||
|
dispatch('remove');
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class="flex items-center justify-between p-4 border border-neutral-200/60 rounded-md hover:border-neutral-200">
|
||||||
|
<div class="flex items-center gap-2.5">
|
||||||
|
<div class={'w-12 aspect-square flex items-center justify-center mr-4 rounded-full bg-gray-200 max-md:hidden'}>
|
||||||
|
<i class={'fas fa-user text-gray-400 text-lg'} />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="h-full flex flex-col justify-between col-span-4 gap-y-1.5">
|
||||||
|
<EditableText
|
||||||
|
rootClass={'font-medium col-span-4'}
|
||||||
|
inputClass={'w-20'}
|
||||||
|
schema={NameSchema}
|
||||||
|
value={peer.name}
|
||||||
|
on:change={({ detail }) => {
|
||||||
|
handleRename(detail.value);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<CopiableText value={peer.allowedIps} class={'text-sm'} showInHover={true}>
|
||||||
|
<span class={'font-mono text-gray-400 text-xs'}> {peer.allowedIps} </span>
|
||||||
|
</CopiableText>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="flex items-center justify-center gap-x-3">
|
||||||
|
<!-- QRCode -->
|
||||||
|
<PeerActionButton disabled={isLoading} on:click={handleQRCode}>
|
||||||
|
<i class={'fal text-neutral-700 group-hover:text-primary fa-qrcode'} />
|
||||||
|
</PeerActionButton>
|
||||||
|
|
||||||
|
<!-- Download -->
|
||||||
|
<PeerActionButton disabled={isLoading} on:click={handleDownload}>
|
||||||
|
<i class={'fal text-neutral-700 group-hover:text-primary fa-download'} />
|
||||||
|
</PeerActionButton>
|
||||||
|
|
||||||
|
<!-- Download -->
|
||||||
|
<PeerActionButton loading={isLoading} on:click={handleRemove}>
|
||||||
|
<i class={'fal text-neutral-700 group-hover:text-primary text-lg fa-trash-can'} />
|
||||||
|
</PeerActionButton>
|
||||||
|
</div>
|
||||||
|
</div>
|
35
web/src/routes/[serverId]/PeerActionButton.svelte
Normal file
35
web/src/routes/[serverId]/PeerActionButton.svelte
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import { cn } from '$lib/utils';
|
||||||
|
import { createEventDispatcher } from 'svelte';
|
||||||
|
|
||||||
|
export let disabled: boolean = false;
|
||||||
|
export let loading: boolean = false;
|
||||||
|
|
||||||
|
const dispatch = createEventDispatcher();
|
||||||
|
|
||||||
|
function handleClick() {
|
||||||
|
if (disabled || loading) return;
|
||||||
|
dispatch('click');
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div
|
||||||
|
aria-roledescription="Action"
|
||||||
|
role="button"
|
||||||
|
tabindex="0"
|
||||||
|
class={cn(
|
||||||
|
'group flex items-center justify-center w-10 aspect-square rounded-md',
|
||||||
|
'bg-gray-200/80 hover:bg-gray-100/50',
|
||||||
|
'border border-transparent hover:border-primary',
|
||||||
|
'transition-colors duration-200 ease-in-out',
|
||||||
|
'cursor-pointer',
|
||||||
|
disabled && 'opacity-50 cursor-not-allowed',
|
||||||
|
loading && 'animate-pulse',
|
||||||
|
)}
|
||||||
|
on:click={handleClick}
|
||||||
|
on:keydown={(e) => {
|
||||||
|
if (e.key === 'Enter') handleClick();
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<slot />
|
||||||
|
</div>
|
22
web/src/routes/api/host/+server.ts
Normal file
22
web/src/routes/api/host/+server.ts
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
import type { RequestHandler } from '@sveltejs/kit';
|
||||||
|
import { WG_HOST } from '$env/static/private';
|
||||||
|
import Shell from '$lib/shell';
|
||||||
|
|
||||||
|
export const GET: RequestHandler = async () => {
|
||||||
|
|
||||||
|
let HOSTNAME = WG_HOST;
|
||||||
|
|
||||||
|
// if the host is not set, then we are using the server's public IP
|
||||||
|
if (!HOSTNAME) {
|
||||||
|
const resp = await Shell.exec('curl -s ifconfig.me', true);
|
||||||
|
HOSTNAME = resp.trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if WG_HOST is still not set
|
||||||
|
if (!HOSTNAME) {
|
||||||
|
console.error('WG_HOST is not set');
|
||||||
|
return new Response('NOT_SET', { status: 500, headers: { 'Content-Type': 'text/plain' } });
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Response(HOSTNAME, { status: 200, headers: { 'Content-Type': 'text/plain' } });
|
||||||
|
};
|
@ -9,3 +9,5 @@ export const CreateServerSchema = z.object({
|
|||||||
dns: DnsSchema,
|
dns: DnsSchema,
|
||||||
mtu: MtuSchema,
|
mtu: MtuSchema,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export type CreateServerSchemaType = typeof CreateServerSchema;
|
Loading…
Reference in New Issue
Block a user