From e4f434e730f4bb683523326f8e6fbeaffa0ab439 Mon Sep 17 00:00:00 2001 From: Mohamed Bassem Date: Sun, 30 Nov 2025 00:27:07 +0000 Subject: fix: fix bypass email verification in apiKey.exchange --- packages/trpc/routers/apiKeys.test.ts | 46 +++++++++++++++++++++++++++++++++++ packages/trpc/routers/apiKeys.ts | 10 ++++++++ 2 files changed, 56 insertions(+) (limited to 'packages/trpc') diff --git a/packages/trpc/routers/apiKeys.test.ts b/packages/trpc/routers/apiKeys.test.ts index 1fd2159a..d68eaaf1 100644 --- a/packages/trpc/routers/apiKeys.test.ts +++ b/packages/trpc/routers/apiKeys.test.ts @@ -417,6 +417,52 @@ describe("API Keys Routes", () => { }), ).rejects.toThrow(/UNAUTHORIZED/); }); + + test("rejects unverified user when email verification is enabled", async ({ + db, + }) => { + // Import User model to create an unverified user directly + const { User } = await import("../models/users"); + + // Create user with password but without email verification + await User.createRaw(db, { + name: "Unverified User", + email: "unverified@test.com", + password: await ( + await import("../auth") + ).hashPassword("password123", "test-salt"), + salt: "test-salt", + emailVerified: null, // User is not verified + }); + + // Mock serverConfig to enable email verification requirement + const originalConfig = (await import("@karakeep/shared/config")).default; + vi.spyOn( + originalConfig.auth, + "emailVerificationRequired", + "get", + ).mockReturnValue(true); + + const { createCallerFactory } = await import("../index"); + const { appRouter } = await import("./_app"); + const createCaller = createCallerFactory(appRouter); + const caller = createCaller({ + user: null, + db, + req: { ip: null }, + }); + + // Attempting to exchange should fail with verification error + await expect(() => + caller.apiKeys.exchange({ + keyName: "Extension Key", + email: "unverified@test.com", + password: "password123", + }), + ).rejects.toThrow(/verify your email/i); + + vi.restoreAllMocks(); + }); }); describe("integration scenarios", () => { diff --git a/packages/trpc/routers/apiKeys.ts b/packages/trpc/routers/apiKeys.ts index 93b7d9ec..763bc23a 100644 --- a/packages/trpc/routers/apiKeys.ts +++ b/packages/trpc/routers/apiKeys.ts @@ -131,6 +131,16 @@ export const apiKeysAppRouter = router({ } catch { throw new TRPCError({ code: "UNAUTHORIZED" }); } + + // Check if email verification is required and if the user has verified their email + if (serverConfig.auth.emailVerificationRequired && !user.emailVerified) { + throw new TRPCError({ + message: + "Please verify your email address before generating an API key", + code: "FORBIDDEN", + }); + } + return await generateApiKey(input.keyName, user.id, ctx.db); }), validate: publicProcedure -- cgit v1.2.3-70-g09d2