@web-ts-toolkit/express-oidc-vault 0.47.1 → 0.49.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/README.md +994 -75
- package/index.d.mts +423 -32
- package/index.d.ts +423 -32
- package/index.js +1972 -390
- package/index.mjs +1965 -384
- package/package.json +5 -3
package/index.d.ts
CHANGED
|
@@ -3,6 +3,97 @@ import { KeyObject } from 'node:crypto';
|
|
|
3
3
|
import { JWK } from 'jose';
|
|
4
4
|
|
|
5
5
|
type OidcVaultRouteName = 'login' | 'callback' | 'exchange' | 'refresh' | 'logout' | 'backchannel-logout';
|
|
6
|
+
/** Enabling the option defaults to `optional`; omitting it keeps bearer behavior. */
|
|
7
|
+
type OidcVaultDeviceBindingMode = 'optional' | 'required';
|
|
8
|
+
/** DPoP proof algorithms, independent of the app-local access token's signing algorithm. */
|
|
9
|
+
type OidcVaultDpopAlgorithm = 'ES256' | 'PS256' | 'RS256';
|
|
10
|
+
/**
|
|
11
|
+
* Immutable persisted sender constraint. `jkt` is the canonical RFC 7638
|
|
12
|
+
* SHA-256 JWK thumbprint (43 base64url characters). Store no JWK, private key,
|
|
13
|
+
* proof algorithm, or historical enforcement mode in this record.
|
|
14
|
+
*/
|
|
15
|
+
interface OidcVaultDpopBinding {
|
|
16
|
+
type: 'dpop';
|
|
17
|
+
jkt: string;
|
|
18
|
+
}
|
|
19
|
+
/** Verified request context; `alg` is checked against the current proof policy. */
|
|
20
|
+
interface OidcVaultVerifiedDpopBinding extends OidcVaultDpopBinding {
|
|
21
|
+
alg: OidcVaultDpopAlgorithm;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Optional stateless, key/context-bound DPoP nonce policy. Challenges are issued
|
|
25
|
+
* only after other proof/target checks and before replay reservation. Any
|
|
26
|
+
* authentic live nonce permits parallel fresh proofs; it does not replace the
|
|
27
|
+
* normal iat window or single-use JTI reservation. Shared instances need the
|
|
28
|
+
* same secret; rotation requires a new challenge, with no previous-secret list.
|
|
29
|
+
*/
|
|
30
|
+
interface OidcVaultDpopNonceOptions {
|
|
31
|
+
/** Shared random secret of at least 32 bytes, copied at construction. */
|
|
32
|
+
secret: Uint8Array;
|
|
33
|
+
/** Integer lifetime in seconds, 1–300; default 60. */
|
|
34
|
+
lifetimeSeconds?: number;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Shared RFC 9449 proof profile for vault POSTs and request-aware APIs.
|
|
38
|
+
* Proofs are limited to 8192 wire bytes and 2048 decoded protected-header/JWK
|
|
39
|
+
* bytes, use typ dpop+jwt and public-only asymmetric keys, and require exact
|
|
40
|
+
* method/pinned normalized URL plus a signed printable ASCII JTI (1–128 bytes).
|
|
41
|
+
* Signature verification precedes claims; strict iat validity is
|
|
42
|
+
* nowSeconds - age - skew < iat <= nowSeconds + skew. APIs additionally match
|
|
43
|
+
* original verified cnf.jkt and SHA-256 ath of the ASCII access token.
|
|
44
|
+
*/
|
|
45
|
+
interface OidcVaultDpopProofOptions {
|
|
46
|
+
/** Nonempty asymmetric allowlist; default `['ES256']` (P-256). RSA proofs require 2048–4096 bits. */
|
|
47
|
+
algorithms?: readonly OidcVaultDpopAlgorithm[];
|
|
48
|
+
/** Integer maximum proof age in seconds, 1–300; default 60. */
|
|
49
|
+
proofMaxAgeSeconds?: number;
|
|
50
|
+
/** Integer clock tolerance in seconds, 0–30; default 5. */
|
|
51
|
+
clockSkewSeconds?: number;
|
|
52
|
+
/** Off by default. Challenges are at most 512 bytes; retry once with a fresh proof, never reuse its JTI. */
|
|
53
|
+
nonce?: false | OidcVaultDpopNonceOptions;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Opt-in sender constraint. `optional` permits legacy unbound records without
|
|
57
|
+
* enrolling them from a later proof; `required` rejects unbound use. Persisted
|
|
58
|
+
* bound records never downgrade when the option or a proof is omitted.
|
|
59
|
+
*/
|
|
60
|
+
interface OidcVaultDeviceBindingOptions extends OidcVaultDpopProofOptions {
|
|
61
|
+
/** Default optional when configured. Required rejects unbound use; there is no legacy downgrade switch. */
|
|
62
|
+
mode?: OidcVaultDeviceBindingMode;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Opt-in, vendor-independent browser recognition/change detection, NOT proof of
|
|
66
|
+
* possession. A copyable signal never satisfies required DPoP or constrains API
|
|
67
|
+
* access. POST login alone enrolls a supplied signal; absence is intentionally
|
|
68
|
+
* unenrolled. Callback stores only SHA-256 in reserved session metadata.
|
|
69
|
+
*/
|
|
70
|
+
interface OidcVaultFingerprintRecognitionOptions {
|
|
71
|
+
/**
|
|
72
|
+
* HTTP field name; default X-Device-Fingerprint. Must not collide with auth,
|
|
73
|
+
* cookie, origin, content, or transport headers. One raw field with a nonempty
|
|
74
|
+
* printable ASCII value, at most 256 bytes; no trimming or normalization.
|
|
75
|
+
* Malformed/duplicate/oversized opted-in signals return 400
|
|
76
|
+
* OIDC_VAULT_INVALID_FINGERPRINT before credential work.
|
|
77
|
+
*/
|
|
78
|
+
headerName?: string;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Request-aware API sender constraint. Every API accepting bound JWTs must
|
|
82
|
+
* enforce this policy; signature-only validation does not prove possession.
|
|
83
|
+
* Construction snapshots plain options, URLs, algorithms and nonce bytes.
|
|
84
|
+
*/
|
|
85
|
+
interface OidcVaultApiDeviceBindingOptions extends OidcVaultDeviceBindingOptions {
|
|
86
|
+
/** Static HTTPS origin (loopback HTTP development allowed); never derived from Host/proxy headers. */
|
|
87
|
+
publicOrigin: string;
|
|
88
|
+
/** External mount prefix stripped by a proxy, normalized at construction; default empty. No query/fragment. */
|
|
89
|
+
publicPathPrefix?: string;
|
|
90
|
+
/** Shared static printable ASCII protection-space label, 1–128 bytes; never a token, route or instance ID. */
|
|
91
|
+
replayNamespace: string;
|
|
92
|
+
/** Explicit shared atomic service, normally the vault store. No per-middleware fallback. */
|
|
93
|
+
replayStore: OidcVaultDpopReplayStore;
|
|
94
|
+
/** Epoch-millisecond clock for proof age/nonce/replay; default Date.now. Shared instances need synchronized clocks. */
|
|
95
|
+
now?: () => number;
|
|
96
|
+
}
|
|
6
97
|
interface OidcVaultUserProfile {
|
|
7
98
|
sub: string;
|
|
8
99
|
email?: string;
|
|
@@ -11,15 +102,19 @@ interface OidcVaultUserProfile {
|
|
|
11
102
|
[key: string]: unknown;
|
|
12
103
|
}
|
|
13
104
|
/**
|
|
14
|
-
* Stored session identity. Exchange, refresh, and
|
|
15
|
-
*
|
|
105
|
+
* Stored session identity. Exchange, refresh, and logout compare each defined
|
|
106
|
+
* field verbatim against resolved middleware config before use. Opt-in/guarded
|
|
107
|
+
* exchange checks before code consumption; built-in logout also checks the
|
|
108
|
+
* surviving lineage through unexpired aliases before proof or deletion.
|
|
16
109
|
* Known mismatches fail with 401 `OIDC_VAULT_INVALID_SESSION` without changing
|
|
17
110
|
* the session or cookie. Issuer trailing-slash variants are distinct.
|
|
18
111
|
*
|
|
19
112
|
* Omitted fields remain legacy-compatible and are not backfilled by refresh.
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
113
|
+
* Use separate session/alias, exchange-code, and transaction namespaces for
|
|
114
|
+
* complete isolation. Disabled legacy bearer exchange retains its historical
|
|
115
|
+
* consume-before-identity ordering; old custom bearer stores without revocation
|
|
116
|
+
* context retain their legacy alias behavior. Missing identifiers are not an
|
|
117
|
+
* isolation guarantee.
|
|
23
118
|
*/
|
|
24
119
|
interface OidcVaultProviderMetadata {
|
|
25
120
|
issuer?: string;
|
|
@@ -36,6 +131,8 @@ interface OidcVaultSession {
|
|
|
36
131
|
subject: string;
|
|
37
132
|
providerSessionId?: string;
|
|
38
133
|
provider?: OidcVaultProviderMetadata;
|
|
134
|
+
/** Original login-selected sender constraint, enforced before exchange/refresh/logout (including aliases); never enrolled by a later proof. */
|
|
135
|
+
deviceBinding?: OidcVaultDpopBinding;
|
|
39
136
|
refreshToken: string;
|
|
40
137
|
idToken: string;
|
|
41
138
|
accessToken?: string;
|
|
@@ -70,6 +167,11 @@ interface OidcVaultSession {
|
|
|
70
167
|
* serialization round-trips, so callers must not rely on object identity,
|
|
71
168
|
* custom prototypes, functions, symbols, Dates, Maps, Sets, undefined object
|
|
72
169
|
* properties, or other runtime-only values surviving persistence.
|
|
170
|
+
* `oidcVaultFingerprintRecognition` is reserved: `{ version: 1, hash }` is
|
|
171
|
+
* immutable login-selected SHA-256 recognition evidence, never raw signal
|
|
172
|
+
* data. Core preserves it through callback/refresh and removes it from token
|
|
173
|
+
* issuer input and public profiles/responses. Disclose collection/retention;
|
|
174
|
+
* it lasts with the transaction/session, not the local access-token lifetime.
|
|
73
175
|
*/
|
|
74
176
|
metadata?: Record<string, unknown>;
|
|
75
177
|
}
|
|
@@ -79,9 +181,19 @@ interface AuthorizationTransactionInput {
|
|
|
79
181
|
pkceVerifier: string;
|
|
80
182
|
codeChallenge: string;
|
|
81
183
|
returnTo?: string;
|
|
184
|
+
/** Login-selected sender constraint, never reconstructed from a later proof. */
|
|
185
|
+
deviceBinding?: OidcVaultDpopBinding;
|
|
186
|
+
/** SHA-256 hash of the temporary HttpOnly browser-binding cookie; never store the cookie secret. */
|
|
187
|
+
browserBindingHash?: string;
|
|
82
188
|
createdAt: number;
|
|
83
189
|
expiresAt: number;
|
|
84
|
-
/**
|
|
190
|
+
/**
|
|
191
|
+
* See `OidcVaultSession.metadata` for the portable value domain. POST login
|
|
192
|
+
* reserves `oidcVaultTransactionProvider` for its resolved issuer/clientId;
|
|
193
|
+
* stores must preserve it for callback identity preflight. Opted-in POST login
|
|
194
|
+
* also carries immutable `oidcVaultFingerprintRecognition` for callback
|
|
195
|
+
* session creation; no raw fingerprint signal is stored.
|
|
196
|
+
*/
|
|
85
197
|
metadata?: Record<string, unknown>;
|
|
86
198
|
}
|
|
87
199
|
type AuthorizationTransaction = AuthorizationTransactionInput;
|
|
@@ -89,6 +201,10 @@ interface ExchangeCodeRecordInput {
|
|
|
89
201
|
code: string;
|
|
90
202
|
sessionId: string;
|
|
91
203
|
returnTo?: string;
|
|
204
|
+
/** Copied from the authenticated login transaction; must agree with the session. */
|
|
205
|
+
deviceBinding?: OidcVaultDpopBinding;
|
|
206
|
+
/** Copied transaction-cookie hash; guarded exchange matches both cookie and key. */
|
|
207
|
+
browserBindingHash?: string;
|
|
92
208
|
createdAt: number;
|
|
93
209
|
expiresAt: number;
|
|
94
210
|
}
|
|
@@ -99,6 +215,7 @@ interface OidcVaultSessionInput extends Omit<OidcVaultSession, 'createdAt' | 'up
|
|
|
99
215
|
}
|
|
100
216
|
interface RotateSessionInput {
|
|
101
217
|
sessionId: string;
|
|
218
|
+
/** Omitted binding inherits the source; changing its key or enrolling an unbound source is rejected. */
|
|
102
219
|
nextSession: OidcVaultSession;
|
|
103
220
|
}
|
|
104
221
|
interface DeleteSessionsBySubjectInput {
|
|
@@ -119,9 +236,72 @@ interface ConsumeBackchannelLogoutTokenJtiInput {
|
|
|
119
236
|
/** Finite future epoch-millisecond expiry. Values `<= now` are expired. */
|
|
120
237
|
expiresAt: number;
|
|
121
238
|
}
|
|
239
|
+
/**
|
|
240
|
+
* Complete guarded-record match. Explicit `null` requires an absent/undefined
|
|
241
|
+
* stored field; it never means ignore the field. Both fields are mandatory.
|
|
242
|
+
* Valid persisted shapes are legacy (neither field), cookie-only (hash), or
|
|
243
|
+
* bound (hash + key). Stored null/malformed fields and a key without a hash
|
|
244
|
+
* are invalid. Both hashes use canonical 43-character SHA-256 base64url.
|
|
245
|
+
*/
|
|
246
|
+
interface OidcVaultRecordBindingMatch {
|
|
247
|
+
deviceBinding: OidcVaultDpopBinding | null;
|
|
248
|
+
browserBindingHash: string | null;
|
|
249
|
+
}
|
|
250
|
+
interface ConsumeAuthorizationTransactionIfMatchesInput {
|
|
251
|
+
state: string;
|
|
252
|
+
match: OidcVaultRecordBindingMatch;
|
|
253
|
+
}
|
|
254
|
+
interface ConsumeExchangeCodeIfMatchesInput {
|
|
255
|
+
code: string;
|
|
256
|
+
/** Session ID from preflight, included in the atomic consume comparison. */
|
|
257
|
+
expectedSessionId: string;
|
|
258
|
+
match: OidcVaultRecordBindingMatch;
|
|
259
|
+
}
|
|
260
|
+
interface ReserveDpopProofInput {
|
|
261
|
+
/** Opaque `dpop:v1:` + SHA-256 base64url of JSON([effectiveNamespace, jkt, jti]), supplied after proof/target/nonce checks. */
|
|
262
|
+
replayKey: string;
|
|
263
|
+
/** Future safe-integer epoch milliseconds; maximum remaining TTL 360000 ms. */
|
|
264
|
+
expiresAt: number;
|
|
265
|
+
}
|
|
266
|
+
/**
|
|
267
|
+
* Shared atomic per-request replay admission; no implicit per-core-instance
|
|
268
|
+
* memory fallback. Independent memory-store objects are not shared protection.
|
|
269
|
+
* Shared instances need identical protection spaces/proof windows and synchronized
|
|
270
|
+
* clocks. Never release a reservation after a later route/issuer failure.
|
|
271
|
+
*/
|
|
272
|
+
interface OidcVaultDpopReplayStore {
|
|
273
|
+
/**
|
|
274
|
+
* Reserve once through expiry. Duplicate/invalid/expired input returns false
|
|
275
|
+
* without extending expiry or allocating state. Capacity/provider failures
|
|
276
|
+
* throw; callers must fail closed, never evict live reservations. Built-ins
|
|
277
|
+
* default to 100000 entries per shared namespace. Expired entries awaiting
|
|
278
|
+
* bounded cleanup may conservatively occupy capacity. Duplicate detection
|
|
279
|
+
* precedes capacity rejection; capacity throws `OidcVaultDpopReplayCapacityError`.
|
|
280
|
+
*/
|
|
281
|
+
reserveDpopProof(input: ReserveDpopProofInput): Promise<boolean>;
|
|
282
|
+
}
|
|
283
|
+
/**
|
|
284
|
+
* Detached revocation authority for a currently live lineage, resolved through
|
|
285
|
+
* a live handle or unexpired rotation alias. Never authenticates an alias and
|
|
286
|
+
* contains no tokens, profile, metadata, or provider fields beyond issuer/clientId.
|
|
287
|
+
* Inconsistent/malformed lineage binding or identity throws a private diagnostic.
|
|
288
|
+
*/
|
|
289
|
+
interface OidcVaultSessionRevocationContext {
|
|
290
|
+
logicalSessionId: string;
|
|
291
|
+
provider?: OidcVaultProviderMetadata;
|
|
292
|
+
deviceBinding?: OidcVaultDpopBinding;
|
|
293
|
+
}
|
|
122
294
|
declare class OidcVaultStoreConflictError extends Error {
|
|
123
295
|
constructor(message?: string);
|
|
124
296
|
}
|
|
297
|
+
/**
|
|
298
|
+
* Shared DPoP replay capacity is exhausted. No live reservation is evicted and
|
|
299
|
+
* no proof is admitted without replay state. Handle like any replay-store
|
|
300
|
+
* failure: fail closed; expose only the sanitized replay-unavailable error.
|
|
301
|
+
*/
|
|
302
|
+
declare class OidcVaultDpopReplayCapacityError extends Error {
|
|
303
|
+
constructor(message?: string);
|
|
304
|
+
}
|
|
125
305
|
/**
|
|
126
306
|
* Portable store boundary for JSON-compatible plain objects/arrays and scalar
|
|
127
307
|
* values (strings, finite numbers, booleans, null). Built-in providers capture
|
|
@@ -140,10 +320,20 @@ declare class OidcVaultStoreConflictError extends Error {
|
|
|
140
320
|
interface OidcVaultStoreProvider {
|
|
141
321
|
/** Upsert an authorization transaction by `state`. */
|
|
142
322
|
createAuthorizationTransaction(input: AuthorizationTransactionInput): Promise<void>;
|
|
323
|
+
/** Legacy consume: refuses guarded (cookie/key-bound) records without consuming them. */
|
|
143
324
|
consumeAuthorizationTransaction(state: string): Promise<AuthorizationTransaction | null>;
|
|
325
|
+
/** Optional opt-in capability: detached live preflight snapshot, not a lock. */
|
|
326
|
+
getAuthorizationTransaction?(state: string): Promise<AuthorizationTransaction | null>;
|
|
327
|
+
/** Optional opt-in capability: atomic expiry + complete exact/null match + consume; mismatch leaves the record live. */
|
|
328
|
+
consumeAuthorizationTransactionIfMatches?(input: ConsumeAuthorizationTransactionIfMatchesInput): Promise<AuthorizationTransaction | null>;
|
|
144
329
|
/** Upsert an exchange code record by `code`. */
|
|
145
330
|
createExchangeCode(input: ExchangeCodeRecordInput): Promise<void>;
|
|
331
|
+
/** Legacy consume: refuses guarded (cookie/key-bound) records without consuming them. */
|
|
146
332
|
consumeExchangeCode(code: string): Promise<ExchangeCodeRecord | null>;
|
|
333
|
+
/** Optional opt-in capability: detached live preflight snapshot, not a lock. */
|
|
334
|
+
getExchangeCode?(code: string): Promise<ExchangeCodeRecord | null>;
|
|
335
|
+
/** Optional opt-in capability: atomically match the session ID and both binding fields before consuming. */
|
|
336
|
+
consumeExchangeCodeIfMatches?(input: ConsumeExchangeCodeIfMatchesInput): Promise<ExchangeCodeRecord | null>;
|
|
147
337
|
/**
|
|
148
338
|
* Create a session by `sessionId`, defaulting timestamps and logical lineage when omitted.
|
|
149
339
|
*
|
|
@@ -166,12 +356,19 @@ interface OidcVaultStoreProvider {
|
|
|
166
356
|
*/
|
|
167
357
|
createSession(input: OidcVaultSessionInput): Promise<OidcVaultSession>;
|
|
168
358
|
getSession(sessionId: string): Promise<OidcVaultSession | null>;
|
|
359
|
+
/** Optional opt-in capability: resolve only a currently live lineage, including through unexpired aliases. No upstream tokens. */
|
|
360
|
+
getSessionRevocationContext?(sessionId: string): Promise<OidcVaultSessionRevocationContext | null>;
|
|
361
|
+
/** Optional opt-in capability; see `OidcVaultDpopReplayStore.reserveDpopProof`. */
|
|
362
|
+
reserveDpopProof?(input: ReserveDpopProofInput): Promise<boolean>;
|
|
169
363
|
/**
|
|
170
364
|
* Atomically replace an existing session with a distinct unused `nextSession.sessionId`.
|
|
171
365
|
*
|
|
172
366
|
* Providers preserve the existing logical session ID when the next session omits
|
|
173
|
-
* one
|
|
174
|
-
*
|
|
367
|
+
* one, inherit the original device binding when omitted, and reject changing
|
|
368
|
+
* a bound key or adding binding to an unbound source without mutation. Null or
|
|
369
|
+
* malformed security fields are invalid, never legacy. Retain the old public
|
|
370
|
+
* session ID as an in-flight-request revocation alias. Rotation itself does
|
|
371
|
+
* not revoke the lineage. Providers throw
|
|
175
372
|
* `OidcVaultStoreConflictError` without changing source or target data when
|
|
176
373
|
* the source is missing, the target already exists, or the target ID equals
|
|
177
374
|
* the source ID.
|
|
@@ -220,6 +417,28 @@ interface OidcVaultStoreProvider {
|
|
|
220
417
|
/** Delete matching provider-session IDs, filtering by each supplied issuer/client; string input is unscoped. */
|
|
221
418
|
deleteSessionsByProviderSessionId(input: string | DeleteSessionsByProviderSessionIdInput): Promise<number>;
|
|
222
419
|
}
|
|
420
|
+
/**
|
|
421
|
+
* Required store capabilities for opt-in device binding or fingerprint
|
|
422
|
+
* recognition. All six methods are checked at vault construction, including
|
|
423
|
+
* fingerprint-only flows (which do not reserve DPoP proofs). Old bearer-only
|
|
424
|
+
* custom stores retain the base interface. Guarded reads are preflight only:
|
|
425
|
+
* providers must compare/consume atomically and preserve original binding and
|
|
426
|
+
* portable reserved recognition metadata through core's rotation inputs.
|
|
427
|
+
*/
|
|
428
|
+
interface OidcVaultDeviceBindingStoreProvider extends OidcVaultStoreProvider, OidcVaultDpopReplayStore {
|
|
429
|
+
/** Detached live snapshot, never a lock. Malformed/null binding/hash is invalid, not legacy. */
|
|
430
|
+
getAuthorizationTransaction(state: string): Promise<AuthorizationTransaction | null>;
|
|
431
|
+
/** Atomic expiry + full exact/null match + deletion. Mismatch leaves the live record available for an honest retry. */
|
|
432
|
+
consumeAuthorizationTransactionIfMatches(input: ConsumeAuthorizationTransactionIfMatchesInput): Promise<AuthorizationTransaction | null>;
|
|
433
|
+
/** Detached live preflight snapshot, without spending the code. */
|
|
434
|
+
getExchangeCode(code: string): Promise<ExchangeCodeRecord | null>;
|
|
435
|
+
/** Atomic expiry + expectedSessionId + both exact/null binding fields + deletion; no get/unconditional-delete fallback. */
|
|
436
|
+
consumeExchangeCodeIfMatches(input: ConsumeExchangeCodeIfMatchesInput): Promise<ExchangeCodeRecord | null>;
|
|
437
|
+
/** Resolve current lineage authority, never the alias's missing/historical binding; no credentials are returned. */
|
|
438
|
+
getSessionRevocationContext(sessionId: string): Promise<OidcVaultSessionRevocationContext | null>;
|
|
439
|
+
/** Atomic duplicate-first admission; false rejects the proof, capacity/provider errors fail closed with HTTP 503. */
|
|
440
|
+
reserveDpopProof(input: ReserveDpopProofInput): Promise<boolean>;
|
|
441
|
+
}
|
|
223
442
|
interface OidcVaultHookContext {
|
|
224
443
|
route: OidcVaultRouteName;
|
|
225
444
|
req: Request;
|
|
@@ -230,7 +449,7 @@ interface OidcVaultHookContext {
|
|
|
230
449
|
interface OidcVaultErrorContext extends OidcVaultHookContext {
|
|
231
450
|
/**
|
|
232
451
|
* Original private diagnostic, separate from sanitized browser JSON. Narrow
|
|
233
|
-
* before use; provider transport errors retain the original failure in
|
|
452
|
+
* before use; provider transport/replay admission errors retain the original failure in
|
|
234
453
|
* `error.cause`, while issuer-result validation supplies a TypeError directly.
|
|
235
454
|
*/
|
|
236
455
|
error: unknown;
|
|
@@ -246,18 +465,34 @@ interface OidcVaultHooks {
|
|
|
246
465
|
* After this hook, a valid earlier epoch-millisecond expiry is preserved;
|
|
247
466
|
* removal, extension, or an invalid timestamp restores the configured cap.
|
|
248
467
|
* Without `sessionTtlMs`, application/store lifetime policy is unchanged.
|
|
468
|
+
* Security-owned `deviceBinding` is restored from core's private snapshot;
|
|
469
|
+
* the hook cannot enroll, remove, or rebind a sender constraint. Guarded POST
|
|
470
|
+
* callbacks also retain their fresh session/lineage IDs and resolved provider
|
|
471
|
+
* identity independently of hook mutations. Reserved fingerprint recognition
|
|
472
|
+
* metadata is restored from the original transaction, including unenrolled
|
|
473
|
+
* absence; a hook/profile cannot enroll, strip, or rebind it. Other application
|
|
474
|
+
* metadata/profile fields remain mutable; throwing is an authenticated terminal veto.
|
|
249
475
|
*/
|
|
250
476
|
onBeforeSessionCreate?(context: OidcVaultHookContext): void | Promise<void>;
|
|
251
477
|
onSessionCreated?(context: OidcVaultHookContext): void | Promise<void>;
|
|
478
|
+
/** Post-rotation notification with owned plain session data; mutation cannot change stored/response authority or profile precedence. */
|
|
252
479
|
onSessionRefreshed?(context: OidcVaultHookContext): void | Promise<void>;
|
|
480
|
+
/** Pre-revocation veto for a live handle, after identity/proof/nonce/replay. Receives owned session data; deletion uses original lineage authority. */
|
|
253
481
|
onBeforeLogout?(context: OidcVaultHookContext): void | Promise<void>;
|
|
254
482
|
onLogout?(context: OidcVaultHookContext): void | Promise<void>;
|
|
255
483
|
onError?(context: OidcVaultErrorContext): void | Promise<void>;
|
|
256
484
|
}
|
|
257
485
|
interface IssueTokenInput {
|
|
486
|
+
/** Owned session data; reserved fingerprint recognition evidence is omitted to keep hashes out of application tokens. */
|
|
258
487
|
session: OidcVaultSession;
|
|
259
488
|
req: Request;
|
|
260
489
|
res: Response;
|
|
490
|
+
/**
|
|
491
|
+
* Authoritative verified request/key context, detached and frozen by core.
|
|
492
|
+
* Use this thumbprint for `cnf.jkt`, not mutable session/profile fields.
|
|
493
|
+
* Absent for unbound issuance; a later proof never enrolls a legacy session.
|
|
494
|
+
*/
|
|
495
|
+
deviceBinding?: Readonly<OidcVaultVerifiedDpopBinding>;
|
|
261
496
|
}
|
|
262
497
|
/**
|
|
263
498
|
* Local application credentials returned by `OidcVaultTokenIssuer.issue`.
|
|
@@ -265,18 +500,19 @@ interface IssueTokenInput {
|
|
|
265
500
|
* properties are ignored and cannot override the response's session ID/user.
|
|
266
501
|
*/
|
|
267
502
|
interface OidcVaultTokenIssueResult {
|
|
268
|
-
/** Nonempty opaque token
|
|
503
|
+
/** Nonempty opaque token for unbound issuance; bound issuance requires a compact signed JWT with matching `cnf.jkt`. */
|
|
269
504
|
accessToken: string;
|
|
270
505
|
/** Token lifetime in seconds: a finite, nonnegative safe integer (zero is valid). */
|
|
271
506
|
expiresIn: number;
|
|
272
|
-
/**
|
|
273
|
-
tokenType?: 'Bearer';
|
|
507
|
+
/** Exact `DPoP` is required when bound. Unbound permits only `Bearer` or omission; omitted/undefined stays absent in JSON. */
|
|
508
|
+
tokenType?: 'Bearer' | 'DPoP';
|
|
274
509
|
}
|
|
275
510
|
/**
|
|
276
511
|
* Trusted application token issuer for exchange and refresh. Return a non-null,
|
|
277
512
|
* non-array object satisfying `OidcVaultTokenIssueResult`; only its declared
|
|
278
513
|
* credential fields enter the response. This contains accidental extensions,
|
|
279
|
-
* not arbitrary behavior of trusted issuers/hooks with
|
|
514
|
+
* not arbitrary behavior of trusted issuers/hooks with request/response access.
|
|
515
|
+
* Core retains its own binding/lineage snapshots across issuer calls.
|
|
280
516
|
*/
|
|
281
517
|
interface OidcVaultTokenIssuer {
|
|
282
518
|
/**
|
|
@@ -284,6 +520,8 @@ interface OidcVaultTokenIssuer {
|
|
|
284
520
|
* (including the rotated refresh session), clear a cookie-transport session
|
|
285
521
|
* cookie, and return sanitized HTTP 500 / `OIDC_VAULT_INTERNAL_ERROR`.
|
|
286
522
|
* Field diagnostics are available privately through `hooks.onError`.
|
|
523
|
+
* Core decodes a bound result only to check this trusted issuer contract;
|
|
524
|
+
* APIs must independently verify signature, issuer, audience, and expiry.
|
|
287
525
|
*/
|
|
288
526
|
issue(input: IssueTokenInput): Promise<OidcVaultTokenIssueResult>;
|
|
289
527
|
}
|
|
@@ -292,12 +530,40 @@ interface OidcVaultAccessTokenValidationResult {
|
|
|
292
530
|
sessionId?: string;
|
|
293
531
|
scope?: string;
|
|
294
532
|
claims?: Record<string, unknown>;
|
|
533
|
+
/** Verified sender constraint. Legacy adapters may omit it only for genuinely unbound credentials. */
|
|
534
|
+
confirmation?: OidcVaultAccessTokenConfirmation | null;
|
|
535
|
+
}
|
|
536
|
+
/** Canonical RFC 7638 SHA-256 thumbprint derived from verified token/introspection data, never from a proof alone. */
|
|
537
|
+
interface OidcVaultAccessTokenConfirmation {
|
|
538
|
+
jkt: string;
|
|
539
|
+
}
|
|
540
|
+
interface OidcVaultAccessTokenRequestInput {
|
|
541
|
+
token: string;
|
|
542
|
+
scheme: 'Bearer' | 'DPoP';
|
|
543
|
+
req: Request;
|
|
544
|
+
}
|
|
545
|
+
/** Mandatory confirmation: null means verified unbound; missing confirmation or malformed/unsupported cnf is invalid. */
|
|
546
|
+
interface OidcVaultRequestAwareAccessTokenValidationResult extends OidcVaultAccessTokenValidationResult {
|
|
547
|
+
confirmation: OidcVaultAccessTokenConfirmation | null;
|
|
295
548
|
}
|
|
296
549
|
interface OidcVaultAuthContext extends OidcVaultAccessTokenValidationResult {
|
|
297
550
|
token: string;
|
|
551
|
+
/** Present only after original-key proof, API ath, nonce and shared replay admission all pass. */
|
|
552
|
+
deviceBinding?: Readonly<OidcVaultVerifiedDpopBinding>;
|
|
298
553
|
}
|
|
299
554
|
interface OidcVaultAccessTokenValidator {
|
|
555
|
+
/** Binding-disabled middleware invokes exactly validate(token), with one argument. Report any known confirmation. */
|
|
300
556
|
validate(token: string): Promise<OidcVaultAccessTokenValidationResult>;
|
|
557
|
+
/** Required at middleware construction when deviceBinding is enabled; called for both Bearer and DPoP. */
|
|
558
|
+
validateWithRequest?(input: OidcVaultAccessTokenRequestInput): Promise<OidcVaultRequestAwareAccessTokenValidationResult>;
|
|
559
|
+
}
|
|
560
|
+
/**
|
|
561
|
+
* Trusted adapter for verified JWT/introspection data. Faithfully report the
|
|
562
|
+
* original confirmation independently of custom mapping: null is genuinely
|
|
563
|
+
* unbound, never a malformed/unsupported cnf. The middleware owns proof checks.
|
|
564
|
+
*/
|
|
565
|
+
interface OidcVaultRequestAwareAccessTokenValidator extends OidcVaultAccessTokenValidator {
|
|
566
|
+
validateWithRequest(input: OidcVaultAccessTokenRequestInput): Promise<OidcVaultRequestAwareAccessTokenValidationResult>;
|
|
301
567
|
}
|
|
302
568
|
interface OidcVaultAccessTokenMiddlewareErrorContext {
|
|
303
569
|
error: unknown;
|
|
@@ -308,16 +574,20 @@ interface OidcVaultAccessTokenMiddlewareErrorContext {
|
|
|
308
574
|
}
|
|
309
575
|
interface OidcVaultAccessTokenMiddlewareOptions {
|
|
310
576
|
validator: OidcVaultAccessTokenValidator;
|
|
577
|
+
/** Opt-in API DPoP enforcement; requires validateWithRequest. Omission preserves the one-argument legacy path. */
|
|
578
|
+
deviceBinding?: OidcVaultApiDeviceBindingOptions;
|
|
311
579
|
/**
|
|
312
580
|
* Pre-`next()` veto hook, not a post-commit notification: when it throws,
|
|
313
581
|
* downstream middleware never runs and `req.auth` is detached before the
|
|
314
|
-
* error response is sent. A valid
|
|
315
|
-
* never surfaces as an invalid-token 401:
|
|
316
|
-
* hook keeps its own status/code/client message (a 401
|
|
317
|
-
* challenge, other statuses carry no challenge), while any other hook
|
|
582
|
+
* error response is sent. A valid credential plus a failing hook
|
|
583
|
+
* never surfaces as an invalid-token 401: a controlled package error from the
|
|
584
|
+
* hook keeps its own status/code/client message (a 401 uses the attempted
|
|
585
|
+
* scheme's challenge, other statuses carry no challenge), while any other hook
|
|
318
586
|
* error becomes a sanitized `500 OIDC_VAULT_AUTH_CONTEXT_FAILED` without
|
|
319
587
|
* leaking the original message. The original error is observable via
|
|
320
|
-
* `onError` for private server-side logs.
|
|
588
|
+
* `onError` for private server-side logs. Security-owned token/confirmation/
|
|
589
|
+
* deviceBinding and req.auth authority are restored after mutable hooks;
|
|
590
|
+
* a veto never releases an admitted proof's replay reservation.
|
|
321
591
|
*/
|
|
322
592
|
onAuthContext?(input: {
|
|
323
593
|
req: Request;
|
|
@@ -325,21 +595,25 @@ interface OidcVaultAccessTokenMiddlewareOptions {
|
|
|
325
595
|
auth: OidcVaultAuthContext;
|
|
326
596
|
}): void | Promise<void>;
|
|
327
597
|
/**
|
|
328
|
-
* Observes the original error for every
|
|
329
|
-
* (extraction, validator, and `onAuthContext`
|
|
598
|
+
* Observes the original error for every API-middleware failure
|
|
599
|
+
* (extraction, validator, proof/nonce/replay, and `onAuthContext`) without affecting
|
|
330
600
|
* the sanitized client response. Failures thrown by this observer are
|
|
331
|
-
* swallowed so the original error response is preserved.
|
|
601
|
+
* swallowed so the original error response is preserved. Replay failures
|
|
602
|
+
* retain the provider diagnostic in non-enumerable error.cause. No request
|
|
603
|
+
* auth context is attached before proof acceptance or after a veto.
|
|
332
604
|
*/
|
|
333
605
|
onError?(context: OidcVaultAccessTokenMiddlewareErrorContext): void | Promise<void>;
|
|
334
606
|
}
|
|
335
607
|
interface OidcVaultAuthenticatedRequest extends Request {
|
|
336
608
|
auth?: OidcVaultAuthContext;
|
|
337
609
|
}
|
|
610
|
+
/** Local JWT verification options, independent of the asymmetric DPoP proof policy; captured at construction. */
|
|
338
611
|
interface OidcVaultJwtAccessTokenValidatorOptions {
|
|
339
612
|
key: CryptoKey | KeyObject | JWK | Uint8Array;
|
|
340
613
|
issuer?: string;
|
|
341
614
|
audience?: string | string[];
|
|
342
615
|
algorithms?: string[];
|
|
616
|
+
/** Verified cnf is snapshotted before this mapper; mapper-supplied confirmation/deviceBinding is ignored. */
|
|
343
617
|
mapClaims?(claims: Record<string, unknown>): OidcVaultAccessTokenValidationResult;
|
|
344
618
|
}
|
|
345
619
|
declare module 'express-serve-static-core' {
|
|
@@ -373,11 +647,15 @@ interface OidcVaultConfig {
|
|
|
373
647
|
}
|
|
374
648
|
interface OidcVaultLogoutResult {
|
|
375
649
|
/**
|
|
376
|
-
* Successful
|
|
377
|
-
*
|
|
378
|
-
*
|
|
379
|
-
*
|
|
380
|
-
* a
|
|
650
|
+
* Successful logout commits revocation before upstream work and clears the
|
|
651
|
+
* session cookie under cookie transport. Built-in live handles and unexpired
|
|
652
|
+
* aliases authenticate the surviving lineage's provider/original binding;
|
|
653
|
+
* wrong identity, missing/wrong/stale/replayed proof, or disabled acceptance
|
|
654
|
+
* of a bound lineage fails without deleting or clearing. No currently live
|
|
655
|
+
* target is idempotent success without deletion or proof reservation. Aliases
|
|
656
|
+
* grant revocation only, not refresh authentication or upstream redirects.
|
|
657
|
+
* Old custom bearer stores without revocation context retain legacy alias
|
|
658
|
+
* deletion behavior. Stateless application access tokens are not invalidated.
|
|
381
659
|
* Local-only logout (`redirect` unset or `false`) never contacts the provider.
|
|
382
660
|
* Redirected logout (`redirect: true`)
|
|
383
661
|
* treats the upstream end-session redirect as best-effort: when provider
|
|
@@ -397,9 +675,38 @@ interface OidcVaultExchangeResult extends Partial<OidcVaultTokenIssueResult> {
|
|
|
397
675
|
/** Session profile; extra token-issuer result properties cannot override it. */
|
|
398
676
|
user?: OidcVaultUserProfile;
|
|
399
677
|
}
|
|
678
|
+
/** JSON body for opt-in `POST <basePath>/login`; proof/key and recognition signals belong in their configured headers, not the body. */
|
|
679
|
+
interface OidcVaultLoginInitiationInput {
|
|
680
|
+
/** Optional destination on the configured frontend origin. Query-string returnTo is ignored by POST login. */
|
|
681
|
+
returnTo?: string;
|
|
682
|
+
}
|
|
683
|
+
/**
|
|
684
|
+
* Exact successful POST-login JSON. Navigate to this URL after storing a proof
|
|
685
|
+
* key when DPoP is enabled. Use credentials: 'include' even with body session
|
|
686
|
+
* transport: initiation sets a temporary HttpOnly transaction cookie.
|
|
687
|
+
*/
|
|
688
|
+
interface OidcVaultLoginInitiationResult {
|
|
689
|
+
authorizationUrl: string;
|
|
690
|
+
}
|
|
400
691
|
type OidcVaultSessionTransport = 'body' | 'cookie';
|
|
401
692
|
type OidcVaultCookieDeploymentMode = 'same-origin' | 'same-site' | 'cross-site';
|
|
402
693
|
type OidcVaultCookieSameSite = 'lax' | 'strict' | 'none';
|
|
694
|
+
/**
|
|
695
|
+
* Temporary browser-binding cookie for POST login -> headerless callback ->
|
|
696
|
+
* guarded exchange. Always host-only, Path=/, HttpOnly, and Secure on HTTPS;
|
|
697
|
+
* no Domain/path/security opt-outs. One pending flow per cookie name: a fresh
|
|
698
|
+
* initiation replaces it. Use distinct names for multiple vault mounts.
|
|
699
|
+
*/
|
|
700
|
+
interface OidcVaultTransactionCookieOptions {
|
|
701
|
+
/**
|
|
702
|
+
* HTTP cookie token, distinct from the session cookie. HTTPS defaults to
|
|
703
|
+
* __Host-oidc_vault_transaction; loopback HTTP to oidc_vault_transaction.
|
|
704
|
+
* __Host-/__Secure- prefixes require HTTPS.
|
|
705
|
+
*/
|
|
706
|
+
name?: string;
|
|
707
|
+
/** Default lax permits the provider's top-level GET callback. Explicit none requires HTTPS for cross-site SPAs. */
|
|
708
|
+
sameSite?: 'lax' | 'none';
|
|
709
|
+
}
|
|
403
710
|
interface OidcVaultCookieOptions {
|
|
404
711
|
/**
|
|
405
712
|
* Session cookie name. Must be a valid HTTP cookie name (printable ASCII
|
|
@@ -440,8 +747,11 @@ interface OidcVaultCookieOptions {
|
|
|
440
747
|
httpOnly?: boolean;
|
|
441
748
|
}
|
|
442
749
|
interface OidcVaultOptions {
|
|
750
|
+
/** Public router mount; default /auth/oidc. DPoP vault proxies must preserve this externally visible path. */
|
|
443
751
|
basePath?: string;
|
|
752
|
+
/** Pinned public callback/proof origin. DPoP requires a static HTTPS origin, with loopback HTTP allowed for development. */
|
|
444
753
|
backendOrigin: string;
|
|
754
|
+
/** Vault persistence and, when DPoP is enabled, atomic replay admission. All six stronger capabilities are required for either opt-in feature. */
|
|
445
755
|
storeProvider: OidcVaultStoreProvider;
|
|
446
756
|
config?: OidcVaultConfig;
|
|
447
757
|
/**
|
|
@@ -455,6 +765,31 @@ interface OidcVaultOptions {
|
|
|
455
765
|
hooks?: OidcVaultHooks;
|
|
456
766
|
/** Optional local issuer; when omitted, exchange/refresh return no local token fields. */
|
|
457
767
|
tokenIssuer?: OidcVaultTokenIssuer;
|
|
768
|
+
/**
|
|
769
|
+
* Opt-in DPoP policy; absent preserves unbound bearer behavior. Present with
|
|
770
|
+
* no mode means `optional`. Requires all `OidcVaultDeviceBindingStoreProvider`
|
|
771
|
+
* capabilities and a static HTTPS `backendOrigin` (loopback HTTP development
|
|
772
|
+
* is allowed). Bound exchange/refresh/logout require a fresh original-key
|
|
773
|
+
* DPoP header before code consumption, upstream refresh, hooks or revocation;
|
|
774
|
+
* vault POSTs need no Authorization access token/ath. A supplied optional
|
|
775
|
+
* unbound proof validates/reserves but never enrolls or rebinds. Construction
|
|
776
|
+
* snapshots/freezes plain options and algorithms and copies nonce bytes.
|
|
777
|
+
*/
|
|
778
|
+
deviceBinding?: OidcVaultDeviceBindingOptions;
|
|
779
|
+
/**
|
|
780
|
+
* Separate opt-in recognition policy; omission means no signal capture/check.
|
|
781
|
+
* Enables JSON POST login and its temporary HttpOnly cookie in both session
|
|
782
|
+
* transports, even without DPoP; requires all guarded-store capabilities.
|
|
783
|
+
* POST login alone enrolls a supplied signal in reserved metadata. Enrolled
|
|
784
|
+
* exchange/refresh compare before proof admission/code consume/upstream use:
|
|
785
|
+
* missing/mismatch returns 403 OIDC_VAULT_FINGERPRINT_REAUTH_REQUIRED without
|
|
786
|
+
* mutation. Legacy/GET/absent-signal sessions remain unenrolled. Refresh never
|
|
787
|
+
* enrolls/rotates recognition; changes require fresh POST login. Logout,
|
|
788
|
+
* rotation aliases, signed backchannel logout and API recognition policy are
|
|
789
|
+
* unaffected. Disclose collection and transaction/session retention, including
|
|
790
|
+
* store cleanup/backups; hashing is not anonymization or theft prevention.
|
|
791
|
+
*/
|
|
792
|
+
fingerprintRecognition?: OidcVaultFingerprintRecognitionOptions;
|
|
458
793
|
/**
|
|
459
794
|
* Default browser return target after backend callback completion. Required
|
|
460
795
|
* if login accepts a custom `returnTo`. Remains optional at middleware
|
|
@@ -473,6 +808,7 @@ interface OidcVaultOptions {
|
|
|
473
808
|
* session). Discovery errors also reach `onError`.
|
|
474
809
|
*/
|
|
475
810
|
postLogoutRedirectUri?: string;
|
|
811
|
+
/** Default enabled when discovery/manual config has a UserInfo endpoint and the response supplies an access token; false disables it. */
|
|
476
812
|
fetchUserInfo?: boolean;
|
|
477
813
|
/**
|
|
478
814
|
* Authorization transaction lifetime in milliseconds (default: 10 minutes).
|
|
@@ -499,8 +835,27 @@ interface OidcVaultOptions {
|
|
|
499
835
|
* store-owned lifetime behavior; no default session expiry is assigned.
|
|
500
836
|
*/
|
|
501
837
|
sessionTtlMs?: number;
|
|
838
|
+
/** Default body: JSON sessionId. Cookie mode omits that handle from JSON; POST login/exchange need the temporary cookie in both modes. */
|
|
502
839
|
sessionTransport?: OidcVaultSessionTransport;
|
|
503
840
|
cookie?: OidcVaultCookieOptions;
|
|
841
|
+
/**
|
|
842
|
+
* Detached/frozen transaction-cookie settings, independent of session
|
|
843
|
+
* transport. POST login stores only SHA-256(cookie secret) and the verified
|
|
844
|
+
* initiating jkt when bound; callback authenticates and atomically spends the
|
|
845
|
+
* stored match. Guarded exchange needs this cookie in both session transports
|
|
846
|
+
* plus the original-key proof when bound. Success/authenticated terminal
|
|
847
|
+
* issuance failure clears it; mismatches and nonce challenges do not spend or
|
|
848
|
+
* clear. Cookie lifetime rounds down to the transaction/code deadline.
|
|
849
|
+
*/
|
|
850
|
+
transactionCookie?: OidcVaultTransactionCookieOptions;
|
|
851
|
+
/**
|
|
852
|
+
* Allowed browser source origins: POST login uses this policy in both
|
|
853
|
+
* transports; guarded exchange uses the same policy (JSON or form), and
|
|
854
|
+
* cookie refresh/logout retain their source checks. Missing/null/untrusted
|
|
855
|
+
* sources fail closed; POST login/guarded exchange also reject raw source
|
|
856
|
+
* ambiguity. backendOrigin is included internally; a valid Referer is the
|
|
857
|
+
* fallback only when Origin is absent.
|
|
858
|
+
*/
|
|
504
859
|
trustedOrigins?: string[];
|
|
505
860
|
requestBodyLimit?: string | number;
|
|
506
861
|
/**
|
|
@@ -571,30 +926,66 @@ declare const DEFAULT_OIDC_VAULT_REQUEST_BODY_LIMIT = "16kb";
|
|
|
571
926
|
declare const OIDC_VAULT_URL_ENCODED_PARAMETER_LIMIT = 16;
|
|
572
927
|
declare const OIDC_VAULT_ROUTE_PATHS: Record<OidcVaultRouteName, string>;
|
|
573
928
|
|
|
929
|
+
/**
|
|
930
|
+
* API authentication from package-root named imports. With deviceBinding
|
|
931
|
+
* enabled, requires validateWithRequest at construction for BOTH schemes and
|
|
932
|
+
* verifies a single raw DPoP proof, pinned method/URL, original confirmation,
|
|
933
|
+
* API ath, nonce and shared replay BEFORE attaching req.auth or invoking hooks.
|
|
934
|
+
* Bound tokens require Authorization: DPoP; unbound DPoP presentation is invalid.
|
|
935
|
+
* Omitted binding retains exactly validate(token) for legacy Bearer adapters,
|
|
936
|
+
* but refuses any known bound credential. Construction snapshots configuration,
|
|
937
|
+
* callbacks/validator methods, URLs, algorithms and secret bytes; the replay
|
|
938
|
+
* store remains the shared atomic service. Responses carry no-store and fixed
|
|
939
|
+
* errors; onError privately observes originals and cannot override failures.
|
|
940
|
+
*/
|
|
574
941
|
declare function createOidcVaultAccessTokenMiddleware(options: OidcVaultAccessTokenMiddlewareOptions): RequestHandler;
|
|
575
942
|
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
943
|
+
/**
|
|
944
|
+
* Verify local JWTs with both legacy validate(token) and validateWithRequest.
|
|
945
|
+
* Raw verified cnf is captured before mapClaims; mapping cannot forge or strip
|
|
946
|
+
* the sender constraint. The request-aware result always has confirmation
|
|
947
|
+
* (null only for genuinely unbound JWTs). Legacy unbound results omit it;
|
|
948
|
+
* bound results report it so binding-disabled vault middleware refuses downgrade.
|
|
949
|
+
* Proof/target/ath/nonce/replay enforcement belongs to the API middleware.
|
|
950
|
+
* Construction captures options and copies secret/JWK/allowlist containers.
|
|
951
|
+
*/
|
|
952
|
+
declare function createOidcVaultJwtAccessTokenValidator(options: OidcVaultJwtAccessTokenValidatorOptions): OidcVaultRequestAwareAccessTokenValidator;
|
|
579
953
|
|
|
580
954
|
/**
|
|
581
955
|
* Normalize the mounted base path for the OIDC router.
|
|
582
956
|
*/
|
|
583
957
|
declare function normalizeOidcVaultBasePath(value?: string): string;
|
|
584
958
|
/**
|
|
585
|
-
* Create the
|
|
959
|
+
* Create the OIDC lifecycle router using a named package-root import.
|
|
960
|
+
* The default mount is /auth/oidc and default transport is body. Configure
|
|
961
|
+
* issuer/clientId (or complete manual endpoints), a pinned backendOrigin,
|
|
962
|
+
* frontendRedirectUri for callback completion, and a storeProvider.
|
|
963
|
+
*
|
|
964
|
+
* With deviceBinding enabled, JSON POST login selects a verified persistent
|
|
965
|
+
* browser key, callback authenticates the temporary HttpOnly cookie, and
|
|
966
|
+
* exchange/refresh/logout enforce the original key before credential work.
|
|
967
|
+
* A local tokenIssuer must emit exact DPoP and matching cnf.jkt from its verified
|
|
968
|
+
* input. Protect every accepting API separately with
|
|
969
|
+
* createOidcVaultAccessTokenMiddleware and a request-aware validator/replay store.
|
|
970
|
+
* Vault refresh/logout need no access token or ath and work after JWT expiry.
|
|
971
|
+
* All vault responses carry no-store; logout does not revoke stateless JWTs.
|
|
586
972
|
*
|
|
587
973
|
* Construction takes an internal resolved snapshot of `options` without
|
|
588
974
|
* mutating the caller object: normalized values (such as
|
|
589
975
|
* `frontendRedirectUri`) are stored on the snapshot, plain-data containers
|
|
590
|
-
* (`cookie`, `trustedOrigins`, `config`) are shallow-copied,
|
|
976
|
+
* (`cookie`, `trustedOrigins`, `config`) are shallow-copied, `transactionCookie`
|
|
977
|
+
* is resolved into a detached/frozen security configuration, and service
|
|
591
978
|
* references (`storeProvider`, `hooks`, `tokenIssuer`, `now`) are retained
|
|
592
979
|
* by reference, never deep-cloned. Mutating or replacing the caller options
|
|
593
980
|
* after this call has no effect on the created router. Post-commit hooks
|
|
594
981
|
* (`onSessionCreated`, `onSessionRefreshed`, `onLogout`) are notifications
|
|
595
982
|
* whose failures are reported to `onError` without undoing committed state;
|
|
596
983
|
* other hooks run pre-commit and can veto the operation by throwing.
|
|
984
|
+
* Opt-in `deviceBinding` policy/algorithm containers are frozen snapshots;
|
|
985
|
+
* an enabled nonce secret is copied into private owned storage. Separate opt-in
|
|
986
|
+
* `fingerprintRecognition` settings are detached/frozen; recognition enrolls
|
|
987
|
+
* only at POST login and checks exchange/refresh before credential mutation.
|
|
597
988
|
*/
|
|
598
989
|
declare function createOidcVaultMiddleware(options: OidcVaultOptions): Router;
|
|
599
990
|
|
|
600
|
-
export { type AuthorizationTransaction, type AuthorizationTransactionInput, type ConsumeBackchannelLogoutTokenJtiInput, DEFAULT_AUTHORIZATION_TRANSACTION_TTL_MS, DEFAULT_EXCHANGE_CODE_TTL_MS, DEFAULT_OIDC_SCOPES, DEFAULT_OIDC_VAULT_BASE_PATH, DEFAULT_OIDC_VAULT_REQUEST_BODY_LIMIT, type DeleteSessionsByLogicalSessionIdInput, type DeleteSessionsByProviderSessionIdInput, type DeleteSessionsBySubjectInput, type ExchangeCodeRecord, type ExchangeCodeRecordInput, type IssueTokenInput, OIDC_VAULT_ROUTE_PATHS, OIDC_VAULT_URL_ENCODED_PARAMETER_LIMIT, type OidcVaultAccessTokenMiddlewareErrorContext, type OidcVaultAccessTokenMiddlewareOptions, type OidcVaultAccessTokenValidationResult, type OidcVaultAccessTokenValidator, type OidcVaultAuthContext, type OidcVaultAuthenticatedRequest, type OidcVaultBackchannelLogoutResult, type OidcVaultConfig, type OidcVaultConfigMode, type OidcVaultCookieDeploymentMode, type OidcVaultCookieOptions, type OidcVaultCookieSameSite, type OidcVaultEnv, type OidcVaultErrorContext, type OidcVaultExchangeResult, type OidcVaultHookContext, type OidcVaultHooks, type OidcVaultJwtAccessTokenValidatorOptions, type OidcVaultLogoutResult, type OidcVaultOptions, type OidcVaultProviderMetadata, type OidcVaultResolvedConfig, type OidcVaultRouteName, type OidcVaultSession, type OidcVaultSessionInput, type OidcVaultSessionTransport, OidcVaultStoreConflictError, type OidcVaultStoreProvider, type OidcVaultTokenIssueResult, type OidcVaultTokenIssuer, type OidcVaultUserProfile, type RotateSessionInput, createOidcVaultAccessTokenMiddleware, createOidcVaultJwtAccessTokenValidator, createOidcVaultMiddleware, normalizeOidcVaultBasePath, resolveOidcVaultConfig, resolveOidcVaultConfigFromEnv };
|
|
991
|
+
export { type AuthorizationTransaction, type AuthorizationTransactionInput, type ConsumeAuthorizationTransactionIfMatchesInput, type ConsumeBackchannelLogoutTokenJtiInput, type ConsumeExchangeCodeIfMatchesInput, DEFAULT_AUTHORIZATION_TRANSACTION_TTL_MS, DEFAULT_EXCHANGE_CODE_TTL_MS, DEFAULT_OIDC_SCOPES, DEFAULT_OIDC_VAULT_BASE_PATH, DEFAULT_OIDC_VAULT_REQUEST_BODY_LIMIT, type DeleteSessionsByLogicalSessionIdInput, type DeleteSessionsByProviderSessionIdInput, type DeleteSessionsBySubjectInput, type ExchangeCodeRecord, type ExchangeCodeRecordInput, type IssueTokenInput, OIDC_VAULT_ROUTE_PATHS, OIDC_VAULT_URL_ENCODED_PARAMETER_LIMIT, type OidcVaultAccessTokenConfirmation, type OidcVaultAccessTokenMiddlewareErrorContext, type OidcVaultAccessTokenMiddlewareOptions, type OidcVaultAccessTokenRequestInput, type OidcVaultAccessTokenValidationResult, type OidcVaultAccessTokenValidator, type OidcVaultApiDeviceBindingOptions, type OidcVaultAuthContext, type OidcVaultAuthenticatedRequest, type OidcVaultBackchannelLogoutResult, type OidcVaultConfig, type OidcVaultConfigMode, type OidcVaultCookieDeploymentMode, type OidcVaultCookieOptions, type OidcVaultCookieSameSite, type OidcVaultDeviceBindingMode, type OidcVaultDeviceBindingOptions, type OidcVaultDeviceBindingStoreProvider, type OidcVaultDpopAlgorithm, type OidcVaultDpopBinding, type OidcVaultDpopNonceOptions, type OidcVaultDpopProofOptions, OidcVaultDpopReplayCapacityError, type OidcVaultDpopReplayStore, type OidcVaultEnv, type OidcVaultErrorContext, type OidcVaultExchangeResult, type OidcVaultFingerprintRecognitionOptions, type OidcVaultHookContext, type OidcVaultHooks, type OidcVaultJwtAccessTokenValidatorOptions, type OidcVaultLoginInitiationInput, type OidcVaultLoginInitiationResult, type OidcVaultLogoutResult, type OidcVaultOptions, type OidcVaultProviderMetadata, type OidcVaultRecordBindingMatch, type OidcVaultRequestAwareAccessTokenValidationResult, type OidcVaultRequestAwareAccessTokenValidator, type OidcVaultResolvedConfig, type OidcVaultRouteName, type OidcVaultSession, type OidcVaultSessionInput, type OidcVaultSessionRevocationContext, type OidcVaultSessionTransport, OidcVaultStoreConflictError, type OidcVaultStoreProvider, type OidcVaultTokenIssueResult, type OidcVaultTokenIssuer, type OidcVaultTransactionCookieOptions, type OidcVaultUserProfile, type OidcVaultVerifiedDpopBinding, type ReserveDpopProofInput, type RotateSessionInput, createOidcVaultAccessTokenMiddleware, createOidcVaultJwtAccessTokenValidator, createOidcVaultMiddleware, normalizeOidcVaultBasePath, resolveOidcVaultConfig, resolveOidcVaultConfigFromEnv };
|