diff --git a/src/lib/opnsense/wg.ts b/src/lib/opnsense/wg.ts
index 3bef846..9c4c54a 100644
--- a/src/lib/opnsense/wg.ts
+++ b/src/lib/opnsense/wg.ts
@@ -67,3 +67,41 @@ export interface OpnsenseWgServers {
uuid: string;
}[];
}
+
+/**
+ * Sample response for OPNsense WireGuard clients
+ * ```json
+ * {
+ * "rows": [
+ * {
+ * "uuid": "d99334de-7671-4ca7-9c9b-5f5578acae70",
+ * "enabled": "1",
+ * "name": "Yura-TPX13",
+ * "pubkey": "iJa5JmJbMHNlbEluNwoB2Q8LyrPAfb7S/mluanMcI08=",
+ * "tunneladdress": "fd00::1/112,10.6.0.3/32",
+ * "serveraddress": "",
+ * "serverport": "",
+ * "servers": "wg0"
+ * }
+ * ],
+ * "rowCount": 1,
+ * "total": 10,
+ * "current": 1
+ * }
+ * ```
+ */
+export interface OpnsenseWgClients {
+ rowCount: number;
+ total: number;
+ current: number;
+ rows: {
+ uuid: string;
+ enabled: string;
+ name: string;
+ pubkey: string;
+ tunneladdress: string;
+ serveraddress: string;
+ serverport: string;
+ servers: string;
+ }[];
+}
diff --git a/src/lib/server/db/schema.ts b/src/lib/server/db/schema.ts
index 6b51959..5ad7bd0 100644
--- a/src/lib/server/db/schema.ts
+++ b/src/lib/server/db/schema.ts
@@ -49,7 +49,14 @@ export const wgClients = sqliteTable('wg_clients', {
});
export const wgClientsRelations = relations(wgClients, ({ one }) => ({
- ipAllocation: one(ipAllocations),
+ user: one(users, {
+ fields: [wgClients.userId],
+ references: [users.id],
+ }),
+ ipAllocation: one(ipAllocations, {
+ fields: [wgClients.id],
+ references: [ipAllocations.clientId],
+ }),
}));
export type WgClient = typeof wgClients.$inferSelect;
diff --git a/src/lib/server/db/seed.ts b/src/lib/server/db/seed.ts
index 92f1418..1ebb61e 100644
--- a/src/lib/server/db/seed.ts
+++ b/src/lib/server/db/seed.ts
@@ -1,4 +1,4 @@
-import { users, wgClients } from './schema';
+import { ipAllocations, users, wgClients } from './schema';
import { eq } from 'drizzle-orm';
import assert from 'node:assert';
import { drizzle } from 'drizzle-orm/libsql';
@@ -7,23 +7,27 @@ import * as schema from '$lib/server/db/schema';
assert(process.env.DATABASE_URL, 'DATABASE_URL is not set');
const db = drizzle(process.env.DATABASE_URL, { schema });
-export async function seed() {
+async function seed() {
const user = await db.query.users.findFirst({ where: eq(users.username, 'CaZzzer') });
assert(user, 'User not found');
- const clients = [
+ const clients: typeof wgClients.$inferInsert[] = [
{
userId: user.id,
name: 'Client1',
publicKey: 'BJ5faPVJsDP4CCxNYilmKnwlQXOtXEOJjqIwb4U/CgM=',
privateKey: 'KKqsHDu30WCSrVsyzMkOKbE3saQ+wlx0sBwGs61UGXk=',
preSharedKey: '0LWopbrISXBNHUxr+WOhCSAg+0hD8j3TLmpyzHkBHCQ=',
- ipIndex: 1,
+ // ipIndex: 1,
// allowedIps: '10.18.11.101/32,fd00::1/112',
- }
- ]
+ },
+ ];
+ const returned = await db.insert(wgClients).values(clients).returning({ insertedId: wgClients.id });
- await db.insert(wgClients).values(clients);
+ const ipAllocation: typeof ipAllocations.$inferInsert = {
+ clientId: returned[0].insertedId,
+ };
+ await db.insert(ipAllocations).values(ipAllocation);
}
seed();
diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte
index 6bdb547..28f08c6 100644
--- a/src/routes/+layout.svelte
+++ b/src/routes/+layout.svelte
@@ -19,6 +19,7 @@
{#if user}
Profile
Connections
+ Clients
{/if}
diff --git a/src/routes/api/clients/+server.ts b/src/routes/api/clients/+server.ts
new file mode 100644
index 0000000..5053d83
--- /dev/null
+++ b/src/routes/api/clients/+server.ts
@@ -0,0 +1,28 @@
+import { error, type RequestHandler } from '@sveltejs/kit';
+import { wgClients } from '$lib/server/db/schema';
+import { db } from '$lib/server/db';
+import { eq } from 'drizzle-orm';
+
+export const GET: RequestHandler = async (event) => {
+ if (!event.locals.user) {
+ return error(401, 'Unauthorized');
+ }
+
+ const clients = await findClients(event.locals.user.id);
+ return new Response(
+ JSON.stringify({
+ clients,
+ })
+ );
+};
+
+async function findClients(userId: string) {
+ return db.query.wgClients.findMany({
+ where: eq(wgClients.userId, userId),
+ with: {
+ ipAllocation: true
+ }
+ });
+}
+
+export type Clients = Awaited>;
diff --git a/src/routes/clients/+page.svelte b/src/routes/clients/+page.svelte
new file mode 100644
index 0000000..a8afd60
--- /dev/null
+++ b/src/routes/clients/+page.svelte
@@ -0,0 +1,34 @@
+
+
+
+ Clients
+
+
+
+
+ Name
+ Public Key
+ Private Key
+ Pre-Shared Key
+ IP Allocation
+
+
+ {#each data.clients as client}
+
+ {client.name}
+ {client.publicKey}
+ {client.privateKey}
+ {client.preSharedKey}
+
+ {client.ipAllocation.id}
+
+
+ {/each}
+
+
diff --git a/src/routes/clients/+page.ts b/src/routes/clients/+page.ts
new file mode 100644
index 0000000..643cd24
--- /dev/null
+++ b/src/routes/clients/+page.ts
@@ -0,0 +1,9 @@
+import type { PageLoad } from './$types';
+import type { Clients } from '../api/clients/+server';
+
+export const load: PageLoad = async ({ fetch }) => {
+ const res = await fetch('/api/clients');
+ const { clients } = await res.json() as { clients: Clients };
+
+ return { clients };
+};