@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/README.md +50 -0
- package/dist/access-token.d.ts +18 -0
- package/dist/access-token.d.ts.map +1 -0
- package/dist/access-token.js +49 -0
- package/dist/access-token.js.map +1 -0
- package/dist/claims.d.ts +14 -0
- package/dist/claims.d.ts.map +1 -0
- package/dist/claims.js +110 -0
- package/dist/claims.js.map +1 -0
- package/dist/config.d.ts +10 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +229 -0
- package/dist/config.js.map +1 -0
- package/dist/errors.d.ts +25 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +164 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -0
- package/dist/oidc.d.ts +38 -0
- package/dist/oidc.d.ts.map +1 -0
- package/dist/oidc.js +421 -0
- package/dist/oidc.js.map +1 -0
- package/dist/return-to.d.ts +11 -0
- package/dist/return-to.d.ts.map +1 -0
- package/dist/return-to.js +39 -0
- package/dist/return-to.js.map +1 -0
- package/dist/session-store.d.ts +20 -0
- package/dist/session-store.d.ts.map +1 -0
- package/dist/session-store.js +50 -0
- package/dist/session-store.js.map +1 -0
- package/dist/store-security.d.ts +18 -0
- package/dist/store-security.d.ts.map +1 -0
- package/dist/store-security.js +21 -0
- package/dist/store-security.js.map +1 -0
- package/dist/transaction.d.ts +11 -0
- package/dist/transaction.d.ts.map +1 -0
- package/dist/transaction.js +17 -0
- package/dist/transaction.js.map +1 -0
- package/package.json +35 -0
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
|
package/dist/oidc.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oidc.js","sourceRoot":"","sources":["../src/oidc.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,IAAI,MAAM,eAAe,CAAC;AACtC,OAAO,EACL,+BAA+B,GAEhC,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAC3D,OAAO,EAAE,yBAAyB,EAAE,MAAM,qBAAqB,CAAC;AA0BhE,MAAM,WAAW,GAAe;IAC9B,KAAK,KAAI,CAAC;IACV,IAAI,KAAI,CAAC;IACT,IAAI,KAAI,CAAC;IACT,KAAK,KAAI,CAAC;CACX,CAAC;AAEF,SAAS,GAAG,CACV,MAAkB,EAClB,KAAuB,EACvB,OAAe,EACf,MAAsB;IAEtB,4EAA4E;IAC5E,4EAA4E;IAC5E,MAAM,CAAC,KAAK,CAAC,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;AACjC,CAAC;AAED,SAAS,gBAAgB,CACvB,KAAgB,EAChB,aAAsB;IAEtB,OAAO;QACL,aAAa,EAAE,KAAK,CAAC,IAAI;QACzB,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC3C,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACpE,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,WAAW;YAC3B,CAAC,CAAC,EAAE,WAAW,EAAE,KAAK,CAAC,OAAO,CAAC,WAAW,EAAE;YAC5C,CAAC,CAAC,EAAE,CAAC;QACP,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,UAAU;YAC1B,CAAC,CAAC,EAAE,UAAU,EAAE,KAAK,CAAC,OAAO,CAAC,UAAU,EAAE;YAC1C,CAAC,CAAC,EAAE,CAAC;QACP,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC9D,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,KAAK,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC1E,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,KAAK,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC1E,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,aAAa;YAC7B,CAAC,CAAC,EAAE,aAAa,EAAE,KAAK,CAAC,OAAO,CAAC,aAAa,EAAE;YAChD,CAAC,CAAC,EAAE,CAAC;QACP,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,cAAc;YAC9B,CAAC,CAAC,EAAE,cAAc,EAAE,KAAK,CAAC,OAAO,CAAC,cAAc,EAAE;YAClD,CAAC,CAAC,EAAE,CAAC;QACP,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,WAAW;YAC3B,CAAC,CAAC,EAAE,WAAW,EAAE,KAAK,CAAC,OAAO,CAAC,WAAW,EAAE;YAC5C,CAAC,CAAC,EAAE,CAAC;QACP,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,kBAAkB;YAClC,CAAC,CAAC,EAAE,kBAAkB,EAAE,KAAK,CAAC,OAAO,CAAC,kBAAkB,EAAE;YAC1D,CAAC,CAAC,EAAE,CAAC;KACR,CAAC;AACJ,CAAC;AAED,SAAS,yBAAyB,CAAC,MAAkB,EAAE,QAA6B;IAClF,IAAI,MAAM,CAAC,WAAW,KAAK,YAAY;QAAE,OAAO;IAChD,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IAC7D,IAAI,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,cAAc,EAAE,CAAC;QAC1D,MAAM,IAAI,SAAS,CACjB,uBAAuB,EACvB,4DAA4D,EAC5D,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,2BAA2B,EAAE,CAC5D,CAAC;IACJ,CAAC;IACD,KAAK,MAAM,KAAK,IAAI,CAAC,wBAAwB,EAAE,gBAAgB,EAAE,UAAU,CAAU,EAAE,CAAC;QACtF,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;QAC9B,IAAI,QAAa,CAAC;QAClB,IAAI,CAAC;YACH,QAAQ,GAAG,IAAI,GAAG,CAAC,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAC7D,CAAC;QAAC,MAAM,CAAC;YACP,MAAM,IAAI,SAAS,CACjB,uBAAuB,EACvB,4CAA4C,KAAK,EAAE,EACnD,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,2BAA2B,EAAE,CAC5D,CAAC;QACJ,CAAC;QACD,IAAI,QAAQ,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;YACnC,MAAM,IAAI,SAAS,CACjB,uBAAuB,EACvB,sBAAsB,KAAK,iBAAiB,EAC5C,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,2BAA2B,EAAE,CAC5D,CAAC;QACJ,CAAC;IACH,CAAC;IACD,IAAI,QAAQ,CAAC,wBAAwB;QACjC,CAAC,QAAQ,CAAC,wBAAwB,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;QACxD,MAAM,IAAI,SAAS,CACjB,uBAAuB,EACvB,gEAAgE,EAChE,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,2BAA2B,EAAE,CAC5D,CAAC;IACJ,CAAC;IACD,IAAI,QAAQ,CAAC,qCAAqC;QAC9C,CAAC,QAAQ,CAAC,qCAAqC,CAAC,QAAQ,CACtD,MAAM,CAAC,0BAA0B,CAClC,EAAE,CAAC;QACN,MAAM,IAAI,SAAS,CACjB,uBAAuB,EACvB,4DAA4D,EAC5D,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,2BAA2B,EAAE,CAC5D,CAAC;IACJ,CAAC;IACD,IAAI,MAAM,CAAC,qBAAqB;QAC5B,OAAO,QAAQ,CAAC,oBAAoB,KAAK,QAAQ,EAAE,CAAC;QACtD,MAAM,IAAI,SAAS,CACjB,uBAAuB,EACvB,qDAAqD,EACrD,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,2BAA2B,EAAE,CAC5D,CAAC;IACJ,CAAC;IACD,IAAI,MAAM,CAAC,qBAAqB,EAAE,CAAC;QACjC,IAAI,cAAmB,CAAC;QACxB,IAAI,CAAC;YACH,cAAc,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,oBAAqB,CAAC,CAAC;QAC3D,CAAC;QAAC,MAAM,CAAC;YACP,MAAM,IAAI,SAAS,CACjB,uBAAuB,EACvB,0CAA0C,EAC1C,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,2BAA2B,EAAE,CAC5D,CAAC;QACJ,CAAC;QACD,IAAI,cAAc,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;YACzC,MAAM,IAAI,SAAS,CACjB,uBAAuB,EACvB,8CAA8C,EAC9C,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,2BAA2B,EAAE,CAC5D,CAAC;QACJ,CAAC;IACH,CAAC;AACH,CAAC;AAED,SAAS,YAAY,CACnB,QAAiE,EACjE,GAAW,EACX,YAA+C,EAC/C,QAAuB;IAEvB,IAAI,CAAC,QAAQ,CAAC,YAAY,EAAE,CAAC;QAC3B,MAAM,IAAI,SAAS,CACjB,sBAAsB,EACtB,+CAA+C,EAC/C,EAAE,KAAK,EAAE,gBAAgB,EAAE,MAAM,EAAE,sBAAsB,EAAE,CAC5D,CAAC;IACJ,CAAC;IACD,MAAM,SAAS,GACb,OAAO,QAAQ,CAAC,UAAU,KAAK,QAAQ,IAAI,QAAQ,CAAC,UAAU,GAAG,CAAC;QAChE,CAAC,CAAC,GAAG,GAAG,QAAQ,CAAC,UAAU,GAAG,KAAK;QACnC,CAAC,CAAC,OAAO,YAAY,CAAC,KAAK,CAAC,KAAK,QAAQ;YACrC,MAAM,CAAC,aAAa,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;YACzC,YAAY,CAAC,KAAK,CAAC,GAAG,KAAK,GAAG,GAAG;YACnC,CAAC,CAAC,YAAY,CAAC,KAAK,CAAC,GAAG,KAAK;YAC7B,CAAC,CAAC,SAAS,CAAC;IAClB,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;QAC5B,MAAM,IAAI,SAAS,CACjB,sBAAsB,EACtB,yCAAyC,EACzC;YACE,KAAK,EAAE,yBAAyB;YAChC,MAAM,EAAE,wBAAwB;YAChC,WAAW,EAAE,EAAE,WAAW,EAAE,KAAK,EAAE,kBAAkB,EAAE,SAAS,EAAE;SACnE,CACF,CAAC;IACJ,CAAC;IACD,OAAO;QACL,WAAW,EAAE,QAAQ,CAAC,YAAY;QAClC,GAAG,CAAC,QAAQ,CAAC,aAAa;YACxB,CAAC,CAAC,EAAE,YAAY,EAAE,QAAQ,CAAC,aAAa,EAAE;YAC1C,CAAC,CAAC,QAAQ,EAAE,YAAY;gBACtB,CAAC,CAAC,EAAE,YAAY,EAAE,QAAQ,CAAC,YAAY,EAAE;gBACzC,CAAC,CAAC,EAAE,CAAC;QACT,GAAG,CAAC,QAAQ,CAAC,QAAQ;YACnB,CAAC,CAAC,EAAE,OAAO,EAAE,QAAQ,CAAC,QAAQ,EAAE;YAChC,CAAC,CAAC,QAAQ,EAAE,OAAO;gBACjB,CAAC,CAAC,EAAE,OAAO,EAAE,QAAQ,CAAC,OAAO,EAAE;gBAC/B,CAAC,CAAC,EAAE,CAAC;QACT,SAAS;QACT,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAClE,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACrD,CAAC;AACJ,CAAC;AAED,MAAM,OAAO,aAAa;IACf,WAAW,CAAqB;IAChC,OAAO,CAAa;IACpB,SAAS,CAAe;IACxB,OAAO,CAAa;IACpB,IAAI,CAAe;IACnB,aAAa,CAAuB;IAE7C,YACE,UAA8B,EAC9B,MAAkB,EAClB,QAAsB,EACtB,MAAkB,EAClB,GAAiB,EACjB,YAAkC;QAElC,IAAI,CAAC,WAAW,GAAG,UAAU,CAAC;QAC9B,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC;QACtB,IAAI,CAAC,SAAS,GAAG,QAAQ,CAAC;QAC1B,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC;QACtB,IAAI,CAAC,IAAI,GAAG,GAAG,CAAC;QAChB,IAAI,CAAC,aAAa,GAAG,YAAY,CAAC;IACpC,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,QAAQ,CACnB,MAAkB,EAClB,QAAsB,EACtB,UAII,EAAE;QAEN,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,WAAW,CAAC;QAC7C,yEAAyE;QACzE,yEAAyE;QACzE,yBAAyB,CAAC,QAAQ,EAAE,MAAM,CAAC,WAAW,EAAE;YACtD,OAAO,EAAE,SAAS;SACnB,CAAC,CAAC;QACH,IAAI,CAAC;YACH,MAAM,oBAAoB,GAAG,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;YACzE,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,SAAS,CACrC,MAAM,CAAC,MAAM,EACb,MAAM,CAAC,QAAQ,EACf;gBACE,aAAa,EAAE,CAAC,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC;gBACxC,cAAc,EAAE,CAAC,MAAM,CAAC;aACzB,EACD,oBAAoB,CACrB,CAAC;YACF,MAAM,QAAQ,GAAG,UAAU,CAAC,cAAc,EAAE,CAAC;YAC7C,yBAAyB,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;YAC5C,MAAM,OAAO,GACX,OAAO,QAAQ,CAAC,QAAQ,KAAK,QAAQ;gBACnC,CAAC,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC;gBAC5B,CAAC,CAAC,SAAS,CAAC;YAChB,MAAM,YAAY,GAChB,OAAO,CAAC,oBAAoB;gBAC5B,CAAC,OAAO;oBACN,CAAC,CAAC,IAAI,+BAA+B,CAAC,MAAM,EAAE,OAAO,CAAC;oBACtD,CAAC,CAAC,SAAS,CAAC,CAAC;YACjB,IAAI,CAAC,YAAY,EAAE,CAAC;gBAClB,MAAM,IAAI,SAAS,CACjB,uBAAuB,EACvB,uDAAuD,CACxD,CAAC;YACJ,CAAC;YACD,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,0BAA0B,EAAE;gBAC9C,YAAY,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM;gBAClC,QAAQ,EAAE,MAAM,CAAC,QAAQ;aAC1B,CAAC,CAAC;YACH,MAAM,MAAM,GAAG,IAAI,aAAa,CAC9B,UAAU,EACV,MAAM,EACN,QAAQ,EACR,MAAM,EACN,OAAO,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,EACvB,YAAY,CACb,CAAC;YACF,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,uBAAuB,EAAE;gBAC3C,KAAK,EAAE,eAAe;gBACtB,MAAM,EAAE,OAAO;gBACf,YAAY,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM;gBAClC,QAAQ,EAAE,MAAM,CAAC,QAAQ;gBACzB,GAAG,CAAC,MAAM,CAAC,YAAY;oBACrB,CAAC,CAAC,EAAE,YAAY,EAAE,MAAM,CAAC,YAAY,CAAC,MAAM,EAAE;oBAC9C,CAAC,CAAC,EAAE,CAAC;gBACP,cAAc,EAAE,MAAM,CAAC,WAAW,CAAC,MAAM;gBACzC,YAAY,EAAE,MAAM,CAAC,MAAM,CAAC,YAAY;gBACxC,aAAa,EAAE,MAAM,CAAC,MAAM,CAAC,aAAa;gBAC1C,GAAG,CAAC,MAAM,CAAC,qBAAqB;oBAC9B,CAAC,CAAC;wBACE,wBAAwB,EAAE,MAAM,CAAC,qBAAqB,CAAC,MAAM;wBAC7D,sBAAsB,EAAE,MAAM,CAAC,qBAAqB,CAAC,QAAQ;qBAC9D;oBACH,CAAC,CAAC,EAAE,CAAC;gBACP,qBAAqB,EAAE,MAAM,CAAC,MAAM,CAAC,UAAU;gBAC/C,4BAA4B,EAAE,MAAM,CAAC,oBAAoB;gBACzD,yBAAyB,EAAE,MAAM,CAAC,4BAA4B;gBAC9D,MAAM,EAAE,MAAM,CAAC,MAAM;aACtB,CAAC,CAAC;YACH,OAAO,MAAM,CAAC;QAChB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,UAAU,GAAG,iBAAiB,CAAC,KAAK,CAAC,CAAC;YAC5C,MAAM,KAAK,GAAG,KAAK,YAAY,SAAS;gBACtC,CAAC,CAAC,KAAK;gBACP,CAAC,CAAC,IAAI,SAAS,CACX,uBAAuB,EACvB,sCAAsC,EACtC;oBACE,KAAK;oBACL,KAAK,EAAE,WAAW;oBAClB,MAAM,EAAE,UAAU,CAAC,MAAM,KAAK,yBAAyB;wBACrD,CAAC,CAAC,sBAAsB;wBACxB,CAAC,CAAC,UAAU,CAAC,MAAM;oBACrB,OAAO,EAAE,UAAU,CAAC,OAAO;iBAC5B,CACF,CAAC;YACN,GAAG,CAAC,MAAM,EAAE,OAAO,EAAE,2BAA2B,EAAE;gBAChD,GAAG,gBAAgB,CAAC,KAAK,CAAC;gBAC1B,YAAY,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM;gBAClC,QAAQ,EAAE,MAAM,CAAC,QAAQ;aAC1B,CAAC,CAAC;YACH,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;IAED,KAAK,CAAC,0BAA0B,CAC9B,UAAgC,EAAE;QAElC,MAAM,YAAY,GAAG,IAAI,CAAC,sBAAsB,EAAE,CAAC;QACnD,MAAM,aAAa,GAAG,MAAM,IAAI,CAAC,0BAA0B,CAAC,YAAY,CAAC,CAAC;QAC1E,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;QACjC,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;QACjC,MAAM,UAAU,GAA2B;YACzC,GAAG,OAAO,CAAC,oBAAoB;YAC/B,YAAY,EAAE,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI;YAC3C,KAAK,EAAE,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC;YACpC,aAAa,EAAE,MAAM;YACrB,cAAc,EAAE,aAAa;YAC7B,qBAAqB,EAAE,MAAM;YAC7B,KAAK;YACL,KAAK;SACN,CAAC;QACF,IAAI,OAAO,CAAC,SAAS;YAAE,UAAU,CAAC,YAAY,CAAC,GAAG,OAAO,CAAC,SAAS,CAAC;QACpE,IAAI,OAAO,CAAC,MAAM;YAAE,UAAU,CAAC,QAAQ,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC;QAE1D,OAAO;YACL,gBAAgB,EAAE,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,WAAW,EAAE,UAAU,CAAC;YAC1E,KAAK;YACL,KAAK;YACL,YAAY;SACb,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,cAAc,CAAC,KAAoB;QACvC,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,sBAAsB,CAChD,IAAI,CAAC,WAAW,EAChB,KAAK,CAAC,WAAW,EACjB;gBACE,aAAa,EAAE,KAAK,CAAC,KAAK;gBAC1B,aAAa,EAAE,KAAK,CAAC,KAAK;gBAC1B,gBAAgB,EAAE,KAAK,CAAC,YAAY;gBACpC,eAAe,EAAE,IAAI;aACtB,CACF,CAAC;YACF,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,EAAE,CAAC;YACjC,IAAI,CAAC,MAAM,EAAE,CAAC;gBACZ,MAAM,IAAI,SAAS,CACjB,gBAAgB,EAChB,sDAAsD,EACtD,EAAE,KAAK,EAAE,qBAAqB,EAAE,MAAM,EAAE,kBAAkB,EAAE,CAC7D,CAAC;YACJ,CAAC;YACD,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,QAAQ,CACpD,QAAQ,CAAC,YAAY,CACtB,CAAC;YACF,IACE,OAAO,YAAY,CAAC,KAAK,CAAC,KAAK,QAAQ;gBACvC,YAAY,CAAC,KAAK,CAAC,KAAK,MAAM,CAAC,GAAG,EAClC,CAAC;gBACD,MAAM,IAAI,SAAS,CACjB,sBAAsB,EACtB,iDAAiD,EACjD;oBACE,KAAK,EAAE,yBAAyB;oBAChC,MAAM,EAAE,wBAAwB;oBAChC,WAAW,EAAE,EAAE,WAAW,EAAE,KAAK,EAAE,kBAAkB,EAAE,cAAc,EAAE;iBACxE,CACF,CAAC;YACJ,CAAC;YACD,MAAM,YAAY,GAAG;gBACnB,GAAG,MAAM;gBACT,YAAY,EAAE,YAAY,CAAC,cAAc,CAAC;gBAC1C,eAAe,EAAE,YAAY,CAAC,iBAAiB,CAAC;aACjD,CAAC;YACF,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;YACxB,MAAM,OAAO,GAAkB;gBAC7B,EAAE,EAAE,IAAI,CAAC,WAAW,EAAE;gBACtB,KAAK,EAAE,eAAe,CAAC,YAAY,CAAC;gBACpC,MAAM,EAAE,YAAY,CAAC,QAAQ,EAAE,GAAG,EAAE,YAAY,CAAC;gBACjD,SAAS,EAAE,GAAG;gBACd,SAAS,EAAE,GAAG;aACf,CAAC;YACF,IAAI,CAAC;gBACH,MAAM,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC;YACpE,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,MAAM,IAAI,SAAS,CACjB,4BAA4B,EAC5B,6CAA6C,EAC7C;oBACE,KAAK;oBACL,KAAK,EAAE,qBAAqB;oBAC5B,MAAM,EAAE,sBAAsB;iBAC/B,CACF,CAAC;YACJ,CAAC;YACD,GAAG,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,6BAA6B,EAAE;gBACvD,KAAK,EAAE,mBAAmB;gBAC1B,GAAG,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,KAAK,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBACtE,kBAAkB,EAAE,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC;aACtD,CAAC,CAAC;YACH,OAAO,OAAO,CAAC;QACjB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,KAAK,GAAG,KAAK,YAAY,SAAS;gBACtC,CAAC,CAAC,KAAK;gBACP,CAAC,CAAC,CAAC,GAAG,EAAE;oBACJ,MAAM,UAAU,GAAG,iBAAiB,CAAC,KAAK,CAAC,CAAC;oBAC5C,OAAO,IAAI,SAAS,CAClB,sBAAsB,EACtB,oCAAoC,EACpC;wBACE,KAAK;wBACL,KAAK,EAAE,UAAU,CAAC,MAAM,KAAK,gBAAgB;4BACzC,UAAU,CAAC,MAAM,KAAK,wBAAwB;4BAC9C,UAAU,CAAC,MAAM,KAAK,yBAAyB;4BACjD,CAAC,CAAC,gBAAgB;4BAClB,CAAC,CAAC,mCAAmC;wBACvC,MAAM,EAAE,UAAU,CAAC,MAAM;wBACzB,OAAO,EAAE,UAAU,CAAC,OAAO;qBAC5B,CACF,CAAC;gBACJ,CAAC,CAAC,EAAE,CAAC;YACT,GAAG,CACD,IAAI,CAAC,OAAO,EACZ,MAAM,EACN,4BAA4B,EAC5B,gBAAgB,CAAC,KAAK,EAAE,KAAK,CAAC,aAAa,CAAC,CAC7C,CAAC;YACF,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;IAED,KAAK,CAAC,cAAc,CAAC,SAAiB;QACpC,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QACpD,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,MAAM,IAAI,SAAS,CAAC,mBAAmB,EAAE,uBAAuB,CAAC,CAAC;QACpE,CAAC;QACD,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,YAAY,EAAE,CAAC;YACjC,MAAM,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;YACvC,MAAM,IAAI,SAAS,CACjB,sBAAsB,EACtB,8BAA8B,CAC/B,CAAC;QACJ,CAAC;QACD,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,iBAAiB,CAC3C,IAAI,CAAC,WAAW,EAChB,OAAO,CAAC,MAAM,CAAC,YAAY,CAC5B,CAAC;YACF,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;YACxB,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,EAAE,CAAC;YACjC,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,QAAQ,CACpD,QAAQ,CAAC,YAAY,CACtB,CAAC;YACF,IACE,OAAO,YAAY,CAAC,KAAK,CAAC,KAAK,QAAQ;gBACvC,YAAY,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,EAAE,GAAG,IAAI,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,EAC1D,CAAC;gBACD,MAAM,IAAI,SAAS,CACjB,sBAAsB,EACtB,2DAA2D,EAC3D;oBACE,KAAK,EAAE,yBAAyB;oBAChC,MAAM,EAAE,wBAAwB;oBAChC,WAAW,EAAE,EAAE,WAAW,EAAE,KAAK,EAAE,kBAAkB,EAAE,cAAc,EAAE;iBACxE,CACF,CAAC;YACJ,CAAC;YACD,MAAM,YAAY,GAAG,MAAM;gBACzB,CAAC,CAAC;oBACE,GAAG,MAAM;oBACT,YAAY,EAAE,YAAY,CAAC,cAAc,CAAC;oBAC1C,eAAe,EAAE,YAAY,CAAC,iBAAiB,CAAC;iBACjD;gBACH,CAAC,CAAC,SAAS,CAAC;YACd,MAAM,SAAS,GAAkB;gBAC/B,GAAG,OAAO;gBACV,KAAK,EAAE,YAAY;oBACjB,CAAC,CAAC,eAAe,CAAC,YAAY,CAAC;oBAC/B,CAAC,CAAC;wBACE,GAAG,OAAO,CAAC,KAAK;wBAChB,UAAU,EAAE,eAAe,CAAC;4BAC1B,GAAG,EAAE,OAAO,CAAC,KAAK,CAAC,GAAG;4BACtB,YAAY,EAAE,YAAY,CAAC,cAAc,CAAC;yBAC3C,CAAC,CAAC,UAAU;wBACb,WAAW,EAAE,eAAe,CAAC;4BAC3B,GAAG,EAAE,OAAO,CAAC,KAAK,CAAC,GAAG;4BACtB,eAAe,EAAE,YAAY,CAAC,iBAAiB,CAAC;yBACjD,CAAC,CAAC,WAAW;qBACf;gBACL,MAAM,EAAE,YAAY,CAAC,QAAQ,EAAE,GAAG,EAAE,YAAY,EAAE,OAAO,CAAC,MAAM,CAAC;gBACjE,SAAS,EAAE,GAAG;aACf,CAAC;YACF,MAAM,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,SAAS,EAAE,IAAI,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC;YACpE,GAAG,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,uBAAuB,EAAE;gBACjD,kBAAkB,EAAE,OAAO,CAAC,SAAS,CAAC,KAAK,CAAC,UAAU,CAAC;aACxD,CAAC,CAAC;YACH,OAAO,SAAS,CAAC;QACnB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;YACvC,MAAM,KAAK,GAAG,KAAK,YAAY,SAAS;gBACtC,CAAC,CAAC,KAAK;gBACP,CAAC,CAAC,IAAI,SAAS,CAAC,sBAAsB,EAAE,2BAA2B,EAAE;oBACjE,KAAK;oBACL,KAAK,EAAE,eAAe;oBACtB,MAAM,EAAE,iBAAiB,CAAC,KAAK,CAAC,CAAC,MAAM;oBACvC,WAAW,EAAE,iBAAiB,CAAC,KAAK,CAAC,CAAC,OAAO;iBAC9C,CAAC,CAAC;YACP,GAAG,CACD,IAAI,CAAC,OAAO,EACZ,MAAM,EACN,iCAAiC,EACjC,gBAAgB,CAAC,KAAK,CAAC,CACxB,CAAC;YACF,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,SAAiB;QAC5B,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QACpD,MAAM,UAAU,GAA2B,EAAE,CAAC;QAC9C,IAAI,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC;YAC5B,UAAU,CAAC,eAAe,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC;QACvD,CAAC;QACD,IAAI,IAAI,CAAC,OAAO,CAAC,qBAAqB,EAAE,CAAC;YACvC,UAAU,CAAC,0BAA0B,CAAC;gBACpC,IAAI,CAAC,OAAO,CAAC,qBAAqB,CAAC,IAAI,CAAC;QAC5C,CAAC;QACD,MAAM,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QACvC,GAAG,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,uCAAuC,EAAE;YACjE,KAAK,EAAE,QAAQ;YACf,MAAM,EAAE,uBAAuB;YAC/B,UAAU,EAAE,OAAO,CAAC,OAAO,CAAC;SAC7B,CAAC,CAAC;QACH,IAAI,CAAC;YACH,MAAM,SAAS,GAAG,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC;YACxE,GAAG,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,kCAAkC,EAAE;gBAC5D,KAAK,EAAE,QAAQ;gBACf,MAAM,EAAE,kCAAkC;aAC3C,CAAC,CAAC;YACH,OAAO,SAAS,CAAC;QACnB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,KAAK,GAAG,IAAI,SAAS,CACzB,eAAe,EACf,2CAA2C,EAC3C;gBACE,KAAK;gBACL,KAAK,EAAE,QAAQ;gBACf,MAAM,EAAE,0BAA0B;aACnC,CACF,CAAC;YACF,GAAG,CACD,IAAI,CAAC,OAAO,EACZ,MAAM,EACN,0BAA0B,EAC1B,gBAAgB,CAAC,KAAK,CAAC,CACxB,CAAC;YACF,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;CACF;AAED,MAAM,UAAU,eAAe,CAAC,OAAsB;IACpD,OAAO;QACL,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC7E,CAAC;AACJ,CAAC"}
|
|
@@ -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
|