diff --git a/apps/server/src/services/auth.spec.ts b/apps/server/src/services/auth.spec.ts index f0446dfe14..c46688c58d 100644 --- a/apps/server/src/services/auth.spec.ts +++ b/apps/server/src/services/auth.spec.ts @@ -9,6 +9,10 @@ import options from "./options"; let app: Application; +function encodeCred(password: string): string { + return Buffer.from(`dummy:${password}`).toString("base64"); +} + describe("Auth", () => { beforeAll(async () => { const buildApp = (await (import("../../src/app.js"))).default; @@ -72,4 +76,49 @@ describe("Auth", () => { .expect(200); }); }); + + describe("Setup status endpoint", () => { + it("returns totpEnabled: true when TOTP is enabled", async () => { + cls.init(() => { + options.setOption("mfaEnabled", "true"); + options.setOption("mfaMethod", "totp"); + options.setOption("totpVerificationHash", "hi"); + }); + const response = await supertest(app) + .get("/api/setup/status") + .expect(200); + expect(response.body.totpEnabled).toBe(true); + }); + + it("returns totpEnabled: false when TOTP is disabled", async () => { + cls.init(() => { + options.setOption("mfaEnabled", "false"); + }); + const response = await supertest(app) + .get("/api/setup/status") + .expect(200); + expect(response.body.totpEnabled).toBe(false); + }); + }); + + describe("checkCredentials TOTP enforcement", () => { + beforeAll(() => { + config.General.noAuthentication = false; + refreshAuth(); + }); + + it("does not require TOTP token when TOTP is disabled", async () => { + cls.init(() => { + options.setOption("mfaEnabled", "false"); + }); + // Will still fail with 401 due to wrong password, but NOT because of missing TOTP + const response = await supertest(app) + .get("/api/setup/sync-seed") + .set("trilium-cred", encodeCred("wrongpassword")) + .expect(401); + // The error should be about password, not TOTP + expect(response.text).toContain("Incorrect password"); + }); + }); }, 60_000); +