@idp.global/sdk 19.2.1 → 19.4.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.
Files changed (44) hide show
  1. package/changelog.md +58 -0
  2. package/dist_ts/00_commitinfo_data.js +1 -1
  3. package/dist_ts_browser/classes.idpclient.js +1 -1
  4. package/dist_ts_browser/classes.idprequests.js +1 -1
  5. package/dist_ts_browser/classes.relyingpartybearerclient.d.ts +276 -0
  6. package/dist_ts_browser/classes.relyingpartybearerclient.js +591 -0
  7. package/dist_ts_browser/index.d.ts +1 -0
  8. package/dist_ts_browser/index.js +2 -1
  9. package/dist_ts_browser/plugins.js +1 -1
  10. package/dist_ts_browser/secret-delivery.js +1 -1
  11. package/dist_ts_relyingparty/classes.authorityobserver.d.ts +23 -0
  12. package/dist_ts_relyingparty/classes.authorityobserver.js +68 -13
  13. package/dist_ts_relyingparty/classes.errors.d.ts +11 -1
  14. package/dist_ts_relyingparty/classes.errors.js +6 -1
  15. package/dist_ts_relyingparty/classes.relyingpartyroutes.d.ts +74 -2
  16. package/dist_ts_relyingparty/classes.relyingpartyroutes.js +289 -14
  17. package/dist_ts_relyingparty/classes.relyingpartysessions.d.ts +209 -7
  18. package/dist_ts_relyingparty/classes.relyingpartysessions.js +734 -87
  19. package/dist_ts_relyingparty/classes.rpmodels.d.ts +71 -8
  20. package/dist_ts_relyingparty/classes.rpmodels.js +224 -10
  21. package/dist_ts_relyingparty/contract.bearer.d.ts +82 -0
  22. package/dist_ts_relyingparty/contract.bearer.js +9 -0
  23. package/dist_ts_relyingparty/helpers.bearer.d.ts +48 -0
  24. package/dist_ts_relyingparty/helpers.bearer.js +199 -0
  25. package/dist_ts_relyingparty/index.d.ts +1 -0
  26. package/dist_ts_relyingparty/index.js +2 -1
  27. package/dist_ts_relyingparty/interfaces.d.ts +122 -2
  28. package/dist_ts_relyingparty/testing.d.ts +22 -0
  29. package/dist_ts_relyingparty/testing.js +42 -1
  30. package/package.json +9 -11
  31. package/readme.md +353 -8
  32. package/ts/00_commitinfo_data.ts +1 -1
  33. package/ts_browser/classes.relyingpartybearerclient.ts +821 -0
  34. package/ts_browser/index.ts +1 -0
  35. package/ts_relyingparty/classes.authorityobserver.ts +80 -12
  36. package/ts_relyingparty/classes.errors.ts +16 -1
  37. package/ts_relyingparty/classes.relyingpartyroutes.ts +340 -16
  38. package/ts_relyingparty/classes.relyingpartysessions.ts +907 -94
  39. package/ts_relyingparty/classes.rpmodels.ts +131 -9
  40. package/ts_relyingparty/contract.bearer.ts +99 -0
  41. package/ts_relyingparty/helpers.bearer.ts +259 -0
  42. package/ts_relyingparty/index.ts +1 -0
  43. package/ts_relyingparty/interfaces.ts +144 -2
  44. package/ts_relyingparty/testing.ts +60 -0
@@ -1,9 +1,11 @@
1
1
  import * as plugins from './plugins.js';
2
+ import type { TRelyingPartyBearerClientKind } from './interfaces.js';
2
3
  /**
3
- * One browser session of a relying party. The persisted field names, their
4
- * types and the index declarations are the ones nevermind.finance has stored
5
- * under `SessionDoc` since before this module existed, so its collection is
6
- * read and written unchanged.
4
+ * One browser session of a relying party. The persisted field names and their
5
+ * types are the ones nevermind.finance has stored under `SessionDoc` since
6
+ * before this module existed, so its collection is read and written
7
+ * unchanged; its indexes are those and the `expiresAt` index the sweep of
8
+ * ended sessions reads.
7
9
  */
8
10
  export declare class RelyingPartySessionDoc extends plugins.nosqldb.SmartDataDbDoc<RelyingPartySessionDoc, RelyingPartySessionDoc> {
9
11
  id: string;
@@ -13,6 +15,7 @@ export declare class RelyingPartySessionDoc extends plugins.nosqldb.SmartDataDbD
13
15
  userId: string;
14
16
  createdAt: number;
15
17
  lastSeenAt: number;
18
+ /** a revocation lowers it to `revokedAt` when that is earlier, so the sweep finds every ended session by it */
16
19
  expiresAt: number;
17
20
  /** absent while the session is valid */
18
21
  revokedAt?: number;
@@ -33,7 +36,8 @@ export declare class RelyingPartySessionDoc extends plugins.nosqldb.SmartDataDbD
33
36
  * against, the binding to the browser that started it, the sealed PKCE
34
37
  * verifier and the return path. Consumed exactly once by a conditional update.
35
38
  * Field names and indexes are the ones nevermind.finance stores under
36
- * `LoginAttemptDoc`.
39
+ * `LoginAttemptDoc`; the `bearer…` fields exist only on the attempt of a
40
+ * bearer login, whose binding token is never issued.
37
41
  */
38
42
  export declare class RelyingPartyLoginAttemptDoc extends plugins.nosqldb.SmartDataDbDoc<RelyingPartyLoginAttemptDoc, RelyingPartyLoginAttemptDoc> {
39
43
  id: string;
@@ -53,10 +57,57 @@ export declare class RelyingPartyLoginAttemptDoc extends plugins.nosqldb.SmartDa
53
57
  consumedAt?: number | null;
54
58
  /** the session the callback created; finalize releases the return path against it */
55
59
  createdSessionId?: string | null;
60
+ /** how the bearer client of this login receives its outcome; absent on a cookie login */
61
+ bearerClientKind?: TRelyingPartyBearerClientKind;
62
+ /** the return target the bearer client named, exactly */
63
+ bearerReturnTarget?: string;
64
+ /** the bearer client's S256 code challenge; its hand-off is claimed with the matching verifier */
65
+ bearerCodeChallenge?: string;
66
+ /** the bearer client's own `state`, handed back with the outcome */
67
+ bearerClientState?: string;
68
+ }
69
+ /**
70
+ * The single-use code a bearer login hands its client. Only the hash of the
71
+ * code is stored; the code is bound to the client's S256 challenge, lives at
72
+ * most a minute and is consumed by one conditional update.
73
+ */
74
+ export declare class RelyingPartyBearerHandoffDoc extends plugins.nosqldb.SmartDataDbDoc<RelyingPartyBearerHandoffDoc, RelyingPartyBearerHandoffDoc> {
75
+ id: string;
76
+ /** sha256 of the code */
77
+ codeHash: string;
78
+ /** the session the login opened; the code is its only way out */
79
+ sessionId: string;
80
+ codeChallenge: string;
81
+ createdAt: number;
82
+ /** at most a minute after the callback; the sweep ends the session of a code nobody claimed by then */
83
+ expiresAt: number;
84
+ /** `null` until a claim consumes the code */
85
+ consumedAt: number | null;
86
+ }
87
+ /**
88
+ * One generation of a bearer session's tokens: an access token and the
89
+ * refresh token that replaces both. Only hashes are stored. Exactly one
90
+ * generation of a session is current (`rotatedAt` `null`); a rotated one is
91
+ * kept until the session expires, so its refresh token coming back is
92
+ * recognized as reuse.
93
+ */
94
+ export declare class RelyingPartyBearerTokenDoc extends plugins.nosqldb.SmartDataDbDoc<RelyingPartyBearerTokenDoc, RelyingPartyBearerTokenDoc> {
95
+ id: string;
96
+ accessTokenHash: string;
97
+ refreshTokenHash: string;
98
+ sessionId: string;
99
+ createdAt: number;
100
+ accessTokenExpiresAt: number;
101
+ /** the session's end; the refresh token never outlives it, and the sweep removes the generation after it */
102
+ expiresAt: number;
103
+ /** `null` while this generation is current; when its refresh token was spent otherwise */
104
+ rotatedAt: number | null;
56
105
  }
57
106
  export declare const RELYING_PARTY_DEFAULT_COLLECTION_NAMES: {
58
107
  readonly sessions: 'IdpRelyingPartySession';
59
108
  readonly loginAttempts: 'IdpRelyingPartyLoginAttempt';
109
+ readonly bearerHandoffs: 'IdpRelyingPartyBearerHandoff';
110
+ readonly bearerTokens: 'IdpRelyingPartyBearerToken';
60
111
  };
61
112
  export interface IRelyingPartyModelsOptions {
62
113
  /**
@@ -73,17 +124,29 @@ export interface IRelyingPartyModelsOptions {
73
124
  collectionNames?: {
74
125
  sessions?: string;
75
126
  loginAttempts?: string;
127
+ bearerHandoffs?: string;
128
+ bearerTokens?: string;
76
129
  };
77
130
  }
78
- export interface IRelyingPartyModels {
131
+ /** The models bearer hand-off mode stores its codes and tokens in. */
132
+ export interface IRelyingPartyBearerModels {
133
+ readonly BearerHandoff: typeof RelyingPartyBearerHandoffDoc;
134
+ readonly BearerToken: typeof RelyingPartyBearerTokenDoc;
135
+ }
136
+ /**
137
+ * The models of the session layer. The bearer models are needed only when
138
+ * `RelyingPartySessions` runs with `bearer`; `createRelyingPartyModels`
139
+ * always binds them.
140
+ */
141
+ export interface IRelyingPartyModels extends Partial<IRelyingPartyBearerModels> {
79
142
  readonly Session: typeof RelyingPartySessionDoc;
80
143
  readonly LoginAttempt: typeof RelyingPartyLoginAttemptDoc;
81
144
  }
82
145
  /**
83
- * Binds the two relying-party models to one database. Each call declares its
146
+ * Binds the relying-party models to one database. Each call declares its
84
147
  * own model classes, so several databases — and several applications in one
85
148
  * process — never share a binding. A deferred `db` is resolved on every use,
86
149
  * the way `@Collection(() => db)` resolves it; a use before it answers a
87
150
  * `SmartdataDb` throws `RelyingPartyDatabaseUnavailableError`.
88
151
  */
89
- export declare const createRelyingPartyModels: (optionsArg: IRelyingPartyModelsOptions) => IRelyingPartyModels;
152
+ export declare const createRelyingPartyModels: (optionsArg: IRelyingPartyModelsOptions) => IRelyingPartyModels & IRelyingPartyBearerModels;
@@ -35,10 +35,11 @@ var __runInitializers = (this && this.__runInitializers) || function (thisArg, i
35
35
  import * as plugins from './plugins.js';
36
36
  import { RelyingPartyDatabaseUnavailableError } from './classes.errors.js';
37
37
  /**
38
- * One browser session of a relying party. The persisted field names, their
39
- * types and the index declarations are the ones nevermind.finance has stored
40
- * under `SessionDoc` since before this module existed, so its collection is
41
- * read and written unchanged.
38
+ * One browser session of a relying party. The persisted field names and their
39
+ * types are the ones nevermind.finance has stored under `SessionDoc` since
40
+ * before this module existed, so its collection is read and written
41
+ * unchanged; its indexes are those and the `expiresAt` index the sweep of
42
+ * ended sessions reads.
42
43
  */
43
44
  let RelyingPartySessionDoc = (() => {
44
45
  let _classSuper = plugins.nosqldb.SmartDataDbDoc;
@@ -89,7 +90,7 @@ let RelyingPartySessionDoc = (() => {
89
90
  _userId_decorators = [plugins.nosqldb.svDb(), plugins.nosqldb.index()];
90
91
  _createdAt_decorators = [plugins.nosqldb.svDb()];
91
92
  _lastSeenAt_decorators = [plugins.nosqldb.svDb()];
92
- _expiresAt_decorators = [plugins.nosqldb.svDb()];
93
+ _expiresAt_decorators = [plugins.nosqldb.svDb(), plugins.nosqldb.index()];
93
94
  _revokedAt_decorators = [plugins.nosqldb.svDb()];
94
95
  _idpSubject_decorators = [plugins.nosqldb.svDb()];
95
96
  _loginAttemptId_decorators = [plugins.nosqldb.svDb()];
@@ -119,6 +120,7 @@ let RelyingPartySessionDoc = (() => {
119
120
  userId = (__runInitializers(this, _tokenHash_extraInitializers), __runInitializers(this, _userId_initializers, ''));
120
121
  createdAt = (__runInitializers(this, _userId_extraInitializers), __runInitializers(this, _createdAt_initializers, 0));
121
122
  lastSeenAt = (__runInitializers(this, _createdAt_extraInitializers), __runInitializers(this, _lastSeenAt_initializers, 0));
123
+ /** a revocation lowers it to `revokedAt` when that is earlier, so the sweep finds every ended session by it */
122
124
  expiresAt = (__runInitializers(this, _lastSeenAt_extraInitializers), __runInitializers(this, _expiresAt_initializers, 0));
123
125
  /** absent while the session is valid */
124
126
  revokedAt = (__runInitializers(this, _expiresAt_extraInitializers), __runInitializers(this, _revokedAt_initializers, void 0));
@@ -145,7 +147,8 @@ export { RelyingPartySessionDoc };
145
147
  * against, the binding to the browser that started it, the sealed PKCE
146
148
  * verifier and the return path. Consumed exactly once by a conditional update.
147
149
  * Field names and indexes are the ones nevermind.finance stores under
148
- * `LoginAttemptDoc`.
150
+ * `LoginAttemptDoc`; the `bearer…` fields exist only on the attempt of a
151
+ * bearer login, whose binding token is never issued.
149
152
  */
150
153
  let RelyingPartyLoginAttemptDoc = (() => {
151
154
  let _classSuper = plugins.nosqldb.SmartDataDbDoc;
@@ -182,6 +185,18 @@ let RelyingPartyLoginAttemptDoc = (() => {
182
185
  let _createdSessionId_decorators;
183
186
  let _createdSessionId_initializers = [];
184
187
  let _createdSessionId_extraInitializers = [];
188
+ let _bearerClientKind_decorators;
189
+ let _bearerClientKind_initializers = [];
190
+ let _bearerClientKind_extraInitializers = [];
191
+ let _bearerReturnTarget_decorators;
192
+ let _bearerReturnTarget_initializers = [];
193
+ let _bearerReturnTarget_extraInitializers = [];
194
+ let _bearerCodeChallenge_decorators;
195
+ let _bearerCodeChallenge_initializers = [];
196
+ let _bearerCodeChallenge_extraInitializers = [];
197
+ let _bearerClientState_decorators;
198
+ let _bearerClientState_initializers = [];
199
+ let _bearerClientState_extraInitializers = [];
185
200
  return class RelyingPartyLoginAttemptDoc extends _classSuper {
186
201
  static {
187
202
  const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
@@ -196,6 +211,10 @@ let RelyingPartyLoginAttemptDoc = (() => {
196
211
  _expiresAt_decorators = [plugins.nosqldb.svDb()];
197
212
  _consumedAt_decorators = [plugins.nosqldb.svDb()];
198
213
  _createdSessionId_decorators = [plugins.nosqldb.svDb()];
214
+ _bearerClientKind_decorators = [plugins.nosqldb.svDb()];
215
+ _bearerReturnTarget_decorators = [plugins.nosqldb.svDb()];
216
+ _bearerCodeChallenge_decorators = [plugins.nosqldb.svDb()];
217
+ _bearerClientState_decorators = [plugins.nosqldb.svDb()];
199
218
  __esDecorate(null, null, _id_decorators, { kind: "field", name: "id", static: false, private: false, access: { has: obj => "id" in obj, get: obj => obj.id, set: (obj, value) => { obj.id = value; } }, metadata: _metadata }, _id_initializers, _id_extraInitializers);
200
219
  __esDecorate(null, null, _stateHash_decorators, { kind: "field", name: "stateHash", static: false, private: false, access: { has: obj => "stateHash" in obj, get: obj => obj.stateHash, set: (obj, value) => { obj.stateHash = value; } }, metadata: _metadata }, _stateHash_initializers, _stateHash_extraInitializers);
201
220
  __esDecorate(null, null, _bindingTokenHash_decorators, { kind: "field", name: "bindingTokenHash", static: false, private: false, access: { has: obj => "bindingTokenHash" in obj, get: obj => obj.bindingTokenHash, set: (obj, value) => { obj.bindingTokenHash = value; } }, metadata: _metadata }, _bindingTokenHash_initializers, _bindingTokenHash_extraInitializers);
@@ -207,6 +226,10 @@ let RelyingPartyLoginAttemptDoc = (() => {
207
226
  __esDecorate(null, null, _expiresAt_decorators, { kind: "field", name: "expiresAt", static: false, private: false, access: { has: obj => "expiresAt" in obj, get: obj => obj.expiresAt, set: (obj, value) => { obj.expiresAt = value; } }, metadata: _metadata }, _expiresAt_initializers, _expiresAt_extraInitializers);
208
227
  __esDecorate(null, null, _consumedAt_decorators, { kind: "field", name: "consumedAt", static: false, private: false, access: { has: obj => "consumedAt" in obj, get: obj => obj.consumedAt, set: (obj, value) => { obj.consumedAt = value; } }, metadata: _metadata }, _consumedAt_initializers, _consumedAt_extraInitializers);
209
228
  __esDecorate(null, null, _createdSessionId_decorators, { kind: "field", name: "createdSessionId", static: false, private: false, access: { has: obj => "createdSessionId" in obj, get: obj => obj.createdSessionId, set: (obj, value) => { obj.createdSessionId = value; } }, metadata: _metadata }, _createdSessionId_initializers, _createdSessionId_extraInitializers);
229
+ __esDecorate(null, null, _bearerClientKind_decorators, { kind: "field", name: "bearerClientKind", static: false, private: false, access: { has: obj => "bearerClientKind" in obj, get: obj => obj.bearerClientKind, set: (obj, value) => { obj.bearerClientKind = value; } }, metadata: _metadata }, _bearerClientKind_initializers, _bearerClientKind_extraInitializers);
230
+ __esDecorate(null, null, _bearerReturnTarget_decorators, { kind: "field", name: "bearerReturnTarget", static: false, private: false, access: { has: obj => "bearerReturnTarget" in obj, get: obj => obj.bearerReturnTarget, set: (obj, value) => { obj.bearerReturnTarget = value; } }, metadata: _metadata }, _bearerReturnTarget_initializers, _bearerReturnTarget_extraInitializers);
231
+ __esDecorate(null, null, _bearerCodeChallenge_decorators, { kind: "field", name: "bearerCodeChallenge", static: false, private: false, access: { has: obj => "bearerCodeChallenge" in obj, get: obj => obj.bearerCodeChallenge, set: (obj, value) => { obj.bearerCodeChallenge = value; } }, metadata: _metadata }, _bearerCodeChallenge_initializers, _bearerCodeChallenge_extraInitializers);
232
+ __esDecorate(null, null, _bearerClientState_decorators, { kind: "field", name: "bearerClientState", static: false, private: false, access: { has: obj => "bearerClientState" in obj, get: obj => obj.bearerClientState, set: (obj, value) => { obj.bearerClientState = value; } }, metadata: _metadata }, _bearerClientState_initializers, _bearerClientState_extraInitializers);
210
233
  if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
211
234
  }
212
235
  id = __runInitializers(this, _id_initializers, '');
@@ -226,19 +249,165 @@ let RelyingPartyLoginAttemptDoc = (() => {
226
249
  consumedAt = (__runInitializers(this, _expiresAt_extraInitializers), __runInitializers(this, _consumedAt_initializers, void 0));
227
250
  /** the session the callback created; finalize releases the return path against it */
228
251
  createdSessionId = (__runInitializers(this, _consumedAt_extraInitializers), __runInitializers(this, _createdSessionId_initializers, void 0));
252
+ /** how the bearer client of this login receives its outcome; absent on a cookie login */
253
+ bearerClientKind = (__runInitializers(this, _createdSessionId_extraInitializers), __runInitializers(this, _bearerClientKind_initializers, void 0));
254
+ /** the return target the bearer client named, exactly */
255
+ bearerReturnTarget = (__runInitializers(this, _bearerClientKind_extraInitializers), __runInitializers(this, _bearerReturnTarget_initializers, void 0));
256
+ /** the bearer client's S256 code challenge; its hand-off is claimed with the matching verifier */
257
+ bearerCodeChallenge = (__runInitializers(this, _bearerReturnTarget_extraInitializers), __runInitializers(this, _bearerCodeChallenge_initializers, void 0));
258
+ /** the bearer client's own `state`, handed back with the outcome */
259
+ bearerClientState = (__runInitializers(this, _bearerCodeChallenge_extraInitializers), __runInitializers(this, _bearerClientState_initializers, void 0));
229
260
  constructor() {
230
261
  super(...arguments);
231
- __runInitializers(this, _createdSessionId_extraInitializers);
262
+ __runInitializers(this, _bearerClientState_extraInitializers);
232
263
  }
233
264
  };
234
265
  })();
235
266
  export { RelyingPartyLoginAttemptDoc };
267
+ /**
268
+ * The single-use code a bearer login hands its client. Only the hash of the
269
+ * code is stored; the code is bound to the client's S256 challenge, lives at
270
+ * most a minute and is consumed by one conditional update.
271
+ */
272
+ let RelyingPartyBearerHandoffDoc = (() => {
273
+ let _classSuper = plugins.nosqldb.SmartDataDbDoc;
274
+ let _id_decorators;
275
+ let _id_initializers = [];
276
+ let _id_extraInitializers = [];
277
+ let _codeHash_decorators;
278
+ let _codeHash_initializers = [];
279
+ let _codeHash_extraInitializers = [];
280
+ let _sessionId_decorators;
281
+ let _sessionId_initializers = [];
282
+ let _sessionId_extraInitializers = [];
283
+ let _codeChallenge_decorators;
284
+ let _codeChallenge_initializers = [];
285
+ let _codeChallenge_extraInitializers = [];
286
+ let _createdAt_decorators;
287
+ let _createdAt_initializers = [];
288
+ let _createdAt_extraInitializers = [];
289
+ let _expiresAt_decorators;
290
+ let _expiresAt_initializers = [];
291
+ let _expiresAt_extraInitializers = [];
292
+ let _consumedAt_decorators;
293
+ let _consumedAt_initializers = [];
294
+ let _consumedAt_extraInitializers = [];
295
+ return class RelyingPartyBearerHandoffDoc extends _classSuper {
296
+ static {
297
+ const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
298
+ _id_decorators = [plugins.nosqldb.unI()];
299
+ _codeHash_decorators = [plugins.nosqldb.unI()];
300
+ _sessionId_decorators = [plugins.nosqldb.svDb()];
301
+ _codeChallenge_decorators = [plugins.nosqldb.svDb()];
302
+ _createdAt_decorators = [plugins.nosqldb.svDb()];
303
+ _expiresAt_decorators = [plugins.nosqldb.svDb(), plugins.nosqldb.index()];
304
+ _consumedAt_decorators = [plugins.nosqldb.svDb()];
305
+ __esDecorate(null, null, _id_decorators, { kind: "field", name: "id", static: false, private: false, access: { has: obj => "id" in obj, get: obj => obj.id, set: (obj, value) => { obj.id = value; } }, metadata: _metadata }, _id_initializers, _id_extraInitializers);
306
+ __esDecorate(null, null, _codeHash_decorators, { kind: "field", name: "codeHash", static: false, private: false, access: { has: obj => "codeHash" in obj, get: obj => obj.codeHash, set: (obj, value) => { obj.codeHash = value; } }, metadata: _metadata }, _codeHash_initializers, _codeHash_extraInitializers);
307
+ __esDecorate(null, null, _sessionId_decorators, { kind: "field", name: "sessionId", static: false, private: false, access: { has: obj => "sessionId" in obj, get: obj => obj.sessionId, set: (obj, value) => { obj.sessionId = value; } }, metadata: _metadata }, _sessionId_initializers, _sessionId_extraInitializers);
308
+ __esDecorate(null, null, _codeChallenge_decorators, { kind: "field", name: "codeChallenge", static: false, private: false, access: { has: obj => "codeChallenge" in obj, get: obj => obj.codeChallenge, set: (obj, value) => { obj.codeChallenge = value; } }, metadata: _metadata }, _codeChallenge_initializers, _codeChallenge_extraInitializers);
309
+ __esDecorate(null, null, _createdAt_decorators, { kind: "field", name: "createdAt", static: false, private: false, access: { has: obj => "createdAt" in obj, get: obj => obj.createdAt, set: (obj, value) => { obj.createdAt = value; } }, metadata: _metadata }, _createdAt_initializers, _createdAt_extraInitializers);
310
+ __esDecorate(null, null, _expiresAt_decorators, { kind: "field", name: "expiresAt", static: false, private: false, access: { has: obj => "expiresAt" in obj, get: obj => obj.expiresAt, set: (obj, value) => { obj.expiresAt = value; } }, metadata: _metadata }, _expiresAt_initializers, _expiresAt_extraInitializers);
311
+ __esDecorate(null, null, _consumedAt_decorators, { kind: "field", name: "consumedAt", static: false, private: false, access: { has: obj => "consumedAt" in obj, get: obj => obj.consumedAt, set: (obj, value) => { obj.consumedAt = value; } }, metadata: _metadata }, _consumedAt_initializers, _consumedAt_extraInitializers);
312
+ if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
313
+ }
314
+ id = __runInitializers(this, _id_initializers, '');
315
+ /** sha256 of the code */
316
+ codeHash = (__runInitializers(this, _id_extraInitializers), __runInitializers(this, _codeHash_initializers, ''));
317
+ /** the session the login opened; the code is its only way out */
318
+ sessionId = (__runInitializers(this, _codeHash_extraInitializers), __runInitializers(this, _sessionId_initializers, ''));
319
+ codeChallenge = (__runInitializers(this, _sessionId_extraInitializers), __runInitializers(this, _codeChallenge_initializers, ''));
320
+ createdAt = (__runInitializers(this, _codeChallenge_extraInitializers), __runInitializers(this, _createdAt_initializers, 0));
321
+ /** at most a minute after the callback; the sweep ends the session of a code nobody claimed by then */
322
+ expiresAt = (__runInitializers(this, _createdAt_extraInitializers), __runInitializers(this, _expiresAt_initializers, 0));
323
+ /** `null` until a claim consumes the code */
324
+ consumedAt = (__runInitializers(this, _expiresAt_extraInitializers), __runInitializers(this, _consumedAt_initializers, null));
325
+ constructor() {
326
+ super(...arguments);
327
+ __runInitializers(this, _consumedAt_extraInitializers);
328
+ }
329
+ };
330
+ })();
331
+ export { RelyingPartyBearerHandoffDoc };
332
+ /**
333
+ * One generation of a bearer session's tokens: an access token and the
334
+ * refresh token that replaces both. Only hashes are stored. Exactly one
335
+ * generation of a session is current (`rotatedAt` `null`); a rotated one is
336
+ * kept until the session expires, so its refresh token coming back is
337
+ * recognized as reuse.
338
+ */
339
+ let RelyingPartyBearerTokenDoc = (() => {
340
+ let _classSuper = plugins.nosqldb.SmartDataDbDoc;
341
+ let _id_decorators;
342
+ let _id_initializers = [];
343
+ let _id_extraInitializers = [];
344
+ let _accessTokenHash_decorators;
345
+ let _accessTokenHash_initializers = [];
346
+ let _accessTokenHash_extraInitializers = [];
347
+ let _refreshTokenHash_decorators;
348
+ let _refreshTokenHash_initializers = [];
349
+ let _refreshTokenHash_extraInitializers = [];
350
+ let _sessionId_decorators;
351
+ let _sessionId_initializers = [];
352
+ let _sessionId_extraInitializers = [];
353
+ let _createdAt_decorators;
354
+ let _createdAt_initializers = [];
355
+ let _createdAt_extraInitializers = [];
356
+ let _accessTokenExpiresAt_decorators;
357
+ let _accessTokenExpiresAt_initializers = [];
358
+ let _accessTokenExpiresAt_extraInitializers = [];
359
+ let _expiresAt_decorators;
360
+ let _expiresAt_initializers = [];
361
+ let _expiresAt_extraInitializers = [];
362
+ let _rotatedAt_decorators;
363
+ let _rotatedAt_initializers = [];
364
+ let _rotatedAt_extraInitializers = [];
365
+ return class RelyingPartyBearerTokenDoc extends _classSuper {
366
+ static {
367
+ const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
368
+ _id_decorators = [plugins.nosqldb.unI()];
369
+ _accessTokenHash_decorators = [plugins.nosqldb.unI()];
370
+ _refreshTokenHash_decorators = [plugins.nosqldb.unI()];
371
+ _sessionId_decorators = [plugins.nosqldb.svDb()];
372
+ _createdAt_decorators = [plugins.nosqldb.svDb()];
373
+ _accessTokenExpiresAt_decorators = [plugins.nosqldb.svDb()];
374
+ _expiresAt_decorators = [plugins.nosqldb.svDb(), plugins.nosqldb.index()];
375
+ _rotatedAt_decorators = [plugins.nosqldb.svDb()];
376
+ __esDecorate(null, null, _id_decorators, { kind: "field", name: "id", static: false, private: false, access: { has: obj => "id" in obj, get: obj => obj.id, set: (obj, value) => { obj.id = value; } }, metadata: _metadata }, _id_initializers, _id_extraInitializers);
377
+ __esDecorate(null, null, _accessTokenHash_decorators, { kind: "field", name: "accessTokenHash", static: false, private: false, access: { has: obj => "accessTokenHash" in obj, get: obj => obj.accessTokenHash, set: (obj, value) => { obj.accessTokenHash = value; } }, metadata: _metadata }, _accessTokenHash_initializers, _accessTokenHash_extraInitializers);
378
+ __esDecorate(null, null, _refreshTokenHash_decorators, { kind: "field", name: "refreshTokenHash", static: false, private: false, access: { has: obj => "refreshTokenHash" in obj, get: obj => obj.refreshTokenHash, set: (obj, value) => { obj.refreshTokenHash = value; } }, metadata: _metadata }, _refreshTokenHash_initializers, _refreshTokenHash_extraInitializers);
379
+ __esDecorate(null, null, _sessionId_decorators, { kind: "field", name: "sessionId", static: false, private: false, access: { has: obj => "sessionId" in obj, get: obj => obj.sessionId, set: (obj, value) => { obj.sessionId = value; } }, metadata: _metadata }, _sessionId_initializers, _sessionId_extraInitializers);
380
+ __esDecorate(null, null, _createdAt_decorators, { kind: "field", name: "createdAt", static: false, private: false, access: { has: obj => "createdAt" in obj, get: obj => obj.createdAt, set: (obj, value) => { obj.createdAt = value; } }, metadata: _metadata }, _createdAt_initializers, _createdAt_extraInitializers);
381
+ __esDecorate(null, null, _accessTokenExpiresAt_decorators, { kind: "field", name: "accessTokenExpiresAt", static: false, private: false, access: { has: obj => "accessTokenExpiresAt" in obj, get: obj => obj.accessTokenExpiresAt, set: (obj, value) => { obj.accessTokenExpiresAt = value; } }, metadata: _metadata }, _accessTokenExpiresAt_initializers, _accessTokenExpiresAt_extraInitializers);
382
+ __esDecorate(null, null, _expiresAt_decorators, { kind: "field", name: "expiresAt", static: false, private: false, access: { has: obj => "expiresAt" in obj, get: obj => obj.expiresAt, set: (obj, value) => { obj.expiresAt = value; } }, metadata: _metadata }, _expiresAt_initializers, _expiresAt_extraInitializers);
383
+ __esDecorate(null, null, _rotatedAt_decorators, { kind: "field", name: "rotatedAt", static: false, private: false, access: { has: obj => "rotatedAt" in obj, get: obj => obj.rotatedAt, set: (obj, value) => { obj.rotatedAt = value; } }, metadata: _metadata }, _rotatedAt_initializers, _rotatedAt_extraInitializers);
384
+ if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
385
+ }
386
+ id = __runInitializers(this, _id_initializers, '');
387
+ accessTokenHash = (__runInitializers(this, _id_extraInitializers), __runInitializers(this, _accessTokenHash_initializers, ''));
388
+ refreshTokenHash = (__runInitializers(this, _accessTokenHash_extraInitializers), __runInitializers(this, _refreshTokenHash_initializers, ''));
389
+ sessionId = (__runInitializers(this, _refreshTokenHash_extraInitializers), __runInitializers(this, _sessionId_initializers, ''));
390
+ createdAt = (__runInitializers(this, _sessionId_extraInitializers), __runInitializers(this, _createdAt_initializers, 0));
391
+ accessTokenExpiresAt = (__runInitializers(this, _createdAt_extraInitializers), __runInitializers(this, _accessTokenExpiresAt_initializers, 0));
392
+ /** the session's end; the refresh token never outlives it, and the sweep removes the generation after it */
393
+ expiresAt = (__runInitializers(this, _accessTokenExpiresAt_extraInitializers), __runInitializers(this, _expiresAt_initializers, 0));
394
+ /** `null` while this generation is current; when its refresh token was spent otherwise */
395
+ rotatedAt = (__runInitializers(this, _expiresAt_extraInitializers), __runInitializers(this, _rotatedAt_initializers, null));
396
+ constructor() {
397
+ super(...arguments);
398
+ __runInitializers(this, _rotatedAt_extraInitializers);
399
+ }
400
+ };
401
+ })();
402
+ export { RelyingPartyBearerTokenDoc };
236
403
  export const RELYING_PARTY_DEFAULT_COLLECTION_NAMES = {
237
404
  sessions: 'IdpRelyingPartySession',
238
405
  loginAttempts: 'IdpRelyingPartyLoginAttempt',
406
+ bearerHandoffs: 'IdpRelyingPartyBearerHandoff',
407
+ bearerTokens: 'IdpRelyingPartyBearerToken',
239
408
  };
240
409
  /**
241
- * Binds the two relying-party models to one database. Each call declares its
410
+ * Binds the relying-party models to one database. Each call declares its
242
411
  * own model classes, so several databases — and several applications in one
243
412
  * process — never share a binding. A deferred `db` is resolved on every use,
244
413
  * the way `@Collection(() => db)` resolves it; a use before it answers a
@@ -268,6 +437,10 @@ export const createRelyingPartyModels = (optionsArg) => {
268
437
  const sessions = optionsArg.collectionNames?.sessions ?? RELYING_PARTY_DEFAULT_COLLECTION_NAMES.sessions;
269
438
  const loginAttempts = optionsArg.collectionNames?.loginAttempts
270
439
  ?? RELYING_PARTY_DEFAULT_COLLECTION_NAMES.loginAttempts;
440
+ const bearerHandoffs = optionsArg.collectionNames?.bearerHandoffs
441
+ ?? RELYING_PARTY_DEFAULT_COLLECTION_NAMES.bearerHandoffs;
442
+ const bearerTokens = optionsArg.collectionNames?.bearerTokens
443
+ ?? RELYING_PARTY_DEFAULT_COLLECTION_NAMES.bearerTokens;
271
444
  let BoundSessionDoc = (() => {
272
445
  let _classDecorators = [plugins.nosqldb.Collection(resolveDb, { collectionName: sessions })];
273
446
  let _classDescriptor;
@@ -304,6 +477,47 @@ export const createRelyingPartyModels = (optionsArg) => {
304
477
  };
305
478
  return BoundLoginAttemptDoc = _classThis;
306
479
  })();
307
- return { Session: BoundSessionDoc, LoginAttempt: BoundLoginAttemptDoc };
480
+ let BoundBearerHandoffDoc = (() => {
481
+ let _classDecorators = [plugins.nosqldb.Collection(resolveDb, { collectionName: bearerHandoffs })];
482
+ let _classDescriptor;
483
+ let _classExtraInitializers = [];
484
+ let _classThis;
485
+ let _classSuper = RelyingPartyBearerHandoffDoc;
486
+ var BoundBearerHandoffDoc = class extends _classSuper {
487
+ static { _classThis = this; }
488
+ static {
489
+ const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
490
+ __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
491
+ BoundBearerHandoffDoc = _classThis = _classDescriptor.value;
492
+ if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
493
+ __runInitializers(_classThis, _classExtraInitializers);
494
+ }
495
+ };
496
+ return BoundBearerHandoffDoc = _classThis;
497
+ })();
498
+ let BoundBearerTokenDoc = (() => {
499
+ let _classDecorators = [plugins.nosqldb.Collection(resolveDb, { collectionName: bearerTokens })];
500
+ let _classDescriptor;
501
+ let _classExtraInitializers = [];
502
+ let _classThis;
503
+ let _classSuper = RelyingPartyBearerTokenDoc;
504
+ var BoundBearerTokenDoc = class extends _classSuper {
505
+ static { _classThis = this; }
506
+ static {
507
+ const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
508
+ __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
509
+ BoundBearerTokenDoc = _classThis = _classDescriptor.value;
510
+ if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
511
+ __runInitializers(_classThis, _classExtraInitializers);
512
+ }
513
+ };
514
+ return BoundBearerTokenDoc = _classThis;
515
+ })();
516
+ return {
517
+ Session: BoundSessionDoc,
518
+ LoginAttempt: BoundLoginAttemptDoc,
519
+ BearerHandoff: BoundBearerHandoffDoc,
520
+ BearerToken: BoundBearerTokenDoc,
521
+ };
308
522
  };
309
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5ycG1vZGVscy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3RzX3JlbHlpbmdwYXJ0eS9jbGFzc2VzLnJwbW9kZWxzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLGNBQWMsQ0FBQztBQUN4QyxPQUFPLEVBQUUsb0NBQW9DLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUUzRTs7Ozs7R0FLRztJQUNVLHNCQUFzQjtzQkFBUyxPQUFPLENBQUMsT0FBTyxDQUFDLGNBQWM7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7aUJBQTdELHNCQUF1QixTQUFRLFdBQThFOzs7OEJBQ3ZILE9BQU8sQ0FBQyxPQUFPLENBQUMsR0FBRyxFQUFFO3FDQUlyQixPQUFPLENBQUMsT0FBTyxDQUFDLEdBQUcsRUFBRTtrQ0FJckIsT0FBTyxDQUFDLE9BQU8sQ0FBQyxJQUFJLEVBQUUsRUFDdEIsT0FBTyxDQUFDLE9BQU8sQ0FBQyxLQUFLLEVBQUU7cUNBR3ZCLE9BQU8sQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFFO3NDQUd0QixPQUFPLENBQUMsT0FBTyxDQUFDLElBQUksRUFBRTtxQ0FHdEIsT0FBTyxDQUFDLE9BQU8sQ0FBQyxJQUFJLEVBQUU7cUNBSXRCLE9BQU8sQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFFO3NDQUl0QixPQUFPLENBQUMsT0FBTyxDQUFDLElBQUksRUFBRTswQ0FJdEIsT0FBTyxDQUFDLE9BQU8sQ0FBQyxJQUFJLEVBQUU7NkNBSXRCLE9BQU8sQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFFOzhDQUd0QixPQUFPLENBQUMsT0FBTyxDQUFDLElBQUksRUFBRTtnREFJdEIsT0FBTyxDQUFDLE9BQU8sQ0FBQyxJQUFJLEVBQUU7NENBSXRCLE9BQU8sQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFFO1lBNUN2Qix3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
523
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5ycG1vZGVscy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3RzX3JlbHlpbmdwYXJ0eS9jbGFzc2VzLnJwbW9kZWxzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLGNBQWMsQ0FBQztBQUN4QyxPQUFPLEVBQUUsb0NBQW9DLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUczRTs7Ozs7O0dBTUc7SUFDVSxzQkFBc0I7c0JBQVMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxjQUFjOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O2lCQUE3RCxzQkFBdUIsU0FBUSxXQUE4RTs7OzhCQUN2SCxPQUFPLENBQUMsT0FBTyxDQUFDLEdBQUcsRUFBRTtxQ0FJckIsT0FBTyxDQUFDLE9BQU8sQ0FBQyxHQUFHLEVBQUU7a0NBSXJCLE9BQU8sQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFFLEVBQ3RCLE9BQU8sQ0FBQyxPQUFPLENBQUMsS0FBSyxFQUFFO3FDQUd2QixPQUFPLENBQUMsT0FBTyxDQUFDLElBQUksRUFBRTtzQ0FHdEIsT0FBTyxDQUFDLE9BQU8sQ0FBQyxJQUFJLEVBQUU7cUNBSXRCLE9BQU8sQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFFLEVBQ3RCLE9BQU8sQ0FBQyxPQUFPLENBQUMsS0FBSyxFQUFFO3FDQUl2QixPQUFPLENBQUMsT0FBTyxDQUFDLElBQUksRUFBRTtzQ0FJdEIsT0FBTyxDQUFDLE9BQU8sQ0FBQyxJQUFJLEVBQUU7MENBSXRCLE9BQU8sQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFFOzZDQUl0QixPQUFPLENBQUMsT0FBTyxDQUFDLElBQUksRUFBRTs4Q0FHdEIsT0FBTyxDQUFDLE9BQU8sQ0FBQyxJQUFJLEVBQUU7Z0RBSXRCLE9BQU8sQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFFOzRDQUl0QixP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
@@ -0,0 +1,82 @@
1
+ /**
2
+ * The wire contract of the bearer hand-off routes: what a bearer client sends
3
+ * and what it is answered. This module imports nothing, so the browser client
4
+ * (`@idp.global/sdk/browser`) shares it with the routes without reaching any
5
+ * server code; keep it that way.
6
+ */
7
+ /** The `type` of every message a popup delivery posts. */
8
+ export declare const RELYING_PARTY_BEARER_MESSAGE_TYPE = "idp.global/relyingparty:bearer-handoff";
9
+ /**
10
+ * How a bearer client receives the outcome of its login:
11
+ *
12
+ * - `web`: a redirect to a same-origin path of the application
13
+ * - `loopback`: a redirect to `http://127.0.0.1:<port>/…` or `http://[::1]:<port>/…`, any port (RFC 8252)
14
+ * - `custom_scheme`: a redirect to a registered private-use URI scheme such as `com.example.app:/signed-in` (RFC 8252)
15
+ * - `popup`: a page that posts the outcome to `window.opener` at exactly one registered origin
16
+ */
17
+ export type TRelyingPartyBearerClientKind = 'web' | 'loopback' | 'custom_scheme' | 'popup';
18
+ /**
19
+ * What the popup page of a `popup` delivery posts to `window.opener`. The
20
+ * receiver accepts it only when `event.origin` is the relying party's public
21
+ * origin, `event.source` is the popup it opened, `type` is
22
+ * `RELYING_PARTY_BEARER_MESSAGE_TYPE` and `state` is its own.
23
+ */
24
+ export interface IRelyingPartyBearerMessage {
25
+ type: string;
26
+ /** the hand-off code; absent when the login failed */
27
+ code?: string;
28
+ /** why the login failed (`TRelyingPartyBearerDeliveryError`); absent when it succeeded */
29
+ error?: string;
30
+ state?: string;
31
+ }
32
+ /**
33
+ * Why a bearer login delivered no code, as the `error` of its redirect or
34
+ * popup message: `access_denied` when the provider came back without one,
35
+ * `authentication_failed` when the login could not be completed, or the code
36
+ * of the application's own refusal (`RelyingPartyRefusal.code`).
37
+ */
38
+ export type TRelyingPartyBearerDeliveryError = 'access_denied' | 'authentication_failed' | (string & {});
39
+ /** The session a bearer answer names. */
40
+ export interface IRelyingPartyBearerSessionInfo {
41
+ sessionId: string;
42
+ principalId: string;
43
+ /** epoch milliseconds: the end of the session, which no refresh extends */
44
+ expiresAt: number;
45
+ }
46
+ /** What `POST <prefix>bearer/claim` and `POST <prefix>bearer/refresh` answer with status 200. */
47
+ export interface IRelyingPartyBearerTokenAnswer {
48
+ tokenType: 'Bearer';
49
+ accessToken: string;
50
+ /** epoch milliseconds on the relying party's clock */
51
+ accessTokenExpiresAt: number;
52
+ /** seconds the access token lives from the answer, for a client whose clock differs */
53
+ expiresIn: number;
54
+ /** spent by the next refresh; it never comes back after that */
55
+ refreshToken: string;
56
+ /** epoch milliseconds: the end of the session */
57
+ refreshTokenExpiresAt: number;
58
+ session: IRelyingPartyBearerSessionInfo;
59
+ }
60
+ /** What `GET <prefix>bearer/session` answers with status 200; `null` for any token that is not live. */
61
+ export interface IRelyingPartyBearerSessionAnswer {
62
+ session: IRelyingPartyBearerSessionInfo | null;
63
+ }
64
+ /** What `POST <prefix>bearer/logout` answers with status 200; `true` only when this call ended a live session. */
65
+ export interface IRelyingPartyBearerLogoutAnswer {
66
+ endedLiveSession: boolean;
67
+ }
68
+ /**
69
+ * The `error` of a failed bearer route, answered as `{ error }`:
70
+ *
71
+ * - `invalid_bearer_request` (400): a login start or claim with a missing or malformed parameter
72
+ * - `return_target_not_allowed` (400): a login start naming a return target not configured for its kind
73
+ * - `invalid_bearer_handoff` (400): a claim with a code that is unknown, expired, already claimed or of the wrong verifier
74
+ * - `invalid_bearer_grant` (400): a refresh token that is unknown, spent, expired or of a session that is over
75
+ * - `authority_unavailable` (503): a refresh that could not reach the provider; nothing was spent, retry it
76
+ * - `authentication_unavailable` (503): any other failure on the relying party's side
77
+ * - `forbidden` (403): a CORS preflight from an origin that is no popup return target
78
+ */
79
+ export type TRelyingPartyBearerErrorCode = 'invalid_bearer_request' | 'return_target_not_allowed' | 'invalid_bearer_handoff' | 'invalid_bearer_grant' | 'authority_unavailable' | 'authentication_unavailable' | 'forbidden';
80
+ export interface IRelyingPartyBearerErrorAnswer {
81
+ error: TRelyingPartyBearerErrorCode;
82
+ }
@@ -0,0 +1,9 @@
1
+ /**
2
+ * The wire contract of the bearer hand-off routes: what a bearer client sends
3
+ * and what it is answered. This module imports nothing, so the browser client
4
+ * (`@idp.global/sdk/browser`) shares it with the routes without reaching any
5
+ * server code; keep it that way.
6
+ */
7
+ /** The `type` of every message a popup delivery posts. */
8
+ export const RELYING_PARTY_BEARER_MESSAGE_TYPE = 'idp.global/relyingparty:bearer-handoff';
9
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29udHJhY3QuYmVhcmVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vdHNfcmVseWluZ3BhcnR5L2NvbnRyYWN0LmJlYXJlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7R0FLRztBQUVILDBEQUEwRDtBQUMxRCxNQUFNLENBQUMsTUFBTSxpQ0FBaUMsR0FBRyx3Q0FBd0MsQ0FBQyJ9
@@ -0,0 +1,48 @@
1
+ import { RELYING_PARTY_BEARER_MESSAGE_TYPE, type IRelyingPartyBearerMessage, type TRelyingPartyBearerClientKind } from './contract.bearer.js';
2
+ import type { IRelyingPartyBearerDelivery, IRelyingPartyBearerReturnTargets } from './interfaces.js';
3
+ export { RELYING_PARTY_BEARER_MESSAGE_TYPE };
4
+ export declare const RELYING_PARTY_BEARER_CLIENT_KINDS: readonly TRelyingPartyBearerClientKind[];
5
+ export declare const isBearerClientKind: (valueArg: unknown) => valueArg is TRelyingPartyBearerClientKind;
6
+ export declare const isPkceChallenge: (valueArg: unknown) => valueArg is string;
7
+ export declare const isPkceVerifier: (valueArg: unknown) => valueArg is string;
8
+ export declare const isBearerClientState: (valueArg: unknown) => valueArg is string;
9
+ /** The S256 challenge of a verifier: BASE64URL(SHA-256(ASCII(verifier))). */
10
+ export declare const pkceChallengeOf: (verifierArg: string) => string;
11
+ /** Whether a verifier answers a challenge under S256, compared in constant time. */
12
+ export declare const verifyPkceChallenge: (verifierArg: unknown, challengeArg: string) => boolean;
13
+ /**
14
+ * The return targets of a deployment, checked once: every entry has to be
15
+ * the exact canonical form a client can name, or the configuration is
16
+ * refused. A target with a query or a fragment is refused too, because the
17
+ * delivery adds its own query, and so is one with a `*`: nothing is a wildcard.
18
+ */
19
+ export declare const normalizeBearerReturnTargets: (targetsArg: IRelyingPartyBearerReturnTargets, publicOriginArg: string, loginPathPrefixArg: string) => Readonly<Required<IRelyingPartyBearerReturnTargets>>;
20
+ /**
21
+ * Whether a client may name this return target: an entry of its kind,
22
+ * exactly. A loopback target names its own port, which is the only part
23
+ * that is not compared; it has to be given in canonical form.
24
+ */
25
+ export declare const isBearerReturnTargetAllowed: (targetsArg: Readonly<Required<IRelyingPartyBearerReturnTargets>>, kindArg: TRelyingPartyBearerClientKind, candidateArg: unknown) => boolean;
26
+ /** The token of an `Authorization: Bearer <token>` header, or `null`. */
27
+ export declare const parseBearerAuthorization: (headerArg: string | null | undefined) => string | null;
28
+ /** What a delivery hands the client: the code, or why there is none. */
29
+ export type TRelyingPartyBearerOutcome = {
30
+ code: string;
31
+ } | {
32
+ error: string;
33
+ };
34
+ /** The location a redirect delivery sends the client to, with the outcome and its `state` in the query. */
35
+ export declare const bearerDeliveryLocation: (deliveryArg: IRelyingPartyBearerDelivery, outcomeArg: TRelyingPartyBearerOutcome, publicOriginArg: string) => string;
36
+ /** The message a popup delivery posts. */
37
+ export declare const bearerDeliveryMessage: (deliveryArg: IRelyingPartyBearerDelivery, outcomeArg: TRelyingPartyBearerOutcome) => IRelyingPartyBearerMessage;
38
+ /** The id of the element a popup page keeps its delivery in. */
39
+ export declare const RELYING_PARTY_BEARER_POPUP_DATA_ID = "idp-rp-bearer-delivery";
40
+ /**
41
+ * The page of a popup delivery. Its one script, allowed by nonce alone,
42
+ * posts the message to `window.opener` with the registered origin as the
43
+ * target origin — never `*` — so a browser hands it to nobody else, and
44
+ * closes the window. The delivery is data in a JSON block, never script.
45
+ */
46
+ export declare const bearerPopupPage: (deliveryArg: IRelyingPartyBearerDelivery, outcomeArg: TRelyingPartyBearerOutcome, nonceArg: string) => string;
47
+ /** The policy of a popup page: its nonce script and nothing else. */
48
+ export declare const bearerPopupContentSecurityPolicy: (nonceArg: string) => string;