41 lines
1.3 KiB
TypeScript
41 lines
1.3 KiB
TypeScript
import { getDb } from "@wrnexus/db";
|
|
import { dbPermissionStore } from "./db.ts";
|
|
import type { PermissionStore } from "./store.ts";
|
|
|
|
export type AuthzIdentityEvent = "signup" | "invitation";
|
|
|
|
interface DefaultRoleState {
|
|
signup: string[];
|
|
invitation: string[];
|
|
store?: PermissionStore;
|
|
}
|
|
|
|
const key = Symbol.for("@wrnexus/authz:default-roles:v1");
|
|
|
|
function state(): DefaultRoleState {
|
|
const global = globalThis as Record<PropertyKey, unknown>;
|
|
return (global[key] ??= { signup: [], invitation: [] }) as DefaultRoleState;
|
|
}
|
|
|
|
export function setDefaultAuthzRoles(roles: Partial<DefaultRoleState>): void {
|
|
state().signup = [...(roles.signup ?? [])];
|
|
state().invitation = [...(roles.invitation ?? [])];
|
|
}
|
|
|
|
/** Bind lifecycle role assignment to the same store used by authorization middleware. */
|
|
export function setDefaultAuthzRoleStore(store: PermissionStore): void {
|
|
state().store = store;
|
|
}
|
|
|
|
/** Assign configured identity lifecycle roles through the framework-owned store. */
|
|
export async function assignDefaultAuthzRoles(
|
|
subjectId: string,
|
|
event: AuthzIdentityEvent,
|
|
): Promise<void> {
|
|
if (!subjectId) return;
|
|
const roles = state()[event];
|
|
if (!roles.length) return;
|
|
const store = state().store ?? dbPermissionStore(getDb());
|
|
await Promise.all(roles.map((role) => store.assignRole(subjectId, role)));
|
|
}
|