@dreadkn1ght123/auth-core 0.2.0

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.
package/dist/oidc.js ADDED
@@ -0,0 +1,421 @@
1
+ import * as oidc from "openid-client";
2
+ import { KeycloakJwtAccessTokenValidator, } from "./access-token.js";
3
+ import { actorFromClaims } from "./claims.js";
4
+ import { AuthError, classifyAuthError } from "./errors.js";
5
+ import { assertProductionSafeStore } from "./store-security.js";
6
+ const NOOP_LOGGER = {
7
+ debug() { },
8
+ info() { },
9
+ warn() { },
10
+ error() { },
11
+ };
12
+ function log(logger, level, message, fields) {
13
+ // Call sites pass only identifiers/status metadata. Exceptions and protocol
14
+ // responses are intentionally never forwarded because they can hold tokens.
15
+ logger[level](message, fields);
16
+ }
17
+ function diagnosticFields(error, correlationId) {
18
+ return {
19
+ authErrorCode: error.code,
20
+ stage: error.stage,
21
+ reason: error.reason,
22
+ ...(correlationId ? { correlationId } : {}),
23
+ ...(error.details.library ? { library: error.details.library } : {}),
24
+ ...(error.details.libraryCode
25
+ ? { libraryCode: error.details.libraryCode }
26
+ : {}),
27
+ ...(error.details.httpStatus
28
+ ? { httpStatus: error.details.httpStatus }
29
+ : {}),
30
+ ...(error.details.claim ? { claim: error.details.claim } : {}),
31
+ ...(error.details.causeName ? { causeName: error.details.causeName } : {}),
32
+ ...(error.details.causeCode ? { causeCode: error.details.causeCode } : {}),
33
+ ...(error.details.providerError
34
+ ? { providerError: error.details.providerError }
35
+ : {}),
36
+ ...(error.details.providerStatus
37
+ ? { providerStatus: error.details.providerStatus }
38
+ : {}),
39
+ ...(error.details.failedClaim
40
+ ? { failedClaim: error.details.failedClaim }
41
+ : {}),
42
+ ...(error.details.claimFailureReason
43
+ ? { claimFailureReason: error.details.claimFailureReason }
44
+ : {}),
45
+ };
46
+ }
47
+ function validateDiscoveryMetadata(config, metadata) {
48
+ if (config.environment !== "production")
49
+ return;
50
+ const expectedIssuer = config.issuer.href.replace(/\/$/, "");
51
+ if (metadata.issuer.replace(/\/$/, "") !== expectedIssuer) {
52
+ throw new AuthError("OIDC_DISCOVERY_FAILED", "Provider discovery issuer does not match configured issuer", { stage: "discovery", reason: "provider_metadata_invalid" });
53
+ }
54
+ for (const field of ["authorization_endpoint", "token_endpoint", "jwks_uri"]) {
55
+ const value = metadata[field];
56
+ let endpoint;
57
+ try {
58
+ endpoint = new URL(typeof value === "string" ? value : "");
59
+ }
60
+ catch {
61
+ throw new AuthError("OIDC_DISCOVERY_FAILED", `Provider discovery metadata has no valid ${field}`, { stage: "discovery", reason: "provider_metadata_invalid" });
62
+ }
63
+ if (endpoint.protocol !== "https:") {
64
+ throw new AuthError("OIDC_DISCOVERY_FAILED", `Provider discovery ${field} must use HTTPS`, { stage: "discovery", reason: "provider_metadata_invalid" });
65
+ }
66
+ }
67
+ if (metadata.response_types_supported &&
68
+ !metadata.response_types_supported.includes("code")) {
69
+ throw new AuthError("OIDC_DISCOVERY_FAILED", "Provider does not support the authorization code response type", { stage: "discovery", reason: "provider_metadata_invalid" });
70
+ }
71
+ if (metadata.token_endpoint_auth_methods_supported &&
72
+ !metadata.token_endpoint_auth_methods_supported.includes(config.clientAuthenticationMethod)) {
73
+ throw new AuthError("OIDC_DISCOVERY_FAILED", "Provider does not support configured client authentication", { stage: "discovery", reason: "provider_metadata_invalid" });
74
+ }
75
+ if (config.postLogoutRedirectUri &&
76
+ typeof metadata.end_session_endpoint !== "string") {
77
+ throw new AuthError("OIDC_DISCOVERY_FAILED", "Provider does not advertise an end-session endpoint", { stage: "discovery", reason: "provider_metadata_invalid" });
78
+ }
79
+ if (config.postLogoutRedirectUri) {
80
+ let logoutEndpoint;
81
+ try {
82
+ logoutEndpoint = new URL(metadata.end_session_endpoint);
83
+ }
84
+ catch {
85
+ throw new AuthError("OIDC_DISCOVERY_FAILED", "Provider end-session endpoint is invalid", { stage: "discovery", reason: "provider_metadata_invalid" });
86
+ }
87
+ if (logoutEndpoint.protocol !== "https:") {
88
+ throw new AuthError("OIDC_DISCOVERY_FAILED", "Provider end-session endpoint must use HTTPS", { stage: "discovery", reason: "provider_metadata_invalid" });
89
+ }
90
+ }
91
+ }
92
+ function serverTokens(response, now, accessClaims, previous) {
93
+ if (!response.access_token) {
94
+ throw new AuthError("AUTHORIZATION_FAILED", "Token endpoint did not return an access token", { stage: "token_exchange", reason: "access_token_missing" });
95
+ }
96
+ const expiresAt = typeof response.expires_in === "number" && response.expires_in > 0
97
+ ? now + response.expires_in * 1_000
98
+ : typeof accessClaims["exp"] === "number" &&
99
+ Number.isSafeInteger(accessClaims["exp"]) &&
100
+ accessClaims["exp"] * 1_000 > now
101
+ ? accessClaims["exp"] * 1_000
102
+ : undefined;
103
+ if (expiresAt === undefined) {
104
+ throw new AuthError("AUTHORIZATION_FAILED", "Token response has no usable expiration", {
105
+ stage: "access_token_validation",
106
+ reason: "required_claim_missing",
107
+ safeDetails: { failedClaim: "exp", claimFailureReason: "missing" },
108
+ });
109
+ }
110
+ return {
111
+ accessToken: response.access_token,
112
+ ...(response.refresh_token
113
+ ? { refreshToken: response.refresh_token }
114
+ : previous?.refreshToken
115
+ ? { refreshToken: previous.refreshToken }
116
+ : {}),
117
+ ...(response.id_token
118
+ ? { idToken: response.id_token }
119
+ : previous?.idToken
120
+ ? { idToken: previous.idToken }
121
+ : {}),
122
+ expiresAt,
123
+ ...(response.token_type ? { tokenType: response.token_type } : {}),
124
+ ...(response.scope ? { scope: response.scope } : {}),
125
+ };
126
+ }
127
+ export class VvpOidcClient {
128
+ #oidcConfig;
129
+ #config;
130
+ #sessions;
131
+ #logger;
132
+ #now;
133
+ #accessTokens;
134
+ constructor(oidcConfig, config, sessions, logger, now, accessTokens) {
135
+ this.#oidcConfig = oidcConfig;
136
+ this.#config = config;
137
+ this.#sessions = sessions;
138
+ this.#logger = logger;
139
+ this.#now = now;
140
+ this.#accessTokens = accessTokens;
141
+ }
142
+ static async discover(config, sessions, options = {}) {
143
+ const logger = options.logger ?? NOOP_LOGGER;
144
+ // Fail before any network activity: an un-attested store could otherwise
145
+ // let an application appear ready while losing sessions after discovery.
146
+ assertProductionSafeStore(sessions, config.environment, {
147
+ purpose: "session",
148
+ });
149
+ try {
150
+ const clientAuthentication = oidc.ClientSecretBasic(config.clientSecret);
151
+ const discovered = await oidc.discovery(config.issuer, config.clientId, {
152
+ redirect_uris: [config.redirectUri.href],
153
+ response_types: ["code"],
154
+ }, clientAuthentication);
155
+ const metadata = discovered.serverMetadata();
156
+ validateDiscoveryMetadata(config, metadata);
157
+ const jwksUri = typeof metadata.jwks_uri === "string"
158
+ ? new URL(metadata.jwks_uri)
159
+ : undefined;
160
+ const accessTokens = options.accessTokenValidator ??
161
+ (jwksUri
162
+ ? new KeycloakJwtAccessTokenValidator(config, jwksUri)
163
+ : undefined);
164
+ if (!accessTokens) {
165
+ throw new AuthError("OIDC_DISCOVERY_FAILED", "Provider discovery metadata does not include jwks_uri");
166
+ }
167
+ log(logger, "info", "OIDC discovery completed", {
168
+ issuerOrigin: config.issuer.origin,
169
+ clientId: config.clientId,
170
+ });
171
+ const client = new VvpOidcClient(discovered, config, sessions, logger, options.now ?? Date.now, accessTokens);
172
+ log(logger, "info", "vvp.auth.config.ready", {
173
+ stage: "configuration",
174
+ status: "ready",
175
+ issuerOrigin: config.issuer.origin,
176
+ clientId: config.clientId,
177
+ ...(config.publicOrigin
178
+ ? { publicOrigin: config.publicOrigin.origin }
179
+ : {}),
180
+ redirectOrigin: config.redirectUri.origin,
181
+ callbackPath: config.routes.callbackPath,
182
+ signedOutPath: config.routes.signedOutPath,
183
+ ...(config.postLogoutRedirectUri
184
+ ? {
185
+ postLogoutRedirectOrigin: config.postLogoutRedirectUri.origin,
186
+ postLogoutRedirectPath: config.postLogoutRedirectUri.pathname,
187
+ }
188
+ : {}),
189
+ transactionCookiePath: config.routes.cookiePath,
190
+ expectedAccessTokenAudiences: config.accessTokenAudiences,
191
+ expectedAuthorizedParties: config.accessTokenAuthorizedParties,
192
+ scopes: config.scopes,
193
+ });
194
+ return client;
195
+ }
196
+ catch (cause) {
197
+ const classified = classifyAuthError(cause);
198
+ const error = cause instanceof AuthError
199
+ ? cause
200
+ : new AuthError("OIDC_DISCOVERY_FAILED", "Unable to discover the OIDC provider", {
201
+ cause,
202
+ stage: "discovery",
203
+ reason: classified.reason === "callback_failed_unknown"
204
+ ? "provider_unavailable"
205
+ : classified.reason,
206
+ details: classified.details,
207
+ });
208
+ log(logger, "error", "vvp.auth.discovery.failed", {
209
+ ...diagnosticFields(error),
210
+ issuerOrigin: config.issuer.origin,
211
+ clientId: config.clientId,
212
+ });
213
+ throw error;
214
+ }
215
+ }
216
+ async createAuthorizationRequest(options = {}) {
217
+ const codeVerifier = oidc.randomPKCECodeVerifier();
218
+ const codeChallenge = await oidc.calculatePKCECodeChallenge(codeVerifier);
219
+ const state = oidc.randomState();
220
+ const nonce = oidc.randomNonce();
221
+ const parameters = {
222
+ ...options.additionalParameters,
223
+ redirect_uri: this.#config.redirectUri.href,
224
+ scope: this.#config.scopes.join(" "),
225
+ response_type: "code",
226
+ code_challenge: codeChallenge,
227
+ code_challenge_method: "S256",
228
+ state,
229
+ nonce,
230
+ };
231
+ if (options.loginHint)
232
+ parameters["login_hint"] = options.loginHint;
233
+ if (options.prompt)
234
+ parameters["prompt"] = options.prompt;
235
+ return {
236
+ authorizationUrl: oidc.buildAuthorizationUrl(this.#oidcConfig, parameters),
237
+ state,
238
+ nonce,
239
+ codeVerifier,
240
+ };
241
+ }
242
+ async handleCallback(input) {
243
+ try {
244
+ const response = await oidc.authorizationCodeGrant(this.#oidcConfig, input.callbackUrl, {
245
+ expectedState: input.state,
246
+ expectedNonce: input.nonce,
247
+ pkceCodeVerifier: input.codeVerifier,
248
+ idTokenExpected: true,
249
+ });
250
+ const claims = response.claims();
251
+ if (!claims) {
252
+ throw new AuthError("CLAIMS_INVALID", "The provider did not return verified ID token claims", { stage: "id_token_validation", reason: "id_token_missing" });
253
+ }
254
+ const accessClaims = await this.#accessTokens.validate(response.access_token);
255
+ if (typeof accessClaims["sub"] !== "string" ||
256
+ accessClaims["sub"] !== claims.sub) {
257
+ throw new AuthError("ACCESS_TOKEN_INVALID", "ID token and access token subjects do not match", {
258
+ stage: "access_token_validation",
259
+ reason: "token_subject_mismatch",
260
+ safeDetails: { failedClaim: "sub", claimFailureReason: "check_failed" },
261
+ });
262
+ }
263
+ const mergedClaims = {
264
+ ...claims,
265
+ realm_access: accessClaims["realm_access"],
266
+ resource_access: accessClaims["resource_access"],
267
+ };
268
+ const now = this.#now();
269
+ const session = {
270
+ id: oidc.randomState(),
271
+ actor: actorFromClaims(mergedClaims),
272
+ tokens: serverTokens(response, now, accessClaims),
273
+ createdAt: now,
274
+ updatedAt: now,
275
+ };
276
+ try {
277
+ await this.#sessions.set(session, this.#config.sessionTtlSeconds);
278
+ }
279
+ catch (cause) {
280
+ throw new AuthError("SESSION_PERSISTENCE_FAILED", "Unable to persist the authenticated session", {
281
+ cause,
282
+ stage: "session_persistence",
283
+ reason: "session_store_failed",
284
+ });
285
+ }
286
+ log(this.#logger, "info", "vvp.auth.callback.succeeded", {
287
+ stage: "callback_redirect",
288
+ ...(input.correlationId ? { correlationId: input.correlationId } : {}),
289
+ hasBusinessActorId: Boolean(session.actor.vvpActorId),
290
+ });
291
+ return session;
292
+ }
293
+ catch (cause) {
294
+ const error = cause instanceof AuthError
295
+ ? cause
296
+ : (() => {
297
+ const classified = classifyAuthError(cause);
298
+ return new AuthError("AUTHORIZATION_FAILED", "OIDC authorization callback failed", {
299
+ cause,
300
+ stage: classified.reason === "invalid_client" ||
301
+ classified.reason === "pkce_validation_failed" ||
302
+ classified.reason === "token_endpoint_rejected"
303
+ ? "token_exchange"
304
+ : "authorization_response_validation",
305
+ reason: classified.reason,
306
+ details: classified.details,
307
+ });
308
+ })();
309
+ log(this.#logger, "warn", "vvp.auth.callback.rejected", diagnosticFields(error, input.correlationId));
310
+ throw error;
311
+ }
312
+ }
313
+ async refreshSession(sessionId) {
314
+ const session = await this.#sessions.get(sessionId);
315
+ if (!session) {
316
+ throw new AuthError("SESSION_NOT_FOUND", "Session was not found");
317
+ }
318
+ if (!session.tokens.refreshToken) {
319
+ await this.#sessions.delete(sessionId);
320
+ throw new AuthError("TOKEN_REFRESH_FAILED", "Session has no refresh token");
321
+ }
322
+ try {
323
+ const response = await oidc.refreshTokenGrant(this.#oidcConfig, session.tokens.refreshToken);
324
+ const now = this.#now();
325
+ const claims = response.claims();
326
+ const accessClaims = await this.#accessTokens.validate(response.access_token);
327
+ if (typeof accessClaims["sub"] !== "string" ||
328
+ accessClaims["sub"] !== (claims?.sub ?? session.actor.sub)) {
329
+ throw new AuthError("ACCESS_TOKEN_INVALID", "Identity and refreshed access token subjects do not match", {
330
+ stage: "access_token_validation",
331
+ reason: "token_subject_mismatch",
332
+ safeDetails: { failedClaim: "sub", claimFailureReason: "check_failed" },
333
+ });
334
+ }
335
+ const mergedClaims = claims
336
+ ? {
337
+ ...claims,
338
+ realm_access: accessClaims["realm_access"],
339
+ resource_access: accessClaims["resource_access"],
340
+ }
341
+ : undefined;
342
+ const refreshed = {
343
+ ...session,
344
+ actor: mergedClaims
345
+ ? actorFromClaims(mergedClaims)
346
+ : {
347
+ ...session.actor,
348
+ realmRoles: actorFromClaims({
349
+ sub: session.actor.sub,
350
+ realm_access: accessClaims["realm_access"],
351
+ }).realmRoles,
352
+ clientRoles: actorFromClaims({
353
+ sub: session.actor.sub,
354
+ resource_access: accessClaims["resource_access"],
355
+ }).clientRoles,
356
+ },
357
+ tokens: serverTokens(response, now, accessClaims, session.tokens),
358
+ updatedAt: now,
359
+ };
360
+ await this.#sessions.set(refreshed, this.#config.sessionTtlSeconds);
361
+ log(this.#logger, "info", "OIDC tokens refreshed", {
362
+ hasBusinessActorId: Boolean(refreshed.actor.vvpActorId),
363
+ });
364
+ return refreshed;
365
+ }
366
+ catch (cause) {
367
+ await this.#sessions.delete(sessionId);
368
+ const error = cause instanceof AuthError
369
+ ? cause
370
+ : new AuthError("TOKEN_REFRESH_FAILED", "OIDC token refresh failed", {
371
+ cause,
372
+ stage: "token_refresh",
373
+ reason: classifyAuthError(cause).reason,
374
+ safeDetails: classifyAuthError(cause).details,
375
+ });
376
+ log(this.#logger, "warn", "vvp.auth.session.refresh_failed", diagnosticFields(error));
377
+ throw error;
378
+ }
379
+ }
380
+ async logout(sessionId) {
381
+ const session = await this.#sessions.get(sessionId);
382
+ const parameters = {};
383
+ if (session?.tokens.idToken) {
384
+ parameters["id_token_hint"] = session.tokens.idToken;
385
+ }
386
+ if (this.#config.postLogoutRedirectUri) {
387
+ parameters["post_logout_redirect_uri"] =
388
+ this.#config.postLogoutRedirectUri.href;
389
+ }
390
+ await this.#sessions.delete(sessionId);
391
+ log(this.#logger, "info", "vvp.auth.logout.local_session_deleted", {
392
+ stage: "logout",
393
+ reason: "local_session_deleted",
394
+ hadSession: Boolean(session),
395
+ });
396
+ try {
397
+ const logoutUrl = oidc.buildEndSessionUrl(this.#oidcConfig, parameters);
398
+ log(this.#logger, "info", "vvp.auth.logout.redirect_created", {
399
+ stage: "logout",
400
+ reason: "provider_logout_redirect_created",
401
+ });
402
+ return logoutUrl;
403
+ }
404
+ catch (cause) {
405
+ const error = new AuthError("LOGOUT_FAILED", "Unable to create provider logout redirect", {
406
+ cause,
407
+ stage: "logout",
408
+ reason: "provider_logout_rejected",
409
+ });
410
+ log(this.#logger, "warn", "vvp.auth.logout.rejected", diagnosticFields(error));
411
+ throw error;
412
+ }
413
+ }
414
+ }
415
+ export function toPublicSession(session) {
416
+ return {
417
+ actor: session.actor,
418
+ ...(session.tokens.expiresAt ? { expiresAt: session.tokens.expiresAt } : {}),
419
+ };
420
+ }
421
+ //# sourceMappingURL=oidc.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oidc.js","sourceRoot":"","sources":["../src/oidc.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ export interface ReturnToOptions {
2
+ fallback?: string;
3
+ baseOrigin?: string;
4
+ allowedOrigins?: readonly string[];
5
+ }
6
+ /**
7
+ * Accepts local absolute paths, or HTTP(S) URLs on an explicitly allowed
8
+ * origin. Protocol-relative URLs, credentials and non-HTTP schemes are denied.
9
+ */
10
+ export declare function safeReturnTo(candidate: string | null | undefined, options?: ReturnToOptions): string;
11
+ //# sourceMappingURL=return-to.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"return-to.d.ts","sourceRoot":"","sources":["../src/return-to.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACpC;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAC1B,SAAS,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EACpC,OAAO,GAAE,eAAoB,GAC5B,MAAM,CAkCR"}
@@ -0,0 +1,39 @@
1
+ import { AuthError } from "./errors.js";
2
+ /**
3
+ * Accepts local absolute paths, or HTTP(S) URLs on an explicitly allowed
4
+ * origin. Protocol-relative URLs, credentials and non-HTTP schemes are denied.
5
+ */
6
+ export function safeReturnTo(candidate, options = {}) {
7
+ const fallback = options.fallback ?? "/";
8
+ if (!candidate)
9
+ return fallback;
10
+ const value = candidate.trim();
11
+ if (!value || value.startsWith("//") || value.includes("\\"))
12
+ return fallback;
13
+ if (value.startsWith("/")) {
14
+ return value;
15
+ }
16
+ let url;
17
+ try {
18
+ url = new URL(value);
19
+ }
20
+ catch {
21
+ return fallback;
22
+ }
23
+ if ((url.protocol !== "https:" && url.protocol !== "http:") ||
24
+ url.username ||
25
+ url.password) {
26
+ return fallback;
27
+ }
28
+ const allowed = new Set(options.allowedOrigins ?? []);
29
+ if (options.baseOrigin) {
30
+ try {
31
+ allowed.add(new URL(options.baseOrigin).origin);
32
+ }
33
+ catch {
34
+ throw new AuthError("RETURN_TO_INVALID", "baseOrigin must be an absolute URL");
35
+ }
36
+ }
37
+ return allowed.has(url.origin) ? url.href : fallback;
38
+ }
39
+ //# sourceMappingURL=return-to.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"return-to.js","sourceRoot":"","sources":["../src/return-to.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAQxC;;;GAGG;AACH,MAAM,UAAU,YAAY,CAC1B,SAAoC,EACpC,UAA2B,EAAE;IAE7B,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,GAAG,CAAC;IACzC,IAAI,CAAC,SAAS;QAAE,OAAO,QAAQ,CAAC;IAEhC,MAAM,KAAK,GAAG,SAAS,CAAC,IAAI,EAAE,CAAC;IAC/B,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC;QAAE,OAAO,QAAQ,CAAC;IAE9E,IAAI,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QAC1B,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IAAI,GAAQ,CAAC;IACb,IAAI,CAAC;QACH,GAAG,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC;IACvB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,QAAQ,CAAC;IAClB,CAAC;IACD,IACE,CAAC,GAAG,CAAC,QAAQ,KAAK,QAAQ,IAAI,GAAG,CAAC,QAAQ,KAAK,OAAO,CAAC;QACvD,GAAG,CAAC,QAAQ;QACZ,GAAG,CAAC,QAAQ,EACZ,CAAC;QACD,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,cAAc,IAAI,EAAE,CAAC,CAAC;IACtD,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC;QACvB,IAAI,CAAC;YACH,OAAO,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC;QAClD,CAAC;QAAC,MAAM,CAAC;YACP,MAAM,IAAI,SAAS,CAAC,mBAAmB,EAAE,oCAAoC,CAAC,CAAC;QACjF,CAAC;IACH,CAAC;IACD,OAAO,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC;AACvD,CAAC"}
@@ -0,0 +1,20 @@
1
+ import type { RuntimeEnvironment, ServerSession, SessionStore } from "@dreadkn1ght123/auth-types";
2
+ /**
3
+ * Process-local and non-durable. This implementation intentionally refuses to
4
+ * start in production, where callers must supply a shared persistent store.
5
+ */
6
+ export declare class MemorySessionStore implements SessionStore {
7
+ #private;
8
+ readonly capabilities: {
9
+ readonly persistence: "memory";
10
+ readonly shared: false;
11
+ };
12
+ constructor(environment: RuntimeEnvironment, options?: {
13
+ now?: () => number;
14
+ });
15
+ get(id: string): Promise<ServerSession | null>;
16
+ set(session: ServerSession, ttlSeconds: number): Promise<void>;
17
+ delete(id: string): Promise<void>;
18
+ touch(id: string, ttlSeconds: number): Promise<void>;
19
+ }
20
+ //# sourceMappingURL=session-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-store.d.ts","sourceRoot":"","sources":["../src/session-store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,kBAAkB,EAClB,aAAa,EACb,YAAY,EACb,MAAM,4BAA4B,CAAC;AAYpC;;;GAGG;AACH,qBAAa,kBAAmB,YAAW,YAAY;;IACrD,QAAQ,CAAC,YAAY;;;MAGV;gBAKT,WAAW,EAAE,kBAAkB,EAC/B,OAAO,GAAE;QAAE,GAAG,CAAC,EAAE,MAAM,MAAM,CAAA;KAAO;IAWhC,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC;IAU9C,GAAG,CAAC,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAU9D,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIjC,KAAK,CAAC,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAI3D"}
@@ -0,0 +1,50 @@
1
+ import { AuthError } from "./errors.js";
2
+ function clone(session) {
3
+ return structuredClone(session);
4
+ }
5
+ /**
6
+ * Process-local and non-durable. This implementation intentionally refuses to
7
+ * start in production, where callers must supply a shared persistent store.
8
+ */
9
+ export class MemorySessionStore {
10
+ capabilities = {
11
+ persistence: "memory",
12
+ shared: false,
13
+ };
14
+ #entries = new Map();
15
+ #now;
16
+ constructor(environment, options = {}) {
17
+ if (environment === "production") {
18
+ throw new AuthError("SESSION_STORE_UNSAFE", "MemorySessionStore must not be used in production");
19
+ }
20
+ this.#now = options.now ?? Date.now;
21
+ }
22
+ async get(id) {
23
+ const entry = this.#entries.get(id);
24
+ if (!entry)
25
+ return null;
26
+ if (entry.expiresAt <= this.#now()) {
27
+ this.#entries.delete(id);
28
+ return null;
29
+ }
30
+ return clone(entry.session);
31
+ }
32
+ async set(session, ttlSeconds) {
33
+ if (!Number.isSafeInteger(ttlSeconds) || ttlSeconds <= 0) {
34
+ throw new AuthError("CONFIG_INVALID", "Session TTL must be a positive integer");
35
+ }
36
+ this.#entries.set(session.id, {
37
+ session: clone(session),
38
+ expiresAt: this.#now() + ttlSeconds * 1_000,
39
+ });
40
+ }
41
+ async delete(id) {
42
+ this.#entries.delete(id);
43
+ }
44
+ async touch(id, ttlSeconds) {
45
+ const entry = this.#entries.get(id);
46
+ if (entry)
47
+ entry.expiresAt = this.#now() + ttlSeconds * 1_000;
48
+ }
49
+ }
50
+ //# sourceMappingURL=session-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-store.js","sourceRoot":"","sources":["../src/session-store.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAOxC,SAAS,KAAK,CAAC,OAAsB;IACnC,OAAO,eAAe,CAAC,OAAO,CAAC,CAAC;AAClC,CAAC;AAED;;;GAGG;AACH,MAAM,OAAO,kBAAkB;IACpB,YAAY,GAAG;QACtB,WAAW,EAAE,QAAQ;QACrB,MAAM,EAAE,KAAK;KACL,CAAC;IACF,QAAQ,GAAG,IAAI,GAAG,EAAiB,CAAC;IACpC,IAAI,CAAe;IAE5B,YACE,WAA+B,EAC/B,UAAkC,EAAE;QAEpC,IAAI,WAAW,KAAK,YAAY,EAAE,CAAC;YACjC,MAAM,IAAI,SAAS,CACjB,sBAAsB,EACtB,mDAAmD,CACpD,CAAC;QACJ,CAAC;QACD,IAAI,CAAC,IAAI,GAAG,OAAO,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC;IACtC,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,EAAU;QAClB,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACpC,IAAI,CAAC,KAAK;YAAE,OAAO,IAAI,CAAC;QACxB,IAAI,KAAK,CAAC,SAAS,IAAI,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC;YACnC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;YACzB,OAAO,IAAI,CAAC;QACd,CAAC;QACD,OAAO,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAC9B,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,OAAsB,EAAE,UAAkB;QAClD,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,UAAU,CAAC,IAAI,UAAU,IAAI,CAAC,EAAE,CAAC;YACzD,MAAM,IAAI,SAAS,CAAC,gBAAgB,EAAE,wCAAwC,CAAC,CAAC;QAClF,CAAC;QACD,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,EAAE;YAC5B,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC;YACvB,SAAS,EAAE,IAAI,CAAC,IAAI,EAAE,GAAG,UAAU,GAAG,KAAK;SAC5C,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,EAAU;QACrB,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IAC3B,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,EAAU,EAAE,UAAkB;QACxC,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACpC,IAAI,KAAK;YAAE,KAAK,CAAC,SAAS,GAAG,IAAI,CAAC,IAAI,EAAE,GAAG,UAAU,GAAG,KAAK,CAAC;IAChE,CAAC;CACF"}
@@ -0,0 +1,18 @@
1
+ import type { AuthStoreCapabilities, RuntimeEnvironment } from "@dreadkn1ght123/auth-types";
2
+ type AttestedStore = {
3
+ readonly capabilities?: AuthStoreCapabilities;
4
+ };
5
+ export declare function isProductionSafeStore(store: AttestedStore, options?: {
6
+ requireAtomicConsume?: boolean;
7
+ }): boolean;
8
+ /**
9
+ * Rejects un-attested stores in production. An optional capabilities property
10
+ * keeps the SessionStore structural contract backward compatible in non-prod,
11
+ * while making production safety explicit and auditable.
12
+ */
13
+ export declare function assertProductionSafeStore(store: AttestedStore, environment: RuntimeEnvironment, options?: {
14
+ requireAtomicConsume?: boolean;
15
+ purpose?: "session" | "transaction";
16
+ }): void;
17
+ export {};
18
+ //# sourceMappingURL=store-security.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store-security.d.ts","sourceRoot":"","sources":["../src/store-security.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAG5F,KAAK,aAAa,GAAG;IAAE,QAAQ,CAAC,YAAY,CAAC,EAAE,qBAAqB,CAAA;CAAE,CAAC;AAEvE,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,aAAa,EACpB,OAAO,GAAE;IAAE,oBAAoB,CAAC,EAAE,OAAO,CAAA;CAAO,GAC/C,OAAO,CAKT;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,CACvC,KAAK,EAAE,aAAa,EACpB,WAAW,EAAE,kBAAkB,EAC/B,OAAO,GAAE;IAAE,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAAC,OAAO,CAAC,EAAE,SAAS,GAAG,aAAa,CAAA;CAAO,GACpF,IAAI,CASN"}
@@ -0,0 +1,21 @@
1
+ import { AuthError } from "./errors.js";
2
+ export function isProductionSafeStore(store, options = {}) {
3
+ const capabilities = store.capabilities;
4
+ return capabilities?.persistence === "persistent" &&
5
+ capabilities.shared === true &&
6
+ (!options.requireAtomicConsume || capabilities.atomicConsume === true);
7
+ }
8
+ /**
9
+ * Rejects un-attested stores in production. An optional capabilities property
10
+ * keeps the SessionStore structural contract backward compatible in non-prod,
11
+ * while making production safety explicit and auditable.
12
+ */
13
+ export function assertProductionSafeStore(store, environment, options = {}) {
14
+ if (environment !== "production")
15
+ return;
16
+ if (isProductionSafeStore(store, options))
17
+ return;
18
+ const purpose = options.purpose ?? "session";
19
+ throw new AuthError("SESSION_STORE_UNSAFE", `A persistent shared ${purpose} store${options.requireAtomicConsume ? " with atomic consume" : ""} is required in production`, { stage: "configuration", reason: "store_unsafe" });
20
+ }
21
+ //# sourceMappingURL=store-security.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store-security.js","sourceRoot":"","sources":["../src/store-security.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAIxC,MAAM,UAAU,qBAAqB,CACnC,KAAoB,EACpB,UAA8C,EAAE;IAEhD,MAAM,YAAY,GAAG,KAAK,CAAC,YAAY,CAAC;IACxC,OAAO,YAAY,EAAE,WAAW,KAAK,YAAY;QAC/C,YAAY,CAAC,MAAM,KAAK,IAAI;QAC5B,CAAC,CAAC,OAAO,CAAC,oBAAoB,IAAI,YAAY,CAAC,aAAa,KAAK,IAAI,CAAC,CAAC;AAC3E,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,yBAAyB,CACvC,KAAoB,EACpB,WAA+B,EAC/B,UAAmF,EAAE;IAErF,IAAI,WAAW,KAAK,YAAY;QAAE,OAAO;IACzC,IAAI,qBAAqB,CAAC,KAAK,EAAE,OAAO,CAAC;QAAE,OAAO;IAClD,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,SAAS,CAAC;IAC7C,MAAM,IAAI,SAAS,CACjB,sBAAsB,EACtB,uBAAuB,OAAO,SAAS,OAAO,CAAC,oBAAoB,CAAC,CAAC,CAAC,sBAAsB,CAAC,CAAC,CAAC,EAAE,4BAA4B,EAC7H,EAAE,KAAK,EAAE,eAAe,EAAE,MAAM,EAAE,cAAc,EAAE,CACnD,CAAC;AACJ,CAAC"}
@@ -0,0 +1,11 @@
1
+ import type { TransactionConsumeOutcome } from "@dreadkn1ght123/auth-types";
2
+ import { AuthError } from "./errors.js";
3
+ /**
4
+ * Converts an explicit, secret-free atomic consume result to the diagnostic
5
+ * used by adapters. The successful transaction is deliberately never copied
6
+ * into the error or its safe details.
7
+ */
8
+ export declare function transactionConsumeError<T>(outcome: Exclude<TransactionConsumeOutcome<T>, {
9
+ status: "ok";
10
+ }>): AuthError;
11
+ //# sourceMappingURL=transaction.d.ts.map