@dereekb/util 13.23.0 → 13.25.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/eslint/index.cjs.js +433 -106
- package/eslint/index.esm.js +414 -107
- package/eslint/package.json +4 -3
- package/eslint/src/lib/index.d.ts +1 -0
- package/eslint/src/lib/no-enum-literal-cast.rule.d.ts +51 -0
- package/eslint/src/lib/plugin.d.ts +2 -0
- package/fetch/package.json +2 -2
- package/index.cjs.js +768 -191
- package/index.esm.js +761 -192
- package/oidc/LICENSE +21 -0
- package/oidc/index.cjs.default.js +1 -0
- package/oidc/index.cjs.js +1071 -0
- package/oidc/index.cjs.mjs +2 -0
- package/oidc/index.d.ts +1 -0
- package/oidc/index.esm.js +1057 -0
- package/oidc/package.json +19 -0
- package/oidc/src/index.d.ts +1 -0
- package/oidc/src/lib/index.d.ts +2 -0
- package/oidc/src/lib/oidc.protocol.d.ts +96 -0
- package/oidc/src/lib/oidc.token.d.ts +175 -0
- package/package.json +7 -1
- package/src/lib/auth/oauth.d.ts +277 -0
- package/test/package.json +2 -2
|
@@ -0,0 +1,1057 @@
|
|
|
1
|
+
import { OidcRelyingPartyError, buildOidcDiscoveryCandidates, expirationDetails, inMemoryAsyncValueCache, calculateExpirationDate, MS_IN_SECOND } from '@dereekb/util';
|
|
2
|
+
|
|
3
|
+
function asyncGeneratorStep$1(gen, resolve, reject, _next, _throw, key, arg) {
|
|
4
|
+
try {
|
|
5
|
+
var info = gen[key](arg);
|
|
6
|
+
var value = info.value;
|
|
7
|
+
} catch (error) {
|
|
8
|
+
reject(error);
|
|
9
|
+
return;
|
|
10
|
+
}
|
|
11
|
+
if (info.done) {
|
|
12
|
+
resolve(value);
|
|
13
|
+
} else {
|
|
14
|
+
Promise.resolve(value).then(_next, _throw);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
function _async_to_generator$1(fn) {
|
|
18
|
+
return function() {
|
|
19
|
+
var self = this, args = arguments;
|
|
20
|
+
return new Promise(function(resolve, reject) {
|
|
21
|
+
var gen = fn.apply(self, args);
|
|
22
|
+
function _next(value) {
|
|
23
|
+
asyncGeneratorStep$1(gen, resolve, reject, _next, _throw, "next", value);
|
|
24
|
+
}
|
|
25
|
+
function _throw(err) {
|
|
26
|
+
asyncGeneratorStep$1(gen, resolve, reject, _next, _throw, "throw", err);
|
|
27
|
+
}
|
|
28
|
+
_next(undefined);
|
|
29
|
+
});
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
function _define_property$1(obj, key, value) {
|
|
33
|
+
if (key in obj) {
|
|
34
|
+
Object.defineProperty(obj, key, {
|
|
35
|
+
value: value,
|
|
36
|
+
enumerable: true,
|
|
37
|
+
configurable: true,
|
|
38
|
+
writable: true
|
|
39
|
+
});
|
|
40
|
+
} else {
|
|
41
|
+
obj[key] = value;
|
|
42
|
+
}
|
|
43
|
+
return obj;
|
|
44
|
+
}
|
|
45
|
+
function _instanceof$1(left, right) {
|
|
46
|
+
"@swc/helpers - instanceof";
|
|
47
|
+
if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) {
|
|
48
|
+
return !!right[Symbol.hasInstance](left);
|
|
49
|
+
} else {
|
|
50
|
+
return left instanceof right;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
function _object_spread$1(target) {
|
|
54
|
+
for(var i = 1; i < arguments.length; i++){
|
|
55
|
+
var source = arguments[i] != null ? arguments[i] : {};
|
|
56
|
+
var ownKeys = Object.keys(source);
|
|
57
|
+
if (typeof Object.getOwnPropertySymbols === "function") {
|
|
58
|
+
ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function(sym) {
|
|
59
|
+
return Object.getOwnPropertyDescriptor(source, sym).enumerable;
|
|
60
|
+
}));
|
|
61
|
+
}
|
|
62
|
+
ownKeys.forEach(function(key) {
|
|
63
|
+
_define_property$1(target, key, source[key]);
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
return target;
|
|
67
|
+
}
|
|
68
|
+
function _ts_generator$1(thisArg, body) {
|
|
69
|
+
var f, y, t, _ = {
|
|
70
|
+
label: 0,
|
|
71
|
+
sent: function() {
|
|
72
|
+
if (t[0] & 1) throw t[1];
|
|
73
|
+
return t[1];
|
|
74
|
+
},
|
|
75
|
+
trys: [],
|
|
76
|
+
ops: []
|
|
77
|
+
}, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype), d = Object.defineProperty;
|
|
78
|
+
return d(g, "next", {
|
|
79
|
+
value: verb(0)
|
|
80
|
+
}), d(g, "throw", {
|
|
81
|
+
value: verb(1)
|
|
82
|
+
}), d(g, "return", {
|
|
83
|
+
value: verb(2)
|
|
84
|
+
}), typeof Symbol === "function" && d(g, Symbol.iterator, {
|
|
85
|
+
value: function() {
|
|
86
|
+
return this;
|
|
87
|
+
}
|
|
88
|
+
}), g;
|
|
89
|
+
function verb(n) {
|
|
90
|
+
return function(v) {
|
|
91
|
+
return step([
|
|
92
|
+
n,
|
|
93
|
+
v
|
|
94
|
+
]);
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
function step(op) {
|
|
98
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
99
|
+
while(g && (g = 0, op[0] && (_ = 0)), _)try {
|
|
100
|
+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
101
|
+
if (y = 0, t) op = [
|
|
102
|
+
op[0] & 2,
|
|
103
|
+
t.value
|
|
104
|
+
];
|
|
105
|
+
switch(op[0]){
|
|
106
|
+
case 0:
|
|
107
|
+
case 1:
|
|
108
|
+
t = op;
|
|
109
|
+
break;
|
|
110
|
+
case 4:
|
|
111
|
+
_.label++;
|
|
112
|
+
return {
|
|
113
|
+
value: op[1],
|
|
114
|
+
done: false
|
|
115
|
+
};
|
|
116
|
+
case 5:
|
|
117
|
+
_.label++;
|
|
118
|
+
y = op[1];
|
|
119
|
+
op = [
|
|
120
|
+
0
|
|
121
|
+
];
|
|
122
|
+
continue;
|
|
123
|
+
case 7:
|
|
124
|
+
op = _.ops.pop();
|
|
125
|
+
_.trys.pop();
|
|
126
|
+
continue;
|
|
127
|
+
default:
|
|
128
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) {
|
|
129
|
+
_ = 0;
|
|
130
|
+
continue;
|
|
131
|
+
}
|
|
132
|
+
if (op[0] === 3 && (!t || op[1] > t[0] && op[1] < t[3])) {
|
|
133
|
+
_.label = op[1];
|
|
134
|
+
break;
|
|
135
|
+
}
|
|
136
|
+
if (op[0] === 6 && _.label < t[1]) {
|
|
137
|
+
_.label = t[1];
|
|
138
|
+
t = op;
|
|
139
|
+
break;
|
|
140
|
+
}
|
|
141
|
+
if (t && _.label < t[2]) {
|
|
142
|
+
_.label = t[2];
|
|
143
|
+
_.ops.push(op);
|
|
144
|
+
break;
|
|
145
|
+
}
|
|
146
|
+
if (t[2]) _.ops.pop();
|
|
147
|
+
_.trys.pop();
|
|
148
|
+
continue;
|
|
149
|
+
}
|
|
150
|
+
op = body.call(thisArg, _);
|
|
151
|
+
} catch (e) {
|
|
152
|
+
op = [
|
|
153
|
+
6,
|
|
154
|
+
e
|
|
155
|
+
];
|
|
156
|
+
y = 0;
|
|
157
|
+
} finally{
|
|
158
|
+
f = t = 0;
|
|
159
|
+
}
|
|
160
|
+
if (op[0] & 5) throw op[1];
|
|
161
|
+
return {
|
|
162
|
+
value: op[0] ? op[1] : void 0,
|
|
163
|
+
done: true
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
// MARK: Discovery
|
|
168
|
+
/**
|
|
169
|
+
* Fetches the OIDC discovery document for the given issuer, trying the candidates returned by
|
|
170
|
+
* {@link buildOidcDiscoveryCandidates} in order.
|
|
171
|
+
*
|
|
172
|
+
* @param input - The discovery request plus the injected fetch transport.
|
|
173
|
+
* @param input.issuer - The OIDC issuer URL whose `.well-known/openid-configuration` is fetched first.
|
|
174
|
+
* @param input.fallbackBaseUrl - Optional sibling base URL tried after the issuer-prefixed and origin-rooted candidates.
|
|
175
|
+
* @param input.fetch - The plain fetch transport.
|
|
176
|
+
* @returns The parsed {@link OidcDiscoveryMetadata}. Throws an {@link OidcRelyingPartyError} (`DISCOVERY_FAILED`) when every candidate fails.
|
|
177
|
+
*/ function discoverOidcMetadata(input) {
|
|
178
|
+
return _async_to_generator$1(function() {
|
|
179
|
+
var candidates, lastError, result, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, url, res, e, err, _ref;
|
|
180
|
+
return _ts_generator$1(this, function(_state) {
|
|
181
|
+
switch(_state.label){
|
|
182
|
+
case 0:
|
|
183
|
+
candidates = buildOidcDiscoveryCandidates(input);
|
|
184
|
+
_iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
|
|
185
|
+
_state.label = 1;
|
|
186
|
+
case 1:
|
|
187
|
+
_state.trys.push([
|
|
188
|
+
1,
|
|
189
|
+
10,
|
|
190
|
+
11,
|
|
191
|
+
12
|
|
192
|
+
]);
|
|
193
|
+
_iterator = candidates[Symbol.iterator]();
|
|
194
|
+
_state.label = 2;
|
|
195
|
+
case 2:
|
|
196
|
+
if (!!(_iteratorNormalCompletion = (_step = _iterator.next()).done)) return [
|
|
197
|
+
3,
|
|
198
|
+
9
|
|
199
|
+
];
|
|
200
|
+
url = _step.value;
|
|
201
|
+
_state.label = 3;
|
|
202
|
+
case 3:
|
|
203
|
+
_state.trys.push([
|
|
204
|
+
3,
|
|
205
|
+
7,
|
|
206
|
+
,
|
|
207
|
+
8
|
|
208
|
+
]);
|
|
209
|
+
return [
|
|
210
|
+
4,
|
|
211
|
+
input.fetch(url, {
|
|
212
|
+
headers: {
|
|
213
|
+
Accept: 'application/json'
|
|
214
|
+
}
|
|
215
|
+
})
|
|
216
|
+
];
|
|
217
|
+
case 4:
|
|
218
|
+
res = _state.sent();
|
|
219
|
+
if (!res.ok) return [
|
|
220
|
+
3,
|
|
221
|
+
6
|
|
222
|
+
];
|
|
223
|
+
return [
|
|
224
|
+
4,
|
|
225
|
+
res.json()
|
|
226
|
+
];
|
|
227
|
+
case 5:
|
|
228
|
+
result = _state.sent();
|
|
229
|
+
return [
|
|
230
|
+
3,
|
|
231
|
+
9
|
|
232
|
+
];
|
|
233
|
+
case 6:
|
|
234
|
+
lastError = new Error("OIDC discovery failed at ".concat(url, ": ").concat(res.status, " ").concat(res.statusText));
|
|
235
|
+
return [
|
|
236
|
+
3,
|
|
237
|
+
8
|
|
238
|
+
];
|
|
239
|
+
case 7:
|
|
240
|
+
e = _state.sent();
|
|
241
|
+
lastError = new Error("OIDC discovery failed at ".concat(url, ": ").concat(_instanceof$1(e, Error) ? e.message : String(e)));
|
|
242
|
+
return [
|
|
243
|
+
3,
|
|
244
|
+
8
|
|
245
|
+
];
|
|
246
|
+
case 8:
|
|
247
|
+
_iteratorNormalCompletion = true;
|
|
248
|
+
return [
|
|
249
|
+
3,
|
|
250
|
+
2
|
|
251
|
+
];
|
|
252
|
+
case 9:
|
|
253
|
+
return [
|
|
254
|
+
3,
|
|
255
|
+
12
|
|
256
|
+
];
|
|
257
|
+
case 10:
|
|
258
|
+
err = _state.sent();
|
|
259
|
+
_didIteratorError = true;
|
|
260
|
+
_iteratorError = err;
|
|
261
|
+
return [
|
|
262
|
+
3,
|
|
263
|
+
12
|
|
264
|
+
];
|
|
265
|
+
case 11:
|
|
266
|
+
try {
|
|
267
|
+
if (!_iteratorNormalCompletion && _iterator.return != null) {
|
|
268
|
+
_iterator.return();
|
|
269
|
+
}
|
|
270
|
+
} finally{
|
|
271
|
+
if (_didIteratorError) {
|
|
272
|
+
throw _iteratorError;
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
return [
|
|
276
|
+
7
|
|
277
|
+
];
|
|
278
|
+
case 12:
|
|
279
|
+
if (result == null) {
|
|
280
|
+
throw new OidcRelyingPartyError({
|
|
281
|
+
message: (_ref = lastError === null || lastError === void 0 ? void 0 : lastError.message) !== null && _ref !== void 0 ? _ref : "OIDC discovery failed for all candidates: ".concat(candidates.join(', ')),
|
|
282
|
+
code: 'DISCOVERY_FAILED',
|
|
283
|
+
_error: lastError
|
|
284
|
+
});
|
|
285
|
+
}
|
|
286
|
+
return [
|
|
287
|
+
2,
|
|
288
|
+
result
|
|
289
|
+
];
|
|
290
|
+
}
|
|
291
|
+
});
|
|
292
|
+
})();
|
|
293
|
+
}
|
|
294
|
+
// MARK: Token Endpoint
|
|
295
|
+
/**
|
|
296
|
+
* Exchanges an authorization code (from the redirect) for an access token + refresh token.
|
|
297
|
+
*
|
|
298
|
+
* Sends `client_secret` only when provided — public PKCE clients (`token_endpoint_auth_method: 'none'`)
|
|
299
|
+
* authenticate via the `code_verifier` alone.
|
|
300
|
+
*
|
|
301
|
+
* @param input - The token exchange parameters plus the injected fetch transport.
|
|
302
|
+
* @param input.tokenEndpoint - The OIDC token endpoint URL discovered from the issuer.
|
|
303
|
+
* @param input.clientId - The OAuth client ID.
|
|
304
|
+
* @param input.clientSecret - Optional client secret for `client_secret_post` auth; omit for public clients.
|
|
305
|
+
* @param input.redirectUri - The redirect URI registered with the OAuth client.
|
|
306
|
+
* @param input.code - The authorization code returned to the redirect URI.
|
|
307
|
+
* @param input.codeVerifier - The PKCE code verifier originally paired with the code challenge.
|
|
308
|
+
* @param input.fetch - The plain fetch transport.
|
|
309
|
+
* @returns The parsed {@link OidcTokenResponse} with access/refresh tokens.
|
|
310
|
+
*/ function exchangeAuthorizationCode(input) {
|
|
311
|
+
return _async_to_generator$1(function() {
|
|
312
|
+
var params;
|
|
313
|
+
return _ts_generator$1(this, function(_state) {
|
|
314
|
+
params = new URLSearchParams({
|
|
315
|
+
grant_type: 'authorization_code',
|
|
316
|
+
client_id: input.clientId,
|
|
317
|
+
redirect_uri: input.redirectUri,
|
|
318
|
+
code: input.code,
|
|
319
|
+
code_verifier: input.codeVerifier
|
|
320
|
+
});
|
|
321
|
+
if (input.clientSecret) {
|
|
322
|
+
params.set('client_secret', input.clientSecret);
|
|
323
|
+
}
|
|
324
|
+
return [
|
|
325
|
+
2,
|
|
326
|
+
postTokenEndpoint({
|
|
327
|
+
tokenEndpoint: input.tokenEndpoint,
|
|
328
|
+
body: params,
|
|
329
|
+
fetch: input.fetch
|
|
330
|
+
})
|
|
331
|
+
];
|
|
332
|
+
});
|
|
333
|
+
})();
|
|
334
|
+
}
|
|
335
|
+
/**
|
|
336
|
+
* Exchanges a refresh token for a new access token (and possibly a rotated refresh token).
|
|
337
|
+
*
|
|
338
|
+
* @param input - The refresh request plus the injected fetch transport.
|
|
339
|
+
* @param input.tokenEndpoint - The OIDC token endpoint URL discovered from the issuer.
|
|
340
|
+
* @param input.clientId - The OAuth client ID.
|
|
341
|
+
* @param input.clientSecret - Optional client secret; omit for public clients.
|
|
342
|
+
* @param input.refreshToken - The cached refresh token to redeem.
|
|
343
|
+
* @param input.fetch - The plain fetch transport.
|
|
344
|
+
* @returns The parsed {@link OidcTokenResponse} with the refreshed access token.
|
|
345
|
+
*/ function refreshAccessToken(input) {
|
|
346
|
+
return _async_to_generator$1(function() {
|
|
347
|
+
var params;
|
|
348
|
+
return _ts_generator$1(this, function(_state) {
|
|
349
|
+
params = new URLSearchParams({
|
|
350
|
+
grant_type: 'refresh_token',
|
|
351
|
+
client_id: input.clientId,
|
|
352
|
+
refresh_token: input.refreshToken
|
|
353
|
+
});
|
|
354
|
+
if (input.clientSecret) {
|
|
355
|
+
params.set('client_secret', input.clientSecret);
|
|
356
|
+
}
|
|
357
|
+
return [
|
|
358
|
+
2,
|
|
359
|
+
postTokenEndpoint({
|
|
360
|
+
tokenEndpoint: input.tokenEndpoint,
|
|
361
|
+
body: params,
|
|
362
|
+
fetch: input.fetch
|
|
363
|
+
})
|
|
364
|
+
];
|
|
365
|
+
});
|
|
366
|
+
})();
|
|
367
|
+
}
|
|
368
|
+
/**
|
|
369
|
+
* Revokes an access or refresh token at the OIDC revocation endpoint.
|
|
370
|
+
*
|
|
371
|
+
* @param input - The revocation request plus the injected fetch transport.
|
|
372
|
+
* @param input.revocationEndpoint - The OIDC revocation endpoint URL.
|
|
373
|
+
* @param input.clientId - The OAuth client ID.
|
|
374
|
+
* @param input.clientSecret - Optional client secret; omit for public clients.
|
|
375
|
+
* @param input.token - The access or refresh token to revoke.
|
|
376
|
+
* @param input.tokenTypeHint - Optional hint passed as `token_type_hint` (`access_token` or `refresh_token`).
|
|
377
|
+
* @param input.fetch - The plain fetch transport.
|
|
378
|
+
* @returns Resolves when the server returns a non-error status. Throws an {@link OidcRelyingPartyError} (`TOKEN_REVOCATION_FAILED`) on error.
|
|
379
|
+
*/ function revokeToken(input) {
|
|
380
|
+
return _async_to_generator$1(function() {
|
|
381
|
+
var params, res;
|
|
382
|
+
return _ts_generator$1(this, function(_state) {
|
|
383
|
+
switch(_state.label){
|
|
384
|
+
case 0:
|
|
385
|
+
params = new URLSearchParams(_object_spread$1({
|
|
386
|
+
client_id: input.clientId,
|
|
387
|
+
token: input.token
|
|
388
|
+
}, input.tokenTypeHint ? {
|
|
389
|
+
token_type_hint: input.tokenTypeHint
|
|
390
|
+
} : {}));
|
|
391
|
+
if (input.clientSecret) {
|
|
392
|
+
params.set('client_secret', input.clientSecret);
|
|
393
|
+
}
|
|
394
|
+
return [
|
|
395
|
+
4,
|
|
396
|
+
input.fetch(input.revocationEndpoint, {
|
|
397
|
+
method: 'POST',
|
|
398
|
+
headers: {
|
|
399
|
+
'Content-Type': 'application/x-www-form-urlencoded',
|
|
400
|
+
Accept: 'application/json'
|
|
401
|
+
},
|
|
402
|
+
body: params.toString()
|
|
403
|
+
})
|
|
404
|
+
];
|
|
405
|
+
case 1:
|
|
406
|
+
res = _state.sent();
|
|
407
|
+
if (!res.ok) {
|
|
408
|
+
throw new OidcRelyingPartyError({
|
|
409
|
+
message: "Token revocation failed: ".concat(res.status, " ").concat(res.statusText),
|
|
410
|
+
code: 'TOKEN_REVOCATION_FAILED'
|
|
411
|
+
});
|
|
412
|
+
}
|
|
413
|
+
return [
|
|
414
|
+
2
|
|
415
|
+
];
|
|
416
|
+
}
|
|
417
|
+
});
|
|
418
|
+
})();
|
|
419
|
+
}
|
|
420
|
+
// MARK: Userinfo + Session
|
|
421
|
+
/**
|
|
422
|
+
* Fetches the OIDC `userinfo` endpoint and returns the parsed claims object.
|
|
423
|
+
*
|
|
424
|
+
* @param input - The userinfo request plus the injected fetch transport.
|
|
425
|
+
* @param input.userinfoEndpoint - The OIDC userinfo endpoint URL discovered from the issuer.
|
|
426
|
+
* @param input.accessToken - The Bearer access token sent in the `Authorization` header.
|
|
427
|
+
* @param input.fetch - The fetch transport.
|
|
428
|
+
* @returns The parsed userinfo claims. Throws an {@link OidcRelyingPartyError} (`USERINFO_FAILED`) on a non-OK response.
|
|
429
|
+
*/ function fetchUserInfo(input) {
|
|
430
|
+
return _async_to_generator$1(function() {
|
|
431
|
+
var res;
|
|
432
|
+
return _ts_generator$1(this, function(_state) {
|
|
433
|
+
switch(_state.label){
|
|
434
|
+
case 0:
|
|
435
|
+
return [
|
|
436
|
+
4,
|
|
437
|
+
input.fetch(input.userinfoEndpoint, {
|
|
438
|
+
headers: {
|
|
439
|
+
Authorization: "Bearer ".concat(input.accessToken),
|
|
440
|
+
Accept: 'application/json'
|
|
441
|
+
}
|
|
442
|
+
})
|
|
443
|
+
];
|
|
444
|
+
case 1:
|
|
445
|
+
res = _state.sent();
|
|
446
|
+
if (!res.ok) {
|
|
447
|
+
throw new OidcRelyingPartyError({
|
|
448
|
+
message: "Userinfo request failed: ".concat(res.status, " ").concat(res.statusText),
|
|
449
|
+
code: 'USERINFO_FAILED'
|
|
450
|
+
});
|
|
451
|
+
}
|
|
452
|
+
return [
|
|
453
|
+
4,
|
|
454
|
+
res.json()
|
|
455
|
+
];
|
|
456
|
+
case 2:
|
|
457
|
+
return [
|
|
458
|
+
2,
|
|
459
|
+
_state.sent()
|
|
460
|
+
];
|
|
461
|
+
}
|
|
462
|
+
});
|
|
463
|
+
})();
|
|
464
|
+
}
|
|
465
|
+
/**
|
|
466
|
+
* Fetches the dbx-components `GET /oidc/session` route and returns the parsed session lifetime metadata.
|
|
467
|
+
*
|
|
468
|
+
* Mirrors {@link fetchUserInfo}, but reads the access token's baked-in session-lifetime claims
|
|
469
|
+
* (`dbx_session_expires_at` / `dbx_rotation_disabled`) which userinfo does not echo.
|
|
470
|
+
*
|
|
471
|
+
* @param input - The session request plus the injected fetch transport.
|
|
472
|
+
* @param input.sessionEndpoint - The `GET /oidc/session` endpoint URL.
|
|
473
|
+
* @param input.accessToken - The Bearer access token sent in the `Authorization` header.
|
|
474
|
+
* @param input.fetch - The fetch transport.
|
|
475
|
+
* @returns The parsed {@link OidcSessionInfo}. Throws an {@link OidcRelyingPartyError} (`SESSION_INFO_FAILED`) on a non-OK response.
|
|
476
|
+
*/ function fetchSessionInfo(input) {
|
|
477
|
+
return _async_to_generator$1(function() {
|
|
478
|
+
var res;
|
|
479
|
+
return _ts_generator$1(this, function(_state) {
|
|
480
|
+
switch(_state.label){
|
|
481
|
+
case 0:
|
|
482
|
+
return [
|
|
483
|
+
4,
|
|
484
|
+
input.fetch(input.sessionEndpoint, {
|
|
485
|
+
headers: {
|
|
486
|
+
Authorization: "Bearer ".concat(input.accessToken),
|
|
487
|
+
Accept: 'application/json'
|
|
488
|
+
}
|
|
489
|
+
})
|
|
490
|
+
];
|
|
491
|
+
case 1:
|
|
492
|
+
res = _state.sent();
|
|
493
|
+
if (!res.ok) {
|
|
494
|
+
throw new OidcRelyingPartyError({
|
|
495
|
+
message: "Session info request failed: ".concat(res.status, " ").concat(res.statusText),
|
|
496
|
+
code: 'SESSION_INFO_FAILED'
|
|
497
|
+
});
|
|
498
|
+
}
|
|
499
|
+
return [
|
|
500
|
+
4,
|
|
501
|
+
res.json()
|
|
502
|
+
];
|
|
503
|
+
case 2:
|
|
504
|
+
return [
|
|
505
|
+
2,
|
|
506
|
+
_state.sent()
|
|
507
|
+
];
|
|
508
|
+
}
|
|
509
|
+
});
|
|
510
|
+
})();
|
|
511
|
+
}
|
|
512
|
+
function postTokenEndpoint(input) {
|
|
513
|
+
return _async_to_generator$1(function() {
|
|
514
|
+
var res, body, _ref, _body_error_description, message;
|
|
515
|
+
return _ts_generator$1(this, function(_state) {
|
|
516
|
+
switch(_state.label){
|
|
517
|
+
case 0:
|
|
518
|
+
return [
|
|
519
|
+
4,
|
|
520
|
+
input.fetch(input.tokenEndpoint, {
|
|
521
|
+
method: 'POST',
|
|
522
|
+
headers: {
|
|
523
|
+
'Content-Type': 'application/x-www-form-urlencoded',
|
|
524
|
+
Accept: 'application/json'
|
|
525
|
+
},
|
|
526
|
+
body: input.body.toString()
|
|
527
|
+
})
|
|
528
|
+
];
|
|
529
|
+
case 1:
|
|
530
|
+
res = _state.sent();
|
|
531
|
+
return [
|
|
532
|
+
4,
|
|
533
|
+
res.json().catch(function() {
|
|
534
|
+
return {};
|
|
535
|
+
})
|
|
536
|
+
];
|
|
537
|
+
case 2:
|
|
538
|
+
body = _state.sent();
|
|
539
|
+
if (!res.ok || body.error) {
|
|
540
|
+
message = (_ref = (_body_error_description = body.error_description) !== null && _body_error_description !== void 0 ? _body_error_description : body.error) !== null && _ref !== void 0 ? _ref : "".concat(res.status, " ").concat(res.statusText);
|
|
541
|
+
throw new OidcRelyingPartyError({
|
|
542
|
+
message: "OIDC token endpoint error: ".concat(message),
|
|
543
|
+
code: body.error === 'invalid_grant' ? 'TOKEN_INVALID_GRANT' : 'TOKEN_EXCHANGE_FAILED'
|
|
544
|
+
});
|
|
545
|
+
}
|
|
546
|
+
if (!body.access_token) {
|
|
547
|
+
throw new OidcRelyingPartyError({
|
|
548
|
+
message: 'OIDC token endpoint returned no access_token.',
|
|
549
|
+
code: 'TOKEN_EXCHANGE_FAILED'
|
|
550
|
+
});
|
|
551
|
+
}
|
|
552
|
+
return [
|
|
553
|
+
2,
|
|
554
|
+
body
|
|
555
|
+
];
|
|
556
|
+
}
|
|
557
|
+
});
|
|
558
|
+
})();
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
|
|
562
|
+
try {
|
|
563
|
+
var info = gen[key](arg);
|
|
564
|
+
var value = info.value;
|
|
565
|
+
} catch (error) {
|
|
566
|
+
reject(error);
|
|
567
|
+
return;
|
|
568
|
+
}
|
|
569
|
+
if (info.done) {
|
|
570
|
+
resolve(value);
|
|
571
|
+
} else {
|
|
572
|
+
Promise.resolve(value).then(_next, _throw);
|
|
573
|
+
}
|
|
574
|
+
}
|
|
575
|
+
function _async_to_generator(fn) {
|
|
576
|
+
return function() {
|
|
577
|
+
var self = this, args = arguments;
|
|
578
|
+
return new Promise(function(resolve, reject) {
|
|
579
|
+
var gen = fn.apply(self, args);
|
|
580
|
+
function _next(value) {
|
|
581
|
+
asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
|
|
582
|
+
}
|
|
583
|
+
function _throw(err) {
|
|
584
|
+
asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
|
|
585
|
+
}
|
|
586
|
+
_next(undefined);
|
|
587
|
+
});
|
|
588
|
+
};
|
|
589
|
+
}
|
|
590
|
+
function _define_property(obj, key, value) {
|
|
591
|
+
if (key in obj) {
|
|
592
|
+
Object.defineProperty(obj, key, {
|
|
593
|
+
value: value,
|
|
594
|
+
enumerable: true,
|
|
595
|
+
configurable: true,
|
|
596
|
+
writable: true
|
|
597
|
+
});
|
|
598
|
+
} else {
|
|
599
|
+
obj[key] = value;
|
|
600
|
+
}
|
|
601
|
+
return obj;
|
|
602
|
+
}
|
|
603
|
+
function _instanceof(left, right) {
|
|
604
|
+
"@swc/helpers - instanceof";
|
|
605
|
+
if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) {
|
|
606
|
+
return !!right[Symbol.hasInstance](left);
|
|
607
|
+
} else {
|
|
608
|
+
return left instanceof right;
|
|
609
|
+
}
|
|
610
|
+
}
|
|
611
|
+
function _object_spread(target) {
|
|
612
|
+
for(var i = 1; i < arguments.length; i++){
|
|
613
|
+
var source = arguments[i] != null ? arguments[i] : {};
|
|
614
|
+
var ownKeys = Object.keys(source);
|
|
615
|
+
if (typeof Object.getOwnPropertySymbols === "function") {
|
|
616
|
+
ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function(sym) {
|
|
617
|
+
return Object.getOwnPropertyDescriptor(source, sym).enumerable;
|
|
618
|
+
}));
|
|
619
|
+
}
|
|
620
|
+
ownKeys.forEach(function(key) {
|
|
621
|
+
_define_property(target, key, source[key]);
|
|
622
|
+
});
|
|
623
|
+
}
|
|
624
|
+
return target;
|
|
625
|
+
}
|
|
626
|
+
function ownKeys(object, enumerableOnly) {
|
|
627
|
+
var keys = Object.keys(object);
|
|
628
|
+
if (Object.getOwnPropertySymbols) {
|
|
629
|
+
var symbols = Object.getOwnPropertySymbols(object);
|
|
630
|
+
keys.push.apply(keys, symbols);
|
|
631
|
+
}
|
|
632
|
+
return keys;
|
|
633
|
+
}
|
|
634
|
+
function _object_spread_props(target, source) {
|
|
635
|
+
source = source != null ? source : {};
|
|
636
|
+
if (Object.getOwnPropertyDescriptors) {
|
|
637
|
+
Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
|
|
638
|
+
} else {
|
|
639
|
+
ownKeys(Object(source)).forEach(function(key) {
|
|
640
|
+
Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
|
|
641
|
+
});
|
|
642
|
+
}
|
|
643
|
+
return target;
|
|
644
|
+
}
|
|
645
|
+
function _ts_generator(thisArg, body) {
|
|
646
|
+
var f, y, t, _ = {
|
|
647
|
+
label: 0,
|
|
648
|
+
sent: function() {
|
|
649
|
+
if (t[0] & 1) throw t[1];
|
|
650
|
+
return t[1];
|
|
651
|
+
},
|
|
652
|
+
trys: [],
|
|
653
|
+
ops: []
|
|
654
|
+
}, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype), d = Object.defineProperty;
|
|
655
|
+
return d(g, "next", {
|
|
656
|
+
value: verb(0)
|
|
657
|
+
}), d(g, "throw", {
|
|
658
|
+
value: verb(1)
|
|
659
|
+
}), d(g, "return", {
|
|
660
|
+
value: verb(2)
|
|
661
|
+
}), typeof Symbol === "function" && d(g, Symbol.iterator, {
|
|
662
|
+
value: function() {
|
|
663
|
+
return this;
|
|
664
|
+
}
|
|
665
|
+
}), g;
|
|
666
|
+
function verb(n) {
|
|
667
|
+
return function(v) {
|
|
668
|
+
return step([
|
|
669
|
+
n,
|
|
670
|
+
v
|
|
671
|
+
]);
|
|
672
|
+
};
|
|
673
|
+
}
|
|
674
|
+
function step(op) {
|
|
675
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
676
|
+
while(g && (g = 0, op[0] && (_ = 0)), _)try {
|
|
677
|
+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
678
|
+
if (y = 0, t) op = [
|
|
679
|
+
op[0] & 2,
|
|
680
|
+
t.value
|
|
681
|
+
];
|
|
682
|
+
switch(op[0]){
|
|
683
|
+
case 0:
|
|
684
|
+
case 1:
|
|
685
|
+
t = op;
|
|
686
|
+
break;
|
|
687
|
+
case 4:
|
|
688
|
+
_.label++;
|
|
689
|
+
return {
|
|
690
|
+
value: op[1],
|
|
691
|
+
done: false
|
|
692
|
+
};
|
|
693
|
+
case 5:
|
|
694
|
+
_.label++;
|
|
695
|
+
y = op[1];
|
|
696
|
+
op = [
|
|
697
|
+
0
|
|
698
|
+
];
|
|
699
|
+
continue;
|
|
700
|
+
case 7:
|
|
701
|
+
op = _.ops.pop();
|
|
702
|
+
_.trys.pop();
|
|
703
|
+
continue;
|
|
704
|
+
default:
|
|
705
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) {
|
|
706
|
+
_ = 0;
|
|
707
|
+
continue;
|
|
708
|
+
}
|
|
709
|
+
if (op[0] === 3 && (!t || op[1] > t[0] && op[1] < t[3])) {
|
|
710
|
+
_.label = op[1];
|
|
711
|
+
break;
|
|
712
|
+
}
|
|
713
|
+
if (op[0] === 6 && _.label < t[1]) {
|
|
714
|
+
_.label = t[1];
|
|
715
|
+
t = op;
|
|
716
|
+
break;
|
|
717
|
+
}
|
|
718
|
+
if (t && _.label < t[2]) {
|
|
719
|
+
_.label = t[2];
|
|
720
|
+
_.ops.push(op);
|
|
721
|
+
break;
|
|
722
|
+
}
|
|
723
|
+
if (t[2]) _.ops.pop();
|
|
724
|
+
_.trys.pop();
|
|
725
|
+
continue;
|
|
726
|
+
}
|
|
727
|
+
op = body.call(thisArg, _);
|
|
728
|
+
} catch (e) {
|
|
729
|
+
op = [
|
|
730
|
+
6,
|
|
731
|
+
e
|
|
732
|
+
];
|
|
733
|
+
y = 0;
|
|
734
|
+
} finally{
|
|
735
|
+
f = t = 0;
|
|
736
|
+
}
|
|
737
|
+
if (op[0] & 5) throw op[1];
|
|
738
|
+
return {
|
|
739
|
+
value: op[0] ? op[1] : void 0,
|
|
740
|
+
done: true
|
|
741
|
+
};
|
|
742
|
+
}
|
|
743
|
+
}
|
|
744
|
+
// MARK: Constants
|
|
745
|
+
/**
|
|
746
|
+
* Default pre-emptive refresh buffer in milliseconds.
|
|
747
|
+
*
|
|
748
|
+
* An access token is treated as needing a refresh this far ahead of its real expiry to absorb
|
|
749
|
+
* clock skew and request latency.
|
|
750
|
+
*/ var DEFAULT_OIDC_TOKEN_REFRESH_BUFFER_MS = 60000;
|
|
751
|
+
/**
|
|
752
|
+
* Normalizes an {@link OidcTokenResponse} into an {@link OidcTokenState}, converting the relative
|
|
753
|
+
* `expires_in` (seconds) into an absolute `expiresAt` (epoch ms) anchored at `config.now`.
|
|
754
|
+
*
|
|
755
|
+
* @param response - The token endpoint response to normalize.
|
|
756
|
+
* @param config - Optional anchoring time and pre-decoded claims.
|
|
757
|
+
* @returns The normalized {@link OidcTokenState}.
|
|
758
|
+
*/ function oidcTokenStateFromResponse(response, config) {
|
|
759
|
+
var _ref, _ref1;
|
|
760
|
+
var _calculateExpirationDate;
|
|
761
|
+
var nowMs = resolveNowMs(config === null || config === void 0 ? void 0 : config.now);
|
|
762
|
+
var expiresAt = response.expires_in == null ? undefined : (_ref = (_calculateExpirationDate = calculateExpirationDate({
|
|
763
|
+
expiresFromDate: nowMs,
|
|
764
|
+
expiresIn: response.expires_in * MS_IN_SECOND
|
|
765
|
+
})) === null || _calculateExpirationDate === void 0 ? void 0 : _calculateExpirationDate.getTime()) !== null && _ref !== void 0 ? _ref : undefined;
|
|
766
|
+
return {
|
|
767
|
+
accessToken: response.access_token,
|
|
768
|
+
refreshToken: response.refresh_token,
|
|
769
|
+
idToken: response.id_token,
|
|
770
|
+
tokenType: response.token_type,
|
|
771
|
+
scope: response.scope,
|
|
772
|
+
expiresAt: expiresAt,
|
|
773
|
+
claims: (_ref1 = config === null || config === void 0 ? void 0 : config.claims) !== null && _ref1 !== void 0 ? _ref1 : decodeJwtClaims(response.id_token)
|
|
774
|
+
};
|
|
775
|
+
}
|
|
776
|
+
// MARK: Expiry
|
|
777
|
+
/**
|
|
778
|
+
* Returns true when the access token's real expiry has already passed (no buffer applied), or when
|
|
779
|
+
* the state / its `expiresAt` is missing.
|
|
780
|
+
*
|
|
781
|
+
* @param state - The token state to inspect.
|
|
782
|
+
* @param now - Optional current time override.
|
|
783
|
+
* @returns Whether the access token has expired.
|
|
784
|
+
*/ function isAccessTokenExpired(state, now) {
|
|
785
|
+
return accessTokenNeedsRefresh(state, now, 0);
|
|
786
|
+
}
|
|
787
|
+
/**
|
|
788
|
+
* Returns true when the access token is expired or within `bufferMs` of expiry (pre-emptive
|
|
789
|
+
* refresh), or when the state / its `expiresAt` is missing.
|
|
790
|
+
*
|
|
791
|
+
* @param state - The token state to inspect.
|
|
792
|
+
* @param now - Optional current time override.
|
|
793
|
+
* @param bufferMs - Pre-emptive refresh buffer in milliseconds. Defaults to {@link DEFAULT_OIDC_TOKEN_REFRESH_BUFFER_MS}.
|
|
794
|
+
* @returns Whether the access token should be refreshed.
|
|
795
|
+
*/ function accessTokenNeedsRefresh(state, now) {
|
|
796
|
+
var bufferMs = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : DEFAULT_OIDC_TOKEN_REFRESH_BUFFER_MS;
|
|
797
|
+
var result = true;
|
|
798
|
+
if ((state === null || state === void 0 ? void 0 : state.expiresAt) != null) {
|
|
799
|
+
result = expirationDetails({
|
|
800
|
+
expiresFromDate: state.expiresAt,
|
|
801
|
+
expiresIn: -bufferMs,
|
|
802
|
+
now: new Date(resolveNowMs(now))
|
|
803
|
+
}).hasExpired();
|
|
804
|
+
}
|
|
805
|
+
return result;
|
|
806
|
+
}
|
|
807
|
+
/**
|
|
808
|
+
* Returns the milliseconds remaining until the access token should be pre-emptively refreshed
|
|
809
|
+
* (its real expiry minus `bufferMs`), clamped to a minimum of `0`.
|
|
810
|
+
*
|
|
811
|
+
* @param state - The token state to inspect.
|
|
812
|
+
* @param now - Optional current time override.
|
|
813
|
+
* @param bufferMs - Pre-emptive refresh buffer in milliseconds. Defaults to {@link DEFAULT_OIDC_TOKEN_REFRESH_BUFFER_MS}.
|
|
814
|
+
* @returns The delay in milliseconds, or `0` when already due / unknown.
|
|
815
|
+
*/ function nextRefreshDelay(state, now) {
|
|
816
|
+
var bufferMs = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : DEFAULT_OIDC_TOKEN_REFRESH_BUFFER_MS;
|
|
817
|
+
var result = 0;
|
|
818
|
+
if ((state === null || state === void 0 ? void 0 : state.expiresAt) != null) {
|
|
819
|
+
result = Math.max(0, state.expiresAt - bufferMs - resolveNowMs(now));
|
|
820
|
+
}
|
|
821
|
+
return result;
|
|
822
|
+
}
|
|
823
|
+
/**
|
|
824
|
+
* Creates an {@link OidcTokenManager} over the given storage + refresh function.
|
|
825
|
+
*
|
|
826
|
+
* - **Lazy** — refreshes only on demand (no timer), so it works unchanged in a CLI or browser.
|
|
827
|
+
* - **Single-flight** — concurrent `getValidAccessToken()` / `refreshNow()` calls share one
|
|
828
|
+
* in-flight refresh, so N callers trigger at most one network exchange.
|
|
829
|
+
* - **Rotation-safe** — a rotated `refresh_token` replaces the old one; when the response omits it,
|
|
830
|
+
* the prior refresh token is kept. The `id_token`/`claims` are likewise carried forward when a
|
|
831
|
+
* refresh response omits them.
|
|
832
|
+
* - **invalid_grant → logout** — a refresh that fails with `TOKEN_INVALID_GRANT` clears the store
|
|
833
|
+
* and surfaces as "no token" (`undefined`); other errors propagate.
|
|
834
|
+
*
|
|
835
|
+
* @param config - The manager configuration.
|
|
836
|
+
* @returns The configured {@link OidcTokenManager}.
|
|
837
|
+
*/ function oidcTokenManager(config) {
|
|
838
|
+
var _config_storage, _config_now, _config_refreshBufferMs;
|
|
839
|
+
var storage = (_config_storage = config.storage) !== null && _config_storage !== void 0 ? _config_storage : inMemoryAsyncValueCache();
|
|
840
|
+
var now = (_config_now = config.now) !== null && _config_now !== void 0 ? _config_now : function() {
|
|
841
|
+
return Date.now();
|
|
842
|
+
};
|
|
843
|
+
var refreshBufferMs = (_config_refreshBufferMs = config.refreshBufferMs) !== null && _config_refreshBufferMs !== void 0 ? _config_refreshBufferMs : DEFAULT_OIDC_TOKEN_REFRESH_BUFFER_MS;
|
|
844
|
+
var inFlight;
|
|
845
|
+
function performRefresh(state) {
|
|
846
|
+
return _async_to_generator(function() {
|
|
847
|
+
var result, _next_refreshToken, _next_idToken, _next_claims, response, next, merged, e;
|
|
848
|
+
return _ts_generator(this, function(_state) {
|
|
849
|
+
switch(_state.label){
|
|
850
|
+
case 0:
|
|
851
|
+
if (!state.refreshToken) return [
|
|
852
|
+
3,
|
|
853
|
+
8
|
|
854
|
+
];
|
|
855
|
+
_state.label = 1;
|
|
856
|
+
case 1:
|
|
857
|
+
_state.trys.push([
|
|
858
|
+
1,
|
|
859
|
+
4,
|
|
860
|
+
,
|
|
861
|
+
8
|
|
862
|
+
]);
|
|
863
|
+
return [
|
|
864
|
+
4,
|
|
865
|
+
config.refresh({
|
|
866
|
+
state: state,
|
|
867
|
+
refreshToken: state.refreshToken
|
|
868
|
+
})
|
|
869
|
+
];
|
|
870
|
+
case 2:
|
|
871
|
+
response = _state.sent();
|
|
872
|
+
next = oidcTokenStateFromResponse(response, {
|
|
873
|
+
now: now()
|
|
874
|
+
});
|
|
875
|
+
merged = _object_spread_props(_object_spread({}, next), {
|
|
876
|
+
refreshToken: (_next_refreshToken = next.refreshToken) !== null && _next_refreshToken !== void 0 ? _next_refreshToken : state.refreshToken,
|
|
877
|
+
idToken: (_next_idToken = next.idToken) !== null && _next_idToken !== void 0 ? _next_idToken : state.idToken,
|
|
878
|
+
claims: (_next_claims = next.claims) !== null && _next_claims !== void 0 ? _next_claims : state.claims
|
|
879
|
+
});
|
|
880
|
+
return [
|
|
881
|
+
4,
|
|
882
|
+
storage.update(merged)
|
|
883
|
+
];
|
|
884
|
+
case 3:
|
|
885
|
+
_state.sent();
|
|
886
|
+
result = merged;
|
|
887
|
+
return [
|
|
888
|
+
3,
|
|
889
|
+
8
|
|
890
|
+
];
|
|
891
|
+
case 4:
|
|
892
|
+
e = _state.sent();
|
|
893
|
+
if (!(_instanceof(e, OidcRelyingPartyError) && e.code === 'TOKEN_INVALID_GRANT')) return [
|
|
894
|
+
3,
|
|
895
|
+
6
|
|
896
|
+
];
|
|
897
|
+
return [
|
|
898
|
+
4,
|
|
899
|
+
storage.clear()
|
|
900
|
+
];
|
|
901
|
+
case 5:
|
|
902
|
+
_state.sent();
|
|
903
|
+
result = undefined;
|
|
904
|
+
return [
|
|
905
|
+
3,
|
|
906
|
+
7
|
|
907
|
+
];
|
|
908
|
+
case 6:
|
|
909
|
+
throw e;
|
|
910
|
+
case 7:
|
|
911
|
+
return [
|
|
912
|
+
3,
|
|
913
|
+
8
|
|
914
|
+
];
|
|
915
|
+
case 8:
|
|
916
|
+
return [
|
|
917
|
+
2,
|
|
918
|
+
result
|
|
919
|
+
];
|
|
920
|
+
}
|
|
921
|
+
});
|
|
922
|
+
})();
|
|
923
|
+
}
|
|
924
|
+
function refreshSingleFlight(state) {
|
|
925
|
+
if (inFlight == null) {
|
|
926
|
+
// Cache the in-flight refresh so concurrent callers share one network exchange. Cleared on
|
|
927
|
+
// settle so a failed refresh doesn't permanently block subsequent attempts.
|
|
928
|
+
inFlight = performRefresh(state).finally(function() {
|
|
929
|
+
inFlight = undefined;
|
|
930
|
+
});
|
|
931
|
+
}
|
|
932
|
+
return inFlight;
|
|
933
|
+
}
|
|
934
|
+
function getValidAccessToken() {
|
|
935
|
+
return _async_to_generator(function() {
|
|
936
|
+
var state, result, refreshed;
|
|
937
|
+
return _ts_generator(this, function(_state) {
|
|
938
|
+
switch(_state.label){
|
|
939
|
+
case 0:
|
|
940
|
+
return [
|
|
941
|
+
4,
|
|
942
|
+
storage.load()
|
|
943
|
+
];
|
|
944
|
+
case 1:
|
|
945
|
+
state = _state.sent();
|
|
946
|
+
if (!(state != null)) return [
|
|
947
|
+
3,
|
|
948
|
+
4
|
|
949
|
+
];
|
|
950
|
+
if (!accessTokenNeedsRefresh(state, now(), refreshBufferMs)) return [
|
|
951
|
+
3,
|
|
952
|
+
3
|
|
953
|
+
];
|
|
954
|
+
return [
|
|
955
|
+
4,
|
|
956
|
+
refreshSingleFlight(state)
|
|
957
|
+
];
|
|
958
|
+
case 2:
|
|
959
|
+
refreshed = _state.sent();
|
|
960
|
+
result = refreshed === null || refreshed === void 0 ? void 0 : refreshed.accessToken;
|
|
961
|
+
return [
|
|
962
|
+
3,
|
|
963
|
+
4
|
|
964
|
+
];
|
|
965
|
+
case 3:
|
|
966
|
+
result = state.accessToken;
|
|
967
|
+
_state.label = 4;
|
|
968
|
+
case 4:
|
|
969
|
+
return [
|
|
970
|
+
2,
|
|
971
|
+
result
|
|
972
|
+
];
|
|
973
|
+
}
|
|
974
|
+
});
|
|
975
|
+
})();
|
|
976
|
+
}
|
|
977
|
+
function refreshNow() {
|
|
978
|
+
return _async_to_generator(function() {
|
|
979
|
+
var state;
|
|
980
|
+
return _ts_generator(this, function(_state) {
|
|
981
|
+
switch(_state.label){
|
|
982
|
+
case 0:
|
|
983
|
+
return [
|
|
984
|
+
4,
|
|
985
|
+
storage.load()
|
|
986
|
+
];
|
|
987
|
+
case 1:
|
|
988
|
+
state = _state.sent();
|
|
989
|
+
return [
|
|
990
|
+
2,
|
|
991
|
+
state == null ? undefined : refreshSingleFlight(state)
|
|
992
|
+
];
|
|
993
|
+
}
|
|
994
|
+
});
|
|
995
|
+
})();
|
|
996
|
+
}
|
|
997
|
+
return {
|
|
998
|
+
getValidAccessToken: getValidAccessToken,
|
|
999
|
+
getState: function getState() {
|
|
1000
|
+
return storage.load();
|
|
1001
|
+
},
|
|
1002
|
+
setState: function setState(state) {
|
|
1003
|
+
return storage.update(state);
|
|
1004
|
+
},
|
|
1005
|
+
refreshNow: refreshNow,
|
|
1006
|
+
clear: function clear() {
|
|
1007
|
+
return storage.clear();
|
|
1008
|
+
}
|
|
1009
|
+
};
|
|
1010
|
+
}
|
|
1011
|
+
// MARK: Internal
|
|
1012
|
+
function resolveNowMs(now) {
|
|
1013
|
+
var result;
|
|
1014
|
+
if (now == null) {
|
|
1015
|
+
result = Date.now();
|
|
1016
|
+
} else if (_instanceof(now, Date)) {
|
|
1017
|
+
result = now.getTime();
|
|
1018
|
+
} else {
|
|
1019
|
+
result = now;
|
|
1020
|
+
}
|
|
1021
|
+
return result;
|
|
1022
|
+
}
|
|
1023
|
+
/**
|
|
1024
|
+
* Decodes the (unverified) payload claims from a JWT such as an `id_token`.
|
|
1025
|
+
*
|
|
1026
|
+
* This does NOT verify the signature — it is purely for surfacing identity claims a relying party
|
|
1027
|
+
* already trusts (the token was just issued to it). Returns `undefined` when the input is missing
|
|
1028
|
+
* or not a decodable JWT.
|
|
1029
|
+
*
|
|
1030
|
+
* @param token - The JWT string.
|
|
1031
|
+
* @returns The decoded claims object, or `undefined`.
|
|
1032
|
+
*/ function decodeJwtClaims(token) {
|
|
1033
|
+
var result;
|
|
1034
|
+
if (token) {
|
|
1035
|
+
var parts = token.split('.');
|
|
1036
|
+
if (parts.length >= 2 && parts[1]) {
|
|
1037
|
+
try {
|
|
1038
|
+
result = JSON.parse(decodeBase64UrlToString(parts[1]));
|
|
1039
|
+
} catch (unused) {
|
|
1040
|
+
result = undefined;
|
|
1041
|
+
}
|
|
1042
|
+
}
|
|
1043
|
+
}
|
|
1044
|
+
return result;
|
|
1045
|
+
}
|
|
1046
|
+
function decodeBase64UrlToString(base64Url) {
|
|
1047
|
+
var base64 = base64Url.replaceAll('-', '+').replaceAll('_', '/');
|
|
1048
|
+
var padded = base64.padEnd(base64.length + (4 - base64.length % 4) % 4, '=');
|
|
1049
|
+
var binary = atob(padded);
|
|
1050
|
+
var bytes = Uint8Array.from(binary, function(c) {
|
|
1051
|
+
var _c_codePointAt;
|
|
1052
|
+
return (_c_codePointAt = c.codePointAt(0)) !== null && _c_codePointAt !== void 0 ? _c_codePointAt : 0;
|
|
1053
|
+
});
|
|
1054
|
+
return new TextDecoder().decode(bytes);
|
|
1055
|
+
}
|
|
1056
|
+
|
|
1057
|
+
export { DEFAULT_OIDC_TOKEN_REFRESH_BUFFER_MS, accessTokenNeedsRefresh, decodeJwtClaims, discoverOidcMetadata, exchangeAuthorizationCode, fetchSessionInfo, fetchUserInfo, isAccessTokenExpired, nextRefreshDelay, oidcTokenManager, oidcTokenStateFromResponse, refreshAccessToken, revokeToken };
|