Files
Ekklesia/core/tests/identity-factory.test.ts
T
ekklesiaandClaude Sonnet 5 679a5d225c
CI / verify (pull_request) Successful in 25s
CI / infrastructure-smoke (pull_request) Successful in 12s
CI / migration-smoke (pull_request) Successful in 22s
feat: establish core identity foundation
Adds Core-owned identity contracts, a Core-owned Better Auth database schema
(ekklesia_core_user/session/account/verification), a first-class Core-owned
migration source that coexists with module-owned migrations under the exact
existing migration system, and an explicit Better Auth construction boundary.
No authentication endpoint or sign-in UI is exposed yet (ADR 0010).

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-07-21 16:39:15 -05:00

124 lines
4.5 KiB
TypeScript

import { beforeEach, describe, expect, it, vi } from "vitest";
const betterAuthMock = vi.hoisted(() => vi.fn());
const drizzleAdapterMock = vi.hoisted(() =>
vi.fn((db: unknown, options: unknown) => ({ __adapterOptions: options, db })),
);
vi.mock("better-auth", () => ({ betterAuth: betterAuthMock }));
vi.mock("better-auth/adapters/drizzle", () => ({ drizzleAdapter: drizzleAdapterMock }));
import type { IdentityConfig } from "../src/identity/config.js";
import { createIdentityAuth, IdentityConstructionError } from "../src/identity/factory.js";
import { identityAdapterSchema } from "../src/identity/schema.js";
function validConfig(): IdentityConfig {
return Object.freeze({
baseUrl: "https://identity.example.test",
secret: "correct-horse-battery-staple-0123456789",
trustedOrigins: Object.freeze(["https://identity.example.test"]),
});
}
describe("Core identity Better Auth construction boundary", () => {
beforeEach(() => {
betterAuthMock.mockReset();
drizzleAdapterMock.mockClear();
});
it("constructs explicitly with narrow injected dependencies and returns only a success marker", () => {
betterAuthMock.mockReturnValue({ api: {}, handler: () => undefined });
const fakeDb = { __fakeDb: true };
const result = createIdentityAuth({ config: validConfig(), db: fakeDb as never });
expect(result).toEqual({ constructed: true });
expect(Object.keys(result)).toEqual(["constructed"]);
expect(Object.isFrozen(result)).toBe(true);
});
it("does not expose the raw database, adapter, or Better Auth instance on the returned value", () => {
betterAuthMock.mockReturnValue({ api: {}, handler: () => undefined });
const fakeDb = { __fakeDb: true };
const result = createIdentityAuth({ config: validConfig(), db: fakeDb as never });
expect(JSON.stringify(result)).not.toContain("__fakeDb");
expect(JSON.stringify(result)).not.toContain("handler");
});
it("passes the explicit ekklesia_core_* schema mapping to the Drizzle adapter", () => {
betterAuthMock.mockReturnValue({});
const fakeDb = { __fakeDb: true };
createIdentityAuth({ config: validConfig(), db: fakeDb as never });
expect(drizzleAdapterMock).toHaveBeenCalledTimes(1);
const [db, options] = drizzleAdapterMock.mock.calls[0] as [unknown, unknown];
expect(db).toBe(fakeDb);
expect(options).toEqual({ provider: "pg", schema: identityAdapterSchema });
});
it("enables no provider or plugin beyond the four core models", () => {
betterAuthMock.mockReturnValue({});
createIdentityAuth({ config: validConfig(), db: {} as never });
expect(betterAuthMock).toHaveBeenCalledTimes(1);
const [options] = betterAuthMock.mock.calls[0] as [Record<string, unknown>];
expect(Object.keys(options).sort()).toEqual([
"baseURL",
"database",
"secret",
"trustedOrigins",
]);
expect(options.baseURL).toBe(validConfig().baseUrl);
expect(options.secret).toBe(validConfig().secret);
expect(options.trustedOrigins).toEqual([...validConfig().trustedOrigins]);
});
it("sanitizes a construction failure without leaking the underlying error, secret, or URL", () => {
const hostileSecret = validConfig().secret;
betterAuthMock.mockImplementation(() => {
throw new Error(
`Better Auth failed for secret ${hostileSecret} at https://internal.example.test`,
);
});
let captured: unknown;
try {
createIdentityAuth({ config: validConfig(), db: {} as never });
} catch (error) {
captured = error;
}
expect(captured).toBeInstanceOf(IdentityConstructionError);
expect(captured).toMatchObject({ code: "IDENTITY_CONSTRUCTION_FAILED" });
const publicText = `${String(captured)}\n${
captured instanceof Error ? (captured.stack ?? "") : ""
}`;
expect(publicText).not.toContain(hostileSecret);
expect(publicText).not.toContain("internal.example.test");
});
it("sanitizes an adapter construction failure the same way", () => {
drizzleAdapterMock.mockImplementation(() => {
throw new Error("adapter exploded with postgresql://admin:[email protected]/ekklesia");
});
let captured: unknown;
try {
createIdentityAuth({ config: validConfig(), db: {} as never });
} catch (error) {
captured = error;
}
expect(captured).toBeInstanceOf(IdentityConstructionError);
const publicText = `${String(captured)}\n${
captured instanceof Error ? (captured.stack ?? "") : ""
}`;
expect(publicText).not.toContain("db.internal");
expect(publicText).not.toContain("admin");
});
});