@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/LICENSE +203 -0
- package/dist/error.d.ts +168 -0
- package/dist/error.d.ts.map +1 -0
- package/dist/index.cjs +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.iife.js +1 -0
- package/dist/index.js +1980 -0
- package/dist/interfaces.d.ts +262 -0
- package/dist/interfaces.d.ts.map +1 -0
- package/dist/jwt.d.ts +25 -0
- package/dist/jwt.d.ts.map +1 -0
- package/dist/logger.d.ts +148 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/oauth/client.d.ts +475 -0
- package/dist/oauth/client.d.ts.map +1 -0
- package/dist/oauth/tokenconsumer.d.ts +115 -0
- package/dist/oauth/tokenconsumer.d.ts.map +1 -0
- package/dist/oauth/wellknown.d.ts +59 -0
- package/dist/oauth/wellknown.d.ts.map +1 -0
- package/package.json +32 -0
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
|
+
};
|