Selaa lähdekoodia

add client olm relationship

miloschwartz 4 kuukautta sitten
vanhempi
commit
346f2db5fb

+ 37 - 9
server/db/schema.ts

@@ -61,7 +61,9 @@ export const resources = sqliteTable("resources", {
         .notNull()
         .default(false),
     isBaseDomain: integer("isBaseDomain", { mode: "boolean" }),
-    applyRules: integer("applyRules", { mode: "boolean" }).notNull().default(false)
+    applyRules: integer("applyRules", { mode: "boolean" })
+        .notNull()
+        .default(false)
 });
 
 export const targets = sqliteTable("targets", {
@@ -114,22 +116,27 @@ export const newts = sqliteTable("newt", {
     })
 });
 
-export const olms = sqliteTable("olms", {
-    olmId: text("id").primaryKey(),
-    secretHash: text("secretHash").notNull(),
-    dateCreated: text("dateCreated").notNull(),
+export const clients = sqliteTable("clients", {
+    clientId: integer("id").primaryKey({ autoIncrement: true }),
     siteId: integer("siteId").references(() => sites.siteId, {
         onDelete: "cascade"
     }),
-
-    // wgstuff
     pubKey: text("pubKey"),
     subnet: text("subnet").notNull(),
     megabytesIn: integer("bytesIn"),
     megabytesOut: integer("bytesOut"),
     lastBandwidthUpdate: text("lastBandwidthUpdate"),
-    type: text("type").notNull(), // "newt" or "wireguard"
-    online: integer("online", { mode: "boolean" }).notNull().default(false),
+    type: text("type").notNull(), // "olm"
+    online: integer("online", { mode: "boolean" }).notNull().default(false)
+});
+
+export const olms = sqliteTable("olms", {
+    olmId: text("id").primaryKey(),
+    secretHash: text("secretHash").notNull(),
+    dateCreated: text("dateCreated").notNull(),
+    clientId: integer("clientId").references(() => clients.clientId, {
+        onDelete: "cascade"
+    })
 });
 
 export const twoFactorBackupCodes = sqliteTable("twoFactorBackupCodes", {
@@ -259,6 +266,24 @@ export const userSites = sqliteTable("userSites", {
         .references(() => sites.siteId, { onDelete: "cascade" })
 });
 
+export const userClients = sqliteTable("userClients", {
+    userId: text("userId")
+        .notNull()
+        .references(() => users.userId, { onDelete: "cascade" }),
+    clientId: integer("clientId")
+        .notNull()
+        .references(() => clients.clientId, { onDelete: "cascade" })
+});
+
+export const roleClients = sqliteTable("roleClients", {
+    roleId: integer("roleId")
+        .notNull()
+        .references(() => roles.roleId, { onDelete: "cascade" }),
+    clientId: integer("clientId")
+        .notNull()
+        .references(() => clients.clientId, { onDelete: "cascade" })
+});
+
 export const roleResources = sqliteTable("roleResources", {
     roleId: integer("roleId")
         .notNull()
@@ -451,3 +476,6 @@ export type ResourceAccessToken = InferSelectModel<typeof resourceAccessToken>;
 export type ResourceWhitelist = InferSelectModel<typeof resourceWhitelist>;
 export type VersionMigration = InferSelectModel<typeof versionMigrations>;
 export type ResourceRule = InferSelectModel<typeof resourceRules>;
+export type Client = InferSelectModel<typeof clients>;
+export type RoleClient = InferSelectModel<typeof roleClients>;
+export type UserClient = InferSelectModel<typeof userClients>;

+ 1 - 0
server/routers/client/index.ts

@@ -0,0 +1 @@
+export * from "./pickClientDefaults";

+ 28 - 18
server/routers/olm/pickOlmDefaults.ts → server/routers/client/pickClientDefaults.ts

@@ -1,6 +1,6 @@
 import { Request, Response, NextFunction } from "express";
 import { db } from "@server/db";
-import { olms, sites } from "@server/db/schema";
+import { clients, olms, sites } from "@server/db/schema";
 import { eq } from "drizzle-orm";
 import response from "@server/lib/response";
 import HttpCode from "@server/types/HttpCode";
@@ -30,7 +30,7 @@ export type PickClientDefaultsResponse = {
     clientSecret: string;
 };
 
-export async function pickOlmDefaults(
+export async function pickClientDefaults(
     req: Request,
     res: Response,
     next: NextFunction
@@ -58,29 +58,39 @@ export async function pickOlmDefaults(
         }
 
         // make sure all the required fields are present
-        if (
-            !site.address ||
-            !site.publicKey ||
-            !site.listenPort ||
-            !site.endpoint
-        ) {
+
+        const sitesRequiredFields = z.object({
+            address: z.string(),
+            publicKey: z.string(),
+            listenPort: z.number(),
+            endpoint: z.string()
+        });
+
+        const parsedSite = sitesRequiredFields.safeParse(site);
+        if (!parsedSite.success) {
             return next(
-                createHttpError(HttpCode.BAD_REQUEST, "Site has no address")
+                createHttpError(
+                    HttpCode.BAD_REQUEST,
+                    "Unable to pick client defaults because: " +
+                        fromError(parsedSite.error).toString()
+                )
             );
         }
 
+        const { address, publicKey, listenPort, endpoint } = parsedSite.data;
+
         const clientsQuery = await db
             .select({
-                subnet: olms.subnet
+                subnet: clients.subnet
             })
-            .from(olms)
-            .where(eq(olms.siteId, site.siteId));
+            .from(clients)
+            .where(eq(clients.siteId, site.siteId));
 
         let subnets = clientsQuery.map((client) => client.subnet);
 
         // exclude the exit node address by replacing after the / with a site block size
         subnets.push(
-            site.address.replace(
+            address.replace(
                 /\/\d+$/,
                 `/${config.getRawConfig().wg_site.block_size}`
             )
@@ -88,7 +98,7 @@ export async function pickOlmDefaults(
         const newSubnet = findNextAvailableCidr(
             subnets,
             config.getRawConfig().wg_site.block_size,
-            site.address
+            address
         );
         if (!newSubnet) {
             return next(
@@ -105,11 +115,11 @@ export async function pickOlmDefaults(
         return response<PickClientDefaultsResponse>(res, {
             data: {
                 siteId: site.siteId,
-                address: site.address,
-                publicKey: site.publicKey,
+                address: address,
+                publicKey: publicKey,
                 name: site.name,
-                listenPort: site.listenPort,
-                endpoint: site.endpoint,
+                listenPort: listenPort,
+                endpoint: endpoint,
                 subnet: newSubnet,
                 clientId,
                 clientSecret: secret

+ 2 - 2
server/routers/external.ts

@@ -7,7 +7,7 @@ import * as target from "./target";
 import * as user from "./user";
 import * as auth from "./auth";
 import * as role from "./role";
-import * as olm from "./olm";
+import * as client from "./client";
 import * as accessToken from "./accessToken";
 import HttpCode from "@server/types/HttpCode";
 import {
@@ -100,7 +100,7 @@ authenticated.get(
     "/site/:siteId/pick-client-defaults",
     verifyOrgAccess,
     verifyUserHasAction(ActionsEnum.createClient),
-    olm.pickOlmDefaults
+    client.pickClientDefaults
 );
 
 // authenticated.get(

+ 1 - 2
server/routers/olm/index.ts

@@ -1,2 +1 @@
-export * from "./pickOlmDefaults";
-export * from "./handleOlmRegisterMessage";
+export * from "./handleOlmRegisterMessage";