mirror of
https://github.com/wireadmin/wireadmin
synced 2025-02-26 05:48:44 +00:00
fix
This commit is contained in:
parent
ac5275168c
commit
0dc9e89b6c
@ -1,5 +1,5 @@
|
||||
{
|
||||
"$schema": "https://json.schemastore.org/mocharc.json",
|
||||
"require": ["tsx", "chai/register-expect"],
|
||||
"require": ["tsx", "chai/register-expect", "mocha.setup.js"],
|
||||
"timeout": 10000
|
||||
}
|
||||
|
1
web/mocha.setup.js
Normal file
1
web/mocha.setup.js
Normal file
@ -0,0 +1 @@
|
||||
process.env.NODE_ENV = 'test';
|
@ -3,7 +3,7 @@
|
||||
"version": "0.0.1",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "vite dev",
|
||||
"dev": "NODE_ENV=development vite dev",
|
||||
"build": "NODE_ENV=build vite build",
|
||||
"preview": "vite preview",
|
||||
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
|
||||
@ -11,7 +11,7 @@
|
||||
"test": "mocha",
|
||||
"lint": "prettier --check .",
|
||||
"format": "prettier --write .",
|
||||
"start": "node ./build/index.js"
|
||||
"start": "NODE_ENV=production node ./build/index.js"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@sveltejs/adapter-node": "^2.0.1",
|
||||
@ -50,10 +50,12 @@
|
||||
"ioredis": "^5.3.2",
|
||||
"jsonwebtoken": "^9.0.2",
|
||||
"lucide-svelte": "^0.294.0",
|
||||
"node-netkit": "0.1.0-canary.1",
|
||||
"pino": "^8.17.1",
|
||||
"pino-pretty": "^10.3.0",
|
||||
"pretty-bytes": "^6.1.1",
|
||||
"qrcode": "^1.5.3",
|
||||
"svelte-french-toast": "^1.2.0",
|
||||
"tailwind-merge": "^2.1.0",
|
||||
"tailwind-variants": "^0.1.18"
|
||||
}
|
||||
|
@ -32,6 +32,9 @@ dependencies:
|
||||
lucide-svelte:
|
||||
specifier: ^0.294.0
|
||||
version: 0.294.0(svelte@4.2.8)
|
||||
node-netkit:
|
||||
specifier: 0.1.0-canary.1
|
||||
version: 0.1.0-canary.1
|
||||
pino:
|
||||
specifier: ^8.17.1
|
||||
version: 8.17.1
|
||||
@ -44,6 +47,9 @@ dependencies:
|
||||
qrcode:
|
||||
specifier: ^1.5.3
|
||||
version: 1.5.3
|
||||
svelte-french-toast:
|
||||
specifier: ^1.2.0
|
||||
version: 1.2.0(svelte@4.2.8)
|
||||
tailwind-merge:
|
||||
specifier: ^2.1.0
|
||||
version: 2.1.0
|
||||
@ -2068,6 +2074,12 @@ packages:
|
||||
hasBin: true
|
||||
dev: false
|
||||
|
||||
/node-netkit@0.1.0-canary.1:
|
||||
resolution: {integrity: sha512-RjSQt0LBeWPkSlQ8anel3vplQONVahdI5nkA6/PWwA9ZZIY/g/sFB0o62D6PYU264XWssEJFPkRHIpoGBfNBIA==}
|
||||
dependencies:
|
||||
execa: 8.0.1
|
||||
dev: false
|
||||
|
||||
/node-releases@2.0.13:
|
||||
resolution: {integrity: sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==}
|
||||
dev: true
|
||||
@ -2696,6 +2708,15 @@ packages:
|
||||
- sugarss
|
||||
dev: true
|
||||
|
||||
/svelte-french-toast@1.2.0(svelte@4.2.8):
|
||||
resolution: {integrity: sha512-5PW+6RFX3xQPbR44CngYAP1Sd9oCq9P2FOox4FZffzJuZI2mHOB7q5gJBVnOiLF5y3moVGZ7u2bYt7+yPAgcEQ==}
|
||||
peerDependencies:
|
||||
svelte: ^3.57.0 || ^4.0.0
|
||||
dependencies:
|
||||
svelte: 4.2.8
|
||||
svelte-writable-derived: 3.1.0(svelte@4.2.8)
|
||||
dev: false
|
||||
|
||||
/svelte-hmr@0.15.3(svelte@4.2.8):
|
||||
resolution: {integrity: sha512-41snaPswvSf8TJUhlkoJBekRrABDXDMdpNpT2tfHIv4JuhgvHqLMhEPGtaQn0BmbNSTkuz2Ed20DF2eHw0SmBQ==}
|
||||
engines: {node: ^12.20 || ^14.13.1 || >= 16}
|
||||
@ -2753,6 +2774,14 @@ packages:
|
||||
typescript: 5.3.3
|
||||
dev: true
|
||||
|
||||
/svelte-writable-derived@3.1.0(svelte@4.2.8):
|
||||
resolution: {integrity: sha512-cTvaVFNIJ036vSDIyPxJYivKC7ZLtcFOPm1Iq6qWBDo1fOHzfk6ZSbwaKrxhjgy52Rbl5IHzRcWgos6Zqn9/rg==}
|
||||
peerDependencies:
|
||||
svelte: ^3.2.1 || ^4.0.0-next.1
|
||||
dependencies:
|
||||
svelte: 4.2.8
|
||||
dev: false
|
||||
|
||||
/svelte@4.2.8:
|
||||
resolution: {integrity: sha512-hU6dh1MPl8gh6klQZwK/n73GiAHiR95IkFsesLPbMeEZi36ydaXL/ZAb4g9sayT0MXzpxyZjR28yderJHxcmYA==}
|
||||
engines: {node: '>=16'}
|
||||
|
@ -19,13 +19,8 @@ let logger: Logger = pino(
|
||||
pino.multistream([prettyStream]),
|
||||
);
|
||||
|
||||
fsTouch(LOG_FILE_PATH)
|
||||
.then(() => fsAccess(LOG_FILE_PATH))
|
||||
.then((ok) => {
|
||||
if (!ok) {
|
||||
logger.warn('Log file is not accessible');
|
||||
return;
|
||||
}
|
||||
if (fsAccess(LOG_FILE_PATH)) {
|
||||
fsTouch(LOG_FILE_PATH).then(() => {
|
||||
logger = pino(
|
||||
{
|
||||
level: LOG_LEVEL,
|
||||
@ -37,7 +32,9 @@ fsTouch(LOG_FILE_PATH)
|
||||
}),
|
||||
]),
|
||||
);
|
||||
})
|
||||
.catch(console.error);
|
||||
});
|
||||
} else {
|
||||
logger.warn('Log file is not accessible');
|
||||
}
|
||||
|
||||
export default logger;
|
||||
|
@ -1,20 +1,21 @@
|
||||
import { execaCommand } from 'execa';
|
||||
import { execa } from 'execa';
|
||||
import logger from '$lib/logger';
|
||||
import { ip } from 'node-netkit';
|
||||
|
||||
export default class Network {
|
||||
public static async dropInterface(inet: string) {
|
||||
await execaCommand(`ip link delete dev ${inet}`);
|
||||
await execa(`ip link delete dev ${inet}`, { shell: true });
|
||||
}
|
||||
|
||||
public static async defaultInterface(): Promise<string> {
|
||||
const { stdout: o } = await execaCommand(`ip route list default | awk '{print $5}'`);
|
||||
return o.trim();
|
||||
const route = await ip.route.defaultRoute();
|
||||
if (!route) throw new Error('No default route found');
|
||||
return route.dev;
|
||||
}
|
||||
|
||||
public static async interfaceExists(inet: string): Promise<boolean> {
|
||||
try {
|
||||
const { stdout: o } = await execaCommand(`ip link show | grep ${inet}`);
|
||||
console.log(o);
|
||||
const { stdout: o } = await execa(`ip link show | grep ${inet}`, { shell: true });
|
||||
return o.trim() !== '';
|
||||
} catch (e) {
|
||||
logger.debug('Interface does not exist:', inet);
|
||||
@ -24,12 +25,13 @@ export default class Network {
|
||||
|
||||
public static async inUsePorts(): Promise<number[]> {
|
||||
const ports = [];
|
||||
const { stdout: output } = await execaCommand(
|
||||
const { stdout: output } = await execa(
|
||||
`netstat -tulpn | grep LISTEN | awk '{print $4}' | awk -F ':' '{print $NF}'`,
|
||||
{ shell: true },
|
||||
);
|
||||
for (const line of output.split('\n')) {
|
||||
const clean = Number(line.trim());
|
||||
if (!isNaN(clean)) ports.push(clean);
|
||||
if (!isNaN(clean) && clean !== 0) ports.push(clean);
|
||||
}
|
||||
|
||||
return ports;
|
||||
|
@ -16,7 +16,7 @@ export function setClient(redis: RedisClient): void {
|
||||
client = redis;
|
||||
}
|
||||
|
||||
if (process.env.NODE_ENV !== 'build') {
|
||||
if (process.env.NODE_ENV && ['development', 'production'].includes(process.env.NODE_ENV)) {
|
||||
setClient(
|
||||
new Redis({
|
||||
port: 6479,
|
||||
|
@ -10,7 +10,7 @@ import logger from '$lib/logger';
|
||||
import { sha256 } from '$lib/hash';
|
||||
import { fsAccess } from '$lib/fs-extra';
|
||||
import { getClient } from '$lib/redis';
|
||||
import { execaCommand } from 'execa';
|
||||
import { execa } from 'execa';
|
||||
|
||||
export class WGServer {
|
||||
readonly id: string;
|
||||
@ -51,7 +51,7 @@ export class WGServer {
|
||||
const server = await this.get();
|
||||
|
||||
if (await Network.interfaceExists(`wg${server.confId}`)) {
|
||||
await execaCommand(`wg-quick down wg${server.confId}`);
|
||||
await execa(`wg-quick down wg${server.confId}`, { shell: true });
|
||||
}
|
||||
|
||||
await this.update({ status: 'down' });
|
||||
@ -70,10 +70,10 @@ export class WGServer {
|
||||
logger.debug('WGServer:Start: isAlreadyUp:', isAlreadyUp);
|
||||
if (isAlreadyUp) {
|
||||
logger.debug('WGServer:Start: interface already up... taking down');
|
||||
await execaCommand(`wg-quick down wg${server.confId}`);
|
||||
await execa(`wg-quick down wg${server.confId}`, { shell: true });
|
||||
}
|
||||
|
||||
await execaCommand(`wg-quick up wg${server.confId}`);
|
||||
await execa(`wg-quick up wg${server.confId}`, { shell: true });
|
||||
|
||||
await this.update({ status: 'up' });
|
||||
return true;
|
||||
@ -137,7 +137,7 @@ export class WGServer {
|
||||
async isUp(): Promise<boolean> {
|
||||
const server = await this.get();
|
||||
try {
|
||||
const res = await execaCommand(`wg show wg${server.confId}`);
|
||||
const res = await execa(`wg show wg${server.confId}`, { shell: true });
|
||||
return res.stdout.includes('wg');
|
||||
} catch (e) {
|
||||
return false;
|
||||
@ -158,7 +158,9 @@ export class WGServer {
|
||||
return usages;
|
||||
}
|
||||
|
||||
const { stdout, stderr } = await execaCommand(`wg show wg${server.confId} transfer`);
|
||||
const { stdout, stderr } = await execa(`wg show wg${server.confId} transfer`, {
|
||||
shell: true,
|
||||
});
|
||||
if (stderr) {
|
||||
logger.warn(`WgServer: GetUsage: ${stderr}`);
|
||||
return usages;
|
||||
@ -502,9 +504,11 @@ function wgPeersStr(configId: number): string[] {
|
||||
}
|
||||
|
||||
export async function generateWgKey(): Promise<WgKey> {
|
||||
const { stdout: privateKey } = await execaCommand('wg genkey');
|
||||
const { stdout: publicKey } = await execaCommand(`echo ${privateKey} | wg pubkey`);
|
||||
const { stdout: preSharedKey } = await execaCommand('wg genkey');
|
||||
const { stdout: privateKey } = await execa('wg genkey', { shell: true });
|
||||
const { stdout: publicKey } = await execa(`echo ${privateKey} | wg pubkey`, {
|
||||
shell: true,
|
||||
});
|
||||
const { stdout: preSharedKey } = await execa('wg genkey', { shell: true });
|
||||
return { privateKey, publicKey, preSharedKey };
|
||||
}
|
||||
|
||||
@ -673,7 +677,9 @@ export async function findServer(
|
||||
|
||||
export async function makeWgIptables(s: WgServer): Promise<{ up: string; down: string }> {
|
||||
const inet = await Network.defaultInterface();
|
||||
const { stdout: inet_address } = await execaCommand(`hostname -i | awk '{print $1}'`);
|
||||
const { stdout: inet_address } = await execa(`hostname -i | awk '{print $1}'`, {
|
||||
shell: true,
|
||||
});
|
||||
|
||||
const source = `${s.address}/24`;
|
||||
const wg_inet = `wg${s.confId}`;
|
||||
|
@ -1,6 +1,8 @@
|
||||
<script lang="ts">
|
||||
import '../app.css';
|
||||
import '$lib/assets/fontawesome/index.css';
|
||||
import { Toaster } from 'svelte-french-toast';
|
||||
</script>
|
||||
|
||||
<slot />
|
||||
<Toaster />
|
||||
|
@ -28,12 +28,12 @@ export const actions: Actions = {
|
||||
|
||||
const server = await findServer(serverId ?? '');
|
||||
if (!server) {
|
||||
logger.error('Server not found');
|
||||
logger.error('Actions: RenameServer: Server not found');
|
||||
return error(404, 'Not found');
|
||||
}
|
||||
|
||||
if (!NameSchema.safeParse(name).success) {
|
||||
logger.error('Peer name is invalid');
|
||||
logger.error('Actions: RenameServer: Server name is invalid');
|
||||
return error(400, 'Bad Request');
|
||||
}
|
||||
|
||||
@ -69,11 +69,11 @@ export const actions: Actions = {
|
||||
});
|
||||
|
||||
return {
|
||||
ok: true,
|
||||
form,
|
||||
serverId,
|
||||
};
|
||||
} catch (e: any) {
|
||||
logger.error('Exception:', e);
|
||||
} catch (e) {
|
||||
logger.error(e);
|
||||
return setError(form, 'Unhandled Exception');
|
||||
}
|
||||
},
|
||||
|
@ -19,22 +19,19 @@
|
||||
FormSwitch,
|
||||
FormValidation,
|
||||
} from '$lib/components/ui/form';
|
||||
import { goto } from '$app/navigation';
|
||||
import { FormItem } from '$lib/components/ui/form/index.js';
|
||||
import { cn } from '$lib/utils';
|
||||
import {
|
||||
Collapsible,
|
||||
CollapsibleContent,
|
||||
CollapsibleTrigger,
|
||||
} from '$lib/components/ui/collapsible';
|
||||
import { Collapsible, CollapsibleContent, CollapsibleTrigger } from '$lib/components/ui/collapsible';
|
||||
import { Button } from '$lib/components/ui/button';
|
||||
import toast from 'svelte-french-toast';
|
||||
|
||||
let loading: boolean = false;
|
||||
let dialogOpen = false;
|
||||
|
||||
let form: SuperValidated<CreateServerSchemaType>;
|
||||
</script>
|
||||
|
||||
<Dialog>
|
||||
<Dialog bind:open={dialogOpen}>
|
||||
<DialogTrigger asChild let:builder>
|
||||
<slot {builder} />
|
||||
</DialogTrigger>
|
||||
@ -50,7 +47,7 @@
|
||||
method={'POST'}
|
||||
let:config
|
||||
options={{
|
||||
onSubmit: (s) => {
|
||||
onSubmit: () => {
|
||||
loading = true;
|
||||
},
|
||||
onError: (e) => {
|
||||
@ -60,9 +57,11 @@
|
||||
onResult: ({ result }) => {
|
||||
loading = false;
|
||||
if (result.type === 'success') {
|
||||
goto(`/${result.data.serverId}`);
|
||||
dialogOpen = false;
|
||||
toast.success('Server created successfully!');
|
||||
} else {
|
||||
console.error('Server-failure: Result:', result);
|
||||
toast.error('Server failed to create.');
|
||||
}
|
||||
},
|
||||
}}
|
||||
@ -89,7 +88,7 @@
|
||||
<FormLabel>Port</FormLabel>
|
||||
<FormInput placeholder={'e.g. 51820'} type={'text'} />
|
||||
<FormDescription
|
||||
>This is the port that the WireGuard server will listen on.</FormDescription
|
||||
>This is the port that the WireGuard server will listen on.</FormDescription
|
||||
>
|
||||
<FormValidation />
|
||||
</FormItem>
|
||||
@ -119,7 +118,7 @@
|
||||
<FormLabel>DNS</FormLabel>
|
||||
<FormInput placeholder={'e.g. 1.1.1.1'} type={'text'} />
|
||||
<FormDescription
|
||||
>Optional. This is the DNS server that will be pushed to clients.</FormDescription
|
||||
>Optional. This is the DNS server that will be pushed to clients.</FormDescription
|
||||
>
|
||||
<FormValidation />
|
||||
</FormItem>
|
||||
|
@ -10,26 +10,28 @@ export const load: PageServerLoad = async ({ params }) => {
|
||||
const { serverId } = params;
|
||||
const exists = await WGServer.exists(serverId ?? '');
|
||||
|
||||
if (exists) {
|
||||
const wg = new WGServer(serverId);
|
||||
const server = await wg.get();
|
||||
|
||||
if (server.status === 'up') {
|
||||
const hasInterface = await wg.isUp();
|
||||
if (!hasInterface) {
|
||||
await wg.start();
|
||||
}
|
||||
}
|
||||
|
||||
const usage = await wg.getUsage();
|
||||
|
||||
return {
|
||||
server,
|
||||
usage,
|
||||
};
|
||||
if (!exists) {
|
||||
logger.warn(`Server not found. Redirecting to home page. ServerId: ${serverId}`);
|
||||
throw redirect(303, '/');
|
||||
}
|
||||
|
||||
throw error(404, 'Not found');
|
||||
const wg = new WGServer(serverId);
|
||||
const server = await wg.get();
|
||||
|
||||
if (server.status === 'up') {
|
||||
const hasInterface = await wg.isUp();
|
||||
if (!hasInterface) {
|
||||
logger.debug(`Interface not found. Starting WireGuard. ServerId: ${serverId}`);
|
||||
await wg.start();
|
||||
}
|
||||
}
|
||||
|
||||
const usage = await wg.getUsage();
|
||||
|
||||
return {
|
||||
server,
|
||||
usage,
|
||||
};
|
||||
};
|
||||
|
||||
export const actions: Actions = {
|
||||
@ -98,19 +100,19 @@ export const actions: Actions = {
|
||||
const wg = new WGServer(server.id);
|
||||
await wg.remove();
|
||||
}
|
||||
|
||||
return { ok: true };
|
||||
} catch (e) {
|
||||
console.error('Exception:', e);
|
||||
logger.error(e);
|
||||
throw error(500, 'Unhandled Exception');
|
||||
}
|
||||
|
||||
return redirect(303, '/');
|
||||
},
|
||||
'change-server-state': async ({ request, params }) => {
|
||||
const { serverId } = params;
|
||||
|
||||
const server = await findServer(serverId ?? '');
|
||||
if (!server) {
|
||||
logger.error('Action: ChangeState: Server not found');
|
||||
logger.warn(`Action: ChangeState: Server not found. ServerId: ${serverId}`);
|
||||
throw redirect(303, '/');
|
||||
}
|
||||
|
||||
@ -140,19 +142,20 @@ export const actions: Actions = {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return { ok: true };
|
||||
} catch (e) {
|
||||
logger.error({
|
||||
message: 'Exception: ChangeState',
|
||||
message: `Exception: ChangeState. ServerId: ${serverId}`,
|
||||
exception: e,
|
||||
});
|
||||
throw error(500, 'Unhandled Exception');
|
||||
}
|
||||
|
||||
return { ok: true };
|
||||
},
|
||||
create: async (event) => {
|
||||
const form = await superValidate(event, CreatePeerSchema);
|
||||
if (!form.valid) {
|
||||
logger.warn('CreatePeer: Bad Request: failed to validate form');
|
||||
return setError(form, 'Bad Request');
|
||||
}
|
||||
|
||||
@ -162,13 +165,13 @@ export const actions: Actions = {
|
||||
try {
|
||||
const server = await findServer(serverId ?? '');
|
||||
if (!server) {
|
||||
console.error('Server not found');
|
||||
logger.error(`Server not found. ServerId: ${serverId}`);
|
||||
return setError(form, 'Server not found');
|
||||
}
|
||||
|
||||
const freeAddress = await WGServer.getFreePeerIp(server.id);
|
||||
if (!freeAddress) {
|
||||
console.error(`ERR: ServerId: ${serverId};`, 'No free addresses;');
|
||||
logger.error(`No free addresses. ServerId: ${serverId}`);
|
||||
return setError(form, 'No free addresses');
|
||||
}
|
||||
|
||||
@ -186,13 +189,16 @@ export const actions: Actions = {
|
||||
});
|
||||
|
||||
if (!addedPeer) {
|
||||
console.error(`ERR: ServerId: ${serverId};`, 'Failed to add peer;');
|
||||
logger.error(`Failed to add peer. ServerId: ${serverId}`);
|
||||
return setError(form, 'Failed to add peer');
|
||||
}
|
||||
|
||||
return { ok: true };
|
||||
return { form };
|
||||
} catch (e) {
|
||||
console.error('Exception:', e);
|
||||
logger.error({
|
||||
message: `Exception: CreatePeer. ServerId: ${serverId}`,
|
||||
exception: e,
|
||||
});
|
||||
return setError(form, 'Unhandled Exception');
|
||||
}
|
||||
},
|
||||
|
@ -14,27 +14,27 @@
|
||||
FormButton,
|
||||
FormField,
|
||||
FormInput,
|
||||
FormItem,
|
||||
FormLabel,
|
||||
FormValidation,
|
||||
} from '$lib/components/ui/form';
|
||||
import { FormItem } from '$lib/components/ui/form/index.js';
|
||||
import { cn } from '$lib/utils';
|
||||
import { invalidateAll } from '$app/navigation';
|
||||
import { createEventDispatcher } from 'svelte';
|
||||
|
||||
const dispatch = createEventDispatcher();
|
||||
import toast from 'svelte-french-toast';
|
||||
|
||||
let loading: boolean = false;
|
||||
let dialogOpen = false;
|
||||
|
||||
let form: SuperValidated<CreatePeerSchemaType>;
|
||||
|
||||
const handleSuccess = async () => {
|
||||
await invalidateAll();
|
||||
dispatch('close', 'OK');
|
||||
toast.success('Peer created!');
|
||||
dialogOpen = false;
|
||||
};
|
||||
</script>
|
||||
|
||||
<Dialog>
|
||||
<Dialog bind:open={dialogOpen}>
|
||||
<DialogTrigger asChild let:builder>
|
||||
<slot {builder} />
|
||||
</DialogTrigger>
|
||||
@ -50,7 +50,7 @@
|
||||
method={'POST'}
|
||||
let:config
|
||||
options={{
|
||||
onSubmit: (s) => {
|
||||
onSubmit: () => {
|
||||
loading = true;
|
||||
},
|
||||
onError: (e) => {
|
||||
@ -61,6 +61,7 @@
|
||||
if (result.type === 'success') {
|
||||
handleSuccess();
|
||||
} else {
|
||||
toast.error('Failed to create peer');
|
||||
console.error('Server-failure: Result:', result);
|
||||
}
|
||||
loading = false;
|
||||
|
@ -8,7 +8,7 @@ export const GET: RequestHandler = async () => {
|
||||
|
||||
// if the host is not set, then we are using the server's public IP
|
||||
if (!WG_HOST) {
|
||||
const { stdout: resp } = await execaCommand('curl -s ifconfig.me');
|
||||
const { stdout: resp } = await execa('curl -s ifconfig.me', { shell: true });
|
||||
WG_HOST = resp.trim();
|
||||
}
|
||||
|
||||
|
18
web/tests/network.test.ts
Normal file
18
web/tests/network.test.ts
Normal file
@ -0,0 +1,18 @@
|
||||
import Network from '$lib/network';
|
||||
|
||||
describe('Network', () => {
|
||||
it('should return default interface', async () => {
|
||||
const inet = await Network.defaultInterface();
|
||||
console.log(inet);
|
||||
});
|
||||
|
||||
it('should return in use ports', async () => {
|
||||
const ports = await Network.inUsePorts();
|
||||
console.log(ports);
|
||||
});
|
||||
|
||||
it('should check interface exists', async () => {
|
||||
const exists = await Network.interfaceExists('lo');
|
||||
console.log(exists);
|
||||
});
|
||||
});
|
8
web/tests/wireguard.test.ts
Normal file
8
web/tests/wireguard.test.ts
Normal file
@ -0,0 +1,8 @@
|
||||
import { generateWgKey } from '$lib/wireguard';
|
||||
|
||||
describe('Keys', () => {
|
||||
it('should generate a key', async () => {
|
||||
const keys = await generateWgKey();
|
||||
console.log(keys);
|
||||
});
|
||||
});
|
Loading…
Reference in New Issue
Block a user