@idp.global/sdk 19.4.0 → 19.6.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/changelog.md +60 -0
- package/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts_browser/classes.relyingpartybearerclient.d.ts +40 -3
- package/dist_ts_browser/classes.relyingpartybearerclient.js +67 -12
- package/dist_ts_relyingparty/classes.errors.d.ts +2 -0
- package/dist_ts_relyingparty/classes.errors.js +2 -1
- package/dist_ts_relyingparty/classes.idpoidcprovider.d.ts +69 -11
- package/dist_ts_relyingparty/classes.idpoidcprovider.js +127 -17
- package/dist_ts_relyingparty/classes.relyingpartysessions.d.ts +128 -18
- package/dist_ts_relyingparty/classes.relyingpartysessions.js +334 -69
- package/dist_ts_relyingparty/classes.rpmodels.d.ts +21 -4
- package/dist_ts_relyingparty/classes.rpmodels.js +35 -8
- package/dist_ts_relyingparty/contract.bearer.d.ts +37 -0
- package/dist_ts_relyingparty/contract.bearer.js +5 -1
- package/dist_ts_relyingparty/helpers.bearer.d.ts +2 -3
- package/dist_ts_relyingparty/helpers.bearer.js +4 -6
- package/dist_ts_relyingparty/helpers.cookies.d.ts +6 -0
- package/dist_ts_relyingparty/helpers.cookies.js +8 -1
- package/dist_ts_relyingparty/interfaces.d.ts +73 -3
- package/dist_ts_relyingparty/testing.js +8 -4
- package/package.json +3 -3
- package/readme.md +280 -34
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts_browser/classes.relyingpartybearerclient.ts +98 -18
- package/ts_relyingparty/classes.errors.ts +3 -0
- package/ts_relyingparty/classes.idpoidcprovider.ts +183 -17
- package/ts_relyingparty/classes.relyingpartysessions.ts +393 -78
- package/ts_relyingparty/classes.rpmodels.ts +27 -4
- package/ts_relyingparty/contract.bearer.ts +46 -0
- package/ts_relyingparty/helpers.bearer.ts +3 -6
- package/ts_relyingparty/helpers.cookies.ts +13 -0
- package/ts_relyingparty/interfaces.ts +76 -7
- package/ts_relyingparty/testing.ts +7 -3
|
@@ -2,26 +2,123 @@ import * as plugins from './plugins.js';
|
|
|
2
2
|
import { OidcIntrospectionClient, OidcIntrospectionError, } from '../dist_ts_server/classes.oidc-introspection-client.js';
|
|
3
3
|
import { createTrustedCaFetch } from '../dist_ts_server/helpers.trusted-ca-fetch.js';
|
|
4
4
|
export const OIDC_PROMPTS = ['none', 'login', 'consent'];
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
export const OIDC_PROVIDER_ERROR_CODES = [
|
|
6
|
+
'token_exchange_refused',
|
|
7
|
+
'login_mismatch',
|
|
8
|
+
'invalid_response',
|
|
9
|
+
'provider_unreachable',
|
|
10
|
+
'refresh_refused',
|
|
11
|
+
];
|
|
12
|
+
/** An OAuth error code is a short token; anything else a provider sends there is dropped, never kept. */
|
|
13
|
+
const OAUTH_ERROR_PATTERN = /^[A-Za-z0-9_.-]{1,64}$/;
|
|
14
|
+
const oauthErrorOf = (valueArg) => typeof valueArg === 'string' && OAUTH_ERROR_PATTERN.test(valueArg) ? valueArg : undefined;
|
|
15
|
+
/** The OAuth error and HTTP status of an openid-client failure that is the provider's own answer; `null` for any other failure. */
|
|
16
|
+
const providerAnswerOf = (errorArg) => {
|
|
17
|
+
const openidClient = plugins.openidClient;
|
|
18
|
+
if (errorArg instanceof openidClient.ResponseBodyError) {
|
|
19
|
+
return { oauthError: oauthErrorOf(errorArg.error), status: errorArg.status };
|
|
20
|
+
}
|
|
21
|
+
if (errorArg instanceof openidClient.AuthorizationResponseError) {
|
|
22
|
+
return { oauthError: oauthErrorOf(errorArg.error) };
|
|
23
|
+
}
|
|
24
|
+
if (errorArg instanceof openidClient.WWWAuthenticateChallengeError) {
|
|
25
|
+
return { oauthError: oauthErrorOf(errorArg.cause[0]?.parameters.error), status: errorArg.status };
|
|
26
|
+
}
|
|
27
|
+
return null;
|
|
28
|
+
};
|
|
29
|
+
/** openid-client's codes (`ClientError.code`) for a provider that did not answer in time or within HTTP's own contract. */
|
|
30
|
+
const UNREACHABLE_CLIENT_ERROR_CODES = ['OAUTH_TIMEOUT', 'OAUTH_ABORT', 'OAUTH_RESPONSE_IS_NOT_CONFORM'];
|
|
31
|
+
/** openid-client's code for a JWT claim that is not the expected one: the nonce, the issuer, the audience or the authorized party. */
|
|
32
|
+
const JWT_CLAIM_COMPARISON_CODE = 'OAUTH_JWT_CLAIM_COMPARISON_FAILED';
|
|
33
|
+
/**
|
|
34
|
+
* The class of an openid-client failure of the code exchange or of UserInfo.
|
|
35
|
+
* The provider's own OAuth error answer is a refusal, or unreachable on a 5xx;
|
|
36
|
+
* a claim that does not match is not this login's; every other failure of
|
|
37
|
+
* openid-client's checks is an invalid response; and anything else (a
|
|
38
|
+
* transport failure is fetch's `TypeError`) is an unreachable provider.
|
|
39
|
+
*/
|
|
40
|
+
const classifyCompletionFailure = (errorArg) => {
|
|
41
|
+
if (errorArg instanceof OidcProviderError) {
|
|
42
|
+
return { code: errorArg.code, oauthError: errorArg.oauthError };
|
|
43
|
+
}
|
|
44
|
+
const answer = providerAnswerOf(errorArg);
|
|
45
|
+
if (answer) {
|
|
46
|
+
const code = answer.status !== undefined && answer.status >= 500
|
|
47
|
+
? 'provider_unreachable'
|
|
48
|
+
: 'token_exchange_refused';
|
|
49
|
+
return { code, oauthError: answer.oauthError };
|
|
50
|
+
}
|
|
51
|
+
if (errorArg instanceof plugins.openidClient.ClientError) {
|
|
52
|
+
if (errorArg.code === JWT_CLAIM_COMPARISON_CODE) {
|
|
53
|
+
return { code: 'login_mismatch' };
|
|
54
|
+
}
|
|
55
|
+
return { code: errorArg.code !== undefined && UNREACHABLE_CLIENT_ERROR_CODES.includes(errorArg.code) ? 'provider_unreachable' : 'invalid_response' };
|
|
56
|
+
}
|
|
57
|
+
return { code: 'provider_unreachable' };
|
|
58
|
+
};
|
|
59
|
+
/** Why a refresh could not be made: openid-client's checks failed on the answer, or the provider could not be asked. */
|
|
60
|
+
const refreshFailureReasonOf = (errorArg) => errorArg instanceof plugins.openidClient.ClientError
|
|
61
|
+
&& !(errorArg.code !== undefined && UNREACHABLE_CLIENT_ERROR_CODES.includes(errorArg.code))
|
|
62
|
+
? 'invalid_response'
|
|
63
|
+
: 'unavailable';
|
|
64
|
+
/**
|
|
65
|
+
* Every failure of the provider this module throws: its `code` says which
|
|
66
|
+
* case it is, `oauthError` the provider's own OAuth error code where it sent
|
|
67
|
+
* one (a short token, never its description). An application classifies a
|
|
68
|
+
* failure by these and never by openid-client's classes; `cause` keeps the
|
|
69
|
+
* original for a debugger, not for a log line.
|
|
70
|
+
*/
|
|
71
|
+
export class OidcProviderError extends Error {
|
|
72
|
+
code;
|
|
73
|
+
oauthError;
|
|
74
|
+
constructor(messageArg, detailArg, causeArg) {
|
|
75
|
+
super(messageArg, { cause: causeArg });
|
|
76
|
+
this.name = 'OidcProviderError';
|
|
77
|
+
if (!OIDC_PROVIDER_ERROR_CODES.includes(detailArg?.code)) {
|
|
78
|
+
throw new TypeError('OidcProviderError needs one of OIDC_PROVIDER_ERROR_CODES');
|
|
79
|
+
}
|
|
80
|
+
this.code = detailArg.code;
|
|
81
|
+
const oauthError = oauthErrorOf(detailArg.oauthError);
|
|
82
|
+
if (oauthError !== undefined) {
|
|
83
|
+
this.oauthError = oauthError;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* The provider could not be asked, or did not answer in its own contract. The
|
|
89
|
+
* caller fails closed on it. `code` is `provider_unreachable` or
|
|
90
|
+
* `invalid_response`, after `reason`.
|
|
91
|
+
*/
|
|
92
|
+
export class OidcAuthorityUnavailableError extends OidcProviderError {
|
|
7
93
|
reason;
|
|
8
94
|
constructor(reason, causeArg) {
|
|
9
|
-
super('The identity provider could not be observed', {
|
|
95
|
+
super('The identity provider could not be observed', {
|
|
96
|
+
code: reason === 'invalid_response' ? 'invalid_response' : 'provider_unreachable',
|
|
97
|
+
oauthError: providerAnswerOf(causeArg)?.oauthError,
|
|
98
|
+
}, causeArg);
|
|
10
99
|
this.reason = reason;
|
|
11
100
|
this.name = 'OidcAuthorityUnavailableError';
|
|
12
101
|
}
|
|
13
102
|
}
|
|
14
|
-
/**
|
|
15
|
-
|
|
103
|
+
/**
|
|
104
|
+
* The provider refused the refresh with `invalid_grant`: the refresh family is
|
|
105
|
+
* revoked, expired or was reused. `code` is `refresh_refused`.
|
|
106
|
+
*/
|
|
107
|
+
export class OidcRefreshRefusedError extends OidcProviderError {
|
|
16
108
|
constructor(causeArg) {
|
|
17
|
-
super('The identity provider refused the refresh', {
|
|
109
|
+
super('The identity provider refused the refresh', { code: 'refresh_refused', oauthError: 'invalid_grant' }, causeArg);
|
|
18
110
|
this.name = 'OidcRefreshRefusedError';
|
|
19
111
|
}
|
|
20
112
|
}
|
|
21
|
-
|
|
113
|
+
/**
|
|
114
|
+
* A login the provider half could not complete. `stage` says where it
|
|
115
|
+
* stopped, `code` what it was; without a `detailArg` the code is read from
|
|
116
|
+
* the cause, an openid-client failure.
|
|
117
|
+
*/
|
|
118
|
+
export class OidcCompletionError extends OidcProviderError {
|
|
22
119
|
stage;
|
|
23
|
-
constructor(stage, causeArg) {
|
|
24
|
-
super('OIDC completion failed',
|
|
120
|
+
constructor(stage, causeArg, detailArg) {
|
|
121
|
+
super('OIDC completion failed', detailArg ?? classifyCompletionFailure(causeArg), causeArg);
|
|
25
122
|
this.stage = stage;
|
|
26
123
|
this.name = 'OidcCompletionError';
|
|
27
124
|
}
|
|
@@ -68,9 +165,9 @@ export const readOrganizationClaims = (valueArg) => {
|
|
|
68
165
|
/**
|
|
69
166
|
* The relying-party side of the authorization code flow with S256 PKCE on
|
|
70
167
|
* `openid-client`, in the profile idp.global supports: code responses, S256
|
|
71
|
-
* challenges, RS256 ID tokens
|
|
72
|
-
*
|
|
73
|
-
* `OidcIntrospectionClient`.
|
|
168
|
+
* challenges, RS256 ID tokens whose signature is verified against the
|
|
169
|
+
* issuer's JWKS, and `client_secret_basic` for a confidential client. Live
|
|
170
|
+
* organization authority is observed with the sdk's `OidcIntrospectionClient`.
|
|
74
171
|
*/
|
|
75
172
|
export class IdpOidcProvider {
|
|
76
173
|
requestTimeoutSeconds;
|
|
@@ -114,13 +211,18 @@ export class IdpOidcProvider {
|
|
|
114
211
|
}
|
|
115
212
|
const options = this.#options;
|
|
116
213
|
// the timeout and the fetch given to discovery apply to discovery itself
|
|
117
|
-
// and stay on the resolved configuration for every later request
|
|
214
|
+
// and stay on the resolved configuration for every later request.
|
|
215
|
+
// `enableNonRepudiationChecks` verifies the signature of every ID token the
|
|
216
|
+
// code grant and the refresh grant answer against the issuer's JWKS
|
|
217
|
+
// (`jwks_uri`, fetched through the same fetch), so an ID token is never
|
|
218
|
+
// accepted on the trust of the TLS connection alone
|
|
118
219
|
const configuration = await plugins.openidClient.discovery(options.issuer, options.clientId, {
|
|
119
220
|
client_secret: options.clientSecret,
|
|
120
221
|
token_endpoint_auth_method: 'client_secret_basic',
|
|
121
222
|
id_token_signed_response_alg: 'RS256',
|
|
122
223
|
}, plugins.openidClient.ClientSecretBasic(options.clientSecret), {
|
|
123
224
|
timeout: this.requestTimeoutSeconds,
|
|
225
|
+
execute: [plugins.openidClient.enableNonRepudiationChecks],
|
|
124
226
|
...(this.#fetch ? { [plugins.openidClient.customFetch]: this.#fetch } : {}),
|
|
125
227
|
});
|
|
126
228
|
const metadata = configuration.serverMetadata();
|
|
@@ -164,6 +266,11 @@ export class IdpOidcProvider {
|
|
|
164
266
|
});
|
|
165
267
|
}
|
|
166
268
|
async completeAuthorization(optionsArg) {
|
|
269
|
+
// the one state of the callback is the login's, or nothing is exchanged
|
|
270
|
+
const states = optionsArg.callbackUrl.searchParams.getAll('state');
|
|
271
|
+
if (states.length !== 1 || states[0] !== optionsArg.state) {
|
|
272
|
+
throw new OidcCompletionError('token_exchange', new Error('The callback state is not the state of this login'), { code: 'login_mismatch' });
|
|
273
|
+
}
|
|
167
274
|
let tokens;
|
|
168
275
|
try {
|
|
169
276
|
tokens = await plugins.openidClient.authorizationCodeGrant(this.configuration, optionsArg.callbackUrl, {
|
|
@@ -185,7 +292,7 @@ export class IdpOidcProvider {
|
|
|
185
292
|
subject = claims.sub;
|
|
186
293
|
}
|
|
187
294
|
catch (error) {
|
|
188
|
-
throw new OidcCompletionError('token_validation', error);
|
|
295
|
+
throw new OidcCompletionError('token_validation', error, { code: 'invalid_response' });
|
|
189
296
|
}
|
|
190
297
|
// UserInfo is the current view of profile and organization claims; the ID
|
|
191
298
|
// token proves the login. Both are read, and the subjects must agree.
|
|
@@ -197,7 +304,7 @@ export class IdpOidcProvider {
|
|
|
197
304
|
throw new OidcCompletionError('userinfo', error);
|
|
198
305
|
}
|
|
199
306
|
if (userInfo.sub !== subject) {
|
|
200
|
-
throw new OidcCompletionError('token_validation', new Error('The UserInfo subject does not match the ID token'));
|
|
307
|
+
throw new OidcCompletionError('token_validation', new Error('The UserInfo subject does not match the ID token'), { code: 'invalid_response' });
|
|
201
308
|
}
|
|
202
309
|
return {
|
|
203
310
|
subject,
|
|
@@ -263,7 +370,10 @@ export class IdpOidcProvider {
|
|
|
263
370
|
if (error instanceof plugins.openidClient.ResponseBodyError && error.error === 'invalid_grant') {
|
|
264
371
|
throw new OidcRefreshRefusedError(error);
|
|
265
372
|
}
|
|
266
|
-
|
|
373
|
+
// everything else fails closed: another OAuth error (`invalid_client` for a
|
|
374
|
+
// deactivated app) or a transport failure is unreachable, an answer that
|
|
375
|
+
// fails openid-client's checks (an ID token that does not verify) is invalid
|
|
376
|
+
throw new OidcAuthorityUnavailableError(refreshFailureReasonOf(error), error);
|
|
267
377
|
}
|
|
268
378
|
return {
|
|
269
379
|
accessToken: tokens.access_token,
|
|
@@ -272,4 +382,4 @@ export class IdpOidcProvider {
|
|
|
272
382
|
};
|
|
273
383
|
}
|
|
274
384
|
}
|
|
275
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5pZHBvaWRjcHJvdmlkZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi90c19yZWx5aW5ncGFydHkvY2xhc3Nlcy5pZHBvaWRjcHJvdmlkZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLE9BQU8sTUFBTSxjQUFjLENBQUM7QUFDeEMsT0FBTyxFQUNMLHVCQUF1QixFQUN2QixzQkFBc0IsR0FDdkIsTUFBTSxtREFBbUQsQ0FBQztBQUMzRCxPQUFPLEVBQUUsb0JBQW9CLEVBQW1CLE1BQU0sMENBQTBDLENBQUM7QUFLakcsTUFBTSxDQUFDLE1BQU0sWUFBWSxHQUEyQixDQUFDLE1BQU0sRUFBRSxPQUFPLEVBQUUsU0FBUyxDQUFDLENBQUM7QUFpRWpGLDZHQUE2RztBQUM3RyxNQUFNLE9BQU8sNkJBQThCLFNBQVEsS0FBSztJQUVwQyxNQUFNO0lBRHhCLFlBQ2tCLE1BQTZCLEVBQzdDLFFBQWtCO1FBRWxCLEtBQUssQ0FBQyw2Q0FBNkMsRUFBRSxFQUFFLEtBQUssRUFBRSxRQUFRLEVBQUUsQ0FBQyxDQUFDO3NCQUgxRCxNQUFNO1FBSXRCLElBQUksQ0FBQyxJQUFJLEdBQUcsK0JBQStCLENBQUM7SUFDOUMsQ0FBQztDQUNGO0FBRUQsbUhBQW1IO0FBQ25ILE1BQU0sT0FBTyx1QkFBd0IsU0FBUSxLQUFLO0lBQ2hELFlBQVksUUFBa0I7UUFDNUIsS0FBSyxDQUFDLDJDQUEyQyxFQUFFLEVBQUUsS0FBSyxFQUFFLFFBQVEsRUFBRSxDQUFDLENBQUM7UUFDeEUsSUFBSSxDQUFDLElBQUksR0FBRyx5QkFBeUIsQ0FBQztJQUN4QyxDQUFDO0NBQ0Y7QUFNRCxNQUFNLE9BQU8sbUJBQW9CLFNBQVEsS0FBSztJQUUxQixLQUFLO0lBRHZCLFlBQ2tCLEtBQWtDLEVBQ2xELFFBQWlCO1FBRWpCLEtBQUssQ0FBQyx3QkFBd0IsRUFBRSxFQUFFLEtBQUssRUFBRSxRQUFRLEVBQUUsQ0FBQyxDQUFDO3FCQUhy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
|
|
385
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5pZHBvaWRjcHJvdmlkZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi90c19yZWx5aW5ncGFydHkvY2xhc3Nlcy5pZHBvaWRjcHJvdmlkZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLE9BQU8sTUFBTSxjQUFjLENBQUM7QUFDeEMsT0FBTyxFQUNMLHVCQUF1QixFQUN2QixzQkFBc0IsR0FDdkIsTUFBTSxtREFBbUQsQ0FBQztBQUMzRCxPQUFPLEVBQUUsb0JBQW9CLEVBQW1CLE1BQU0sMENBQTBDLENBQUM7QUFLakcsTUFBTSxDQUFDLE1BQU0sWUFBWSxHQUEyQixDQUFDLE1BQU0sRUFBRSxPQUFPLEVBQUUsU0FBUyxDQUFDLENBQUM7QUEwRmpGLE1BQU0sQ0FBQyxNQUFNLHlCQUF5QixHQUFzQztJQUMxRSx3QkFBd0I7SUFDeEIsZ0JBQWdCO0lBQ2hCLGtCQUFrQjtJQUNsQixzQkFBc0I7SUFDdEIsaUJBQWlCO0NBQ2xCLENBQUM7QUFFRix5R0FBeUc7QUFDekcsTUFBTSxtQkFBbUIsR0FBRyx3QkFBd0IsQ0FBQztBQUVyRCxNQUFNLFlBQVksR0FBRyxDQUFDLFFBQWlCLEVBQXNCLEVBQUUsQ0FDN0QsT0FBTyxRQUFRLEtBQUssUUFBUSxJQUFJLG1CQUFtQixDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUM7QUFFNUYsbUlBQW1JO0FBQ25JLE1BQU0sZ0JBQWdCLEdBQUcsQ0FBQyxRQUFpQixFQUFtRCxFQUFFO0lBQzlGLE1BQU0sWUFBWSxHQUFHLE9BQU8sQ0FBQyxZQUFZLENBQUM7SUFDMUMsSUFBSSxRQUFRLFlBQVksWUFBWSxDQUFDLGlCQUFpQixFQUFFLENBQUM7UUFDdkQsT0FBTyxFQUFFLFVBQVUsRUFBRSxZQUFZLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxFQUFFLE1BQU0sRUFBRSxRQUFRLENBQUMs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
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type IOidcProvider } from './classes.idpoidcprovider.js';
|
|
2
2
|
import type { IRelyingPartyModels } from './classes.rpmodels.js';
|
|
3
|
-
import type { IAuthorityTokenSource, IProviderToken, IRelyingPartyBearerDelivery, IRelyingPartyBearerHandoff, IRelyingPartyBearerLoginRequest, IRelyingPartyBearerLoginStart, IRelyingPartyBearerOptions, IRelyingPartyBearerReturnTargets, IRelyingPartyBearerTokens, IRelyingPartyHooks, IRelyingPartyLiveSession, IRelyingPartyLoginOptions, IRelyingPartyLoginStart, IRelyingPartySession, IRelyingPartySessionOpening, IRelyingPartySessionsPage, IRelyingPartySessionsPageOptions, IResolvedRelyingPartySession, TRelyingPartyPrincipals, TRelyingPartySessionEndReason } from './interfaces.js';
|
|
3
|
+
import type { IAuthorityTokenSource, IProviderToken, IRelyingPartyBearerDelivery, IRelyingPartyBearerHandoff, IRelyingPartyBearerHandoffOpening, IRelyingPartyBearerLoginRequest, IRelyingPartyBearerLoginStart, IRelyingPartyBearerOptions, IRelyingPartyBearerReturnTargets, IRelyingPartyBearerTokens, IRelyingPartyCookiePolicy, IRelyingPartyHooks, IRelyingPartyLiveSession, IRelyingPartyLoginOptions, IRelyingPartyLoginStart, IRelyingPartySession, IRelyingPartySessionOpening, IRelyingPartySessionsErasure, IRelyingPartySessionsPage, IRelyingPartySessionsPageOptions, IResolvedRelyingPartySession, TRelyingPartyPrincipals, TRelyingPartySessionEndReason } from './interfaces.js';
|
|
4
4
|
export declare const RELYING_PARTY_DEFAULT_SESSION_MAX_AGE_SECONDS: number;
|
|
5
5
|
export declare const RELYING_PARTY_DEFAULT_LOGIN_PATH_PREFIX = "/auth/";
|
|
6
6
|
/** The label the CSRF HMAC starts with unless the application names its own. */
|
|
@@ -17,6 +17,10 @@ export declare const RELYING_PARTY_MAX_SESSIONS_PAGE_LIMIT = 1000;
|
|
|
17
17
|
export declare const BEARER_HANDOFF_MAX_AGE_SECONDS = 60;
|
|
18
18
|
/** How long a bearer access token lives unless `bearer.accessTokenMaxAgeSeconds` says otherwise. */
|
|
19
19
|
export declare const RELYING_PARTY_DEFAULT_BEARER_ACCESS_TOKEN_MAX_AGE_SECONDS: number;
|
|
20
|
+
/** How long a spent refresh token may come back as a lost answer unless `bearer.refreshReuseGraceSeconds` says otherwise. */
|
|
21
|
+
export declare const RELYING_PARTY_DEFAULT_REFRESH_REUSE_GRACE_SECONDS = 60;
|
|
22
|
+
/** The longest `bearer.refreshReuseGraceSeconds`: a spent token that comes back later is always reuse. */
|
|
23
|
+
export declare const RELYING_PARTY_MAX_REFRESH_REUSE_GRACE_SECONDS = 300;
|
|
20
24
|
/**
|
|
21
25
|
* How long ending a session waits for the provider to take its tokens back.
|
|
22
26
|
* The local session is already revoked when that call runs.
|
|
@@ -62,6 +66,14 @@ export interface IRelyingPartySessionsOptions<TPrincipal extends object | undefi
|
|
|
62
66
|
session?: string;
|
|
63
67
|
intent?: string;
|
|
64
68
|
};
|
|
69
|
+
/**
|
|
70
|
+
* How the session and intent cookies go across sites: `{ sameSite: 'Lax' }`
|
|
71
|
+
* by default. A page framed on another site needs `sameSite: 'None'` (an
|
|
72
|
+
* https `publicOrigin` only), with `partitioned: true` where the browser
|
|
73
|
+
* keeps third-party cookies per top-level site. The constructor refuses
|
|
74
|
+
* every other combination.
|
|
75
|
+
*/
|
|
76
|
+
cookiePolicy?: IRelyingPartyCookiePolicy;
|
|
65
77
|
/** the prefix of the login routes; a login never returns into it */
|
|
66
78
|
loginPathPrefix?: string;
|
|
67
79
|
/**
|
|
@@ -78,20 +90,22 @@ export interface IRelyingPartySessionsOptions<TPrincipal extends object | undefi
|
|
|
78
90
|
* sign in through bearer hand-off and nothing else. The relying party never
|
|
79
91
|
* reads or sets a cookie — not even the clearing intent cookie of a callback
|
|
80
92
|
* that is no bearer login — so it has no CSRF token and takes no CSRF key:
|
|
81
|
-
* `csrfKey`, `csrfLabel` and `
|
|
93
|
+
* `csrfKey`, `csrfLabel`, `cookieNames` and `cookiePolicy` are refused, not
|
|
94
|
+
* ignored. The
|
|
82
95
|
* cookie steps (`openSession`, `startLogin`, `completeLogin`, `abandonLogin`,
|
|
83
96
|
* `finalizeLogin`, `clearSessionCookie`, `clearIntentCookie`) throw
|
|
84
97
|
* `RelyingPartyError('login_method_unavailable')` and `resolveCookieSession`
|
|
85
98
|
* answers `null`.
|
|
86
99
|
*/
|
|
87
|
-
export interface IRelyingPartyBearerOnlySessionsOptions<TPrincipal extends object | undefined = undefined> extends Omit<IRelyingPartySessionsOptions<TPrincipal>, 'provider' | 'csrfKey' | 'csrfLabel' | 'cookieNames' | 'cookieSessions' | 'bearer'> {
|
|
100
|
+
export interface IRelyingPartyBearerOnlySessionsOptions<TPrincipal extends object | undefined = undefined> extends Omit<IRelyingPartySessionsOptions<TPrincipal>, 'provider' | 'csrfKey' | 'csrfLabel' | 'cookieNames' | 'cookiePolicy' | 'cookieSessions' | 'bearer'> {
|
|
88
101
|
cookieSessions: false;
|
|
89
|
-
/** every bearer session
|
|
102
|
+
/** every bearer session comes from a live provider login, directly or through a hand-off opened from one */
|
|
90
103
|
provider: IOidcProvider;
|
|
91
104
|
bearer: IRelyingPartyBearerOptions;
|
|
92
105
|
csrfKey?: never;
|
|
93
106
|
csrfLabel?: never;
|
|
94
107
|
cookieNames?: never;
|
|
108
|
+
cookiePolicy?: never;
|
|
95
109
|
}
|
|
96
110
|
/**
|
|
97
111
|
* The relying-party session layer: provider logins through the authorization
|
|
@@ -106,10 +120,10 @@ export interface IRelyingPartyBearerOnlySessionsOptions<TPrincipal extends objec
|
|
|
106
120
|
* ended sessions are swept one bounded batch at a time when a login starts or
|
|
107
121
|
* the application opens a session, and the only timer — the revocation
|
|
108
122
|
* budget — is unreferenced and cleared on every path. Every session comes
|
|
109
|
-
* from a login start or
|
|
110
|
-
* of at least one first, so removal keeps pace with creation
|
|
111
|
-
* sessions kept stay bounded. Nothing here does I/O while it is
|
|
112
|
-
* so it is built before the database connects.
|
|
123
|
+
* from a login start, `openSession` or `openBearerHandoff`, and each of those
|
|
124
|
+
* sweeps a batch of at least one first, so removal keeps pace with creation
|
|
125
|
+
* and the ended sessions kept stay bounded. Nothing here does I/O while it is
|
|
126
|
+
* constructed, so it is built before the database connects.
|
|
113
127
|
*
|
|
114
128
|
* `TPrincipal` is what a `principals.resolve` answers; with `isActive`
|
|
115
129
|
* principals it stays `undefined`.
|
|
@@ -120,6 +134,8 @@ export declare class RelyingPartySessions<TPrincipal extends object | undefined
|
|
|
120
134
|
readonly secureCookies: boolean;
|
|
121
135
|
readonly sessionCookieName: string;
|
|
122
136
|
readonly intentCookieName: string;
|
|
137
|
+
/** how the session and intent cookies go across sites, as the constructor resolved `cookiePolicy` */
|
|
138
|
+
readonly cookiePolicy: Readonly<Required<IRelyingPartyCookiePolicy>>;
|
|
123
139
|
readonly loginPathPrefix: string;
|
|
124
140
|
readonly sessionMaxAgeSeconds: number;
|
|
125
141
|
constructor(optionsArg: IRelyingPartySessionsOptions<TPrincipal> | IRelyingPartyBearerOnlySessionsOptions<TPrincipal>);
|
|
@@ -181,10 +197,29 @@ export declare class RelyingPartySessions<TPrincipal extends object | undefined
|
|
|
181
197
|
/**
|
|
182
198
|
* Ends every live session of a principal but `keepSessionId` (a password
|
|
183
199
|
* change keeps the session that asked for it) and answers how many ended.
|
|
200
|
+
* A session that expired is over already and is neither ended nor counted.
|
|
184
201
|
*/
|
|
185
202
|
endSessionsOfPrincipal(principalIdArg: string, optionsArg?: {
|
|
186
203
|
keepSessionId?: string;
|
|
187
204
|
}): Promise<number>;
|
|
205
|
+
/**
|
|
206
|
+
* Erases every session of a principal, live or ended, and every row that
|
|
207
|
+
* belongs to one, without waiting for a sweep: what an application runs
|
|
208
|
+
* when it deletes an account, after its own erasers and before its user
|
|
209
|
+
* record.
|
|
210
|
+
*
|
|
211
|
+
* First each session not revoked yet, an expired one too, ends as
|
|
212
|
+
* `endSession` ends it: its tokens stop working at once, `onSessionEnded`
|
|
213
|
+
* names the principal, and its provider tokens go back to idp.global,
|
|
214
|
+
* which a deleted row could no longer do. Then each session's rows go: in
|
|
215
|
+
* bearer mode its hand-offs, claimed or not, and its token generations;
|
|
216
|
+
* the login attempt a provider session came out of; and the session row
|
|
217
|
+
* last, because it is the only link from the principal to the others, so
|
|
218
|
+
* an erase that fails half way leaves a retry everything it needs. A
|
|
219
|
+
* session opened or a token issued while the erase runs is not covered;
|
|
220
|
+
* it works only while the principal is active.
|
|
221
|
+
*/
|
|
222
|
+
eraseSessionsOfPrincipal(principalIdArg: string): Promise<IRelyingPartySessionsErasure>;
|
|
188
223
|
/**
|
|
189
224
|
* One page of a principal's live sessions, newest first: the ones neither
|
|
190
225
|
* ended nor expired, and none at all while the principal is not active —
|
|
@@ -248,6 +283,35 @@ export declare class RelyingPartySessions<TPrincipal extends object | undefined
|
|
|
248
283
|
* at most and only its hash is stored. A code nobody claims ends its session.
|
|
249
284
|
*/
|
|
250
285
|
completeBearerLogin(callbackUrlArg: URL): Promise<IRelyingPartyBearerHandoff>;
|
|
286
|
+
/**
|
|
287
|
+
* Opens a bearer session for a device the application pairs to a person
|
|
288
|
+
* who is signed in here, and answers its single-use hand-off code, which
|
|
289
|
+
* the device claims at `bearer/claim` with the verifier of `codeChallenge`,
|
|
290
|
+
* exactly like the code of a bearer login.
|
|
291
|
+
*
|
|
292
|
+
* `openerSessionId` names the session that confirmed the pairing, taken
|
|
293
|
+
* from the application's own record, never from the device. It must be a
|
|
294
|
+
* live provider login: not ended, not expired, its principal active, and
|
|
295
|
+
* with a provider login of its own. A session the application opened
|
|
296
|
+
* itself or one opened here does not qualify, so a paired device never
|
|
297
|
+
* pairs another one. Anything else throws
|
|
298
|
+
* `RelyingPartyError('invalid_handoff_opener')`.
|
|
299
|
+
*
|
|
300
|
+
* The new session acts as the opener's principal and has no provider login
|
|
301
|
+
* of its own: it ends by its expiry, `endSession`, `endSessionsOfPrincipal`,
|
|
302
|
+
* `bearer/logout` or the reuse of one of its credentials, never by an
|
|
303
|
+
* idp.global logout, and `AuthorityObserver` refuses it
|
|
304
|
+
* (`authority_login_required`). `maxAgeSeconds` is a whole number from 1 to
|
|
305
|
+
* `sessionMaxAgeSeconds`, the default, as for `openSession`. The code lives
|
|
306
|
+
* `BEARER_HANDOFF_MAX_AGE_SECONDS` at most and never past the session, and
|
|
307
|
+
* only its hash is stored; a code nobody claims ends its session. Nothing
|
|
308
|
+
* is stored for a refused opening.
|
|
309
|
+
*/
|
|
310
|
+
openBearerHandoff(optionsArg: {
|
|
311
|
+
openerSessionId: string;
|
|
312
|
+
codeChallenge: string;
|
|
313
|
+
maxAgeSeconds?: number;
|
|
314
|
+
}): Promise<IRelyingPartyBearerHandoffOpening>;
|
|
251
315
|
/** `abandonLogin` for a bearer login: the provider came back without a code. */
|
|
252
316
|
abandonBearerLogin(callbackUrlArg: URL): Promise<void>;
|
|
253
317
|
/**
|
|
@@ -261,13 +325,45 @@ export declare class RelyingPartySessions<TPrincipal extends object | undefined
|
|
|
261
325
|
/**
|
|
262
326
|
* Rotates a bearer session's tokens: the refresh token is spent, a new
|
|
263
327
|
* access and refresh token answer, and the old access token stops working.
|
|
264
|
-
*
|
|
265
|
-
*
|
|
266
|
-
*
|
|
267
|
-
*
|
|
268
|
-
*
|
|
328
|
+
* A client serializes its refreshes, because a refresh token that comes
|
|
329
|
+
* back after it was spent ends the whole session, with one exception for
|
|
330
|
+
* an answer that never reached the client: within
|
|
331
|
+
* `bearer.refreshReuseGraceSeconds` of its rotation (60 by default), a
|
|
332
|
+
* spent refresh token whose successor was never presented — neither its
|
|
333
|
+
* access token nor its refresh token — revokes that successor and answers a
|
|
334
|
+
* new pair (`bearer_refresh_reissued`). Only hashes are stored, so the lost
|
|
335
|
+
* pair is replaced, never repeated. Once the successor was presented, after
|
|
336
|
+
* the window, or for a second retry that loses the race to the first, it is
|
|
337
|
+
* reuse. The provider login of a bearer login is checked on the way: a
|
|
338
|
+
* login idp.global ended ends the session here (`invalid_bearer_grant`), an
|
|
339
|
+
* unreachable provider fails with `AuthorityTokenError('authority_unavailable')`
|
|
340
|
+
* and spends nothing. A session `openBearerHandoff` opened has no provider
|
|
341
|
+
* login (no `idpSubject` is stored) and rotates without the provider.
|
|
269
342
|
*/
|
|
270
343
|
refreshBearerTokens(refreshTokenArg: unknown): Promise<IRelyingPartyBearerTokens>;
|
|
344
|
+
/**
|
|
345
|
+
* The successor of a spent generation when its answer may have been lost:
|
|
346
|
+
* the rotation is at most `refreshReuseGraceMs` old, and the successor is
|
|
347
|
+
* still current and was never presented. `null` otherwise, which is reuse.
|
|
348
|
+
*/
|
|
349
|
+
private lostSuccessorOf;
|
|
350
|
+
/**
|
|
351
|
+
* Issues a pair again for a spent generation whose answer was lost. The
|
|
352
|
+
* successor that answer carried is revoked first, by one conditional write
|
|
353
|
+
* that needs it current and unpresented: of two retries at once exactly one
|
|
354
|
+
* takes it, and the other is reuse, as is a successor presented in the
|
|
355
|
+
* meantime. Then the new generation is stored and the spent one names it,
|
|
356
|
+
* so a retry after this answer is lost too finds it within the same window
|
|
357
|
+
* (counted from the original rotation). A failure after the revocation
|
|
358
|
+
* leaves the session without a current generation; its retry is reuse.
|
|
359
|
+
*/
|
|
360
|
+
private reissueLostRotation;
|
|
361
|
+
/**
|
|
362
|
+
* Records the first presentation of a current generation's access or refresh
|
|
363
|
+
* token, once. Answers whether the generation is still current: `false`
|
|
364
|
+
* when a lost answer of its predecessor revoked it just now.
|
|
365
|
+
*/
|
|
366
|
+
private markBearerGenerationPresented;
|
|
271
367
|
/**
|
|
272
368
|
* The live session behind a bearer access token, or `null`: the token of the
|
|
273
369
|
* session's current generation, not expired, its session live and its
|
|
@@ -279,7 +375,9 @@ export declare class RelyingPartySessions<TPrincipal extends object | undefined
|
|
|
279
375
|
/**
|
|
280
376
|
* Ends the session of a bearer token — a live access token or the current
|
|
281
377
|
* refresh token — like `endSession`. A refresh token that was already spent
|
|
282
|
-
* is reuse and ends the session as such
|
|
378
|
+
* is reuse and ends the session as such, unless `refreshBearerTokens` would
|
|
379
|
+
* take it as a lost answer (`lostSuccessorOf`): then it is a logout like the
|
|
380
|
+
* current one. Answers whether this call ended it.
|
|
283
381
|
*/
|
|
284
382
|
endBearerSession(tokenArg: unknown): Promise<boolean>;
|
|
285
383
|
/**
|
|
@@ -328,6 +426,8 @@ export declare class RelyingPartySessions<TPrincipal extends object | undefined
|
|
|
328
426
|
*/
|
|
329
427
|
private openProviderLogin;
|
|
330
428
|
private newSessionDoc;
|
|
429
|
+
/** The attributes every session and intent cookie is set and cleared with: one policy for all of them. */
|
|
430
|
+
private cookieAttributes;
|
|
331
431
|
private csrfTokenOf;
|
|
332
432
|
private opening;
|
|
333
433
|
private snapshot;
|
|
@@ -341,7 +441,13 @@ export declare class RelyingPartySessions<TPrincipal extends object | undefined
|
|
|
341
441
|
private createProviderSession;
|
|
342
442
|
/** Where a bearer attempt's outcome goes, while its return target is still configured; `null` otherwise. */
|
|
343
443
|
private bearerDeliveryOfAttempt;
|
|
344
|
-
/**
|
|
444
|
+
/**
|
|
445
|
+
* Stores a new hand-off of a session, bound to the client's challenge, and
|
|
446
|
+
* answers its code, which is stored only as a hash. The code lives
|
|
447
|
+
* `BEARER_HANDOFF_MAX_AGE_SECONDS` at most and never past the session.
|
|
448
|
+
*/
|
|
449
|
+
private storeBearerHandoff;
|
|
450
|
+
/** Stores the next token generation of a live session and answers its tokens and its id; no token is stored in the clear. */
|
|
345
451
|
private issueBearerTokens;
|
|
346
452
|
/** A spent hand-off code or refresh token came back: whoever holds it, the session ends. */
|
|
347
453
|
private bearerCredentialReused;
|
|
@@ -415,9 +521,13 @@ export declare class RelyingPartySessions<TPrincipal extends object | undefined
|
|
|
415
521
|
* page per login start and per session the application opens. An ended
|
|
416
522
|
* session's expiry is its revocation at the latest, so the expiry index
|
|
417
523
|
* finds expired and revoked sessions alike. Each of them ended already: the
|
|
418
|
-
* row goes without an end, a hook or a provider call.
|
|
419
|
-
*
|
|
420
|
-
*
|
|
524
|
+
* row goes without an end, a hook or a provider call. Its children go
|
|
525
|
+
* first: in bearer mode its hand-offs and token generations, by their
|
|
526
|
+
* `sessionId` index, and only then the session row, which is the only link
|
|
527
|
+
* from a principal to them; a sweep that fails half way leaves the session
|
|
528
|
+
* row, and the next sweep finds it and deletes the rest. Expiry never moves
|
|
529
|
+
* later, so a session past the cutoff stays past it, and its row is deleted
|
|
530
|
+
* only while that still holds. A sweep that cannot run never blocks a
|
|
421
531
|
* sign-in.
|
|
422
532
|
*/
|
|
423
533
|
private sweepEndedSessions;
|