feat: add authorization bootstrap and HTTP enforcement
Wires Core's identity and authorization domains into apps/api over one shared, validated PostgreSQL pool; adds an explicit, single-use, concurrency-safe platform-owner bootstrap CLI; adds a smallest-possible immutable permission registry with one Core-owned restricted permission (core.authorization.grants.manage); and adds reusable Hono authorization enforcement plus a narrowly scoped /api/v1/grants HTTP API for managing explicit grants only, gated by an exact trusted Origin on every mutation.
This commit is contained in:
@@ -0,0 +1,61 @@
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
|
||||
const poolConstructor = vi.hoisted(() => vi.fn());
|
||||
|
||||
vi.mock("pg", () => ({ Pool: poolConstructor }));
|
||||
|
||||
import { createAuthorizationDrizzleDatabase } from "../src/authorization/database.js";
|
||||
import {
|
||||
bootstrapPlatformOwner,
|
||||
PlatformOwnerBootstrapError,
|
||||
} from "../src/authorization/bootstrap.js";
|
||||
|
||||
describe("Core authorization bootstrap — import and construction safety", () => {
|
||||
it("does not construct a pool or open a connection merely because the module is imported", () => {
|
||||
expect(poolConstructor).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("performs no database work merely by being imported: bootstrapPlatformOwner is only a function reference until called", () => {
|
||||
expect(typeof bootstrapPlatformOwner).toBe("function");
|
||||
expect(poolConstructor).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe("PlatformOwnerBootstrapError", () => {
|
||||
it.each([
|
||||
"PLATFORM_OWNER_BOOTSTRAP_ALREADY_CONSUMED",
|
||||
"PLATFORM_OWNER_BOOTSTRAP_FAILED",
|
||||
"PLATFORM_OWNER_BOOTSTRAP_USER_NOT_FOUND",
|
||||
] as const)("exposes a stable code and a fixed, generic message for %s", (code) => {
|
||||
const error = new PlatformOwnerBootstrapError(code);
|
||||
expect(error.code).toBe(code);
|
||||
expect(error.name).toBe("PlatformOwnerBootstrapError");
|
||||
expect(Object.isFrozen(error)).toBe(true);
|
||||
expect(error.message.length).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
it("never carries a cause, raw driver error, SQL, or stack detail beyond the fixed message", () => {
|
||||
const error = new PlatformOwnerBootstrapError("PLATFORM_OWNER_BOOTSTRAP_FAILED");
|
||||
const publicText = `${String(error)}\n${error.stack ?? ""}`;
|
||||
expect(publicText).toBe(
|
||||
`PlatformOwnerBootstrapError: ${error.message}\nPlatformOwnerBootstrapError: ${error.message}`,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe("bootstrapPlatformOwner — construction without a real database", () => {
|
||||
it("does not construct a pool merely because a database handle was created; only calling bootstrapPlatformOwner would query", () => {
|
||||
poolConstructor.mockClear();
|
||||
poolConstructor.mockImplementation(function fakePool() {
|
||||
return { end: async () => undefined, on: vi.fn() };
|
||||
});
|
||||
|
||||
const { db } = createAuthorizationDrizzleDatabase("postgresql://example.test/ekklesia");
|
||||
|
||||
expect(poolConstructor).toHaveBeenCalledTimes(1);
|
||||
expect(db).toBeDefined();
|
||||
// bootstrapPlatformOwner is intentionally not invoked here: exercising the real transactional
|
||||
// and advisory-lock behavior requires a real PostgreSQL server and is covered by
|
||||
// core/tests/authorization-bootstrap.integration.ts.
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user