@idp.global/sdk 19.1.0 → 19.2.1
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 +29 -0
- package/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts_browser/classes.idpclient.js +1 -1
- package/dist_ts_browser/classes.idprequests.js +1 -1
- package/dist_ts_relyingparty/classes.authorityobserver.js +1 -1
- package/dist_ts_relyingparty/classes.errors.js +1 -1
- package/dist_ts_relyingparty/classes.idpoidcprovider.d.ts +5 -0
- package/dist_ts_relyingparty/classes.idpoidcprovider.js +4 -2
- package/dist_ts_relyingparty/classes.relyingpartysessions.js +4 -2
- package/dist_ts_relyingparty/classes.rpmodels.d.ts +2 -2
- package/dist_ts_relyingparty/helpers.cookies.d.ts +1 -1
- package/dist_ts_relyingparty/helpers.cookies.js +1 -1
- package/dist_ts_relyingparty/helpers.crypto.js +1 -1
- package/dist_ts_relyingparty/testing.d.ts +14 -1
- package/dist_ts_relyingparty/testing.js +48 -4
- package/dist_ts_server/classes.account-auth-service.js +1 -1
- package/dist_ts_server/classes.account-store.js +1 -1
- package/dist_ts_server/classes.idp-global-server-client.js +1 -1
- package/dist_ts_server/classes.oidc-introspection-client.js +1 -1
- package/dist_ts_server/classes.oidc-userinfo-client.js +1 -1
- package/package.json +7 -7
- package/readme.md +12 -3
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts_relyingparty/classes.idpoidcprovider.ts +8 -1
- package/ts_relyingparty/classes.relyingpartysessions.ts +3 -1
- package/ts_relyingparty/testing.ts +48 -2
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import * as plugins from './plugins.js';
|
|
2
2
|
import {
|
|
3
|
+
OidcAuthorityUnavailableError,
|
|
3
4
|
OidcCompletionError,
|
|
4
5
|
OidcRefreshRefusedError,
|
|
5
6
|
type IOidcAuthorizationOptions,
|
|
@@ -60,6 +61,9 @@ interface IIssuedToken {
|
|
|
60
61
|
|
|
61
62
|
const randomToken = (): string => plugins.crypto.randomBytes(18).toString('base64url');
|
|
62
63
|
|
|
64
|
+
/** What `IdpOidcProvider` fails with when a step needs the discovery that has not succeeded. */
|
|
65
|
+
const notDiscovered = (): Error => new Error('The identity provider is not initialized');
|
|
66
|
+
|
|
63
67
|
/**
|
|
64
68
|
* The provider as `IOidcProvider` sees it. A test adds personas, names the one
|
|
65
69
|
* the next login signs in as (`signInNextAs`), follows the authorization URL
|
|
@@ -68,7 +72,9 @@ const randomToken = (): string => plugins.crypto.randomBytes(18).toString('base6
|
|
|
68
72
|
* their login's state; access tokens introspect for their subject while they
|
|
69
73
|
* live; refresh tokens rotate, and a superseded one coming back revokes its
|
|
70
74
|
* whole family, as idp.global's reuse detection does. Every call is recorded,
|
|
71
|
-
* and each step can be made to fail.
|
|
75
|
+
* and each step can be made to fail. Discovery as well (`discoveryFailure`):
|
|
76
|
+
* until an `init` succeeds, the double then answers as `IdpOidcProvider` does
|
|
77
|
+
* before discovery.
|
|
72
78
|
*/
|
|
73
79
|
export class RelyingPartyProviderDouble implements IOidcProvider {
|
|
74
80
|
public readonly requestTimeoutSeconds: number;
|
|
@@ -80,7 +86,18 @@ export class RelyingPartyProviderDouble implements IOidcProvider {
|
|
|
80
86
|
public readonly revocations: Array<{ token: string; hint: TOidcTokenHint }> = [];
|
|
81
87
|
public readonly introspections: Array<{ accessToken: string; subject: string; organizationId: string }> = [];
|
|
82
88
|
public readonly refreshes: string[] = [];
|
|
89
|
+
/** how often `init` was called, failed or not */
|
|
90
|
+
public discoveries = 0;
|
|
83
91
|
|
|
92
|
+
/**
|
|
93
|
+
* when set, an `init` before one has succeeded fails with it, and from then
|
|
94
|
+
* until an `init` succeeds no authorization URL is built, a completion fails
|
|
95
|
+
* at the token exchange and introspection and refresh fail as unavailable,
|
|
96
|
+
* as before discovery; such a step is not recorded, as no request of it
|
|
97
|
+
* reached the provider. Once an `init` has succeeded, discovery stays done,
|
|
98
|
+
* as with `IdpOidcProvider`
|
|
99
|
+
*/
|
|
100
|
+
public discoveryFailure?: Error;
|
|
84
101
|
/** when set, the completion of a login fails with it (an `OidcCompletionError` names its stage) */
|
|
85
102
|
public completionFailure?: Error;
|
|
86
103
|
/** when set, every introspection fails with it (an `OidcAuthorityUnavailableError` for an unreachable provider) */
|
|
@@ -99,6 +116,9 @@ export class RelyingPartyProviderDouble implements IOidcProvider {
|
|
|
99
116
|
readonly #codes = new Map<string, IIssuedCode>();
|
|
100
117
|
readonly #tokens = new Map<string, IIssuedToken>();
|
|
101
118
|
#next?: string;
|
|
119
|
+
/** the double counts as discovered until an `init` fails, and for good once one has succeeded */
|
|
120
|
+
#discovered = true;
|
|
121
|
+
#initialized = false;
|
|
102
122
|
|
|
103
123
|
constructor(optionsArg: IProviderDoubleOptions = {}) {
|
|
104
124
|
this.issuer = new URL(optionsArg.issuer ?? 'https://idp.test').origin;
|
|
@@ -172,9 +192,23 @@ export class RelyingPartyProviderDouble implements IOidcProvider {
|
|
|
172
192
|
|
|
173
193
|
// ---- IOidcProvider ----
|
|
174
194
|
|
|
175
|
-
public async init(): Promise<void> {
|
|
195
|
+
public async init(): Promise<void> {
|
|
196
|
+
this.discoveries += 1;
|
|
197
|
+
if (this.#initialized) {
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
200
|
+
if (this.discoveryFailure) {
|
|
201
|
+
this.#discovered = false;
|
|
202
|
+
throw this.discoveryFailure;
|
|
203
|
+
}
|
|
204
|
+
this.#discovered = true;
|
|
205
|
+
this.#initialized = true;
|
|
206
|
+
}
|
|
176
207
|
|
|
177
208
|
public async buildAuthorizationUrl(optionsArg: IOidcAuthorizationOptions): Promise<URL> {
|
|
209
|
+
if (!this.#discovered) {
|
|
210
|
+
throw notDiscovered();
|
|
211
|
+
}
|
|
178
212
|
if (!this.#next) {
|
|
179
213
|
throw new Error('RelyingPartyProviderDouble: name the persona this login signs in as with signInNextAs');
|
|
180
214
|
}
|
|
@@ -194,6 +228,9 @@ export class RelyingPartyProviderDouble implements IOidcProvider {
|
|
|
194
228
|
}
|
|
195
229
|
|
|
196
230
|
public async completeAuthorization(optionsArg: IOidcCompletionOptions): Promise<IOidcCompletion> {
|
|
231
|
+
if (!this.#discovered) {
|
|
232
|
+
throw new OidcCompletionError('token_exchange', notDiscovered());
|
|
233
|
+
}
|
|
197
234
|
const code = optionsArg.callbackUrl.searchParams.get('code') ?? '';
|
|
198
235
|
const issued = this.#codes.get(code);
|
|
199
236
|
this.#codes.delete(code);
|
|
@@ -224,6 +261,9 @@ export class RelyingPartyProviderDouble implements IOidcProvider {
|
|
|
224
261
|
}
|
|
225
262
|
|
|
226
263
|
public async revokeToken(tokenArg: string, hintArg: TOidcTokenHint): Promise<void> {
|
|
264
|
+
if (!this.#discovered) {
|
|
265
|
+
throw notDiscovered();
|
|
266
|
+
}
|
|
227
267
|
this.revocations.push({ token: tokenArg, hint: hintArg });
|
|
228
268
|
if (this.revocationFailure) {
|
|
229
269
|
throw this.revocationFailure;
|
|
@@ -239,6 +279,9 @@ export class RelyingPartyProviderDouble implements IOidcProvider {
|
|
|
239
279
|
subject: string;
|
|
240
280
|
organizationId: string;
|
|
241
281
|
}): Promise<IOidcOrganizationObservation> {
|
|
282
|
+
if (!this.#discovered) {
|
|
283
|
+
throw new OidcAuthorityUnavailableError('unavailable', notDiscovered());
|
|
284
|
+
}
|
|
242
285
|
this.introspections.push({ ...optionsArg });
|
|
243
286
|
await this.onIntrospect?.({ ...optionsArg });
|
|
244
287
|
if (this.introspectionFailure) {
|
|
@@ -257,6 +300,9 @@ export class RelyingPartyProviderDouble implements IOidcProvider {
|
|
|
257
300
|
}
|
|
258
301
|
|
|
259
302
|
public async refreshTokens(refreshTokenArg: string): Promise<IOidcRefreshedTokens> {
|
|
303
|
+
if (!this.#discovered) {
|
|
304
|
+
throw new OidcAuthorityUnavailableError('unavailable', notDiscovered());
|
|
305
|
+
}
|
|
260
306
|
this.refreshes.push(refreshTokenArg);
|
|
261
307
|
await this.onRefresh?.(refreshTokenArg);
|
|
262
308
|
if (this.refreshFailure) {
|