@idp.global/sdk 19.2.0 → 19.3.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.
@@ -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, IRelyingPartyHooks, IRelyingPartyLiveSession, IRelyingPartyLoginOptions, IRelyingPartyLoginStart, IRelyingPartySession, IRelyingPartySessionOpening, IResolvedRelyingPartySession, TRelyingPartyPrincipals, TRelyingPartySessionEndReason } from './interfaces.js';
3
+ import type { IAuthorityTokenSource, IProviderToken, IRelyingPartyBearerDelivery, IRelyingPartyBearerHandoff, IRelyingPartyBearerLoginRequest, IRelyingPartyBearerLoginStart, IRelyingPartyBearerOptions, IRelyingPartyBearerReturnTargets, IRelyingPartyBearerTokens, IRelyingPartyHooks, IRelyingPartyLiveSession, IRelyingPartyLoginOptions, IRelyingPartyLoginStart, IRelyingPartySession, IRelyingPartySessionOpening, 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. */
@@ -9,6 +9,10 @@ export declare const RELYING_PARTY_DEFAULT_CSRF_LABEL: string;
9
9
  export declare const LOGIN_ATTEMPT_MAX_AGE_SECONDS: number;
10
10
  /** The longest intent a login carries (`IRelyingPartyLoginOptions.intent`), in characters. */
11
11
  export declare const RELYING_PARTY_MAX_INTENT_LENGTH = 4096;
12
+ /** How long a bearer hand-off code can be claimed, at most; never past its session. */
13
+ export declare const BEARER_HANDOFF_MAX_AGE_SECONDS = 60;
14
+ /** How long a bearer access token lives unless `bearer.accessTokenMaxAgeSeconds` says otherwise. */
15
+ export declare const RELYING_PARTY_DEFAULT_BEARER_ACCESS_TOKEN_MAX_AGE_SECONDS: number;
12
16
  /**
13
17
  * How long ending a session waits for the provider to take its tokens back.
14
18
  * The local session is already revoked when that call runs.
@@ -50,6 +54,11 @@ export interface IRelyingPartySessionsOptions<TPrincipal extends object | undefi
50
54
  };
51
55
  /** the prefix of the login routes; a login never returns into it */
52
56
  loginPathPrefix?: string;
57
+ /**
58
+ * absent: no bearer hand-off mode. Needs `provider` and the bearer models
59
+ * (`createRelyingPartyModels` binds them).
60
+ */
61
+ bearer?: IRelyingPartyBearerOptions;
53
62
  hooks?: IRelyingPartyHooks;
54
63
  /** the clock every comparison reads; tests step it instead of sleeping */
55
64
  now?: () => number;
@@ -79,6 +88,10 @@ export declare class RelyingPartySessions<TPrincipal extends object | undefined
79
88
  constructor(optionsArg: IRelyingPartySessionsOptions<TPrincipal>);
80
89
  /** Whether provider logins are offered at all. */
81
90
  get providerLoginEnabled(): boolean;
91
+ /** Whether bearer hand-off mode is offered. */
92
+ get bearerLoginEnabled(): boolean;
93
+ /** The return targets bearer clients may name, per kind, as configured; `undefined` without bearer mode. */
94
+ get bearerReturnTargets(): Readonly<Required<IRelyingPartyBearerReturnTargets>> | undefined;
82
95
  /**
83
96
  * How long one replica holds the right to rotate a session's tokens. The
84
97
  * provider detects reuse of a superseded refresh token and kills the family,
@@ -157,6 +170,65 @@ export declare class RelyingPartySessions<TPrincipal extends object | undefined
157
170
  * session this very attempt created.
158
171
  */
159
172
  finalizeLogin(cookieHeaderArg: string | null | undefined): Promise<string>;
173
+ /**
174
+ * Starts a bearer login for one of the application's own clients: the same
175
+ * provider login as `startLogin`, but the outcome goes to the return target
176
+ * the client named — exactly one of the configured targets of its kind —
177
+ * and it sets no cookie. The login is bound to the client's S256 challenge
178
+ * instead of a browser: whoever claims its hand-off code has to present the
179
+ * verifier. Every field of the request is checked as untrusted input.
180
+ */
181
+ startBearerLogin(requestArg: IRelyingPartyBearerLoginRequest, optionsArg?: IRelyingPartyLoginOptions): Promise<IRelyingPartyBearerLoginStart>;
182
+ /**
183
+ * Where the outcome of a login callback goes when it belongs to a bearer
184
+ * login: the client kind, the return target and the client's `state`, read
185
+ * without consuming anything. `null` for a cookie login, an unknown state,
186
+ * and a return target that is no longer configured — the callback is then
187
+ * not answered as a bearer login at all.
188
+ */
189
+ bearerDeliveryOf(callbackUrlArg: URL): Promise<IRelyingPartyBearerDelivery | null>;
190
+ /**
191
+ * Consumes a bearer login's attempt exactly once, exchanges the code, admits
192
+ * the principal and opens its session — everything `completeLogin` does,
193
+ * with the same failures — and answers a single-use hand-off code bound to
194
+ * the client's challenge. The code lives `BEARER_HANDOFF_MAX_AGE_SECONDS`
195
+ * at most and only its hash is stored. A code nobody claims ends its session.
196
+ */
197
+ completeBearerLogin(callbackUrlArg: URL): Promise<IRelyingPartyBearerHandoff>;
198
+ /** `abandonLogin` for a bearer login: the provider came back without a code. */
199
+ abandonBearerLogin(callbackUrlArg: URL): Promise<void>;
200
+ /**
201
+ * Trades a hand-off code and the verifier of its challenge for the first
202
+ * access and refresh token of the session. The code is consumed by the first
203
+ * claim whatever its verifier: a wrong verifier ends the session, and so
204
+ * does the code coming back after it was claimed (RFC 6749 §4.1.2). A code
205
+ * that expired unclaimed ends its session too.
206
+ */
207
+ claimBearerHandoff(codeArg: unknown, codeVerifierArg: unknown): Promise<IRelyingPartyBearerTokens>;
208
+ /**
209
+ * Rotates a bearer session's tokens: the refresh token is spent, a new
210
+ * access and refresh token answer, and the old access token stops working.
211
+ * Rotation is strict — a client serializes its refreshes — because a
212
+ * refresh token that comes back after it was spent ends the whole session.
213
+ * The provider login is checked on the way: a login idp.global ended ends
214
+ * the session here (`invalid_bearer_grant`), an unreachable provider fails
215
+ * with `AuthorityTokenError('authority_unavailable')` and spends nothing.
216
+ */
217
+ refreshBearerTokens(refreshTokenArg: unknown): Promise<IRelyingPartyBearerTokens>;
218
+ /**
219
+ * The live session behind a bearer access token, or `null`: the token of the
220
+ * session's current generation, not expired, its session live and its
221
+ * principal active. A read touches the session at most once a minute.
222
+ */
223
+ resolveBearerAccessToken(accessTokenArg: unknown): Promise<IRelyingPartyLiveSession<TPrincipal> | null>;
224
+ /** `resolveBearerAccessToken` for an `Authorization: Bearer <token>` header. */
225
+ resolveBearerSession(authorizationHeaderArg: string | null | undefined): Promise<IRelyingPartyLiveSession<TPrincipal> | null>;
226
+ /**
227
+ * Ends the session of a bearer token — a live access token or the current
228
+ * refresh token — like `endSession`. A refresh token that was already spent
229
+ * is reuse and ends the session as such. Answers whether this call ended it.
230
+ */
231
+ endBearerSession(tokenArg: unknown): Promise<boolean>;
160
232
  /**
161
233
  * An access token of this login session that is usable right now. A token
162
234
  * within `ACCESS_TOKEN_REFRESH_SKEW_MS` of its expiry — or one whose expiry
@@ -174,13 +246,40 @@ export declare class RelyingPartySessions<TPrincipal extends object | undefined
174
246
  */
175
247
  private tokenAfterForeignRefresh;
176
248
  private requireProvider;
249
+ private requireBearer;
250
+ private checkLoginOptions;
251
+ /** An unsaved attempt with its state, nonce and sealed verifier; the caller binds it and names where it returns. */
252
+ private newLoginAttempt;
253
+ /**
254
+ * The provider half of a consumed attempt: exchanges the code, admits the
255
+ * principal and opens the session. Nothing of a failed login survives: its
256
+ * tokens are handed back before the failure leaves.
257
+ */
258
+ private openProviderLogin;
177
259
  private newSessionDoc;
178
260
  private csrfTokenOf;
179
261
  private opening;
180
262
  private snapshot;
181
263
  /** A session document that is live right now with its active principal, touched at most once a minute. */
182
264
  private liveSession;
265
+ /**
266
+ * Stores the session of a provider login and links it to its attempt.
267
+ * `beforeOpenedArg` stores what the session is handed out with besides its
268
+ * cookie; like the hook after it, a throw discards the session.
269
+ */
183
270
  private createProviderSession;
271
+ /** Where a bearer attempt's outcome goes, while its return target is still configured; `null` otherwise. */
272
+ private bearerDeliveryOfAttempt;
273
+ /** Stores the next token generation of a live session and answers its tokens; none of them is stored in the clear. */
274
+ private issueBearerTokens;
275
+ /** A spent hand-off code or refresh token came back: whoever holds it, the session ends. */
276
+ private bearerCredentialReused;
277
+ /**
278
+ * Takes a hand-off whose code expired unclaimed and ends its session, which
279
+ * nothing can reach any more. The caller has read it expired; expiry never
280
+ * moves, so only a claim in between can stop this.
281
+ */
282
+ private endUnclaimedHandoff;
184
283
  /** Revokes a session that was never handed out and erases its sealed tokens. */
185
284
  private discardUnopenedSession;
186
285
  /**
@@ -219,6 +318,14 @@ export declare class RelyingPartySessions<TPrincipal extends object | undefined
219
318
  * start. A sweep that cannot run never blocks a sign-in.
220
319
  */
221
320
  private sweepExpiredAttempts;
321
+ /**
322
+ * One bounded page per bearer login start, oldest first: hand-offs whose
323
+ * code expired unclaimed end their session, and hand-offs and token
324
+ * generations an hour past their expiry are removed — an unclaimed hand-off
325
+ * only after its session was ended. A sweep that cannot run never blocks a
326
+ * sign-in.
327
+ */
328
+ private sweepBearerState;
222
329
  /**
223
330
  * Reports one diagnostic. Every cleanup step reports through here, so a
224
331
  * throwing sink must not end it: the event and the sink's failure go to