@crossauth/common 0.0.1

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/dist/index.js ADDED
@@ -0,0 +1,1980 @@
1
+ var fe = Object.defineProperty;
2
+ var G = (e) => {
3
+ throw TypeError(e);
4
+ };
5
+ var pe = (e, t, r) => t in e ? fe(e, t, { enumerable: !0, configurable: !0, writable: !0, value: r }) : e[t] = r;
6
+ var a = (e, t, r) => pe(e, typeof t != "symbol" ? t + "" : t, r), Y = (e, t, r) => t.has(e) || G("Cannot " + r);
7
+ var u = (e, t, r) => (Y(e, t, "read from private field"), r ? r.call(e) : t.get(e)), O = (e, t, r) => t.has(e) ? G("Cannot add the same private member more than once") : t instanceof WeakSet ? t.add(e) : t.set(e, r), _ = (e, t, r, n) => (Y(e, t, "write to private field"), n ? n.call(e, r) : t.set(e, r), r);
8
+ class k {
9
+ }
10
+ /** Ordinary, active user who can log in freely */
11
+ a(k, "active", "active"), /** Deactivated account. User cannot log in */
12
+ a(k, "disabled", "disabled"), /** Two factor authentication has been actived for this user
13
+ * but has not yet been configured. Once a user logs in,
14
+ * they will be directed to a page to configure 2FA and will
15
+ * not be able to do anything else (that requires login) until
16
+ * they have done so.
17
+ */
18
+ a(k, "awaitingTwoFactorSetup", "awaitingtwofactorsetup"), /** Email verification has been turned on but user has not
19
+ * verified his or her email address. Cannot log on until it has
20
+ * been verified.
21
+ */
22
+ a(k, "awaitingEmailVerification", "awaitingemailverification"), /**
23
+ * If the state is set to this, the user may not access any
24
+ * login-required functions unless he or she has changed their password.
25
+ *
26
+ * Upon login, the user is redirected to the change password page.
27
+ */
28
+ a(k, "passwordChangeNeeded", "passwordchangeneeded"), /**
29
+ * If the state is set to this, the user may not access any
30
+ * login-required functions unless he or she has reset their password.
31
+ *
32
+ * Upon login, the user is redirected to the reset password page.
33
+ */
34
+ a(k, "passwordResetNeeded", "passwordresetneeded"), /**
35
+ * If the state is set to this, the user may not access any
36
+ * login-required functions unless he or she has reset their second
37
+ * factor configuration.
38
+ *
39
+ * Upon login, the user is redirected to the 2FA configuration page.
40
+ *
41
+ * If you create a user and 2FA is mandatory, you can set state to
42
+ * this value and the user will then be prompted to configure 2FA
43
+ * upon login.
44
+ */
45
+ a(k, "factor2ResetNeeded", "factor2resetneeded"), /**
46
+ * If the state is set to this, the user may not access any
47
+ * login-required functions unless he or she has reset their password
48
+ * and then resets factor2.
49
+ *
50
+ * Upon login, the user is redirected to the reset password page.
51
+ */
52
+ a(k, "passwordAndFactor2ResetNeeded", "passwordandfactor2resetneeded");
53
+ class C {
54
+ }
55
+ /** Session ID */
56
+ a(C, "session", "s:"), /** Password Reset Token */
57
+ a(C, "passwordResetToken", "p:"), /** Email verification token */
58
+ a(C, "emailVerificationToken", "e:"), /** API key */
59
+ a(C, "apiKey", "api:"), /** OAuth authorization code */
60
+ a(C, "authorizationCode", "authz:"), /** OAuth access token */
61
+ a(C, "accessToken", "access:"), /** OAuth refresh token */
62
+ a(C, "refreshToken", "refresh:"), /** OAuth MFA key (used by the password MFA flow) */
63
+ a(C, "mfaToken", "omfa:"), /** Device code device code */
64
+ a(C, "deviceCode", "dc:"), /** Device code flow user code */
65
+ a(C, "userCode", "uc:");
66
+ var y = /* @__PURE__ */ ((e) => (e[e.UserNotExist = 0] = "UserNotExist", e[e.PasswordInvalid = 1] = "PasswordInvalid", e[e.EmailNotExist = 2] = "EmailNotExist", e[e.UsernameOrPasswordInvalid = 3] = "UsernameOrPasswordInvalid", e[e.InvalidClientId = 4] = "InvalidClientId", e[e.ClientExists = 5] = "ClientExists", e[e.InvalidClientSecret = 6] = "InvalidClientSecret", e[e.InvalidClientIdOrSecret = 7] = "InvalidClientIdOrSecret", e[e.InvalidRedirectUri = 8] = "InvalidRedirectUri", e[e.InvalidOAuthFlow = 9] = "InvalidOAuthFlow", e[e.UserNotActive = 10] = "UserNotActive", e[e.EmailNotVerified = 11] = "EmailNotVerified", e[e.TwoFactorIncomplete = 12] = "TwoFactorIncomplete", e[e.Unauthorized = 13] = "Unauthorized", e[e.UnauthorizedClient = 14] = "UnauthorizedClient", e[e.InvalidScope = 15] = "InvalidScope", e[e.InsufficientScope = 16] = "InsufficientScope", e[e.InsufficientPriviledges = 17] = "InsufficientPriviledges", e[e.Forbidden = 18] = "Forbidden", e[e.InvalidKey = 19] = "InvalidKey", e[e.InvalidCsrf = 20] = "InvalidCsrf", e[e.InvalidSession = 21] = "InvalidSession", e[e.Expired = 22] = "Expired", e[e.Connection = 23] = "Connection", e[e.InvalidHash = 24] = "InvalidHash", e[e.UnsupportedAlgorithm = 25] = "UnsupportedAlgorithm", e[e.KeyExists = 26] = "KeyExists", e[e.PasswordChangeNeeded = 27] = "PasswordChangeNeeded", e[e.PasswordResetNeeded = 28] = "PasswordResetNeeded", e[e.Factor2ResetNeeded = 29] = "Factor2ResetNeeded", e[e.Configuration = 30] = "Configuration", e[e.InvalidEmail = 31] = "InvalidEmail", e[e.InvalidPhoneNumber = 32] = "InvalidPhoneNumber", e[e.InvalidUsername = 33] = "InvalidUsername", e[e.PasswordMatch = 34] = "PasswordMatch", e[e.InvalidToken = 35] = "InvalidToken", e[e.MfaRequired = 36] = "MfaRequired", e[e.PasswordFormat = 37] = "PasswordFormat", e[e.DataFormat = 38] = "DataFormat", e[e.FetchError = 39] = "FetchError", e[e.UserExists = 40] = "UserExists", e[e.FormEntry = 41] = "FormEntry", e[e.BadRequest = 42] = "BadRequest", e[e.AuthorizationPending = 43] = "AuthorizationPending", e[e.SlowDown = 44] = "SlowDown", e[e.ExpiredToken = 45] = "ExpiredToken", e[e.ConstraintViolation = 46] = "ConstraintViolation", e[e.NotImplemented = 47] = "NotImplemented", e[e.UnknownError = 48] = "UnknownError", e))(y || {});
67
+ class g extends Error {
68
+ /**
69
+ * Creates a new error to throw,
70
+ *
71
+ * @param code describes the type of error
72
+ * @param message if provided, this error will display. Otherwise a default one for the error code will be used.
73
+ */
74
+ constructor(r, n = void 0) {
75
+ let i, s = 500;
76
+ r == 0 ? (i = "User does not exist", s = 401) : r == 1 ? (i = "Password doesn't match", s = 401) : r == 3 ? (i = "Username or password incorrect", s = 401) : r == 4 ? (i = "Client id is invalid", s = 401) : r == 5 ? (i = "Client ID or name already exists", s = 500) : r == 6 ? (i = "Client secret is invalid", s = 401) : r == 7 ? (i = "Client id or secret is invalid", s = 401) : r == 8 ? (i = "Redirect Uri is not registered", s = 401) : r == 9 ? (i = "Invalid OAuth flow type", s = 500) : r == 2 ? (i = "No user exists with that email address", s = 401) : r == 10 ? (i = "Account is not active", s = 403) : r == 33 ? (i = "Username is not in an allowed format", s = 400) : r == 31 ? (i = "Email is not in an allowed format", s = 400) : r == 32 ? (i = "Phone number is not in an allowed format", s = 400) : r == 11 ? (i = "Email address has not been verified", s = 403) : r == 12 ? (i = "Two-factor setup is not complete", s = 403) : r == 13 ? (i = "Not authorized", s = 401) : r == 14 ? (i = "Client not authorized", s = 401) : r == 15 ? (i = "Invalid scope", s = 403) : r == 16 ? (i = "Insufficient scope", s = 403) : r == 23 ? i = "Connection failure" : r == 22 ? (i = "Token has expired", s = 401) : r == 24 ? i = "Hash is not in a valid format" : r == 19 ? (i = "Key is invalid", s = 401) : r == 18 ? (i = "You do not have permission to access this resource", s = 403) : r == 17 ? (i = "You do not have the right privileges to access this resource", s = 401) : r == 20 ? (i = "CSRF token is invalid", s = 401) : r == 21 ? (i = "Session cookie is invalid", s = 401) : r == 25 ? i = "Algorithm not supported" : r == 26 ? i = "Attempt to create a key that already exists" : r == 27 ? (i = "User must change password", s = 403) : r == 28 ? (i = "User must reset password", s = 403) : r == 29 ? (i = "User must reset 2FA", s = 403) : r == 30 ? i = "There was an error in the configuration" : r == 34 ? (i = "Passwords do not match", s = 401) : r == 35 ? (i = "Token is not valid", s = 401) : r == 36 ? (i = "MFA is required", s = 401) : r == 37 ? (i = "Password format was incorrect", s = 401) : r == 40 ? (i = "User already exists", s = 400) : r == 42 ? (i = "The request is invalid", s = 400) : r == 38 ? (i = "Session data has unexpected format", s = 500) : r == 39 ? (i = "Couldn't execute a fetch", s = 500) : r == 43 ? (i = "Waiting for authorization", s = 200) : r == 44 ? (i = "Slow polling down by 5 seconds", s = 200) : r == 45 ? (i = "Token has expired", s = 401) : r == 46 ? (i = "Database update/insert caused a constraint violation", s = 500) : r == 47 ? (i = "This method has not been implemented", s = 500) : (i = "Unknown error", s = 500), n != null && !Array.isArray(n) ? i = n : Array.isArray(n) && (i = n.join(". "));
77
+ super(i);
78
+ /** `typeof` won't work on this class. To determine if the
79
+ * object is a `CrossauthError`, check for presence of this member.
80
+ */
81
+ a(this, "isCrossauthError", !0);
82
+ /** The best HTTP status to report */
83
+ a(this, "httpStatus");
84
+ /** All Crossauth errors have an error code */
85
+ a(this, "code");
86
+ /** All Crossauth errors have an error code */
87
+ a(this, "codeName");
88
+ /** A vector of error messages. If there was only one, it will still be in this array.
89
+ * The inherited property `message` is also always available. If there were multiple messages,
90
+ * it will be a concatenation of them with `". "` in between.
91
+ */
92
+ a(this, "messages");
93
+ this.code = r, this.codeName = y[r], this.httpStatus = s, this.name = "CrossauthError", Array.isArray(n) ? this.messages = n : this.messages = [i], Object.setPrototypeOf(this, g.prototype);
94
+ }
95
+ /**
96
+ * OAuth defines certain error types. To convert the error in an OAuth
97
+ * response into a CrossauthError object, call this function.
98
+ *
99
+ * @param error as returned by an OAuth call (converted to an {@link @crossauth/common!ErrorCode}).
100
+ * @param error_description as returned by an OAuth call (put in the `message`)
101
+ * @returns a `CrossauthError` instance.
102
+ */
103
+ static fromOAuthError(r, n) {
104
+ let i;
105
+ switch (r) {
106
+ case "invalid_request":
107
+ i = 42;
108
+ break;
109
+ case "unauthorized_client":
110
+ i = 14;
111
+ break;
112
+ case "access_denied":
113
+ i = 13;
114
+ break;
115
+ case "unsupported_response_type":
116
+ i = 42;
117
+ break;
118
+ case "invalid_scope":
119
+ i = 15;
120
+ break;
121
+ case "server_error":
122
+ i = 48;
123
+ break;
124
+ case "temporarily_unavailable":
125
+ i = 23;
126
+ break;
127
+ case "invalid_token":
128
+ i = 35;
129
+ break;
130
+ case "expired_token":
131
+ i = 45;
132
+ break;
133
+ case "insufficient_scope":
134
+ i = 35;
135
+ break;
136
+ case "mfa_required":
137
+ i = 36;
138
+ break;
139
+ case "authorization_pending":
140
+ i = 43;
141
+ break;
142
+ case "slow_down":
143
+ i = 44;
144
+ break;
145
+ default:
146
+ i = 48;
147
+ }
148
+ return new g(i, n);
149
+ }
150
+ get oauthErrorCode() {
151
+ switch (this.code) {
152
+ case 42:
153
+ return "invalid_request";
154
+ case 14:
155
+ return "unauthorized_client";
156
+ case 13:
157
+ return "access_denied";
158
+ case 15:
159
+ return "invalid_scope";
160
+ case 23:
161
+ return "temporarily_unavailable";
162
+ case 35:
163
+ return "invalid_token";
164
+ case 36:
165
+ return "mfa_required";
166
+ case 43:
167
+ return "authorization_pending";
168
+ case 44:
169
+ return "slow_down";
170
+ case 45:
171
+ return "expired_token";
172
+ case 22:
173
+ return "expired_token";
174
+ default:
175
+ return "server_error";
176
+ }
177
+ }
178
+ /**
179
+ * If the passed object is a `CrossauthError` instance, simply returns
180
+ * it.
181
+ * If not and it is an object with `errorCode` in it, creates a
182
+ * CrossauthError from that and `errorMessage`, if present.
183
+ * Otherwise creates a `CrossauthError` object with {@link @crossauth/common!ErrorCode}
184
+ * of `Unknown` from it, setting the `message` if possible.
185
+ *
186
+ * @param e the error to convert.
187
+ * @returns a `CrossauthError` instance.
188
+ */
189
+ static asCrossauthError(r, n) {
190
+ if (r instanceof Error)
191
+ return "isCrossauthError" in r ? r : new g(48, r.message);
192
+ if ("errorCode" in r) {
193
+ let s = 48;
194
+ try {
195
+ s = Number(r.errorCode) ?? 48;
196
+ } catch {
197
+ }
198
+ let o = n ?? y[s];
199
+ return "errorMessage" in r ? o = r.errorMessage : "message" in r && (o = r.message), new g(s, o);
200
+ }
201
+ let i = n ?? y[
202
+ 48
203
+ /* UnknownError */
204
+ ];
205
+ return "message" in r && (i = r.message), new g(48, i);
206
+ }
207
+ }
208
+ function $e(e) {
209
+ return typeof e == "number" && (e = "" + e), e in B ? B[e] : B[500];
210
+ }
211
+ const B = {
212
+ 200: "OK",
213
+ 201: "Created",
214
+ 202: "Accepted",
215
+ 203: "Non-Authoritative Information",
216
+ 204: "No Content",
217
+ 205: "Reset Content",
218
+ 206: "Partial Content",
219
+ 300: "Multiple Choices",
220
+ 301: "Moved Permanently",
221
+ 302: "Found",
222
+ 303: "See Other",
223
+ 304: "Not Modified",
224
+ 305: "Use Proxy",
225
+ 306: "Unused",
226
+ 307: "Temporary Redirect",
227
+ 400: "Bad Request",
228
+ 401: "Unauthorized",
229
+ 402: "Payment Required",
230
+ 403: "Forbidden",
231
+ 404: "Not Found",
232
+ 405: "Method Not Allowed",
233
+ 406: "Not Acceptable",
234
+ 407: "Proxy Authentication Required",
235
+ 408: "Request Timeout",
236
+ 409: "Conflict",
237
+ 410: "Gone",
238
+ 411: "Length Required",
239
+ 412: "Precondition Required",
240
+ 413: "Request Entry Too Large",
241
+ 414: "Request-URI Too Long",
242
+ 415: "Unsupported Media Type",
243
+ 416: "Requested Range Not Satisfiable",
244
+ 417: "Expectation Failed",
245
+ 418: "I'm a teapot",
246
+ 429: "Too Many Requests",
247
+ 500: "Internal Server Error",
248
+ 501: "Not Implemented",
249
+ 502: "Bad Gateway",
250
+ 503: "Service Unavailable",
251
+ 504: "Gateway Timeout",
252
+ 505: "HTTP Version Not Supported"
253
+ }, m = class m {
254
+ /**
255
+ * Create a logger with the given level
256
+ * @param level the level to report to
257
+ */
258
+ constructor(t) {
259
+ /** the log level. This can be set dynamically */
260
+ a(this, "level");
261
+ if (t) this.level = t;
262
+ else if (typeof process < "u" && "CROSSAUTH_LOG_LEVEL" in process.env) {
263
+ const r = (process.env.CROSSAUTH_LOG_LEVEL ?? "ERROR").toUpperCase();
264
+ m.levelName.includes(r) ? this.level = m.levelName.indexOf(r) : this.level = m.Error;
265
+ } else
266
+ this.level = m.Error;
267
+ }
268
+ /**
269
+ * Return the singleton instance of the logger.
270
+ * @returns the logger
271
+ */
272
+ static get logger() {
273
+ return globalThis.crossauthLogger;
274
+ }
275
+ setLevel(t) {
276
+ this.level = t;
277
+ }
278
+ log(t, r) {
279
+ t <= this.level && (typeof r == "string" ? console.log("Crossauth " + m.levelName[t] + " " + (/* @__PURE__ */ new Date()).toISOString(), r) : console.log(JSON.stringify({ level: m.levelName[t], time: (/* @__PURE__ */ new Date()).toISOString(), ...r })));
280
+ }
281
+ /**
282
+ * Report an error
283
+ * @param output object to output
284
+ */
285
+ error(t) {
286
+ this.log(m.Error, t);
287
+ }
288
+ /**
289
+ * Report an warning
290
+ * @param output object to output
291
+ */
292
+ warn(t) {
293
+ this.log(m.Warn, t);
294
+ }
295
+ /**
296
+ * Report information
297
+ * @param output object to output
298
+ */
299
+ info(t) {
300
+ this.log(m.Info, t);
301
+ }
302
+ /**
303
+ * Print a debugging message
304
+ * @param output object to output
305
+ */
306
+ debug(t) {
307
+ this.log(m.Debug, t);
308
+ }
309
+ /**
310
+ * Override the default logger.
311
+ *
312
+ * The only requirement is that the logger has the functions `error()`, `warn()`, `info()` and `debug()`.
313
+ * These functions must accept either an object or a string. If they can only accept a string,
314
+ * set `acceptsJson` to false.
315
+ *
316
+ * @param logger a new logger instance of any supported class
317
+ * @param acceptsJson set this to false if the logger can only take strings.
318
+ */
319
+ static setLogger(t, r) {
320
+ globalThis.crossauthLogger = t, globalThis.crossauthLoggerAcceptsJson = r;
321
+ }
322
+ };
323
+ /** Don't log anything */
324
+ a(m, "None", 0), /** Only log errors */
325
+ a(m, "Error", 1), /** Log errors and warning */
326
+ a(m, "Warn", 2), /** Log errors, warnings and info messages */
327
+ a(m, "Info", 3), /** Log everything */
328
+ a(m, "Debug", 4), a(m, "levelName", ["NONE", "ERROR", "WARN", "INFO", "DEBUG"]);
329
+ let d = m;
330
+ function h(e) {
331
+ let t;
332
+ typeof e == "object" && "err" in e && typeof e.err == "object" && (t = e.err.stack);
333
+ try {
334
+ typeof e == "object" && "err" in e && typeof e.err == "object" && e.err && "message" in e.err && !("msg" in e) && (e.msg = e.err.message);
335
+ } catch {
336
+ }
337
+ try {
338
+ typeof e == "object" && "err" in e && typeof e.err == "object" && (e.err = { ...e.err, stack: t });
339
+ } catch {
340
+ }
341
+ try {
342
+ typeof e == "object" && "err" in e && !("msg" in e) && (e.msg = e.msg = "An unknown error occurred");
343
+ } catch {
344
+ }
345
+ try {
346
+ typeof e == "object" && "cerr" in e && "isCrossauthError" in e.cerr && e.cerr && (e.errorCode = e.cerr.code, e.errorCodeName = e.cerr.codeName, e.httpStatus = e.cerr.httpStatus, "msg" in e || (e.msg = e.cerr.message), delete e.cerr);
347
+ } catch {
348
+ }
349
+ return typeof e == "string" || globalThis.crossauthLoggerAcceptsJson ? e : JSON.stringify(e);
350
+ }
351
+ globalThis.crossauthLogger = new d(d.None);
352
+ globalThis.crossauthLoggerAcceptsJson = !0;
353
+ const te = {
354
+ issuer: "",
355
+ authorization_endpoint: "",
356
+ token_endpoint: "",
357
+ jwks_uri: "",
358
+ response_types_supported: [],
359
+ subject_types_supported: [],
360
+ response_modes_supported: ["query", "fragment"],
361
+ grant_types_supported: ["authorization_code", "implicit"],
362
+ id_token_signing_alg_values_supported: [],
363
+ claim_types_supported: ["normal"],
364
+ claims_parameter_supported: !1,
365
+ request_parameter_supported: !1,
366
+ request_uri_parameter_supported: !0,
367
+ require_request_uri_registration: !1
368
+ }, F = crypto, re = (e) => e instanceof CryptoKey, H = new TextEncoder(), z = new TextDecoder();
369
+ function ge(...e) {
370
+ const t = e.reduce((i, { length: s }) => i + s, 0), r = new Uint8Array(t);
371
+ let n = 0;
372
+ for (const i of e)
373
+ r.set(i, n), n += i.length;
374
+ return r;
375
+ }
376
+ const ye = (e) => {
377
+ const t = atob(e), r = new Uint8Array(t.length);
378
+ for (let n = 0; n < t.length; n++)
379
+ r[n] = t.charCodeAt(n);
380
+ return r;
381
+ }, K = (e) => {
382
+ let t = e;
383
+ t instanceof Uint8Array && (t = z.decode(t)), t = t.replace(/-/g, "+").replace(/_/g, "/").replace(/\s/g, "");
384
+ try {
385
+ return ye(t);
386
+ } catch {
387
+ throw new TypeError("The input to be decoded is not correctly encoded.");
388
+ }
389
+ };
390
+ class $ extends Error {
391
+ static get code() {
392
+ return "ERR_JOSE_GENERIC";
393
+ }
394
+ constructor(t) {
395
+ var r;
396
+ super(t), this.code = "ERR_JOSE_GENERIC", this.name = this.constructor.name, (r = Error.captureStackTrace) == null || r.call(Error, this, this.constructor);
397
+ }
398
+ }
399
+ class b extends $ {
400
+ constructor() {
401
+ super(...arguments), this.code = "ERR_JOSE_NOT_SUPPORTED";
402
+ }
403
+ static get code() {
404
+ return "ERR_JOSE_NOT_SUPPORTED";
405
+ }
406
+ }
407
+ class v extends $ {
408
+ constructor() {
409
+ super(...arguments), this.code = "ERR_JWS_INVALID";
410
+ }
411
+ static get code() {
412
+ return "ERR_JWS_INVALID";
413
+ }
414
+ }
415
+ class E extends $ {
416
+ constructor() {
417
+ super(...arguments), this.code = "ERR_JWT_INVALID";
418
+ }
419
+ static get code() {
420
+ return "ERR_JWT_INVALID";
421
+ }
422
+ }
423
+ class me extends $ {
424
+ constructor() {
425
+ super(...arguments), this.code = "ERR_JWS_SIGNATURE_VERIFICATION_FAILED", this.message = "signature verification failed";
426
+ }
427
+ static get code() {
428
+ return "ERR_JWS_SIGNATURE_VERIFICATION_FAILED";
429
+ }
430
+ }
431
+ function A(e, t = "algorithm.name") {
432
+ return new TypeError(`CryptoKey does not support this operation, its ${t} must be ${e}`);
433
+ }
434
+ function J(e, t) {
435
+ return e.name === t;
436
+ }
437
+ function L(e) {
438
+ return parseInt(e.name.slice(4), 10);
439
+ }
440
+ function we(e) {
441
+ switch (e) {
442
+ case "ES256":
443
+ return "P-256";
444
+ case "ES384":
445
+ return "P-384";
446
+ case "ES512":
447
+ return "P-521";
448
+ default:
449
+ throw new Error("unreachable");
450
+ }
451
+ }
452
+ function ve(e, t) {
453
+ if (t.length && !t.some((r) => e.usages.includes(r))) {
454
+ let r = "CryptoKey does not support this operation, its usages must include ";
455
+ if (t.length > 2) {
456
+ const n = t.pop();
457
+ r += `one of ${t.join(", ")}, or ${n}.`;
458
+ } else t.length === 2 ? r += `one of ${t[0]} or ${t[1]}.` : r += `${t[0]}.`;
459
+ throw new TypeError(r);
460
+ }
461
+ }
462
+ function Se(e, t, ...r) {
463
+ switch (t) {
464
+ case "HS256":
465
+ case "HS384":
466
+ case "HS512": {
467
+ if (!J(e.algorithm, "HMAC"))
468
+ throw A("HMAC");
469
+ const n = parseInt(t.slice(2), 10);
470
+ if (L(e.algorithm.hash) !== n)
471
+ throw A(`SHA-${n}`, "algorithm.hash");
472
+ break;
473
+ }
474
+ case "RS256":
475
+ case "RS384":
476
+ case "RS512": {
477
+ if (!J(e.algorithm, "RSASSA-PKCS1-v1_5"))
478
+ throw A("RSASSA-PKCS1-v1_5");
479
+ const n = parseInt(t.slice(2), 10);
480
+ if (L(e.algorithm.hash) !== n)
481
+ throw A(`SHA-${n}`, "algorithm.hash");
482
+ break;
483
+ }
484
+ case "PS256":
485
+ case "PS384":
486
+ case "PS512": {
487
+ if (!J(e.algorithm, "RSA-PSS"))
488
+ throw A("RSA-PSS");
489
+ const n = parseInt(t.slice(2), 10);
490
+ if (L(e.algorithm.hash) !== n)
491
+ throw A(`SHA-${n}`, "algorithm.hash");
492
+ break;
493
+ }
494
+ case "EdDSA": {
495
+ if (e.algorithm.name !== "Ed25519" && e.algorithm.name !== "Ed448")
496
+ throw A("Ed25519 or Ed448");
497
+ break;
498
+ }
499
+ case "ES256":
500
+ case "ES384":
501
+ case "ES512": {
502
+ if (!J(e.algorithm, "ECDSA"))
503
+ throw A("ECDSA");
504
+ const n = we(t);
505
+ if (e.algorithm.namedCurve !== n)
506
+ throw A(n, "algorithm.namedCurve");
507
+ break;
508
+ }
509
+ default:
510
+ throw new TypeError("CryptoKey does not support this operation");
511
+ }
512
+ ve(e, r);
513
+ }
514
+ function ie(e, t, ...r) {
515
+ var n;
516
+ if (r.length > 2) {
517
+ const i = r.pop();
518
+ e += `one of type ${r.join(", ")}, or ${i}.`;
519
+ } else r.length === 2 ? e += `one of type ${r[0]} or ${r[1]}.` : e += `of type ${r[0]}.`;
520
+ return t == null ? e += ` Received ${t}` : typeof t == "function" && t.name ? e += ` Received function ${t.name}` : typeof t == "object" && t != null && (n = t.constructor) != null && n.name && (e += ` Received an instance of ${t.constructor.name}`), e;
521
+ }
522
+ const X = (e, ...t) => ie("Key must be ", e, ...t);
523
+ function ne(e, t, ...r) {
524
+ return ie(`Key for the ${e} algorithm must be `, t, ...r);
525
+ }
526
+ const se = (e) => re(e) ? !0 : (e == null ? void 0 : e[Symbol.toStringTag]) === "KeyObject", M = ["CryptoKey"], _e = (...e) => {
527
+ const t = e.filter(Boolean);
528
+ if (t.length === 0 || t.length === 1)
529
+ return !0;
530
+ let r;
531
+ for (const n of t) {
532
+ const i = Object.keys(n);
533
+ if (!r || r.size === 0) {
534
+ r = new Set(i);
535
+ continue;
536
+ }
537
+ for (const s of i) {
538
+ if (r.has(s))
539
+ return !1;
540
+ r.add(s);
541
+ }
542
+ }
543
+ return !0;
544
+ };
545
+ function Ce(e) {
546
+ return typeof e == "object" && e !== null;
547
+ }
548
+ function x(e) {
549
+ if (!Ce(e) || Object.prototype.toString.call(e) !== "[object Object]")
550
+ return !1;
551
+ if (Object.getPrototypeOf(e) === null)
552
+ return !0;
553
+ let t = e;
554
+ for (; Object.getPrototypeOf(t) !== null; )
555
+ t = Object.getPrototypeOf(t);
556
+ return Object.getPrototypeOf(e) === t;
557
+ }
558
+ const be = (e, t) => {
559
+ if (e.startsWith("RS") || e.startsWith("PS")) {
560
+ const { modulusLength: r } = t.algorithm;
561
+ if (typeof r != "number" || r < 2048)
562
+ throw new TypeError(`${e} requires key modulusLength to be 2048 bits or larger`);
563
+ }
564
+ };
565
+ function Ae(e) {
566
+ let t, r;
567
+ switch (e.kty) {
568
+ case "RSA": {
569
+ switch (e.alg) {
570
+ case "PS256":
571
+ case "PS384":
572
+ case "PS512":
573
+ t = { name: "RSA-PSS", hash: `SHA-${e.alg.slice(-3)}` }, r = e.d ? ["sign"] : ["verify"];
574
+ break;
575
+ case "RS256":
576
+ case "RS384":
577
+ case "RS512":
578
+ t = { name: "RSASSA-PKCS1-v1_5", hash: `SHA-${e.alg.slice(-3)}` }, r = e.d ? ["sign"] : ["verify"];
579
+ break;
580
+ case "RSA-OAEP":
581
+ case "RSA-OAEP-256":
582
+ case "RSA-OAEP-384":
583
+ case "RSA-OAEP-512":
584
+ t = {
585
+ name: "RSA-OAEP",
586
+ hash: `SHA-${parseInt(e.alg.slice(-3), 10) || 1}`
587
+ }, r = e.d ? ["decrypt", "unwrapKey"] : ["encrypt", "wrapKey"];
588
+ break;
589
+ default:
590
+ throw new b('Invalid or unsupported JWK "alg" (Algorithm) Parameter value');
591
+ }
592
+ break;
593
+ }
594
+ case "EC": {
595
+ switch (e.alg) {
596
+ case "ES256":
597
+ t = { name: "ECDSA", namedCurve: "P-256" }, r = e.d ? ["sign"] : ["verify"];
598
+ break;
599
+ case "ES384":
600
+ t = { name: "ECDSA", namedCurve: "P-384" }, r = e.d ? ["sign"] : ["verify"];
601
+ break;
602
+ case "ES512":
603
+ t = { name: "ECDSA", namedCurve: "P-521" }, r = e.d ? ["sign"] : ["verify"];
604
+ break;
605
+ case "ECDH-ES":
606
+ case "ECDH-ES+A128KW":
607
+ case "ECDH-ES+A192KW":
608
+ case "ECDH-ES+A256KW":
609
+ t = { name: "ECDH", namedCurve: e.crv }, r = e.d ? ["deriveBits"] : [];
610
+ break;
611
+ default:
612
+ throw new b('Invalid or unsupported JWK "alg" (Algorithm) Parameter value');
613
+ }
614
+ break;
615
+ }
616
+ case "OKP": {
617
+ switch (e.alg) {
618
+ case "EdDSA":
619
+ t = { name: e.crv }, r = e.d ? ["sign"] : ["verify"];
620
+ break;
621
+ case "ECDH-ES":
622
+ case "ECDH-ES+A128KW":
623
+ case "ECDH-ES+A192KW":
624
+ case "ECDH-ES+A256KW":
625
+ t = { name: e.crv }, r = e.d ? ["deriveBits"] : [];
626
+ break;
627
+ default:
628
+ throw new b('Invalid or unsupported JWK "alg" (Algorithm) Parameter value');
629
+ }
630
+ break;
631
+ }
632
+ default:
633
+ throw new b('Invalid or unsupported JWK "kty" (Key Type) Parameter value');
634
+ }
635
+ return { algorithm: t, keyUsages: r };
636
+ }
637
+ const oe = async (e) => {
638
+ if (!e.alg)
639
+ throw new TypeError('"alg" argument is required when "jwk.alg" is not present');
640
+ const { algorithm: t, keyUsages: r } = Ae(e), n = [
641
+ t,
642
+ e.ext ?? !1,
643
+ e.key_ops ?? r
644
+ ], i = { ...e };
645
+ return delete i.alg, delete i.use, F.subtle.importKey("jwk", i, ...n);
646
+ }, ae = (e) => K(e);
647
+ let V, j;
648
+ const ce = (e) => (e == null ? void 0 : e[Symbol.toStringTag]) === "KeyObject", de = async (e, t, r, n) => {
649
+ let i = e.get(t);
650
+ if (i != null && i[n])
651
+ return i[n];
652
+ const s = await oe({ ...r, alg: n });
653
+ return i ? i[n] = s : e.set(t, { [n]: s }), s;
654
+ }, Pe = (e, t) => {
655
+ if (ce(e)) {
656
+ let r = e.export({ format: "jwk" });
657
+ return delete r.d, delete r.dp, delete r.dq, delete r.p, delete r.q, delete r.qi, r.k ? ae(r.k) : (j || (j = /* @__PURE__ */ new WeakMap()), de(j, e, r, t));
658
+ }
659
+ return e;
660
+ }, ke = (e, t) => {
661
+ if (ce(e)) {
662
+ let r = e.export({ format: "jwk" });
663
+ return r.k ? ae(r.k) : (V || (V = /* @__PURE__ */ new WeakMap()), de(V, e, r, t));
664
+ }
665
+ return e;
666
+ }, Ie = { normalizePublicKey: Pe, normalizePrivateKey: ke }, I = (e, t, r = 0) => {
667
+ r === 0 && (t.unshift(t.length), t.unshift(6));
668
+ const n = e.indexOf(t[0], r);
669
+ if (n === -1)
670
+ return !1;
671
+ const i = e.subarray(n, n + t.length);
672
+ return i.length !== t.length ? !1 : i.every((s, o) => s === t[o]) || I(e, t, n + 1);
673
+ }, Q = (e) => {
674
+ switch (!0) {
675
+ case I(e, [42, 134, 72, 206, 61, 3, 1, 7]):
676
+ return "P-256";
677
+ case I(e, [43, 129, 4, 0, 34]):
678
+ return "P-384";
679
+ case I(e, [43, 129, 4, 0, 35]):
680
+ return "P-521";
681
+ case I(e, [43, 101, 110]):
682
+ return "X25519";
683
+ case I(e, [43, 101, 111]):
684
+ return "X448";
685
+ case I(e, [43, 101, 112]):
686
+ return "Ed25519";
687
+ case I(e, [43, 101, 113]):
688
+ return "Ed448";
689
+ default:
690
+ throw new b("Invalid or unsupported EC Key Curve or OKP Key Sub Type");
691
+ }
692
+ }, le = async (e, t, r, n, i) => {
693
+ let s, o;
694
+ const l = new Uint8Array(atob(r.replace(e, "")).split("").map((p) => p.charCodeAt(0))), f = t === "spki";
695
+ switch (n) {
696
+ case "PS256":
697
+ case "PS384":
698
+ case "PS512":
699
+ s = { name: "RSA-PSS", hash: `SHA-${n.slice(-3)}` }, o = f ? ["verify"] : ["sign"];
700
+ break;
701
+ case "RS256":
702
+ case "RS384":
703
+ case "RS512":
704
+ s = { name: "RSASSA-PKCS1-v1_5", hash: `SHA-${n.slice(-3)}` }, o = f ? ["verify"] : ["sign"];
705
+ break;
706
+ case "RSA-OAEP":
707
+ case "RSA-OAEP-256":
708
+ case "RSA-OAEP-384":
709
+ case "RSA-OAEP-512":
710
+ s = {
711
+ name: "RSA-OAEP",
712
+ hash: `SHA-${parseInt(n.slice(-3), 10) || 1}`
713
+ }, o = f ? ["encrypt", "wrapKey"] : ["decrypt", "unwrapKey"];
714
+ break;
715
+ case "ES256":
716
+ s = { name: "ECDSA", namedCurve: "P-256" }, o = f ? ["verify"] : ["sign"];
717
+ break;
718
+ case "ES384":
719
+ s = { name: "ECDSA", namedCurve: "P-384" }, o = f ? ["verify"] : ["sign"];
720
+ break;
721
+ case "ES512":
722
+ s = { name: "ECDSA", namedCurve: "P-521" }, o = f ? ["verify"] : ["sign"];
723
+ break;
724
+ case "ECDH-ES":
725
+ case "ECDH-ES+A128KW":
726
+ case "ECDH-ES+A192KW":
727
+ case "ECDH-ES+A256KW": {
728
+ const p = Q(l);
729
+ s = p.startsWith("P-") ? { name: "ECDH", namedCurve: p } : { name: p }, o = f ? [] : ["deriveBits"];
730
+ break;
731
+ }
732
+ case "EdDSA":
733
+ s = { name: Q(l) }, o = f ? ["verify"] : ["sign"];
734
+ break;
735
+ default:
736
+ throw new b('Invalid or unsupported "alg" (Algorithm) value');
737
+ }
738
+ return F.subtle.importKey(t, l, s, !1, o);
739
+ }, Te = (e, t, r) => le(/(?:-----(?:BEGIN|END) PRIVATE KEY-----|\s)/g, "pkcs8", e, t), Re = (e, t, r) => le(/(?:-----(?:BEGIN|END) PUBLIC KEY-----|\s)/g, "spki", e, t);
740
+ async function Ee(e, t, r) {
741
+ if (typeof e != "string" || e.indexOf("-----BEGIN PUBLIC KEY-----") !== 0)
742
+ throw new TypeError('"spki" must be SPKI formatted string');
743
+ return Re(e, t);
744
+ }
745
+ async function Oe(e, t, r) {
746
+ if (typeof e != "string" || e.indexOf("-----BEGIN PRIVATE KEY-----") !== 0)
747
+ throw new TypeError('"pkcs8" must be PKCS#8 formatted string');
748
+ return Te(e, t);
749
+ }
750
+ async function Z(e, t) {
751
+ if (!x(e))
752
+ throw new TypeError("JWK must be an object");
753
+ switch (t || (t = e.alg), e.kty) {
754
+ case "oct":
755
+ if (typeof e.k != "string" || !e.k)
756
+ throw new TypeError('missing "k" (Key Value) Parameter value');
757
+ return K(e.k);
758
+ case "RSA":
759
+ if (e.oth !== void 0)
760
+ throw new b('RSA JWK "oth" (Other Primes Info) Parameter value is not supported');
761
+ case "EC":
762
+ case "OKP":
763
+ return oe({ ...e, alg: t });
764
+ default:
765
+ throw new b('Unsupported "kty" (Key Type) Parameter value');
766
+ }
767
+ }
768
+ const q = (e) => e == null ? void 0 : e[Symbol.toStringTag], Ke = (e, t) => {
769
+ if (!(t instanceof Uint8Array)) {
770
+ if (!se(t))
771
+ throw new TypeError(ne(e, t, ...M, "Uint8Array"));
772
+ if (t.type !== "secret")
773
+ throw new TypeError(`${q(t)} instances for symmetric algorithms must be of type "secret"`);
774
+ }
775
+ }, Ne = (e, t, r) => {
776
+ if (!se(t))
777
+ throw new TypeError(ne(e, t, ...M));
778
+ if (t.type === "secret")
779
+ throw new TypeError(`${q(t)} instances for asymmetric algorithms must not be of type "secret"`);
780
+ if (t.algorithm && r === "verify" && t.type === "private")
781
+ throw new TypeError(`${q(t)} instances for asymmetric algorithm verifying must be of type "public"`);
782
+ if (t.algorithm && r === "encrypt" && t.type === "private")
783
+ throw new TypeError(`${q(t)} instances for asymmetric algorithm encryption must be of type "public"`);
784
+ }, Ue = (e, t, r) => {
785
+ e.startsWith("HS") || e === "dir" || e.startsWith("PBES2") || /^A\d{3}(?:GCM)?KW$/.test(e) ? Ke(e, t) : Ne(e, t, r);
786
+ };
787
+ function xe(e, t, r, n, i) {
788
+ if (i.crit !== void 0 && (n == null ? void 0 : n.crit) === void 0)
789
+ throw new e('"crit" (Critical) Header Parameter MUST be integrity protected');
790
+ if (!n || n.crit === void 0)
791
+ return /* @__PURE__ */ new Set();
792
+ if (!Array.isArray(n.crit) || n.crit.length === 0 || n.crit.some((o) => typeof o != "string" || o.length === 0))
793
+ throw new e('"crit" (Critical) Header Parameter MUST be an array of non-empty strings when present');
794
+ let s;
795
+ s = t;
796
+ for (const o of n.crit) {
797
+ if (!s.has(o))
798
+ throw new b(`Extension Header Parameter "${o}" is not recognized`);
799
+ if (i[o] === void 0)
800
+ throw new e(`Extension Header Parameter "${o}" is missing`);
801
+ if (s.get(o) && n[o] === void 0)
802
+ throw new e(`Extension Header Parameter "${o}" MUST be integrity protected`);
803
+ }
804
+ return new Set(n.crit);
805
+ }
806
+ function ze(e, t) {
807
+ const r = `SHA-${e.slice(-3)}`;
808
+ switch (e) {
809
+ case "HS256":
810
+ case "HS384":
811
+ case "HS512":
812
+ return { hash: r, name: "HMAC" };
813
+ case "PS256":
814
+ case "PS384":
815
+ case "PS512":
816
+ return { hash: r, name: "RSA-PSS", saltLength: e.slice(-3) >> 3 };
817
+ case "RS256":
818
+ case "RS384":
819
+ case "RS512":
820
+ return { hash: r, name: "RSASSA-PKCS1-v1_5" };
821
+ case "ES256":
822
+ case "ES384":
823
+ case "ES512":
824
+ return { hash: r, name: "ECDSA", namedCurve: t.namedCurve };
825
+ case "EdDSA":
826
+ return { name: t.name };
827
+ default:
828
+ throw new b(`alg ${e} is not supported either by JOSE or your javascript runtime`);
829
+ }
830
+ }
831
+ async function We(e, t, r) {
832
+ if (t = await Ie.normalizePublicKey(t, e), re(t))
833
+ return Se(t, e, r), t;
834
+ if (t instanceof Uint8Array) {
835
+ if (!e.startsWith("HS"))
836
+ throw new TypeError(X(t, ...M));
837
+ return F.subtle.importKey("raw", t, { hash: `SHA-${e.slice(-3)}`, name: "HMAC" }, !1, [r]);
838
+ }
839
+ throw new TypeError(X(t, ...M, "Uint8Array"));
840
+ }
841
+ const De = async (e, t, r, n) => {
842
+ const i = await We(e, t, "verify");
843
+ be(e, i);
844
+ const s = ze(e, i.algorithm);
845
+ try {
846
+ return await F.subtle.verify(s, i, r, n);
847
+ } catch {
848
+ return !1;
849
+ }
850
+ };
851
+ async function He(e, t, r) {
852
+ if (!x(e))
853
+ throw new v("Flattened JWS must be an object");
854
+ if (e.protected === void 0 && e.header === void 0)
855
+ throw new v('Flattened JWS must have either of the "protected" or "header" members');
856
+ if (e.protected !== void 0 && typeof e.protected != "string")
857
+ throw new v("JWS Protected Header incorrect type");
858
+ if (e.payload === void 0)
859
+ throw new v("JWS Payload missing");
860
+ if (typeof e.signature != "string")
861
+ throw new v("JWS Signature missing or incorrect type");
862
+ if (e.header !== void 0 && !x(e.header))
863
+ throw new v("JWS Unprotected Header incorrect type");
864
+ let n = {};
865
+ if (e.protected)
866
+ try {
867
+ const ue = K(e.protected);
868
+ n = JSON.parse(z.decode(ue));
869
+ } catch {
870
+ throw new v("JWS Protected Header is invalid");
871
+ }
872
+ if (!_e(n, e.header))
873
+ throw new v("JWS Protected and JWS Unprotected Header Parameter names must be disjoint");
874
+ const i = {
875
+ ...n,
876
+ ...e.header
877
+ }, s = xe(v, /* @__PURE__ */ new Map([["b64", !0]]), r == null ? void 0 : r.crit, n, i);
878
+ let o = !0;
879
+ if (s.has("b64") && (o = n.b64, typeof o != "boolean"))
880
+ throw new v('The "b64" (base64url-encode payload) Header Parameter must be a boolean');
881
+ const { alg: l } = i;
882
+ if (typeof l != "string" || !l)
883
+ throw new v('JWS "alg" (Algorithm) Header Parameter missing or invalid');
884
+ if (o) {
885
+ if (typeof e.payload != "string")
886
+ throw new v("JWS Payload must be a string");
887
+ } else if (typeof e.payload != "string" && !(e.payload instanceof Uint8Array))
888
+ throw new v("JWS Payload must be a string or an Uint8Array instance");
889
+ let f = !1;
890
+ typeof t == "function" && (t = await t(n, e), f = !0), Ue(l, t, "verify");
891
+ const p = ge(H.encode(e.protected ?? ""), H.encode("."), typeof e.payload == "string" ? H.encode(e.payload) : e.payload);
892
+ let P;
893
+ try {
894
+ P = K(e.signature);
895
+ } catch {
896
+ throw new v("Failed to base64url decode the signature");
897
+ }
898
+ if (!await De(l, t, P, p))
899
+ throw new me();
900
+ let W;
901
+ if (o)
902
+ try {
903
+ W = K(e.payload);
904
+ } catch {
905
+ throw new v("Failed to base64url decode the payload");
906
+ }
907
+ else typeof e.payload == "string" ? W = H.encode(e.payload) : W = e.payload;
908
+ const D = { payload: W };
909
+ return e.protected !== void 0 && (D.protectedHeader = n), e.header !== void 0 && (D.unprotectedHeader = e.header), f ? { ...D, key: t } : D;
910
+ }
911
+ async function Je(e, t, r) {
912
+ if (e instanceof Uint8Array && (e = z.decode(e)), typeof e != "string")
913
+ throw new v("Compact JWS must be a string or Uint8Array");
914
+ const { 0: n, 1: i, 2: s, length: o } = e.split(".");
915
+ if (o !== 3)
916
+ throw new v("Invalid Compact JWS");
917
+ const l = await He({ payload: i, protected: n, signature: s }, t, r), f = { payload: l.payload, protectedHeader: l.protectedHeader };
918
+ return typeof t == "function" ? { ...f, key: l.key } : f;
919
+ }
920
+ const he = K;
921
+ function qe(e) {
922
+ let t;
923
+ if (typeof e == "string") {
924
+ const r = e.split(".");
925
+ (r.length === 3 || r.length === 5) && ([t] = r);
926
+ } else if (typeof e == "object" && e)
927
+ if ("protected" in e)
928
+ t = e.protected;
929
+ else
930
+ throw new TypeError("Token does not contain a Protected Header");
931
+ try {
932
+ if (typeof t != "string" || !t)
933
+ throw new Error();
934
+ const r = JSON.parse(z.decode(he(t)));
935
+ if (!x(r))
936
+ throw new Error();
937
+ return r;
938
+ } catch {
939
+ throw new TypeError("Invalid Token or Protected Header formatting");
940
+ }
941
+ }
942
+ function Me(e) {
943
+ if (typeof e != "string")
944
+ throw new E("JWTs must use Compact JWS serialization, JWT must be a string");
945
+ const { 1: t, length: r } = e.split(".");
946
+ if (r === 5)
947
+ throw new E("Only JWTs using Compact JWS serialization can be decoded");
948
+ if (r !== 3)
949
+ throw new E("Invalid JWT");
950
+ if (!t)
951
+ throw new E("JWTs must contain a payload");
952
+ let n;
953
+ try {
954
+ n = he(t);
955
+ } catch {
956
+ throw new E("Failed to base64url decode the payload");
957
+ }
958
+ let i;
959
+ try {
960
+ i = JSON.parse(z.decode(n));
961
+ } catch {
962
+ throw new E("Failed to parse the decoded payload as JSON");
963
+ }
964
+ if (!x(i))
965
+ throw new E("Invalid JWT Claims Set");
966
+ return i;
967
+ }
968
+ const c = class c {
969
+ /**
970
+ * Returns a user-friendly name for the given flow strings.
971
+ *
972
+ * The value returned is the one in `flowName`.
973
+ * @param flows the flows to return the names of
974
+ * @returns an array of strings
975
+ */
976
+ static flowNames(t) {
977
+ let r = {};
978
+ return t.forEach((n) => {
979
+ n in c.flowName && (r[n] = c.flowName[n]);
980
+ }), r;
981
+ }
982
+ /**
983
+ * Returns true if the given string is a valid flow name.
984
+ * @param flow the flow to check
985
+ * @returns true or false.
986
+ */
987
+ static isValidFlow(t) {
988
+ return c.allFlows().includes(t);
989
+ }
990
+ /**
991
+ * Returns true only if all given strings are valid flows
992
+ * @param flows the flows to check
993
+ * @returns true or false.
994
+ */
995
+ static areAllValidFlows(t) {
996
+ let r = !0;
997
+ return t.forEach((n) => {
998
+ c.isValidFlow(n) || (r = !1);
999
+ }), r;
1000
+ }
1001
+ static allFlows() {
1002
+ return [
1003
+ c.AuthorizationCode,
1004
+ c.AuthorizationCodeWithPKCE,
1005
+ c.ClientCredentials,
1006
+ c.RefreshToken,
1007
+ c.DeviceCode,
1008
+ c.Password,
1009
+ c.PasswordMfa,
1010
+ c.OidcAuthorizationCode
1011
+ ];
1012
+ }
1013
+ /**
1014
+ * Returns the OAuth grant types that are valid for a given flow, or
1015
+ * `undefined` if it is not a valid flow.
1016
+ * @param oauthFlow the flow to get the grant type for.
1017
+ * @returns a {@link GrantType} value
1018
+ */
1019
+ static grantType(t) {
1020
+ switch (t) {
1021
+ case c.AuthorizationCode:
1022
+ case c.AuthorizationCodeWithPKCE:
1023
+ case c.OidcAuthorizationCode:
1024
+ return ["authorization_code"];
1025
+ case c.ClientCredentials:
1026
+ return ["client_credentials"];
1027
+ case c.RefreshToken:
1028
+ return ["refresh_token"];
1029
+ case c.Password:
1030
+ return ["password"];
1031
+ case c.PasswordMfa:
1032
+ return ["http://auth0.com/oauth/grant-type/mfa-otp", "http://auth0.com/oauth/grant-type/mfa-oob"];
1033
+ case c.DeviceCode:
1034
+ return ["urn:ietf:params:oauth:grant-type:device_code"];
1035
+ }
1036
+ }
1037
+ };
1038
+ /** All flows are allowed */
1039
+ a(c, "All", "all"), /** OAuth authorization code flow (without PKCE) */
1040
+ a(c, "AuthorizationCode", "authorizationCode"), /** OAuth authorization code flow with PKCE */
1041
+ a(c, "AuthorizationCodeWithPKCE", "authorizationCodeWithPKCE"), /** Auth client credentials flow */
1042
+ a(c, "ClientCredentials", "clientCredentials"), /** OAuth refresh token flow */
1043
+ a(c, "RefreshToken", "refreshToken"), /** OAuth device code flow */
1044
+ a(c, "DeviceCode", "deviceCode"), /** OAuth password flow */
1045
+ a(c, "Password", "password"), /** The Auth0 password MFA extension to the password flow */
1046
+ a(c, "PasswordMfa", "passwordMfa"), /** The OpenID Connect authorization code flow, with or without
1047
+ * PKCE.
1048
+ */
1049
+ a(c, "OidcAuthorizationCode", "oidcAuthorizationCode"), /** A user friendly name for the given flow ID
1050
+ *
1051
+ * For example, if you pass "authorizationCode"
1052
+ * (`OAuthFlows.AuthorizationCode`) you will get `"Authorization Code"`.
1053
+ */
1054
+ a(c, "flowName", {
1055
+ [c.AuthorizationCode]: "Authorization Code",
1056
+ [c.AuthorizationCodeWithPKCE]: "Authorization Code with PKCE",
1057
+ [c.ClientCredentials]: "Client Credentials",
1058
+ [c.RefreshToken]: "Refresh Token",
1059
+ [c.DeviceCode]: "Device Code",
1060
+ [c.Password]: "Password",
1061
+ [c.PasswordMfa]: "Password MFA",
1062
+ [c.OidcAuthorizationCode]: "OIDC Authorization Code"
1063
+ });
1064
+ let ee = c;
1065
+ var w, S, N, T, R;
1066
+ class Be {
1067
+ /**
1068
+ * Constructor.
1069
+ *
1070
+ * @param options options:
1071
+ * - `authServerBaseUrl` the base URI for OAuth calls. This is
1072
+ * the value in the isser field of a JWT. The client will
1073
+ * reject any JWTs that are not from this issuer.
1074
+ * - `client_id` the client ID for this client.
1075
+ * - `redriectUri` when making OAuth calls, this value is put
1076
+ * in the redirect_uri field.
1077
+ * - `number` of characters (before base64-url-encoding) for generating
1078
+ * state values in OAuth calls.
1079
+ * - `verifierLength` of characters (before base64-url-encoding) for
1080
+ * generating PKCE values in OAuth calls.
1081
+ * - `tokenConsumer` to keep this class independent of frontend
1082
+ * and backend specific funtionality (eg classes not available
1083
+ * in browsers), the token consumer, which determines if a token
1084
+ * is valid or not, is abstracted out.
1085
+ * - authServerCredentials credentials flag for fetch calls to the
1086
+ * authorization server
1087
+ * - authServerMode mode flag for fetch calls to the
1088
+ * authorization server
1089
+ * - authServerHeaders headers flag for calls to the
1090
+ * authorization server
1091
+ * - `receiveTokensFn` if defined, this will be called when tokens
1092
+ * are received
1093
+ */
1094
+ constructor({
1095
+ authServerBaseUrl: t,
1096
+ client_id: r,
1097
+ client_secret: n,
1098
+ redirect_uri: i,
1099
+ codeChallengeMethod: s,
1100
+ stateLength: o,
1101
+ verifierLength: l,
1102
+ tokenConsumer: f,
1103
+ authServerCredentials: p,
1104
+ authServerMode: P,
1105
+ authServerHeaders: U
1106
+ }) {
1107
+ a(this, "authServerBaseUrl", "");
1108
+ O(this, w);
1109
+ O(this, S);
1110
+ O(this, N);
1111
+ a(this, "codeChallengeMethod", "S256");
1112
+ O(this, T);
1113
+ a(this, "verifierLength", 32);
1114
+ a(this, "redirect_uri");
1115
+ O(this, R, "");
1116
+ a(this, "stateLength", 32);
1117
+ a(this, "authzCode", "");
1118
+ a(this, "oidcConfig");
1119
+ a(this, "tokenConsumer");
1120
+ a(this, "authServerHeaders", {});
1121
+ a(this, "authServerMode");
1122
+ a(this, "authServerCredentials");
1123
+ this.tokenConsumer = f, this.authServerBaseUrl = t, l && (this.verifierLength = l), o && (this.stateLength = o), r && _(this, w, r), n && _(this, S, n), i && (this.redirect_uri = i), s && (this.codeChallengeMethod = s), this.authServerBaseUrl = t, p && (this.authServerCredentials = p), P && (this.authServerMode = P), U && (this.authServerHeaders = U);
1124
+ }
1125
+ set client_id(t) {
1126
+ _(this, w, t);
1127
+ }
1128
+ set client_secret(t) {
1129
+ _(this, S, t);
1130
+ }
1131
+ set codeVerifier(t) {
1132
+ _(this, T, t);
1133
+ }
1134
+ set codeChallenge(t) {
1135
+ _(this, N, t);
1136
+ }
1137
+ set state(t) {
1138
+ _(this, R, t);
1139
+ }
1140
+ /**
1141
+ * Loads OpenID Connect configuration so that the client can determine
1142
+ * the URLs it can call and the features the authorization server provides.
1143
+ *
1144
+ * @param oidcConfig if defined, loadsa the config from this object.
1145
+ * Otherwise, performs a fetch by appending
1146
+ * `/.well-known/openid-configuration` to the
1147
+ * `authServerBaseUrl`.
1148
+ * @throws {@link @crossauth/common!CrossauthError} with the following {@link @crossauth/common!ErrorCode}s
1149
+ * - `Connection` if data from the URL could not be fetched or parsed.
1150
+ */
1151
+ async loadConfig(t) {
1152
+ if (t) {
1153
+ d.logger.debug(h({ msg: "Reading OIDC config locally" })), this.oidcConfig = t;
1154
+ return;
1155
+ }
1156
+ let r;
1157
+ try {
1158
+ const n = new URL(
1159
+ this.authServerBaseUrl + "/.well-known/openid-configuration"
1160
+ );
1161
+ d.logger.debug(h({ msg: `Fetching OIDC config from ${n}` }));
1162
+ let i = { headers: this.authServerHeaders };
1163
+ this.authServerMode && (i.mode = this.authServerMode), this.authServerCredentials && (i.credentials = this.authServerCredentials), r = await fetch(n, i);
1164
+ } catch (n) {
1165
+ d.logger.error(h({ err: n }));
1166
+ }
1167
+ if (!r || !r.ok)
1168
+ throw new g(
1169
+ y.Connection,
1170
+ "Couldn't get OIDC configuration from URL" + this.authServerBaseUrl + "/.well-known/openid-configuration"
1171
+ );
1172
+ this.oidcConfig = { ...te };
1173
+ try {
1174
+ const n = await r.json();
1175
+ for (const [i, s] of Object.entries(n))
1176
+ this.oidcConfig[i] = s;
1177
+ } catch {
1178
+ throw new g(
1179
+ y.Connection,
1180
+ "Unrecognized response from OIDC configuration endpoint"
1181
+ );
1182
+ }
1183
+ }
1184
+ getOidcConfig() {
1185
+ return this.oidcConfig;
1186
+ }
1187
+ //////////////////////////////////////////////////////////////////////
1188
+ // Authorization Code Flow
1189
+ /**
1190
+ * Starts the authorizatuin code flow, optionally with PKCE.
1191
+ *
1192
+ * Doesn't actually call the endpoint but rather returns its URL
1193
+ *
1194
+ * @param scope optionally specify the scopes to ask the user to
1195
+ * authorize (space separated, non URL-encoded)
1196
+ * @param pkce if true, initiate the Authorization Code Flow with PKCE,
1197
+ * otherwiswe without PKCE.
1198
+ * @returns an object with
1199
+ * - `url` - the full `authorize` URL to fetch, if there was no
1200
+ * error, undefined otherwise
1201
+ * - `error` OAuth error if there was an error, undefined
1202
+ * otherwise. See OAuth specification for authorize endpoint
1203
+ * - `error_description` friendly error message or undefined
1204
+ * if no error
1205
+ */
1206
+ async startAuthorizationCodeFlow(t, r = !1) {
1207
+ var s, o, l;
1208
+ if (d.logger.debug(h({ msg: "Starting authorization code flow" })), this.oidcConfig || await this.loadConfig(), !((s = this.oidcConfig) != null && s.response_types_supported.includes("code")) || !((o = this.oidcConfig) != null && o.response_modes_supported.includes("query")))
1209
+ return {
1210
+ error: "invalid_request",
1211
+ error_description: "Server does not support authorization code flow"
1212
+ };
1213
+ if (!((l = this.oidcConfig) != null && l.authorization_endpoint))
1214
+ return {
1215
+ error: "server_error",
1216
+ error_description: "Cannot get authorize endpoint"
1217
+ };
1218
+ if (_(this, R, this.randomValue(this.stateLength)), !u(this, w)) return {
1219
+ error: "invalid_request",
1220
+ error_description: "Cannot make authorization code flow without client id"
1221
+ };
1222
+ if (!this.redirect_uri) return {
1223
+ error: "invalid_request",
1224
+ error_description: "Cannot make authorization code flow without Redirect Uri"
1225
+ };
1226
+ let i = this.oidcConfig.authorization_endpoint + "?response_type=code&client_id=" + encodeURIComponent(u(this, w)) + "&state=" + encodeURIComponent(u(this, R)) + "&redirect_uri=" + encodeURIComponent(this.redirect_uri);
1227
+ return t && (i += "&scope=" + encodeURIComponent(t)), r && (_(this, T, this.randomValue(this.verifierLength)), _(this, N, this.codeChallengeMethod == "plain" ? u(this, T) : await this.sha256(u(this, T))), i += "&code_challenge=" + u(this, N)), { url: i };
1228
+ }
1229
+ /**
1230
+ * This implements the functionality behind the redirect URI
1231
+ *
1232
+ * Does not throw exceptions.
1233
+ *
1234
+ * If an error wasn't reported, a POST request to the `token` endpoint with
1235
+ * the authorization code to get an access token, etc. If there was
1236
+ * an error, this is just passed through without calling and further
1237
+ * endpoints.
1238
+ *
1239
+ * @param code the authorization code
1240
+ * @param state the random state variable
1241
+ * @param error if defined, it will be returned as an error. This is
1242
+ * for cascading errors from previous requests.
1243
+ * @param errorDescription if error is defined, this text is returned
1244
+ * as the `error_description` It is set to `Unknown error`
1245
+ * otherwise
1246
+ * @returns The {@link OAuthTokenResponse} from the `token` endpoint
1247
+ * request, or `error` and `error_description`.
1248
+ */
1249
+ async redirectEndpoint(t, r, n, i) {
1250
+ var p, P;
1251
+ if (this.oidcConfig || await this.loadConfig(), n || !t)
1252
+ return n || (n = "server_error"), i || (i = "Unknown error"), { error: n, error_description: i };
1253
+ if (u(this, R) && r != u(this, R))
1254
+ return { error: "access_denied", error_description: "State is not valid" };
1255
+ if (this.authzCode = t, !((p = this.oidcConfig) != null && p.grant_types_supported.includes("authorization_code")))
1256
+ return {
1257
+ error: "invalid_request",
1258
+ error_description: "Server does not support authorization code grant"
1259
+ };
1260
+ if (!((P = this.oidcConfig) != null && P.token_endpoint))
1261
+ return {
1262
+ error: "server_error",
1263
+ error_description: "Cannot get token endpoint"
1264
+ };
1265
+ const s = this.oidcConfig.token_endpoint;
1266
+ let o, l;
1267
+ o = "authorization_code", l = u(this, S);
1268
+ let f = {
1269
+ grant_type: o,
1270
+ client_id: u(this, w),
1271
+ code: this.authzCode
1272
+ };
1273
+ l && (f.client_secret = l), f.code_verifier = u(this, T);
1274
+ try {
1275
+ return this.post(s, f, this.authServerHeaders);
1276
+ } catch (U) {
1277
+ return d.logger.error(h({ err: U })), {
1278
+ error: "server_error",
1279
+ error_description: "Unable to get access token from server"
1280
+ };
1281
+ }
1282
+ }
1283
+ //////////////////////////////////////////////////////////////////////
1284
+ // Client Credentials Flow
1285
+ /**
1286
+ * Performs the client credentials flow.
1287
+ *
1288
+ * Does not throw exceptions.
1289
+ *
1290
+ * Makes a POST request to the `token` endpoint with the
1291
+ * authorization code to get an access token, etc.
1292
+ *
1293
+ * @param scope the scopes to authorize for the client (optional)
1294
+ * @returns The {@link OAuthTokenResponse} from the `token` endpoint
1295
+ * request, or `error` and `error_description`.
1296
+ */
1297
+ async clientCredentialsFlow(t) {
1298
+ var i, s;
1299
+ if (d.logger.debug(h({ msg: "Starting client credentials flow" })), this.oidcConfig || await this.loadConfig(), !((i = this.oidcConfig) != null && i.grant_types_supported.includes("client_credentials")))
1300
+ return {
1301
+ error: "invalid_request",
1302
+ error_description: "Server does not support client credentials grant"
1303
+ };
1304
+ if (!((s = this.oidcConfig) != null && s.token_endpoint))
1305
+ return { error: "server_error", error_description: "Cannot get token endpoint" };
1306
+ if (!u(this, w)) return {
1307
+ error: "invalid_request",
1308
+ error_description: "Cannot make client credentials flow without client id"
1309
+ };
1310
+ const r = this.oidcConfig.token_endpoint;
1311
+ let n = {
1312
+ grant_type: "client_credentials",
1313
+ client_id: u(this, w),
1314
+ client_secret: u(this, S)
1315
+ };
1316
+ t && (n.scope = t);
1317
+ try {
1318
+ return await this.post(r, n, this.authServerHeaders);
1319
+ } catch (o) {
1320
+ return d.logger.error(h({ err: o })), {
1321
+ error: "server_error",
1322
+ error_description: "Error connecting to authorization server"
1323
+ };
1324
+ }
1325
+ }
1326
+ //////////////////////////////////////////////////////////////////////
1327
+ // Password and Password MFA Flows
1328
+ /** Initiates the Password Flow.
1329
+ *
1330
+ * Does not throw exceptions.
1331
+ *
1332
+ * @param username the username
1333
+ * @param password the user's password
1334
+ * @param scope the scopes to authorize (optional)
1335
+ * @returns An {@link OAuthTokenResponse} which may contain data or
1336
+ * the OAuth error fields. If 2FA is enabled for this user on the
1337
+ * authorization server, the Password MFA flow is followed. See
1338
+ * {@link https://auth0.com/docs/secure/multi-factor-authentication/multi-factor-authentication-factors}.
1339
+ *
1340
+ */
1341
+ async passwordFlow(t, r, n) {
1342
+ var o, l;
1343
+ if (d.logger.debug(h({ msg: "Starting password flow" })), this.oidcConfig || await this.loadConfig(), !((o = this.oidcConfig) != null && o.grant_types_supported.includes("password")))
1344
+ return {
1345
+ error: "invalid_request",
1346
+ error_description: "Server does not support password grant"
1347
+ };
1348
+ if (!((l = this.oidcConfig) != null && l.token_endpoint))
1349
+ return {
1350
+ error: "server_error",
1351
+ error_description: "Cannot get token endpoint"
1352
+ };
1353
+ const i = this.oidcConfig.token_endpoint;
1354
+ let s = {
1355
+ grant_type: "password",
1356
+ client_id: u(this, w),
1357
+ client_secret: u(this, S),
1358
+ username: t,
1359
+ password: r
1360
+ };
1361
+ n && (s.scope = n);
1362
+ try {
1363
+ return await this.post(i, s, this.authServerHeaders);
1364
+ } catch (f) {
1365
+ return d.logger.error(h({ err: f })), {
1366
+ error: "server_error",
1367
+ error_description: "Error connecting to authorization server"
1368
+ };
1369
+ }
1370
+ }
1371
+ /** Request valid authenticators using the Password MFA flow,
1372
+ * after the Password flow has been initiated.
1373
+ *
1374
+ * Does not throw exceptions.
1375
+ *
1376
+ * @param mfaToken the MFA token that was returned by the authorization
1377
+ * server in the response from the Password Flow.
1378
+ * @returns Either
1379
+ * - authenticators an array of {@link MfaAuthenticatorResponse} objects,
1380
+ * as per Auth0's Password MFA documentation
1381
+ * - an `error` and `error_description`, also as per Auth0's Password MFA
1382
+ * documentation
1383
+ */
1384
+ async mfaAuthenticators(t) {
1385
+ var s, o, l;
1386
+ if (d.logger.debug(h({ msg: "Getting valid MFA authenticators" })), this.oidcConfig || await this.loadConfig(), !((s = this.oidcConfig) != null && s.grant_types_supported.includes("http://auth0.com/oauth/grant-type/mfa-otp")) && ((o = this.oidcConfig) != null && o.grant_types_supported.includes("http://auth0.com/oauth/grant-type/mfa-oob")))
1387
+ return {
1388
+ error: "invalid_request",
1389
+ error_description: "Server does not support password_mfa grant"
1390
+ };
1391
+ if (!((l = this.oidcConfig) != null && l.issuer))
1392
+ return { error: "server_error", error_description: "Cannot get issuer" };
1393
+ const r = this.oidcConfig.issuer + (this.oidcConfig.issuer.endsWith("/") ? "" : "/") + "mfa/authenticators", n = await this.get(r, { authorization: "Bearer " + t, ...this.authServerHeaders });
1394
+ if (!Array.isArray(n))
1395
+ return {
1396
+ error: "server_error",
1397
+ error_description: "Expected array of authenticators in mfa/authenticators response"
1398
+ };
1399
+ let i = [];
1400
+ for (let f = 0; f < n.length; ++f) {
1401
+ const p = n[f];
1402
+ if (!p.id || !p.authenticator_type || !p.active)
1403
+ return {
1404
+ error: "server_error",
1405
+ error_description: "Invalid mfa/authenticators response"
1406
+ };
1407
+ i.push({
1408
+ id: p.id,
1409
+ authenticator_type: p.authenticator_type,
1410
+ active: p.active,
1411
+ name: p.name,
1412
+ oob_channel: p.oob_channel
1413
+ });
1414
+ }
1415
+ return { authenticators: i };
1416
+ }
1417
+ /**
1418
+ * This is part of the Auth0 Password MFA flow. Once the client has
1419
+ * received a list of valid authenticators, if it wishes to initiate
1420
+ * OTP, call this function
1421
+ *
1422
+ * Does not throw exceptions.
1423
+ *
1424
+ * @param mfaToken the MFA token that was returned by the authorization
1425
+ * server in the response from the Password Flow.
1426
+ * @param authenticatorId the authenticator ID, as returned in the response
1427
+ * from the `mfaAuthenticators` request.
1428
+ */
1429
+ async mfaOtpRequest(t, r) {
1430
+ var s, o;
1431
+ if (d.logger.debug(h({ msg: "Making MFA OTB request" })), this.oidcConfig || await this.loadConfig(), !((s = this.oidcConfig) != null && s.grant_types_supported.includes("http://auth0.com/oauth/grant-type/mfa-otp")))
1432
+ return {
1433
+ error: "invalid_request",
1434
+ error_description: "Server does not support password_mfa grant"
1435
+ };
1436
+ if (!((o = this.oidcConfig) != null && o.issuer))
1437
+ return { error: "server_error", error_description: "Cannot get issuer" };
1438
+ const n = this.oidcConfig.issuer + (this.oidcConfig.issuer.endsWith("/") ? "" : "/") + "mfa/challenge", i = await this.post(n, {
1439
+ client_id: u(this, w),
1440
+ client_secret: u(this, S),
1441
+ challenge_type: "otp",
1442
+ mfa_token: t,
1443
+ authenticator_id: r
1444
+ }, this.authServerHeaders);
1445
+ return i.challenge_type != "otp" ? {
1446
+ error: i.error ?? "server_error",
1447
+ error_description: i.error_description ?? "Invalid OTP challenge response"
1448
+ } : i;
1449
+ }
1450
+ /**
1451
+ * Completes the Password MFA OTP flow.
1452
+ * @param mfaToken the MFA token that was returned by the authorization
1453
+ * server in the response from the Password Flow.
1454
+ * @param otp the OTP entered by the user
1455
+ * @returns an object with some of the following fields, depending on
1456
+ * authorization server configuration and whether there were
1457
+ * errors:
1458
+ * - `access_token` an OAuth access token
1459
+ * - `refresh_token` an OAuth access token
1460
+ * - `id_token` an OpenID Connect ID token
1461
+ * - `expires_in` number of seconds when the access token expires
1462
+ * - `scope` the scopes the user authorized
1463
+ * - `token_type` the OAuth token type
1464
+ * - `error` as per Auth0 Password MFA documentation
1465
+ * - `error_description` friendly error message
1466
+ */
1467
+ async mfaOtpComplete(t, r, n) {
1468
+ var o, l;
1469
+ if (d.logger.debug(h({ msg: "Completing MFA OTP request" })), this.oidcConfig || await this.loadConfig(), !((o = this.oidcConfig) != null && o.grant_types_supported.includes("http://auth0.com/oauth/grant-type/mfa-otp")))
1470
+ return {
1471
+ error: "invalid_request",
1472
+ error_description: "Server does not support password_mfa grant"
1473
+ };
1474
+ if (!((l = this.oidcConfig) != null && l.issuer))
1475
+ return { error: "server_error", error_description: "Cannot get issuer" };
1476
+ const i = this.oidcConfig.token_endpoint, s = await this.post(i, {
1477
+ grant_type: "http://auth0.com/oauth/grant-type/mfa-otp",
1478
+ client_id: u(this, w),
1479
+ client_secret: u(this, S),
1480
+ challenge_type: "otp",
1481
+ mfa_token: t,
1482
+ otp: r,
1483
+ scope: n
1484
+ }, this.authServerHeaders);
1485
+ return {
1486
+ id_token: s.id_token,
1487
+ access_token: s.access_token,
1488
+ refresh_token: s.refresh_token,
1489
+ expires_in: Number(s.expires_in),
1490
+ scope: s.scope,
1491
+ token_type: s.token_type,
1492
+ error: s.error,
1493
+ error_description: s.error_description
1494
+ };
1495
+ }
1496
+ /**
1497
+ * This is part of the Auth0 Password MFA flow. Once the client has
1498
+ * received a list of valid authenticators, if it wishes to initiate
1499
+ * OOB (out of band) login, call this function
1500
+ *
1501
+ * Does not throw exceptions.
1502
+ *
1503
+ * @param mfaToken the MFA token that was returned by the authorization
1504
+ * server in the response from the Password Flow.
1505
+ * @param authenticatorId the authenticator ID, as returned in the response
1506
+ * from the `mfaAuthenticators` request.
1507
+ * @returns an object with one or more of the following defined:
1508
+ * - `challenge_type` as per the Auth0 MFA documentation
1509
+ * - `oob_code` as per the Auth0 MFA documentation
1510
+ * - `binding_method` as per the Auth0 MFA documentation
1511
+ * - `error` as per Auth0 Password MFA documentation
1512
+ * - `error_description` friendly error message
1513
+ */
1514
+ async mfaOobRequest(t, r) {
1515
+ var s, o;
1516
+ if (d.logger.debug(h({ msg: "Making MFA OOB request" })), this.oidcConfig || await this.loadConfig(), !((s = this.oidcConfig) != null && s.grant_types_supported.includes("http://auth0.com/oauth/grant-type/mfa-otp")))
1517
+ return {
1518
+ error: "invalid_request",
1519
+ error_description: "Server does not support password_mfa grant"
1520
+ };
1521
+ if (!((o = this.oidcConfig) != null && o.issuer))
1522
+ return { error: "server_error", error_description: "Cannot get issuer" };
1523
+ const n = this.oidcConfig.issuer + (this.oidcConfig.issuer.endsWith("/") ? "" : "/") + "mfa/challenge", i = await this.post(n, {
1524
+ client_id: u(this, w),
1525
+ client_secret: u(this, S),
1526
+ challenge_type: "oob",
1527
+ mfa_token: t,
1528
+ authenticator_id: r
1529
+ }, this.authServerHeaders);
1530
+ return i.challenge_type != "oob" || !i.oob_code || !i.binding_method ? { error: i.error ?? "server_error", error_description: i.error_description ?? "Invalid OOB challenge response" } : {
1531
+ challenge_type: i.challenge_type,
1532
+ oob_code: i.oob_code,
1533
+ binding_method: i.binding_method,
1534
+ error: i.error,
1535
+ error_description: i.error_description
1536
+ };
1537
+ }
1538
+ /**
1539
+ * Completes the Password MFA OTP flow.
1540
+ *
1541
+ * Does not throw exceptions.
1542
+ *
1543
+ * @param mfaToken the MFA token that was returned by the authorization
1544
+ * server in the response from the Password Flow.
1545
+ * @param oobCode the code entered by the user
1546
+ * @returns an {@link OAuthTokenResponse} object, which may contain
1547
+ * an error instead of the response fields.
1548
+ */
1549
+ async mfaOobComplete(t, r, n, i) {
1550
+ var l, f;
1551
+ if (d.logger.debug(h({ msg: "Completing MFA OOB request" })), this.oidcConfig || await this.loadConfig(), !((l = this.oidcConfig) != null && l.grant_types_supported.includes("http://auth0.com/oauth/grant-type/mfa-oob")))
1552
+ return {
1553
+ error: "invalid_request",
1554
+ error_description: "Server does not support password_mfa grant"
1555
+ };
1556
+ if (!((f = this.oidcConfig) != null && f.issuer))
1557
+ return { error: "server_error", error_description: "Cannot get issuer" };
1558
+ const s = this.oidcConfig.token_endpoint, o = await this.post(s, {
1559
+ grant_type: "http://auth0.com/oauth/grant-type/mfa-oob",
1560
+ client_id: u(this, w),
1561
+ client_secret: u(this, S),
1562
+ challenge_type: "otp",
1563
+ mfa_token: t,
1564
+ oob_code: r,
1565
+ binding_code: n,
1566
+ scope: i
1567
+ }, this.authServerHeaders);
1568
+ return o.error ? {
1569
+ error: o.error,
1570
+ error_description: o.error_description
1571
+ } : {
1572
+ id_token: o.id_token,
1573
+ access_token: o.access_token,
1574
+ refresh_token: o.refresh_token,
1575
+ expires_in: "expires_in" in o ? Number(o.expires_in) : void 0,
1576
+ scope: o.scope,
1577
+ token_type: o.token_type
1578
+ };
1579
+ }
1580
+ //////////////////////////////////////////////////////////////////////
1581
+ // Refresh Token Flow
1582
+ async refreshTokenFlow(t) {
1583
+ var s, o;
1584
+ if (d.logger.debug(h({ msg: "Starting refresh token flow" })), this.oidcConfig || await this.loadConfig(), !((s = this.oidcConfig) != null && s.grant_types_supported.includes("refresh_token")))
1585
+ return {
1586
+ error: "invalid_request",
1587
+ error_description: "Server does not support refresh_token grant"
1588
+ };
1589
+ if (!((o = this.oidcConfig) != null && o.token_endpoint))
1590
+ return {
1591
+ error: "server_error",
1592
+ error_description: "Cannot get token endpoint"
1593
+ };
1594
+ const r = this.oidcConfig.token_endpoint;
1595
+ let n;
1596
+ n = u(this, S);
1597
+ let i = {
1598
+ grant_type: "refresh_token",
1599
+ refresh_token: t,
1600
+ client_id: u(this, w)
1601
+ };
1602
+ n && (i.client_secret = n);
1603
+ try {
1604
+ return await this.post(r, i, this.authServerHeaders);
1605
+ } catch (l) {
1606
+ return d.logger.error(h({ err: l })), {
1607
+ error: "server_error",
1608
+ error_description: "Error connecting to authorization server"
1609
+ };
1610
+ }
1611
+ }
1612
+ //////////////////////////////////////////////////////////////////////
1613
+ // Device Code Flow
1614
+ /**
1615
+ * Starts the Device Code Flow on the primary device (the one wanting an access token)
1616
+ * @param url The URl for the device_authorization endpoint, as it is not defined in the OIDC configuration
1617
+ * @param scope optional scope to request authorization for
1618
+ * @returns See {@link OAuthDeviceAuthorizationResponse}
1619
+ */
1620
+ async startDeviceCodeFlow(t, r) {
1621
+ var i;
1622
+ if (d.logger.debug(h({ msg: "Starting device code flow" })), this.oidcConfig || await this.loadConfig(), !((i = this.oidcConfig) != null && i.grant_types_supported.includes("urn:ietf:params:oauth:grant-type:device_code")))
1623
+ return {
1624
+ error: "invalid_request",
1625
+ error_description: "Server does not support device code grant"
1626
+ };
1627
+ let n = {
1628
+ grant_type: "urn:ietf:params:oauth:grant-type:device_code",
1629
+ client_id: u(this, w),
1630
+ client_secret: u(this, S)
1631
+ };
1632
+ r && (n.scope = r);
1633
+ try {
1634
+ return await this.post(t, n, this.authServerHeaders);
1635
+ } catch (s) {
1636
+ return d.logger.error(h({ err: s })), {
1637
+ error: "server_error",
1638
+ error_description: "Error connecting to authorization server"
1639
+ };
1640
+ }
1641
+ }
1642
+ /**
1643
+ * Polls the device endpoint to check if the device code flow has been
1644
+ * authorized by the user.
1645
+ *
1646
+ * @param deviceCode the device code to poll
1647
+ * @returns See {@link OAuthDeviceResponse}
1648
+ */
1649
+ async pollDeviceCodeFlow(t) {
1650
+ var n, i, s;
1651
+ if (d.logger.debug(h({ msg: "Starting device code flow" })), this.oidcConfig || await this.loadConfig(), !((n = this.oidcConfig) != null && n.grant_types_supported.includes("urn:ietf:params:oauth:grant-type:device_code")))
1652
+ return {
1653
+ error: "invalid_request",
1654
+ error_description: "Server does not support device code grant"
1655
+ };
1656
+ if (!((i = this.oidcConfig) != null && i.token_endpoint))
1657
+ return {
1658
+ error: "server_error",
1659
+ error_description: "Cannot get token endpoint"
1660
+ };
1661
+ let r = {
1662
+ grant_type: "urn:ietf:params:oauth:grant-type:device_code",
1663
+ client_id: u(this, w),
1664
+ client_secret: u(this, S),
1665
+ device_code: t
1666
+ };
1667
+ try {
1668
+ const o = await this.post((s = this.oidcConfig) == null ? void 0 : s.token_endpoint, r, this.authServerHeaders);
1669
+ return o.error, o;
1670
+ } catch (o) {
1671
+ return d.logger.error(h({ err: o })), {
1672
+ error: "server_error",
1673
+ error_description: "Error connecting to authorization server"
1674
+ };
1675
+ }
1676
+ }
1677
+ /**
1678
+ * Makes a POST request to the given URL using `fetch()`.
1679
+ *
1680
+ * @param url the URL to fetch
1681
+ * @param params the body parameters, which are passed as JSON.
1682
+ * @returns the parsed JSON response as an object.
1683
+ * @throws any exception raised by `fetch()`
1684
+ */
1685
+ async post(t, r, n = {}) {
1686
+ d.logger.debug(h({
1687
+ msg: "Fetch POST",
1688
+ url: t,
1689
+ params: Object.keys(r)
1690
+ }));
1691
+ let i = {};
1692
+ return this.authServerCredentials && (i.credentials = this.authServerCredentials), this.authServerMode && (i.mode = this.authServerMode), await (await fetch(t, {
1693
+ method: "POST",
1694
+ ...i,
1695
+ headers: {
1696
+ Accept: "application/json",
1697
+ "Content-Type": "application/json",
1698
+ ...n
1699
+ },
1700
+ body: JSON.stringify(r)
1701
+ })).json();
1702
+ }
1703
+ /**
1704
+ * Makes a GET request to the given URL using `fetch()`.
1705
+ *
1706
+ * @param url the URL to fetch
1707
+ * @param headers any headers to add to the request
1708
+ * @returns the parsed JSON response as an object.
1709
+ * @throws any exception raised by `fetch()`
1710
+ */
1711
+ async get(t, r = {}) {
1712
+ d.logger.debug(h({ msg: "Fetch GET", url: t }));
1713
+ let n = {};
1714
+ return this.authServerCredentials && (n.credentials = this.authServerCredentials), this.authServerMode && (n.mode = this.authServerMode), await (await fetch(t, {
1715
+ method: "GET",
1716
+ ...n,
1717
+ headers: {
1718
+ Accept: "application/json",
1719
+ "Content-Type": "application/json",
1720
+ ...r
1721
+ }
1722
+ })).json();
1723
+ }
1724
+ /**
1725
+ * Validates an OpenID ID token, returning undefined if it is invalid.
1726
+ *
1727
+ * Does not raise exceptions.
1728
+ *
1729
+ * @param token the token to validate. To be valid, the signature must
1730
+ * be valid and the `type` claim in the payload must be set to `id`.
1731
+ * @returns the parsed payload or undefined if the token is invalid.
1732
+ */
1733
+ async validateIdToken(t) {
1734
+ try {
1735
+ return await this.tokenConsumer.tokenAuthorized(t, "id");
1736
+ } catch {
1737
+ return;
1738
+ }
1739
+ }
1740
+ /**
1741
+ * Validatesd a token using the token consumer.
1742
+ *
1743
+ * @param idToken the token to validate
1744
+ * @returns the parsed JSON of the payload, or undefinedf if it is not
1745
+ * valid.
1746
+ */
1747
+ async idTokenAuthorized(t) {
1748
+ try {
1749
+ return await this.tokenConsumer.tokenAuthorized(t, "id");
1750
+ } catch (r) {
1751
+ d.logger.warn(h({ err: r }));
1752
+ return;
1753
+ }
1754
+ }
1755
+ getTokenPayload(t) {
1756
+ return Me(t);
1757
+ }
1758
+ }
1759
+ w = new WeakMap(), S = new WeakMap(), N = new WeakMap(), T = new WeakMap(), R = new WeakMap();
1760
+ class Le {
1761
+ /**
1762
+ * Constrctor
1763
+ *
1764
+ * @param audience : this is the value expected in the `aud` field
1765
+ * of the JWT. The token is rejected if it doesn't match.
1766
+ * @param options See {@link OAuthTokenConsumerBaseOptions}.
1767
+ */
1768
+ constructor(t, r = {}) {
1769
+ a(this, "audience");
1770
+ a(this, "jwtKeyType");
1771
+ a(this, "jwtSecretKey");
1772
+ a(this, "jwtPublicKey");
1773
+ a(this, "clockTolerance", 10);
1774
+ a(this, "authServerBaseUrl", "");
1775
+ /**
1776
+ * The OpenID Connect configuration for the authorization server,
1777
+ * either passed to the constructor or fetched from the authorization
1778
+ * server.
1779
+ */
1780
+ a(this, "oidcConfig");
1781
+ /**
1782
+ * The RSA public keys or symmetric keys for the authorization server,
1783
+ * either passed to the constructor or fetched from the authorization
1784
+ * server.
1785
+ */
1786
+ a(this, "keys", {});
1787
+ if (this.audience = t, r.authServerBaseUrl && (this.authServerBaseUrl = r.authServerBaseUrl), r.jwtKeyType && (this.jwtKeyType = r.jwtKeyType), r.jwtSecretKey && (this.jwtSecretKey = r.jwtSecretKey), r.jwtPublicKey && (this.jwtPublicKey = r.jwtPublicKey), r.clockTolerance && (this.clockTolerance = r.clockTolerance), r.oidcConfig && (this.oidcConfig = r.oidcConfig), this.jwtPublicKey && !this.jwtKeyType)
1788
+ throw new g(
1789
+ y.Configuration,
1790
+ "If specifying jwtPublic key, must also specify jwtKeyType"
1791
+ );
1792
+ }
1793
+ /**
1794
+ * This loads keys either from the ones passed in the constructor
1795
+ * or by fetching from the authorization server.
1796
+ *
1797
+ * Note that even if you pass the keys to the constructor, you must
1798
+ * still call this function. This is because key loading is
1799
+ * asynchronous, and constructors may not be async.
1800
+ */
1801
+ async loadKeys() {
1802
+ try {
1803
+ if (this.jwtSecretKey) {
1804
+ if (!this.jwtKeyType)
1805
+ throw new g(
1806
+ y.Configuration,
1807
+ "Must specify jwtKeyType if setting jwtSecretKey"
1808
+ );
1809
+ this.keys._default = await Oe(this.jwtSecretKey, this.jwtKeyType);
1810
+ } else if (this.jwtPublicKey) {
1811
+ if (!this.jwtKeyType)
1812
+ throw new g(
1813
+ y.Configuration,
1814
+ "Must specify jwtKeyType if setting jwtPublicKey"
1815
+ );
1816
+ const t = await Ee(this.jwtPublicKey, this.jwtKeyType);
1817
+ this.keys._default = t;
1818
+ } else {
1819
+ if (this.oidcConfig || await this.loadConfig(), !this.oidcConfig)
1820
+ throw new g(
1821
+ y.Connection,
1822
+ "Load OIDC config before Jwks"
1823
+ );
1824
+ await this.loadJwks();
1825
+ }
1826
+ } catch (t) {
1827
+ throw d.logger.debug(h({ err: t })), new g(y.Connection, "Couldn't load keys");
1828
+ }
1829
+ }
1830
+ /**
1831
+ * Loads OpenID Connect configuration, or fetches it from the
1832
+ * authorization server (using the well-known enpoint appended
1833
+ * to `authServerBaseUrl` )
1834
+ * @param oidcConfig the configuration, or undefined to load it from
1835
+ * the authorization server
1836
+ * @throws a {@link @crossauth/common!CrossauthError} object with {@link @crossauth/common!ErrorCode} of
1837
+ * - `Connection` if the fetch to the authorization server failed.
1838
+ */
1839
+ async loadConfig(t) {
1840
+ if (t) {
1841
+ this.oidcConfig = t;
1842
+ return;
1843
+ }
1844
+ if (!this.authServerBaseUrl)
1845
+ throw new g(y.Connection, "Couldn't get OIDC configuration. Either set authServerBaseUrl or set config manually");
1846
+ let r;
1847
+ try {
1848
+ r = await fetch(new URL("/.well-known/openid-configuration", this.authServerBaseUrl));
1849
+ } catch (n) {
1850
+ d.logger.error(h({ err: n }));
1851
+ }
1852
+ if (!r || !r.ok)
1853
+ throw new g(y.Connection, "Couldn't get OIDC configuration");
1854
+ this.oidcConfig = { ...te };
1855
+ try {
1856
+ const n = await r.json();
1857
+ for (const [i, s] of Object.entries(n))
1858
+ this.oidcConfig[i] = s;
1859
+ } catch {
1860
+ throw new g(y.Connection, "Unrecognized response from OIDC configuration endpoint");
1861
+ }
1862
+ }
1863
+ /**
1864
+ * Loads the JWT signature validation keys, or fetches them from the
1865
+ * authorization server (using the URL in the OIDC configuration).
1866
+ * @param jwks the keys to load, or undefined to fetch them from
1867
+ * the authorization server.
1868
+ * @throws a {@link @crossauth/common!CrossauthError} object with {@link @crossauth/common!ErrorCode} of
1869
+ * - `Connection` if the fetch to the authorization server failed,
1870
+ * the OIDC configuration wasn't set or the keys could not be parsed.
1871
+ */
1872
+ async loadJwks(t) {
1873
+ if (t) {
1874
+ this.keys = {};
1875
+ for (let r = 0; r < t.keys.length; ++r) {
1876
+ const n = t.keys[r];
1877
+ this.keys[n.kid ?? "_default"] = await Z(t.keys[r]);
1878
+ }
1879
+ } else {
1880
+ if (!this.oidcConfig)
1881
+ throw new g(y.Connection, "Load OIDC config before Jwks");
1882
+ let r;
1883
+ try {
1884
+ r = await fetch(new URL(this.oidcConfig.jwks_uri));
1885
+ } catch (n) {
1886
+ d.logger.error(h({ err: n }));
1887
+ }
1888
+ if (!r || !r.ok)
1889
+ throw new g(y.Connection, "Couldn't get OIDC configuration");
1890
+ this.keys = {};
1891
+ try {
1892
+ const n = await r.json();
1893
+ if (!("keys" in n) || !Array.isArray(n.keys))
1894
+ throw new g(y.Connection, "Couldn't fetch keys");
1895
+ for (let i = 0; i < n.keys.length; ++i)
1896
+ try {
1897
+ let s = "_default";
1898
+ "kid" in n.keys[i] && typeof n.keys[i] == "string" && (s = String(n.keys[i]));
1899
+ const o = await Z(n.keys[i]);
1900
+ this.keys[s] = o;
1901
+ } catch (s) {
1902
+ throw d.logger.error(h({ err: s })), new g(y.Connection, "Couldn't load keys");
1903
+ }
1904
+ } catch (n) {
1905
+ throw d.logger.error(h({ err: n })), new g(y.Connection, "Unrecognized response from OIDC jwks endpoint");
1906
+ }
1907
+ }
1908
+ }
1909
+ /**
1910
+ * Returns JWT payload if the token is valid, undefined otherwise.
1911
+ *
1912
+ * Doesn't throw exceptions.
1913
+ *
1914
+ * @param token the token to validate
1915
+ * @param tokenType either `access`, `refresh` or `id`. If the
1916
+ * `type` field in the JWT payload doesn't match this, validation
1917
+ * fails.
1918
+ * @returns the JWT payload if the token is valid, `undefined` otherwise.
1919
+ */
1920
+ async tokenAuthorized(t, r) {
1921
+ (!this.keys || Object.keys(this.keys).length == 0) && await this.loadKeys();
1922
+ const n = await this.validateToken(t);
1923
+ if (n) {
1924
+ if (n.type != r && d.logger.error(h({ msg: r + " expected but got " + n.type })), n.iss != this.authServerBaseUrl) {
1925
+ d.logger.error(h({ msg: `Invalid issuer ${n.iss} in access token`, hashedAccessToken: await this.hash(n.jti) }));
1926
+ return;
1927
+ }
1928
+ if (n.aud && (Array.isArray(n.aud) && !n.aud.includes(this.audience) || !Array.isArray(n.aud) && n.aud != this.audience)) {
1929
+ d.logger.error(h({ msg: `Invalid audience ${n.aud} in access token`, hashedAccessToken: await this.hash(n.jti) }));
1930
+ return;
1931
+ }
1932
+ return n;
1933
+ }
1934
+ }
1935
+ async validateToken(t) {
1936
+ (!this.keys || Object.keys(this.keys).length == 0) && d.logger.warn("No keys loaded so cannot validate tokens");
1937
+ let r;
1938
+ try {
1939
+ r = qe(t).kid;
1940
+ } catch {
1941
+ d.logger.warn(h({ msg: "Invalid access token format" }));
1942
+ return;
1943
+ }
1944
+ let n;
1945
+ "_default" in this.keys && (n = this.keys._default);
1946
+ for (let i in this.keys)
1947
+ if (r == i) {
1948
+ n = this.keys[i];
1949
+ break;
1950
+ }
1951
+ if (!n) {
1952
+ d.logger.warn(h({ msg: "No matching keys found for access token" }));
1953
+ return;
1954
+ }
1955
+ try {
1956
+ const { payload: i } = await Je(t, n), s = JSON.parse(new TextDecoder().decode(i));
1957
+ if (s.exp * 1e3 < Date.now() + this.clockTolerance) {
1958
+ d.logger.warn(h({ msg: "Access token has expired" }));
1959
+ return;
1960
+ }
1961
+ return s;
1962
+ } catch {
1963
+ d.logger.warn(h({ msg: "Access token did not validate" }));
1964
+ return;
1965
+ }
1966
+ }
1967
+ }
1968
+ export {
1969
+ g as CrossauthError,
1970
+ d as CrossauthLogger,
1971
+ te as DEFAULT_OIDCCONFIG,
1972
+ y as ErrorCode,
1973
+ C as KeyPrefix,
1974
+ Be as OAuthClientBase,
1975
+ ee as OAuthFlows,
1976
+ Le as OAuthTokenConsumerBase,
1977
+ k as UserState,
1978
+ $e as httpStatus,
1979
+ h as j
1980
+ };