@idp.global/sdk 19.4.0 → 19.5.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.
@@ -36,6 +36,43 @@ export interface IRelyingPartyBearerMessage {
36
36
  * of the application's own refusal (`RelyingPartyRefusal.code`).
37
37
  */
38
38
  export type TRelyingPartyBearerDeliveryError = 'access_denied' | 'authentication_failed' | (string & {});
39
+ /** Whether a value is a well-formed PKCE code verifier (RFC 7636 §4.1). */
40
+ export declare const isPkceVerifier: (valueArg: unknown) => valueArg is string;
41
+ /**
42
+ * The query of `GET <prefix>bearer/login`, by its parameter names on the
43
+ * wire. The routes check every parameter as untrusted input.
44
+ */
45
+ export interface IRelyingPartyBearerLoginQuery {
46
+ client_kind: TRelyingPartyBearerClientKind;
47
+ /** one of the configured return targets of the kind, exactly; a loopback target with the client's port */
48
+ return_target: string;
49
+ /** BASE64URL(SHA-256(code verifier)), 43 characters */
50
+ code_challenge: string;
51
+ /** only `S256` is accepted */
52
+ code_challenge_method: 'S256';
53
+ /** the client's own correlation value, 1 to 256 characters of `A-Z a-z 0-9 . _ ~ -`, handed back with the outcome */
54
+ state?: string;
55
+ }
56
+ /** The JSON body of `POST <prefix>bearer/claim`. */
57
+ export interface IRelyingPartyBearerClaimRequest {
58
+ /** the hand-off code, claimed once */
59
+ code: string;
60
+ /** the verifier of the challenge the code is bound to (`isPkceVerifier`) */
61
+ codeVerifier: string;
62
+ }
63
+ /** The JSON body of `POST <prefix>bearer/refresh`. */
64
+ export interface IRelyingPartyBearerRefreshRequest {
65
+ /** the current refresh token; this call spends it */
66
+ refreshToken: string;
67
+ }
68
+ /**
69
+ * The JSON body of `POST <prefix>bearer/logout`. The session is named by
70
+ * `Authorization: Bearer <accessToken>`, or by `refreshToken` once that access
71
+ * token has expired.
72
+ */
73
+ export interface IRelyingPartyBearerLogoutRequest {
74
+ refreshToken?: string;
75
+ }
39
76
  /** The session a bearer answer names. */
40
77
  export interface IRelyingPartyBearerSessionInfo {
41
78
  sessionId: string;
@@ -6,4 +6,8 @@
6
6
  */
7
7
  /** The `type` of every message a popup delivery posts. */
8
8
  export const RELYING_PARTY_BEARER_MESSAGE_TYPE = 'idp.global/relyingparty:bearer-handoff';
9
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29udHJhY3QuYmVhcmVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vdHNfcmVseWluZ3BhcnR5L2NvbnRyYWN0LmJlYXJlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7R0FLRztBQUVILDBEQUEwRDtBQUMxRCxNQUFNLENBQUMsTUFBTSxpQ0FBaUMsR0FBRyx3Q0FBd0MsQ0FBQyJ9
9
+ /** RFC 7636 §4.1: a code verifier is 43 to 128 characters of `A-Z a-z 0-9 . _ ~ -`. */
10
+ const PKCE_VERIFIER = /^[A-Za-z0-9._~-]{43,128}$/u;
11
+ /** Whether a value is a well-formed PKCE code verifier (RFC 7636 §4.1). */
12
+ export const isPkceVerifier = (valueArg) => typeof valueArg === 'string' && PKCE_VERIFIER.test(valueArg);
13
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29udHJhY3QuYmVhcmVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vdHNfcmVseWluZ3BhcnR5L2NvbnRyYWN0LmJlYXJlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7R0FLRztBQUVILDBEQUEwRDtBQUMxRCxNQUFNLENBQUMsTUFBTSxpQ0FBaUMsR0FBRyx3Q0FBd0MsQ0FBQztBQW1DMUYsdUZBQXVGO0FBQ3ZGLE1BQU0sYUFBYSxHQUFHLDRCQUE0QixDQUFDO0FBRW5ELDJFQUEyRTtBQUMzRSxNQUFNLENBQUMsTUFBTSxjQUFjLEdBQUcsQ0FBQyxRQUFpQixFQUFzQixFQUFFLENBQ3RFLE9BQU8sUUFBUSxLQUFLLFFBQVEsSUFBSSxhQUFhLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDIn0=
@@ -1,10 +1,9 @@
1
- import { RELYING_PARTY_BEARER_MESSAGE_TYPE, type IRelyingPartyBearerMessage, type TRelyingPartyBearerClientKind } from './contract.bearer.js';
1
+ import { isPkceVerifier, RELYING_PARTY_BEARER_MESSAGE_TYPE, type IRelyingPartyBearerMessage, type TRelyingPartyBearerClientKind } from './contract.bearer.js';
2
2
  import type { IRelyingPartyBearerDelivery, IRelyingPartyBearerReturnTargets } from './interfaces.js';
3
- export { RELYING_PARTY_BEARER_MESSAGE_TYPE };
3
+ export { isPkceVerifier, RELYING_PARTY_BEARER_MESSAGE_TYPE };
4
4
  export declare const RELYING_PARTY_BEARER_CLIENT_KINDS: readonly TRelyingPartyBearerClientKind[];
5
5
  export declare const isBearerClientKind: (valueArg: unknown) => valueArg is TRelyingPartyBearerClientKind;
6
6
  export declare const isPkceChallenge: (valueArg: unknown) => valueArg is string;
7
- export declare const isPkceVerifier: (valueArg: unknown) => valueArg is string;
8
7
  export declare const isBearerClientState: (valueArg: unknown) => valueArg is string;
9
8
  /** The S256 challenge of a verifier: BASE64URL(SHA-256(ASCII(verifier))). */
10
9
  export declare const pkceChallengeOf: (verifierArg: string) => string;
@@ -1,7 +1,8 @@
1
- import { RELYING_PARTY_BEARER_MESSAGE_TYPE, } from './contract.bearer.js';
1
+ import { isPkceVerifier, RELYING_PARTY_BEARER_MESSAGE_TYPE, } from './contract.bearer.js';
2
2
  import { sha256, timingSafeEqualString } from './helpers.crypto.js';
3
3
  import { sanitizeReturnPath } from './helpers.returnpath.js';
4
- export { RELYING_PARTY_BEARER_MESSAGE_TYPE };
4
+ // the verifier check lives in the import-free contract, which the browser client shares
5
+ export { isPkceVerifier, RELYING_PARTY_BEARER_MESSAGE_TYPE };
5
6
  export const RELYING_PARTY_BEARER_CLIENT_KINDS = Object.freeze([
6
7
  'web',
7
8
  'loopback',
@@ -12,15 +13,12 @@ export const RELYING_PARTY_BEARER_CLIENT_KINDS = Object.freeze([
12
13
  const MAX_RETURN_TARGET_LENGTH = 2_048;
13
14
  /** BASE64URL of a SHA-256 digest, without padding (RFC 7636 §4.2). */
14
15
  const PKCE_CHALLENGE = /^[A-Za-z0-9_-]{43}$/u;
15
- /** RFC 7636 §4.1: 43 to 128 unreserved characters. */
16
- const PKCE_VERIFIER = /^[A-Za-z0-9._~-]{43,128}$/u;
17
16
  const CLIENT_STATE = /^[A-Za-z0-9._~-]{1,256}$/u;
18
17
  const LOOPBACK_HOSTS = ['127.0.0.1', '[::1]'];
19
18
  /** A private-use scheme is a reverse domain name: it has a dot, and no web scheme has one (RFC 8252 §7.1). */
20
19
  const CUSTOM_SCHEME = /^[a-z][a-z0-9+-]*(\.[a-z0-9+-]+)+:$/u;
21
20
  export const isBearerClientKind = (valueArg) => typeof valueArg === 'string' && RELYING_PARTY_BEARER_CLIENT_KINDS.includes(valueArg);
22
21
  export const isPkceChallenge = (valueArg) => typeof valueArg === 'string' && PKCE_CHALLENGE.test(valueArg);
23
- export const isPkceVerifier = (valueArg) => typeof valueArg === 'string' && PKCE_VERIFIER.test(valueArg);
24
22
  export const isBearerClientState = (valueArg) => typeof valueArg === 'string' && CLIENT_STATE.test(valueArg);
25
23
  /** The S256 challenge of a verifier: BASE64URL(SHA-256(ASCII(verifier))). */
26
24
  export const pkceChallengeOf = (verifierArg) => sha256(verifierArg);
@@ -196,4 +194,4 @@ export const bearerPopupPage = (deliveryArg, outcomeArg, nonceArg) => {
196
194
  };
197
195
  /** The policy of a popup page: its nonce script and nothing else. */
198
196
  export const bearerPopupContentSecurityPolicy = (nonceArg) => `default-src 'none'; script-src 'nonce-${nonceArg}'; base-uri 'none'; form-action 'none'; frame-ancestors 'none'`;
199
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaGVscGVycy5iZWFyZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi90c19yZWx5aW5ncGFydHkvaGVscGVycy5iZWFyZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUNMLGlDQUFpQyxHQUdsQyxNQUFNLHNCQUFzQixDQUFDO0FBQzlCLE9BQU8sRUFBRSxNQUFNLEVBQUUscUJBQXFCLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUNwRSxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUc3RCxPQUFPLEVBQUUsaUNBQWlDLEVBQUUsQ0FBQztBQUU3QyxNQUFNLENBQUMsTUFBTSxpQ0FBaUMsR0FBNkMsTUFBTSxDQUFDLE1BQU0sQ0FBQztJQUN2RyxLQUFLO0lBQ0wsVUFBVTtJQUNWLGVBQWU7SUFDZixPQUFPO0NBQ1IsQ0FBQyxDQUFDO0FBRUgsMEZBQTBGO0FBQzFGLE1BQU0sd0JBQXdCLEdBQUcsS0FBSyxDQUFDO0FBQ3ZDLHNFQUFzRTtBQUN0RSxNQUFNLGNBQWMsR0FBRyxzQkFBc0IsQ0FBQztBQUM5QyxzREFBc0Q7QUFDdEQsTUFBTSxhQUFhLEdBQUcsNEJBQTRCLENBQUM7QUFDbkQsTUFBTSxZQUFZLEdBQUcsMkJBQTJCLENBQUM7QUFDakQsTUFBTSxjQUFjLEdBQXNCLENBQUMsV0FBVyxFQUFFLE9BQU8sQ0FBQyxDQUFDO0FBQ2pFLDhHQUE4RztBQUM5RyxNQUFNLGFBQWEsR0FBRyxzQ0FBc0MsQ0FBQztBQUU3RCxNQUFNLENBQUMsTUFBTSxrQkFBa0IsR0FBRyxDQUFDLFFBQWlCLEVBQTZDLEVBQUUsQ0FDakcsT0FBTyxRQUFRLEtBQUssUUFBUSxJQUFLLGlDQUF1RCxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsQ0FBQztBQUU5RyxNQUFNLENBQUMsTUFBTSxlQUFlLEdBQUcsQ0FBQyxRQUFpQixFQUFzQixFQUFFLENBQ3ZFLE9BQU8sUUFBUSxLQUFLLFFBQVEsSUFBSSxjQUFj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
197
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaGVscGVycy5iZWFyZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi90c19yZWx5aW5ncGFydHkvaGVscGVycy5iZWFyZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUNMLGNBQWMsRUFDZCxpQ0FBaUMsR0FHbEMsTUFBTSxzQkFBc0IsQ0FBQztBQUM5QixPQUFPLEVBQUUsTUFBTSxFQUFFLHFCQUFxQixFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDcEUsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFHN0Qsd0ZBQXdGO0FBQ3hGLE9BQU8sRUFBRSxjQUFjLEVBQUUsaUNBQWlDLEVBQUUsQ0FBQztBQUU3RCxNQUFNLENBQUMsTUFBTSxpQ0FBaUMsR0FBNkMsTUFBTSxDQUFDLE1BQU0sQ0FBQztJQUN2RyxLQUFLO0lBQ0wsVUFBVTtJQUNWLGVBQWU7SUFDZixPQUFPO0NBQ1IsQ0FBQyxDQUFDO0FBRUgsMEZBQTBGO0FBQzFGLE1BQU0sd0JBQXdCLEdBQUcsS0FBSyxDQUFDO0FBQ3ZDLHNFQUFzRTtBQUN0RSxNQUFNLGNBQWMsR0FBRyxzQkFBc0IsQ0FBQztBQUM5QyxNQUFNLFlBQVksR0FBRywyQkFBMkIsQ0FBQztBQUNqRCxNQUFNLGNBQWMsR0FBc0IsQ0FBQyxXQUFXLEVBQUUsT0FBTyxDQUFDLENBQUM7QUFDakUsOEdBQThHO0FBQzlHLE1BQU0sYUFBYSxHQUFHLHNDQUFzQyxDQUFDO0FBRTdELE1BQU0sQ0FBQyxNQUFNLGtCQUFrQixHQUFHLENBQUMsUUFBaUIsRUFBNkMsRUFBRSxDQUNqRyxPQUFPLFFBQVEsS0FBSyxRQUFRLElBQUssaUNBQXVELENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxDQUFDO0FBRTlHLE1BQU0sQ0FBQyxNQUFNLGVBQWUsR0FBRyxDQUFDLFFBQWlCLEVBQXNCLEVBQUUsQ0FDdkUsT0FBTyxRQUFRLEtBQUssUUFBUSxJQUFJLGNBQWMsQ0FBQyxJQUFJLENB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
@@ -1,6 +1,6 @@
1
1
  import type { IOidcCompletion, TOidcCompletionFailureStage, TOidcPrompt, TOidcTokenHint } from './classes.idpoidcprovider.js';
2
2
  import type { TRelyingPartyBearerClientKind } from './contract.bearer.js';
3
- export type { IRelyingPartyBearerErrorAnswer, IRelyingPartyBearerLogoutAnswer, IRelyingPartyBearerMessage, IRelyingPartyBearerSessionAnswer, IRelyingPartyBearerSessionInfo, IRelyingPartyBearerTokenAnswer, TRelyingPartyBearerClientKind, TRelyingPartyBearerDeliveryError, TRelyingPartyBearerErrorCode, } from './contract.bearer.js';
3
+ export type { IRelyingPartyBearerClaimRequest, IRelyingPartyBearerErrorAnswer, IRelyingPartyBearerLoginQuery, IRelyingPartyBearerLogoutAnswer, IRelyingPartyBearerLogoutRequest, IRelyingPartyBearerMessage, IRelyingPartyBearerRefreshRequest, IRelyingPartyBearerSessionAnswer, IRelyingPartyBearerSessionInfo, IRelyingPartyBearerTokenAnswer, TRelyingPartyBearerClientKind, TRelyingPartyBearerDeliveryError, TRelyingPartyBearerErrorCode, } from './contract.bearer.js';
4
4
  /** A session as the application reads it; no token and no sealed value is part of it. */
5
5
  export interface IRelyingPartySession {
6
6
  id: string;
@@ -129,6 +129,35 @@ export interface IRelyingPartyBearerHandoff {
129
129
  /** epoch milliseconds, at most `BEARER_HANDOFF_MAX_AGE_SECONDS` after the callback */
130
130
  expiresAt: number;
131
131
  }
132
+ /**
133
+ * A bearer session the application opened for a device it paired
134
+ * (`openBearerHandoff`): the session, which has no provider login of its own
135
+ * (`idpSubject` and `loginAttemptId` are absent), and the single-use code the
136
+ * device claims at `bearer/claim` with the verifier of its challenge. The
137
+ * code is no token; only its hash is stored.
138
+ */
139
+ export interface IRelyingPartyBearerHandoffOpening {
140
+ session: IRelyingPartySession;
141
+ code: string;
142
+ /** epoch milliseconds, at most `BEARER_HANDOFF_MAX_AGE_SECONDS` after the opening and never past the session */
143
+ expiresAt: number;
144
+ }
145
+ /**
146
+ * What `eraseSessionsOfPrincipal` removed of one principal: the sessions it
147
+ * ended first, and the rows it deleted.
148
+ */
149
+ export interface IRelyingPartySessionsErasure {
150
+ /** sessions not revoked yet (an expired one too) that it ended, each with `onSessionEnded` and its provider tokens handed back */
151
+ endedSessions: number;
152
+ /** session rows, live or ended */
153
+ deletedSessions: number;
154
+ /** the sign-in transactions the provider sessions came out of */
155
+ deletedLoginAttempts: number;
156
+ /** bearer hand-offs, claimed or not */
157
+ deletedBearerHandoffs: number;
158
+ /** bearer token generations, current or rotated */
159
+ deletedBearerTokens: number;
160
+ }
132
161
  /**
133
162
  * The relying party's own tokens of a bearer session. The refresh token
134
163
  * rotates on every use; a rotated one coming back ends the session.
@@ -254,21 +283,31 @@ export interface IRelyingPartyHooks {
254
283
  * A provider login opened a session, linked to its attempt. Runs before the
255
284
  * login answers; a throw fails the login: the session is revoked, the
256
285
  * provider tokens are handed back and the original error is rethrown.
286
+ * `delivery` is where a bearer login's outcome goes (its client kind, return
287
+ * target and the client's `state`); a cookie login has none.
257
288
  */
258
289
  onProviderSessionOpened?(eventArg: {
259
290
  session: IRelyingPartySession;
291
+ delivery?: IRelyingPartyBearerDelivery;
260
292
  }): Promise<void>;
261
293
  /**
262
294
  * A session ended, or a caller tried to end one that was already over
263
295
  * (`revokedHere: false`). Close its live connections when `revokedHere`,
264
296
  * drop cached authority either way. Must not wait. A throw (or a rejected
265
297
  * promise) is reported as a `hook_failed` event and never stops the end:
266
- * the provider tokens go back regardless.
298
+ * the provider tokens go back regardless. An end that revoked the session
299
+ * here names its principal (`principalId`); one that found it over already
300
+ * does not.
267
301
  */
268
302
  onSessionEnded?(eventArg: {
269
303
  sessionId: string;
270
304
  reason: TRelyingPartySessionEndReason;
271
- revokedHere: boolean;
305
+ revokedHere: true;
306
+ principalId: string;
307
+ } | {
308
+ sessionId: string;
309
+ reason: TRelyingPartySessionEndReason;
310
+ revokedHere: false;
272
311
  }): void;
273
312
  /**
274
313
  * Structured diagnostics; the default writes one JSON line to
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@idp.global/sdk",
3
- "version": "19.4.0",
3
+ "version": "19.5.0",
4
4
  "private": false,
5
5
  "description": "Reusable browser and server SDK for idp.global authentication.",
6
6
  "type": "module",
package/readme.md CHANGED
@@ -152,7 +152,7 @@ await idp.logout();
152
152
  | `getTransferTokenAndSwitchToLocation()` | Request a transfer token and navigate to the same configured target with `transfertoken` attached. |
153
153
  | `processTransferToken()` | Consume a `transfertoken` from the current URL and refresh local auth state. |
154
154
  | `logout()` | Revoke and clear the current login flow. |
155
- | `RelyingPartyBearerClient` | The bearer hand-off client of a relying party's own `web` and `popup` logins: PKCE start URL, the redirect and popup receivers, claim, refresh single-flight across tabs through Web Locks, and logout, with the token pair in an application storage adapter (`IRelyingPartyBearerTokenStorage`). See [Bearer Hand-off](#bearer-hand-off). |
155
+ | `RelyingPartyBearerClient` | The bearer hand-off client of a relying party's own `web` and `popup` logins: PKCE start URL, the redirect and popup receivers, claim, refresh single-flight across tabs through Web Locks, and logout, with the token pair in an application storage adapter (`IRelyingPartyBearerTokenStorage`). `createPkce()` and `claimCode(pkce, code)` claim a code delivered another way, such as a device pairing, without a window. See [Bearer Hand-off](#bearer-hand-off). |
156
156
 
157
157
  ### Typed Request Shortcuts
158
158
 
@@ -614,6 +614,13 @@ What it does:
614
614
  Nothing runs on a timer, and no token, cookie or sealed value ever reaches a
615
615
  log line or an error message.
616
616
 
617
+ `onSessionEnded` names the session, the reason and whether this call revoked
618
+ it (`revokedHere`); when it did, it also names the session's principal
619
+ (`principalId`), and when the session was over already it does not.
620
+ `onProviderSessionOpened` receives the session and, for a bearer login, its
621
+ `delivery`: the client kind, the return target and the client's `state`. A
622
+ cookie login has no `delivery`.
623
+
617
624
  Application hooks never stand in the way of that cleanup. A throwing (or
618
625
  rejecting) `onSessionEnded` or `onEvent` is reported as a `hook_failed` event —
619
626
  `onEvent`'s own failure on `console.error` — and the provider tokens go back
@@ -648,9 +655,46 @@ example after a local password check.
648
655
 
649
656
  Nothing runs on a timer. A login start first removes up to 100 login attempts
650
657
  and up to 100 sessions that ended more than an hour ago, and a bearer login
651
- start also its bearer hand-offs and token generations; `openSession` removes
652
- the sessions only. Removing an ended session fires no end hook and calls no
653
- provider.
658
+ start also its bearer hand-offs and token generations; `openBearerHandoff`
659
+ removes the bearer state and the sessions, `openSession` the sessions only.
660
+ Removing an ended session fires no end hook and calls no provider.
661
+
662
+ **Deleting an account.** The sweeps above run only when a session is created,
663
+ so an ended session can stay stored for long on a quiet service.
664
+ `eraseSessionsOfPrincipal(principalId)` removes everything of one principal at
665
+ once: an application calls it when it deletes the account, after its own
666
+ erasers and before its user record, so a failure can be retried.
667
+
668
+ ```ts
669
+ await accountData.eraseAll(userId); // the application's own records
670
+ const erasure = await sessions.eraseSessionsOfPrincipal(userId);
671
+ await users.delete(userId);
672
+ ```
673
+
674
+ - It ends every session of the principal that is not revoked yet, an expired
675
+ one too, as `endSession` does: its tokens stop working at once,
676
+ `onSessionEnded` fires (reason `logout`, with `principalId`), and its
677
+ provider tokens go back to idp.global, which a deleted row could no longer
678
+ do.
679
+ - Then it deletes every session row of the principal, live or ended, and with
680
+ each the login attempt a provider session came out of and, in bearer mode,
681
+ its hand-offs (claimed or not) and its token generations. The session row
682
+ goes last: it is the only link from the principal to the others, so an
683
+ erase that fails half way leaves a retry everything it needs.
684
+ - It answers what it removed (`IRelyingPartySessionsErasure`: `endedSessions`,
685
+ `deletedSessions`, `deletedLoginAttempts`, `deletedBearerHandoffs`,
686
+ `deletedBearerTokens`); a second call finds nothing.
687
+ - A session opened by a login already past `admit` when the erase runs is not
688
+ covered. It keeps the principal id until it expires and a later sweep
689
+ removes it. A second `eraseSessionsOfPrincipal(principalId)`, run after the
690
+ user record is deleted, removes it. A token generation issued by a refresh
691
+ already under way is not covered either; it outlives its session row as
692
+ described below.
693
+ - A token generation, and for at most a minute a hand-off, outlives the row
694
+ of its session when that session was revoked and swept before its expiry.
695
+ It holds only hashes, the session id and times, the bearer sweep removes it
696
+ an hour after the session would have expired, and the erase cannot
697
+ attribute it to the principal any more.
654
698
 
655
699
  **Building before the database connects.** `db` may be a function that answers
656
700
  the database once it exists. It is called on every use of a model, the way
@@ -843,8 +887,10 @@ Tokens and their ends:
843
887
  bearer login sweeps it (`handoff_unclaimed`). Each answers 400
844
888
  `invalid_bearer_handoff`; reuse is also reported as a
845
889
  `bearer_credential_reused` event.
846
- - A bearer session is a provider login like a cookie session: `onSessionEnded`,
847
- `endSessionsOfPrincipal` and `AuthorityObserver` apply as they are. A refresh
890
+ - A bearer login is a provider login like a cookie session: `onSessionEnded`,
891
+ `endSessionsOfPrincipal` and `AuthorityObserver` apply as they are. (A
892
+ session opened by pairing a device has no provider login of its own; see
893
+ "Pairing a device" below.) A refresh
848
894
  rotates the provider token when it is due and ends the session when
849
895
  idp.global has ended the login (`invalid_bearer_grant`); an unreachable
850
896
  provider answers 503 `authority_unavailable` and spends nothing. Until then
@@ -877,8 +923,13 @@ The client side:
877
923
  The HTTP answers are exported as types (`IRelyingPartyBearerTokenAnswer`,
878
924
  `IRelyingPartyBearerSessionAnswer`, `IRelyingPartyBearerLogoutAnswer`,
879
925
  `IRelyingPartyBearerErrorAnswer` with `TRelyingPartyBearerErrorCode`, and the
880
- popup's `IRelyingPartyBearerMessage`). They come from a module that imports
881
- nothing, so `@idp.global/sdk/browser` shares them with the server.
926
+ popup's `IRelyingPartyBearerMessage`), and so are the requests:
927
+ `IRelyingPartyBearerLoginQuery` (the `bearer/login` query by its parameter
928
+ names), `IRelyingPartyBearerClaimRequest` (`{ code, codeVerifier }`),
929
+ `IRelyingPartyBearerRefreshRequest` (`{ refreshToken }`) and
930
+ `IRelyingPartyBearerLogoutRequest` (`{ refreshToken? }`). They come from a
931
+ module that imports nothing, so `@idp.global/sdk/browser` and
932
+ `@idp.global/sdk/browser/bearer` share them with the server.
882
933
 
883
934
  **The browser client.** `RelyingPartyBearerClient` from `@idp.global/sdk/browser`
884
935
  is that client side for `web` and `popup` logins. The application owns where the
@@ -929,6 +980,16 @@ await client.logout();
929
980
  `previous_session_not_revoked` with `previousSessionError`. In the last case
930
981
  that session lives on at the relying party until it expires. A failed claim
931
982
  leaves the stored pair and its session as they were.
983
+ - `createPkce()` makes a verifier and its S256 challenge from 32 random bytes,
984
+ and `claimCode(pkce, code)` claims a code bound to that challenge which
985
+ reached the client another way than its own login, such as a device pairing
986
+ ("Pairing a device" below). It is received like a login: one
987
+ claim, never retried, under `requestTimeoutMs`, and the pair replaces the
988
+ stored one under the lock (`IRelyingPartyBearerLoginResult`). A pair is
989
+ claimed with once: a second call with it, after a failed claim as well, is
990
+ `already_received` and sends nothing. A pair that is not one (a malformed
991
+ verifier, a challenge that is not its S256) or a code that is not text
992
+ throws before anything is sent. Neither needs a window.
932
993
  - `openPopupLogin(login, { timeoutMs?, signal?, windowFeatures? })` calls
933
994
  `window.open` before it returns, so a browser lets it through within the
934
995
  click. It takes only a message from the relying party's exact origin, from
@@ -981,6 +1042,87 @@ await client.logout();
981
1042
  - The client needs the Web Locks API and Web Crypto, which a browser offers
982
1043
  only in a secure context, and has no fallback for either. Every request is
983
1044
  sent without credentials, cache or redirects.
1045
+ - It runs in a Manifest V3 extension's service worker. That was checked in
1046
+ Chromium 149: a module service worker imported `@idp.global/sdk/browser/bearer`
1047
+ and ran `createPkce`, `claimCode` against the bearer routes and a rotation
1048
+ through `accessToken()`, with the lock held at each write. Other browsers'
1049
+ extension workers were not checked. The extension needs a host permission
1050
+ for the relying party's origin: the routes answer CORS for popup origins
1051
+ only, so without one the browser's preflight is refused and the claim fails
1052
+ with `request_failed` before it is sent.
1053
+
1054
+ **Pairing a device.** A person who is signed in can sign a second device of
1055
+ theirs in without a login on it, such as a TV or a browser extension. The
1056
+ device makes a PKCE pair and shows the application its challenge, for example
1057
+ together with a short code that the person confirms in a session where they
1058
+ are signed in. The application's server then opens the device's session from
1059
+ the session that confirmed:
1060
+
1061
+ ```ts
1062
+ // the device polls; the person has confirmed the pairing in one of their sessions
1063
+ const { code, expiresAt } = await sessions.openBearerHandoff({
1064
+ openerSessionId: pairing.confirmedInSessionId, // written by the confirm handler, never taken from the device
1065
+ codeChallenge: pairing.codeChallenge, // the device's S256 challenge
1066
+ maxAgeSeconds: 8 * 60 * 60, // optional: 1 to sessionMaxAgeSeconds, which is the default
1067
+ });
1068
+ // answer the poll with `code`; the device claims it at POST /auth/bearer/claim with its verifier
1069
+ ```
1070
+
1071
+ ```ts
1072
+ // the device, with the browser client (a native client claims at bearer/claim itself)
1073
+ const pkce = await client.createPkce();
1074
+ await showPairingRequest(pkce.codeChallenge);
1075
+ const result = await client.claimCode(pkce, await pollForCode());
1076
+ ```
1077
+
1078
+ - **The opener.** `openerSessionId` must name a live provider login: not ended
1079
+ and not expired, with an active principal and a provider login of its own
1080
+ (`idpSubject`). A session from `openSession` or from `openBearerHandoff`
1081
+ does not qualify, so a paired device cannot pair another one. Any other
1082
+ opener throws `RelyingPartyError('invalid_handoff_opener')` (400). A
1083
+ challenge that is not one throws `invalid_bearer_request`, and a
1084
+ `maxAgeSeconds` outside 1 to `sessionMaxAgeSeconds` throws a `RangeError`.
1085
+ Nothing is stored for any of these. Without `bearer` the call throws
1086
+ `login_method_unavailable`; in bearer-only mode it works, with a bearer login
1087
+ as the opener. The check reads this relying party's state of the opener;
1088
+ observe authority with the opener first to ask idp.global itself.
1089
+ - **The pairing record.** It keeps the id of the session that confirmed,
1090
+ written by the confirm handler and never taken from the device. That opener
1091
+ must still be live when the poll delivers the code. Open one hand-off per
1092
+ confirmed pairing, in the poll that delivers it; then the code is never
1093
+ stored, and only the public challenge sits in the record. Only server code
1094
+ opens a hand-off, and no route does. Guard the confirmation against a code
1095
+ the person did not start themselves (RFC 8628 §5.4).
1096
+ - **The code** is a bearer login's code: one claim within
1097
+ `BEARER_HANDOFF_MAX_AGE_SECONDS` (60) and never past the session, bound to
1098
+ the challenge, stored only as a hash. A claimed code that comes back, a wrong
1099
+ verifier or a code nobody claims ends the session.
1100
+ - **The session** acts as the opener's principal and has no `idpSubject` or
1101
+ `loginAttemptId`. It lives `maxAgeSeconds` from the opening, the same rule as
1102
+ every session, and no refresh extends it. It refreshes without asking the
1103
+ provider. Its expiry, `endSession`, `endSessionsOfPrincipal`, the device's
1104
+ `bearer/logout` and the reuse of its code or refresh token end it; an
1105
+ inactive principal resolves it to nothing.
1106
+ - **What does not reach it.** It holds no provider token, so an idp.global
1107
+ logout or a change of the person's memberships never reaches it, and
1108
+ `AuthorityObserver.observe` refuses it (`authority_login_required`) without
1109
+ ending it. So the application:
1110
+ - grants a paired session (`session.idpSubject` absent) no idp.global
1111
+ organization authority and does not observe it. An application that ends
1112
+ sessions on `authority_login_required` must not observe paired sessions at
1113
+ all;
1114
+ - sees idp.global end a login only as `onSessionEnded` with the reason
1115
+ `refresh_token_refused` for one of the person's provider sessions. It may
1116
+ answer that by ending the person's paired sessions: `endSession` for those
1117
+ `sessionsOfPrincipal` lists without `idpSubject`, or
1118
+ `endSessionsOfPrincipal` to end every session of the person. The hook
1119
+ names the principal of a session it revoked (`principalId`), so the
1120
+ application needs no table of sessions and principals of its own;
1121
+ - ends paired sessions itself when the person signs out everywhere, and
1122
+ erases them with every other session when the account goes
1123
+ (`eraseSessionsOfPrincipal`, see "Deleting an account");
1124
+ - chooses `sessionMaxAgeSeconds`, or `maxAgeSeconds` per pairing, knowing
1125
+ that a paired device lives that long without a check at idp.global.
984
1126
 
985
1127
  **Bearer-only mode.** An application whose every client is a bearer client turns
986
1128
  the cookie login off with `cookieSessions: false`. No route then reads or sets a
@@ -1004,7 +1146,8 @@ const sessions = new RelyingPartySessions({
1004
1146
  `null`, like every path the routes do not serve. `startLogin`,
1005
1147
  `completeLogin`, `abandonLogin`, `finalizeLogin`, `openSession`,
1006
1148
  `clearSessionCookie` and `clearIntentCookie` throw `login_method_unavailable`,
1007
- and `resolveCookieSession` answers `null`. A callback that belongs to no bearer
1149
+ and `resolveCookieSession` answers `null`. `openBearerHandoff` works, with a
1150
+ bearer login as the opener. A callback that belongs to no bearer
1008
1151
  login redirects to `failureLocation` when the provider sent an `error`, and
1009
1152
  otherwise answers 400 `authentication_failed`. `RelyingPartySocketBinding`
1010
1153
  registers a browser by its cookie session, so it binds no connection in this
@@ -1088,7 +1231,7 @@ const delivery = await readBearerDelivery(await fetch(callback, { redirect: 'man
1088
1231
  | --- | --- |
1089
1232
  | `IdpOidcProvider` | Discovery, PKCE authorization URL, code exchange with UserInfo, refresh, revocation and organization introspection for idp.global. Implements `IOidcProvider`. `trustedCaPem` or `fetch` for an issuer under a private CA. |
1090
1233
  | `createRelyingPartyModels()` | Binds the session, login-attempt, bearer hand-off and bearer token models to one `SmartdataDb`, or to a function asked for it on every use, optionally under existing collection names. |
1091
- | `RelyingPartySessions<TPrincipal>` | Login start (with an application intent and a prompt)/complete/abandon/finalize, `openSession` (with a shorter lifetime), `resolveCookieSession`, `revalidateSession`, `revalidateLiveSession`, `isSessionLive`, `validateCsrf`, `logout`/`endSession`, `endSessionsOfPrincipal`, `sessionsOfPrincipal` (paged), `liveProviderToken` (with `rejectedAccessToken`). Principals give `isActive` or `resolve` (`IRelyingPartyPrincipals`, `IRelyingPartyPrincipalResolver<TPrincipal>`); with `resolve`, live sessions carry `principal`. With `bearer`: `startBearerLogin`, `bearerDeliveryOf`, `completeBearerLogin`, `abandonBearerLogin`, `claimBearerHandoff`, `refreshBearerTokens`, `resolveBearerAccessToken`, `resolveBearerSession`, `endBearerSession`; `cookieSessions: false` (`IRelyingPartyBearerOnlySessionsOptions`) runs bearer hand-off alone, without cookies or a CSRF key. |
1234
+ | `RelyingPartySessions<TPrincipal>` | Login start (with an application intent and a prompt)/complete/abandon/finalize, `openSession` (with a shorter lifetime), `resolveCookieSession`, `revalidateSession`, `revalidateLiveSession`, `isSessionLive`, `validateCsrf`, `logout`/`endSession`, `endSessionsOfPrincipal`, `eraseSessionsOfPrincipal` (deleting an account), `sessionsOfPrincipal` (paged), `liveProviderToken` (with `rejectedAccessToken`). Principals give `isActive` or `resolve` (`IRelyingPartyPrincipals`, `IRelyingPartyPrincipalResolver<TPrincipal>`); with `resolve`, live sessions carry `principal`. With `bearer`: `startBearerLogin`, `bearerDeliveryOf`, `completeBearerLogin`, `abandonBearerLogin`, `openBearerHandoff` (pairing a device from a live provider login), `claimBearerHandoff`, `refreshBearerTokens`, `resolveBearerAccessToken`, `resolveBearerSession`, `endBearerSession`; `cookieSessions: false` (`IRelyingPartyBearerOnlySessionsOptions`) runs bearer hand-off alone, without cookies or a CSRF key. |
1092
1235
  | `AuthorityObserver`, `AUTHORITY_FORCED_REFRESH_INTERVAL_MS` | Live organization authority with opt-in positive and negative reuse. An inactive answer rotates the session's token, at most once per interval, before it refuses. |
1093
1236
  | `RelyingPartyRoutes` | `handle(ctx)` for `/auth/login`, `/auth/callback`, `/auth/finalize`, `/auth/session` and `/auth/logout`; `null` for anything else. Takes a typedserver route context. `onLogout` is awaited after a CSRF-checked logout ended the session. In bearer mode also `/auth/bearer/login`, `/auth/bearer/claim`, `/auth/bearer/refresh`, `/auth/bearer/session` and `/auth/bearer/logout`, with CORS for the popup origins only; in bearer-only mode `/auth/login`, `/auth/finalize`, `/auth/session` and `/auth/logout` answer `null`. |
1094
1237
  | `createActorScope()` | AsyncLocalStorage actor context with a TypedRouter request scope. |
@@ -1096,6 +1239,9 @@ const delivery = await readBearerDelivery(await fetch(callback, { redirect: 'man
1096
1239
  | `SecretBox`, `deriveCsrfToken()`, `decodeSecretKey()`, `parseCookies()`, `serializeCookie()`, `sanitizeReturnPath()` | The primitives underneath. |
1097
1240
  | `pkceChallengeOf()`, `verifyPkceChallenge()`, `parseBearerAuthorization()`, `isBearerReturnTargetAllowed()`, `RELYING_PARTY_BEARER_MESSAGE_TYPE`, `BEARER_HANDOFF_MAX_AGE_SECONDS` | The bearer primitives: S256, the `Authorization` header, the return-target match and the popup message type. |
1098
1241
  | `IRelyingPartyBearerTokenAnswer`, `IRelyingPartyBearerSessionAnswer`, `IRelyingPartyBearerLogoutAnswer`, `IRelyingPartyBearerErrorAnswer`, `TRelyingPartyBearerErrorCode`, `IRelyingPartyBearerMessage` | The HTTP answers of the bearer routes and the popup message, shared with `@idp.global/sdk/browser`. |
1242
+ | `IRelyingPartyBearerLoginQuery`, `IRelyingPartyBearerClaimRequest`, `IRelyingPartyBearerRefreshRequest`, `IRelyingPartyBearerLogoutRequest` | The requests of the bearer routes: the `bearer/login` query and the JSON bodies, shared with `@idp.global/sdk/browser`. |
1243
+ | `IRelyingPartyBearerHandoffOpening` | What `openBearerHandoff` answers: the paired session, its code and when the code expires. |
1244
+ | `IRelyingPartySessionsErasure` | What `eraseSessionsOfPrincipal` answers: how many sessions it ended, and how many sessions, login attempts, bearer hand-offs and token generations it deleted. |
1099
1245
  | `RelyingPartyError`, `RelyingPartyRefusal`, `LoginCallbackError`, `AuthorityTokenError`, `AuthorityRefusedError`, `RelyingPartyDatabaseUnavailableError` | Errors with stable codes; none carries token material. A `RelyingPartyRefusal` may name the application's `location` for the browser. |
1100
1246
  | `RelyingPartyProviderDouble` (`/relyingparty/testing`) | An in-process idp.global for an application's tests: personas, live organization roles, single-use codes, rotating and reuse-detecting refresh tokens, recorded calls and injectable failures. `createBearerPkcePair()` and `readBearerDelivery()` for bearer clients. |
1101
1247
 
@@ -3,6 +3,6 @@
3
3
  */
4
4
  export const commitinfo = {
5
5
  name: '@idp.global/sdk',
6
- version: '19.4.0',
6
+ version: '19.5.0',
7
7
  description: 'Reusable browser and server SDK for idp.global authentication.'
8
8
  }