Files
WRNexusJS/packages/auth/test/oauth-device-policy.test.ts
T

41 lines
2.1 KiB
TypeScript

import { expect, test } from "bun:test";
import { createAuthEngine } from "../src/engine.ts";
import { MemoryAuthStore } from "../src/stores/memory.ts";
const profile = { id: "google-user", email: "google@example.test", raw: { email_verified: true } };
function setup(providers?: string[]) {
const store = new MemoryAuthStore();
const engine = createAuthEngine({ store, secret: "oauth-device-policy-test-at-least-32-characters",
requireVerifiedEmail: true, requireTrustedDeviceVerification: true,
verifiedOAuthDeviceProviders: providers,
isOAuthEmailVerified: (_provider, value) => value.raw.email_verified === true,
});
return { engine, store };
}
test("explicit verified Google policy satisfies the device check without trusting future password logins", async () => {
const { engine } = setup(["google"]);
const result = await engine.loginWithOAuth("google", profile, undefined, { fingerprint: "new-browser" });
expect(result.ok).toBe(true);
expect(result.session).toBeDefined();
expect(await engine.listTrustedDevices(result.user!.id)).toHaveLength(0);
});
test("device verification remains the default and applies to other providers", async () => {
expect((await setup().engine.loginWithOAuth("google", profile)).code).toBe("mfa-required");
expect((await setup(["google"]).engine.loginWithOAuth("other", profile)).code).toBe("mfa-required");
});
test("unverified provider emails cannot satisfy verification", async () => {
const { engine } = setup(["google"]);
const result = await engine.loginWithOAuth("google", { ...profile, raw: { email_verified: false } });
expect(result.ok).toBe(false);
expect(result.session).toBeUndefined();
});
test("explicit account MFA remains required after verified Google sign-in", async () => {
const { engine } = setup(["google"]);
const first = await engine.loginWithOAuth("google", profile);
await engine.generateRecoveryCodes(first.user!.id);
const result = await engine.loginWithOAuth("google", profile);
expect(result.code).toBe("mfa-required");
expect(result.session).toBeUndefined();
expect(result.requires?.mfa).toContain("recovery-code");
});