@eminuckan/spine 0.2.2 → 0.2.4

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.
Files changed (79) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/README.md +45 -6
  3. package/dist/access/evaluator.d.ts +3 -0
  4. package/dist/access/evaluator.d.ts.map +1 -0
  5. package/dist/access/index.d.ts +3 -0
  6. package/dist/access/index.d.ts.map +1 -0
  7. package/dist/access/index.js +4 -0
  8. package/dist/access/types.d.ts +30 -0
  9. package/dist/access/types.d.ts.map +1 -0
  10. package/dist/access-DlAqsVGQ.js +59 -0
  11. package/dist/access-DlAqsVGQ.js.map +1 -0
  12. package/dist/api-client/index.js +2 -2
  13. package/dist/api-client/server.js +3 -3
  14. package/dist/{api-client-DsrxK05Z.js → api-client-CZapXIF8.js} +1 -1
  15. package/dist/{api-client-DsrxK05Z.js.map → api-client-CZapXIF8.js.map} +1 -1
  16. package/dist/auth/auth.server.d.ts +21 -16
  17. package/dist/auth/auth.server.d.ts.map +1 -1
  18. package/dist/auth/index.d.ts +1 -1
  19. package/dist/auth/index.d.ts.map +1 -1
  20. package/dist/auth/redis-session-storage.server.d.ts +18 -1
  21. package/dist/auth/redis-session-storage.server.d.ts.map +1 -1
  22. package/dist/auth/route-protection.server.d.ts.map +1 -1
  23. package/dist/auth/server.d.ts +1 -1
  24. package/dist/auth/server.d.ts.map +1 -1
  25. package/dist/auth/server.js +4 -4
  26. package/dist/auth/types.d.ts +65 -20
  27. package/dist/auth/types.d.ts.map +1 -1
  28. package/dist/auth.server-B3ODGIX4.js +1057 -0
  29. package/dist/auth.server-B3ODGIX4.js.map +1 -0
  30. package/dist/auth.server-wdKsjQsn.js +5 -0
  31. package/dist/identity/index.js +1 -1
  32. package/dist/identity/server.js +2 -2
  33. package/dist/{identity-CFa1txoj.js → identity-yT2ijZF0.js} +1 -1
  34. package/dist/{identity-CFa1txoj.js.map → identity-yT2ijZF0.js.map} +1 -1
  35. package/dist/index.d.ts +1 -0
  36. package/dist/index.d.ts.map +1 -1
  37. package/dist/index.js +11 -9
  38. package/dist/permission-service-CvGpwI0d.js +95 -0
  39. package/dist/permission-service-CvGpwI0d.js.map +1 -0
  40. package/dist/permissions/index.js +2 -1
  41. package/dist/{permissions-D5ScGGnd.js → permissions-OUK8Eql2.js} +3 -95
  42. package/dist/permissions-OUK8Eql2.js.map +1 -0
  43. package/dist/query-client/index.js +1 -1
  44. package/dist/{query-client-Bpe08pk9.js → query-client-Bh3TyB8W.js} +2 -2
  45. package/dist/query-client-Bh3TyB8W.js.map +1 -0
  46. package/dist/react-router/index.js +11 -9
  47. package/dist/react-router/server.js +18 -16
  48. package/dist/redis-session-storage.server-D0-72FV-.js +500 -0
  49. package/dist/redis-session-storage.server-D0-72FV-.js.map +1 -0
  50. package/dist/{server-BHfKHKF_.js → server-B7JN86_0.js} +13 -9
  51. package/dist/server-B7JN86_0.js.map +1 -0
  52. package/dist/{server-C3L8J7iE.js → server-BmiuV28c.js} +2 -2
  53. package/dist/{server-C3L8J7iE.js.map → server-BmiuV28c.js.map} +1 -1
  54. package/dist/{server-BxvRxjCK.js → server-Ce9jQRdL.js} +2 -2
  55. package/dist/{server-BxvRxjCK.js.map → server-Ce9jQRdL.js.map} +1 -1
  56. package/dist/{server-DZmcd2Lr.js → server-DeBlxoaW.js} +3 -3
  57. package/dist/{server-DZmcd2Lr.js.map → server-DeBlxoaW.js.map} +1 -1
  58. package/dist/{server-CouYoZiw.js → server-hGrElJMG.js} +2 -2
  59. package/dist/{server-CouYoZiw.js.map → server-hGrElJMG.js.map} +1 -1
  60. package/dist/server.js +18 -16
  61. package/dist/signalr/index.js +1 -1
  62. package/dist/{signalr-SJ-1sIxw.js → signalr-CSfCz1Ik.js} +1 -1
  63. package/dist/{signalr-SJ-1sIxw.js.map → signalr-CSfCz1Ik.js.map} +1 -1
  64. package/dist/tenant/index.js +1 -1
  65. package/dist/tenant/server.js +2 -2
  66. package/dist/{tenant-C6KPaSCX.js → tenant-BErqEENp.js} +1 -1
  67. package/dist/{tenant-C6KPaSCX.js.map → tenant-BErqEENp.js.map} +1 -1
  68. package/dist/{types-BnKaWdfe.js → types-BaaE6wjY.js} +1 -1
  69. package/dist/{types-BnKaWdfe.js.map → types-BaaE6wjY.js.map} +1 -1
  70. package/package.json +7 -2
  71. package/dist/auth.server-BPiCtlJE.js +0 -5
  72. package/dist/auth.server-Cx2h2qu3.js +0 -724
  73. package/dist/auth.server-Cx2h2qu3.js.map +0 -1
  74. package/dist/permissions-D5ScGGnd.js.map +0 -1
  75. package/dist/query-client-Bpe08pk9.js.map +0 -1
  76. package/dist/redis-session-storage.server-BR_0y-QO.js +0 -250
  77. package/dist/redis-session-storage.server-BR_0y-QO.js.map +0 -1
  78. package/dist/server-BHfKHKF_.js.map +0 -1
  79. /package/dist/{src-CJ2RLi94.js → src-B9rDUgSb.js} +0 -0
package/CHANGELOG.md CHANGED
@@ -2,6 +2,35 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file.
4
4
 
5
+ ## [Unreleased]
6
+
7
+ ### Added
8
+
9
+ - Added Keycloak-compatible back-channel and front-channel logout handlers.
10
+ - Added Redis session indexes by user, OIDC `sid`, and legacy `session_state`.
11
+ - Added session listing and destroy primitives for current-user, all-user, `sid`, and `session_state` cleanup.
12
+ - Added OIDC client authentication method configuration for public and confidential clients.
13
+
14
+ ### Changed
15
+
16
+ - Switched server-side auth from direct `oauth4webapi` calls to `openid-client`.
17
+ - Made default logout RP-Initiated Logout and kept app-local cleanup explicit with `logout=local`.
18
+ - Removed `offline_access` from the default scope; apps can opt in explicitly if they need long-lived refresh tokens.
19
+
20
+ ## [0.2.4] - 2026-04-25
21
+
22
+ ### Fixed
23
+
24
+ - Allow HTTP OIDC requests for localhost issuers in non-production environments.
25
+ - Keep insecure OIDC requests disabled unconditionally in production.
26
+
27
+ ## [0.2.3] - 2026-04-25
28
+
29
+ ### Fixed
30
+
31
+ - Added richer OIDC discovery diagnostics, including the resolved discovery URL.
32
+ - Avoid sending stale `id_token_hint` values to a new OIDC provider during provider migrations.
33
+
5
34
  ## [0.2.0] - 2026-03-15
6
35
 
7
36
  ### Added
package/README.md CHANGED
@@ -54,8 +54,9 @@ Spine aims to be:
54
54
 
55
55
  ## What Spine Includes
56
56
 
57
- - OAuth2/OIDC login, callback handling, logout, and token refresh
58
- - Redis-backed session and OAuth state storage
57
+ - OpenID Connect login, callback handling, RP-Initiated Logout, and token refresh
58
+ - Redis-backed session and OAuth state storage with user/session indexes
59
+ - Keycloak-compatible front-channel and back-channel logout handlers
59
60
  - Server-side route protection primitives
60
61
  - Server-side permission route protection configuration
61
62
  - Multi-tenant client state and server helpers
@@ -113,19 +114,57 @@ The built-in auth/session layer currently reads these environment variables:
113
114
 
114
115
  | Variable | Required | Purpose |
115
116
  | --- | --- | --- |
116
- | `OIDC_AUTHORITY` | Yes | OAuth/OIDC issuer base URL |
117
+ | `OIDC_AUTHORITY` | Yes | OpenID Connect issuer base URL |
117
118
  | `OIDC_CLIENT_ID` | Yes | Client identifier |
118
- | `OIDC_REDIRECT_URI` | Yes | OAuth callback URL |
119
+ | `OIDC_REDIRECT_URI` | Yes | OIDC callback URL |
119
120
  | `OIDC_CLIENT_SECRET` | No | Client secret for confidential clients |
120
- | `OIDC_SCOPE` | No | Requested scope string |
121
+ | `OIDC_CLIENT_AUTH_METHOD` | No | `none`, `client_secret_post`, or `client_secret_basic` |
122
+ | `OIDC_SCOPE` | No | Requested scope string. Defaults to `openid profile email api` |
121
123
  | `OIDC_POST_LOGOUT_REDIRECT_URI` | No | Logout return URL |
122
124
  | `OIDC_APPLICATION_TYPE` | No | `no-landing-page`, `landing-page`, or legacy aliases |
123
- | `OIDC_SSO_LOGOUT` | No | Explicit full-logout override |
124
125
  | `OIDC_HAS_LANDING_PAGE` | No | Explicit landing-page behavior override |
126
+ | `OIDC_ALLOW_INSECURE_REQUESTS` | No | Allows non-HTTPS OIDC issuer calls only outside production |
125
127
  | `REDIS_URL` | No | Redis connection string for sessions and OAuth state |
126
128
  | `REDIS_KEY_PREFIX` | No | Prefix for Redis keys |
127
129
  | `API_BASE_URL` | No | Default API base URL for `createAPIConfigFactory` |
128
130
 
131
+ ## OIDC Session Lifecycle
132
+
133
+ Spine treats the OIDC provider as the identity/session authority and the app as a relying party with its own Redis session. The default logout behavior follows RP-Initiated Logout:
134
+
135
+ - `/auth/logout` clears the current app session and redirects to the provider end-session endpoint.
136
+ - `/auth/logout?logout=local` clears only the current app session. Use this for automatic cleanup after token refresh failure or expired local state.
137
+ - `/auth/logout?logout=all` revokes all known app sessions for the current user, clears their Redis session indexes, and then redirects to the provider end-session endpoint.
138
+
139
+ For Keycloak clients, wire the provider logout callbacks to thin app routes that call Spine:
140
+
141
+ ```ts
142
+ // app/routes/auth/backchannel-logout.ts
143
+ import { handleBackChannelLogout } from '@eminuckan/spine/react-router/server';
144
+
145
+ export async function action({ request }: { request: Request }) {
146
+ return handleBackChannelLogout(request);
147
+ }
148
+ ```
149
+
150
+ ```ts
151
+ // app/routes/auth/frontchannel-logout.ts
152
+ import { handleFrontChannelLogout } from '@eminuckan/spine/react-router/server';
153
+
154
+ export async function loader({ request }: { request: Request }) {
155
+ return handleFrontChannelLogout(request);
156
+ }
157
+ ```
158
+
159
+ In Keycloak, configure the client with:
160
+
161
+ - Backchannel Logout URL: `https://your-app.example.com/auth/backchannel-logout`
162
+ - Backchannel Logout Session Required: enabled
163
+ - Frontchannel Logout URL: `https://your-app.example.com/auth/frontchannel-logout`
164
+ - Frontchannel Logout Session Required: enabled
165
+
166
+ Back-channel logout verifies the signed `logout_token` against the provider JWKS and destroys sessions by `sid` or `sub`. Front-channel logout validates `iss` and destroys sessions by `sid` when Keycloak sends it.
167
+
129
168
  ## Quick Start
130
169
 
131
170
  ### 1. Configure Identity and Tenant Adapters
@@ -0,0 +1,3 @@
1
+ import type { AccessDecision, AccessRequirement, AccessSubject } from './types';
2
+ export declare function evaluateAccessRequirement(requirement: AccessRequirement | null | undefined, subject: AccessSubject): AccessDecision;
3
+ //# sourceMappingURL=evaluator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"evaluator.d.ts","sourceRoot":"","sources":["../../src/access/evaluator.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,cAAc,EAGd,iBAAiB,EACjB,aAAa,EAEd,MAAM,SAAS,CAAC;AA0CjB,wBAAgB,yBAAyB,CACvC,WAAW,EAAE,iBAAiB,GAAG,IAAI,GAAG,SAAS,EACjD,OAAO,EAAE,aAAa,GACrB,cAAc,CAkDhB"}
@@ -0,0 +1,3 @@
1
+ export type { AccessDecision, AccessDeniedReason, AccessOperator, AccessRequirement, AccessSubject, SubscriptionAccessSnapshot, } from './types';
2
+ export { evaluateAccessRequirement } from './evaluator';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/access/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,cAAc,EACd,kBAAkB,EAClB,cAAc,EACd,iBAAiB,EACjB,aAAa,EACb,0BAA0B,GAC3B,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,yBAAyB,EAAE,MAAM,aAAa,CAAC"}
@@ -0,0 +1,4 @@
1
+ import "../permission-service-CvGpwI0d.js";
2
+ import { evaluateAccessRequirement } from "../access-DlAqsVGQ.js";
3
+
4
+ export { evaluateAccessRequirement };
@@ -0,0 +1,30 @@
1
+ import type { PermissionCode } from '../permissions/types';
2
+ export type AccessOperator = 'AND' | 'OR';
3
+ export interface SubscriptionAccessSnapshot {
4
+ exists?: boolean;
5
+ status?: string | null;
6
+ planCode?: string | null;
7
+ featureKeys?: readonly string[] | null;
8
+ limits?: Record<string, unknown> | null;
9
+ }
10
+ export interface AccessSubject {
11
+ permissions?: readonly PermissionCode[] | null;
12
+ subscription?: SubscriptionAccessSnapshot | null;
13
+ isInternalUser?: boolean;
14
+ }
15
+ export interface AccessRequirement {
16
+ permissions?: readonly PermissionCode[];
17
+ permissionOperator?: AccessOperator;
18
+ features?: readonly string[];
19
+ featureOperator?: AccessOperator;
20
+ requireActiveSubscription?: boolean;
21
+ internalOnly?: boolean;
22
+ }
23
+ export type AccessDeniedReason = 'internal-only' | 'inactive-subscription' | 'missing-permissions' | 'missing-features';
24
+ export interface AccessDecision {
25
+ allowed: boolean;
26
+ reasons: AccessDeniedReason[];
27
+ missingPermissions: PermissionCode[];
28
+ missingFeatures: string[];
29
+ }
30
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/access/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAE3D,MAAM,MAAM,cAAc,GAAG,KAAK,GAAG,IAAI,CAAC;AAE1C,MAAM,WAAW,0BAA0B;IACzC,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,WAAW,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI,CAAC;IACvC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;CACzC;AAED,MAAM,WAAW,aAAa;IAC5B,WAAW,CAAC,EAAE,SAAS,cAAc,EAAE,GAAG,IAAI,CAAC;IAC/C,YAAY,CAAC,EAAE,0BAA0B,GAAG,IAAI,CAAC;IACjD,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED,MAAM,WAAW,iBAAiB;IAChC,WAAW,CAAC,EAAE,SAAS,cAAc,EAAE,CAAC;IACxC,kBAAkB,CAAC,EAAE,cAAc,CAAC;IACpC,QAAQ,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC7B,eAAe,CAAC,EAAE,cAAc,CAAC;IACjC,yBAAyB,CAAC,EAAE,OAAO,CAAC;IACpC,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED,MAAM,MAAM,kBAAkB,GAC1B,eAAe,GACf,uBAAuB,GACvB,qBAAqB,GACrB,kBAAkB,CAAC;AAEvB,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,kBAAkB,EAAE,CAAC;IAC9B,kBAAkB,EAAE,cAAc,EAAE,CAAC;IACrC,eAAe,EAAE,MAAM,EAAE,CAAC;CAC3B"}
@@ -0,0 +1,59 @@
1
+ import { PermissionChecker } from "./permission-service-CvGpwI0d.js";
2
+
3
+ //#region src/access/evaluator.ts
4
+ const ACTIVE_SUBSCRIPTION_STATUSES = new Set(["active", "trialing"]);
5
+ const EMPTY_DECISION = Object.freeze({
6
+ allowed: true,
7
+ reasons: [],
8
+ missingPermissions: [],
9
+ missingFeatures: []
10
+ });
11
+ function normalizeFeature(value) {
12
+ return value.trim().toLowerCase();
13
+ }
14
+ function hasActiveSubscription(subscription) {
15
+ if (!subscription?.exists) return false;
16
+ return ACTIVE_SUBSCRIPTION_STATUSES.has(subscription.status?.toLowerCase() ?? "");
17
+ }
18
+ function checkFeatureSet(grantedFeatures, requiredFeatures, operator) {
19
+ if (requiredFeatures.length === 0) return [];
20
+ const granted = new Set(grantedFeatures.map(normalizeFeature));
21
+ const normalizedRequired = requiredFeatures.map(normalizeFeature).filter(Boolean);
22
+ if (operator === "OR") return normalizedRequired.some((feature) => granted.has(feature)) ? [] : normalizedRequired;
23
+ return normalizedRequired.filter((feature) => !granted.has(feature));
24
+ }
25
+ function evaluateAccessRequirement(requirement, subject) {
26
+ if (!requirement) return EMPTY_DECISION;
27
+ const reasons = [];
28
+ const permissions = requirement.permissions ?? [];
29
+ const features = requirement.features ?? [];
30
+ let missingPermissions = [];
31
+ let missingFeatures = [];
32
+ if (requirement.internalOnly && !subject.isInternalUser) reasons.push("internal-only");
33
+ if (requirement.requireActiveSubscription && !hasActiveSubscription(subject.subscription)) reasons.push("inactive-subscription");
34
+ if (permissions.length > 0) {
35
+ const checker = new PermissionChecker([...subject.permissions ?? []]);
36
+ const result = checker.hasPermissions([...permissions], {
37
+ operator: requirement.permissionOperator ?? "AND",
38
+ wildcard: true
39
+ });
40
+ if (!result.hasPermission) {
41
+ missingPermissions = result.missingPermissions;
42
+ reasons.push("missing-permissions");
43
+ }
44
+ }
45
+ if (features.length > 0) {
46
+ missingFeatures = checkFeatureSet(subject.subscription?.featureKeys ?? [], features, requirement.featureOperator ?? "AND");
47
+ if (missingFeatures.length > 0) reasons.push("missing-features");
48
+ }
49
+ return {
50
+ allowed: reasons.length === 0,
51
+ reasons,
52
+ missingPermissions,
53
+ missingFeatures
54
+ };
55
+ }
56
+
57
+ //#endregion
58
+ export { evaluateAccessRequirement };
59
+ //# sourceMappingURL=access-DlAqsVGQ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"access-DlAqsVGQ.js","names":["EMPTY_DECISION: AccessDecision","value: string","subscription?: SubscriptionAccessSnapshot | null","grantedFeatures: readonly string[]","requiredFeatures: readonly string[]","operator: AccessOperator","requirement: AccessRequirement | null | undefined","subject: AccessSubject","reasons: AccessDeniedReason[]","missingPermissions: string[]","missingFeatures: string[]"],"sources":["../src/access/evaluator.ts"],"sourcesContent":["import { PermissionChecker } from '../permissions/permission-service';\nimport type {\n AccessDecision,\n AccessDeniedReason,\n AccessOperator,\n AccessRequirement,\n AccessSubject,\n SubscriptionAccessSnapshot,\n} from './types';\n\nconst ACTIVE_SUBSCRIPTION_STATUSES = new Set(['active', 'trialing']);\n\nconst EMPTY_DECISION: AccessDecision = Object.freeze({\n allowed: true,\n reasons: [],\n missingPermissions: [],\n missingFeatures: [],\n});\n\nfunction normalizeFeature(value: string): string {\n return value.trim().toLowerCase();\n}\n\nfunction hasActiveSubscription(subscription?: SubscriptionAccessSnapshot | null): boolean {\n if (!subscription?.exists) {\n return false;\n }\n\n return ACTIVE_SUBSCRIPTION_STATUSES.has(subscription.status?.toLowerCase() ?? '');\n}\n\nfunction checkFeatureSet(\n grantedFeatures: readonly string[],\n requiredFeatures: readonly string[],\n operator: AccessOperator,\n): string[] {\n if (requiredFeatures.length === 0) {\n return [];\n }\n\n const granted = new Set(grantedFeatures.map(normalizeFeature));\n const normalizedRequired = requiredFeatures.map(normalizeFeature).filter(Boolean);\n\n if (operator === 'OR') {\n return normalizedRequired.some((feature) => granted.has(feature)) ? [] : normalizedRequired;\n }\n\n return normalizedRequired.filter((feature) => !granted.has(feature));\n}\n\nexport function evaluateAccessRequirement(\n requirement: AccessRequirement | null | undefined,\n subject: AccessSubject,\n): AccessDecision {\n if (!requirement) {\n return EMPTY_DECISION;\n }\n\n const reasons: AccessDeniedReason[] = [];\n const permissions = requirement.permissions ?? [];\n const features = requirement.features ?? [];\n let missingPermissions: string[] = [];\n let missingFeatures: string[] = [];\n\n if (requirement.internalOnly && !subject.isInternalUser) {\n reasons.push('internal-only');\n }\n\n if (requirement.requireActiveSubscription && !hasActiveSubscription(subject.subscription)) {\n reasons.push('inactive-subscription');\n }\n\n if (permissions.length > 0) {\n const checker = new PermissionChecker([...(subject.permissions ?? [])]);\n const result = checker.hasPermissions([...permissions], {\n operator: requirement.permissionOperator ?? 'AND',\n wildcard: true,\n });\n\n if (!result.hasPermission) {\n missingPermissions = result.missingPermissions;\n reasons.push('missing-permissions');\n }\n }\n\n if (features.length > 0) {\n missingFeatures = checkFeatureSet(\n subject.subscription?.featureKeys ?? [],\n features,\n requirement.featureOperator ?? 'AND',\n );\n\n if (missingFeatures.length > 0) {\n reasons.push('missing-features');\n }\n }\n\n return {\n allowed: reasons.length === 0,\n reasons,\n missingPermissions,\n missingFeatures,\n };\n}\n"],"mappings":";;;AAUA,MAAM,+BAA+B,IAAI,IAAI,CAAC,UAAU,UAAW;AAEnE,MAAMA,iBAAiC,OAAO,OAAO;CACnD,SAAS;CACT,SAAS,CAAE;CACX,oBAAoB,CAAE;CACtB,iBAAiB,CAAE;AACpB,EAAC;AAEF,SAAS,iBAAiBC,OAAuB;AAC/C,QAAO,MAAM,MAAM,CAAC,aAAa;AAClC;AAED,SAAS,sBAAsBC,cAA2D;AACxF,MAAK,cAAc,OACjB,QAAO;AAGT,QAAO,6BAA6B,IAAI,aAAa,QAAQ,aAAa,IAAI,GAAG;AAClF;AAED,SAAS,gBACPC,iBACAC,kBACAC,UACU;AACV,KAAI,iBAAiB,WAAW,EAC9B,QAAO,CAAE;CAGX,MAAM,UAAU,IAAI,IAAI,gBAAgB,IAAI,iBAAiB;CAC7D,MAAM,qBAAqB,iBAAiB,IAAI,iBAAiB,CAAC,OAAO,QAAQ;AAEjF,KAAI,aAAa,KACf,QAAO,mBAAmB,KAAK,CAAC,YAAY,QAAQ,IAAI,QAAQ,CAAC,GAAG,CAAE,IAAG;AAG3E,QAAO,mBAAmB,OAAO,CAAC,aAAa,QAAQ,IAAI,QAAQ,CAAC;AACrE;AAED,SAAgB,0BACdC,aACAC,SACgB;AAChB,MAAK,YACH,QAAO;CAGT,MAAMC,UAAgC,CAAE;CACxC,MAAM,cAAc,YAAY,eAAe,CAAE;CACjD,MAAM,WAAW,YAAY,YAAY,CAAE;CAC3C,IAAIC,qBAA+B,CAAE;CACrC,IAAIC,kBAA4B,CAAE;AAElC,KAAI,YAAY,iBAAiB,QAAQ,eACvC,SAAQ,KAAK,gBAAgB;AAG/B,KAAI,YAAY,8BAA8B,sBAAsB,QAAQ,aAAa,CACvF,SAAQ,KAAK,wBAAwB;AAGvC,KAAI,YAAY,SAAS,GAAG;EAC1B,MAAM,UAAU,IAAI,kBAAkB,CAAC,GAAI,QAAQ,eAAe,CAAE,CAAE;EACtE,MAAM,SAAS,QAAQ,eAAe,CAAC,GAAG,WAAY,GAAE;GACtD,UAAU,YAAY,sBAAsB;GAC5C,UAAU;EACX,EAAC;AAEF,OAAK,OAAO,eAAe;AACzB,wBAAqB,OAAO;AAC5B,WAAQ,KAAK,sBAAsB;EACpC;CACF;AAED,KAAI,SAAS,SAAS,GAAG;AACvB,oBAAkB,gBAChB,QAAQ,cAAc,eAAe,CAAE,GACvC,UACA,YAAY,mBAAmB,MAChC;AAED,MAAI,gBAAgB,SAAS,EAC3B,SAAQ,KAAK,mBAAmB;CAEnC;AAED,QAAO;EACL,SAAS,QAAQ,WAAW;EAC5B;EACA;EACA;CACD;AACF"}
@@ -1,5 +1,5 @@
1
1
  import "../logging-_h2mi3L9.js";
2
- import { isApiClientError } from "../types-BnKaWdfe.js";
3
- import { ApiError, ErrorCodes, ErrorHandler, calculateBackoffDelay, createRetryFetch, fetchWithTimeout, handleApiError, isRetryableError, withRetry } from "../api-client-DsrxK05Z.js";
2
+ import { isApiClientError } from "../types-BaaE6wjY.js";
3
+ import { ApiError, ErrorCodes, ErrorHandler, calculateBackoffDelay, createRetryFetch, fetchWithTimeout, handleApiError, isRetryableError, withRetry } from "../api-client-CZapXIF8.js";
4
4
 
5
5
  export { ApiError, ErrorCodes, ErrorHandler, calculateBackoffDelay, createRetryFetch, fetchWithTimeout, handleApiError, isApiClientError, isRetryableError, withRetry };
@@ -1,6 +1,6 @@
1
1
  import "../logging-_h2mi3L9.js";
2
- import { isApiClientError } from "../types-BnKaWdfe.js";
3
- import { ApiError, ErrorCodes, ErrorHandler, calculateBackoffDelay, createRetryFetch, fetchWithTimeout, handleApiError, isRetryableError, withRetry } from "../api-client-DsrxK05Z.js";
4
- import { createAPIConfigFactory, createApiClient, createFetchMiddleware } from "../server-DZmcd2Lr.js";
2
+ import { isApiClientError } from "../types-BaaE6wjY.js";
3
+ import { ApiError, ErrorCodes, ErrorHandler, calculateBackoffDelay, createRetryFetch, fetchWithTimeout, handleApiError, isRetryableError, withRetry } from "../api-client-CZapXIF8.js";
4
+ import { createAPIConfigFactory, createApiClient, createFetchMiddleware } from "../server-DeBlxoaW.js";
5
5
 
6
6
  export { ApiError, ErrorCodes, ErrorHandler, calculateBackoffDelay, createAPIConfigFactory, createApiClient, createFetchMiddleware, createRetryFetch, fetchWithTimeout, handleApiError, isApiClientError, isRetryableError, withRetry };
@@ -209,4 +209,4 @@ function createRetryFetch(config) {
209
209
 
210
210
  //#endregion
211
211
  export { ApiError, ErrorCodes, ErrorHandler, calculateBackoffDelay, createRetryFetch, fetchWithTimeout, handleApiError, isRetryableError, withRetry };
212
- //# sourceMappingURL=api-client-DsrxK05Z.js.map
212
+ //# sourceMappingURL=api-client-CZapXIF8.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"api-client-DsrxK05Z.js","names":["problemDetails: ProblemDetails","response: Response","config: ErrorHandlerConfig","error: ApiError","message: string","type: 'error' | 'success' | 'info'","DEFAULT_RETRY_CONFIG: Required<RetryConfig>","error: unknown","attempt: number","baseDelay: number","maxDelay: number","fn: () => Promise<T>","config?: RetryConfig","lastError: unknown","input: RequestInfo | URL","init?: RequestInit & { timeout?: number }","init?: RequestInit"],"sources":["../src/api-client/error-codes.ts","../src/api-client/error-handler.ts","../src/api-client/retry-handler.ts"],"sourcesContent":["/**\n * Error Codes\n * \n * Standard error codes from backend.\n */\n\nexport const ErrorCodes = {\n // Validation\n Validation: {\n Failed: 'ValidationFailed',\n },\n\n // Identity\n Identity: {\n InvalidCredentials: 'InvalidCredentials',\n UserInactive: 'UserInactive',\n TenantContextMissing: 'TenantContextMissing',\n InvalidCurrentPassword: 'InvalidCurrentPassword',\n OwnerCannotDisableMembership: 'OwnerCannotDisableMembership',\n CurrentUserMissing: 'CurrentUserMissing',\n UserNotFound: 'UserNotFound',\n EmailAlreadyExists: 'EmailAlreadyExists',\n },\n\n // Accounting\n Accounting: {\n OpeningBalanceLockedReconciliation: 'OpeningBalanceLockedReconciliation',\n OpeningBalanceLockedJournal: 'OpeningBalanceLockedJournal',\n SystemLocked: 'SystemLocked',\n AccountsDuplicate: 'AccountsDuplicate',\n AccountNotFound: 'AccountNotFound',\n },\n\n // Subscription\n Subscription: {\n SubscriptionRequired: 'SubscriptionRequired',\n SubscriptionExpired: 'SubscriptionExpired',\n FeatureNotAvailable: 'FeatureNotAvailable',\n },\n\n // Property Management\n PropertyManagement: {\n PropertyNotFound: 'PropertyNotFound',\n UnitNotFound: 'UnitNotFound',\n DuplicateProperty: 'DuplicateProperty',\n DuplicateUnit: 'DuplicateUnit',\n },\n\n // Leasing\n Leasing: {\n LeaseNotFound: 'LeaseNotFound',\n LeaseConflict: 'LeaseConflict',\n TenantNotFound: 'TenantNotFound',\n LateFeeValidationError: 'LateFeeValidationError',\n },\n\n // General\n NotFound: 'NotFound',\n Unauthorized: 'Unauthorized',\n Forbidden: 'Forbidden',\n InternalError: 'InternalError',\n} as const;\n\n/**\n * Check if error code is from PropertyManagement module\n */\nexport function isPropertyManagementError(code: string): boolean {\n return Object.values(ErrorCodes.PropertyManagement).includes(code as any);\n}\n\n/**\n * Check if error code is from Leasing module\n */\nexport function isLeasingError(code: string): boolean {\n return Object.values(ErrorCodes.Leasing).includes(code as any);\n}\n","/**\n * Error Handler\n * \n * Centralized error handling with ProblemDetails parsing.\n */\n\nimport type { ProblemDetails, ValidationError } from './types';\nimport { ErrorCodes } from './error-codes';\nimport { logger } from '../logging';\n\n/**\n * API Error Class\n */\nexport class ApiError extends Error {\n constructor(\n public problemDetails: ProblemDetails,\n public response: Response\n ) {\n super(problemDetails.detail);\n this.name = 'ApiError';\n }\n\n get code(): string {\n return this.problemDetails.title;\n }\n\n get status(): number {\n return this.problemDetails.status;\n }\n\n get isValidationError(): boolean {\n return this.code === ErrorCodes.Validation.Failed;\n }\n\n get validationErrors(): ValidationError[] {\n return this.problemDetails.meta?.errors ?? [];\n }\n\n get traceId(): string {\n return this.problemDetails.traceId;\n }\n}\n\n/**\n * Parse API error response\n */\nexport async function handleApiError(response: Response): Promise<never> {\n let problemDetails: ProblemDetails;\n\n try {\n problemDetails = await response.json();\n } catch {\n problemDetails = {\n type: `https://httpstatuses.com/${response.status}`,\n title: 'UnknownError',\n status: response.status,\n detail: response.statusText || 'An unknown error occurred',\n traceId: response.headers.get('x-trace-id') ?? 'unknown',\n };\n }\n\n logger.error('API request failed', undefined, {\n code: problemDetails.title,\n status: problemDetails.status,\n detail: problemDetails.detail,\n traceId: problemDetails.traceId,\n });\n\n throw new ApiError(problemDetails, response);\n}\n\n/**\n * Error Handler Configuration\n */\nexport interface ErrorHandlerConfig {\n handlers?: Partial<Record<string, (error: ApiError) => void>>;\n showToast?: boolean;\n toastMessages?: Partial<Record<string, string>>;\n onError?: (error: ApiError) => void;\n toast?: (message: string, type: 'error' | 'success' | 'info') => void;\n}\n\n/**\n * Error Handler Class\n */\nexport class ErrorHandler {\n private config: ErrorHandlerConfig;\n\n constructor(config: ErrorHandlerConfig = {}) {\n this.config = {\n showToast: true,\n ...config,\n };\n }\n\n handle(error: ApiError): void {\n const code = error.code;\n\n logger.error('Handling API Error', undefined, {\n code,\n status: error.status,\n traceId: error.traceId,\n });\n\n // Try custom handler first\n if (this.config.handlers?.[code]) {\n this.config.handlers[code]!(error);\n return;\n }\n\n // Fallback\n if (this.config.onError) {\n this.config.onError(error);\n } else {\n this.showDefaultToast(error);\n }\n }\n\n private showToast(message: string, type: 'error' | 'success' | 'info'): void {\n if (this.config.showToast && this.config.toast) {\n this.config.toast(message, type);\n }\n }\n\n private showDefaultToast(error: ApiError): void {\n const message =\n this.config.toastMessages?.[error.code] ||\n error.problemDetails.detail ||\n 'An error occurred';\n this.showToast(message, 'error');\n }\n}\n\n/**\n * Create global error handler\n */\nexport function createErrorHandler(config?: ErrorHandlerConfig): ErrorHandler {\n return new ErrorHandler(config);\n}\n\n/**\n * Map validation errors to form fields\n */\nexport function mapValidationErrors(errors: ValidationError[]): Record<string, string> {\n const mapped: Record<string, string> = {};\n for (const error of errors) {\n const fieldName = error.field.charAt(0).toLowerCase() + error.field.slice(1);\n mapped[fieldName] = error.message;\n }\n return mapped;\n}\n","/**\n * Retry Handler\n * \n * Retry logic for API requests.\n */\n\nimport type { RetryConfig } from './types';\n\nconst DEFAULT_RETRY_CONFIG: Required<RetryConfig> = {\n maxRetries: 3,\n baseDelay: 1000,\n maxDelay: 10000,\n retryCondition: (error: unknown) => {\n if (error instanceof Response) {\n return error.status >= 500 || error.status === 429;\n }\n return false;\n },\n};\n\n/**\n * Calculate backoff delay\n */\nexport function calculateBackoffDelay(\n attempt: number,\n baseDelay: number,\n maxDelay: number\n): number {\n const delay = baseDelay * Math.pow(2, attempt);\n const jitter = Math.random() * 0.3 * delay;\n return Math.min(delay + jitter, maxDelay);\n}\n\n/**\n * Check if error is retryable\n */\nexport function isRetryableError(error: unknown): boolean {\n if (error instanceof Response) {\n return error.status >= 500 || error.status === 429;\n }\n if (error instanceof TypeError) {\n // Network errors\n return true;\n }\n return false;\n}\n\n/**\n * Execute function with retry logic\n */\nexport async function withRetry<T>(\n fn: () => Promise<T>,\n config?: RetryConfig\n): Promise<T> {\n const { maxRetries, baseDelay, maxDelay, retryCondition } = {\n ...DEFAULT_RETRY_CONFIG,\n ...config,\n };\n\n let lastError: unknown;\n\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n try {\n return await fn();\n } catch (error) {\n lastError = error;\n\n if (attempt === maxRetries || !retryCondition(error)) {\n throw error;\n }\n\n const delay = calculateBackoffDelay(attempt, baseDelay, maxDelay);\n console.log(`Retry attempt ${attempt + 1}/${maxRetries} after ${delay}ms`);\n await new Promise((resolve) => setTimeout(resolve, delay));\n }\n }\n\n throw lastError;\n}\n\n/**\n * Fetch with timeout\n */\nexport async function fetchWithTimeout(\n input: RequestInfo | URL,\n init?: RequestInit & { timeout?: number }\n): Promise<Response> {\n const { timeout = 30000, ...fetchInit } = init || {};\n\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), timeout);\n\n try {\n const response = await fetch(input, {\n ...fetchInit,\n signal: controller.signal,\n });\n return response;\n } finally {\n clearTimeout(timeoutId);\n }\n}\n\n/**\n * Create fetch function with retry\n */\nexport function createRetryFetch(config?: RetryConfig) {\n return async (input: RequestInfo | URL, init?: RequestInit): Promise<Response> => {\n return withRetry(() => fetch(input, init), config);\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"api-client-CZapXIF8.js","names":["problemDetails: ProblemDetails","response: Response","config: ErrorHandlerConfig","error: ApiError","message: string","type: 'error' | 'success' | 'info'","DEFAULT_RETRY_CONFIG: Required<RetryConfig>","error: unknown","attempt: number","baseDelay: number","maxDelay: number","fn: () => Promise<T>","config?: RetryConfig","lastError: unknown","input: RequestInfo | URL","init?: RequestInit & { timeout?: number }","init?: RequestInit"],"sources":["../src/api-client/error-codes.ts","../src/api-client/error-handler.ts","../src/api-client/retry-handler.ts"],"sourcesContent":["/**\n * Error Codes\n * \n * Standard error codes from backend.\n */\n\nexport const ErrorCodes = {\n // Validation\n Validation: {\n Failed: 'ValidationFailed',\n },\n\n // Identity\n Identity: {\n InvalidCredentials: 'InvalidCredentials',\n UserInactive: 'UserInactive',\n TenantContextMissing: 'TenantContextMissing',\n InvalidCurrentPassword: 'InvalidCurrentPassword',\n OwnerCannotDisableMembership: 'OwnerCannotDisableMembership',\n CurrentUserMissing: 'CurrentUserMissing',\n UserNotFound: 'UserNotFound',\n EmailAlreadyExists: 'EmailAlreadyExists',\n },\n\n // Accounting\n Accounting: {\n OpeningBalanceLockedReconciliation: 'OpeningBalanceLockedReconciliation',\n OpeningBalanceLockedJournal: 'OpeningBalanceLockedJournal',\n SystemLocked: 'SystemLocked',\n AccountsDuplicate: 'AccountsDuplicate',\n AccountNotFound: 'AccountNotFound',\n },\n\n // Subscription\n Subscription: {\n SubscriptionRequired: 'SubscriptionRequired',\n SubscriptionExpired: 'SubscriptionExpired',\n FeatureNotAvailable: 'FeatureNotAvailable',\n },\n\n // Property Management\n PropertyManagement: {\n PropertyNotFound: 'PropertyNotFound',\n UnitNotFound: 'UnitNotFound',\n DuplicateProperty: 'DuplicateProperty',\n DuplicateUnit: 'DuplicateUnit',\n },\n\n // Leasing\n Leasing: {\n LeaseNotFound: 'LeaseNotFound',\n LeaseConflict: 'LeaseConflict',\n TenantNotFound: 'TenantNotFound',\n LateFeeValidationError: 'LateFeeValidationError',\n },\n\n // General\n NotFound: 'NotFound',\n Unauthorized: 'Unauthorized',\n Forbidden: 'Forbidden',\n InternalError: 'InternalError',\n} as const;\n\n/**\n * Check if error code is from PropertyManagement module\n */\nexport function isPropertyManagementError(code: string): boolean {\n return Object.values(ErrorCodes.PropertyManagement).includes(code as any);\n}\n\n/**\n * Check if error code is from Leasing module\n */\nexport function isLeasingError(code: string): boolean {\n return Object.values(ErrorCodes.Leasing).includes(code as any);\n}\n","/**\n * Error Handler\n * \n * Centralized error handling with ProblemDetails parsing.\n */\n\nimport type { ProblemDetails, ValidationError } from './types';\nimport { ErrorCodes } from './error-codes';\nimport { logger } from '../logging';\n\n/**\n * API Error Class\n */\nexport class ApiError extends Error {\n constructor(\n public problemDetails: ProblemDetails,\n public response: Response\n ) {\n super(problemDetails.detail);\n this.name = 'ApiError';\n }\n\n get code(): string {\n return this.problemDetails.title;\n }\n\n get status(): number {\n return this.problemDetails.status;\n }\n\n get isValidationError(): boolean {\n return this.code === ErrorCodes.Validation.Failed;\n }\n\n get validationErrors(): ValidationError[] {\n return this.problemDetails.meta?.errors ?? [];\n }\n\n get traceId(): string {\n return this.problemDetails.traceId;\n }\n}\n\n/**\n * Parse API error response\n */\nexport async function handleApiError(response: Response): Promise<never> {\n let problemDetails: ProblemDetails;\n\n try {\n problemDetails = await response.json();\n } catch {\n problemDetails = {\n type: `https://httpstatuses.com/${response.status}`,\n title: 'UnknownError',\n status: response.status,\n detail: response.statusText || 'An unknown error occurred',\n traceId: response.headers.get('x-trace-id') ?? 'unknown',\n };\n }\n\n logger.error('API request failed', undefined, {\n code: problemDetails.title,\n status: problemDetails.status,\n detail: problemDetails.detail,\n traceId: problemDetails.traceId,\n });\n\n throw new ApiError(problemDetails, response);\n}\n\n/**\n * Error Handler Configuration\n */\nexport interface ErrorHandlerConfig {\n handlers?: Partial<Record<string, (error: ApiError) => void>>;\n showToast?: boolean;\n toastMessages?: Partial<Record<string, string>>;\n onError?: (error: ApiError) => void;\n toast?: (message: string, type: 'error' | 'success' | 'info') => void;\n}\n\n/**\n * Error Handler Class\n */\nexport class ErrorHandler {\n private config: ErrorHandlerConfig;\n\n constructor(config: ErrorHandlerConfig = {}) {\n this.config = {\n showToast: true,\n ...config,\n };\n }\n\n handle(error: ApiError): void {\n const code = error.code;\n\n logger.error('Handling API Error', undefined, {\n code,\n status: error.status,\n traceId: error.traceId,\n });\n\n // Try custom handler first\n if (this.config.handlers?.[code]) {\n this.config.handlers[code]!(error);\n return;\n }\n\n // Fallback\n if (this.config.onError) {\n this.config.onError(error);\n } else {\n this.showDefaultToast(error);\n }\n }\n\n private showToast(message: string, type: 'error' | 'success' | 'info'): void {\n if (this.config.showToast && this.config.toast) {\n this.config.toast(message, type);\n }\n }\n\n private showDefaultToast(error: ApiError): void {\n const message =\n this.config.toastMessages?.[error.code] ||\n error.problemDetails.detail ||\n 'An error occurred';\n this.showToast(message, 'error');\n }\n}\n\n/**\n * Create global error handler\n */\nexport function createErrorHandler(config?: ErrorHandlerConfig): ErrorHandler {\n return new ErrorHandler(config);\n}\n\n/**\n * Map validation errors to form fields\n */\nexport function mapValidationErrors(errors: ValidationError[]): Record<string, string> {\n const mapped: Record<string, string> = {};\n for (const error of errors) {\n const fieldName = error.field.charAt(0).toLowerCase() + error.field.slice(1);\n mapped[fieldName] = error.message;\n }\n return mapped;\n}\n","/**\n * Retry Handler\n * \n * Retry logic for API requests.\n */\n\nimport type { RetryConfig } from './types';\n\nconst DEFAULT_RETRY_CONFIG: Required<RetryConfig> = {\n maxRetries: 3,\n baseDelay: 1000,\n maxDelay: 10000,\n retryCondition: (error: unknown) => {\n if (error instanceof Response) {\n return error.status >= 500 || error.status === 429;\n }\n return false;\n },\n};\n\n/**\n * Calculate backoff delay\n */\nexport function calculateBackoffDelay(\n attempt: number,\n baseDelay: number,\n maxDelay: number\n): number {\n const delay = baseDelay * Math.pow(2, attempt);\n const jitter = Math.random() * 0.3 * delay;\n return Math.min(delay + jitter, maxDelay);\n}\n\n/**\n * Check if error is retryable\n */\nexport function isRetryableError(error: unknown): boolean {\n if (error instanceof Response) {\n return error.status >= 500 || error.status === 429;\n }\n if (error instanceof TypeError) {\n // Network errors\n return true;\n }\n return false;\n}\n\n/**\n * Execute function with retry logic\n */\nexport async function withRetry<T>(\n fn: () => Promise<T>,\n config?: RetryConfig\n): Promise<T> {\n const { maxRetries, baseDelay, maxDelay, retryCondition } = {\n ...DEFAULT_RETRY_CONFIG,\n ...config,\n };\n\n let lastError: unknown;\n\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n try {\n return await fn();\n } catch (error) {\n lastError = error;\n\n if (attempt === maxRetries || !retryCondition(error)) {\n throw error;\n }\n\n const delay = calculateBackoffDelay(attempt, baseDelay, maxDelay);\n console.log(`Retry attempt ${attempt + 1}/${maxRetries} after ${delay}ms`);\n await new Promise((resolve) => setTimeout(resolve, delay));\n }\n }\n\n throw lastError;\n}\n\n/**\n * Fetch with timeout\n */\nexport async function fetchWithTimeout(\n input: RequestInfo | URL,\n init?: RequestInit & { timeout?: number }\n): Promise<Response> {\n const { timeout = 30000, ...fetchInit } = init || {};\n\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), timeout);\n\n try {\n const response = await fetch(input, {\n ...fetchInit,\n signal: controller.signal,\n });\n return response;\n } finally {\n clearTimeout(timeoutId);\n }\n}\n\n/**\n * Create fetch function with retry\n */\nexport function createRetryFetch(config?: RetryConfig) {\n return async (input: RequestInfo | URL, init?: RequestInit): Promise<Response> => {\n return withRetry(() => fetch(input, init), config);\n };\n}\n"],"mappings":";;;;;;;;AAMA,MAAa,aAAa;CAExB,YAAY,EACV,QAAQ,mBACT;CAGD,UAAU;EACR,oBAAoB;EACpB,cAAc;EACd,sBAAsB;EACtB,wBAAwB;EACxB,8BAA8B;EAC9B,oBAAoB;EACpB,cAAc;EACd,oBAAoB;CACrB;CAGD,YAAY;EACV,oCAAoC;EACpC,6BAA6B;EAC7B,cAAc;EACd,mBAAmB;EACnB,iBAAiB;CAClB;CAGD,cAAc;EACZ,sBAAsB;EACtB,qBAAqB;EACrB,qBAAqB;CACtB;CAGD,oBAAoB;EAClB,kBAAkB;EAClB,cAAc;EACd,mBAAmB;EACnB,eAAe;CAChB;CAGD,SAAS;EACP,eAAe;EACf,eAAe;EACf,gBAAgB;EAChB,wBAAwB;CACzB;CAGD,UAAU;CACV,cAAc;CACd,WAAW;CACX,eAAe;AAChB;;;;;;;AChDD,IAAa,WAAb,cAA8B,MAAM;CAClC,YACSA,gBACAC,UACP;AACA,QAAM,eAAe,OAAO;EAqI/B,KAxIU;EAwIT,KAvIS;AAGP,OAAK,OAAO;CACb;CAED,IAAI,OAAe;AACjB,SAAO,KAAK,eAAe;CAC5B;CAED,IAAI,SAAiB;AACnB,SAAO,KAAK,eAAe;CAC5B;CAED,IAAI,oBAA6B;AAC/B,SAAO,KAAK,SAAS,WAAW,WAAW;CAC5C;CAED,IAAI,mBAAsC;AACxC,SAAO,KAAK,eAAe,MAAM,UAAU,CAAE;CAC9C;CAED,IAAI,UAAkB;AACpB,SAAO,KAAK,eAAe;CAC5B;AACF;;;;AAKD,eAAsB,eAAeA,UAAoC;CACvE,IAAID;AAEJ,KAAI;AACF,mBAAiB,MAAM,SAAS,MAAM;CACvC,QAAO;AACN,mBAAiB;GACf,OAAO,2BAA2B,SAAS,OAAO;GAClD,OAAO;GACP,QAAQ,SAAS;GACjB,QAAQ,SAAS,cAAc;GAC/B,SAAS,SAAS,QAAQ,IAAI,aAAa,IAAI;EAChD;CACF;AAED,QAAO,MAAM,8BAAiC;EAC5C,MAAM,eAAe;EACrB,QAAQ,eAAe;EACvB,QAAQ,eAAe;EACvB,SAAS,eAAe;CACzB,EAAC;AAEF,OAAM,IAAI,SAAS,gBAAgB;AACpC;;;;AAgBD,IAAa,eAAb,MAA0B;CACxB,AAAQ;CAER,YAAYE,SAA6B,CAAE,GAAE;AAC3C,OAAK,SAAS;GACZ,WAAW;GACX,GAAG;EACJ;CACF;CAED,OAAOC,OAAuB;EAC5B,MAAM,OAAO,MAAM;AAEnB,SAAO,MAAM,8BAAiC;GAC5C;GACA,QAAQ,MAAM;GACd,SAAS,MAAM;EAChB,EAAC;AAGF,MAAI,KAAK,OAAO,WAAW,OAAO;AAChC,QAAK,OAAO,SAAS,MAAO,MAAM;AAClC;EACD;AAGD,MAAI,KAAK,OAAO,QACd,MAAK,OAAO,QAAQ,MAAM;MAE1B,MAAK,iBAAiB,MAAM;CAE/B;CAED,AAAQ,UAAUC,SAAiBC,MAA0C;AAC3E,MAAI,KAAK,OAAO,aAAa,KAAK,OAAO,MACvC,MAAK,OAAO,MAAM,SAAS,KAAK;CAEnC;CAED,AAAQ,iBAAiBF,OAAuB;EAC9C,MAAM,UACJ,KAAK,OAAO,gBAAgB,MAAM,SAClC,MAAM,eAAe,UACrB;AACF,OAAK,UAAU,SAAS,QAAQ;CACjC;AACF;;;;AC3HD,MAAMG,uBAA8C;CAClD,YAAY;CACZ,WAAW;CACX,UAAU;CACV,gBAAgB,CAACC,UAAmB;AAClC,MAAI,iBAAiB,SACnB,QAAO,MAAM,UAAU,OAAO,MAAM,WAAW;AAEjD,SAAO;CACR;AACF;;;;AAKD,SAAgB,sBACdC,SACAC,WACAC,UACQ;CACR,MAAM,QAAQ,YAAY,KAAK,IAAI,GAAG,QAAQ;CAC9C,MAAM,SAAS,KAAK,QAAQ,GAAG,KAAM;AACrC,QAAO,KAAK,IAAI,QAAQ,QAAQ,SAAS;AAC1C;;;;AAKD,SAAgB,iBAAiBH,OAAyB;AACxD,KAAI,iBAAiB,SACnB,QAAO,MAAM,UAAU,OAAO,MAAM,WAAW;AAEjD,KAAI,iBAAiB,UAEnB,QAAO;AAET,QAAO;AACR;;;;AAKD,eAAsB,UACpBI,IACAC,QACY;CACZ,MAAM,EAAE,YAAY,WAAW,UAAU,gBAAgB,GAAG;EAC1D,GAAG;EACH,GAAG;CACJ;CAED,IAAIC;AAEJ,MAAK,IAAI,UAAU,GAAG,WAAW,YAAY,UAC3C,KAAI;AACF,SAAO,MAAM,IAAI;CAClB,SAAQ,OAAO;AACd,cAAY;AAEZ,MAAI,YAAY,eAAe,eAAe,MAAM,CAClD,OAAM;EAGR,MAAM,QAAQ,sBAAsB,SAAS,WAAW,SAAS;AACjE,UAAQ,KAAK,gBAAgB,UAAU,EAAE,GAAG,WAAW,SAAS,MAAM,IAAI;AAC1E,QAAM,IAAI,QAAQ,CAAC,YAAY,WAAW,SAAS,MAAM;CAC1D;AAGH,OAAM;AACP;;;;AAKD,eAAsB,iBACpBC,OACAC,MACmB;CACnB,MAAM,EAAE,UAAU,IAAO,GAAG,WAAW,GAAG,QAAQ,CAAE;CAEpD,MAAM,aAAa,IAAI;CACvB,MAAM,YAAY,WAAW,MAAM,WAAW,OAAO,EAAE,QAAQ;AAE/D,KAAI;EACF,MAAM,WAAW,MAAM,MAAM,OAAO;GAClC,GAAG;GACH,QAAQ,WAAW;EACpB,EAAC;AACF,SAAO;CACR,UAAS;AACR,eAAa,UAAU;CACxB;AACF;;;;AAKD,SAAgB,iBAAiBH,QAAsB;AACrD,QAAO,OAAOE,OAA0BE,SAA0C;AAChF,SAAO,UAAU,MAAM,MAAM,OAAO,KAAK,EAAE,OAAO;CACnD;AACF"}
@@ -1,5 +1,5 @@
1
1
  /**
2
- * OAuth2/OIDC Authentication Server Module
2
+ * OpenID Connect Authentication Server Module
3
3
  *
4
4
  * Handles:
5
5
  * - Login flow (PKCE)
@@ -81,25 +81,30 @@ export declare function login(request: Request, returnUrlOrOptions?: string | Lo
81
81
  */
82
82
  export declare function handleCallback(request: Request): Promise<Response>;
83
83
  /**
84
- * Logout user
84
+ * Logout user.
85
85
  *
86
- * Backend uses id_token_hint to identify which tokens to revoke.
87
- *
88
- * **Scenario 1: Full SSO Logout (Manual Sign Out)**
89
- * - Query param: sso_logout=true
90
- * - Result: Full logout + identity cookie cleared
91
- * - User must re-authenticate everywhere
86
+ * Default logout follows OIDC RP-Initiated Logout and ends the identity
87
+ * provider session. Automatic/session-expiry cleanup can request
88
+ * `/auth/logout?logout=local` to clear only this app's Redis session without
89
+ * bouncing the browser through the identity provider or revoking SSO tokens.
90
+ */
91
+ export declare function logout(request: Request): Promise<Response>;
92
+ /**
93
+ * Handle an OIDC Back-Channel Logout request from Keycloak or another OP.
92
94
  *
93
- * **Scenario 2: Standard Logout (Automatic/Token Expired)**
94
- * - No sso_logout param
95
- * - Result: Tokens revoked based on id_token_hint
96
- * - Backend determines which tokens to revoke
95
+ * Configure the client Backchannel logout URL to this endpoint. The logout
96
+ * token is signature-verified against the provider JWKS, issuer/audience are
97
+ * checked, and all matching local Redis sessions are destroyed by `sid` first,
98
+ * falling back to `sub` when the OP omits a session id.
99
+ */
100
+ export declare function handleBackChannelLogout(request: Request): Promise<Response>;
101
+ /**
102
+ * Handle OIDC Front-Channel Logout iframe/browser requests.
97
103
  *
98
- * Configuration:
99
- * - `OIDC_SSO_LOGOUT` env var ('true' | 'false') - default behavior
100
- * - Query param `sso_logout=true` - override for full logout
104
+ * Front-channel logout cannot carry a signed logout token, so this validates the
105
+ * issuer and applies local cleanup only when a `sid` is present.
101
106
  */
102
- export declare function logout(request: Request): Promise<Response>;
107
+ export declare function handleFrontChannelLogout(request: Request): Promise<Response>;
103
108
  /**
104
109
  * Get current user from session
105
110
  */
@@ -1 +1 @@
1
- {"version":3,"file":"auth.server.d.ts","sourceRoot":"","sources":["../../src/auth/auth.server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH,OAAO,EAKL,cAAc,EAKf,MAAM,gCAAgC,CAAC;AACxC,OAAO,KAAK,EAEV,gBAAgB,EAChB,QAAQ,EAGR,kBAAkB,EAClB,YAAY,EAEZ,SAAS,EACV,MAAM,SAAS,CAAC;AA0NjB;;;GAGG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,gBAAgB,GAAG,IAAI,CAgBzE;AAED;;GAEG;AACH,wBAAgB,qBAAqB,IAAI,IAAI,CAI5C;AAkID;;GAEG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG;IAChE,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,OAAO,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IACtC,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB,CAkDA;AAkDD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,OAAO,GAAG,SAAS,GAAG,IAAI,CAkB/D;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,IAAI,OAAO,CAK/C;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAGtD;AAMD;;;;;GAKG;AACH,wBAAsB,KAAK,CACzB,OAAO,EAAE,OAAO,EAChB,kBAAkB,CAAC,EAAE,MAAM,GAAG,YAAY,GACzC,OAAO,CAAC,QAAQ,CAAC,CAoFnB;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,cAAc,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,CA2NxE;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAsB,MAAM,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,CAyEhE;AAED;;GAEG;AACH,wBAAsB,OAAO,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAQxE;AAED;;GAEG;AACH,wBAAsB,WAAW,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,CAWrE;AAED;;GAEG;AACH,wBAAsB,cAAc,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAQ7E;AAED;;GAEG;AACH,wBAAsB,aAAa,CACjC,OAAO,EAAE,OAAO,EAChB,YAAY,CAAC,EAAE,MAAM,GACpB,OAAO,CAAC,kBAAkB,CAAC,CA4F7B;AAGD,OAAO,EAAE,cAAc,EAAE,CAAC;AAE1B;;GAEG;AACH,wBAAgB,oBAAoB,IAAI,IAAI,CAE3C"}
1
+ {"version":3,"file":"auth.server.d.ts","sourceRoot":"","sources":["../../src/auth/auth.server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAKH,OAAO,EAKL,cAAc,EASf,MAAM,gCAAgC,CAAC;AACxC,OAAO,KAAK,EAEV,gBAAgB,EAChB,QAAQ,EAGR,kBAAkB,EAClB,YAAY,EAKZ,SAAS,EACV,MAAM,SAAS,CAAC;AAwoBjB;;;GAGG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,gBAAgB,GAAG,IAAI,CAgBzE;AAED;;GAEG;AACH,wBAAgB,qBAAqB,IAAI,IAAI,CAI5C;AAkID;;GAEG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG;IAChE,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,OAAO,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IACtC,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB,CAkDA;AAyDD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,OAAO,GAAG,SAAS,GAAG,IAAI,CAkB/D;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,IAAI,OAAO,CAK/C;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAGtD;AAMD;;;;;GAKG;AACH,wBAAsB,KAAK,CACzB,OAAO,EAAE,OAAO,EAChB,kBAAkB,CAAC,EAAE,MAAM,GAAG,YAAY,GACzC,OAAO,CAAC,QAAQ,CAAC,CAgGnB;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,cAAc,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,CA0OxE;AAED;;;;;;;GAOG;AACH,wBAAsB,MAAM,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,CAkGhE;AAED;;;;;;;GAOG;AACH,wBAAsB,uBAAuB,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,CA8CjF;AAED;;;;;GAKG;AACH,wBAAsB,wBAAwB,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,CAmClF;AAED;;GAEG;AACH,wBAAsB,OAAO,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAQxE;AAED;;GAEG;AACH,wBAAsB,WAAW,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,CAWrE;AAED;;GAEG;AACH,wBAAsB,cAAc,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAQ7E;AAED;;GAEG;AACH,wBAAsB,aAAa,CACjC,OAAO,EAAE,OAAO,EAChB,YAAY,CAAC,EAAE,MAAM,GACpB,OAAO,CAAC,kBAAkB,CAAC,CAiD7B;AAGD,OAAO,EAAE,cAAc,EAAE,CAAC;AAE1B;;GAEG;AACH,wBAAgB,oBAAoB,IAAI,IAAI,CAG3C"}
@@ -4,5 +4,5 @@
4
4
  * Client-side auth types live here.
5
5
  * For server-side auth primitives, use `@eminuckan/spine/auth/server`.
6
6
  */
7
- export type { UserInfo, AuthConfig, SessionData, OAuthState, LoginOptions, AuthError, ApplicationType, } from './types';
7
+ export type { UserInfo, AuthSessionSummary, AuthConfig, SessionData, OAuthState, LoginOptions, AuthError, ApplicationType, BackChannelLogoutResult, FrontChannelLogoutResult, OidcClientAuthMethod, } from './types';
8
8
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/auth/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,YAAY,EACV,QAAQ,EACR,UAAU,EACV,WAAW,EACX,UAAU,EACV,YAAY,EACZ,SAAS,EACT,eAAe,GAChB,MAAM,SAAS,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/auth/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,YAAY,EACV,QAAQ,EACR,kBAAkB,EAClB,UAAU,EACV,WAAW,EACX,UAAU,EACV,YAAY,EACZ,SAAS,EACT,eAAe,EACf,uBAAuB,EACvB,wBAAwB,EACxB,oBAAoB,GACrB,MAAM,SAAS,CAAC"}
@@ -5,12 +5,29 @@
5
5
  * Provides secure session management with automatic expiration,
6
6
  * without depending on a framework-specific session implementation.
7
7
  */
8
- import type { SessionData, OAuthState } from './types';
8
+ import type { AuthSessionSummary, SessionData, OAuthState } from './types';
9
9
  export declare const AUTH_ERROR_COOKIE_PREFIX: string;
10
10
  export declare function createAuthSession(request: Request, sessionData: Partial<SessionData>): Promise<Headers>;
11
11
  export declare function getAuthSession(request: Request): Promise<SessionData>;
12
12
  export declare function updateAuthSession(request: Request, updates: Partial<SessionData>): Promise<Headers>;
13
13
  export declare function destroyAuthSession(request: Request): Promise<Headers>;
14
+ export declare function getCurrentAuthSessionId(request: Request): Promise<string | null>;
15
+ export declare function getAuthSessionById(sessionId: string): Promise<SessionData | null>;
16
+ export declare function listAuthSessionDataForUser(userId: string): Promise<Array<{
17
+ sessionId: string;
18
+ data: SessionData;
19
+ }>>;
20
+ export declare function listAuthSessionsForUser(userId: string, currentSessionId?: string | null): Promise<AuthSessionSummary[]>;
21
+ export declare function listCurrentUserAuthSessions(request: Request): Promise<AuthSessionSummary[]>;
22
+ export declare function destroyAuthSessionById(sessionId: string): Promise<boolean>;
23
+ export declare function destroyAuthSessionsForUser(userId: string): Promise<number>;
24
+ export declare function destroyAuthSessionsBySid(sid: string): Promise<number>;
25
+ export declare function destroyAuthSessionsBySessionState(sessionState: string): Promise<number>;
26
+ export declare function destroyAuthSessionsByIdentitySession(params: {
27
+ sid?: string;
28
+ sessionState?: string;
29
+ userId?: string;
30
+ }): Promise<number>;
14
31
  export declare function requireAuthSession(request: Request): Promise<SessionData>;
15
32
  export declare function isSessionValid(request: Request): Promise<boolean>;
16
33
  export declare function createOAuthState(state: OAuthState): Promise<string>;
@@ -1 +1 @@
1
- {"version":3,"file":"redis-session-storage.server.d.ts","sourceRoot":"","sources":["../../src/auth/redis-session-storage.server.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AA4CvD,eAAO,MAAM,wBAAwB,QAAgE,CAAC;AAyKtG,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,OAAO,EAChB,WAAW,EAAE,OAAO,CAAC,WAAW,CAAC,GAChC,OAAO,CAAC,OAAO,CAAC,CAelB;AAED,wBAAsB,cAAc,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,WAAW,CAAC,CAoB3E;AAED,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,OAAO,CAAC,WAAW,CAAC,GAC5B,OAAO,CAAC,OAAO,CAAC,CAalB;AAED,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAS3E;AAED,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,WAAW,CAAC,CAQ/E;AAED,wBAAsB,cAAc,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAgBvE;AAMD,wBAAsB,gBAAgB,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CASzE;AAED,wBAAsB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAe/E;AAED,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAIrE;AAED,wBAAsB,yBAAyB,IAAI,OAAO,CAAC,MAAM,CAAC,CAejE;AAMD,wBAAsB,oBAAoB,IAAI,OAAO,CAAC,IAAI,CAAC,CAM1D"}
1
+ {"version":3,"file":"redis-session-storage.server.d.ts","sourceRoot":"","sources":["../../src/auth/redis-session-storage.server.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,KAAK,EAAE,kBAAkB,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAsD3E,eAAO,MAAM,wBAAwB,QAAgE,CAAC;AA+ctG,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,OAAO,EAChB,WAAW,EAAE,OAAO,CAAC,WAAW,CAAC,GAChC,OAAO,CAAC,OAAO,CAAC,CAqBlB;AAED,wBAAsB,cAAc,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,WAAW,CAAC,CA4B3E;AAED,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,OAAO,CAAC,WAAW,CAAC,GAC5B,OAAO,CAAC,OAAO,CAAC,CAgBlB;AAED,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAS3E;AAED,wBAAsB,uBAAuB,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAEtF;AAED,wBAAsB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAGvF;AAED,wBAAsB,0BAA0B,CAC9C,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,KAAK,CAAC;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,WAAW,CAAA;CAAE,CAAC,CAAC,CAG1D;AAED,wBAAsB,uBAAuB,CAC3C,MAAM,EAAE,MAAM,EACd,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,GAC/B,OAAO,CAAC,kBAAkB,EAAE,CAAC,CAM/B;AAED,wBAAsB,2BAA2B,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,kBAAkB,EAAE,CAAC,CAOjG;AAED,wBAAsB,sBAAsB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAQhF;AAED,wBAAsB,0BAA0B,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAWhF;AAED,wBAAsB,wBAAwB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAW3E;AAED,wBAAsB,iCAAiC,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAW7F;AAED,wBAAsB,oCAAoC,CAAC,MAAM,EAAE;IACjE,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,GAAG,OAAO,CAAC,MAAM,CAAC,CAclB;AAED,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,WAAW,CAAC,CAQ/E;AAED,wBAAsB,cAAc,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAgBvE;AAMD,wBAAsB,gBAAgB,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CASzE;AAED,wBAAsB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAe/E;AAED,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAIrE;AAED,wBAAsB,yBAAyB,IAAI,OAAO,CAAC,MAAM,CAAC,CAejE;AAMD,wBAAsB,oBAAoB,IAAI,OAAO,CAAC,IAAI,CAAC,CAM1D"}
@@ -1 +1 @@
1
- {"version":3,"file":"route-protection.server.d.ts","sourceRoot":"","sources":["../../src/auth/route-protection.server.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"route-protection.server.d.ts","sourceRoot":"","sources":["../../src/auth/route-protection.server.ts"],"names":[],"mappings":"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"}
@@ -8,6 +8,6 @@ export * from './auth.server';
8
8
  export * from './redis-session-storage.server';
9
9
  export * from './route-protection.server';
10
10
  export * from './token-refresh.server';
11
- export type { ApplicationType, AuthClaimMapping, AuthConfig, AuthError, LoginOptions, OAuthState, ProtectedLoaderFn, ProtectionLevel, SessionData, SessionFlashData, UserInfo, } from './types';
11
+ export type { ApplicationType, AuthSessionSummary, AuthClaimMapping, AuthConfig, AuthError, BackChannelLogoutResult, FrontChannelLogoutResult, LoginOptions, OAuthState, OidcClientAuthMethod, ProtectedLoaderFn, ProtectionLevel, SessionData, SessionFlashData, UserInfo, } from './types';
12
12
  export type { TokenRefreshResult as AuthTokenRefreshResult, } from './types';
13
13
  //# sourceMappingURL=server.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/auth/server.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,cAAc,eAAe,CAAC;AAC9B,cAAc,gCAAgC,CAAC;AAC/C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,wBAAwB,CAAC;AACvC,YAAY,EACV,eAAe,EACf,gBAAgB,EAChB,UAAU,EACV,SAAS,EACT,YAAY,EACZ,UAAU,EACV,iBAAiB,EACjB,eAAe,EACf,WAAW,EACX,gBAAgB,EAChB,QAAQ,GACT,MAAM,SAAS,CAAC;AACjB,YAAY,EACV,kBAAkB,IAAI,sBAAsB,GAC7C,MAAM,SAAS,CAAC"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/auth/server.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,cAAc,eAAe,CAAC;AAC9B,cAAc,gCAAgC,CAAC;AAC/C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,wBAAwB,CAAC;AACvC,YAAY,EACV,eAAe,EACf,kBAAkB,EAClB,gBAAgB,EAChB,UAAU,EACV,SAAS,EACT,uBAAuB,EACvB,wBAAwB,EACxB,YAAY,EACZ,UAAU,EACV,oBAAoB,EACpB,iBAAiB,EACjB,eAAe,EACf,WAAW,EACX,gBAAgB,EAChB,QAAQ,GACT,MAAM,SAAS,CAAC;AACjB,YAAY,EACV,kBAAkB,IAAI,sBAAsB,GAC7C,MAAM,SAAS,CAAC"}
@@ -1,6 +1,6 @@
1
1
  import "../logging-_h2mi3L9.js";
2
- import { AUTH_ERROR_COOKIE_PREFIX, cleanupExpiredOAuthStates, closeRedisConnection, createAuthSession, createOAuthState, deleteOAuthState, destroyAuthSession, getAuthSession, getOAuthState, isSessionValid, requireAuthSession, updateAuthSession } from "../redis-session-storage.server-BR_0y-QO.js";
3
- import { clearAuthErrorHeaders, clearAuthServerCache, configureAuthClaimMapping, extractUserInfo, getAccessToken, getAuthError, getUser, handleCallback, hasAuthError, login, logout, refreshTokens, requireAuth, resetAuthClaimMapping } from "../auth.server-Cx2h2qu3.js";
4
- import { attemptTokenRefresh, authRoute, configureRouteProtection, isTokenExpiredResponse, onboardingRoute, protectRoute, publicRoute, resetRouteProtectionConfig, shouldAttemptTokenRefresh, shouldRefreshToken, subscriptionRoute } from "../server-BHfKHKF_.js";
2
+ import { AUTH_ERROR_COOKIE_PREFIX, cleanupExpiredOAuthStates, closeRedisConnection, createAuthSession, createOAuthState, deleteOAuthState, destroyAuthSession, destroyAuthSessionById, destroyAuthSessionsByIdentitySession, destroyAuthSessionsBySessionState, destroyAuthSessionsBySid, destroyAuthSessionsForUser, getAuthSession, getAuthSessionById, getCurrentAuthSessionId, getOAuthState, isSessionValid, listAuthSessionDataForUser, listAuthSessionsForUser, listCurrentUserAuthSessions, requireAuthSession, updateAuthSession } from "../redis-session-storage.server-D0-72FV-.js";
3
+ import { clearAuthErrorHeaders, clearAuthServerCache, configureAuthClaimMapping, extractUserInfo, getAccessToken, getAuthError, getUser, handleBackChannelLogout, handleCallback, handleFrontChannelLogout, hasAuthError, login, logout, refreshTokens, requireAuth, resetAuthClaimMapping } from "../auth.server-B3ODGIX4.js";
4
+ import { attemptTokenRefresh, authRoute, configureRouteProtection, isTokenExpiredResponse, onboardingRoute, protectRoute, publicRoute, resetRouteProtectionConfig, shouldAttemptTokenRefresh, shouldRefreshToken, subscriptionRoute } from "../server-B7JN86_0.js";
5
5
 
6
- export { AUTH_ERROR_COOKIE_PREFIX, attemptTokenRefresh, authRoute, cleanupExpiredOAuthStates, clearAuthErrorHeaders, clearAuthServerCache, closeRedisConnection, configureAuthClaimMapping, configureRouteProtection, createAuthSession, createOAuthState, deleteOAuthState, destroyAuthSession, extractUserInfo, getAccessToken, getAuthError, getAuthSession, getOAuthState, getUser, handleCallback, hasAuthError, isSessionValid, isTokenExpiredResponse, login, logout, onboardingRoute, protectRoute, publicRoute, refreshTokens, requireAuth, requireAuthSession, resetAuthClaimMapping, resetRouteProtectionConfig, shouldAttemptTokenRefresh, shouldRefreshToken, subscriptionRoute, updateAuthSession };
6
+ export { AUTH_ERROR_COOKIE_PREFIX, attemptTokenRefresh, authRoute, cleanupExpiredOAuthStates, clearAuthErrorHeaders, clearAuthServerCache, closeRedisConnection, configureAuthClaimMapping, configureRouteProtection, createAuthSession, createOAuthState, deleteOAuthState, destroyAuthSession, destroyAuthSessionById, destroyAuthSessionsByIdentitySession, destroyAuthSessionsBySessionState, destroyAuthSessionsBySid, destroyAuthSessionsForUser, extractUserInfo, getAccessToken, getAuthError, getAuthSession, getAuthSessionById, getCurrentAuthSessionId, getOAuthState, getUser, handleBackChannelLogout, handleCallback, handleFrontChannelLogout, hasAuthError, isSessionValid, isTokenExpiredResponse, listAuthSessionDataForUser, listAuthSessionsForUser, listCurrentUserAuthSessions, login, logout, onboardingRoute, protectRoute, publicRoute, refreshTokens, requireAuth, requireAuthSession, resetAuthClaimMapping, resetRouteProtectionConfig, shouldAttemptTokenRefresh, shouldRefreshToken, subscriptionRoute, updateAuthSession };