81 lines
3.0 KiB
TypeScript
81 lines
3.0 KiB
TypeScript
import { afterEach, expect, test } from "bun:test";
|
|
import { createContext } from "@wrnexus/core";
|
|
import { createAuthEngine } from "../src/engine.ts";
|
|
import { MemoryAuthStore } from "../src/stores/memory.ts";
|
|
import { configureAuthRuntime } from "../src/plugin.ts";
|
|
import {
|
|
clearDefaultAuthEngine,
|
|
getDefaultAuthRouteOptions,
|
|
setDefaultAuthRouteOptions,
|
|
} from "../src/runtime.ts";
|
|
import { invokeAuthHandler } from "../src/routes/api.ts";
|
|
|
|
afterEach(() => {
|
|
clearDefaultAuthEngine();
|
|
setDefaultAuthRouteOptions({});
|
|
});
|
|
|
|
test("production startup restores runtime-only providers and passkey settings for generated routes", async () => {
|
|
const engine = createAuthEngine({
|
|
store: new MemoryAuthStore(),
|
|
secret: "production-runtime-test-secret-at-least-32-characters",
|
|
passkeys: {
|
|
async authenticationOptions({ rpId }) {
|
|
return { challenge: "test-challenge", rpId, timeout: 60000, userVerification: "required" };
|
|
},
|
|
async registrationOptions() {
|
|
throw new Error("not used");
|
|
},
|
|
async verifyRegistration() {
|
|
return { verified: false };
|
|
},
|
|
async verifyAuthentication() {
|
|
return { verified: false };
|
|
},
|
|
},
|
|
});
|
|
// Build-time credentials absent, followed by server-startup runtime secrets.
|
|
configureAuthRuntime({ engine, oauth: {} });
|
|
const ctx = createContext(
|
|
new Request("https://sso.example/api/auth/oauth/google"),
|
|
new URL("https://sso.example/api/auth/oauth/google"),
|
|
);
|
|
ctx.params = { provider: "google" };
|
|
expect((await invokeAuthHandler("startOAuth", ctx)).status).toBe(404);
|
|
configureAuthRuntime({
|
|
engine,
|
|
baseUrl: "https://sso.example",
|
|
sessionCookieName: "custom_session",
|
|
oauth: { google: { clientId: "runtime-client", clientSecret: "runtime-secret" } },
|
|
passkey: { rpId: "sso.example", origin: "https://sso.example" },
|
|
oauthMfaPath: "/mfa",
|
|
});
|
|
const response = await invokeAuthHandler("startOAuth", ctx);
|
|
expect(response.status).toBe(302);
|
|
const location = new URL(response.headers.get("location")!);
|
|
expect(location.hostname).toBe("accounts.google.com");
|
|
expect(location.searchParams.get("client_id")).toBe("runtime-client");
|
|
expect(location.searchParams.get("redirect_uri")).toBe(
|
|
"https://sso.example/api/auth/oauth/google/callback",
|
|
);
|
|
expect(getDefaultAuthRouteOptions().sessionCookieName).toBe("custom_session");
|
|
const request = new Request("https://sso.example/api/auth/passkeys/login/options", {
|
|
method: "POST",
|
|
headers: {
|
|
"content-type": "application/json",
|
|
origin: "https://sso.example",
|
|
cookie: "wrn-csrf=runtime-test-csrf",
|
|
"x-csrf-token": "runtime-test-csrf",
|
|
},
|
|
body: "{}",
|
|
});
|
|
const result = await invokeAuthHandler(
|
|
"passkeyAuthenticationOptions",
|
|
createContext(request, new URL(request.url)),
|
|
);
|
|
expect(result.status).toBe(200);
|
|
expect((await result.json()).options.rpId).toBe("sso.example");
|
|
configureAuthRuntime({ enabled: false, engine });
|
|
expect((await invokeAuthHandler("startOAuth", ctx)).status).toBe(503);
|
|
});
|