@reckona/mreact-auth 0.0.202 → 0.0.203

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -54,6 +54,7 @@ export async function requireSession(request, store, options = {}) {
54
54
  * Requires an active session with the requested role or redirects to the configured forbidden route.
55
55
  */
56
56
  export async function requireRole(request, store, role, options = {}) {
57
+ assertValidAuthRequirement(role, "missing-role");
57
58
  const session = await requireSession(request, store, options);
58
59
  const result = authorizeRequirement(session.data.roles, role, "missing-role", options.mode);
59
60
  if (!result.authorized) {
@@ -65,6 +66,7 @@ export async function requireRole(request, store, role, options = {}) {
65
66
  * Requires an active session with the requested permission or redirects to the configured forbidden route.
66
67
  */
67
68
  export async function requirePermission(request, store, permission, options = {}) {
69
+ assertValidAuthRequirement(permission, "missing-permission");
68
70
  const session = await requireSession(request, store, options);
69
71
  const result = authorizeRequirement(session.data.permissions, permission, "missing-permission", options.mode);
70
72
  if (!result.authorized) {
@@ -76,6 +78,7 @@ export async function requirePermission(request, store, permission, options = {}
76
78
  * Checks for a role without redirecting, returning a discriminated authorization result.
77
79
  */
78
80
  export async function tryRequireRole(request, store, role, options = {}) {
81
+ assertValidAuthRequirement(role, "missing-role");
79
82
  const session = await getCurrentSession(request, store, options);
80
83
  if (session === undefined) {
81
84
  return { authorized: false, reason: "missing-session" };
@@ -87,6 +90,7 @@ export async function tryRequireRole(request, store, role, options = {}) {
87
90
  * Checks for a permission without redirecting, returning a discriminated authorization result.
88
91
  */
89
92
  export async function tryRequirePermission(request, store, permission, options = {}) {
93
+ assertValidAuthRequirement(permission, "missing-permission");
90
94
  const session = await getCurrentSession(request, store, options);
91
95
  if (session === undefined) {
92
96
  return { authorized: false, reason: "missing-session" };
@@ -162,10 +166,21 @@ export function __resetAuthForTesting() {
162
166
  }
163
167
  }
164
168
  function authorizeRequirement(available, requirement, reason, mode = "any") {
169
+ assertValidAuthRequirement(requirement, reason);
165
170
  const required = Array.isArray(requirement) ? requirement : [requirement];
166
171
  const authorized = mode === "all" ? hasAll(available, required) : hasAny(available, required);
167
172
  return authorized ? { authorized: true } : { authorized: false, reason };
168
173
  }
174
+ function assertValidAuthRequirement(requirement, reason) {
175
+ if (requirement === undefined ||
176
+ (typeof requirement === "string" && requirement.trim() === "") ||
177
+ (Array.isArray(requirement) &&
178
+ (requirement.length === 0 || requirement.some((value) => value.trim() === "")))) {
179
+ const label = reason === "missing-role" ? "Role" : "Permission";
180
+ const noun = reason === "missing-role" ? "role" : "permission";
181
+ throw new TypeError(`${label} requirement must contain at least one ${noun}.`);
182
+ }
183
+ }
169
184
  function authRedirectTo(options) {
170
185
  return options.redirectTo ?? authRequestConfig()?.redirectTo ?? authConfig.redirectTo;
171
186
  }
@@ -184,7 +199,7 @@ function hasAll(available, required) {
184
199
  }
185
200
  function hasAny(available, required) {
186
201
  if (required === undefined || required.length === 0) {
187
- return true;
202
+ return false;
188
203
  }
189
204
  if (available === undefined || available.length === 0) {
190
205
  return false;
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n createMemorySessionStore,\n createSession,\n destroySession as destroyRouterSession,\n getSession,\n rotateSession as rotateRouterSession,\n type SessionCookieOptions,\n type SessionRecord,\n type SessionStore,\n} from \"@reckona/mreact-router/session\";\nimport { getGlobalRuntimeState } from \"@reckona/mreact-reactive-core/runtime-state\";\nimport { redirect } from \"@reckona/mreact-router\";\n\nexport {\n createMemorySessionStore,\n createSession,\n destroyRouterSession as destroySession,\n getSession,\n rotateRouterSession as rotateSession,\n};\n/** Re-exports router session cookie, record, and store types for auth helpers. */\nexport type { SessionCookieOptions, SessionRecord, SessionStore };\n\n/** Identifies the script element that carries serialized auth claims during hydration. */\nexport const __MREACT_AUTH_SESSION_SCRIPT_ID = \"__mreact_auth_session\";\n\n/** Contains serializable auth claims exposed to role and permission checks. */\nexport interface AuthSessionClaims {\n [claim: string]: unknown;\n permissions?: readonly string[] | undefined;\n roles?: readonly string[] | undefined;\n}\n\n/** Configures redirects and requirement matching for auth guard helpers. */\nexport interface AuthGuardOptions extends SessionCookieOptions {\n forbiddenTo?: string | undefined;\n mode?: AuthRequirementMode | undefined;\n redirectTo?: string | undefined;\n}\n\n/** Configures process-wide auth defaults for redirects and claim serialization. */\nexport interface AuthConfig {\n forbiddenTo?: string | undefined;\n redirectTo?: string | undefined;\n serializeClaims?: AuthClaimsSerializer | undefined;\n}\n\nexport interface AuthRequestOptions {\n config?: AuthConfig | undefined;\n}\n\ninterface ResolvedAuthConfig {\n forbiddenTo: string;\n redirectTo: string;\n serializeClaims: AuthClaimsSerializer;\n}\n\n/** Names one required role or permission, or a set of acceptable values. */\nexport type AuthRequirement = string | readonly string[];\n\n/** Controls whether all listed auth requirements or any one requirement must match. */\nexport type AuthRequirementMode = \"all\" | \"any\";\n\n/** Converts raw session data into serializable claims for auth checks and hydration. */\nexport type AuthClaimsSerializer = (data: unknown) => AuthSessionClaims | undefined;\n\n/** Describes role and permission claims required for authorization. */\nexport interface AuthorizationPolicy {\n permissions?: readonly string[] | undefined;\n roles?: readonly string[] | undefined;\n}\n\n/** Reports whether claims satisfy an authorization policy and why they fail. */\nexport type AuthorizationResult =\n | {\n authorized: true;\n }\n | {\n authorized: false;\n reason: \"missing-permission\" | \"missing-role\";\n };\n\n/** Reports a session-bearing auth guard result without redirecting. */\nexport type TryAuthResult<TData> =\n | {\n authorized: true;\n session: SessionRecord<TData>;\n }\n | {\n authorized: false;\n reason: \"missing-permission\" | \"missing-role\" | \"missing-session\";\n };\n\nconst authRuntimeStateKey = \"__mreactAuthRuntimeState\";\n\ninterface AuthRuntimeRequestState {\n claims?: AuthSessionClaims | undefined;\n config?: AuthConfig | undefined;\n}\n\ninterface AuthRequestStorage {\n getStore(): AuthRuntimeRequestState | undefined;\n run<T>(store: AuthRuntimeRequestState, callback: () => T): T;\n}\n\ninterface AuthRuntimeState {\n browserClaims?: AuthSessionClaims | undefined;\n currentClaims?: AuthSessionClaims | undefined;\n storage?: AuthRequestStorage | undefined;\n}\n\nlet authConfig: ResolvedAuthConfig = {\n forbiddenTo: \"/forbidden\",\n redirectTo: \"/login\",\n serializeClaims: defaultSerializeSessionClaims,\n};\n\n/**\n * Updates the process-wide auth defaults used by the guard helpers.\n *\n * Configure redirect targets and claim serialization before handling requests that call `requireSession()`, `requireRole()`, or `requirePermission()`.\n * For per-request or per-tenant overrides, pass `config` to `runWithAuthRequest()` instead of calling `configureAuth()` while requests are in flight.\n */\nexport function configureAuth(config: AuthConfig): void {\n authConfig = {\n forbiddenTo: config.forbiddenTo ?? authConfig.forbiddenTo,\n redirectTo: config.redirectTo ?? authConfig.redirectTo,\n serializeClaims: config.serializeClaims ?? authConfig.serializeClaims,\n };\n}\n\n/**\n * Runs server-side auth work inside an AsyncLocalStorage-backed request scope.\n *\n * Use this around custom server rendering or tests so `getSessionClaims()` can read request-local claims.\n */\nexport async function runWithAuthRequest<T>(\n fn: () => T | Promise<T>,\n options: AuthRequestOptions = {},\n): Promise<Awaited<T>> {\n const storage = await authRequestStorage();\n\n return await storage.run(options.config === undefined ? {} : { config: options.config }, fn);\n}\n\n/**\n * Reads the current session and stores serialized claims for the active auth request scope.\n */\nexport async function getCurrentSession<TData>(\n request: Request,\n store: SessionStore<TData>,\n options: SessionCookieOptions = {},\n): Promise<SessionRecord<TData> | undefined> {\n const session = await getSession(request, store, options);\n\n setSessionClaims(session?.data);\n\n return session;\n}\n\n/**\n * Requires an active session or redirects to the configured login route.\n */\nexport async function requireSession<TData>(\n request: Request,\n store: SessionStore<TData>,\n options: AuthGuardOptions = {},\n): Promise<SessionRecord<TData>> {\n const session = await getCurrentSession(request, store, options);\n\n if (session === undefined) {\n redirect(authRedirectTo(options), { status: 303 });\n }\n\n return session;\n}\n\n/**\n * Requires an active session with the requested role or redirects to the configured forbidden route.\n */\nexport async function requireRole<TData extends AuthSessionClaims>(\n request: Request,\n store: SessionStore<TData>,\n role: AuthRequirement,\n options: AuthGuardOptions = {},\n): Promise<SessionRecord<TData>> {\n const session = await requireSession(request, store, options);\n const result = authorizeRequirement(session.data.roles, role, \"missing-role\", options.mode);\n\n if (!result.authorized) {\n redirect(authForbiddenTo(options), { status: 303 });\n }\n\n return session;\n}\n\n/**\n * Requires an active session with the requested permission or redirects to the configured forbidden route.\n */\nexport async function requirePermission<TData extends AuthSessionClaims>(\n request: Request,\n store: SessionStore<TData>,\n permission: AuthRequirement,\n options: AuthGuardOptions = {},\n): Promise<SessionRecord<TData>> {\n const session = await requireSession(request, store, options);\n const result = authorizeRequirement(\n session.data.permissions,\n permission,\n \"missing-permission\",\n options.mode,\n );\n\n if (!result.authorized) {\n redirect(authForbiddenTo(options), { status: 303 });\n }\n\n return session;\n}\n\n/**\n * Checks for a role without redirecting, returning a discriminated authorization result.\n */\nexport async function tryRequireRole<TData extends AuthSessionClaims>(\n request: Request,\n store: SessionStore<TData>,\n role: AuthRequirement,\n options: Pick<AuthGuardOptions, \"mode\"> & SessionCookieOptions = {},\n): Promise<TryAuthResult<TData>> {\n const session = await getCurrentSession(request, store, options);\n\n if (session === undefined) {\n return { authorized: false, reason: \"missing-session\" };\n }\n\n const result = authorizeRequirement(session.data.roles, role, \"missing-role\", options.mode);\n\n return result.authorized ? { authorized: true, session } : result;\n}\n\n/**\n * Checks for a permission without redirecting, returning a discriminated authorization result.\n */\nexport async function tryRequirePermission<TData extends AuthSessionClaims>(\n request: Request,\n store: SessionStore<TData>,\n permission: AuthRequirement,\n options: Pick<AuthGuardOptions, \"mode\"> & SessionCookieOptions = {},\n): Promise<TryAuthResult<TData>> {\n const session = await getCurrentSession(request, store, options);\n\n if (session === undefined) {\n return { authorized: false, reason: \"missing-session\" };\n }\n\n const result = authorizeRequirement(\n session.data.permissions,\n permission,\n \"missing-permission\",\n options.mode,\n );\n\n return result.authorized ? { authorized: true, session } : result;\n}\n\n/**\n * Evaluates session claims against required roles and permissions without reading cookies or redirecting.\n */\nexport function authorizeSession<TData extends AuthSessionClaims>(\n data: TData,\n policy: AuthorizationPolicy,\n): AuthorizationResult {\n if (!hasAll(data.roles, policy.roles)) {\n return {\n authorized: false,\n reason: \"missing-role\",\n };\n }\n\n if (!hasAll(data.permissions, policy.permissions)) {\n return {\n authorized: false,\n reason: \"missing-permission\",\n };\n }\n\n return { authorized: true };\n}\n\n/**\n * Rotates the current session id and refreshes request-local claims.\n */\nexport async function refreshSession<TData>(\n request: Request,\n response: Response,\n store: SessionStore<TData>,\n options: SessionCookieOptions = {},\n): Promise<SessionRecord<TData> | undefined> {\n const session = await rotateRouterSession(request, response, store, options);\n\n setSessionClaims(session?.data);\n\n return session;\n}\n\n/**\n * Destroys the current session and clears request-local claims.\n */\nexport async function revokeCurrentSession<TData>(\n request: Request,\n response: Response,\n store: SessionStore<TData>,\n options: SessionCookieOptions = {},\n): Promise<void> {\n await destroyRouterSession(request, response, store, options);\n setSessionClaims(undefined);\n}\n\n/**\n * Returns the claims captured by `getCurrentSession()` for the current request or hydrated browser document.\n *\n * Server code should call it inside `runWithAuthRequest()` so concurrent requests do not share claim state.\n */\nexport function getSessionClaims<TData extends AuthSessionClaims = AuthSessionClaims>():\n | TData\n | undefined {\n const state = authRuntimeState();\n const requestClaims = state.storage?.getStore()?.claims;\n\n if (requestClaims !== undefined) {\n return requestClaims as TData;\n }\n\n if (typeof document === \"undefined\") {\n warnMissingAuthRequestScope();\n return undefined;\n }\n\n state.browserClaims = readClaimsFromDocument();\n\n return state.browserClaims as TData | undefined;\n}\n\n/** Resets process-wide auth configuration and cached claims for tests. */\nexport function __resetAuthForTesting(): void {\n authConfig = {\n forbiddenTo: \"/forbidden\",\n redirectTo: \"/login\",\n serializeClaims: defaultSerializeSessionClaims,\n };\n const state = authRuntimeState();\n state.browserClaims = undefined;\n state.currentClaims = undefined;\n const requestState = state.storage?.getStore();\n if (requestState !== undefined) {\n requestState.claims = undefined;\n requestState.config = undefined;\n }\n}\n\nfunction authorizeRequirement(\n available: readonly string[] | undefined,\n requirement: AuthRequirement,\n reason: \"missing-permission\" | \"missing-role\",\n mode: AuthRequirementMode = \"any\",\n): AuthorizationResult {\n const required = Array.isArray(requirement) ? requirement : [requirement];\n const authorized = mode === \"all\" ? hasAll(available, required) : hasAny(available, required);\n\n return authorized ? { authorized: true } : { authorized: false, reason };\n}\n\nfunction authRedirectTo(options: AuthGuardOptions): string {\n return options.redirectTo ?? authRequestConfig()?.redirectTo ?? authConfig.redirectTo;\n}\n\nfunction authForbiddenTo(options: AuthGuardOptions): string {\n return options.forbiddenTo ?? authRequestConfig()?.forbiddenTo ?? authConfig.forbiddenTo;\n}\n\nfunction hasAll(\n available: readonly string[] | undefined,\n required: readonly string[] | undefined,\n): boolean {\n if (required === undefined || required.length === 0) {\n return true;\n }\n\n if (available === undefined || available.length === 0) {\n return false;\n }\n\n const values = new Set(available);\n\n return required.every((value) => values.has(value));\n}\n\nfunction hasAny(\n available: readonly string[] | undefined,\n required: readonly string[] | undefined,\n): boolean {\n if (required === undefined || required.length === 0) {\n return true;\n }\n\n if (available === undefined || available.length === 0) {\n return false;\n }\n\n const values = new Set(available);\n\n return required.some((value) => values.has(value));\n}\n\nfunction setSessionClaims(data: unknown): void {\n const serializer = authRequestConfig()?.serializeClaims ?? authConfig.serializeClaims;\n const claims = normalizeSessionClaims(serializer(data));\n const state = authRuntimeState();\n const requestState = state.storage?.getStore();\n\n if (requestState !== undefined) {\n requestState.claims = claims;\n return;\n }\n\n if (typeof document === \"undefined\") {\n return;\n }\n\n const browserClaims = claims !== undefined && writeClaimsToDocument(claims) ? claims : undefined;\n\n if (browserClaims === undefined) {\n document.getElementById(__MREACT_AUTH_SESSION_SCRIPT_ID)?.remove();\n }\n\n state.browserClaims = browserClaims;\n state.currentClaims = browserClaims;\n}\n\nfunction authRequestConfig(): AuthConfig | undefined {\n return authRuntimeState().storage?.getStore()?.config;\n}\n\nasync function authRequestStorage(): Promise<AuthRequestStorage> {\n const state = authRuntimeState();\n if (state.storage === undefined) {\n const { AsyncLocalStorage } = await import(\"node:async_hooks\");\n state.storage ??= new AsyncLocalStorage<AuthRuntimeRequestState>();\n }\n\n return state.storage;\n}\n\nfunction warnMissingAuthRequestScope(): void {\n console.warn(\n \"mreact auth session claims were read on the server without an active auth request scope. Wrap custom server work in runWithAuthRequest().\",\n );\n}\n\nfunction readClaimsFromDocument(): AuthSessionClaims | undefined {\n const node = document.getElementById(__MREACT_AUTH_SESSION_SCRIPT_ID);\n\n if (node?.textContent === undefined || node.textContent === \"\") {\n return undefined;\n }\n\n try {\n const parsed = JSON.parse(node.textContent) as unknown;\n return normalizeSessionClaims(parsed);\n } catch {\n return undefined;\n }\n}\n\nfunction writeClaimsToDocument(claims: AuthSessionClaims): boolean {\n let serialized: string;\n\n try {\n serialized = JSON.stringify(claims);\n } catch {\n return false;\n }\n let node = document.getElementById(__MREACT_AUTH_SESSION_SCRIPT_ID);\n\n if (node === null) {\n node = document.createElement(\"script\");\n node.id = __MREACT_AUTH_SESSION_SCRIPT_ID;\n node.setAttribute(\"type\", \"application/json\");\n document.body.append(node);\n }\n\n node.textContent = serialized;\n return true;\n}\n\nfunction defaultSerializeSessionClaims(data: unknown): AuthSessionClaims | undefined {\n if (typeof data !== \"object\" || data === null) {\n return undefined;\n }\n\n const claims = data as AuthSessionClaims;\n const roles = normalizeStringArray(claims.roles);\n const permissions = normalizeStringArray(claims.permissions);\n\n if (\n (claims.roles !== undefined && roles === undefined) ||\n (claims.permissions !== undefined && permissions === undefined)\n ) {\n return undefined;\n }\n\n const safeClaims: AuthSessionClaims = {};\n\n if (permissions !== undefined) {\n safeClaims.permissions = permissions;\n }\n\n if (roles !== undefined) {\n safeClaims.roles = roles;\n }\n\n return Object.keys(safeClaims).length === 0 ? undefined : safeClaims;\n}\n\nfunction normalizeSessionClaims(value: unknown): AuthSessionClaims | undefined {\n if (typeof value !== \"object\" || value === null) {\n return undefined;\n }\n\n const claims = value as AuthSessionClaims;\n const roles = normalizeStringArray(claims.roles);\n const permissions = normalizeStringArray(claims.permissions);\n\n if (\n (claims.roles !== undefined && roles === undefined) ||\n (claims.permissions !== undefined && permissions === undefined)\n ) {\n return undefined;\n }\n\n return {\n ...claims,\n ...(permissions === undefined ? {} : { permissions }),\n ...(roles === undefined ? {} : { roles }),\n };\n}\n\nfunction normalizeStringArray(value: unknown): readonly string[] | undefined {\n if (value === undefined) {\n return undefined;\n }\n\n return Array.isArray(value) && value.every((item) => typeof item === \"string\")\n ? value\n : undefined;\n}\n\nfunction authRuntimeState(): AuthRuntimeState {\n return getGlobalRuntimeState(authRuntimeStateKey, () => ({}));\n}\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,wBAAwB,EACxB,aAAa,EACb,cAAc,IAAI,oBAAoB,EACtC,UAAU,EACV,aAAa,IAAI,mBAAmB,GAIrC,MAAM,gCAAgC,CAAC;AACxC,OAAO,EAAE,qBAAqB,EAAE,MAAM,6CAA6C,CAAC;AACpF,OAAO,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAElD,OAAO,EACL,wBAAwB,EACxB,aAAa,EACb,oBAAoB,IAAI,cAAc,EACtC,UAAU,EACV,mBAAmB,IAAI,aAAa,GACrC,CAAC;AAIF,0FAA0F;AAC1F,MAAM,CAAC,MAAM,+BAA+B,GAAG,uBAAuB,CAAC;AAqEvE,MAAM,mBAAmB,GAAG,0BAA0B,CAAC;AAkBvD,IAAI,UAAU,GAAuB;IACnC,WAAW,EAAE,YAAY;IACzB,UAAU,EAAE,QAAQ;IACpB,eAAe,EAAE,6BAA6B;CAC/C,CAAC;AAEF;;;;;GAKG;AACH,MAAM,UAAU,aAAa,CAAC,MAAkB;IAC9C,UAAU,GAAG;QACX,WAAW,EAAE,MAAM,CAAC,WAAW,IAAI,UAAU,CAAC,WAAW;QACzD,UAAU,EAAE,MAAM,CAAC,UAAU,IAAI,UAAU,CAAC,UAAU;QACtD,eAAe,EAAE,MAAM,CAAC,eAAe,IAAI,UAAU,CAAC,eAAe;KACtE,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,EAAwB,EACxB,OAAO,GAAuB,EAAE;IAEhC,MAAM,OAAO,GAAG,MAAM,kBAAkB,EAAE,CAAC;IAE3C,OAAO,MAAM,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC;AAC/F,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,OAAgB,EAChB,KAA0B,EAC1B,OAAO,GAAyB,EAAE;IAElC,MAAM,OAAO,GAAG,MAAM,UAAU,CAAC,OAAO,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;IAE1D,gBAAgB,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IAEhC,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,OAAgB,EAChB,KAA0B,EAC1B,OAAO,GAAqB,EAAE;IAE9B,MAAM,OAAO,GAAG,MAAM,iBAAiB,CAAC,OAAO,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;IAEjE,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QAC1B,QAAQ,CAAC,cAAc,CAAC,OAAO,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;IACrD,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,OAAgB,EAChB,KAA0B,EAC1B,IAAqB,EACrB,OAAO,GAAqB,EAAE;IAE9B,0BAA0B,CAAC,IAAI,EAAE,cAAc,CAAC,CAAC;IACjD,MAAM,OAAO,GAAG,MAAM,cAAc,CAAC,OAAO,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;IAC9D,MAAM,MAAM,GAAG,oBAAoB,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,EAAE,cAAc,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IAE5F,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC;QACvB,QAAQ,CAAC,eAAe,CAAC,OAAO,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;IACtD,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,OAAgB,EAChB,KAA0B,EAC1B,UAA2B,EAC3B,OAAO,GAAqB,EAAE;IAE9B,0BAA0B,CAAC,UAAU,EAAE,oBAAoB,CAAC,CAAC;IAC7D,MAAM,OAAO,GAAG,MAAM,cAAc,CAAC,OAAO,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;IAC9D,MAAM,MAAM,GAAG,oBAAoB,CACjC,OAAO,CAAC,IAAI,CAAC,WAAW,EACxB,UAAU,EACV,oBAAoB,EACpB,OAAO,CAAC,IAAI,CACb,CAAC;IAEF,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC;QACvB,QAAQ,CAAC,eAAe,CAAC,OAAO,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;IACtD,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,OAAgB,EAChB,KAA0B,EAC1B,IAAqB,EACrB,OAAO,GAA0D,EAAE;IAEnE,0BAA0B,CAAC,IAAI,EAAE,cAAc,CAAC,CAAC;IACjD,MAAM,OAAO,GAAG,MAAM,iBAAiB,CAAC,OAAO,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;IAEjE,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QAC1B,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,EAAE,iBAAiB,EAAE,CAAC;IAC1D,CAAC;IAED,MAAM,MAAM,GAAG,oBAAoB,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,EAAE,cAAc,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IAE5F,OAAO,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC;AACpE,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,OAAgB,EAChB,KAA0B,EAC1B,UAA2B,EAC3B,OAAO,GAA0D,EAAE;IAEnE,0BAA0B,CAAC,UAAU,EAAE,oBAAoB,CAAC,CAAC;IAC7D,MAAM,OAAO,GAAG,MAAM,iBAAiB,CAAC,OAAO,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;IAEjE,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QAC1B,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,EAAE,iBAAiB,EAAE,CAAC;IAC1D,CAAC;IAED,MAAM,MAAM,GAAG,oBAAoB,CACjC,OAAO,CAAC,IAAI,CAAC,WAAW,EACxB,UAAU,EACV,oBAAoB,EACpB,OAAO,CAAC,IAAI,CACb,CAAC;IAEF,OAAO,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC;AACpE,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAC9B,IAAW,EACX,MAA2B;IAE3B,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;QACtC,OAAO;YACL,UAAU,EAAE,KAAK;YACjB,MAAM,EAAE,cAAc;SACvB,CAAC;IACJ,CAAC;IAED,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,EAAE,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC;QAClD,OAAO;YACL,UAAU,EAAE,KAAK;YACjB,MAAM,EAAE,oBAAoB;SAC7B,CAAC;IACJ,CAAC;IAED,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC;AAC9B,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,OAAgB,EAChB,QAAkB,EAClB,KAA0B,EAC1B,OAAO,GAAyB,EAAE;IAElC,MAAM,OAAO,GAAG,MAAM,mBAAmB,CAAC,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;IAE7E,gBAAgB,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IAEhC,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,OAAgB,EAChB,QAAkB,EAClB,KAA0B,EAC1B,OAAO,GAAyB,EAAE;IAElC,MAAM,oBAAoB,CAAC,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;IAC9D,gBAAgB,CAAC,SAAS,CAAC,CAAC;AAC9B,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,gBAAgB;IAG9B,MAAM,KAAK,GAAG,gBAAgB,EAAE,CAAC;IACjC,MAAM,aAAa,GAAG,KAAK,CAAC,OAAO,EAAE,QAAQ,EAAE,EAAE,MAAM,CAAC;IAExD,IAAI,aAAa,KAAK,SAAS,EAAE,CAAC;QAChC,OAAO,aAAsB,CAAC;IAChC,CAAC;IAED,IAAI,OAAO,QAAQ,KAAK,WAAW,EAAE,CAAC;QACpC,2BAA2B,EAAE,CAAC;QAC9B,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,KAAK,CAAC,aAAa,GAAG,sBAAsB,EAAE,CAAC;IAE/C,OAAO,KAAK,CAAC,aAAkC,CAAC;AAClD,CAAC;AAED,0EAA0E;AAC1E,MAAM,UAAU,qBAAqB;IACnC,UAAU,GAAG;QACX,WAAW,EAAE,YAAY;QACzB,UAAU,EAAE,QAAQ;QACpB,eAAe,EAAE,6BAA6B;KAC/C,CAAC;IACF,MAAM,KAAK,GAAG,gBAAgB,EAAE,CAAC;IACjC,KAAK,CAAC,aAAa,GAAG,SAAS,CAAC;IAChC,KAAK,CAAC,aAAa,GAAG,SAAS,CAAC;IAChC,MAAM,YAAY,GAAG,KAAK,CAAC,OAAO,EAAE,QAAQ,EAAE,CAAC;IAC/C,IAAI,YAAY,KAAK,SAAS,EAAE,CAAC;QAC/B,YAAY,CAAC,MAAM,GAAG,SAAS,CAAC;QAChC,YAAY,CAAC,MAAM,GAAG,SAAS,CAAC;IAClC,CAAC;AACH,CAAC;AAED,SAAS,oBAAoB,CAC3B,SAAwC,EACxC,WAA4B,EAC5B,MAA6C,EAC7C,IAAI,GAAwB,KAAK;IAEjC,0BAA0B,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;IAChD,MAAM,QAAQ,GAAG,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC;IAC1E,MAAM,UAAU,GAAG,IAAI,KAAK,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;IAE9F,OAAO,UAAU,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;AAC3E,CAAC;AAED,SAAS,0BAA0B,CACjC,WAA4B,EAC5B,MAA6C;IAE7C,IACE,WAAW,KAAK,SAAS;QACzB,CAAC,OAAO,WAAW,KAAK,QAAQ,IAAI,WAAW,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC;QAC9D,CAAC,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC;YACzB,CAAC,WAAW,CAAC,MAAM,KAAK,CAAC,IAAI,WAAW,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EACjF,CAAC;QACD,MAAM,KAAK,GAAG,MAAM,KAAK,cAAc,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,YAAY,CAAC;QAChE,MAAM,IAAI,GAAG,MAAM,KAAK,cAAc,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,YAAY,CAAC;QAC/D,MAAM,IAAI,SAAS,CAAC,GAAG,KAAK,0CAA0C,IAAI,GAAG,CAAC,CAAC;IACjF,CAAC;AACH,CAAC;AAED,SAAS,cAAc,CAAC,OAAyB;IAC/C,OAAO,OAAO,CAAC,UAAU,IAAI,iBAAiB,EAAE,EAAE,UAAU,IAAI,UAAU,CAAC,UAAU,CAAC;AACxF,CAAC;AAED,SAAS,eAAe,CAAC,OAAyB;IAChD,OAAO,OAAO,CAAC,WAAW,IAAI,iBAAiB,EAAE,EAAE,WAAW,IAAI,UAAU,CAAC,WAAW,CAAC;AAC3F,CAAC;AAED,SAAS,MAAM,CACb,SAAwC,EACxC,QAAuC;IAEvC,IAAI,QAAQ,KAAK,SAAS,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACpD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,SAAS,KAAK,SAAS,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACtD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,SAAS,CAAC,CAAC;IAElC,OAAO,QAAQ,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC;AACtD,CAAC;AAED,SAAS,MAAM,CACb,SAAwC,EACxC,QAAuC;IAEvC,IAAI,QAAQ,KAAK,SAAS,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACpD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IAAI,SAAS,KAAK,SAAS,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACtD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,SAAS,CAAC,CAAC;IAElC,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC;AACrD,CAAC;AAED,SAAS,gBAAgB,CAAC,IAAa;IACrC,MAAM,UAAU,GAAG,iBAAiB,EAAE,EAAE,eAAe,IAAI,UAAU,CAAC,eAAe,CAAC;IACtF,MAAM,MAAM,GAAG,sBAAsB,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC;IACxD,MAAM,KAAK,GAAG,gBAAgB,EAAE,CAAC;IACjC,MAAM,YAAY,GAAG,KAAK,CAAC,OAAO,EAAE,QAAQ,EAAE,CAAC;IAE/C,IAAI,YAAY,KAAK,SAAS,EAAE,CAAC;QAC/B,YAAY,CAAC,MAAM,GAAG,MAAM,CAAC;QAC7B,OAAO;IACT,CAAC;IAED,IAAI,OAAO,QAAQ,KAAK,WAAW,EAAE,CAAC;QACpC,OAAO;IACT,CAAC;IAED,MAAM,aAAa,GAAG,MAAM,KAAK,SAAS,IAAI,qBAAqB,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC;IAEjG,IAAI,aAAa,KAAK,SAAS,EAAE,CAAC;QAChC,QAAQ,CAAC,cAAc,CAAC,+BAA+B,CAAC,EAAE,MAAM,EAAE,CAAC;IACrE,CAAC;IAED,KAAK,CAAC,aAAa,GAAG,aAAa,CAAC;IACpC,KAAK,CAAC,aAAa,GAAG,aAAa,CAAC;AACtC,CAAC;AAED,SAAS,iBAAiB;IACxB,OAAO,gBAAgB,EAAE,CAAC,OAAO,EAAE,QAAQ,EAAE,EAAE,MAAM,CAAC;AACxD,CAAC;AAED,KAAK,UAAU,kBAAkB;IAC/B,MAAM,KAAK,GAAG,gBAAgB,EAAE,CAAC;IACjC,IAAI,KAAK,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;QAChC,MAAM,EAAE,iBAAiB,EAAE,GAAG,MAAM,MAAM,CAAC,kBAAkB,CAAC,CAAC;QAC/D,KAAK,CAAC,OAAO,KAAK,IAAI,iBAAiB,EAA2B,CAAC;IACrE,CAAC;IAED,OAAO,KAAK,CAAC,OAAO,CAAC;AACvB,CAAC;AAED,SAAS,2BAA2B;IAClC,OAAO,CAAC,IAAI,CACV,2IAA2I,CAC5I,CAAC;AACJ,CAAC;AAED,SAAS,sBAAsB;IAC7B,MAAM,IAAI,GAAG,QAAQ,CAAC,cAAc,CAAC,+BAA+B,CAAC,CAAC;IAEtE,IAAI,IAAI,EAAE,WAAW,KAAK,SAAS,IAAI,IAAI,CAAC,WAAW,KAAK,EAAE,EAAE,CAAC;QAC/D,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,CAAY,CAAC;QACvD,OAAO,sBAAsB,CAAC,MAAM,CAAC,CAAC;IACxC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC;AAED,SAAS,qBAAqB,CAAC,MAAyB;IACtD,IAAI,UAAkB,CAAC;IAEvB,IAAI,CAAC;QACH,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;IACtC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;IACD,IAAI,IAAI,GAAG,QAAQ,CAAC,cAAc,CAAC,+BAA+B,CAAC,CAAC;IAEpE,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;QAClB,IAAI,GAAG,QAAQ,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;QACxC,IAAI,CAAC,EAAE,GAAG,+BAA+B,CAAC;QAC1C,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC;QAC9C,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAC7B,CAAC;IAED,IAAI,CAAC,WAAW,GAAG,UAAU,CAAC;IAC9B,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,6BAA6B,CAAC,IAAa;IAClD,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;QAC9C,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,MAAM,MAAM,GAAG,IAAyB,CAAC;IACzC,MAAM,KAAK,GAAG,oBAAoB,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACjD,MAAM,WAAW,GAAG,oBAAoB,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;IAE7D,IACE,CAAC,MAAM,CAAC,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,SAAS,CAAC;QACnD,CAAC,MAAM,CAAC,WAAW,KAAK,SAAS,IAAI,WAAW,KAAK,SAAS,CAAC,EAC/D,CAAC;QACD,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,MAAM,UAAU,GAAsB,EAAE,CAAC;IAEzC,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;QAC9B,UAAU,CAAC,WAAW,GAAG,WAAW,CAAC;IACvC,CAAC;IAED,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACxB,UAAU,CAAC,KAAK,GAAG,KAAK,CAAC;IAC3B,CAAC;IAED,OAAO,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,UAAU,CAAC;AACvE,CAAC;AAED,SAAS,sBAAsB,CAAC,KAAc;IAC5C,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;QAChD,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,MAAM,MAAM,GAAG,KAA0B,CAAC;IAC1C,MAAM,KAAK,GAAG,oBAAoB,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACjD,MAAM,WAAW,GAAG,oBAAoB,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;IAE7D,IACE,CAAC,MAAM,CAAC,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,SAAS,CAAC;QACnD,CAAC,MAAM,CAAC,WAAW,KAAK,SAAS,IAAI,WAAW,KAAK,SAAS,CAAC,EAC/D,CAAC;QACD,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,OAAO;QACL,GAAG,MAAM;QACT,GAAG,CAAC,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC;QACrD,GAAG,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC;KAC1C,CAAC;AACJ,CAAC;AAED,SAAS,oBAAoB,CAAC,KAAc;IAC1C,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACxB,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,OAAO,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,IAAI,KAAK,QAAQ,CAAC;QAC5E,CAAC,CAAC,KAAK;QACP,CAAC,CAAC,SAAS,CAAC;AAChB,CAAC;AAED,SAAS,gBAAgB;IACvB,OAAO,qBAAqB,CAAC,mBAAmB,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AAChE,CAAC","sourcesContent":["import {\n createMemorySessionStore,\n createSession,\n destroySession as destroyRouterSession,\n getSession,\n rotateSession as rotateRouterSession,\n type SessionCookieOptions,\n type SessionRecord,\n type SessionStore,\n} from \"@reckona/mreact-router/session\";\nimport { getGlobalRuntimeState } from \"@reckona/mreact-reactive-core/runtime-state\";\nimport { redirect } from \"@reckona/mreact-router\";\n\nexport {\n createMemorySessionStore,\n createSession,\n destroyRouterSession as destroySession,\n getSession,\n rotateRouterSession as rotateSession,\n};\n/** Re-exports router session cookie, record, and store types for auth helpers. */\nexport type { SessionCookieOptions, SessionRecord, SessionStore };\n\n/** Identifies the script element that carries serialized auth claims during hydration. */\nexport const __MREACT_AUTH_SESSION_SCRIPT_ID = \"__mreact_auth_session\";\n\n/** Contains serializable auth claims exposed to role and permission checks. */\nexport interface AuthSessionClaims {\n [claim: string]: unknown;\n permissions?: readonly string[] | undefined;\n roles?: readonly string[] | undefined;\n}\n\n/** Configures redirects and requirement matching for auth guard helpers. */\nexport interface AuthGuardOptions extends SessionCookieOptions {\n forbiddenTo?: string | undefined;\n mode?: AuthRequirementMode | undefined;\n redirectTo?: string | undefined;\n}\n\n/** Configures process-wide auth defaults for redirects and claim serialization. */\nexport interface AuthConfig {\n forbiddenTo?: string | undefined;\n redirectTo?: string | undefined;\n serializeClaims?: AuthClaimsSerializer | undefined;\n}\n\nexport interface AuthRequestOptions {\n config?: AuthConfig | undefined;\n}\n\ninterface ResolvedAuthConfig {\n forbiddenTo: string;\n redirectTo: string;\n serializeClaims: AuthClaimsSerializer;\n}\n\n/** Names one required role or permission, or a set of acceptable values. */\nexport type AuthRequirement = string | readonly string[];\n\n/** Controls whether all listed auth requirements or any one requirement must match. */\nexport type AuthRequirementMode = \"all\" | \"any\";\n\n/** Converts raw session data into serializable claims for auth checks and hydration. */\nexport type AuthClaimsSerializer = (data: unknown) => AuthSessionClaims | undefined;\n\n/** Describes role and permission claims required for authorization. */\nexport interface AuthorizationPolicy {\n permissions?: readonly string[] | undefined;\n roles?: readonly string[] | undefined;\n}\n\n/** Reports whether claims satisfy an authorization policy and why they fail. */\nexport type AuthorizationResult =\n | {\n authorized: true;\n }\n | {\n authorized: false;\n reason: \"missing-permission\" | \"missing-role\";\n };\n\n/** Reports a session-bearing auth guard result without redirecting. */\nexport type TryAuthResult<TData> =\n | {\n authorized: true;\n session: SessionRecord<TData>;\n }\n | {\n authorized: false;\n reason: \"missing-permission\" | \"missing-role\" | \"missing-session\";\n };\n\nconst authRuntimeStateKey = \"__mreactAuthRuntimeState\";\n\ninterface AuthRuntimeRequestState {\n claims?: AuthSessionClaims | undefined;\n config?: AuthConfig | undefined;\n}\n\ninterface AuthRequestStorage {\n getStore(): AuthRuntimeRequestState | undefined;\n run<T>(store: AuthRuntimeRequestState, callback: () => T): T;\n}\n\ninterface AuthRuntimeState {\n browserClaims?: AuthSessionClaims | undefined;\n currentClaims?: AuthSessionClaims | undefined;\n storage?: AuthRequestStorage | undefined;\n}\n\nlet authConfig: ResolvedAuthConfig = {\n forbiddenTo: \"/forbidden\",\n redirectTo: \"/login\",\n serializeClaims: defaultSerializeSessionClaims,\n};\n\n/**\n * Updates the process-wide auth defaults used by the guard helpers.\n *\n * Configure redirect targets and claim serialization before handling requests that call `requireSession()`, `requireRole()`, or `requirePermission()`.\n * For per-request or per-tenant overrides, pass `config` to `runWithAuthRequest()` instead of calling `configureAuth()` while requests are in flight.\n */\nexport function configureAuth(config: AuthConfig): void {\n authConfig = {\n forbiddenTo: config.forbiddenTo ?? authConfig.forbiddenTo,\n redirectTo: config.redirectTo ?? authConfig.redirectTo,\n serializeClaims: config.serializeClaims ?? authConfig.serializeClaims,\n };\n}\n\n/**\n * Runs server-side auth work inside an AsyncLocalStorage-backed request scope.\n *\n * Use this around custom server rendering or tests so `getSessionClaims()` can read request-local claims.\n */\nexport async function runWithAuthRequest<T>(\n fn: () => T | Promise<T>,\n options: AuthRequestOptions = {},\n): Promise<Awaited<T>> {\n const storage = await authRequestStorage();\n\n return await storage.run(options.config === undefined ? {} : { config: options.config }, fn);\n}\n\n/**\n * Reads the current session and stores serialized claims for the active auth request scope.\n */\nexport async function getCurrentSession<TData>(\n request: Request,\n store: SessionStore<TData>,\n options: SessionCookieOptions = {},\n): Promise<SessionRecord<TData> | undefined> {\n const session = await getSession(request, store, options);\n\n setSessionClaims(session?.data);\n\n return session;\n}\n\n/**\n * Requires an active session or redirects to the configured login route.\n */\nexport async function requireSession<TData>(\n request: Request,\n store: SessionStore<TData>,\n options: AuthGuardOptions = {},\n): Promise<SessionRecord<TData>> {\n const session = await getCurrentSession(request, store, options);\n\n if (session === undefined) {\n redirect(authRedirectTo(options), { status: 303 });\n }\n\n return session;\n}\n\n/**\n * Requires an active session with the requested role or redirects to the configured forbidden route.\n */\nexport async function requireRole<TData extends AuthSessionClaims>(\n request: Request,\n store: SessionStore<TData>,\n role: AuthRequirement,\n options: AuthGuardOptions = {},\n): Promise<SessionRecord<TData>> {\n assertValidAuthRequirement(role, \"missing-role\");\n const session = await requireSession(request, store, options);\n const result = authorizeRequirement(session.data.roles, role, \"missing-role\", options.mode);\n\n if (!result.authorized) {\n redirect(authForbiddenTo(options), { status: 303 });\n }\n\n return session;\n}\n\n/**\n * Requires an active session with the requested permission or redirects to the configured forbidden route.\n */\nexport async function requirePermission<TData extends AuthSessionClaims>(\n request: Request,\n store: SessionStore<TData>,\n permission: AuthRequirement,\n options: AuthGuardOptions = {},\n): Promise<SessionRecord<TData>> {\n assertValidAuthRequirement(permission, \"missing-permission\");\n const session = await requireSession(request, store, options);\n const result = authorizeRequirement(\n session.data.permissions,\n permission,\n \"missing-permission\",\n options.mode,\n );\n\n if (!result.authorized) {\n redirect(authForbiddenTo(options), { status: 303 });\n }\n\n return session;\n}\n\n/**\n * Checks for a role without redirecting, returning a discriminated authorization result.\n */\nexport async function tryRequireRole<TData extends AuthSessionClaims>(\n request: Request,\n store: SessionStore<TData>,\n role: AuthRequirement,\n options: Pick<AuthGuardOptions, \"mode\"> & SessionCookieOptions = {},\n): Promise<TryAuthResult<TData>> {\n assertValidAuthRequirement(role, \"missing-role\");\n const session = await getCurrentSession(request, store, options);\n\n if (session === undefined) {\n return { authorized: false, reason: \"missing-session\" };\n }\n\n const result = authorizeRequirement(session.data.roles, role, \"missing-role\", options.mode);\n\n return result.authorized ? { authorized: true, session } : result;\n}\n\n/**\n * Checks for a permission without redirecting, returning a discriminated authorization result.\n */\nexport async function tryRequirePermission<TData extends AuthSessionClaims>(\n request: Request,\n store: SessionStore<TData>,\n permission: AuthRequirement,\n options: Pick<AuthGuardOptions, \"mode\"> & SessionCookieOptions = {},\n): Promise<TryAuthResult<TData>> {\n assertValidAuthRequirement(permission, \"missing-permission\");\n const session = await getCurrentSession(request, store, options);\n\n if (session === undefined) {\n return { authorized: false, reason: \"missing-session\" };\n }\n\n const result = authorizeRequirement(\n session.data.permissions,\n permission,\n \"missing-permission\",\n options.mode,\n );\n\n return result.authorized ? { authorized: true, session } : result;\n}\n\n/**\n * Evaluates session claims against required roles and permissions without reading cookies or redirecting.\n */\nexport function authorizeSession<TData extends AuthSessionClaims>(\n data: TData,\n policy: AuthorizationPolicy,\n): AuthorizationResult {\n if (!hasAll(data.roles, policy.roles)) {\n return {\n authorized: false,\n reason: \"missing-role\",\n };\n }\n\n if (!hasAll(data.permissions, policy.permissions)) {\n return {\n authorized: false,\n reason: \"missing-permission\",\n };\n }\n\n return { authorized: true };\n}\n\n/**\n * Rotates the current session id and refreshes request-local claims.\n */\nexport async function refreshSession<TData>(\n request: Request,\n response: Response,\n store: SessionStore<TData>,\n options: SessionCookieOptions = {},\n): Promise<SessionRecord<TData> | undefined> {\n const session = await rotateRouterSession(request, response, store, options);\n\n setSessionClaims(session?.data);\n\n return session;\n}\n\n/**\n * Destroys the current session and clears request-local claims.\n */\nexport async function revokeCurrentSession<TData>(\n request: Request,\n response: Response,\n store: SessionStore<TData>,\n options: SessionCookieOptions = {},\n): Promise<void> {\n await destroyRouterSession(request, response, store, options);\n setSessionClaims(undefined);\n}\n\n/**\n * Returns the claims captured by `getCurrentSession()` for the current request or hydrated browser document.\n *\n * Server code should call it inside `runWithAuthRequest()` so concurrent requests do not share claim state.\n */\nexport function getSessionClaims<TData extends AuthSessionClaims = AuthSessionClaims>():\n | TData\n | undefined {\n const state = authRuntimeState();\n const requestClaims = state.storage?.getStore()?.claims;\n\n if (requestClaims !== undefined) {\n return requestClaims as TData;\n }\n\n if (typeof document === \"undefined\") {\n warnMissingAuthRequestScope();\n return undefined;\n }\n\n state.browserClaims = readClaimsFromDocument();\n\n return state.browserClaims as TData | undefined;\n}\n\n/** Resets process-wide auth configuration and cached claims for tests. */\nexport function __resetAuthForTesting(): void {\n authConfig = {\n forbiddenTo: \"/forbidden\",\n redirectTo: \"/login\",\n serializeClaims: defaultSerializeSessionClaims,\n };\n const state = authRuntimeState();\n state.browserClaims = undefined;\n state.currentClaims = undefined;\n const requestState = state.storage?.getStore();\n if (requestState !== undefined) {\n requestState.claims = undefined;\n requestState.config = undefined;\n }\n}\n\nfunction authorizeRequirement(\n available: readonly string[] | undefined,\n requirement: AuthRequirement,\n reason: \"missing-permission\" | \"missing-role\",\n mode: AuthRequirementMode = \"any\",\n): AuthorizationResult {\n assertValidAuthRequirement(requirement, reason);\n const required = Array.isArray(requirement) ? requirement : [requirement];\n const authorized = mode === \"all\" ? hasAll(available, required) : hasAny(available, required);\n\n return authorized ? { authorized: true } : { authorized: false, reason };\n}\n\nfunction assertValidAuthRequirement(\n requirement: AuthRequirement,\n reason: \"missing-permission\" | \"missing-role\",\n): void {\n if (\n requirement === undefined ||\n (typeof requirement === \"string\" && requirement.trim() === \"\") ||\n (Array.isArray(requirement) &&\n (requirement.length === 0 || requirement.some((value) => value.trim() === \"\")))\n ) {\n const label = reason === \"missing-role\" ? \"Role\" : \"Permission\";\n const noun = reason === \"missing-role\" ? \"role\" : \"permission\";\n throw new TypeError(`${label} requirement must contain at least one ${noun}.`);\n }\n}\n\nfunction authRedirectTo(options: AuthGuardOptions): string {\n return options.redirectTo ?? authRequestConfig()?.redirectTo ?? authConfig.redirectTo;\n}\n\nfunction authForbiddenTo(options: AuthGuardOptions): string {\n return options.forbiddenTo ?? authRequestConfig()?.forbiddenTo ?? authConfig.forbiddenTo;\n}\n\nfunction hasAll(\n available: readonly string[] | undefined,\n required: readonly string[] | undefined,\n): boolean {\n if (required === undefined || required.length === 0) {\n return true;\n }\n\n if (available === undefined || available.length === 0) {\n return false;\n }\n\n const values = new Set(available);\n\n return required.every((value) => values.has(value));\n}\n\nfunction hasAny(\n available: readonly string[] | undefined,\n required: readonly string[] | undefined,\n): boolean {\n if (required === undefined || required.length === 0) {\n return false;\n }\n\n if (available === undefined || available.length === 0) {\n return false;\n }\n\n const values = new Set(available);\n\n return required.some((value) => values.has(value));\n}\n\nfunction setSessionClaims(data: unknown): void {\n const serializer = authRequestConfig()?.serializeClaims ?? authConfig.serializeClaims;\n const claims = normalizeSessionClaims(serializer(data));\n const state = authRuntimeState();\n const requestState = state.storage?.getStore();\n\n if (requestState !== undefined) {\n requestState.claims = claims;\n return;\n }\n\n if (typeof document === \"undefined\") {\n return;\n }\n\n const browserClaims = claims !== undefined && writeClaimsToDocument(claims) ? claims : undefined;\n\n if (browserClaims === undefined) {\n document.getElementById(__MREACT_AUTH_SESSION_SCRIPT_ID)?.remove();\n }\n\n state.browserClaims = browserClaims;\n state.currentClaims = browserClaims;\n}\n\nfunction authRequestConfig(): AuthConfig | undefined {\n return authRuntimeState().storage?.getStore()?.config;\n}\n\nasync function authRequestStorage(): Promise<AuthRequestStorage> {\n const state = authRuntimeState();\n if (state.storage === undefined) {\n const { AsyncLocalStorage } = await import(\"node:async_hooks\");\n state.storage ??= new AsyncLocalStorage<AuthRuntimeRequestState>();\n }\n\n return state.storage;\n}\n\nfunction warnMissingAuthRequestScope(): void {\n console.warn(\n \"mreact auth session claims were read on the server without an active auth request scope. Wrap custom server work in runWithAuthRequest().\",\n );\n}\n\nfunction readClaimsFromDocument(): AuthSessionClaims | undefined {\n const node = document.getElementById(__MREACT_AUTH_SESSION_SCRIPT_ID);\n\n if (node?.textContent === undefined || node.textContent === \"\") {\n return undefined;\n }\n\n try {\n const parsed = JSON.parse(node.textContent) as unknown;\n return normalizeSessionClaims(parsed);\n } catch {\n return undefined;\n }\n}\n\nfunction writeClaimsToDocument(claims: AuthSessionClaims): boolean {\n let serialized: string;\n\n try {\n serialized = JSON.stringify(claims);\n } catch {\n return false;\n }\n let node = document.getElementById(__MREACT_AUTH_SESSION_SCRIPT_ID);\n\n if (node === null) {\n node = document.createElement(\"script\");\n node.id = __MREACT_AUTH_SESSION_SCRIPT_ID;\n node.setAttribute(\"type\", \"application/json\");\n document.body.append(node);\n }\n\n node.textContent = serialized;\n return true;\n}\n\nfunction defaultSerializeSessionClaims(data: unknown): AuthSessionClaims | undefined {\n if (typeof data !== \"object\" || data === null) {\n return undefined;\n }\n\n const claims = data as AuthSessionClaims;\n const roles = normalizeStringArray(claims.roles);\n const permissions = normalizeStringArray(claims.permissions);\n\n if (\n (claims.roles !== undefined && roles === undefined) ||\n (claims.permissions !== undefined && permissions === undefined)\n ) {\n return undefined;\n }\n\n const safeClaims: AuthSessionClaims = {};\n\n if (permissions !== undefined) {\n safeClaims.permissions = permissions;\n }\n\n if (roles !== undefined) {\n safeClaims.roles = roles;\n }\n\n return Object.keys(safeClaims).length === 0 ? undefined : safeClaims;\n}\n\nfunction normalizeSessionClaims(value: unknown): AuthSessionClaims | undefined {\n if (typeof value !== \"object\" || value === null) {\n return undefined;\n }\n\n const claims = value as AuthSessionClaims;\n const roles = normalizeStringArray(claims.roles);\n const permissions = normalizeStringArray(claims.permissions);\n\n if (\n (claims.roles !== undefined && roles === undefined) ||\n (claims.permissions !== undefined && permissions === undefined)\n ) {\n return undefined;\n }\n\n return {\n ...claims,\n ...(permissions === undefined ? {} : { permissions }),\n ...(roles === undefined ? {} : { roles }),\n };\n}\n\nfunction normalizeStringArray(value: unknown): readonly string[] | undefined {\n if (value === undefined) {\n return undefined;\n }\n\n return Array.isArray(value) && value.every((item) => typeof item === \"string\")\n ? value\n : undefined;\n}\n\nfunction authRuntimeState(): AuthRuntimeState {\n return getGlobalRuntimeState(authRuntimeStateKey, () => ({}));\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@reckona/mreact-auth",
3
- "version": "0.0.202",
3
+ "version": "0.0.203",
4
4
  "description": "Session and authorization helpers for mreact app router applications.",
5
5
  "keywords": [
6
6
  "auth",
@@ -41,7 +41,7 @@
41
41
  "access": "public"
42
42
  },
43
43
  "dependencies": {
44
- "@reckona/mreact-reactive-core": "0.0.202",
45
- "@reckona/mreact-router": "0.0.202"
44
+ "@reckona/mreact-reactive-core": "0.0.203",
45
+ "@reckona/mreact-router": "0.0.203"
46
46
  }
47
47
  }
package/src/index.ts CHANGED
@@ -184,6 +184,7 @@ export async function requireRole<TData extends AuthSessionClaims>(
184
184
  role: AuthRequirement,
185
185
  options: AuthGuardOptions = {},
186
186
  ): Promise<SessionRecord<TData>> {
187
+ assertValidAuthRequirement(role, "missing-role");
187
188
  const session = await requireSession(request, store, options);
188
189
  const result = authorizeRequirement(session.data.roles, role, "missing-role", options.mode);
189
190
 
@@ -203,6 +204,7 @@ export async function requirePermission<TData extends AuthSessionClaims>(
203
204
  permission: AuthRequirement,
204
205
  options: AuthGuardOptions = {},
205
206
  ): Promise<SessionRecord<TData>> {
207
+ assertValidAuthRequirement(permission, "missing-permission");
206
208
  const session = await requireSession(request, store, options);
207
209
  const result = authorizeRequirement(
208
210
  session.data.permissions,
@@ -227,6 +229,7 @@ export async function tryRequireRole<TData extends AuthSessionClaims>(
227
229
  role: AuthRequirement,
228
230
  options: Pick<AuthGuardOptions, "mode"> & SessionCookieOptions = {},
229
231
  ): Promise<TryAuthResult<TData>> {
232
+ assertValidAuthRequirement(role, "missing-role");
230
233
  const session = await getCurrentSession(request, store, options);
231
234
 
232
235
  if (session === undefined) {
@@ -247,6 +250,7 @@ export async function tryRequirePermission<TData extends AuthSessionClaims>(
247
250
  permission: AuthRequirement,
248
251
  options: Pick<AuthGuardOptions, "mode"> & SessionCookieOptions = {},
249
252
  ): Promise<TryAuthResult<TData>> {
253
+ assertValidAuthRequirement(permission, "missing-permission");
250
254
  const session = await getCurrentSession(request, store, options);
251
255
 
252
256
  if (session === undefined) {
@@ -364,12 +368,29 @@ function authorizeRequirement(
364
368
  reason: "missing-permission" | "missing-role",
365
369
  mode: AuthRequirementMode = "any",
366
370
  ): AuthorizationResult {
371
+ assertValidAuthRequirement(requirement, reason);
367
372
  const required = Array.isArray(requirement) ? requirement : [requirement];
368
373
  const authorized = mode === "all" ? hasAll(available, required) : hasAny(available, required);
369
374
 
370
375
  return authorized ? { authorized: true } : { authorized: false, reason };
371
376
  }
372
377
 
378
+ function assertValidAuthRequirement(
379
+ requirement: AuthRequirement,
380
+ reason: "missing-permission" | "missing-role",
381
+ ): void {
382
+ if (
383
+ requirement === undefined ||
384
+ (typeof requirement === "string" && requirement.trim() === "") ||
385
+ (Array.isArray(requirement) &&
386
+ (requirement.length === 0 || requirement.some((value) => value.trim() === "")))
387
+ ) {
388
+ const label = reason === "missing-role" ? "Role" : "Permission";
389
+ const noun = reason === "missing-role" ? "role" : "permission";
390
+ throw new TypeError(`${label} requirement must contain at least one ${noun}.`);
391
+ }
392
+ }
393
+
373
394
  function authRedirectTo(options: AuthGuardOptions): string {
374
395
  return options.redirectTo ?? authRequestConfig()?.redirectTo ?? authConfig.redirectTo;
375
396
  }
@@ -400,7 +421,7 @@ function hasAny(
400
421
  required: readonly string[] | undefined,
401
422
  ): boolean {
402
423
  if (required === undefined || required.length === 0) {
403
- return true;
424
+ return false;
404
425
  }
405
426
 
406
427
  if (available === undefined || available.length === 0) {