From 9dd472c59b8bdbb902617b28cc33fd17ffd9ce28 Mon Sep 17 00:00:00 2001 From: Owen Date: Mon, 3 Nov 2025 16:54:06 -0800 Subject: [PATCH] Creating olm working --- bruno/Auth/login.bru | 4 ++-- bruno/Olm/createOlm.bru | 15 ++++++++++++ bruno/Olm/folder.bru | 8 +++++++ bruno/bruno.json | 2 +- server/routers/client/createClient.ts | 34 ++++++++++++++++++++++++--- server/routers/external.ts | 1 - server/routers/integration.ts | 3 ++- server/routers/olm/createOlm.ts | 26 ++++++++++++++++---- 8 files changed, 81 insertions(+), 12 deletions(-) create mode 100644 bruno/Olm/createOlm.bru create mode 100644 bruno/Olm/folder.bru diff --git a/bruno/Auth/login.bru b/bruno/Auth/login.bru index 4ca7b412..3825a252 100644 --- a/bruno/Auth/login.bru +++ b/bruno/Auth/login.bru @@ -5,14 +5,14 @@ meta { } post { - url: http://localhost:4000/api/v1/auth/login + url: http://localhost:3000/api/v1/auth/login body: json auth: none } body:json { { - "email": "owen@pangolin.net", + "email": "admin@fosrl.io", "password": "Password123!" } } diff --git a/bruno/Olm/createOlm.bru b/bruno/Olm/createOlm.bru new file mode 100644 index 00000000..ca755dea --- /dev/null +++ b/bruno/Olm/createOlm.bru @@ -0,0 +1,15 @@ +meta { + name: createOlm + type: http + seq: 1 +} + +put { + url: http://localhost:3000/api/v1/olm + body: none + auth: inherit +} + +settings { + encodeUrl: true +} diff --git a/bruno/Olm/folder.bru b/bruno/Olm/folder.bru new file mode 100644 index 00000000..d245e6d1 --- /dev/null +++ b/bruno/Olm/folder.bru @@ -0,0 +1,8 @@ +meta { + name: Olm + seq: 15 +} + +auth { + mode: inherit +} diff --git a/bruno/bruno.json b/bruno/bruno.json index f0ed66b3..f19d936a 100644 --- a/bruno/bruno.json +++ b/bruno/bruno.json @@ -1,6 +1,6 @@ { "version": "1", - "name": "Pangolin Saas", + "name": "Pangolin", "type": "collection", "ignore": [ "node_modules", diff --git a/server/routers/client/createClient.ts b/server/routers/client/createClient.ts index a30ffb38..5e73476a 100644 --- a/server/routers/client/createClient.ts +++ b/server/routers/client/createClient.ts @@ -20,11 +20,12 @@ import logger from "@server/logger"; import { eq, and } from "drizzle-orm"; import { fromError } from "zod-validation-error"; import moment from "moment"; -import { hashPassword } from "@server/auth/password"; +import { hashPassword, verifyPassword } from "@server/auth/password"; import { isValidCIDR, isValidIP } from "@server/lib/validators"; import { isIpInCidr } from "@server/lib/ip"; import { OpenAPITags, registry } from "@server/openApi"; import { listExitNodes } from "#dynamic/lib/exitNodes"; +import { generateId } from "@server/auth/sessions/app"; const createClientParamsSchema = z .object({ @@ -37,7 +38,7 @@ const createClientSchema = z name: z.string().min(1).max(255), siteIds: z.array(z.number().int().positive()), olmId: z.string(), - secret: z.string(), + secret: z.string().optional(), subnet: z.string(), type: z.enum(["olm"]) }) @@ -176,6 +177,28 @@ export async function createClient( ); } + // check if the olmId already exists + const [existingOlm] = await db + .select() + .from(olms) + .where(eq(olms.olmId, olmId)) + .limit(1); + + // TODO: HOW DO WE WANT TO AUTH THAT YOU CAN ADOPT AN EXISTING OLM CROSS ORG OTHER THAN MAKING SURE THE SECRET IS CORRECT + if (existingOlm && secret) { + // verify the secret + const validSecret = await verifyPassword( + secret, + existingOlm.secretHash + ); + + if (!validSecret) { + return next( + createHttpError(HttpCode.BAD_REQUEST, "Secret is incorrect on existing olm") + ); + } + } + await db.transaction(async (trx) => { // TODO: more intelligent way to pick the exit node const exitNodesList = await listExitNodes(orgId); @@ -229,7 +252,12 @@ export async function createClient( ); } - const secretHash = await hashPassword(secret); + let secretToUse = secret; + if (!secretToUse) { + secretToUse = generateId(48); + } + + const secretHash = await hashPassword(secretToUse); await trx.insert(olms).values({ olmId, diff --git a/server/routers/external.ts b/server/routers/external.ts index b2de8eed..52896fcc 100644 --- a/server/routers/external.ts +++ b/server/routers/external.ts @@ -728,7 +728,6 @@ authenticated.delete( authenticated.put( "/olm", - verifyUserHasAction(ActionsEnum.createOlm), olm.createOlm ); diff --git a/server/routers/integration.ts b/server/routers/integration.ts index 88a8c05e..9115ab2e 100644 --- a/server/routers/integration.ts +++ b/server/routers/integration.ts @@ -558,7 +558,8 @@ authenticated.delete( // ); authenticated.put( - "/olm", + "/user/:userId/olm", + verifyApiKeyUserAccess, verifyApiKeyHasAction(ActionsEnum.createOlm), olm.createOlm ); diff --git a/server/routers/olm/createOlm.ts b/server/routers/olm/createOlm.ts index b9cbafa3..eff67a88 100644 --- a/server/routers/olm/createOlm.ts +++ b/server/routers/olm/createOlm.ts @@ -25,11 +25,15 @@ export type CreateOlmResponse = { const createOlmSchema = z .object({ - userId: z.string().optional(), name: z.string().min(1).max(255) }) .strict(); +const createOlmParamsSchema = z + .object({ + userId: z.string().optional() + }); + export async function createOlm( req: Request, res: Response, @@ -46,12 +50,26 @@ export async function createOlm( ); } - const { userId, name } = parsedBody.data; + const { name } = parsedBody.data; + + const parsedParams = createOlmParamsSchema.safeParse(req.params); + if (!parsedParams.success) { + return next( + createHttpError( + HttpCode.BAD_REQUEST, + fromError(parsedParams.error).toString() + ) + ); + } + + const { userId } = parsedParams.data; let userIdFinal = userId; if (req.user) { // overwrite the user with the one calling because we want to assign the olm to the user creating it userIdFinal = req.user.userId; - } else if (!userIdFinal) { + } + + if (!userIdFinal) { return next( createHttpError( HttpCode.BAD_REQUEST, @@ -67,7 +85,7 @@ export async function createOlm( await db.insert(olms).values({ olmId: olmId, - userId: userId, + userId: userIdFinal, name, secretHash, dateCreated: moment().toISOString()