Files
2026-05-27 23:29:53 +01:00

3.5 KiB

Capability Spec Delta: api-auth-static-principal (api-auth-static-principal)

Package: @suaveplan/api-auth-static-principal Status: SHIPPED

ADDED Requirements

Requirement: resolveSession returns the configured Principal verbatim

The package SHALL return the exact Principal from options.principal on every resolveSession() call, regardless of request shape. The returned Principal MUST deep-equal the configured one (no mutation, no reference-leak across calls).

Scenario: every request resolves to the configured Principal

  • WHEN the adapter is configured with principal: { id: "u1", scopes: ["x:write"], tenantId: "acme" } AND two distinct requests are processed
  • THEN both resolveSession() calls return Principals that deep-equal the configured one

Scenario: returned Principal is not the same reference each call

  • WHEN two resolveSession() calls are made
  • THEN the returned objects are deep-equal AND callers cannot mutate one and affect the other (defensive clone OR documented frozen reference — pin one)

Verified by: src/factory/create-static-principal-resolver.test.ts::"every request resolves to the configured Principal" AND src/factory/create-static-principal-resolver.test.ts::"returned Principal is isolated across calls"


Requirement: nullForPaths overrides specific routes

When options.nullForPaths is set, resolveSession() SHALL return null for requests whose path matches any entry (exact match or glob). Used to test publicRoutes behaviour without changing adapter wiring.

Scenario: matching path returns null

  • WHEN nullForPaths: ["/webhooks/*"] is configured AND the request path is /webhooks/stripe
  • THEN resolveSession() returns null

Scenario: non-matching path returns the Principal

  • WHEN nullForPaths: ["/webhooks/*"] is configured AND the request path is /billing/invoices
  • THEN resolveSession() returns the configured Principal

Verified by: src/factory/create-static-principal-resolver.test.ts::"matching path in nullForPaths returns null" AND src/factory/create-static-principal-resolver.test.ts::"non-matching path returns the configured Principal"


Requirement: Conforms to AuthSession contract

Scenario: conformance suite passes

  • WHEN runAuthSessionConformance("static-principal-direct", () => createStaticPrincipalResolver({ principal: P })) runs
  • THEN every invariant passes

Verified by: src/factory/create-static-principal-resolver.spec-conformance.test.ts::"static-principal-direct conforms to AuthSession contract"


Requirement: Options Zod-validated

Scenario: missing principal.id throws

  • WHEN createStaticPrincipalResolver({ principal: { scopes: [], claims: {} } as never })
  • THEN a SuaveplanError with code AUTH_STATIC_PRINCIPAL_INVALID_OPTIONS is thrown synchronously

Verified by: src/options/static-principal-resolver-options.test.ts::"throws when principal.id is missing"


Requirement: Registered in api-host/testing adapter table

Scenario: createTestHost resolves the kind sentinel

  • WHEN createTestHost({ adapters: { "auth.session": { kind: "static-principal", principal: P } } })
  • THEN the resulting host.auth is an instance produced by this factory

Verified by: tests/integration/integration.test.ts::"createTestHost resolves kind:\"static-principal\" to this adapter"