@xemahq/oidc-session-nest 0.1.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/LICENSE +176 -0
- package/README.md +101 -0
- package/dist/config/oidc-session-env.d.ts +6 -0
- package/dist/config/oidc-session-env.d.ts.map +1 -0
- package/dist/config/oidc-session-env.js +123 -0
- package/dist/config/oidc-session-env.js.map +1 -0
- package/dist/config/oidc-session-options.d.ts +33 -0
- package/dist/config/oidc-session-options.d.ts.map +1 -0
- package/dist/config/oidc-session-options.js +67 -0
- package/dist/config/oidc-session-options.js.map +1 -0
- package/dist/errors.d.ts +37 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +60 -0
- package/dist/errors.js.map +1 -0
- package/dist/http/cookie.d.ts +12 -0
- package/dist/http/cookie.d.ts.map +1 -0
- package/dist/http/cookie.js +82 -0
- package/dist/http/cookie.js.map +1 -0
- package/dist/http/headers.d.ts +2 -0
- package/dist/http/headers.d.ts.map +1 -0
- package/dist/http/headers.js +5 -0
- package/dist/http/headers.js.map +1 -0
- package/dist/index.d.ts +22 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +68 -0
- package/dist/index.js.map +1 -0
- package/dist/nest/oidc-session-auth.controller.d.ts +30 -0
- package/dist/nest/oidc-session-auth.controller.d.ts.map +1 -0
- package/dist/nest/oidc-session-auth.controller.js +182 -0
- package/dist/nest/oidc-session-auth.controller.js.map +1 -0
- package/dist/nest/oidc-session-context.d.ts +11 -0
- package/dist/nest/oidc-session-context.d.ts.map +1 -0
- package/dist/nest/oidc-session-context.js +37 -0
- package/dist/nest/oidc-session-context.js.map +1 -0
- package/dist/nest/oidc-session.guard.d.ts +5 -0
- package/dist/nest/oidc-session.guard.d.ts.map +1 -0
- package/dist/nest/oidc-session.guard.js +43 -0
- package/dist/nest/oidc-session.guard.js.map +1 -0
- package/dist/nest/oidc-session.middleware.d.ts +19 -0
- package/dist/nest/oidc-session.middleware.d.ts.map +1 -0
- package/dist/nest/oidc-session.middleware.js +57 -0
- package/dist/nest/oidc-session.middleware.js.map +1 -0
- package/dist/nest/oidc-session.module.d.ts +22 -0
- package/dist/nest/oidc-session.module.d.ts.map +1 -0
- package/dist/nest/oidc-session.module.js +100 -0
- package/dist/nest/oidc-session.module.js.map +1 -0
- package/dist/nest/session-actor.decorator.d.ts +2 -0
- package/dist/nest/session-actor.decorator.d.ts.map +1 -0
- package/dist/nest/session-actor.decorator.js +13 -0
- package/dist/nest/session-actor.decorator.js.map +1 -0
- package/dist/nest/session-client-transport.d.ts +6 -0
- package/dist/nest/session-client-transport.d.ts.map +1 -0
- package/dist/nest/session-client-transport.js +41 -0
- package/dist/nest/session-client-transport.js.map +1 -0
- package/dist/nest/tokens.d.ts +3 -0
- package/dist/nest/tokens.d.ts.map +1 -0
- package/dist/nest/tokens.js +6 -0
- package/dist/nest/tokens.js.map +1 -0
- package/dist/oidc/discovery.d.ts +30 -0
- package/dist/oidc/discovery.d.ts.map +1 -0
- package/dist/oidc/discovery.js +101 -0
- package/dist/oidc/discovery.js.map +1 -0
- package/dist/oidc/oidc-client.d.ts +44 -0
- package/dist/oidc/oidc-client.d.ts.map +1 -0
- package/dist/oidc/oidc-client.js +190 -0
- package/dist/oidc/oidc-client.js.map +1 -0
- package/dist/oidc/pkce.d.ts +8 -0
- package/dist/oidc/pkce.d.ts.map +1 -0
- package/dist/oidc/pkce.js +15 -0
- package/dist/oidc/pkce.js.map +1 -0
- package/dist/session/actor.d.ts +14 -0
- package/dist/session/actor.d.ts.map +1 -0
- package/dist/session/actor.js +32 -0
- package/dist/session/actor.js.map +1 -0
- package/dist/session/in-memory-session-store.d.ts +21 -0
- package/dist/session/in-memory-session-store.d.ts.map +1 -0
- package/dist/session/in-memory-session-store.js +79 -0
- package/dist/session/in-memory-session-store.js.map +1 -0
- package/dist/session/redis-session-store.d.ts +28 -0
- package/dist/session/redis-session-store.d.ts.map +1 -0
- package/dist/session/redis-session-store.js +121 -0
- package/dist/session/redis-session-store.js.map +1 -0
- package/dist/session/session-service.d.ts +55 -0
- package/dist/session/session-service.d.ts.map +1 -0
- package/dist/session/session-service.js +224 -0
- package/dist/session/session-service.js.map +1 -0
- package/dist/session/session-store.d.ts +35 -0
- package/dist/session/session-store.d.ts.map +1 -0
- package/dist/session/session-store.js +3 -0
- package/dist/session/session-store.js.map +1 -0
- package/package.json +63 -0
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.OidcClient = exports.OidcInvalidGrantError = void 0;
|
|
4
|
+
const errors_1 = require("../errors");
|
|
5
|
+
class OidcInvalidGrantError extends Error {
|
|
6
|
+
constructor(message) {
|
|
7
|
+
super(message);
|
|
8
|
+
this.name = 'OidcInvalidGrantError';
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
exports.OidcInvalidGrantError = OidcInvalidGrantError;
|
|
12
|
+
const DEFAULT_EXPIRES_IN_SECONDS = 300;
|
|
13
|
+
class OidcClient {
|
|
14
|
+
options;
|
|
15
|
+
discovery;
|
|
16
|
+
verifier;
|
|
17
|
+
fetchImpl;
|
|
18
|
+
jwksCacheKey;
|
|
19
|
+
constructor(deps) {
|
|
20
|
+
this.options = deps.options;
|
|
21
|
+
this.discovery = deps.discovery;
|
|
22
|
+
this.verifier = deps.verifier;
|
|
23
|
+
this.fetchImpl = deps.fetchImpl;
|
|
24
|
+
this.jwksCacheKey = `oidc-session-nest:${deps.options.issuerUrl}`;
|
|
25
|
+
}
|
|
26
|
+
async buildAuthorizationUrl(request) {
|
|
27
|
+
const document = await this.discovery.resolve();
|
|
28
|
+
const url = new URL(document.authorizationEndpoint);
|
|
29
|
+
url.searchParams.set('response_type', 'code');
|
|
30
|
+
url.searchParams.set('client_id', this.options.clientId);
|
|
31
|
+
url.searchParams.set('redirect_uri', this.options.redirectUri);
|
|
32
|
+
url.searchParams.set('scope', this.options.scope);
|
|
33
|
+
url.searchParams.set('state', request.state);
|
|
34
|
+
url.searchParams.set('nonce', request.nonce);
|
|
35
|
+
url.searchParams.set('code_challenge', request.codeChallenge);
|
|
36
|
+
url.searchParams.set('code_challenge_method', 'S256');
|
|
37
|
+
return url.toString();
|
|
38
|
+
}
|
|
39
|
+
async exchangeCode(input) {
|
|
40
|
+
const body = new URLSearchParams({
|
|
41
|
+
grant_type: 'authorization_code',
|
|
42
|
+
code: input.code,
|
|
43
|
+
redirect_uri: this.options.redirectUri,
|
|
44
|
+
client_id: this.options.clientId,
|
|
45
|
+
code_verifier: input.codeVerifier,
|
|
46
|
+
});
|
|
47
|
+
const response = await this.postToTokenEndpoint(body);
|
|
48
|
+
return this.toTokenSet(response, input.nonce);
|
|
49
|
+
}
|
|
50
|
+
async refresh(refreshToken) {
|
|
51
|
+
const body = new URLSearchParams({
|
|
52
|
+
grant_type: 'refresh_token',
|
|
53
|
+
refresh_token: refreshToken,
|
|
54
|
+
client_id: this.options.clientId,
|
|
55
|
+
});
|
|
56
|
+
const response = await this.postToTokenEndpoint(body);
|
|
57
|
+
return this.toTokenSet(response, undefined);
|
|
58
|
+
}
|
|
59
|
+
async buildEndSessionUrl(idToken) {
|
|
60
|
+
const document = await this.discovery.resolve();
|
|
61
|
+
if (document.endSessionEndpoint === undefined) {
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
64
|
+
const url = new URL(document.endSessionEndpoint);
|
|
65
|
+
url.searchParams.set('client_id', this.options.clientId);
|
|
66
|
+
if (idToken !== undefined) {
|
|
67
|
+
url.searchParams.set('id_token_hint', idToken);
|
|
68
|
+
}
|
|
69
|
+
if (this.options.postLogoutRedirectUri !== undefined) {
|
|
70
|
+
url.searchParams.set('post_logout_redirect_uri', this.options.postLogoutRedirectUri);
|
|
71
|
+
}
|
|
72
|
+
return url.toString();
|
|
73
|
+
}
|
|
74
|
+
async postToTokenEndpoint(body) {
|
|
75
|
+
const document = await this.discovery.resolve();
|
|
76
|
+
const headers = {
|
|
77
|
+
'content-type': 'application/x-www-form-urlencoded',
|
|
78
|
+
accept: 'application/json',
|
|
79
|
+
};
|
|
80
|
+
if (this.options.clientSecret !== undefined) {
|
|
81
|
+
const credentials = Buffer.from(`${encodeURIComponent(this.options.clientId)}:${encodeURIComponent(this.options.clientSecret)}`, 'utf8').toString('base64');
|
|
82
|
+
headers.authorization = `Basic ${credentials}`;
|
|
83
|
+
}
|
|
84
|
+
let ok;
|
|
85
|
+
let status;
|
|
86
|
+
let text;
|
|
87
|
+
try {
|
|
88
|
+
const response = await this.fetchImpl(document.tokenEndpoint, {
|
|
89
|
+
method: 'POST',
|
|
90
|
+
headers,
|
|
91
|
+
body: body.toString(),
|
|
92
|
+
});
|
|
93
|
+
ok = response.ok;
|
|
94
|
+
status = response.status;
|
|
95
|
+
text = await response.text();
|
|
96
|
+
}
|
|
97
|
+
catch (error) {
|
|
98
|
+
throw new errors_1.OidcTokenEndpointFailedError(`The token endpoint at ${document.tokenEndpoint} could not be reached: ` +
|
|
99
|
+
`${error instanceof Error ? error.message : String(error)}`);
|
|
100
|
+
}
|
|
101
|
+
let parsed;
|
|
102
|
+
try {
|
|
103
|
+
parsed = JSON.parse(text);
|
|
104
|
+
}
|
|
105
|
+
catch {
|
|
106
|
+
throw new errors_1.OidcTokenEndpointFailedError(`The token endpoint at ${document.tokenEndpoint} answered HTTP ${status} ` +
|
|
107
|
+
'with a body that is not JSON.');
|
|
108
|
+
}
|
|
109
|
+
if (parsed === null || typeof parsed !== 'object') {
|
|
110
|
+
throw new errors_1.OidcTokenEndpointFailedError(`The token endpoint at ${document.tokenEndpoint} answered HTTP ${status} ` +
|
|
111
|
+
'with a body that is not a JSON object.');
|
|
112
|
+
}
|
|
113
|
+
const payload = parsed;
|
|
114
|
+
if (!ok) {
|
|
115
|
+
const code = typeof payload.error === 'string' ? payload.error : 'unknown_error';
|
|
116
|
+
const description = typeof payload.error_description === 'string'
|
|
117
|
+
? `: ${payload.error_description}`
|
|
118
|
+
: '';
|
|
119
|
+
if (code === 'invalid_grant') {
|
|
120
|
+
throw new OidcInvalidGrantError(`The identity provider rejected the grant (invalid_grant${description}).`);
|
|
121
|
+
}
|
|
122
|
+
throw new errors_1.OidcTokenEndpointFailedError(`The token endpoint answered HTTP ${status} (${code}${description}).`);
|
|
123
|
+
}
|
|
124
|
+
return payload;
|
|
125
|
+
}
|
|
126
|
+
async toTokenSet(payload, expectedNonce) {
|
|
127
|
+
const accessToken = payload.access_token;
|
|
128
|
+
if (typeof accessToken !== 'string' || accessToken === '') {
|
|
129
|
+
throw new errors_1.OidcTokenEndpointFailedError('The token endpoint returned no access_token.');
|
|
130
|
+
}
|
|
131
|
+
const document = await this.discovery.resolve();
|
|
132
|
+
let accessClaims;
|
|
133
|
+
try {
|
|
134
|
+
accessClaims = await this.verifier.verify(accessToken, {
|
|
135
|
+
jwksUrl: document.jwksUri,
|
|
136
|
+
cacheKey: this.jwksCacheKey,
|
|
137
|
+
expectedIssuers: [document.issuer],
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
catch (error) {
|
|
141
|
+
throw new errors_1.OidcCallbackRejectedError(`The access token did not verify: ${error instanceof Error ? error.message : String(error)}`);
|
|
142
|
+
}
|
|
143
|
+
const rawIdToken = payload.id_token;
|
|
144
|
+
let idClaims;
|
|
145
|
+
if (typeof rawIdToken === 'string' && rawIdToken !== '') {
|
|
146
|
+
try {
|
|
147
|
+
idClaims = await this.verifier.verify(rawIdToken, {
|
|
148
|
+
jwksUrl: document.jwksUri,
|
|
149
|
+
cacheKey: this.jwksCacheKey,
|
|
150
|
+
expectedIssuers: [document.issuer],
|
|
151
|
+
expectedAudiences: [this.options.clientId],
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
catch (error) {
|
|
155
|
+
throw new errors_1.OidcCallbackRejectedError(`The id token did not verify: ${error instanceof Error ? error.message : String(error)}`);
|
|
156
|
+
}
|
|
157
|
+
if (expectedNonce !== undefined && idClaims.nonce !== expectedNonce) {
|
|
158
|
+
throw new errors_1.OidcCallbackRejectedError('The id token nonce does not match this sign-in attempt. Refusing: a ' +
|
|
159
|
+
'valid token from a different attempt would otherwise be accepted.');
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
const expiresAt = resolveExpiry(payload, accessClaims);
|
|
163
|
+
const refreshToken = payload.refresh_token;
|
|
164
|
+
const tokenSet = {
|
|
165
|
+
accessToken,
|
|
166
|
+
...(typeof refreshToken === 'string' && refreshToken !== ''
|
|
167
|
+
? { refreshToken }
|
|
168
|
+
: {}),
|
|
169
|
+
...(typeof rawIdToken === 'string' && rawIdToken !== ''
|
|
170
|
+
? { idToken: rawIdToken }
|
|
171
|
+
: {}),
|
|
172
|
+
accessTokenExpiresAt: expiresAt,
|
|
173
|
+
accessClaims,
|
|
174
|
+
...(idClaims === undefined ? {} : { idClaims }),
|
|
175
|
+
};
|
|
176
|
+
return tokenSet;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
exports.OidcClient = OidcClient;
|
|
180
|
+
function resolveExpiry(payload, claims) {
|
|
181
|
+
if (typeof claims.exp === 'number' && Number.isFinite(claims.exp)) {
|
|
182
|
+
return claims.exp * 1000;
|
|
183
|
+
}
|
|
184
|
+
const expiresIn = payload.expires_in;
|
|
185
|
+
const seconds = typeof expiresIn === 'number' && Number.isFinite(expiresIn) && expiresIn > 0
|
|
186
|
+
? expiresIn
|
|
187
|
+
: DEFAULT_EXPIRES_IN_SECONDS;
|
|
188
|
+
return Date.now() + seconds * 1000;
|
|
189
|
+
}
|
|
190
|
+
//# sourceMappingURL=oidc-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oidc-client.js","sourceRoot":"","sources":["../../src/oidc/oidc-client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export interface PkcePair {
|
|
2
|
+
readonly verifier: string;
|
|
3
|
+
readonly challenge: string;
|
|
4
|
+
readonly method: 'S256';
|
|
5
|
+
}
|
|
6
|
+
export declare function randomUrlSafeToken(bytes?: number): string;
|
|
7
|
+
export declare function createPkcePair(): PkcePair;
|
|
8
|
+
//# sourceMappingURL=pkce.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pkce.d.ts","sourceRoot":"","sources":["../../src/oidc/pkce.ts"],"names":[],"mappings":"AAUA,MAAM,WAAW,QAAQ;IAEvB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAE1B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAE3B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAYD,wBAAgB,kBAAkB,CAAC,KAAK,GAAE,MAAoB,GAAG,MAAM,CAEtE;AAGD,wBAAgB,cAAc,IAAI,QAAQ,CAIzC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.randomUrlSafeToken = randomUrlSafeToken;
|
|
4
|
+
exports.createPkcePair = createPkcePair;
|
|
5
|
+
const node_crypto_1 = require("node:crypto");
|
|
6
|
+
const TOKEN_BYTES = 32;
|
|
7
|
+
function randomUrlSafeToken(bytes = TOKEN_BYTES) {
|
|
8
|
+
return (0, node_crypto_1.randomBytes)(bytes).toString('base64url');
|
|
9
|
+
}
|
|
10
|
+
function createPkcePair() {
|
|
11
|
+
const verifier = randomUrlSafeToken();
|
|
12
|
+
const challenge = (0, node_crypto_1.createHash)('sha256').update(verifier).digest('base64url');
|
|
13
|
+
return { verifier, challenge, method: 'S256' };
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=pkce.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pkce.js","sourceRoot":"","sources":["../../src/oidc/pkce.ts"],"names":[],"mappings":";;AA6BA,gDAEC;AAGD,wCAIC;AA/BD,6CAAsD;AAatD,MAAM,WAAW,GAAG,EAAE,CAAC;AASvB,SAAgB,kBAAkB,CAAC,QAAgB,WAAW;IAC5D,OAAO,IAAA,yBAAW,EAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;AAClD,CAAC;AAGD,SAAgB,cAAc;IAC5B,MAAM,QAAQ,GAAG,kBAAkB,EAAE,CAAC;IACtC,MAAM,SAAS,GAAG,IAAA,wBAAU,EAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;IAC5E,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;AACjD,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { type OrgRole } from '@xemahq/platform-common';
|
|
2
|
+
import type { SessionRecord } from './session-store';
|
|
3
|
+
export interface SessionActor {
|
|
4
|
+
readonly subjectId: string;
|
|
5
|
+
readonly activeOrgId: string | null;
|
|
6
|
+
readonly orgRoles: Readonly<Record<string, OrgRole>>;
|
|
7
|
+
readonly expiresAt: number;
|
|
8
|
+
readonly accessTokenExpiresAt: number;
|
|
9
|
+
readonly claims: Readonly<Record<string, unknown>>;
|
|
10
|
+
}
|
|
11
|
+
export declare function resolveInitialActiveOrgId(claims: Readonly<Record<string, unknown>>): string | null;
|
|
12
|
+
export declare function resolveSessionOrgRoles(claims: Readonly<Record<string, unknown>>): Record<string, OrgRole>;
|
|
13
|
+
export declare function toSessionActor(record: SessionRecord): SessionActor;
|
|
14
|
+
//# sourceMappingURL=actor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"actor.d.ts","sourceRoot":"","sources":["../../src/session/actor.ts"],"names":[],"mappings":"AAUA,OAAO,EAGL,KAAK,OAAO,EACb,MAAM,yBAAyB,CAAC;AAEjC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAGrD,MAAM,WAAW,YAAY;IAE3B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAQ3B,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAEpC,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IAErD,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAE3B,QAAQ,CAAC,oBAAoB,EAAE,MAAM,CAAC;IAEtC,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;CACpD;AAiBD,wBAAgB,yBAAyB,CACvC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GACxC,MAAM,GAAG,IAAI,CAgBf;AAGD,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GACxC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAEzB;AAGD,wBAAgB,cAAc,CAAC,MAAM,EAAE,aAAa,GAAG,YAAY,CASlE"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.resolveInitialActiveOrgId = resolveInitialActiveOrgId;
|
|
4
|
+
exports.resolveSessionOrgRoles = resolveSessionOrgRoles;
|
|
5
|
+
exports.toSessionActor = toSessionActor;
|
|
6
|
+
const platform_common_1 = require("@xemahq/platform-common");
|
|
7
|
+
function resolveInitialActiveOrgId(claims) {
|
|
8
|
+
const declared = (0, platform_common_1.resolveOrgClaim)(claims);
|
|
9
|
+
if (declared !== null) {
|
|
10
|
+
return declared.value;
|
|
11
|
+
}
|
|
12
|
+
const roles = (0, platform_common_1.resolveOrgRoles)(claims);
|
|
13
|
+
const orgIds = Object.keys(roles);
|
|
14
|
+
if (orgIds.length === 1) {
|
|
15
|
+
return orgIds[0] ?? null;
|
|
16
|
+
}
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
19
|
+
function resolveSessionOrgRoles(claims) {
|
|
20
|
+
return (0, platform_common_1.resolveOrgRoles)(claims);
|
|
21
|
+
}
|
|
22
|
+
function toSessionActor(record) {
|
|
23
|
+
return {
|
|
24
|
+
subjectId: record.subjectId,
|
|
25
|
+
activeOrgId: record.activeOrgId,
|
|
26
|
+
orgRoles: record.orgRoles,
|
|
27
|
+
expiresAt: record.absoluteExpiresAt,
|
|
28
|
+
accessTokenExpiresAt: record.accessTokenExpiresAt,
|
|
29
|
+
claims: record.claims,
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=actor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"actor.js","sourceRoot":"","sources":["../../src/session/actor.ts"],"names":[],"mappings":";;AAuDA,8DAkBC;AAGD,wDAIC;AAGD,wCASC;AAlFD,6DAIiC;AAyCjC,SAAgB,yBAAyB,CACvC,MAAyC;IAOzC,MAAM,QAAQ,GAAG,IAAA,iCAAe,EAAC,MAAM,CAAC,CAAC;IACzC,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;QACtB,OAAO,QAAQ,CAAC,KAAK,CAAC;IACxB,CAAC;IACD,MAAM,KAAK,GAAG,IAAA,iCAAe,EAAC,MAAM,CAAC,CAAC;IACtC,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAClC,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxB,OAAO,MAAM,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC;IAC3B,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAGD,SAAgB,sBAAsB,CACpC,MAAyC;IAEzC,OAAO,IAAA,iCAAe,EAAC,MAAM,CAAC,CAAC;AACjC,CAAC;AAGD,SAAgB,cAAc,CAAC,MAAqB;IAClD,OAAO;QACL,SAAS,EAAE,MAAM,CAAC,SAAS;QAC3B,WAAW,EAAE,MAAM,CAAC,WAAW;QAC/B,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,SAAS,EAAE,MAAM,CAAC,iBAAiB;QACnC,oBAAoB,EAAE,MAAM,CAAC,oBAAoB;QACjD,MAAM,EAAE,MAAM,CAAC,MAAM;KACtB,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { PendingAuthorization, ReadSessionOptions, SessionRecord, SessionStore } from './session-store';
|
|
2
|
+
export interface InMemorySessionStoreOptions {
|
|
3
|
+
readonly now?: () => number;
|
|
4
|
+
}
|
|
5
|
+
export declare class InMemorySessionStore implements SessionStore {
|
|
6
|
+
private readonly sessions;
|
|
7
|
+
private readonly leases;
|
|
8
|
+
private readonly pending;
|
|
9
|
+
private readonly now;
|
|
10
|
+
constructor(options?: InMemorySessionStoreOptions);
|
|
11
|
+
createSession(key: string, record: SessionRecord, ttlMs: number): Promise<boolean>;
|
|
12
|
+
readSession(key: string, options: ReadSessionOptions): Promise<SessionRecord | null>;
|
|
13
|
+
replaceSession(key: string, expectedVersion: number, record: SessionRecord, ttlMs: number): Promise<boolean>;
|
|
14
|
+
deleteSession(key: string): Promise<void>;
|
|
15
|
+
acquireRefreshLease(key: string, ttlMs: number): Promise<boolean>;
|
|
16
|
+
releaseRefreshLease(key: string): Promise<void>;
|
|
17
|
+
putPendingAuthorization(state: string, pending: PendingAuthorization, ttlMs: number): Promise<void>;
|
|
18
|
+
takePendingAuthorization(state: string): Promise<PendingAuthorization | null>;
|
|
19
|
+
private live;
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=in-memory-session-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"in-memory-session-store.d.ts","sourceRoot":"","sources":["../../src/session/in-memory-session-store.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EACV,oBAAoB,EACpB,kBAAkB,EAClB,aAAa,EACb,YAAY,EACb,MAAM,iBAAiB,CAAC;AAOzB,MAAM,WAAW,2BAA2B;IAE1C,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;CAC7B;AAED,qBAAa,oBAAqB,YAAW,YAAY;IACvD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA2C;IAEpE,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAkC;IAEzD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAkD;IAE1E,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAe;gBAEvB,OAAO,GAAE,2BAAgC;IAIrD,aAAa,CACX,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,aAAa,EACrB,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,OAAO,CAAC;IAQnB,WAAW,CACT,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,kBAAkB,GAC1B,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC;IAiBhC,cAAc,CACZ,GAAG,EAAE,MAAM,EACX,eAAe,EAAE,MAAM,EACvB,MAAM,EAAE,aAAa,EACrB,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,OAAO,CAAC;IAYnB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAKzC,mBAAmB,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAQjE,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAK/C,uBAAuB,CACrB,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,oBAAoB,EAC7B,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,IAAI,CAAC;IAKhB,wBAAwB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC;IAM7E,OAAO,CAAC,IAAI;CAWb"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.InMemorySessionStore = void 0;
|
|
4
|
+
class InMemorySessionStore {
|
|
5
|
+
sessions = new Map();
|
|
6
|
+
leases = new Map();
|
|
7
|
+
pending = new Map();
|
|
8
|
+
now;
|
|
9
|
+
constructor(options = {}) {
|
|
10
|
+
this.now = options.now ?? (() => Date.now());
|
|
11
|
+
}
|
|
12
|
+
createSession(key, record, ttlMs) {
|
|
13
|
+
if (this.live(this.sessions, key) !== null) {
|
|
14
|
+
return Promise.resolve(false);
|
|
15
|
+
}
|
|
16
|
+
this.sessions.set(key, { value: record, expiresAt: this.now() + ttlMs });
|
|
17
|
+
return Promise.resolve(true);
|
|
18
|
+
}
|
|
19
|
+
readSession(key, options) {
|
|
20
|
+
const entry = this.live(this.sessions, key);
|
|
21
|
+
if (entry === null) {
|
|
22
|
+
return Promise.resolve(null);
|
|
23
|
+
}
|
|
24
|
+
if (options.now >= entry.value.absoluteExpiresAt) {
|
|
25
|
+
this.sessions.delete(key);
|
|
26
|
+
return Promise.resolve(null);
|
|
27
|
+
}
|
|
28
|
+
entry.expiresAt = Math.min(options.now + options.idleTtlMs, entry.value.absoluteExpiresAt);
|
|
29
|
+
return Promise.resolve(entry.value);
|
|
30
|
+
}
|
|
31
|
+
replaceSession(key, expectedVersion, record, ttlMs) {
|
|
32
|
+
const entry = this.live(this.sessions, key);
|
|
33
|
+
if (entry === null || entry.value.version !== expectedVersion) {
|
|
34
|
+
return Promise.resolve(false);
|
|
35
|
+
}
|
|
36
|
+
this.sessions.set(key, {
|
|
37
|
+
value: record,
|
|
38
|
+
expiresAt: Math.min(this.now() + ttlMs, record.absoluteExpiresAt),
|
|
39
|
+
});
|
|
40
|
+
return Promise.resolve(true);
|
|
41
|
+
}
|
|
42
|
+
deleteSession(key) {
|
|
43
|
+
this.sessions.delete(key);
|
|
44
|
+
return Promise.resolve();
|
|
45
|
+
}
|
|
46
|
+
acquireRefreshLease(key, ttlMs) {
|
|
47
|
+
if (this.live(this.leases, key) !== null) {
|
|
48
|
+
return Promise.resolve(false);
|
|
49
|
+
}
|
|
50
|
+
this.leases.set(key, { value: true, expiresAt: this.now() + ttlMs });
|
|
51
|
+
return Promise.resolve(true);
|
|
52
|
+
}
|
|
53
|
+
releaseRefreshLease(key) {
|
|
54
|
+
this.leases.delete(key);
|
|
55
|
+
return Promise.resolve();
|
|
56
|
+
}
|
|
57
|
+
putPendingAuthorization(state, pending, ttlMs) {
|
|
58
|
+
this.pending.set(state, { value: pending, expiresAt: this.now() + ttlMs });
|
|
59
|
+
return Promise.resolve();
|
|
60
|
+
}
|
|
61
|
+
takePendingAuthorization(state) {
|
|
62
|
+
const entry = this.live(this.pending, state);
|
|
63
|
+
this.pending.delete(state);
|
|
64
|
+
return Promise.resolve(entry === null ? null : entry.value);
|
|
65
|
+
}
|
|
66
|
+
live(map, key) {
|
|
67
|
+
const entry = map.get(key);
|
|
68
|
+
if (entry === undefined) {
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
if (this.now() >= entry.expiresAt) {
|
|
72
|
+
map.delete(key);
|
|
73
|
+
return null;
|
|
74
|
+
}
|
|
75
|
+
return entry;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
exports.InMemorySessionStore = InMemorySessionStore;
|
|
79
|
+
//# sourceMappingURL=in-memory-session-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"in-memory-session-store.js","sourceRoot":"","sources":["../../src/session/in-memory-session-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { PendingAuthorization, ReadSessionOptions, SessionRecord, SessionStore } from './session-store';
|
|
2
|
+
export interface RedisScriptClient {
|
|
3
|
+
eval(script: string, keys: readonly string[], args?: readonly (string | number)[]): Promise<unknown>;
|
|
4
|
+
}
|
|
5
|
+
export interface IoredisLike {
|
|
6
|
+
eval(...args: unknown[]): Promise<unknown>;
|
|
7
|
+
}
|
|
8
|
+
export declare function ioredisScriptClient(client: IoredisLike): RedisScriptClient;
|
|
9
|
+
export interface RedisSessionStoreOptions {
|
|
10
|
+
readonly keyPrefix: string;
|
|
11
|
+
}
|
|
12
|
+
export declare class RedisSessionStore implements SessionStore {
|
|
13
|
+
private readonly client;
|
|
14
|
+
private readonly options;
|
|
15
|
+
constructor(client: RedisScriptClient, options: RedisSessionStoreOptions);
|
|
16
|
+
createSession(key: string, record: SessionRecord, ttlMs: number): Promise<boolean>;
|
|
17
|
+
readSession(key: string, options: ReadSessionOptions): Promise<SessionRecord | null>;
|
|
18
|
+
replaceSession(key: string, expectedVersion: number, record: SessionRecord, ttlMs: number): Promise<boolean>;
|
|
19
|
+
deleteSession(key: string): Promise<void>;
|
|
20
|
+
acquireRefreshLease(key: string, ttlMs: number): Promise<boolean>;
|
|
21
|
+
releaseRefreshLease(key: string): Promise<void>;
|
|
22
|
+
putPendingAuthorization(state: string, pending: PendingAuthorization, ttlMs: number): Promise<void>;
|
|
23
|
+
takePendingAuthorization(state: string): Promise<PendingAuthorization | null>;
|
|
24
|
+
private sessionKey;
|
|
25
|
+
private leaseKey;
|
|
26
|
+
private pendingKey;
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=redis-session-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"redis-session-store.d.ts","sourceRoot":"","sources":["../../src/session/redis-session-store.ts"],"names":[],"mappings":"AAqBA,OAAO,KAAK,EACV,oBAAoB,EACpB,kBAAkB,EAClB,aAAa,EACb,YAAY,EACb,MAAM,iBAAiB,CAAC;AAQzB,MAAM,WAAW,iBAAiB;IAChC,IAAI,CACF,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,IAAI,CAAC,EAAE,SAAS,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,GAClC,OAAO,CAAC,OAAO,CAAC,CAAC;CACrB;AAGD,MAAM,WAAW,WAAW;IAC1B,IAAI,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CAC5C;AAQD,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,WAAW,GAAG,iBAAiB,CAK1E;AA0DD,MAAM,WAAW,wBAAwB;IAEvC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B;AAED,qBAAa,iBAAkB,YAAW,YAAY;IAElD,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,OAAO;gBADP,MAAM,EAAE,iBAAiB,EACzB,OAAO,EAAE,wBAAwB;IAG9C,aAAa,CACjB,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,aAAa,EACrB,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,OAAO,CAAC;IASb,WAAW,CACf,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,kBAAkB,GAC1B,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC;IAS1B,cAAc,CAClB,GAAG,EAAE,MAAM,EACX,eAAe,EAAE,MAAM,EACvB,MAAM,EAAE,aAAa,EACrB,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,OAAO,CAAC;IAeb,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAMzC,mBAAmB,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IASjE,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAM/C,uBAAuB,CAC3B,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,oBAAoB,EAC7B,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,IAAI,CAAC;IAQV,wBAAwB,CAC5B,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC;IAUvC,OAAO,CAAC,UAAU;IAIlB,OAAO,CAAC,QAAQ;IAIhB,OAAO,CAAC,UAAU;CAGnB"}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.RedisSessionStore = void 0;
|
|
4
|
+
exports.ioredisScriptClient = ioredisScriptClient;
|
|
5
|
+
function ioredisScriptClient(client) {
|
|
6
|
+
return {
|
|
7
|
+
eval: (script, keys, args = []) => client.eval(script, keys.length, ...keys, ...args),
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
const CREATE_SESSION = `
|
|
11
|
+
if redis.call('SET', KEYS[1], ARGV[1], 'PX', tonumber(ARGV[2]), 'NX') then
|
|
12
|
+
return 1
|
|
13
|
+
end
|
|
14
|
+
return 0
|
|
15
|
+
`;
|
|
16
|
+
const READ_SESSION = `
|
|
17
|
+
local raw = redis.call('GET', KEYS[1])
|
|
18
|
+
if not raw then return nil end
|
|
19
|
+
local record = cjson.decode(raw)
|
|
20
|
+
local now = tonumber(ARGV[1])
|
|
21
|
+
local idle = tonumber(ARGV[2])
|
|
22
|
+
if now >= record.absoluteExpiresAt then
|
|
23
|
+
redis.call('DEL', KEYS[1])
|
|
24
|
+
return nil
|
|
25
|
+
end
|
|
26
|
+
local remaining = record.absoluteExpiresAt - now
|
|
27
|
+
local ttl = idle
|
|
28
|
+
if remaining < ttl then ttl = remaining end
|
|
29
|
+
if ttl > 0 then redis.call('PEXPIRE', KEYS[1], ttl) end
|
|
30
|
+
return raw
|
|
31
|
+
`;
|
|
32
|
+
const REPLACE_SESSION = `
|
|
33
|
+
local raw = redis.call('GET', KEYS[1])
|
|
34
|
+
if not raw then return 0 end
|
|
35
|
+
local record = cjson.decode(raw)
|
|
36
|
+
if tonumber(record.version) ~= tonumber(ARGV[1]) then return 0 end
|
|
37
|
+
local ttl = tonumber(ARGV[3])
|
|
38
|
+
local cap = tonumber(ARGV[4]) - tonumber(ARGV[5])
|
|
39
|
+
if cap < ttl then ttl = cap end
|
|
40
|
+
if ttl <= 0 then
|
|
41
|
+
redis.call('DEL', KEYS[1])
|
|
42
|
+
return 0
|
|
43
|
+
end
|
|
44
|
+
redis.call('SET', KEYS[1], ARGV[2], 'PX', ttl)
|
|
45
|
+
return 1
|
|
46
|
+
`;
|
|
47
|
+
const TAKE_PENDING = `
|
|
48
|
+
local raw = redis.call('GET', KEYS[1])
|
|
49
|
+
if not raw then return nil end
|
|
50
|
+
redis.call('DEL', KEYS[1])
|
|
51
|
+
return raw
|
|
52
|
+
`;
|
|
53
|
+
class RedisSessionStore {
|
|
54
|
+
client;
|
|
55
|
+
options;
|
|
56
|
+
constructor(client, options) {
|
|
57
|
+
this.client = client;
|
|
58
|
+
this.options = options;
|
|
59
|
+
}
|
|
60
|
+
async createSession(key, record, ttlMs) {
|
|
61
|
+
const result = await this.client.eval(CREATE_SESSION, [this.sessionKey(key)], [JSON.stringify(record), Math.max(1, Math.floor(ttlMs))]);
|
|
62
|
+
return result === 1;
|
|
63
|
+
}
|
|
64
|
+
async readSession(key, options) {
|
|
65
|
+
const result = await this.client.eval(READ_SESSION, [this.sessionKey(key)], [Math.floor(options.now), Math.max(1, Math.floor(options.idleTtlMs))]);
|
|
66
|
+
return decodeRecord(result);
|
|
67
|
+
}
|
|
68
|
+
async replaceSession(key, expectedVersion, record, ttlMs) {
|
|
69
|
+
const result = await this.client.eval(REPLACE_SESSION, [this.sessionKey(key)], [
|
|
70
|
+
expectedVersion,
|
|
71
|
+
JSON.stringify(record),
|
|
72
|
+
Math.max(1, Math.floor(ttlMs)),
|
|
73
|
+
Math.floor(record.absoluteExpiresAt),
|
|
74
|
+
Math.floor(Date.now()),
|
|
75
|
+
]);
|
|
76
|
+
return result === 1;
|
|
77
|
+
}
|
|
78
|
+
async deleteSession(key) {
|
|
79
|
+
await this.client.eval(`redis.call('DEL', KEYS[1]) return 1`, [
|
|
80
|
+
this.sessionKey(key),
|
|
81
|
+
]);
|
|
82
|
+
}
|
|
83
|
+
async acquireRefreshLease(key, ttlMs) {
|
|
84
|
+
const result = await this.client.eval(CREATE_SESSION, [this.leaseKey(key)], ['1', Math.max(1, Math.floor(ttlMs))]);
|
|
85
|
+
return result === 1;
|
|
86
|
+
}
|
|
87
|
+
async releaseRefreshLease(key) {
|
|
88
|
+
await this.client.eval(`redis.call('DEL', KEYS[1]) return 1`, [
|
|
89
|
+
this.leaseKey(key),
|
|
90
|
+
]);
|
|
91
|
+
}
|
|
92
|
+
async putPendingAuthorization(state, pending, ttlMs) {
|
|
93
|
+
await this.client.eval(`redis.call('SET', KEYS[1], ARGV[1], 'PX', tonumber(ARGV[2])) return 1`, [this.pendingKey(state)], [JSON.stringify(pending), Math.max(1, Math.floor(ttlMs))]);
|
|
94
|
+
}
|
|
95
|
+
async takePendingAuthorization(state) {
|
|
96
|
+
const result = await this.client.eval(TAKE_PENDING, [
|
|
97
|
+
this.pendingKey(state),
|
|
98
|
+
]);
|
|
99
|
+
if (typeof result !== 'string') {
|
|
100
|
+
return null;
|
|
101
|
+
}
|
|
102
|
+
return JSON.parse(result);
|
|
103
|
+
}
|
|
104
|
+
sessionKey(key) {
|
|
105
|
+
return `${this.options.keyPrefix}:session:${key}`;
|
|
106
|
+
}
|
|
107
|
+
leaseKey(key) {
|
|
108
|
+
return `${this.options.keyPrefix}:refresh-lease:${key}`;
|
|
109
|
+
}
|
|
110
|
+
pendingKey(state) {
|
|
111
|
+
return `${this.options.keyPrefix}:pending:${state}`;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
exports.RedisSessionStore = RedisSessionStore;
|
|
115
|
+
function decodeRecord(result) {
|
|
116
|
+
if (typeof result !== 'string') {
|
|
117
|
+
return null;
|
|
118
|
+
}
|
|
119
|
+
return JSON.parse(result);
|
|
120
|
+
}
|
|
121
|
+
//# sourceMappingURL=redis-session-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"redis-session-store.js","sourceRoot":"","sources":["../../src/session/redis-session-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { type SessionActor } from './actor';
|
|
2
|
+
import { type OidcClient, type OidcTokenSet } from '../oidc/oidc-client';
|
|
3
|
+
import type { PendingAuthorization, SessionRecord, SessionStore } from './session-store';
|
|
4
|
+
import type { OidcSessionOptions } from '../config/oidc-session-options';
|
|
5
|
+
export interface ResolvedSession {
|
|
6
|
+
readonly session: LiveSession | null;
|
|
7
|
+
readonly expired: boolean;
|
|
8
|
+
}
|
|
9
|
+
export interface LiveSession {
|
|
10
|
+
readonly key: string;
|
|
11
|
+
readonly record: SessionRecord;
|
|
12
|
+
readonly actor: SessionActor;
|
|
13
|
+
}
|
|
14
|
+
export interface EstablishedSession {
|
|
15
|
+
readonly cookieValue: string;
|
|
16
|
+
readonly actor: SessionActor;
|
|
17
|
+
readonly returnTo: string | null;
|
|
18
|
+
}
|
|
19
|
+
export interface SessionServiceDeps {
|
|
20
|
+
readonly options: OidcSessionOptions;
|
|
21
|
+
readonly store: SessionStore;
|
|
22
|
+
readonly client: OidcClient;
|
|
23
|
+
readonly now?: () => number;
|
|
24
|
+
readonly sleep?: (ms: number) => Promise<void>;
|
|
25
|
+
}
|
|
26
|
+
export declare class SessionService {
|
|
27
|
+
private readonly options;
|
|
28
|
+
private readonly store;
|
|
29
|
+
private readonly client;
|
|
30
|
+
private readonly now;
|
|
31
|
+
private readonly sleep;
|
|
32
|
+
private readonly inFlightRefresh;
|
|
33
|
+
constructor(deps: SessionServiceDeps);
|
|
34
|
+
beginAuthorization(input: {
|
|
35
|
+
pkceVerifier: string;
|
|
36
|
+
codeChallenge: string;
|
|
37
|
+
returnTo: string | null;
|
|
38
|
+
}): Promise<{
|
|
39
|
+
authorizationUrl: string;
|
|
40
|
+
state: string;
|
|
41
|
+
}>;
|
|
42
|
+
takePendingAuthorization(state: string): Promise<PendingAuthorization | null>;
|
|
43
|
+
establishSession(tokenSet: OidcTokenSet, returnTo: string | null): Promise<EstablishedSession>;
|
|
44
|
+
resolveSession(cookieValue: string): Promise<ResolvedSession>;
|
|
45
|
+
setActiveOrg(session: LiveSession, orgId: string): Promise<SessionActor | null>;
|
|
46
|
+
endSession(session: LiveSession | null): Promise<string | null>;
|
|
47
|
+
storeKeyFor(cookieValue: string): string;
|
|
48
|
+
private idleTtlMs;
|
|
49
|
+
private ensureFreshAccessToken;
|
|
50
|
+
private refreshUnderLease;
|
|
51
|
+
private performRefresh;
|
|
52
|
+
private awaitAnotherRefresh;
|
|
53
|
+
}
|
|
54
|
+
export declare function storeKeyFor(cookieValue: string): string;
|
|
55
|
+
//# sourceMappingURL=session-service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-service.d.ts","sourceRoot":"","sources":["../../src/session/session-service.ts"],"names":[],"mappings":"AA2BA,OAAO,EAIL,KAAK,YAAY,EAClB,MAAM,SAAS,CAAC;AACjB,OAAO,EAEL,KAAK,UAAU,EACf,KAAK,YAAY,EAClB,MAAM,qBAAqB,CAAC;AAG7B,OAAO,KAAK,EACV,oBAAoB,EACpB,aAAa,EACb,YAAY,EACb,MAAM,iBAAiB,CAAC;AACzB,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AAazE,MAAM,WAAW,eAAe;IAE9B,QAAQ,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI,CAAC;IAUrC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;CAC3B;AAGD,MAAM,WAAW,WAAW;IAE1B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC;IAC/B,QAAQ,CAAC,KAAK,EAAE,YAAY,CAAC;CAC9B;AAGD,MAAM,WAAW,kBAAkB;IAEjC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,KAAK,EAAE,YAAY,CAAC;IAE7B,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CAClC;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,OAAO,EAAE,kBAAkB,CAAC;IACrC,QAAQ,CAAC,KAAK,EAAE,YAAY,CAAC;IAC7B,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;IAE5B,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IAE5B,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAChD;AAED,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAqB;IAE7C,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAe;IAErC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAa;IAEpC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAe;IAEnC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAgC;IAGtD,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAoD;gBAExE,IAAI,EAAE,kBAAkB;IAiB9B,kBAAkB,CAAC,KAAK,EAAE;QAC9B,YAAY,EAAE,MAAM,CAAC;QACrB,aAAa,EAAE,MAAM,CAAC;QACtB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;KACzB,GAAG,OAAO,CAAC;QAAE,gBAAgB,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IAuBxD,wBAAwB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC;IAWvE,gBAAgB,CACpB,QAAQ,EAAE,YAAY,EACtB,QAAQ,EAAE,MAAM,GAAG,IAAI,GACtB,OAAO,CAAC,kBAAkB,CAAC;IA+CxB,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC;IAiC7D,YAAY,CAChB,OAAO,EAAE,WAAW,EACpB,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC;IAuBzB,UAAU,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAarE,WAAW,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM;IAIxC,OAAO,CAAC,SAAS;YAMH,sBAAsB;YA0BtB,iBAAiB;YAkBjB,cAAc;YAiEd,mBAAmB;CA+BlC;AAQD,wBAAgB,WAAW,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAEvD"}
|