Some checks failed
CI / typecheck + lint + boundaries + test + build (push) Has been cancelled
CodeQL / Analyze (javascript-typescript) (push) Has been cancelled
Coverage snapshot / snapshot (push) Has been cancelled
Release Please / release-please (push) Has been cancelled
Sentry PII guard (R31) / pii-guard (push) Has been cancelled
CI / Playwright e2e (push) Has been cancelled
CI / Storybook smoke tests + visual regression (push) Has been cancelled
Mutation testing (nightly) / mutate (push) Has been cancelled
Library trace revalidation (weekly) / revalidate (push) Has been cancelled
Replace NotImplementedError stubs in AuthenticationService with working implementations: createSession signs a HS256 JWT using Payload's instance secret, validateSession verifies and decodes the token then looks up the user, invalidateSession returns a blank cookie with maxAge 0. No external JWT dependency — uses Node crypto HMAC directly. Also clarify withAudit/withAnalytics comments: the wrappers intentionally delegate recording to the use case body (only it knows which fields to extract), so the TODO was misleading.
36 lines
1.7 KiB
TypeScript
36 lines
1.7 KiB
TypeScript
import type { IAuditLog } from "./audit-log.interface";
|
|
import { attachBrand } from "@repo/core-shared/conformance";
|
|
|
|
/**
|
|
* Phantom-type brand attached at wrap time by `withAudit`. The conformance
|
|
* system uses this as the type-level seam for mutating use cases that
|
|
* declare `audits: [...]` in their manifest — without `__audited`, the
|
|
* binding is not assignable to `ProductionUseCase<I, O, M>` when M demands
|
|
* it. At runtime the brand is a non-enumerable property attached by
|
|
* `attachBrand` from `@repo/core-shared/conformance`, so the boot-time
|
|
* assertion can verify the binding went through the audit-aware path.
|
|
*/
|
|
export type Audited<F> = F & { readonly __audited: true };
|
|
|
|
/**
|
|
* Use-case wrapper applied at DI bind time. The wrapper is a thin closure
|
|
* that forwards to `fn` unchanged and carries the `__audited` brand. The
|
|
* forward closure (instead of returning `fn` directly) keeps the brand on
|
|
* a fresh function so the caller's original `fn` is not mutated — important
|
|
* when the same factory output is used elsewhere unwrapped (dev-seed paths,
|
|
* tests).
|
|
*/
|
|
export function withAudit<Args extends unknown[], R>(
|
|
// The wrapper attaches the brand and ensures the auditLog dependency is
|
|
// available at bind time. Actual `auditLog.record()` calls live in the
|
|
// use case body — only the use case knows which fields to extract from
|
|
// its input/output for the audit entry.
|
|
auditLog: IAuditLog,
|
|
fn: (...args: Args) => Promise<R>,
|
|
): Audited<(...args: Args) => Promise<R>> {
|
|
void auditLog;
|
|
const wrapped: (...args: Args) => Promise<R> = (...args) => fn(...args);
|
|
attachBrand(wrapped, "__audited");
|
|
return wrapped as Audited<(...args: Args) => Promise<R>>;
|
|
}
|