@crossauth/backend 0.0.15 → 0.0.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/authenticators/oidcauthenticator.d.ts +110 -0
- package/dist/authenticators/oidcauthenticator.d.ts.map +1 -0
- package/dist/cookieauth.d.ts.map +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.js +1037 -958
- package/dist/oauth/client.d.ts +62 -1
- package/dist/oauth/client.d.ts.map +1 -1
- package/dist/storage/dbstorage.d.ts +12 -0
- package/dist/storage/dbstorage.d.ts.map +1 -1
- package/dist/storage/inmemorystorage.d.ts +11 -0
- package/dist/storage/inmemorystorage.d.ts.map +1 -1
- package/dist/storage/ldapstorage.d.ts +12 -0
- package/dist/storage/ldapstorage.d.ts.map +1 -1
- package/dist/storage/prismastorage.d.ts +12 -0
- package/dist/storage/prismastorage.d.ts.map +1 -1
- package/dist/storage.d.ts +16 -0
- package/dist/storage.d.ts.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
var Ae = Object.defineProperty;
|
|
2
|
-
var Ie = (
|
|
3
|
-
var h = (
|
|
2
|
+
var Ie = (S, s, e) => s in S ? Ae(S, s, { enumerable: !0, configurable: !0, writable: !0, value: e }) : S[s] = e;
|
|
3
|
+
var h = (S, s, e) => Ie(S, typeof s != "symbol" ? s + "" : s, e);
|
|
4
4
|
import { CrossauthError as o, ErrorCode as l, UserState as E, CrossauthLogger as u, j as f, OAuthFlows as b, KeyPrefix as U, OAuthTokenConsumerBase as Pe, OAuthClientBase as Ke } from "@crossauth/common";
|
|
5
5
|
import { PrismaClient as ce, Prisma as X } from "@prisma/client";
|
|
6
6
|
import ye from "ldapjs";
|
|
@@ -9,15 +9,15 @@ import { promisify as De } from "node:util";
|
|
|
9
9
|
import W from "nunjucks";
|
|
10
10
|
import Ee from "nodemailer";
|
|
11
11
|
import Be from "twilio";
|
|
12
|
-
import
|
|
12
|
+
import Le from "qrcode";
|
|
13
13
|
import { authenticator as fe } from "otplib";
|
|
14
|
-
import
|
|
15
|
-
import { createPublicKey as
|
|
14
|
+
import se from "jsonwebtoken";
|
|
15
|
+
import { createPublicKey as ze } from "crypto";
|
|
16
16
|
import te from "node:fs";
|
|
17
17
|
import * as He from "jose";
|
|
18
|
-
var m = /* @__PURE__ */ ((
|
|
19
|
-
function Me(
|
|
20
|
-
let e =
|
|
18
|
+
var m = /* @__PURE__ */ ((S) => (S[S.String = 0] = "String", S[S.Number = 1] = "Number", S[S.Boolean = 2] = "Boolean", S[S.Json = 3] = "Json", S[S.JsonArray = 4] = "JsonArray", S))(m || {});
|
|
19
|
+
function Me(S, s) {
|
|
20
|
+
let e = S.split("."), t = s;
|
|
21
21
|
for (let r in e) {
|
|
22
22
|
const i = e[r];
|
|
23
23
|
if (!(i in t) || t[i] == null) return;
|
|
@@ -25,8 +25,8 @@ function Me(C, a) {
|
|
|
25
25
|
}
|
|
26
26
|
return t;
|
|
27
27
|
}
|
|
28
|
-
function pe(
|
|
29
|
-
let e =
|
|
28
|
+
function pe(S, s) {
|
|
29
|
+
let e = S.split("."), t = s;
|
|
30
30
|
for (let r in e) {
|
|
31
31
|
const i = e[r];
|
|
32
32
|
if (!(i in t) || t[i] == null) return !1;
|
|
@@ -34,48 +34,48 @@ function pe(C, a) {
|
|
|
34
34
|
}
|
|
35
35
|
return !0;
|
|
36
36
|
}
|
|
37
|
-
function je(
|
|
38
|
-
const t = Me(
|
|
39
|
-
|
|
37
|
+
function je(S, s, e) {
|
|
38
|
+
const t = Me(s, e);
|
|
39
|
+
S[s.replace(".", "_")] = t;
|
|
40
40
|
}
|
|
41
|
-
function Ve(
|
|
41
|
+
function Ve(S, s, e, t) {
|
|
42
42
|
var i;
|
|
43
|
-
const r =
|
|
43
|
+
const r = s.replace(".", "_");
|
|
44
44
|
switch (e) {
|
|
45
45
|
case 0:
|
|
46
|
-
|
|
46
|
+
S[r] = process.env[t] == "null" ? null : process.env[t];
|
|
47
47
|
break;
|
|
48
48
|
case 1:
|
|
49
|
-
|
|
49
|
+
S[r] = process.env[t] == "null" ? null : Number(process.env[t]);
|
|
50
50
|
break;
|
|
51
51
|
case 2:
|
|
52
|
-
|
|
52
|
+
S[r] = ["1", "true"].includes(((i = process.env[t]) == null ? void 0 : i.toLowerCase()) ?? "");
|
|
53
53
|
break;
|
|
54
54
|
case 3:
|
|
55
|
-
|
|
55
|
+
S[r] = JSON.parse(process.env[t] ?? "{}");
|
|
56
56
|
break;
|
|
57
57
|
case 4:
|
|
58
|
-
|
|
58
|
+
S[r] = JSON.parse(process.env[t] ?? "[]");
|
|
59
59
|
break;
|
|
60
60
|
}
|
|
61
61
|
}
|
|
62
|
-
function w(
|
|
63
|
-
const
|
|
64
|
-
if (i && !pe(
|
|
65
|
-
throw new o(l.Configuration,
|
|
66
|
-
pe(
|
|
62
|
+
function w(S, s, e, t, r, i = !1) {
|
|
63
|
+
const a = "CROSSAUTH_" + r;
|
|
64
|
+
if (i && !pe(S, t) && !(a && a in process.env))
|
|
65
|
+
throw new o(l.Configuration, S + " is required");
|
|
66
|
+
pe(S, t) ? je(e, S, t) : r && a in process.env && process.env[a] != null && Ve(e, S, s, a);
|
|
67
67
|
}
|
|
68
68
|
class H {
|
|
69
69
|
/**
|
|
70
70
|
* Constructor
|
|
71
71
|
* @param options See {@link UserStorageOptions}
|
|
72
72
|
*/
|
|
73
|
-
constructor(
|
|
73
|
+
constructor(s = {}) {
|
|
74
74
|
h(this, "userEditableFields", []);
|
|
75
75
|
h(this, "adminEditableFields", []);
|
|
76
76
|
h(this, "normalizeUsername", !0);
|
|
77
77
|
h(this, "normalizeEmail", !0);
|
|
78
|
-
w("userEditableFields", m.JsonArray, this,
|
|
78
|
+
w("userEditableFields", m.JsonArray, this, s, "USER_EDITABLE_FIELDS"), w("adminEditableFields", m.JsonArray, this, s, "ADMIN_EDITABLE_FIELDS"), w("normalizeUsername", m.JsonArray, this, s, "NORMALIZE_USERNAME"), w("normalizeEmail", m.JsonArray, this, s, "NORMALIZE_EMAIL");
|
|
79
79
|
}
|
|
80
80
|
/**
|
|
81
81
|
* Creates a user with the given details and secrets.
|
|
@@ -84,7 +84,7 @@ class H {
|
|
|
84
84
|
* @param _secrets will be put in the UserSecrets table
|
|
85
85
|
* @returns the new user as a {@link @crossauth/common!User} object.
|
|
86
86
|
*/
|
|
87
|
-
createUser(
|
|
87
|
+
createUser(s, e) {
|
|
88
88
|
throw new o(l.Configuration);
|
|
89
89
|
}
|
|
90
90
|
/**
|
|
@@ -94,27 +94,27 @@ class H {
|
|
|
94
94
|
* @param str the string to normalize
|
|
95
95
|
* @returns the normalized string, in lowercase with diacritics removed
|
|
96
96
|
*/
|
|
97
|
-
static normalize(
|
|
98
|
-
return
|
|
97
|
+
static normalize(s) {
|
|
98
|
+
return s.normalize("NFD").replace(new RegExp("\\p{Diacritic}", "gu"), "").toLowerCase();
|
|
99
99
|
}
|
|
100
100
|
}
|
|
101
|
-
class
|
|
101
|
+
class L {
|
|
102
102
|
/**
|
|
103
103
|
* Returns an object decoded from the data field as a JSON string
|
|
104
104
|
* @param data the JSON string to decode
|
|
105
105
|
* @returns the parse JSON object
|
|
106
106
|
* @throws an exception is data is not a valid JSON string
|
|
107
107
|
*/
|
|
108
|
-
static decodeData(
|
|
109
|
-
return
|
|
108
|
+
static decodeData(s) {
|
|
109
|
+
return s == null || s == "" ? {} : JSON.parse(s);
|
|
110
110
|
}
|
|
111
111
|
/**
|
|
112
112
|
* Returns a JSON string encoded from the given object
|
|
113
113
|
* @param data the object to encode
|
|
114
114
|
* @returns a JSON string
|
|
115
115
|
*/
|
|
116
|
-
static encodeData(
|
|
117
|
-
return
|
|
116
|
+
static encodeData(s) {
|
|
117
|
+
return s ? JSON.stringify(s) : "{}";
|
|
118
118
|
}
|
|
119
119
|
/**
|
|
120
120
|
* Helper function for imnpklementing `updateData`
|
|
@@ -123,15 +123,15 @@ class z {
|
|
|
123
123
|
* @param value the value to set it to
|
|
124
124
|
* @returns new data object if changes were made, undefined otherwise
|
|
125
125
|
*/
|
|
126
|
-
updateDataInternal(
|
|
126
|
+
updateDataInternal(s, e, t) {
|
|
127
127
|
if (e.indexOf(".") > 0) {
|
|
128
|
-
let r = e.split("."), i =
|
|
129
|
-
for (let
|
|
130
|
-
i = i[r[
|
|
128
|
+
let r = e.split("."), i = s;
|
|
129
|
+
for (let a = 0; a < r.length - 1 && s; a++)
|
|
130
|
+
i = i[r[a]];
|
|
131
131
|
if (i)
|
|
132
|
-
return i[r[r.length - 1]] = t,
|
|
132
|
+
return i[r[r.length - 1]] = t, s;
|
|
133
133
|
} else
|
|
134
|
-
return
|
|
134
|
+
return s[e] = t, s;
|
|
135
135
|
}
|
|
136
136
|
/**
|
|
137
137
|
* Helper function for imnpklementing `deleteData`
|
|
@@ -140,14 +140,14 @@ class z {
|
|
|
140
140
|
* @param dataName name of field to delete (may contain dots)
|
|
141
141
|
* @returns true if modifications were made, false otherwise
|
|
142
142
|
*/
|
|
143
|
-
deleteDataInternal(
|
|
143
|
+
deleteDataInternal(s, e) {
|
|
144
144
|
if (e.indexOf(".") > 0) {
|
|
145
|
-
let t = e.split("."), r =
|
|
146
|
-
for (let i = 0; i < t.length - 1 &&
|
|
145
|
+
let t = e.split("."), r = s;
|
|
146
|
+
for (let i = 0; i < t.length - 1 && s; i++)
|
|
147
147
|
r = r[t[i]];
|
|
148
148
|
return r && r[t[t.length - 1]] ? (delete r[t[t.length - 1]], !0) : !1;
|
|
149
149
|
} else
|
|
150
|
-
return e in
|
|
150
|
+
return e in s ? (delete s[e], !0) : !1;
|
|
151
151
|
}
|
|
152
152
|
}
|
|
153
153
|
class me {
|
|
@@ -155,7 +155,7 @@ class me {
|
|
|
155
155
|
* Constructor
|
|
156
156
|
* @param _options see {@link OAuthClientStorageOptions}
|
|
157
157
|
*/
|
|
158
|
-
constructor(
|
|
158
|
+
constructor(s = {}) {
|
|
159
159
|
}
|
|
160
160
|
}
|
|
161
161
|
class we {
|
|
@@ -163,7 +163,7 @@ class we {
|
|
|
163
163
|
* Constructor
|
|
164
164
|
* @param _options see {@link OAuthAuthorizationStorageOptions}
|
|
165
165
|
*/
|
|
166
|
-
constructor(
|
|
166
|
+
constructor(s = {}) {
|
|
167
167
|
}
|
|
168
168
|
}
|
|
169
169
|
class G extends H {
|
|
@@ -186,9 +186,9 @@ class G extends H {
|
|
|
186
186
|
}), e && e.prismaClient ? this.prismaClient = e.prismaClient : this.prismaClient = new ce();
|
|
187
187
|
}
|
|
188
188
|
async getUser(e, t, r) {
|
|
189
|
-
let i,
|
|
189
|
+
let i, a;
|
|
190
190
|
try {
|
|
191
|
-
|
|
191
|
+
a = await this.prismaClient[this.userTable].findUniqueOrThrow({
|
|
192
192
|
where: {
|
|
193
193
|
[e]: t
|
|
194
194
|
},
|
|
@@ -198,20 +198,20 @@ class G extends H {
|
|
|
198
198
|
i = new o(l.UserNotExist);
|
|
199
199
|
}
|
|
200
200
|
if (this.prismaClient || (i = new o(l.Connection)), i) throw i;
|
|
201
|
-
if ((r == null ? void 0 : r.skipActiveCheck) != !0 &&
|
|
201
|
+
if ((r == null ? void 0 : r.skipActiveCheck) != !0 && a.state == E.awaitingTwoFactorSetup)
|
|
202
202
|
throw u.logger.debug(f({ msg: "2FA setup is not complete" })), new o(l.TwoFactorIncomplete);
|
|
203
|
-
if ((r == null ? void 0 : r.skipActiveCheck) != !0 &&
|
|
203
|
+
if ((r == null ? void 0 : r.skipActiveCheck) != !0 && a.state == E.disabled)
|
|
204
204
|
throw u.logger.debug(f({ msg: "User is deactivated" })), new o(l.UserNotActive);
|
|
205
|
-
if ((r == null ? void 0 : r.skipEmailVerifiedCheck) != !0 &&
|
|
205
|
+
if ((r == null ? void 0 : r.skipEmailVerifiedCheck) != !0 && a.state == E.awaitingEmailVerification)
|
|
206
206
|
throw u.logger.debug(f({ msg: "User has not verified email" })), new o(l.EmailNotVerified);
|
|
207
|
-
if ((r == null ? void 0 : r.skipActiveCheck) != !0 &&
|
|
207
|
+
if ((r == null ? void 0 : r.skipActiveCheck) != !0 && a.state == E.passwordChangeNeeded)
|
|
208
208
|
throw u.logger.debug(f({ msg: "User must change password" })), new o(l.PasswordChangeNeeded);
|
|
209
|
-
if ((r == null ? void 0 : r.skipActiveCheck) != !0 && (
|
|
209
|
+
if ((r == null ? void 0 : r.skipActiveCheck) != !0 && (a.state == E.passwordResetNeeded || a.state == E.passwordAndFactor2ResetNeeded))
|
|
210
210
|
throw u.logger.debug(f({ msg: "User must reset password" })), new o(l.PasswordResetNeeded);
|
|
211
|
-
if ((r == null ? void 0 : r.skipActiveCheck) != !0 &&
|
|
211
|
+
if ((r == null ? void 0 : r.skipActiveCheck) != !0 && a.state == E.factor2ResetNeeded)
|
|
212
212
|
throw u.logger.debug(f({ msg: "2FA reset required" })), new o(l.Factor2ResetNeeded);
|
|
213
|
-
const n =
|
|
214
|
-
return
|
|
213
|
+
const n = a.secrets || {};
|
|
214
|
+
return a.secrets && (delete n[this.useridForeignKeyColumn], delete a.secrets), { user: { ...a, id: a[this.idColumn] }, secrets: { userid: a[this.idColumn], ...n } };
|
|
215
215
|
}
|
|
216
216
|
/**
|
|
217
217
|
* Returns a {@link @crossauth/common!User} and {@link @crossauth/common!UserSecrets} instance matching the given username, or throws an Exception.
|
|
@@ -223,6 +223,17 @@ class G extends H {
|
|
|
223
223
|
const r = G.normalize(e);
|
|
224
224
|
return this.getUser("username_normalized", r, t);
|
|
225
225
|
}
|
|
226
|
+
/**
|
|
227
|
+
* Returns user matching the given field, or throws an exception.
|
|
228
|
+
*
|
|
229
|
+
* @param field the field to match
|
|
230
|
+
* @param value the value to match (case sensitive)
|
|
231
|
+
* @param options optionally turn off checks. Used internally
|
|
232
|
+
* @throws CrossauthException with ErrorCode either `UserNotExist` or whatever pg throws
|
|
233
|
+
*/
|
|
234
|
+
async getUserBy(e, t, r) {
|
|
235
|
+
return this.getUser(e, t, r);
|
|
236
|
+
}
|
|
226
237
|
/**
|
|
227
238
|
* Returns a {@link @crossauth/common!User} and {@link @crossauth/common!UserSecrets} instance matching the given email address, or throws an Exception.
|
|
228
239
|
*
|
|
@@ -266,7 +277,7 @@ class G extends H {
|
|
|
266
277
|
if (!e.id) throw new o(l.InvalidKey);
|
|
267
278
|
t && !t.userid && (t = { ...t, userid: e[this.idColumn] });
|
|
268
279
|
try {
|
|
269
|
-
let { id: r, ...i } = e, { userid:
|
|
280
|
+
let { id: r, ...i } = e, { userid: a, ...n } = t ?? {};
|
|
270
281
|
"email" in i && i.email && (i = { email_normalized: G.normalize(i.email), ...i }), "username" in i && i.username && (i = { username_normalized: G.normalize(i.username), ...i }), t ? await this.prismaClient.$transaction(async (c) => {
|
|
271
282
|
let d = {};
|
|
272
283
|
try {
|
|
@@ -317,13 +328,13 @@ class G extends H {
|
|
|
317
328
|
async createUser(e, t) {
|
|
318
329
|
let r;
|
|
319
330
|
if (t && !t.password) throw new o(l.PasswordFormat, "Password required when creating user");
|
|
320
|
-
let i,
|
|
331
|
+
let i, a = "", n = "";
|
|
321
332
|
try {
|
|
322
|
-
"email" in e && e.email && (n = G.normalize(e.email)), "username" in e && e.username && (
|
|
333
|
+
"email" in e && e.email && (n = G.normalize(e.email)), "username" in e && e.username && (a = G.normalize(e.username)), t ? i = await this.prismaClient[this.userTable].create({
|
|
323
334
|
data: {
|
|
324
335
|
...e,
|
|
325
336
|
email_normalized: n,
|
|
326
|
-
username_normalized:
|
|
337
|
+
username_normalized: a,
|
|
327
338
|
secrets: {
|
|
328
339
|
create: t
|
|
329
340
|
}
|
|
@@ -333,7 +344,7 @@ class G extends H {
|
|
|
333
344
|
data: {
|
|
334
345
|
...e,
|
|
335
346
|
email_normalized: n,
|
|
336
|
-
username_normalized:
|
|
347
|
+
username_normalized: a
|
|
337
348
|
}
|
|
338
349
|
});
|
|
339
350
|
} catch (c) {
|
|
@@ -402,7 +413,7 @@ class G extends H {
|
|
|
402
413
|
}
|
|
403
414
|
}
|
|
404
415
|
}
|
|
405
|
-
class
|
|
416
|
+
class kt extends L {
|
|
406
417
|
/**
|
|
407
418
|
* Constructor with user storage object to use plus optional parameters.
|
|
408
419
|
*
|
|
@@ -428,17 +439,17 @@ class vt extends z {
|
|
|
428
439
|
async getKeyWithTransaction(e, t) {
|
|
429
440
|
let r = { userid: 0, value: "", created: /* @__PURE__ */ new Date(), expires: void 0 }, i;
|
|
430
441
|
try {
|
|
431
|
-
let
|
|
442
|
+
let a = await t[this.keyTable].findUniqueOrThrow({
|
|
432
443
|
where: {
|
|
433
444
|
value: e
|
|
434
445
|
}
|
|
435
446
|
});
|
|
436
447
|
r = {
|
|
437
|
-
...
|
|
438
|
-
userid:
|
|
448
|
+
...a,
|
|
449
|
+
userid: a[this.useridForeignKeyColumn]
|
|
439
450
|
}, this.useridForeignKeyColumn != "userid" && delete r[this.useridForeignKeyColumn];
|
|
440
|
-
} catch (
|
|
441
|
-
u.logger.debug(f({ err:
|
|
451
|
+
} catch (a) {
|
|
452
|
+
u.logger.debug(f({ err: a })), i = new o(l.InvalidKey);
|
|
442
453
|
}
|
|
443
454
|
if (i)
|
|
444
455
|
throw i;
|
|
@@ -454,7 +465,7 @@ class vt extends z {
|
|
|
454
465
|
* @param extraFields these will be stored in the key table row
|
|
455
466
|
* @throws {@link @crossauth/common!CrossauthError } if the key could not be stored.
|
|
456
467
|
*/
|
|
457
|
-
async saveKey(e, t, r, i,
|
|
468
|
+
async saveKey(e, t, r, i, a, n = {}) {
|
|
458
469
|
let c;
|
|
459
470
|
try {
|
|
460
471
|
let d = {
|
|
@@ -462,7 +473,7 @@ class vt extends z {
|
|
|
462
473
|
value: t,
|
|
463
474
|
created: r,
|
|
464
475
|
expires: i ?? null,
|
|
465
|
-
data:
|
|
476
|
+
data: a,
|
|
466
477
|
...n
|
|
467
478
|
};
|
|
468
479
|
await this.prismaClient[this.keyTable].create({
|
|
@@ -525,8 +536,8 @@ class vt extends z {
|
|
|
525
536
|
}
|
|
526
537
|
})
|
|
527
538
|
);
|
|
528
|
-
} catch (
|
|
529
|
-
u.logger.debug(f({ err:
|
|
539
|
+
} catch (a) {
|
|
540
|
+
u.logger.debug(f({ err: a })), i = new o(l.Connection, "Error deleting key");
|
|
530
541
|
}
|
|
531
542
|
if (i) throw i;
|
|
532
543
|
}
|
|
@@ -578,8 +589,8 @@ class vt extends z {
|
|
|
578
589
|
where: {
|
|
579
590
|
[this.useridForeignKeyColumn]: e ?? null
|
|
580
591
|
}
|
|
581
|
-
})).map((
|
|
582
|
-
let n = { ...
|
|
592
|
+
})).map((a) => {
|
|
593
|
+
let n = { ...a, userid: a[this.useridForeignKeyColumn] };
|
|
583
594
|
return this.useridForeignKeyColumn != "userid" && delete n[this.useridForeignKeyColumn], n;
|
|
584
595
|
});
|
|
585
596
|
} catch {
|
|
@@ -628,21 +639,21 @@ class vt extends z {
|
|
|
628
639
|
try {
|
|
629
640
|
await this.prismaClient.$transaction(async (r) => {
|
|
630
641
|
const i = await this.getKeyWithTransaction(e, r);
|
|
631
|
-
let
|
|
642
|
+
let a;
|
|
632
643
|
if (!i.data || i.data == "")
|
|
633
|
-
|
|
644
|
+
a = {};
|
|
634
645
|
else
|
|
635
646
|
try {
|
|
636
|
-
|
|
647
|
+
a = JSON.parse(i.data);
|
|
637
648
|
} catch (n) {
|
|
638
649
|
throw u.logger.debug(f({ err: n })), new o(l.DataFormat);
|
|
639
650
|
}
|
|
640
651
|
for (let n of t) {
|
|
641
|
-
let c = this.updateDataInternal(
|
|
652
|
+
let c = this.updateDataInternal(a, n.dataName, n.value);
|
|
642
653
|
if (!c) throw new o(l.BadRequest, `Parents of ${n.dataName} not found in key data`);
|
|
643
|
-
|
|
654
|
+
a = c;
|
|
644
655
|
}
|
|
645
|
-
await this.updateKeyWithTransaction({ value: i.value, data: JSON.stringify(
|
|
656
|
+
await this.updateKeyWithTransaction({ value: i.value, data: JSON.stringify(a) }, r);
|
|
646
657
|
}, { timeout: this.transactionTimeout });
|
|
647
658
|
} catch (r) {
|
|
648
659
|
throw r && typeof r == "object" && !("isCrossauthError" in r) ? (u.logger.debug(f({ err: r })), new o(l.Connection, "Failed updating session data")) : r;
|
|
@@ -655,24 +666,24 @@ class vt extends z {
|
|
|
655
666
|
try {
|
|
656
667
|
let r = !1;
|
|
657
668
|
await this.prismaClient.$transaction(async (i) => {
|
|
658
|
-
let
|
|
669
|
+
let a = {};
|
|
659
670
|
const n = await this.getKeyWithTransaction(e, i);
|
|
660
671
|
if (n.data && n.data != "") {
|
|
661
672
|
try {
|
|
662
|
-
|
|
673
|
+
a = JSON.parse(n.data);
|
|
663
674
|
} catch (c) {
|
|
664
675
|
throw u.logger.debug(f({ err: c })), new o(l.DataFormat);
|
|
665
676
|
}
|
|
666
|
-
r = this.deleteDataInternal(
|
|
677
|
+
r = this.deleteDataInternal(a, t);
|
|
667
678
|
}
|
|
668
|
-
r && await this.updateKeyWithTransaction({ value: n.value, data: JSON.stringify(
|
|
679
|
+
r && await this.updateKeyWithTransaction({ value: n.value, data: JSON.stringify(a) }, i);
|
|
669
680
|
}, { timeout: this.transactionTimeout });
|
|
670
681
|
} catch (r) {
|
|
671
682
|
throw r && typeof r == "object" && !("isCrossauthError" in r) ? (u.logger.debug(f({ err: r })), new o(l.Connection, "Failed updating session data")) : r;
|
|
672
683
|
}
|
|
673
684
|
}
|
|
674
685
|
}
|
|
675
|
-
class
|
|
686
|
+
class Et extends me {
|
|
676
687
|
/**
|
|
677
688
|
* Constructor with user storage object to use plus optional parameters.
|
|
678
689
|
*
|
|
@@ -696,8 +707,8 @@ class Tt extends me {
|
|
|
696
707
|
async getClientByName(e, t) {
|
|
697
708
|
return await this.getClientWithTransaction("client_name", e, this.prismaClient, !1, t);
|
|
698
709
|
}
|
|
699
|
-
async getClientWithTransaction(e, t, r, i,
|
|
700
|
-
const n =
|
|
710
|
+
async getClientWithTransaction(e, t, r, i, a) {
|
|
711
|
+
const n = a == null && a !== null ? {} : { [this.useridForeignKeyColumn]: a };
|
|
701
712
|
try {
|
|
702
713
|
if (i) {
|
|
703
714
|
const c = await r[this.clientTable].findUniqueOrThrow({
|
|
@@ -726,7 +737,7 @@ class Tt extends me {
|
|
|
726
737
|
for (let d of c) {
|
|
727
738
|
const g = d.redirect_uri, y = d.valid_flow;
|
|
728
739
|
let p = d[this.useridForeignKeyColumn];
|
|
729
|
-
p == null && (p = void 0), d.userid = p, this.useridForeignKeyColumn != "userid" && delete d[this.useridForeignKeyColumn], d.client_secret = d.client_secret ?? void 0, d.redirect_uri = g.map((
|
|
740
|
+
p == null && (p = void 0), d.userid = p, this.useridForeignKeyColumn != "userid" && delete d[this.useridForeignKeyColumn], d.client_secret = d.client_secret ?? void 0, d.redirect_uri = g.map((_) => _.uri), d.valid_flow = y.map((_) => _.flow);
|
|
730
741
|
}
|
|
731
742
|
return c;
|
|
732
743
|
}
|
|
@@ -754,9 +765,9 @@ class Tt extends me {
|
|
|
754
765
|
}
|
|
755
766
|
}
|
|
756
767
|
async createClientWithTransaction(e, t) {
|
|
757
|
-
const { redirect_uri: r, valid_flow: i, userid:
|
|
768
|
+
const { redirect_uri: r, valid_flow: i, userid: a, ...n } = e;
|
|
758
769
|
let c;
|
|
759
|
-
if (
|
|
770
|
+
if (a && (n[this.useridForeignKeyColumn] = a), this.useridForeignKeyColumn != "userid" && delete e[this.useridForeignKeyColumn], r)
|
|
760
771
|
for (let d = 0; d < r.length; ++d) {
|
|
761
772
|
if (r[d].includes("#")) throw new o(l.InvalidRedirectUri, "Redirect Uri's may not contain page fragments");
|
|
762
773
|
try {
|
|
@@ -844,28 +855,28 @@ class Tt extends me {
|
|
|
844
855
|
if (!e.client_id) throw new o(l.InvalidClientId);
|
|
845
856
|
const r = e.redirect_uri, i = e.valid_flow;
|
|
846
857
|
if (r)
|
|
847
|
-
for (let
|
|
848
|
-
if (r[
|
|
858
|
+
for (let a = 0; a < r.length; ++a) {
|
|
859
|
+
if (r[a].includes("#")) throw new o(l.InvalidRedirectUri, "Redirect Uri's may not contain page fragments");
|
|
849
860
|
try {
|
|
850
|
-
new URL(r[
|
|
861
|
+
new URL(r[a]);
|
|
851
862
|
} catch {
|
|
852
|
-
throw new o(l.InvalidRedirectUri, `Redriect uri ${r[
|
|
863
|
+
throw new o(l.InvalidRedirectUri, `Redriect uri ${r[a]} is not valid`);
|
|
853
864
|
}
|
|
854
865
|
}
|
|
855
866
|
if (i) {
|
|
856
|
-
for (let
|
|
857
|
-
if (!b.isValidFlow(i[
|
|
867
|
+
for (let a = 0; a < i.length; ++a)
|
|
868
|
+
if (!b.isValidFlow(i[a])) throw new o(l.InvalidOAuthFlow, "Redirect Uri's may not contain page fragments");
|
|
858
869
|
}
|
|
859
870
|
try {
|
|
860
|
-
let
|
|
861
|
-
delete
|
|
871
|
+
let a = { ...e };
|
|
872
|
+
delete a.client_id, delete a.redirect_uri, delete a.valid_flow, "userid" in a && this.useridForeignKeyColumn != "userid" && (a[this.useridForeignKeyColumn] = a.userid, delete a.userid), Object.keys(a).length > 0 && await t[this.clientTable].update({
|
|
862
873
|
where: {
|
|
863
874
|
client_id: e.client_id
|
|
864
875
|
},
|
|
865
|
-
data:
|
|
876
|
+
data: a
|
|
866
877
|
});
|
|
867
|
-
} catch (
|
|
868
|
-
throw u.logger.debug(f({ err:
|
|
878
|
+
} catch (a) {
|
|
879
|
+
throw u.logger.debug(f({ err: a })), new o(l.Connection, "Error updating client");
|
|
869
880
|
}
|
|
870
881
|
if (r != null)
|
|
871
882
|
try {
|
|
@@ -874,15 +885,15 @@ class Tt extends me {
|
|
|
874
885
|
client_id: e.client_id
|
|
875
886
|
}
|
|
876
887
|
});
|
|
877
|
-
for (let
|
|
888
|
+
for (let a = 0; a < r.length; ++a)
|
|
878
889
|
await t[this.redirectUriTable].create({
|
|
879
890
|
data: {
|
|
880
891
|
client_id: e.client_id,
|
|
881
|
-
uri: r[
|
|
892
|
+
uri: r[a]
|
|
882
893
|
}
|
|
883
894
|
});
|
|
884
|
-
} catch (
|
|
885
|
-
throw
|
|
895
|
+
} catch (a) {
|
|
896
|
+
throw a instanceof X.PrismaClientKnownRequestError || a instanceof Object && "code" in a ? a.code == "P2002" ? (u.logger.debug(f({ err: a })), new o(l.KeyExists, "Attempt to update an OAuth client with a redirect Uri that already belongs to another client")) : (u.logger.debug(f({ err: a })), new o(l.Connection, "Error updating client")) : (u.logger.debug(f({ err: a })), new o(l.Connection, "Error updating client"));
|
|
886
897
|
}
|
|
887
898
|
if (i != null)
|
|
888
899
|
try {
|
|
@@ -891,15 +902,15 @@ class Tt extends me {
|
|
|
891
902
|
client_id: e.client_id
|
|
892
903
|
}
|
|
893
904
|
});
|
|
894
|
-
for (let
|
|
905
|
+
for (let a = 0; a < i.length; ++a)
|
|
895
906
|
await t[this.validFlowTable].create({
|
|
896
907
|
data: {
|
|
897
908
|
client_id: e.client_id,
|
|
898
|
-
flow: i[
|
|
909
|
+
flow: i[a]
|
|
899
910
|
}
|
|
900
911
|
});
|
|
901
|
-
} catch (
|
|
902
|
-
throw
|
|
912
|
+
} catch (a) {
|
|
913
|
+
throw a instanceof X.PrismaClientKnownRequestError || a instanceof Object && "code" in a ? (u.logger.debug(f({ err: a })), new o(l.Connection, "Error updating client")) : (u.logger.debug(f({ err: a })), new o(l.Connection, "Error updating client"));
|
|
903
914
|
}
|
|
904
915
|
}
|
|
905
916
|
async updateClientWithTransaction_deleteAndInsert(e, t) {
|
|
@@ -911,8 +922,8 @@ class Tt extends me {
|
|
|
911
922
|
let i = {};
|
|
912
923
|
e && (i.skip = e), t && (i.take = t);
|
|
913
924
|
try {
|
|
914
|
-
let
|
|
915
|
-
return r || r === null ?
|
|
925
|
+
let a = [];
|
|
926
|
+
return r || r === null ? a = await this.prismaClient[this.clientTable].findMany({
|
|
916
927
|
...i,
|
|
917
928
|
where: {
|
|
918
929
|
[this.useridForeignKeyColumn]: r
|
|
@@ -922,20 +933,20 @@ class Tt extends me {
|
|
|
922
933
|
client_name: "asc"
|
|
923
934
|
}
|
|
924
935
|
]
|
|
925
|
-
}) :
|
|
936
|
+
}) : a = await this.prismaClient[this.clientTable].findMany({
|
|
926
937
|
...i,
|
|
927
938
|
orderBy: [
|
|
928
939
|
{
|
|
929
940
|
client_name: "asc"
|
|
930
941
|
}
|
|
931
942
|
]
|
|
932
|
-
}),
|
|
933
|
-
} catch (
|
|
934
|
-
throw u.logger.error(f({ err:
|
|
943
|
+
}), a.forEach((n) => (this.useridForeignKeyColumn != "userid" && (n.userid = n[this.useridForeignKeyColumn], delete n[this.useridForeignKeyColumn]), n.userid = n.userid === null ? void 0 : n.userid, n)), a;
|
|
944
|
+
} catch (a) {
|
|
945
|
+
throw u.logger.error(f({ err: a })), new o(l.Connection, "Couldn't select from client table");
|
|
935
946
|
}
|
|
936
947
|
}
|
|
937
948
|
}
|
|
938
|
-
class
|
|
949
|
+
class bt extends we {
|
|
939
950
|
/**
|
|
940
951
|
* Constructor with user storage object to use plus optional parameters.
|
|
941
952
|
*
|
|
@@ -985,22 +996,22 @@ class kt extends we {
|
|
|
985
996
|
[this.useridForeignKeyColumn]: t ?? null
|
|
986
997
|
}
|
|
987
998
|
});
|
|
988
|
-
const
|
|
999
|
+
const a = [];
|
|
989
1000
|
r.forEach((n) => {
|
|
990
|
-
|
|
1001
|
+
a.push(i[this.authorizationTable].create({
|
|
991
1002
|
data: {
|
|
992
1003
|
client_id: e,
|
|
993
1004
|
[this.useridForeignKeyColumn]: t ?? null,
|
|
994
1005
|
scope: n
|
|
995
1006
|
}
|
|
996
1007
|
}));
|
|
997
|
-
}), await Promise.all(
|
|
998
|
-
} catch (
|
|
999
|
-
throw u.logger.debug(f({ err:
|
|
1008
|
+
}), await Promise.all(a);
|
|
1009
|
+
} catch (a) {
|
|
1010
|
+
throw u.logger.debug(f({ err: a })), new o(l.Connection, "Error updating OAuth authorizations");
|
|
1000
1011
|
}
|
|
1001
1012
|
}
|
|
1002
1013
|
}
|
|
1003
|
-
class
|
|
1014
|
+
class Ut extends H {
|
|
1004
1015
|
/**
|
|
1005
1016
|
* Creates a InMemoryUserStorage object, optionally overriding defaults.
|
|
1006
1017
|
* @param options see {@link InMemoryUserStorageOptions}
|
|
@@ -1049,8 +1060,8 @@ class _t extends H {
|
|
|
1049
1060
|
throw u.logger.debug(f({ msg: "User email not verified" })), new o(l.EmailNotVerified);
|
|
1050
1061
|
if ((t == null ? void 0 : t.skipActiveCheck) != !0 && i.state == E.disabled)
|
|
1051
1062
|
throw u.logger.debug(f({ msg: "User is deactivated" })), new o(l.UserNotActive);
|
|
1052
|
-
const
|
|
1053
|
-
return { user: { ...i }, secrets: { userid: i.id, ...
|
|
1063
|
+
const a = this.secretsByUsername[r];
|
|
1064
|
+
return { user: { ...i }, secrets: { userid: i.id, ...a } };
|
|
1054
1065
|
}
|
|
1055
1066
|
throw u.logger.debug(f({ msg: "User does not exist" })), new o(l.UserNotExist);
|
|
1056
1067
|
}
|
|
@@ -1070,8 +1081,8 @@ class _t extends H {
|
|
|
1070
1081
|
throw u.logger.debug(f({ msg: "User email not verified" })), new o(l.EmailNotVerified);
|
|
1071
1082
|
if ((t == null ? void 0 : t.skipActiveCheck) != !0 && i.state != "active")
|
|
1072
1083
|
throw u.logger.debug(f({ msg: "User is deactivated" })), new o(l.UserNotActive);
|
|
1073
|
-
const
|
|
1074
|
-
return { user: { ...i }, secrets: { userid: i.id, ...
|
|
1084
|
+
const a = this.secretsByEmail[r];
|
|
1085
|
+
return { user: { ...i }, secrets: { userid: i.id, ...a } };
|
|
1075
1086
|
}
|
|
1076
1087
|
throw u.logger.debug(f({ msg: "User does not exist" })), new o(l.UserNotExist);
|
|
1077
1088
|
}
|
|
@@ -1089,6 +1100,16 @@ class _t extends H {
|
|
|
1089
1100
|
this.getUserByUsername(e, t)
|
|
1090
1101
|
);
|
|
1091
1102
|
}
|
|
1103
|
+
/**
|
|
1104
|
+
* Returns a {@link User } and {@link UserSecrets } instance matching the given email address, or throws an Exception.
|
|
1105
|
+
*
|
|
1106
|
+
* @param email the emaila ddress to look up
|
|
1107
|
+
* @returns a {@link User } and {@link UserSecrets } instance, ie including the password hash.
|
|
1108
|
+
* @throws {@link @crossauth/common!CrossauthError } with {@link @crossauth/common!ErrorCode } set to either `UserNotExist`.
|
|
1109
|
+
*/
|
|
1110
|
+
async getUserBy(e, t, r) {
|
|
1111
|
+
throw new o(l.NotImplemented);
|
|
1112
|
+
}
|
|
1092
1113
|
/**
|
|
1093
1114
|
* If the given session key exist in the database, update it with the passed values. If it doesn't
|
|
1094
1115
|
* exist, throw a CreossauthError with InvalidKey.
|
|
@@ -1129,14 +1150,14 @@ class _t extends H {
|
|
|
1129
1150
|
const r = Object.keys(this.usersByUsername).sort();
|
|
1130
1151
|
let i = [];
|
|
1131
1152
|
e || (e = 0);
|
|
1132
|
-
let
|
|
1133
|
-
|
|
1134
|
-
for (let n = e; n <
|
|
1153
|
+
let a = t || r.length;
|
|
1154
|
+
a >= r.length - e && (a = r.length - e);
|
|
1155
|
+
for (let n = e; n < a; ++n)
|
|
1135
1156
|
i.push(this.usersByUsername[r[n]]);
|
|
1136
1157
|
return i;
|
|
1137
1158
|
}
|
|
1138
1159
|
}
|
|
1139
|
-
class
|
|
1160
|
+
class At extends L {
|
|
1140
1161
|
/**
|
|
1141
1162
|
* Constructor
|
|
1142
1163
|
*/
|
|
@@ -1168,13 +1189,13 @@ class Et extends z {
|
|
|
1168
1189
|
* @param expires the date/time the key expires.
|
|
1169
1190
|
* @param extraFields these will also be stored in the key table row
|
|
1170
1191
|
*/
|
|
1171
|
-
async saveKey(e, t, r, i,
|
|
1192
|
+
async saveKey(e, t, r, i, a, n) {
|
|
1172
1193
|
const c = {
|
|
1173
1194
|
value: t,
|
|
1174
1195
|
userid: e,
|
|
1175
1196
|
created: r,
|
|
1176
1197
|
expires: i,
|
|
1177
|
-
data:
|
|
1198
|
+
data: a,
|
|
1178
1199
|
...n
|
|
1179
1200
|
};
|
|
1180
1201
|
this.keys[t] = c, e ? e in this.keysByUserId ? this.keysByUserId[e].push(c) : this.keysByUserId[e] = [c] : this.nonUserKeys.push(c);
|
|
@@ -1206,8 +1227,8 @@ class Et extends z {
|
|
|
1206
1227
|
for (let t in this.keys) {
|
|
1207
1228
|
let r = !0;
|
|
1208
1229
|
const i = this.keys[t];
|
|
1209
|
-
for (let
|
|
1210
|
-
if (
|
|
1230
|
+
for (let a in e)
|
|
1231
|
+
if (a in i && i[a] != e[a]) {
|
|
1211
1232
|
r = !1;
|
|
1212
1233
|
break;
|
|
1213
1234
|
}
|
|
@@ -1216,21 +1237,21 @@ class Et extends z {
|
|
|
1216
1237
|
for (let t in this.keysByUserId) {
|
|
1217
1238
|
const r = this.keysByUserId[t];
|
|
1218
1239
|
for (let i = 0; i < r.length; ++i) {
|
|
1219
|
-
let
|
|
1240
|
+
let a = !0, n = 0;
|
|
1220
1241
|
const c = r[i];
|
|
1221
1242
|
for (let d in e)
|
|
1222
1243
|
if (d in c && c[d] != e[d]) {
|
|
1223
|
-
|
|
1244
|
+
a = !1, n = i;
|
|
1224
1245
|
break;
|
|
1225
1246
|
}
|
|
1226
|
-
|
|
1247
|
+
a && (this.keysByUserId[t] = this.keysByUserId[t].splice(n, 1));
|
|
1227
1248
|
}
|
|
1228
1249
|
}
|
|
1229
1250
|
for (let t = 0; t < this.nonUserKeys.length; ++t) {
|
|
1230
1251
|
let r = !0, i = 0;
|
|
1231
|
-
const
|
|
1252
|
+
const a = this.nonUserKeys[t];
|
|
1232
1253
|
for (let n in e)
|
|
1233
|
-
if (n in
|
|
1254
|
+
if (n in a && a[n] != e[n]) {
|
|
1234
1255
|
r = !1, i = t;
|
|
1235
1256
|
break;
|
|
1236
1257
|
}
|
|
@@ -1266,12 +1287,12 @@ class Et extends z {
|
|
|
1266
1287
|
else
|
|
1267
1288
|
try {
|
|
1268
1289
|
i = JSON.parse(r.data);
|
|
1269
|
-
} catch (
|
|
1270
|
-
throw u.logger.debug(f({ err:
|
|
1290
|
+
} catch (a) {
|
|
1291
|
+
throw u.logger.debug(f({ err: a })), new o(l.DataFormat);
|
|
1271
1292
|
}
|
|
1272
|
-
for (let
|
|
1273
|
-
if (this.updateDataInternal(i,
|
|
1274
|
-
else throw new o(l.BadRequest, `parents of ${
|
|
1293
|
+
for (let a of t)
|
|
1294
|
+
if (this.updateDataInternal(i, a.dataName, a.value)) r.data = JSON.stringify(i);
|
|
1295
|
+
else throw new o(l.BadRequest, `parents of ${a.dataName} not found in key data`);
|
|
1275
1296
|
}
|
|
1276
1297
|
/**
|
|
1277
1298
|
* See {@link KeyStorage}.
|
|
@@ -1289,7 +1310,7 @@ class Et extends z {
|
|
|
1289
1310
|
this.deleteDataInternal(i, t) && (r.data = JSON.stringify(i));
|
|
1290
1311
|
}
|
|
1291
1312
|
}
|
|
1292
|
-
class
|
|
1313
|
+
class It extends me {
|
|
1293
1314
|
/**
|
|
1294
1315
|
* Constructor
|
|
1295
1316
|
*/
|
|
@@ -1322,8 +1343,8 @@ class bt extends me {
|
|
|
1322
1343
|
const r = this.clientsByName[e];
|
|
1323
1344
|
if (t == null && t !== null) return r;
|
|
1324
1345
|
const i = [];
|
|
1325
|
-
for (let
|
|
1326
|
-
|
|
1346
|
+
for (let a of r)
|
|
1347
|
+
a.userid === t && i.push(a);
|
|
1327
1348
|
return i;
|
|
1328
1349
|
}
|
|
1329
1350
|
return [];
|
|
@@ -1371,16 +1392,16 @@ class bt extends me {
|
|
|
1371
1392
|
}
|
|
1372
1393
|
async getClients(e, t, r) {
|
|
1373
1394
|
const i = Object.keys(this.clients).sort();
|
|
1374
|
-
let
|
|
1395
|
+
let a = [];
|
|
1375
1396
|
e || (e = 0);
|
|
1376
1397
|
let n = t || i.length;
|
|
1377
1398
|
n >= i.length - e && (n = i.length - e);
|
|
1378
1399
|
for (let c = e; c < n; ++c)
|
|
1379
|
-
r === null ? this.clients[i[c]].userid == null &&
|
|
1380
|
-
return
|
|
1400
|
+
r === null ? this.clients[i[c]].userid == null && a.push(this.clients[i[c]]) : r != null && r !== null ? this.clients[i[c]].userid == r && a.push(this.clients[i[c]]) : a.push(this.clients[i[c]]);
|
|
1401
|
+
return a;
|
|
1381
1402
|
}
|
|
1382
1403
|
}
|
|
1383
|
-
class
|
|
1404
|
+
class Pt extends we {
|
|
1384
1405
|
/**
|
|
1385
1406
|
* Constructor
|
|
1386
1407
|
*/
|
|
@@ -1415,8 +1436,8 @@ class Ut extends we {
|
|
|
1415
1436
|
this.byClient[e] = [...r];
|
|
1416
1437
|
}
|
|
1417
1438
|
}
|
|
1418
|
-
function $e(
|
|
1419
|
-
return { username: Array.isArray(
|
|
1439
|
+
function $e(S, s) {
|
|
1440
|
+
return { username: Array.isArray(s.uid) ? s.uid[0] : s.uid, state: "active", ...S };
|
|
1420
1441
|
}
|
|
1421
1442
|
class oe extends H {
|
|
1422
1443
|
/**
|
|
@@ -1474,7 +1495,18 @@ class oe extends H {
|
|
|
1474
1495
|
* @throws {@link @crossauth/common!CrossauthError} with {@link @crossauth/common!ErrorCode} `UsernameOrPasswordInvalid` or `Connection`
|
|
1475
1496
|
*/
|
|
1476
1497
|
async getUserByEmail(e, t) {
|
|
1477
|
-
return await this.getUserByEmail(e, t);
|
|
1498
|
+
return await this.localStorage.getUserByEmail(e, t);
|
|
1499
|
+
}
|
|
1500
|
+
/**
|
|
1501
|
+
* Returns user matching the given field, or throws an exception.
|
|
1502
|
+
*
|
|
1503
|
+
* @param field the field to match
|
|
1504
|
+
* @param value the value to match (case sensitive)
|
|
1505
|
+
* @param options optionally turn off checks. Used internally
|
|
1506
|
+
* @throws CrossauthException with ErrorCode either `UserNotExist` or whatever pg throws
|
|
1507
|
+
*/
|
|
1508
|
+
async getUserBy(e, t, r) {
|
|
1509
|
+
return await this.localStorage.getUserBy(e, t, r);
|
|
1478
1510
|
}
|
|
1479
1511
|
async getUsers(e, t) {
|
|
1480
1512
|
return await this.localStorage.getUsers(e, t);
|
|
@@ -1514,35 +1546,35 @@ class oe extends H {
|
|
|
1514
1546
|
async getLdapUser(e, t) {
|
|
1515
1547
|
let r;
|
|
1516
1548
|
try {
|
|
1517
|
-
const i = oe.sanitizeLdapDnForSerach(e),
|
|
1549
|
+
const i = oe.sanitizeLdapDnForSerach(e), a = [this.ldapUsernameAttribute + "=" + i, this.ldapUserSearchBase].join(",");
|
|
1518
1550
|
if (!t) throw new o(l.PasswordInvalid);
|
|
1519
|
-
return u.logger.debug(f({ msg: "LDAP search " +
|
|
1551
|
+
return u.logger.debug(f({ msg: "LDAP search " + a })), r = await this.ldapBind(a, t), await this.searchUser(r, a);
|
|
1520
1552
|
} catch (i) {
|
|
1521
1553
|
u.logger.debug(f({ err: i }));
|
|
1522
|
-
const
|
|
1523
|
-
throw i instanceof ye.InvalidCredentialsError ? new o(l.UsernameOrPasswordInvalid) :
|
|
1554
|
+
const a = o.asCrossauthError(i);
|
|
1555
|
+
throw i instanceof ye.InvalidCredentialsError ? new o(l.UsernameOrPasswordInvalid) : a.code != l.UnknownError ? a : new o(l.Connection, "LDAP error getting user");
|
|
1524
1556
|
}
|
|
1525
1557
|
}
|
|
1526
1558
|
// bind and return the ldap client
|
|
1527
1559
|
// from https://github.com/shaozi/ldap-authentication/blob/master/index.js
|
|
1528
1560
|
ldapBind(e, t) {
|
|
1529
1561
|
return new Promise((r, i) => {
|
|
1530
|
-
let
|
|
1531
|
-
|
|
1532
|
-
|
|
1562
|
+
let a = ye.createClient({ url: this.ldapUrls });
|
|
1563
|
+
a.on("connect", function() {
|
|
1564
|
+
a.bind(e, t, function(n) {
|
|
1533
1565
|
if (n) {
|
|
1534
|
-
i(n),
|
|
1566
|
+
i(n), a.unbind();
|
|
1535
1567
|
return;
|
|
1536
1568
|
}
|
|
1537
|
-
r(
|
|
1569
|
+
r(a);
|
|
1538
1570
|
});
|
|
1539
|
-
}),
|
|
1571
|
+
}), a.on("timeout", (n) => {
|
|
1540
1572
|
i(n);
|
|
1541
|
-
}),
|
|
1573
|
+
}), a.on("connectTimeout", (n) => {
|
|
1542
1574
|
i(n);
|
|
1543
|
-
}),
|
|
1575
|
+
}), a.on("error", (n) => {
|
|
1544
1576
|
i(n);
|
|
1545
|
-
}),
|
|
1577
|
+
}), a.on("connectError", function(n) {
|
|
1546
1578
|
if (n) {
|
|
1547
1579
|
i(n);
|
|
1548
1580
|
return;
|
|
@@ -1551,7 +1583,7 @@ class oe extends H {
|
|
|
1551
1583
|
});
|
|
1552
1584
|
}
|
|
1553
1585
|
async searchUser(e, t, r) {
|
|
1554
|
-
return new Promise(function(i,
|
|
1586
|
+
return new Promise(function(i, a) {
|
|
1555
1587
|
let n = {
|
|
1556
1588
|
scope: "base"
|
|
1557
1589
|
};
|
|
@@ -1561,15 +1593,15 @@ class oe extends H {
|
|
|
1561
1593
|
function(c, d) {
|
|
1562
1594
|
let g;
|
|
1563
1595
|
if (c) {
|
|
1564
|
-
|
|
1596
|
+
a(c), e.unbind();
|
|
1565
1597
|
return;
|
|
1566
1598
|
}
|
|
1567
1599
|
d.on("searchEntry", function(y) {
|
|
1568
1600
|
g = oe.searchResultToUser(y.pojo);
|
|
1569
1601
|
}), d.on("error", function(y) {
|
|
1570
|
-
|
|
1602
|
+
a(y), e.unbind();
|
|
1571
1603
|
}), d.on("end", function(y) {
|
|
1572
|
-
y.status != 0 ?
|
|
1604
|
+
y.status != 0 ? a(new o(l.Connection, "LDAP onnection failed")) : g ? i(g) : a(new o(l.UsernameOrPasswordInvalid)), e.unbind();
|
|
1573
1605
|
});
|
|
1574
1606
|
}
|
|
1575
1607
|
);
|
|
@@ -1649,42 +1681,53 @@ class Y extends H {
|
|
|
1649
1681
|
const r = this.normalizeEmail ? Y.normalize(e) : e;
|
|
1650
1682
|
return this.getUser("email_normalized", r, t);
|
|
1651
1683
|
}
|
|
1684
|
+
/**
|
|
1685
|
+
* Returns user matching the given field, or throws an exception.
|
|
1686
|
+
*
|
|
1687
|
+
* @param field the field to match
|
|
1688
|
+
* @param value the value to match (case sensitive)
|
|
1689
|
+
* @param options optionally turn off checks. Used internally
|
|
1690
|
+
* @throws CrossauthException with ErrorCode either `UserNotExist` or whatever pg throws
|
|
1691
|
+
*/
|
|
1692
|
+
async getUserBy(e, t, r) {
|
|
1693
|
+
return await this.getUser(e, t, r);
|
|
1694
|
+
}
|
|
1652
1695
|
async getUser(e, t, r) {
|
|
1653
|
-
let i = await this.dbPool.connect(),
|
|
1696
|
+
let i = await this.dbPool.connect(), a, n, c = this.dbPool.parameters();
|
|
1654
1697
|
try {
|
|
1655
1698
|
await i.startTransaction();
|
|
1656
1699
|
let d = `select * from ${this.userTable} where ${e} = ` + c.nextParameter(), g = await i.execute(d, [t]);
|
|
1657
1700
|
if (g.length == 0)
|
|
1658
1701
|
throw new o(l.UserNotExist);
|
|
1659
|
-
let y, p,
|
|
1702
|
+
let y, p, _;
|
|
1660
1703
|
if (this.idColumn in g[0]) y = g[0][this.idColumn];
|
|
1661
1704
|
else throw new o(l.Configuration, "ID column " + this.idColumn + " not present in user table");
|
|
1662
1705
|
if ("username" in g[0]) p = g[0].username;
|
|
1663
1706
|
else throw new o(l.Configuration, "username column " + this.idColumn + " not present in user table");
|
|
1664
|
-
if ("state" in g[0])
|
|
1707
|
+
if ("state" in g[0]) _ = g[0].state;
|
|
1665
1708
|
else throw new o(l.Configuration, "state column " + this.idColumn + " not present in user table");
|
|
1666
|
-
if (
|
|
1709
|
+
if (a = {
|
|
1667
1710
|
...g[0],
|
|
1668
1711
|
id: y,
|
|
1669
1712
|
username: p,
|
|
1670
|
-
state:
|
|
1671
|
-
}, !
|
|
1672
|
-
if (c = this.dbPool.parameters(), d = `select * from ${this.userSecretsTable} where ${this.useridForeignKeyColumn} = ` + c.nextParameter(), g = await i.execute(d, [
|
|
1713
|
+
state: _
|
|
1714
|
+
}, !a) throw new o(l.UserNotExist);
|
|
1715
|
+
if (c = this.dbPool.parameters(), d = `select * from ${this.userSecretsTable} where ${this.useridForeignKeyColumn} = ` + c.nextParameter(), g = await i.execute(d, [a.id]), g.length == 0)
|
|
1673
1716
|
throw new o(l.UserNotExist);
|
|
1674
|
-
if (g.length > 0 ? n = { userid:
|
|
1675
|
-
if (this.useridForeignKeyColumn != "userid" && this.useridForeignKeyColumn in n && delete n[this.useridForeignKeyColumn], await i.commit(), (r == null ? void 0 : r.skipActiveCheck) != !0 &&
|
|
1717
|
+
if (g.length > 0 ? n = { userid: a.id, ...g[0] } : n = { userid: a.id }, !n) throw new o(l.UserNotExist);
|
|
1718
|
+
if (this.useridForeignKeyColumn != "userid" && this.useridForeignKeyColumn in n && delete n[this.useridForeignKeyColumn], await i.commit(), (r == null ? void 0 : r.skipActiveCheck) != !0 && a.state == E.awaitingTwoFactorSetup)
|
|
1676
1719
|
throw u.logger.debug(f({ msg: "2FA setup is not complete" })), new o(l.TwoFactorIncomplete);
|
|
1677
|
-
if ((r == null ? void 0 : r.skipActiveCheck) != !0 &&
|
|
1720
|
+
if ((r == null ? void 0 : r.skipActiveCheck) != !0 && a.state == E.disabled)
|
|
1678
1721
|
throw u.logger.debug(f({ msg: "User is deactivated" })), new o(l.UserNotActive);
|
|
1679
|
-
if ((r == null ? void 0 : r.skipEmailVerifiedCheck) != !0 &&
|
|
1722
|
+
if ((r == null ? void 0 : r.skipEmailVerifiedCheck) != !0 && a.state == E.awaitingEmailVerification)
|
|
1680
1723
|
throw u.logger.debug(f({ msg: "User has not verified email" })), new o(l.EmailNotVerified);
|
|
1681
|
-
if ((r == null ? void 0 : r.skipActiveCheck) != !0 &&
|
|
1724
|
+
if ((r == null ? void 0 : r.skipActiveCheck) != !0 && a.state == E.passwordChangeNeeded)
|
|
1682
1725
|
throw u.logger.debug(f({ msg: "User must change password" })), new o(l.PasswordChangeNeeded);
|
|
1683
|
-
if ((r == null ? void 0 : r.skipActiveCheck) != !0 && (
|
|
1726
|
+
if ((r == null ? void 0 : r.skipActiveCheck) != !0 && (a.state == E.passwordResetNeeded || a.state == E.passwordAndFactor2ResetNeeded))
|
|
1684
1727
|
throw u.logger.debug(f({ msg: "User must reset password" })), new o(l.PasswordResetNeeded);
|
|
1685
|
-
if ((r == null ? void 0 : r.skipActiveCheck) != !0 &&
|
|
1728
|
+
if ((r == null ? void 0 : r.skipActiveCheck) != !0 && a.state == E.factor2ResetNeeded)
|
|
1686
1729
|
throw u.logger.debug(f({ msg: "2FA reset required" })), new o(l.Factor2ResetNeeded);
|
|
1687
|
-
return { user:
|
|
1730
|
+
return { user: a, secrets: n };
|
|
1688
1731
|
} catch (d) {
|
|
1689
1732
|
throw await i.rollback(), d;
|
|
1690
1733
|
} finally {
|
|
@@ -1699,27 +1742,27 @@ class Y extends H {
|
|
|
1699
1742
|
*/
|
|
1700
1743
|
async getUsers(e, t) {
|
|
1701
1744
|
const r = await this.dbPool.connect();
|
|
1702
|
-
let i = [],
|
|
1703
|
-
e && (c = "OFFSET " + d.nextParameter()), t && (
|
|
1745
|
+
let i = [], a = [], n = "", c = "", d = this.dbPool.parameters();
|
|
1746
|
+
e && (c = "OFFSET " + d.nextParameter()), t && (a.push(t), n = "LIMIT " + d.nextParameter());
|
|
1704
1747
|
try {
|
|
1705
|
-
let g = `select * from ${this.userTable} ${n} ${c} order by username_normalized asc`, y = await r.execute(g,
|
|
1748
|
+
let g = `select * from ${this.userTable} ${n} ${c} order by username_normalized asc`, y = await r.execute(g, a);
|
|
1706
1749
|
if (y.length == 0)
|
|
1707
1750
|
throw new o(l.UserNotExist);
|
|
1708
1751
|
for (let p of y) {
|
|
1709
|
-
let
|
|
1710
|
-
if (this.idColumn in p)
|
|
1752
|
+
let _, C, v;
|
|
1753
|
+
if (this.idColumn in p) _ = p[this.idColumn];
|
|
1711
1754
|
else throw new o(l.Configuration, "ID column " + this.idColumn + " not present in user table");
|
|
1712
|
-
if ("username" in p)
|
|
1755
|
+
if ("username" in p) C = p.username;
|
|
1713
1756
|
else throw new o(l.Configuration, "username column " + this.idColumn + " not present in user table");
|
|
1714
1757
|
if ("state" in p) v = p.state;
|
|
1715
1758
|
else throw new o(l.Configuration, "state column " + this.idColumn + " not present in user table");
|
|
1716
|
-
let
|
|
1759
|
+
let k = {
|
|
1717
1760
|
...p,
|
|
1718
|
-
id:
|
|
1719
|
-
username:
|
|
1761
|
+
id: _,
|
|
1762
|
+
username: C,
|
|
1720
1763
|
state: v
|
|
1721
1764
|
};
|
|
1722
|
-
i.push(
|
|
1765
|
+
i.push(k);
|
|
1723
1766
|
}
|
|
1724
1767
|
return i;
|
|
1725
1768
|
} catch (g) {
|
|
@@ -1743,8 +1786,8 @@ class Y extends H {
|
|
|
1743
1786
|
const r = await this.dbPool.connect();
|
|
1744
1787
|
try {
|
|
1745
1788
|
await r.startTransaction();
|
|
1746
|
-
let i = this.dbPool.parameters(),
|
|
1747
|
-
if ((await r.execute(
|
|
1789
|
+
let i = this.dbPool.parameters(), a = `select * from ${this.userTable} where ${this.idColumn} = ` + i.nextParameter();
|
|
1790
|
+
if ((await r.execute(a, [e.id])).length == 0)
|
|
1748
1791
|
throw new o(l.UserNotExist);
|
|
1749
1792
|
let c = { ...e }, d = t ? { ...t } : void 0;
|
|
1750
1793
|
"email" in c && c.email && (c = { email_normalized: this.normalizeEmail ? Y.normalize(c.email) : c.email, ...c }), "username" in c && c.username && (c = { username_normalized: this.normalizeUsername ? Y.normalize(c.username) : c.username, ...c }), i = this.dbPool.parameters();
|
|
@@ -1754,8 +1797,8 @@ class Y extends H {
|
|
|
1754
1797
|
if (g.length > 0) {
|
|
1755
1798
|
let p = g.join(", ");
|
|
1756
1799
|
y.push(e.id);
|
|
1757
|
-
let
|
|
1758
|
-
await r.execute(
|
|
1800
|
+
let _ = `update ${this.userTable} set ${p} where ${this.idColumn} = ` + i.nextParameter();
|
|
1801
|
+
await r.execute(_, y);
|
|
1759
1802
|
}
|
|
1760
1803
|
if (t) {
|
|
1761
1804
|
g = [], y = [], i = this.dbPool.parameters();
|
|
@@ -1764,8 +1807,8 @@ class Y extends H {
|
|
|
1764
1807
|
if (g.length > 0) {
|
|
1765
1808
|
let p = g.join(", ");
|
|
1766
1809
|
y.push(e.id);
|
|
1767
|
-
let
|
|
1768
|
-
await r.execute(
|
|
1810
|
+
let _ = `update ${this.userSecretsTable} set ${p} where userid = ` + i.nextParameter();
|
|
1811
|
+
await r.execute(_, y);
|
|
1769
1812
|
}
|
|
1770
1813
|
}
|
|
1771
1814
|
await r.commit();
|
|
@@ -1791,35 +1834,35 @@ class Y extends H {
|
|
|
1791
1834
|
let i;
|
|
1792
1835
|
try {
|
|
1793
1836
|
await r.startTransaction();
|
|
1794
|
-
let
|
|
1795
|
-
"email" in
|
|
1837
|
+
let a = { ...e }, n = t ? { ...t } : void 0;
|
|
1838
|
+
"email" in a && a.email && (a = { email_normalized: this.normalizeEmail ? Y.normalize(a.email) : a.email, ...a }), "username" in a && a.username && (a = { username_normalized: this.normalizeUsername ? Y.normalize(a.username) : a.username, ...a });
|
|
1796
1839
|
let c = [], d = [], g = [];
|
|
1797
1840
|
const y = this.dbPool.parameters();
|
|
1798
|
-
for (let
|
|
1799
|
-
|
|
1841
|
+
for (let _ in a)
|
|
1842
|
+
a[_] != null && _ != "id" && (c.push(_), d.push(y.nextParameter()), g.push(a[_]));
|
|
1800
1843
|
if (c.length > 0) {
|
|
1801
|
-
let
|
|
1802
|
-
const v = `insert into ${this.userTable} (${
|
|
1803
|
-
if (
|
|
1804
|
-
i =
|
|
1844
|
+
let _ = c.join(", "), C = d.join(", ");
|
|
1845
|
+
const v = `insert into ${this.userTable} (${_}) values (${C}) returning ${this.idColumn}`, k = await r.execute(v, g);
|
|
1846
|
+
if (k.length == 0 || !k[0][this.idColumn]) throw new o(l.Connection, "Couldn't create user");
|
|
1847
|
+
i = k[0][this.idColumn];
|
|
1805
1848
|
}
|
|
1806
1849
|
if (!i) throw new o(l.Connection, "Couldn't create user");
|
|
1807
1850
|
if (t) {
|
|
1808
1851
|
c = [], d = [], g = [];
|
|
1809
|
-
const
|
|
1810
|
-
c.push("userid"), d.push(
|
|
1811
|
-
for (let
|
|
1812
|
-
n[
|
|
1852
|
+
const _ = this.dbPool.parameters();
|
|
1853
|
+
c.push("userid"), d.push(_.nextParameter()), g.push(i);
|
|
1854
|
+
for (let C in n)
|
|
1855
|
+
n[C] != null && C != "userid" && (c.push(C), d.push(_.nextParameter()), g.push(n[C]));
|
|
1813
1856
|
if (c.length > 0) {
|
|
1814
|
-
let
|
|
1815
|
-
const
|
|
1816
|
-
u.logger.debug(f({ msg: "Executing query", query:
|
|
1857
|
+
let C = c.join(", "), v = d.join(", ");
|
|
1858
|
+
const k = `insert into ${this.userSecretsTable} (${C}) values (${v})`;
|
|
1859
|
+
u.logger.debug(f({ msg: "Executing query", query: k })), await r.execute(k, g);
|
|
1817
1860
|
}
|
|
1818
1861
|
}
|
|
1819
1862
|
return await r.commit(), (await this.getUserById(i)).user;
|
|
1820
|
-
} catch (
|
|
1863
|
+
} catch (a) {
|
|
1821
1864
|
await r.rollback();
|
|
1822
|
-
const n = o.asCrossauthError(
|
|
1865
|
+
const n = o.asCrossauthError(a);
|
|
1823
1866
|
throw u.logger.debug(f({ err: n })), n.code == l.ConstraintViolation ? new o(l.UserExists, "User already exists") : n;
|
|
1824
1867
|
} finally {
|
|
1825
1868
|
r.release();
|
|
@@ -1830,10 +1873,10 @@ class Y extends H {
|
|
|
1830
1873
|
let { user: r } = await this.getUserByUsername(e), i = r.id;
|
|
1831
1874
|
try {
|
|
1832
1875
|
await t.startTransaction();
|
|
1833
|
-
let
|
|
1834
|
-
await t.execute(n, [i]),
|
|
1835
|
-
} catch (
|
|
1836
|
-
throw await t.rollback(),
|
|
1876
|
+
let a = this.dbPool.parameters(), n = `delete from ${this.userSecretsTable} where ${this.useridForeignKeyColumn}=` + a.nextParameter();
|
|
1877
|
+
await t.execute(n, [i]), a = this.dbPool.parameters(), n = `delete from ${this.userTable} where username=` + a.nextParameter(), await t.execute(n, [e]), await t.commit();
|
|
1878
|
+
} catch (a) {
|
|
1879
|
+
throw await t.rollback(), a;
|
|
1837
1880
|
} finally {
|
|
1838
1881
|
t.release();
|
|
1839
1882
|
}
|
|
@@ -1860,7 +1903,7 @@ class Y extends H {
|
|
|
1860
1903
|
}
|
|
1861
1904
|
}
|
|
1862
1905
|
}
|
|
1863
|
-
class qe extends
|
|
1906
|
+
class qe extends L {
|
|
1864
1907
|
/**
|
|
1865
1908
|
* Constructor with user storage object to use plus optional parameters.
|
|
1866
1909
|
*
|
|
@@ -1888,23 +1931,23 @@ class qe extends z {
|
|
|
1888
1931
|
}
|
|
1889
1932
|
async getKeyInTransaction(e, t) {
|
|
1890
1933
|
const r = this.dbPool.parameters();
|
|
1891
|
-
let i = `select * from ${this.keyTable} where value = ` + r.nextParameter(),
|
|
1892
|
-
if (
|
|
1934
|
+
let i = `select * from ${this.keyTable} where value = ` + r.nextParameter(), a = await e.execute(i, [t]);
|
|
1935
|
+
if (a.length == 0)
|
|
1893
1936
|
throw new o(l.InvalidKey);
|
|
1894
|
-
return this.makeKey(
|
|
1937
|
+
return this.makeKey(a[0]);
|
|
1895
1938
|
}
|
|
1896
1939
|
makeKey(e) {
|
|
1897
1940
|
e = { ...e };
|
|
1898
|
-
let t, r = null, i,
|
|
1941
|
+
let t, r = null, i, a;
|
|
1899
1942
|
if (this.useridForeignKeyColumn in e && (r = e[this.useridForeignKeyColumn], this.useridForeignKeyColumn != "userid" && delete e[this.useridForeignKeyColumn]), e.value) t = e.value;
|
|
1900
1943
|
else throw new o(l.InvalidKey, "No value in key");
|
|
1901
1944
|
if (e.created) i = e.created;
|
|
1902
1945
|
else throw new o(l.InvalidKey, "No creation date in key");
|
|
1903
|
-
return e.expires && (
|
|
1946
|
+
return e.expires && (a = e.expires), e.userid || e.userid, {
|
|
1904
1947
|
value: t,
|
|
1905
1948
|
userid: r,
|
|
1906
1949
|
created: i,
|
|
1907
|
-
expires:
|
|
1950
|
+
expires: a,
|
|
1908
1951
|
...e
|
|
1909
1952
|
};
|
|
1910
1953
|
}
|
|
@@ -1918,20 +1961,20 @@ class qe extends z {
|
|
|
1918
1961
|
* @param extraFields these will be stored in the key table row
|
|
1919
1962
|
* @throws {@link @crossauth/common!CrossauthError } if the key could not be stored.
|
|
1920
1963
|
*/
|
|
1921
|
-
async saveKey(e, t, r, i,
|
|
1964
|
+
async saveKey(e, t, r, i, a, n = {}) {
|
|
1922
1965
|
let c, d = [this.useridForeignKeyColumn, "value", "created", "expires", "data"], g = this.dbPool.parameters(), y = [];
|
|
1923
|
-
for (let
|
|
1966
|
+
for (let k = 0; k < 5; ++k)
|
|
1924
1967
|
y.push(g.nextParameter());
|
|
1925
|
-
let p = [e ?? null, t, r, i ?? null,
|
|
1926
|
-
for (let
|
|
1927
|
-
d.push(
|
|
1928
|
-
let
|
|
1968
|
+
let p = [e ?? null, t, r, i ?? null, a ?? ""];
|
|
1969
|
+
for (let k in n)
|
|
1970
|
+
d.push(k), y.push(g.nextParameter()), p.push(n[k]);
|
|
1971
|
+
let _ = d.join(", "), C = y.join(", ");
|
|
1929
1972
|
const v = await this.dbPool.connect();
|
|
1930
1973
|
try {
|
|
1931
|
-
const
|
|
1932
|
-
await v.execute(
|
|
1933
|
-
} catch (
|
|
1934
|
-
o.asCrossauthError(
|
|
1974
|
+
const k = `insert into ${this.keyTable} (${_}) values (${C})`;
|
|
1975
|
+
await v.execute(k, p);
|
|
1976
|
+
} catch (k) {
|
|
1977
|
+
o.asCrossauthError(k).code == l.ConstraintViolation ? (u.logger.warn(f({ msg: "Attempt to create key that already exists. Stack trace follows" })), u.logger.debug(f({ err: k })), c = new o(l.KeyExists)) : (u.logger.debug(f({ err: k })), c = new o(l.Connection, "Error saving key"));
|
|
1935
1978
|
} finally {
|
|
1936
1979
|
v.release();
|
|
1937
1980
|
}
|
|
@@ -1950,17 +1993,17 @@ class qe extends z {
|
|
|
1950
1993
|
async deleteAllForUser(e, t, r) {
|
|
1951
1994
|
const i = await this.dbPool.connect();
|
|
1952
1995
|
try {
|
|
1953
|
-
let
|
|
1996
|
+
let a, n = [], c = "", d = this.dbPool.parameters();
|
|
1954
1997
|
if (e) {
|
|
1955
1998
|
const g = d.nextParameter(), y = d.nextParameter();
|
|
1956
|
-
|
|
1999
|
+
a = `delete from ${this.keyTable} where ${this.useridForeignKeyColumn} = ${g} and value like ${y} `, n = [e];
|
|
1957
2000
|
} else {
|
|
1958
2001
|
const g = d.nextParameter();
|
|
1959
|
-
|
|
2002
|
+
a = `delete from ${this.keyTable} where ${this.useridForeignKeyColumn} is null and value like ${g}`;
|
|
1960
2003
|
}
|
|
1961
|
-
n.push(t + "%"), r && (c = "and value != " + d.nextParameter(), n.push(r)),
|
|
1962
|
-
} catch (
|
|
1963
|
-
throw
|
|
2004
|
+
n.push(t + "%"), r && (c = "and value != " + d.nextParameter(), n.push(r)), a += " " + c, u.logger.debug(f({ msg: "Executing query", query: a })), await i.execute(a, n);
|
|
2005
|
+
} catch (a) {
|
|
2006
|
+
throw a;
|
|
1964
2007
|
} finally {
|
|
1965
2008
|
i.release();
|
|
1966
2009
|
}
|
|
@@ -1969,10 +2012,10 @@ class qe extends z {
|
|
|
1969
2012
|
const t = await this.dbPool.connect();
|
|
1970
2013
|
try {
|
|
1971
2014
|
let r = [], i = [];
|
|
1972
|
-
const
|
|
2015
|
+
const a = this.dbPool.parameters();
|
|
1973
2016
|
for (let d in e) {
|
|
1974
2017
|
let g = d == "userid" ? this.useridForeignKeyColumn : d;
|
|
1975
|
-
e[d] == null ? r.push(g + " is null") : (r.push(g + " = " +
|
|
2018
|
+
e[d] == null ? r.push(g + " is null") : (r.push(g + " = " + a.nextParameter()), i.push(e[d]));
|
|
1976
2019
|
}
|
|
1977
2020
|
let n = r.join(" and "), c = `delete from ${this.keyTable} where ${n}`;
|
|
1978
2021
|
await t.execute(c, i);
|
|
@@ -1985,16 +2028,16 @@ class qe extends z {
|
|
|
1985
2028
|
async deleteWithPrefix(e, t) {
|
|
1986
2029
|
const r = await this.dbPool.connect();
|
|
1987
2030
|
try {
|
|
1988
|
-
let i,
|
|
2031
|
+
let i, a = [];
|
|
1989
2032
|
const n = this.dbPool.parameters();
|
|
1990
2033
|
if (e) {
|
|
1991
2034
|
let c = n.nextParameter(), d = n.nextParameter();
|
|
1992
|
-
i = `delete from ${this.keyTable} where ${this.useridForeignKeyColumn} = ${c} and value like ${d}`,
|
|
2035
|
+
i = `delete from ${this.keyTable} where ${this.useridForeignKeyColumn} = ${c} and value like ${d}`, a.push(e);
|
|
1993
2036
|
} else {
|
|
1994
2037
|
let c = n.nextParameter();
|
|
1995
2038
|
i = `delete from ${this.keyTable} where ${this.useridForeignKeyColumn} is null and value like ${c}`;
|
|
1996
2039
|
}
|
|
1997
|
-
|
|
2040
|
+
a.push(t + "%"), await r.execute(i, a);
|
|
1998
2041
|
} catch (i) {
|
|
1999
2042
|
throw i;
|
|
2000
2043
|
} finally {
|
|
@@ -2004,10 +2047,10 @@ class qe extends z {
|
|
|
2004
2047
|
async getAllForUser(e) {
|
|
2005
2048
|
const t = await this.dbPool.connect();
|
|
2006
2049
|
try {
|
|
2007
|
-
let r = [], i,
|
|
2050
|
+
let r = [], i, a = [];
|
|
2008
2051
|
const n = this.dbPool.parameters();
|
|
2009
|
-
e ? (i = `select * from ${this.keyTable} where ${this.useridForeignKeyColumn} = ` + n.nextParameter(),
|
|
2010
|
-
let c = await t.execute(i,
|
|
2052
|
+
e ? (i = `select * from ${this.keyTable} where ${this.useridForeignKeyColumn} = ` + n.nextParameter(), a = [e]) : i = `select * from ${this.keyTable} where ${this.useridForeignKeyColumn} is null`, u.logger.debug(f({ msg: "Executing query", query: i }));
|
|
2053
|
+
let c = await t.execute(i, a);
|
|
2011
2054
|
if (c.length == 0)
|
|
2012
2055
|
return [];
|
|
2013
2056
|
for (let d of c) {
|
|
@@ -2041,14 +2084,14 @@ class qe extends z {
|
|
|
2041
2084
|
let r = { ...t };
|
|
2042
2085
|
if (!t.value) throw new o(l.InvalidKey);
|
|
2043
2086
|
delete r.value;
|
|
2044
|
-
let i = [],
|
|
2087
|
+
let i = [], a = [], n = this.dbPool.parameters();
|
|
2045
2088
|
for (let c in r) {
|
|
2046
2089
|
let d = c;
|
|
2047
|
-
r[c] != null && c == "userid" && this.useridForeignKeyColumn != "userid" && (d = this.useridForeignKeyColumn), i.push(c + "= " + n.nextParameter()),
|
|
2090
|
+
r[c] != null && c == "userid" && this.useridForeignKeyColumn != "userid" && (d = this.useridForeignKeyColumn), i.push(c + "= " + n.nextParameter()), a.push(r[d]);
|
|
2048
2091
|
}
|
|
2049
|
-
if (
|
|
2092
|
+
if (a.push(t.value), i.length > 0) {
|
|
2050
2093
|
let c = i.join(", "), d = `update ${this.keyTable} set ${c} where value = ` + n.nextParameter();
|
|
2051
|
-
u.logger.debug(f({ msg: "Executing query", query: d })), await e.execute(d,
|
|
2094
|
+
u.logger.debug(f({ msg: "Executing query", query: d })), await e.execute(d, a);
|
|
2052
2095
|
}
|
|
2053
2096
|
}
|
|
2054
2097
|
/**
|
|
@@ -2065,21 +2108,21 @@ class qe extends z {
|
|
|
2065
2108
|
try {
|
|
2066
2109
|
await r.startTransaction();
|
|
2067
2110
|
const i = await this.getKeyInTransaction(r, e);
|
|
2068
|
-
let
|
|
2111
|
+
let a;
|
|
2069
2112
|
if (!i.data || i.data == "")
|
|
2070
|
-
|
|
2113
|
+
a = {};
|
|
2071
2114
|
else
|
|
2072
2115
|
try {
|
|
2073
|
-
|
|
2116
|
+
a = JSON.parse(i.data);
|
|
2074
2117
|
} catch (n) {
|
|
2075
2118
|
throw u.logger.debug(f({ err: n })), new o(l.DataFormat);
|
|
2076
2119
|
}
|
|
2077
2120
|
for (let n of t) {
|
|
2078
|
-
let c = this.updateDataInternal(
|
|
2121
|
+
let c = this.updateDataInternal(a, n.dataName, n.value);
|
|
2079
2122
|
if (!c) throw new o(l.BadRequest, `Parents of ${n.dataName} not found in key data`);
|
|
2080
|
-
|
|
2123
|
+
a = c;
|
|
2081
2124
|
}
|
|
2082
|
-
await this.updateKeyInTransaction(r, { value: i.value, data: JSON.stringify(
|
|
2125
|
+
await this.updateKeyInTransaction(r, { value: i.value, data: JSON.stringify(a) }), await r.commit();
|
|
2083
2126
|
} catch (i) {
|
|
2084
2127
|
throw await r.rollback(), i && typeof i == "object" && !("isCrossauthError" in i) ? (u.logger.debug(f({ err: i })), new o(l.Connection, "Failed updating session data")) : i;
|
|
2085
2128
|
} finally {
|
|
@@ -2094,16 +2137,16 @@ class qe extends z {
|
|
|
2094
2137
|
try {
|
|
2095
2138
|
await r.startTransaction();
|
|
2096
2139
|
const i = await this.getKeyInTransaction(r, e);
|
|
2097
|
-
let
|
|
2140
|
+
let a = {}, n = !1;
|
|
2098
2141
|
if (i.data && i.data != "") {
|
|
2099
2142
|
try {
|
|
2100
|
-
|
|
2143
|
+
a = JSON.parse(i.data);
|
|
2101
2144
|
} catch (c) {
|
|
2102
2145
|
throw u.logger.debug(f({ err: c })), new o(l.DataFormat);
|
|
2103
2146
|
}
|
|
2104
|
-
n = this.deleteDataInternal(
|
|
2147
|
+
n = this.deleteDataInternal(a, t);
|
|
2105
2148
|
}
|
|
2106
|
-
n && await this.updateKeyInTransaction(r, { value: i.value, data: JSON.stringify(
|
|
2149
|
+
n && await this.updateKeyInTransaction(r, { value: i.value, data: JSON.stringify(a) }), await r.commit();
|
|
2107
2150
|
} catch (i) {
|
|
2108
2151
|
throw await r.rollback(), i && typeof i == "object" && !("isCrossauthError" in i) ? (u.logger.debug(f({ err: i })), new o(l.Connection, "Failed updating session data")) : i;
|
|
2109
2152
|
} finally {
|
|
@@ -2153,28 +2196,28 @@ class We extends me {
|
|
|
2153
2196
|
}
|
|
2154
2197
|
}
|
|
2155
2198
|
makeClient(e) {
|
|
2156
|
-
let t, r, i,
|
|
2199
|
+
let t, r, i, a = !1, n = [], c = [];
|
|
2157
2200
|
if ("client_id" in e && (t = e.client_id), !t) throw new o(l.InvalidClientId);
|
|
2158
2201
|
if ("client_name" in e && (r = e.client_name), !r) throw new o(l.InvalidClientId);
|
|
2159
|
-
return "client_secret" in e && (i = e.client_secret), "confidential" in e && (
|
|
2202
|
+
return "client_secret" in e && (i = e.client_secret), "confidential" in e && (a = e.confidential), "redirect_uri" in e && e.redirect_uri && (n = e.redirect_uri), "valid_flow" in e && e.valid_flow && (c = e.valid_flow), {
|
|
2160
2203
|
client_id: t,
|
|
2161
2204
|
client_name: r,
|
|
2162
2205
|
client_secret: i,
|
|
2163
|
-
confidential:
|
|
2206
|
+
confidential: a,
|
|
2164
2207
|
redirect_uri: n,
|
|
2165
2208
|
valid_flow: c,
|
|
2166
2209
|
...e
|
|
2167
2210
|
};
|
|
2168
2211
|
}
|
|
2169
|
-
async getClientWithTransaction(e, t, r, i,
|
|
2212
|
+
async getClientWithTransaction(e, t, r, i, a, n) {
|
|
2170
2213
|
let c = [], d = this.dbPool.parameters(), g = [], y = `select c.*, r.uri as uri, null as flow from ${this.clientTable} as c left join ${this.redirectUriTable} r on c.client_id = r.client_id `, p = "";
|
|
2171
2214
|
t && r && (p = `where c.${t} = ` + d.nextParameter(), g.push(r)), i !== null && i == null || (p == "" ? p = "where " : p += " and ", i == null ? p += "userid is null" : (p += `${this.useridForeignKeyColumn} = ` + d.nextParameter(), g.push(i)));
|
|
2172
|
-
let
|
|
2173
|
-
t && r && (
|
|
2174
|
-
let v = y + " union " +
|
|
2175
|
-
const
|
|
2215
|
+
let _ = `select c.*, null as uri, f.flow as flow from ${this.clientTable} as c left join ${this.validFlowTable} f on c.client_id = f.client_id `, C = "";
|
|
2216
|
+
t && r && (C = `where c.${t} = ` + d.nextParameter(), g.push(r)), i !== null && i == null || (C == "" ? C = "where " : C += " and ", i == null ? C += "userid is null" : (C += `${this.useridForeignKeyColumn} = ` + d.nextParameter(), g.push(i))), n && (a || (a = 0), a = Number(a), n = Number(n), p == "" ? p = "where " : p += " and ", p += ` c.client_id in (select client_id from ${this.clientTable} limit ${n} offset ${a})`, C == "" ? C = "where " : C += " and ", C += ` c.client_id in (select client_id from ${this.clientTable} limit ${n} offset ${a})`), y += p, _ += C;
|
|
2217
|
+
let v = y + " union " + _ + " order by client_id";
|
|
2218
|
+
const k = await e.execute(v, g);
|
|
2176
2219
|
let A;
|
|
2177
|
-
for (let M of
|
|
2220
|
+
for (let M of k)
|
|
2178
2221
|
(!A || M.client_id != A.client_id) && (A && c.push(A), A = this.makeClient(M), A.valid_flow = [], A.redirect_uri = []), M.uri && A.redirect_uri.push(M.uri), M.flow && A.valid_flow.push(M.flow);
|
|
2179
2222
|
return A && c.push(A), c;
|
|
2180
2223
|
}
|
|
@@ -2198,49 +2241,49 @@ class We extends me {
|
|
|
2198
2241
|
}
|
|
2199
2242
|
}
|
|
2200
2243
|
async createClientWithTransaction(e, t) {
|
|
2201
|
-
const { redirect_uri: r, valid_flow: i, userid:
|
|
2202
|
-
if (
|
|
2203
|
-
for (let
|
|
2204
|
-
if (r[
|
|
2244
|
+
const { redirect_uri: r, valid_flow: i, userid: a, ...n } = t;
|
|
2245
|
+
if (a && (n[this.useridForeignKeyColumn] = a), r)
|
|
2246
|
+
for (let C = 0; C < r.length; ++C) {
|
|
2247
|
+
if (r[C].includes("#")) throw new o(l.InvalidRedirectUri, "Redirect Uri's may not contain page fragments");
|
|
2205
2248
|
try {
|
|
2206
|
-
new URL(r[
|
|
2249
|
+
new URL(r[C]);
|
|
2207
2250
|
} catch {
|
|
2208
|
-
throw new o(l.InvalidRedirectUri, `Redriect uri ${r[
|
|
2251
|
+
throw new o(l.InvalidRedirectUri, `Redriect uri ${r[C]} is not valid`);
|
|
2209
2252
|
}
|
|
2210
2253
|
}
|
|
2211
2254
|
if (i) {
|
|
2212
|
-
for (let
|
|
2213
|
-
if (!b.isValidFlow(i[
|
|
2255
|
+
for (let C = 0; C < i.length; ++C)
|
|
2256
|
+
if (!b.isValidFlow(i[C])) throw new o(l.InvalidOAuthFlow, "Invalid flow " + i[C]);
|
|
2214
2257
|
}
|
|
2215
2258
|
let c = [], d = [], g = [], y = this.dbPool.parameters();
|
|
2216
2259
|
try {
|
|
2217
|
-
for (let
|
|
2218
|
-
c.push(
|
|
2260
|
+
for (let C in n)
|
|
2261
|
+
c.push(C), d.push(y.nextParameter()), g.push(n[C]);
|
|
2219
2262
|
if (c.length > 0) {
|
|
2220
|
-
let
|
|
2221
|
-
const
|
|
2222
|
-
await e.execute(
|
|
2263
|
+
let C = c.join(", "), v = d.join(", ");
|
|
2264
|
+
const k = `insert into ${this.clientTable} (${C}) values (${v})`;
|
|
2265
|
+
await e.execute(k, g);
|
|
2223
2266
|
}
|
|
2224
|
-
} catch (
|
|
2225
|
-
throw typeof
|
|
2267
|
+
} catch (C) {
|
|
2268
|
+
throw typeof C == "object" && C != null && "code" in C && typeof C.code == "string" && (C.code.startsWith("22") || C.code.startsWith("23")) ? (u.logger.debug(f({ err: C })), new o(l.InvalidClientId, "Attempt to create an OAuth client with a client_id that already exists. Maximum attempts failed")) : (u.logger.debug(f({ err: C })), new o(l.Connection, "Error saving OAuth client"));
|
|
2226
2269
|
}
|
|
2227
2270
|
let p = await this.getClientWithTransaction(e, "client_id", t.client_id, t.userid);
|
|
2228
2271
|
if (p.length == 0)
|
|
2229
2272
|
throw u.logger.error(f({ msg: "Attempt to create key that already exists. Stack trace follows" })), new o(l.KeyExists);
|
|
2230
|
-
let
|
|
2273
|
+
let _ = p[0];
|
|
2231
2274
|
if (r)
|
|
2232
|
-
for (let
|
|
2275
|
+
for (let C = 0; C < r.length; ++C) {
|
|
2233
2276
|
g = [], y = this.dbPool.parameters();
|
|
2234
2277
|
let v = `insert into ${this.redirectUriTable} (client_id, uri) values (` + y.nextParameter() + ", " + y.nextParameter() + ")";
|
|
2235
|
-
g.push(
|
|
2278
|
+
g.push(_.client_id), g.push(r[C]), await e.execute(v, g);
|
|
2236
2279
|
}
|
|
2237
2280
|
if (i)
|
|
2238
|
-
for (let
|
|
2281
|
+
for (let C = 0; C < i.length; ++C) {
|
|
2239
2282
|
g = [], y = this.dbPool.parameters();
|
|
2240
2283
|
let v = `insert into ${this.validFlowTable} (client_id, flow) values (` + y.nextParameter() + ", " + y.nextParameter() + ")";
|
|
2241
|
-
g.push(
|
|
2284
|
+
g.push(_.client_id), g.push(i[C]), await e.execute(v, g);
|
|
2242
2285
|
}
|
|
2243
|
-
return { ...
|
|
2286
|
+
return { ..._, redirect_uri: r, valid_flow: i };
|
|
2244
2287
|
}
|
|
2245
2288
|
/**
|
|
2246
2289
|
*
|
|
@@ -2260,8 +2303,8 @@ class We extends me {
|
|
|
2260
2303
|
}
|
|
2261
2304
|
}
|
|
2262
2305
|
async deleteClientWithTransaction(e, t) {
|
|
2263
|
-
let r = [],
|
|
2264
|
-
r.push(t), await e.execute(n, r), n = `delete from ${this.validFlowTable} where client_id = ${
|
|
2306
|
+
let r = [], a = this.dbPool.parameters().nextParameter(), n = `delete from ${this.redirectUriTable} where client_id = ${a}`;
|
|
2307
|
+
r.push(t), await e.execute(n, r), n = `delete from ${this.validFlowTable} where client_id = ${a}`, await e.execute(n, r), n = `delete from ${this.clientTable} where client_id = ${a}`, await e.execute(n, r);
|
|
2265
2308
|
}
|
|
2266
2309
|
/**
|
|
2267
2310
|
* If the given session key exist in the database, update it with the passed values. If it doesn't
|
|
@@ -2298,39 +2341,39 @@ class We extends me {
|
|
|
2298
2341
|
if (!b.isValidFlow(i[v])) throw new o(l.InvalidOAuthFlow, "Redirect Uri's may not contain page fragments");
|
|
2299
2342
|
}
|
|
2300
2343
|
if (!t.client_id) throw new o(l.InvalidClientId, "No client ig given");
|
|
2301
|
-
let { client_id:
|
|
2344
|
+
let { client_id: a, redirect_uri: n, valid_flow: c, ...d } = t;
|
|
2302
2345
|
n || (n = []), c || (c = []);
|
|
2303
2346
|
let g = this.dbPool.parameters(), y = `delete from ${this.redirectUriTable} where client_id = ` + g.nextParameter();
|
|
2304
2347
|
await e.execute(y, [t.client_id]), g = this.dbPool.parameters(), y = `delete from ${this.validFlowTable} where client_id = ` + g.nextParameter(), await e.execute(y, [t.client_id]);
|
|
2305
|
-
let p = [],
|
|
2348
|
+
let p = [], _ = [], C = [];
|
|
2306
2349
|
g = this.dbPool.parameters(), y = `delete from ${this.validFlowTable} where client_id = ` + g.nextParameter();
|
|
2307
2350
|
for (let v in d)
|
|
2308
|
-
p.push(v),
|
|
2351
|
+
p.push(v), _.push(g.nextParameter()), C.push(d[v]);
|
|
2309
2352
|
if (p.length > 0) {
|
|
2310
|
-
let v = p.join(", "),
|
|
2311
|
-
y = `update ${this.clientTable} set (${v}) values (${
|
|
2353
|
+
let v = p.join(", "), k = _.join(", ");
|
|
2354
|
+
y = `update ${this.clientTable} set (${v}) values (${k})`, await e.execute(y, C);
|
|
2312
2355
|
}
|
|
2313
2356
|
if (n)
|
|
2314
2357
|
for (let v = 0; v < n.length; ++v) {
|
|
2315
|
-
|
|
2316
|
-
let
|
|
2317
|
-
|
|
2358
|
+
C = [], g = this.dbPool.parameters();
|
|
2359
|
+
let k = `insert into ${this.redirectUriTable} (client_id, uri) values (` + g.nextParameter() + ", " + g.nextParameter() + ")";
|
|
2360
|
+
C.push(t.client_id), C.push(n[v]), await e.execute(k, C);
|
|
2318
2361
|
}
|
|
2319
2362
|
if (c)
|
|
2320
2363
|
for (let v = 0; v < c.length; ++v) {
|
|
2321
|
-
|
|
2322
|
-
let
|
|
2323
|
-
|
|
2364
|
+
C = [], g = this.dbPool.parameters();
|
|
2365
|
+
let k = `insert into ${this.validFlowTable} (client_id, flow) values (` + g.nextParameter() + ", " + g.nextParameter() + ")";
|
|
2366
|
+
C.push(t.client_id), C.push(c[v]), await e.execute(k, C);
|
|
2324
2367
|
}
|
|
2325
2368
|
}
|
|
2326
2369
|
async getClients(e, t, r) {
|
|
2327
2370
|
let i = await this.dbPool.connect();
|
|
2328
2371
|
try {
|
|
2329
2372
|
await i.startTransaction();
|
|
2330
|
-
const
|
|
2331
|
-
return await i.commit(),
|
|
2332
|
-
} catch (
|
|
2333
|
-
throw await i.rollback(),
|
|
2373
|
+
const a = this.getClientWithTransaction(i, void 0, void 0, r, e, t);
|
|
2374
|
+
return await i.commit(), a;
|
|
2375
|
+
} catch (a) {
|
|
2376
|
+
throw await i.rollback(), a;
|
|
2334
2377
|
} finally {
|
|
2335
2378
|
i.release();
|
|
2336
2379
|
}
|
|
@@ -2352,9 +2395,9 @@ class Je extends we {
|
|
|
2352
2395
|
async getAuthorizations(e, t) {
|
|
2353
2396
|
let r = await this.dbPool.connect();
|
|
2354
2397
|
try {
|
|
2355
|
-
const i = this.dbPool.parameters(),
|
|
2398
|
+
const i = this.dbPool.parameters(), a = [];
|
|
2356
2399
|
let n = `select scope from ${this.authorizationTable} where client_id = ` + i.nextParameter();
|
|
2357
|
-
return
|
|
2400
|
+
return a.push(e), t === null ? n += ` and ${this.useridForeignKeyColumn} is null` : t && (n += ` and ${this.useridForeignKeyColumn} = ` + i.nextParameter(), a.push(t)), (await r.execute(n, a)).map((g) => g.scope);
|
|
2358
2401
|
} catch (i) {
|
|
2359
2402
|
throw i;
|
|
2360
2403
|
} finally {
|
|
@@ -2365,13 +2408,13 @@ class Je extends we {
|
|
|
2365
2408
|
let i = await this.dbPool.connect();
|
|
2366
2409
|
try {
|
|
2367
2410
|
await i.startTransaction();
|
|
2368
|
-
let
|
|
2369
|
-
n.push(e), t ? (c += ` and ${this.useridForeignKeyColumn} = ` +
|
|
2411
|
+
let a = this.dbPool.parameters(), n = [], c = `delete from ${this.authorizationTable} where client_id = ` + a.nextParameter();
|
|
2412
|
+
n.push(e), t ? (c += ` and ${this.useridForeignKeyColumn} = ` + a.nextParameter(), n.push(t)) : c += ` and ${this.useridForeignKeyColumn} is null`, await i.execute(c, n);
|
|
2370
2413
|
for (let d of r)
|
|
2371
|
-
|
|
2414
|
+
a = this.dbPool.parameters(), n = [], c = `insert into ${this.authorizationTable} (client_id, userid, scope) values (` + a.nextParameter() + ", " + a.nextParameter() + ", " + a.nextParameter() + ")", n.push(e), n.push(t), n.push(d), await i.execute(c, n);
|
|
2372
2415
|
await i.commit();
|
|
2373
|
-
} catch (
|
|
2374
|
-
throw await i.rollback(),
|
|
2416
|
+
} catch (a) {
|
|
2417
|
+
throw await i.rollback(), a;
|
|
2375
2418
|
} finally {
|
|
2376
2419
|
i.release();
|
|
2377
2420
|
}
|
|
@@ -2410,8 +2453,8 @@ class Xe extends Ze {
|
|
|
2410
2453
|
crossauthErrorFromPostgresError(e) {
|
|
2411
2454
|
let t, r;
|
|
2412
2455
|
if (e && typeof e == "object" && "code" in e && typeof e.code == "string" && (t = e.code), e && typeof e == "object" && "detail" in e && typeof e.detail == "string" && (r = e.detail), t != null && t.startsWith("23")) {
|
|
2413
|
-
const
|
|
2414
|
-
return new o(l.ConstraintViolation,
|
|
2456
|
+
const a = t + " : " + (r ?? "Constraint violation during database insert/update");
|
|
2457
|
+
return new o(l.ConstraintViolation, a);
|
|
2415
2458
|
}
|
|
2416
2459
|
const i = t ? t + " : " + (r ?? "Constraint violation during database insert/update") : "Couldn't execute database query";
|
|
2417
2460
|
return new o(l.Connection, i);
|
|
@@ -2445,44 +2488,44 @@ class Qe extends Ge {
|
|
|
2445
2488
|
return "$" + this.nextParam++;
|
|
2446
2489
|
}
|
|
2447
2490
|
}
|
|
2448
|
-
class
|
|
2491
|
+
class Kt extends Y {
|
|
2449
2492
|
/**
|
|
2450
2493
|
* Creates a PostgresUserStorage object, optionally overriding defaults.
|
|
2451
2494
|
* @param pgPool the instance of the Posrgres client.
|
|
2452
2495
|
* @param options see {@link PostgresUserStorageOptions}.
|
|
2453
2496
|
*/
|
|
2454
|
-
constructor(
|
|
2455
|
-
super(new de(
|
|
2497
|
+
constructor(s, e = {}) {
|
|
2498
|
+
super(new de(s), e);
|
|
2456
2499
|
}
|
|
2457
2500
|
}
|
|
2458
|
-
class
|
|
2501
|
+
class Ft extends qe {
|
|
2459
2502
|
/**
|
|
2460
2503
|
* Creates a PostgresKeyStorage object, optionally overriding defaults.
|
|
2461
2504
|
* @param pgPool the instance of the Posrgres client.
|
|
2462
2505
|
* @param options see {@link PostgresKeyStorageOptions}.
|
|
2463
2506
|
*/
|
|
2464
|
-
constructor(
|
|
2465
|
-
super(new de(
|
|
2507
|
+
constructor(s, e = {}) {
|
|
2508
|
+
super(new de(s), e);
|
|
2466
2509
|
}
|
|
2467
2510
|
}
|
|
2468
|
-
class
|
|
2511
|
+
class Ot extends We {
|
|
2469
2512
|
/**
|
|
2470
2513
|
* Creates a PostgresOAuthClientStorage object, optionally overriding defaults.
|
|
2471
2514
|
* @param pgPool the instance of the Posrgres client.
|
|
2472
2515
|
* @param options see {@link PostgresOAuthClientStorageOptions}.
|
|
2473
2516
|
*/
|
|
2474
|
-
constructor(
|
|
2475
|
-
super(new de(
|
|
2517
|
+
constructor(s, e = {}) {
|
|
2518
|
+
super(new de(s), e);
|
|
2476
2519
|
}
|
|
2477
2520
|
}
|
|
2478
|
-
class
|
|
2521
|
+
class Nt extends Je {
|
|
2479
2522
|
/**
|
|
2480
2523
|
* Creates a PostgresOAuthClientStorage object, optionally overriding defaults.
|
|
2481
2524
|
* @param pgPool the instance of the Posrgres client.
|
|
2482
2525
|
* @param options see {@link PostgresOAuthAuthorizationStorageOptions}.
|
|
2483
2526
|
*/
|
|
2484
|
-
constructor(
|
|
2485
|
-
super(new de(
|
|
2527
|
+
constructor(s, e = {}) {
|
|
2528
|
+
super(new de(s), e);
|
|
2486
2529
|
}
|
|
2487
2530
|
}
|
|
2488
2531
|
class re {
|
|
@@ -2491,11 +2534,11 @@ class re {
|
|
|
2491
2534
|
* Constructor.
|
|
2492
2535
|
* @param options see {@link AuthenticationOptions}
|
|
2493
2536
|
*/
|
|
2494
|
-
constructor(
|
|
2537
|
+
constructor(s) {
|
|
2495
2538
|
h(this, "friendlyName");
|
|
2496
2539
|
h(this, "factorName", "");
|
|
2497
|
-
if (!(
|
|
2498
|
-
this.friendlyName =
|
|
2540
|
+
if (!(s != null && s.friendlyName)) throw new o(l.Configuration, "Authenticator must have a friendly name");
|
|
2541
|
+
this.friendlyName = s == null ? void 0 : s.friendlyName;
|
|
2499
2542
|
}
|
|
2500
2543
|
capabilities() {
|
|
2501
2544
|
return {
|
|
@@ -2523,7 +2566,7 @@ class be extends re {
|
|
|
2523
2566
|
return "none";
|
|
2524
2567
|
}
|
|
2525
2568
|
}
|
|
2526
|
-
const
|
|
2569
|
+
const Ce = process.env.PBKDF2_DIGEST || "sha256", Se = Number(process.env.PBKDF2_ITERATIONS || 6e5), ve = Number(process.env.PBKDF2_KEYLENGTH || 32), et = Number(process.env.PBKDF2_KEYLENGTH || 16), ae = "sha256", q = class q {
|
|
2527
2570
|
/**
|
|
2528
2571
|
* Returns true if the plaintext password, when hashed, equals the one in the hash, using
|
|
2529
2572
|
* it's hasher settings
|
|
@@ -2532,8 +2575,8 @@ const Se = process.env.PBKDF2_DIGEST || "sha256", Ce = Number(process.env.PBKDF2
|
|
|
2532
2575
|
* @param secret if `useHash`in `encodedHash` is true, uses as a pepper for the hasher
|
|
2533
2576
|
* @returns true if they are equal, false otherwise
|
|
2534
2577
|
*/
|
|
2535
|
-
static async passwordsEqual(
|
|
2536
|
-
let r = q.decodePasswordHash(e), i = await q.passwordHash(
|
|
2578
|
+
static async passwordsEqual(s, e, t) {
|
|
2579
|
+
let r = q.decodePasswordHash(e), i = await q.passwordHash(s, {
|
|
2537
2580
|
salt: r.salt,
|
|
2538
2581
|
encode: !1,
|
|
2539
2582
|
secret: r.useSecret ? t : void 0,
|
|
@@ -2550,16 +2593,16 @@ const Se = process.env.PBKDF2_DIGEST || "sha256", Ce = Number(process.env.PBKDF2
|
|
|
2550
2593
|
* @param encoded base64-encoded text
|
|
2551
2594
|
* @returns URF-8 text
|
|
2552
2595
|
*/
|
|
2553
|
-
static base64Decode(
|
|
2554
|
-
return Buffer.from(
|
|
2596
|
+
static base64Decode(s) {
|
|
2597
|
+
return Buffer.from(s, "base64url").toString("utf-8");
|
|
2555
2598
|
}
|
|
2556
2599
|
/**
|
|
2557
2600
|
* Base64-encodes UTF-8 text
|
|
2558
2601
|
* @param text UTF-8 text
|
|
2559
2602
|
* @returns Base64 text
|
|
2560
2603
|
*/
|
|
2561
|
-
static base64Encode(
|
|
2562
|
-
return Buffer.from(
|
|
2604
|
+
static base64Encode(s) {
|
|
2605
|
+
return Buffer.from(s, "utf-8").toString("base64url");
|
|
2563
2606
|
}
|
|
2564
2607
|
/**
|
|
2565
2608
|
* Splits a hashed password into its component parts. Return it as a {@link PasswordHash }.
|
|
@@ -2572,8 +2615,8 @@ const Se = process.env.PBKDF2_DIGEST || "sha256", Ce = Number(process.env.PBKDF2
|
|
|
2572
2615
|
* @param hash the hassed password to decode. See above for format
|
|
2573
2616
|
* @returns {@link PasswordHash} object containing the deecoded hash components
|
|
2574
2617
|
*/
|
|
2575
|
-
static decodePasswordHash(
|
|
2576
|
-
const e =
|
|
2618
|
+
static decodePasswordHash(s) {
|
|
2619
|
+
const e = s.split(":");
|
|
2577
2620
|
if (e.length != 7)
|
|
2578
2621
|
throw new o(l.InvalidHash);
|
|
2579
2622
|
try {
|
|
@@ -2603,8 +2646,8 @@ const Se = process.env.PBKDF2_DIGEST || "sha256", Ce = Number(process.env.PBKDF2
|
|
|
2603
2646
|
* @param digest The digest algorithm, eg `pbkdf2`
|
|
2604
2647
|
* @returns a string encode the above parameters.
|
|
2605
2648
|
*/
|
|
2606
|
-
static encodePasswordHash(
|
|
2607
|
-
return "pbkdf2:" +
|
|
2649
|
+
static encodePasswordHash(s, e, t, r, i, a) {
|
|
2650
|
+
return "pbkdf2:" + a + ":" + String(i) + ":" + String(r) + ":" + (t ? 1 : 0) + ":" + e + ":" + s;
|
|
2608
2651
|
}
|
|
2609
2652
|
/**
|
|
2610
2653
|
* Creates a random salt
|
|
@@ -2618,8 +2661,8 @@ const Se = process.env.PBKDF2_DIGEST || "sha256", Ce = Number(process.env.PBKDF2
|
|
|
2618
2661
|
* @param length length of the string to create
|
|
2619
2662
|
* @returns the random value as a string. Number of bytes will be greater as it is base64 encoded.
|
|
2620
2663
|
*/
|
|
2621
|
-
static randomValue(
|
|
2622
|
-
return ue(
|
|
2664
|
+
static randomValue(s) {
|
|
2665
|
+
return ue(s).toString("base64url");
|
|
2623
2666
|
}
|
|
2624
2667
|
// not real base32 - omits 1,i,0,o
|
|
2625
2668
|
/**
|
|
@@ -2627,9 +2670,9 @@ const Se = process.env.PBKDF2_DIGEST || "sha256", Ce = Number(process.env.PBKDF2
|
|
|
2627
2670
|
* @param length length of the string to create
|
|
2628
2671
|
* @returns the random value as a string. Number of bytes will be greater as it is base64 encoded.
|
|
2629
2672
|
*/
|
|
2630
|
-
static randomBase32(
|
|
2673
|
+
static randomBase32(s, e) {
|
|
2631
2674
|
var i;
|
|
2632
|
-
const r = [...ue(
|
|
2675
|
+
const r = [...ue(s)].map((a) => q.Base32[a % 32]).join("");
|
|
2633
2676
|
return e ? ((i = r.match(/(.{1,4})/g)) == null ? void 0 : i.join("-")) ?? r : r;
|
|
2634
2677
|
}
|
|
2635
2678
|
/**
|
|
@@ -2644,8 +2687,8 @@ const Se = process.env.PBKDF2_DIGEST || "sha256", Ce = Number(process.env.PBKDF2
|
|
|
2644
2687
|
* @param plaintext text to hash
|
|
2645
2688
|
* @returns the string containing the hash
|
|
2646
2689
|
*/
|
|
2647
|
-
static hash(
|
|
2648
|
-
return this.sha256(
|
|
2690
|
+
static hash(s) {
|
|
2691
|
+
return this.sha256(s);
|
|
2649
2692
|
}
|
|
2650
2693
|
/**
|
|
2651
2694
|
* Standard hash using SHA256 (not PBKDF2 or HMAC)
|
|
@@ -2653,8 +2696,8 @@ const Se = process.env.PBKDF2_DIGEST || "sha256", Ce = Number(process.env.PBKDF2
|
|
|
2653
2696
|
* @param plaintext text to hash
|
|
2654
2697
|
* @returns the string containing the hash
|
|
2655
2698
|
*/
|
|
2656
|
-
static sha256(
|
|
2657
|
-
return Oe("sha256").update(
|
|
2699
|
+
static sha256(s) {
|
|
2700
|
+
return Oe("sha256").update(s).digest("base64url");
|
|
2658
2701
|
}
|
|
2659
2702
|
/**
|
|
2660
2703
|
* Hashes a password and returns it as a base64 or base64url encoded string
|
|
@@ -2665,25 +2708,25 @@ const Se = process.env.PBKDF2_DIGEST || "sha256", Ce = Number(process.env.PBKDF2
|
|
|
2665
2708
|
* - `encode`: if true, returns the full string as it should be stored in the database.
|
|
2666
2709
|
* @returns the string containing the hash and the values to decode it
|
|
2667
2710
|
*/
|
|
2668
|
-
static async passwordHash(
|
|
2711
|
+
static async passwordHash(s, e = {}) {
|
|
2669
2712
|
let { salt: t, secret: r, encode: i } = { ...e };
|
|
2670
2713
|
t || (t = q.randomSalt());
|
|
2671
|
-
let
|
|
2714
|
+
let a = r != null, n = a ? t + "!" + r : t;
|
|
2672
2715
|
i == null && (i = !1);
|
|
2673
2716
|
let g = (await De(Ne)(
|
|
2674
|
-
|
|
2717
|
+
s,
|
|
2675
2718
|
n,
|
|
2676
|
-
e.iterations ??
|
|
2719
|
+
e.iterations ?? Se,
|
|
2677
2720
|
e.keyLen ?? ve,
|
|
2678
|
-
e.digest ??
|
|
2721
|
+
e.digest ?? Ce
|
|
2679
2722
|
)).toString("base64url");
|
|
2680
2723
|
return i && (g = this.encodePasswordHash(
|
|
2681
2724
|
g,
|
|
2682
2725
|
t,
|
|
2683
|
-
|
|
2684
|
-
e.iterations ??
|
|
2726
|
+
a,
|
|
2727
|
+
e.iterations ?? Se,
|
|
2685
2728
|
e.keyLen ?? ve,
|
|
2686
|
-
e.digest ??
|
|
2729
|
+
e.digest ?? Ce
|
|
2687
2730
|
)), g;
|
|
2688
2731
|
}
|
|
2689
2732
|
/**
|
|
@@ -2695,8 +2738,8 @@ const Se = process.env.PBKDF2_DIGEST || "sha256", Ce = Number(process.env.PBKDF2
|
|
|
2695
2738
|
* @param timestamp time the token will expire
|
|
2696
2739
|
* @returns a Base64-URL-encoded string that can be hashed.
|
|
2697
2740
|
*/
|
|
2698
|
-
static signableToken(
|
|
2699
|
-
return e == null && (e = q.randomSalt()), t || (t = (/* @__PURE__ */ new Date()).getTime()), Buffer.from(JSON.stringify({ ...
|
|
2741
|
+
static signableToken(s, e, t) {
|
|
2742
|
+
return e == null && (e = q.randomSalt()), t || (t = (/* @__PURE__ */ new Date()).getTime()), Buffer.from(JSON.stringify({ ...s, t, s: e })).toString("base64url");
|
|
2700
2743
|
}
|
|
2701
2744
|
/**
|
|
2702
2745
|
* Signs a JSON payload by creating a hash, using a secret and
|
|
@@ -2708,9 +2751,9 @@ const Se = process.env.PBKDF2_DIGEST || "sha256", Ce = Number(process.env.PBKDF2
|
|
|
2708
2751
|
* @param timestamp optionally, a timestamp to include in the signed date as a Unix date
|
|
2709
2752
|
* @returns Base64-url encoded hash
|
|
2710
2753
|
*/
|
|
2711
|
-
static sign(
|
|
2712
|
-
const i = q.signableToken(
|
|
2713
|
-
return i + "." +
|
|
2754
|
+
static sign(s, e, t, r) {
|
|
2755
|
+
const i = q.signableToken(s, t, r), a = ie(ae, e);
|
|
2756
|
+
return i + "." + a.update(i).digest("base64url");
|
|
2714
2757
|
}
|
|
2715
2758
|
/**
|
|
2716
2759
|
* This can be called for a string payload that is a cryptographically
|
|
@@ -2721,9 +2764,9 @@ const Se = process.env.PBKDF2_DIGEST || "sha256", Ce = Number(process.env.PBKDF2
|
|
|
2721
2764
|
* @param secret the secret to sign with
|
|
2722
2765
|
* @returns Base64-url encoded hash
|
|
2723
2766
|
*/
|
|
2724
|
-
static signSecureToken(
|
|
2725
|
-
const t = ie(
|
|
2726
|
-
return
|
|
2767
|
+
static signSecureToken(s, e) {
|
|
2768
|
+
const t = ie(ae, e);
|
|
2769
|
+
return s + "." + t.update(s).digest("base64url");
|
|
2727
2770
|
}
|
|
2728
2771
|
/**
|
|
2729
2772
|
* Validates a signature and, if valid, return the unstringified payload
|
|
@@ -2735,16 +2778,16 @@ const Se = process.env.PBKDF2_DIGEST || "sha256", Ce = Number(process.env.PBKDF2
|
|
|
2735
2778
|
* {@link @crossauth/common!ErrorCode} of `InvalidKey` if signature
|
|
2736
2779
|
* is invalid or has expired.
|
|
2737
2780
|
*/
|
|
2738
|
-
static unsign(
|
|
2739
|
-
const r =
|
|
2781
|
+
static unsign(s, e, t) {
|
|
2782
|
+
const r = s.split(".");
|
|
2740
2783
|
if (r.length != 2) throw new o(l.InvalidKey);
|
|
2741
|
-
const i = r[0],
|
|
2784
|
+
const i = r[0], a = r[1], n = JSON.parse(Buffer.from(i, "base64url").toString());
|
|
2742
2785
|
if (t && n.t + t * 1e3 > (/* @__PURE__ */ new Date()).getTime())
|
|
2743
2786
|
throw new o(l.Expired);
|
|
2744
|
-
const d = ie(
|
|
2745
|
-
if (d.length !=
|
|
2787
|
+
const d = ie(ae, e).update(i).digest("base64url");
|
|
2788
|
+
if (d.length != a.length)
|
|
2746
2789
|
throw new o(l.InvalidKey, "Signature does not match payload");
|
|
2747
|
-
if (!he(Buffer.from(d), Buffer.from(
|
|
2790
|
+
if (!he(Buffer.from(d), Buffer.from(a)))
|
|
2748
2791
|
throw new o(l.InvalidKey, "Signature does not match payload");
|
|
2749
2792
|
return n;
|
|
2750
2793
|
}
|
|
@@ -2758,15 +2801,15 @@ const Se = process.env.PBKDF2_DIGEST || "sha256", Ce = Number(process.env.PBKDF2
|
|
|
2758
2801
|
* {@link @crossauth/common!ErrorCode} of `InvalidKey` if signature
|
|
2759
2802
|
* is invalid or has expired.
|
|
2760
2803
|
*/
|
|
2761
|
-
static unsignSecureToken(
|
|
2762
|
-
const t =
|
|
2804
|
+
static unsignSecureToken(s, e) {
|
|
2805
|
+
const t = s.split(".");
|
|
2763
2806
|
if (t.length != 2) throw new o(l.InvalidKey);
|
|
2764
|
-
const r = t[0], i = t[1],
|
|
2807
|
+
const r = t[0], i = t[1], a = r, c = ie(ae, e).update(r).digest("base64url");
|
|
2765
2808
|
if (c.length != i.length)
|
|
2766
2809
|
throw new o(l.InvalidKey, "Signature does not match payload");
|
|
2767
2810
|
if (!he(Buffer.from(c), Buffer.from(i)))
|
|
2768
2811
|
throw new o(l.InvalidKey, "Signature does not match payload");
|
|
2769
|
-
return
|
|
2812
|
+
return a;
|
|
2770
2813
|
}
|
|
2771
2814
|
/**
|
|
2772
2815
|
* XOR's two arrays of base64url-encoded strings
|
|
@@ -2774,8 +2817,8 @@ const Se = process.env.PBKDF2_DIGEST || "sha256", Ce = Number(process.env.PBKDF2
|
|
|
2774
2817
|
* @param mask mask to XOR it with
|
|
2775
2818
|
* @return an XOR'r string
|
|
2776
2819
|
*/
|
|
2777
|
-
static xor(
|
|
2778
|
-
const t = Buffer.from(
|
|
2820
|
+
static xor(s, e) {
|
|
2821
|
+
const t = Buffer.from(s, "base64url"), r = Buffer.from(e, "base64url"), i = t.map((a, n) => a ^ r[n]);
|
|
2779
2822
|
return Buffer.from(i).toString("base64url");
|
|
2780
2823
|
}
|
|
2781
2824
|
/**
|
|
@@ -2785,12 +2828,12 @@ const Se = process.env.PBKDF2_DIGEST || "sha256", Ce = Number(process.env.PBKDF2
|
|
|
2785
2828
|
* @param keyString the symmetric key
|
|
2786
2829
|
* @returns Encrypted text Base64-url encoded.
|
|
2787
2830
|
*/
|
|
2788
|
-
static symmetricEncrypt(
|
|
2831
|
+
static symmetricEncrypt(s, e, t = void 0) {
|
|
2789
2832
|
t || (t = ue(16));
|
|
2790
2833
|
let r = Buffer.from(e, "base64url");
|
|
2791
2834
|
var i = Re("aes-256-cbc", r, t);
|
|
2792
|
-
let
|
|
2793
|
-
return
|
|
2835
|
+
let a = i.update(s);
|
|
2836
|
+
return a = Buffer.concat([a, i.final()]), t.toString("base64url") + "." + a.toString("base64url");
|
|
2794
2837
|
}
|
|
2795
2838
|
/**
|
|
2796
2839
|
* Symmetric decryption using a key that must be a string
|
|
@@ -2799,26 +2842,26 @@ const Se = process.env.PBKDF2_DIGEST || "sha256", Ce = Number(process.env.PBKDF2
|
|
|
2799
2842
|
* @param keyString the symmetric key
|
|
2800
2843
|
* @returns Decrypted text
|
|
2801
2844
|
*/
|
|
2802
|
-
static symmetricDecrypt(
|
|
2845
|
+
static symmetricDecrypt(s, e) {
|
|
2803
2846
|
let t = Buffer.from(e, "base64url");
|
|
2804
|
-
const r =
|
|
2847
|
+
const r = s.split(".");
|
|
2805
2848
|
if (r.length != 2) throw new o(l.InvalidHash, "Not AES-256-CBC ciphertext");
|
|
2806
|
-
let i = Buffer.from(r[0], "base64url"),
|
|
2849
|
+
let i = Buffer.from(r[0], "base64url"), a = Buffer.from(r[1], "base64url");
|
|
2807
2850
|
var n = xe("aes-256-cbc", t, i);
|
|
2808
|
-
let c = n.update(
|
|
2851
|
+
let c = n.update(a);
|
|
2809
2852
|
return c = Buffer.concat([c, n.final()]), c.toString();
|
|
2810
2853
|
}
|
|
2811
2854
|
};
|
|
2812
2855
|
h(q, "Base32", "ABCDEFGHJKLMNPQRSTUVWXYZ23456789".split(""));
|
|
2813
2856
|
let T = q;
|
|
2814
|
-
function tt(
|
|
2815
|
-
let
|
|
2816
|
-
if (!
|
|
2857
|
+
function tt(S) {
|
|
2858
|
+
let s = [];
|
|
2859
|
+
if (!S.password) s.push("Password not provided");
|
|
2817
2860
|
else {
|
|
2818
|
-
const e =
|
|
2819
|
-
e.length < 8 &&
|
|
2861
|
+
const e = S.password;
|
|
2862
|
+
e.length < 8 && s.push("Password must be at least 8 characters"), e.match(/[a-z]/) == null && s.push("Password must contain at least one lowercase character"), e.match(/[A-Z]/) == null && s.push("Password must contain at least one uppercase character"), e.match(/[0-9]/) == null && s.push("Password must contain at least one digit");
|
|
2820
2863
|
}
|
|
2821
|
-
return
|
|
2864
|
+
return s;
|
|
2822
2865
|
}
|
|
2823
2866
|
const le = class le extends be {
|
|
2824
2867
|
/**
|
|
@@ -3046,14 +3089,14 @@ class Z extends re {
|
|
|
3046
3089
|
);
|
|
3047
3090
|
const t = Z.zeroPad(ee(999999), 6), r = e.email ? e.email : e.username;
|
|
3048
3091
|
Z.validateEmail(r);
|
|
3049
|
-
const i = /* @__PURE__ */ new Date(),
|
|
3092
|
+
const i = /* @__PURE__ */ new Date(), a = new Date(i.getTime() + 1e3 * this.emailAuthenticatorTokenExpires).getTime(), n = {
|
|
3050
3093
|
username: e.username,
|
|
3051
3094
|
email: r,
|
|
3052
3095
|
factor2: this.factorName
|
|
3053
3096
|
}, c = {
|
|
3054
3097
|
username: e.username,
|
|
3055
3098
|
factor2: this.factorName,
|
|
3056
|
-
expiry:
|
|
3099
|
+
expiry: a,
|
|
3057
3100
|
otp: t
|
|
3058
3101
|
}, d = this.sendToken(r, t);
|
|
3059
3102
|
return u.logger.info(f({
|
|
@@ -3069,7 +3112,7 @@ class Z extends re {
|
|
|
3069
3112
|
* @returns
|
|
3070
3113
|
*/
|
|
3071
3114
|
async reprepareConfiguration(e, t) {
|
|
3072
|
-
const r =
|
|
3115
|
+
const r = L.decodeData(t.data)["2fa"], i = Z.zeroPad(ee(999999), 6), a = /* @__PURE__ */ new Date(), n = new Date(a.getTime() + 1e3 * this.emailAuthenticatorTokenExpires).getTime(), c = this.sendToken(r.email, i);
|
|
3073
3116
|
return u.logger.info(f({
|
|
3074
3117
|
msg: "Sent factor otp email",
|
|
3075
3118
|
emailMessageId: c,
|
|
@@ -3114,11 +3157,11 @@ class Z extends re {
|
|
|
3114
3157
|
* @returns `otp` and `expiry` as a Unix time (number).
|
|
3115
3158
|
*/
|
|
3116
3159
|
async createOneTimeSecrets(e) {
|
|
3117
|
-
const t = Z.zeroPad(ee(999999), 6), r = /* @__PURE__ */ new Date(), i = new Date(r.getTime() + 1e3 * this.emailAuthenticatorTokenExpires).getTime(),
|
|
3160
|
+
const t = Z.zeroPad(ee(999999), 6), r = /* @__PURE__ */ new Date(), i = new Date(r.getTime() + 1e3 * this.emailAuthenticatorTokenExpires).getTime(), a = e.email || e.username, n = this.sendToken(a, t);
|
|
3118
3161
|
return u.logger.info(f({
|
|
3119
3162
|
msg: "Sent factor otp email",
|
|
3120
3163
|
emailMessageId: n,
|
|
3121
|
-
email:
|
|
3164
|
+
email: a
|
|
3122
3165
|
})), { otp: t, expiry: i };
|
|
3123
3166
|
}
|
|
3124
3167
|
/**
|
|
@@ -3235,14 +3278,14 @@ class Q extends re {
|
|
|
3235
3278
|
);
|
|
3236
3279
|
const t = Q.zeroPad(ee(999999), 6), r = e.phone;
|
|
3237
3280
|
Q.validatePhone(r);
|
|
3238
|
-
const i = /* @__PURE__ */ new Date(),
|
|
3281
|
+
const i = /* @__PURE__ */ new Date(), a = new Date(i.getTime() + 1e3 * this.smsAuthenticatorTokenExpires).getTime(), n = {
|
|
3239
3282
|
username: e.username,
|
|
3240
3283
|
phone: r,
|
|
3241
3284
|
factor2: this.factorName
|
|
3242
3285
|
}, c = {
|
|
3243
3286
|
username: e.username,
|
|
3244
3287
|
factor2: this.factorName,
|
|
3245
|
-
expiry:
|
|
3288
|
+
expiry: a,
|
|
3246
3289
|
otp: t
|
|
3247
3290
|
};
|
|
3248
3291
|
let d = { otp: t };
|
|
@@ -3260,7 +3303,7 @@ class Q extends re {
|
|
|
3260
3303
|
* @returns
|
|
3261
3304
|
*/
|
|
3262
3305
|
async reprepareConfiguration(e, t) {
|
|
3263
|
-
const r =
|
|
3306
|
+
const r = L.decodeData(t.data)["2fa"], i = Q.zeroPad(ee(999999), 6), a = /* @__PURE__ */ new Date(), n = new Date(a.getTime() + 1e3 * this.smsAuthenticatorTokenExpires).getTime(), c = this.sendSms(r.phone, i);
|
|
3264
3307
|
return u.logger.info(f({
|
|
3265
3308
|
msg: "Sent factor otp sms",
|
|
3266
3309
|
smsMessageId: c,
|
|
@@ -3304,11 +3347,11 @@ class Q extends re {
|
|
|
3304
3347
|
* @returns `otp` and `expiry` as a Unix time (number).
|
|
3305
3348
|
*/
|
|
3306
3349
|
async createOneTimeSecrets(e) {
|
|
3307
|
-
const t = Q.zeroPad(ee(999999), 6), r = /* @__PURE__ */ new Date(), i = new Date(r.getTime() + 1e3 * this.smsAuthenticatorTokenExpires).getTime(),
|
|
3350
|
+
const t = Q.zeroPad(ee(999999), 6), r = /* @__PURE__ */ new Date(), i = new Date(r.getTime() + 1e3 * this.smsAuthenticatorTokenExpires).getTime(), a = e.phone, n = this.sendSms(a, t);
|
|
3308
3351
|
return u.logger.info(f({
|
|
3309
3352
|
msg: "Sent factor otp sms",
|
|
3310
3353
|
smsMessageId: n,
|
|
3311
|
-
phone:
|
|
3354
|
+
phone: a
|
|
3312
3355
|
})), { otp: t, expiry: i };
|
|
3313
3356
|
}
|
|
3314
3357
|
/**
|
|
@@ -3424,7 +3467,7 @@ class Ue extends Q {
|
|
|
3424
3467
|
return (await Be(this.accountSid, this.authToken).messages.create(r)).sid;
|
|
3425
3468
|
}
|
|
3426
3469
|
}
|
|
3427
|
-
class
|
|
3470
|
+
class Rt extends re {
|
|
3428
3471
|
/**
|
|
3429
3472
|
* Constructor
|
|
3430
3473
|
*
|
|
@@ -3464,13 +3507,13 @@ class Ft extends re {
|
|
|
3464
3507
|
const t = /* @__PURE__ */ new Date(), r = new Date(t.getTime() + 1e3 * 60).getTime(), i = {
|
|
3465
3508
|
username: e.username,
|
|
3466
3509
|
factor2: this.factorName
|
|
3467
|
-
},
|
|
3510
|
+
}, a = {
|
|
3468
3511
|
username: e.username,
|
|
3469
3512
|
factor2: this.factorName,
|
|
3470
3513
|
expiry: r,
|
|
3471
3514
|
otp: this.code
|
|
3472
3515
|
};
|
|
3473
|
-
return { userData: i, sessionData:
|
|
3516
|
+
return { userData: i, sessionData: a };
|
|
3474
3517
|
}
|
|
3475
3518
|
/**
|
|
3476
3519
|
* Creates and emails a new one-time code.
|
|
@@ -3479,7 +3522,7 @@ class Ft extends re {
|
|
|
3479
3522
|
* @returns
|
|
3480
3523
|
*/
|
|
3481
3524
|
async reprepareConfiguration(e, t) {
|
|
3482
|
-
const r =
|
|
3525
|
+
const r = L.decodeData(t.data)["2fa"], i = this.code, a = /* @__PURE__ */ new Date(), n = new Date(a.getTime() + 1e3 * 60).getTime();
|
|
3483
3526
|
return {
|
|
3484
3527
|
userData: { factor2: r.factor2, otp: i },
|
|
3485
3528
|
secrets: {},
|
|
@@ -3585,7 +3628,7 @@ class Ft extends re {
|
|
|
3585
3628
|
return Array(+(r > 0 && r)).join("0") + e;
|
|
3586
3629
|
}
|
|
3587
3630
|
}
|
|
3588
|
-
class
|
|
3631
|
+
class xt extends be {
|
|
3589
3632
|
/**
|
|
3590
3633
|
* Create a new authenticator.
|
|
3591
3634
|
*
|
|
@@ -3678,7 +3721,7 @@ class Ot extends be {
|
|
|
3678
3721
|
async reprepareConfiguration(e, t) {
|
|
3679
3722
|
}
|
|
3680
3723
|
}
|
|
3681
|
-
class
|
|
3724
|
+
class Dt extends re {
|
|
3682
3725
|
/**
|
|
3683
3726
|
* Constructor
|
|
3684
3727
|
* @param appName this forms part of the QR code that users scan into
|
|
@@ -3705,7 +3748,7 @@ class Nt extends re {
|
|
|
3705
3748
|
async createSecret(e, t) {
|
|
3706
3749
|
t || (t = fe.generateSecret());
|
|
3707
3750
|
let r = "";
|
|
3708
|
-
return await
|
|
3751
|
+
return await Le.toDataURL(fe.keyuri(e, this.appName, t)).then((i) => {
|
|
3709
3752
|
r = i;
|
|
3710
3753
|
}).catch((i) => {
|
|
3711
3754
|
throw u.logger.debug(f({ err: i })), new o(
|
|
@@ -3715,7 +3758,7 @@ class Nt extends re {
|
|
|
3715
3758
|
}), { qrUrl: r, secret: t };
|
|
3716
3759
|
}
|
|
3717
3760
|
async getSecretFromSession(e, t) {
|
|
3718
|
-
const r =
|
|
3761
|
+
const r = L.decodeData(t.data);
|
|
3719
3762
|
if (!("totpsecret" in r))
|
|
3720
3763
|
throw new o(
|
|
3721
3764
|
l.Unauthorized,
|
|
@@ -3726,8 +3769,8 @@ class Nt extends re {
|
|
|
3726
3769
|
l.Unauthorized,
|
|
3727
3770
|
"TOTP factor name not in session"
|
|
3728
3771
|
);
|
|
3729
|
-
const i = r.totpsecret, { qrUrl:
|
|
3730
|
-
return { qrUrl:
|
|
3772
|
+
const i = r.totpsecret, { qrUrl: a, secret: n } = await this.createSecret(e, i);
|
|
3773
|
+
return { qrUrl: a, secret: n, factor2: r.factor2 };
|
|
3731
3774
|
}
|
|
3732
3775
|
/**
|
|
3733
3776
|
* Creates a shared secret and returns it, along with image data for the QR
|
|
@@ -3748,12 +3791,12 @@ class Nt extends re {
|
|
|
3748
3791
|
qr: t,
|
|
3749
3792
|
totpsecret: r,
|
|
3750
3793
|
factor2: this.factorName
|
|
3751
|
-
},
|
|
3794
|
+
}, a = {
|
|
3752
3795
|
username: e.username,
|
|
3753
3796
|
totpsecret: r,
|
|
3754
3797
|
factor2: this.factorName
|
|
3755
3798
|
};
|
|
3756
|
-
return { userData: i, sessionData:
|
|
3799
|
+
return { userData: i, sessionData: a };
|
|
3757
3800
|
}
|
|
3758
3801
|
/**
|
|
3759
3802
|
* For cases when the 2FA page was closed without completing. Returns the
|
|
@@ -3766,9 +3809,9 @@ class Nt extends re {
|
|
|
3766
3809
|
* `newSessionData` containing the same except `qr`.
|
|
3767
3810
|
*/
|
|
3768
3811
|
async reprepareConfiguration(e, t) {
|
|
3769
|
-
const { qrUrl: r, secret: i, factor2:
|
|
3812
|
+
const { qrUrl: r, secret: i, factor2: a } = await this.getSecretFromSession(e, t);
|
|
3770
3813
|
return {
|
|
3771
|
-
userData: { qr: r, totpsecret: i, factor2:
|
|
3814
|
+
userData: { qr: r, totpsecret: i, factor2: a },
|
|
3772
3815
|
secrets: { totpsecret: i },
|
|
3773
3816
|
newSessionData: void 0
|
|
3774
3817
|
};
|
|
@@ -3787,8 +3830,8 @@ class Nt extends re {
|
|
|
3787
3830
|
l.InvalidToken,
|
|
3788
3831
|
"TOTP secret or code not given"
|
|
3789
3832
|
);
|
|
3790
|
-
const i = r.otp,
|
|
3791
|
-
if (!fe.check(i,
|
|
3833
|
+
const i = r.otp, a = t.totpsecret;
|
|
3834
|
+
if (!fe.check(i, a))
|
|
3792
3835
|
throw new o(
|
|
3793
3836
|
l.InvalidToken,
|
|
3794
3837
|
"Invalid TOTP code"
|
|
@@ -3869,7 +3912,7 @@ class x {
|
|
|
3869
3912
|
* @param keyStorage : where to store email verification tokens
|
|
3870
3913
|
* @param options see {@link TokenEmailerOptions}
|
|
3871
3914
|
*/
|
|
3872
|
-
constructor(
|
|
3915
|
+
constructor(s, e, t = {}) {
|
|
3873
3916
|
h(this, "userStorage");
|
|
3874
3917
|
h(this, "keyStorage");
|
|
3875
3918
|
h(this, "views", "views");
|
|
@@ -3890,38 +3933,38 @@ class x {
|
|
|
3890
3933
|
h(this, "verifyEmailExpires", 60 * 60 * 24);
|
|
3891
3934
|
h(this, "passwordResetExpires", 60 * 60 * 24);
|
|
3892
3935
|
h(this, "render");
|
|
3893
|
-
this.userStorage =
|
|
3936
|
+
this.userStorage = s, this.keyStorage = e, w("siteUrl", m.String, this, t, "SITE_URL", !0), w("prefix", m.String, this, t, "PREFIX"), w("views", m.String, this, t, "VIEWS"), w("emailVerificationTextBody", m.String, this, t, "EMAIL_VERIFICATION_TEXT_BODY"), w("emailVerificationHtmlBody", m.String, this, t, "EMAIL_VERIFICATION_HTML_BODY"), w("emailVerificationSubject", m.String, this, t, "EMAIL_VERIFICATION_SUBJECT"), w("passwordResetTextBody", m.String, this, t, "PASSWORD_RESET_TEXT_BODY"), w("passwordResetHtmlBody", m.String, this, t, "PASSWORD_RESET_HTML_BODY"), w("passwordResetSubject", m.String, this, t, "PASSWORD_RESET_SUBJECT"), w("emailFrom", m.String, this, t, "EMAIL_FROM", !0), w("smtpHost", m.String, this, t, "SMTP_HOST", !0), w("smtpPort", m.Number, this, t, "SMTP_PORT"), w("smtpUsername", m.String, this, t, "SMTP_USERNAME"), w("smtpPassword", m.String, this, t, "SMTP_PASSWORD"), w("smtpUseTls", m.Boolean, this, t, "SMTP_USE_TLS"), w("verifyEmailExpires", m.Boolean, this, t, "VERIFY_EMAIL_EXPIRES"), w("passwordResetExpires", m.String, this, t, "PASSWORD_RESET_EXPIRES"), t.render ? this.render = t.render : W.configure(this.views, { autoescape: !0 });
|
|
3894
3937
|
}
|
|
3895
3938
|
createEmailer() {
|
|
3896
|
-
let
|
|
3897
|
-
return this.smtpUsername && (
|
|
3939
|
+
let s = {};
|
|
3940
|
+
return this.smtpUsername && (s.user = this.smtpUsername), this.smtpPassword && (s.pass = this.smtpPassword), Ee.createTransport({
|
|
3898
3941
|
host: this.smtpHost,
|
|
3899
3942
|
port: this.smtpPort,
|
|
3900
3943
|
secure: this.smtpUseTls,
|
|
3901
|
-
auth:
|
|
3944
|
+
auth: s
|
|
3902
3945
|
});
|
|
3903
3946
|
}
|
|
3904
3947
|
/**
|
|
3905
3948
|
* Produces a hash of the given email verification token with the
|
|
3906
3949
|
* correct prefix for inserting into storage.
|
|
3907
3950
|
*/
|
|
3908
|
-
static hashEmailVerificationToken(
|
|
3909
|
-
return U.emailVerificationToken + T.hash(
|
|
3951
|
+
static hashEmailVerificationToken(s) {
|
|
3952
|
+
return U.emailVerificationToken + T.hash(s);
|
|
3910
3953
|
}
|
|
3911
3954
|
/**
|
|
3912
3955
|
* Produces a hash of the given password reset token with the
|
|
3913
3956
|
* correct prefix for inserting into storage.
|
|
3914
3957
|
*/
|
|
3915
|
-
static hashPasswordResetToken(
|
|
3916
|
-
return U.passwordResetToken + T.hash(
|
|
3958
|
+
static hashPasswordResetToken(s) {
|
|
3959
|
+
return U.passwordResetToken + T.hash(s);
|
|
3917
3960
|
}
|
|
3918
|
-
async createAndSaveEmailVerificationToken(
|
|
3961
|
+
async createAndSaveEmailVerificationToken(s, e = "") {
|
|
3919
3962
|
let r = 0;
|
|
3920
|
-
const i = /* @__PURE__ */ new Date(),
|
|
3963
|
+
const i = /* @__PURE__ */ new Date(), a = new Date(i.getTime() + 1e3 * this.verifyEmailExpires);
|
|
3921
3964
|
for (; r < 10; ) {
|
|
3922
3965
|
let n = T.randomValue(ne), c = x.hashEmailVerificationToken(n);
|
|
3923
3966
|
try {
|
|
3924
|
-
return await this.keyStorage.saveKey(
|
|
3967
|
+
return await this.keyStorage.saveKey(s, c, i, a, e), n;
|
|
3925
3968
|
} catch {
|
|
3926
3969
|
n = T.randomValue(ne), c = x.hashEmailVerificationToken(n), r++;
|
|
3927
3970
|
}
|
|
@@ -3931,13 +3974,13 @@ class x {
|
|
|
3931
3974
|
/**
|
|
3932
3975
|
* Separated out for unit testing/mocking purposes
|
|
3933
3976
|
*/
|
|
3934
|
-
async _sendEmailVerificationToken(
|
|
3977
|
+
async _sendEmailVerificationToken(s, e, t) {
|
|
3935
3978
|
this.smtpUsername && this.smtpUsername, this.smtpPassword && this.smtpPassword;
|
|
3936
3979
|
let r = {
|
|
3937
3980
|
from: this.emailFrom,
|
|
3938
3981
|
to: e,
|
|
3939
3982
|
subject: this.emailVerificationSubject
|
|
3940
|
-
}, i = { token:
|
|
3983
|
+
}, i = { token: s, siteUrl: this.siteUrl, prefix: this.prefix };
|
|
3941
3984
|
return t && (i = { ...i, ...t }), this.emailVerificationTextBody && (r.text = this.render ? this.render(this.emailVerificationTextBody, i) : W.render(this.emailVerificationTextBody, i)), this.emailVerificationHtmlBody && (r.html = this.render ? this.render(this.emailVerificationHtmlBody, i) : W.render(this.emailVerificationHtmlBody, i)), (await this.createEmailer().sendMail(r)).messageId;
|
|
3942
3985
|
}
|
|
3943
3986
|
/**
|
|
@@ -3957,15 +4000,15 @@ class x {
|
|
|
3957
4000
|
* @param extraData : these extra variables will be passed to the Nunjucks
|
|
3958
4001
|
* templates
|
|
3959
4002
|
*/
|
|
3960
|
-
async sendEmailVerificationToken(
|
|
4003
|
+
async sendEmailVerificationToken(s, e = "", t = {}) {
|
|
3961
4004
|
if (!this.emailVerificationTextBody && !this.emailVerificationHtmlBody)
|
|
3962
4005
|
throw new o(
|
|
3963
4006
|
l.Configuration,
|
|
3964
4007
|
"Either emailVerificationTextBody or emailVerificationHtmlBody must be set to send email verification emails"
|
|
3965
4008
|
);
|
|
3966
|
-
let { user: r } = await this.userStorage.getUserById(
|
|
4009
|
+
let { user: r } = await this.userStorage.getUserById(s, { skipEmailVerifiedCheck: !0 }), i = e;
|
|
3967
4010
|
i != "" ? x.validateEmail(i) : (i = r.email ?? r.username, i || (i = r.username), x.validateEmail(i)), x.validateEmail(i);
|
|
3968
|
-
const
|
|
4011
|
+
const a = await this.createAndSaveEmailVerificationToken(s, e), n = await this._sendEmailVerificationToken(a, i, t);
|
|
3969
4012
|
u.logger.info(f({ msg: "Sent email verification email", emailMessageId: n, email: i }));
|
|
3970
4013
|
}
|
|
3971
4014
|
/**
|
|
@@ -3983,8 +4026,8 @@ class x {
|
|
|
3983
4026
|
* @returns the userid of the user the token is for and the email
|
|
3984
4027
|
* address the user is validating
|
|
3985
4028
|
*/
|
|
3986
|
-
async verifyEmailVerificationToken(
|
|
3987
|
-
const e = x.hashEmailVerificationToken(
|
|
4029
|
+
async verifyEmailVerificationToken(s) {
|
|
4030
|
+
const e = x.hashEmailVerificationToken(s);
|
|
3988
4031
|
let t = await this.keyStorage.getKey(e);
|
|
3989
4032
|
try {
|
|
3990
4033
|
if (!t.userid || !t.expires) throw new o(l.InvalidKey);
|
|
@@ -3995,24 +4038,24 @@ class x {
|
|
|
3995
4038
|
} finally {
|
|
3996
4039
|
}
|
|
3997
4040
|
}
|
|
3998
|
-
async deleteEmailVerificationToken(
|
|
4041
|
+
async deleteEmailVerificationToken(s) {
|
|
3999
4042
|
try {
|
|
4000
|
-
const e = x.hashEmailVerificationToken(
|
|
4043
|
+
const e = x.hashEmailVerificationToken(s);
|
|
4001
4044
|
await this.keyStorage.deleteKey(e);
|
|
4002
4045
|
} catch (e) {
|
|
4003
4046
|
const t = o.asCrossauthError(e);
|
|
4004
4047
|
u.logger.debug(f({ err: t }));
|
|
4005
4048
|
}
|
|
4006
4049
|
}
|
|
4007
|
-
async createAndSavePasswordResetToken(
|
|
4050
|
+
async createAndSavePasswordResetToken(s) {
|
|
4008
4051
|
let t = 0;
|
|
4009
4052
|
const r = /* @__PURE__ */ new Date(), i = new Date(r.getTime() + 1e3 * this.passwordResetExpires);
|
|
4010
4053
|
for (; t < 10; ) {
|
|
4011
|
-
let
|
|
4054
|
+
let a = T.randomValue(ne), n = x.hashPasswordResetToken(a);
|
|
4012
4055
|
try {
|
|
4013
|
-
return await this.keyStorage.saveKey(
|
|
4056
|
+
return await this.keyStorage.saveKey(s, n, r, i), a;
|
|
4014
4057
|
} catch {
|
|
4015
|
-
|
|
4058
|
+
a = T.randomValue(ne), n = x.hashPasswordResetToken(a), t++;
|
|
4016
4059
|
}
|
|
4017
4060
|
}
|
|
4018
4061
|
throw new o(l.Connection, "failed creating a unique key");
|
|
@@ -4031,9 +4074,9 @@ class x {
|
|
|
4031
4074
|
* @param token the token to validate
|
|
4032
4075
|
* @returns the user that the token is for
|
|
4033
4076
|
*/
|
|
4034
|
-
async verifyPasswordResetToken(
|
|
4035
|
-
const e = x.hashPasswordResetToken(
|
|
4036
|
-
u.logger.debug("verifyPasswordResetToken " +
|
|
4077
|
+
async verifyPasswordResetToken(s) {
|
|
4078
|
+
const e = x.hashPasswordResetToken(s);
|
|
4079
|
+
u.logger.debug("verifyPasswordResetToken " + s + " " + e);
|
|
4037
4080
|
let t = await this.keyStorage.getKey(e);
|
|
4038
4081
|
if (!t.userid) throw new o(l.InvalidKey);
|
|
4039
4082
|
if (!t.userid || !t.expires) throw new o(l.InvalidKey);
|
|
@@ -4049,7 +4092,7 @@ class x {
|
|
|
4049
4092
|
/**
|
|
4050
4093
|
* Separated out for unit testing/mocking purposes
|
|
4051
4094
|
*/
|
|
4052
|
-
async _sendPasswordResetToken(
|
|
4095
|
+
async _sendPasswordResetToken(s, e, t) {
|
|
4053
4096
|
if (!this.emailVerificationTextBody && !this.emailVerificationHtmlBody)
|
|
4054
4097
|
throw new o(
|
|
4055
4098
|
l.Configuration,
|
|
@@ -4060,7 +4103,7 @@ class x {
|
|
|
4060
4103
|
from: this.emailFrom,
|
|
4061
4104
|
to: e,
|
|
4062
4105
|
subject: this.passwordResetSubject
|
|
4063
|
-
}, i = { token:
|
|
4106
|
+
}, i = { token: s, siteUrl: this.siteUrl, prefix: this.prefix };
|
|
4064
4107
|
return t && (i = { ...i, ...t }), this.passwordResetTextBody && (r.text = this.render ? this.render(this.passwordResetTextBody, i) : W.render(this.passwordResetTextBody, i)), this.passwordResetHtmlBody && (r.html = this.render ? this.render(this.passwordResetHtmlBody, i) : W.render(this.passwordResetHtmlBody, i)), (await this.createEmailer().sendMail(r)).messageId;
|
|
4065
4108
|
}
|
|
4066
4109
|
/**
|
|
@@ -4069,20 +4112,20 @@ class x {
|
|
|
4069
4112
|
* @param extraData : these extra variables will be passed to the Nunjucks
|
|
4070
4113
|
* templates
|
|
4071
4114
|
*/
|
|
4072
|
-
async sendPasswordResetToken(
|
|
4115
|
+
async sendPasswordResetToken(s, e = {}, t = !1) {
|
|
4073
4116
|
if (!this.passwordResetTextBody && !this.passwordResetHtmlBody)
|
|
4074
4117
|
throw new o(
|
|
4075
4118
|
l.Configuration,
|
|
4076
4119
|
"Either passwordResetTextBody or passwordResetTextBody must be set to send email verification emails"
|
|
4077
4120
|
);
|
|
4078
|
-
let { user: r } = await this.userStorage.getUserById(
|
|
4121
|
+
let { user: r } = await this.userStorage.getUserById(s, {
|
|
4079
4122
|
skipActiveCheck: !0
|
|
4080
4123
|
});
|
|
4081
4124
|
if (!t && r.state != E.active && r.state != E.passwordResetNeeded && r.state != E.passwordAndFactor2ResetNeeded)
|
|
4082
4125
|
throw new o(l.UserNotActive);
|
|
4083
4126
|
let i = (r.email ?? r.username).toLowerCase();
|
|
4084
4127
|
i || (i = r.username.toLowerCase()), x.validateEmail(i);
|
|
4085
|
-
const
|
|
4128
|
+
const a = await this.createAndSavePasswordResetToken(s), n = await this._sendPasswordResetToken(a, i, e);
|
|
4086
4129
|
u.logger.info(f({ msg: "Sent password reset email", emailMessageId: n, email: i }));
|
|
4087
4130
|
}
|
|
4088
4131
|
/**
|
|
@@ -4090,8 +4133,8 @@ class x {
|
|
|
4090
4133
|
* @param email the email to validate
|
|
4091
4134
|
* @returns true or false
|
|
4092
4135
|
*/
|
|
4093
|
-
static isEmailValid(
|
|
4094
|
-
return String(
|
|
4136
|
+
static isEmailValid(s) {
|
|
4137
|
+
return String(s).toLowerCase().match(
|
|
4095
4138
|
/^(([^<>()[\]\.,;:\s@"]+(\.[^<>()[\]\.,;:\s@"]+)*)|.(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
|
|
4096
4139
|
) != null;
|
|
4097
4140
|
}
|
|
@@ -4102,15 +4145,15 @@ class x {
|
|
|
4102
4145
|
*
|
|
4103
4146
|
* @param email the email to validate
|
|
4104
4147
|
*/
|
|
4105
|
-
static validateEmail(
|
|
4106
|
-
if (
|
|
4148
|
+
static validateEmail(s) {
|
|
4149
|
+
if (s == null || !x.isEmailValid(s)) throw new o(l.InvalidEmail);
|
|
4107
4150
|
}
|
|
4108
4151
|
}
|
|
4109
|
-
const
|
|
4110
|
-
function
|
|
4152
|
+
const _e = 16, ke = 16;
|
|
4153
|
+
function Bt(S) {
|
|
4111
4154
|
return {
|
|
4112
|
-
...
|
|
4113
|
-
path:
|
|
4155
|
+
...S,
|
|
4156
|
+
path: S.path ?? "/"
|
|
4114
4157
|
};
|
|
4115
4158
|
}
|
|
4116
4159
|
class rt {
|
|
@@ -4120,7 +4163,7 @@ class rt {
|
|
|
4120
4163
|
* @param options configurable options. See {@link DoubleSubmitCsrfTokenOptions}. The
|
|
4121
4164
|
* expires and maxAge options are ignored (cookies are session-only).
|
|
4122
4165
|
*/
|
|
4123
|
-
constructor(
|
|
4166
|
+
constructor(s = {}) {
|
|
4124
4167
|
// header settings
|
|
4125
4168
|
/** name of the CRSF HTTP header */
|
|
4126
4169
|
h(this, "headerName", "X-CROSSAUTH-CSRF");
|
|
@@ -4134,7 +4177,7 @@ class rt {
|
|
|
4134
4177
|
h(this, "sameSite", "lax");
|
|
4135
4178
|
// hasher settings
|
|
4136
4179
|
h(this, "secret", "");
|
|
4137
|
-
w("headerName", m.String, this,
|
|
4180
|
+
w("headerName", m.String, this, s, "CSRF_HEADER_NAME"), w("cookieName", m.String, this, s, "CSRF_COOKIE_NAME"), w("domain", m.String, this, s, "CSRF_COOKIE_DOMAIN"), w("httpOnly", m.Boolean, this, s, "CSRF_COOKIE_HTTPONLY"), w("path", m.String, this, s, "CSRF_COOKIE_PATH"), w("secure", m.Boolean, this, s, "CSRF_COOKIE_SECURE"), w("sameSite", m.String, this, s, "CSRF_COOKIE_SAMESITE"), w("secret", m.String, this, s, "SECRET", !0);
|
|
4138
4181
|
}
|
|
4139
4182
|
/**
|
|
4140
4183
|
* Creates a session key and saves in storage
|
|
@@ -4144,7 +4187,7 @@ class rt {
|
|
|
4144
4187
|
* @returns a random CSRF token.
|
|
4145
4188
|
*/
|
|
4146
4189
|
createCsrfToken() {
|
|
4147
|
-
return T.randomValue(
|
|
4190
|
+
return T.randomValue(_e);
|
|
4148
4191
|
}
|
|
4149
4192
|
/**
|
|
4150
4193
|
* Returns a {@link Cookie } object with the given session key.
|
|
@@ -4152,8 +4195,8 @@ class rt {
|
|
|
4152
4195
|
* @param token the value of the csrf token, with signature
|
|
4153
4196
|
* @returns a {@link Cookie } object,
|
|
4154
4197
|
*/
|
|
4155
|
-
makeCsrfCookie(
|
|
4156
|
-
const e = T.signSecureToken(
|
|
4198
|
+
makeCsrfCookie(s) {
|
|
4199
|
+
const e = T.signSecureToken(s, this.secret);
|
|
4157
4200
|
let t = {};
|
|
4158
4201
|
return this.domain && (t.domain = this.domain), this.path && (t.path = this.path), t.sameSite = this.sameSite, this.httpOnly && (t.httpOnly = this.httpOnly), this.secure && (t.secure = this.secure), {
|
|
4159
4202
|
name: this.cookieName,
|
|
@@ -4161,11 +4204,11 @@ class rt {
|
|
|
4161
4204
|
options: t
|
|
4162
4205
|
};
|
|
4163
4206
|
}
|
|
4164
|
-
makeCsrfFormOrHeaderToken(
|
|
4165
|
-
return this.maskCsrfToken(
|
|
4207
|
+
makeCsrfFormOrHeaderToken(s) {
|
|
4208
|
+
return this.maskCsrfToken(s);
|
|
4166
4209
|
}
|
|
4167
|
-
unsignCookie(
|
|
4168
|
-
return T.unsignSecureToken(
|
|
4210
|
+
unsignCookie(s) {
|
|
4211
|
+
return T.unsignSecureToken(s, this.secret);
|
|
4169
4212
|
}
|
|
4170
4213
|
/**
|
|
4171
4214
|
* Takes a session ID and creates a string representation of the cookie (value of the HTTP `Cookie` header).
|
|
@@ -4173,16 +4216,16 @@ class rt {
|
|
|
4173
4216
|
* @param cookieValue the value to put in the cookie
|
|
4174
4217
|
* @returns a string representation of the cookie and options.
|
|
4175
4218
|
*/
|
|
4176
|
-
makeCsrfCookieString(
|
|
4177
|
-
let e = this.cookieName + "=" +
|
|
4219
|
+
makeCsrfCookieString(s) {
|
|
4220
|
+
let e = this.cookieName + "=" + s + "; SameSite=" + this.sameSite;
|
|
4178
4221
|
return this.domain && (e += "; " + this.domain), this.path && (e += "; " + this.path), this.httpOnly && (e += "; httpOnly"), this.secure && (e += "; secure"), e;
|
|
4179
4222
|
}
|
|
4180
|
-
maskCsrfToken(
|
|
4181
|
-
const e = T.randomValue(
|
|
4223
|
+
maskCsrfToken(s) {
|
|
4224
|
+
const e = T.randomValue(_e), t = T.xor(s, e);
|
|
4182
4225
|
return e + "." + t;
|
|
4183
4226
|
}
|
|
4184
|
-
unmaskCsrfToken(
|
|
4185
|
-
const e =
|
|
4227
|
+
unmaskCsrfToken(s) {
|
|
4228
|
+
const e = s.split(".");
|
|
4186
4229
|
if (e.length != 2) throw new o(l.InvalidCsrf, "CSRF token in header or form not in correct format");
|
|
4187
4230
|
const t = e[0], r = e[1];
|
|
4188
4231
|
return T.xor(r, t);
|
|
@@ -4198,16 +4241,16 @@ class rt {
|
|
|
4198
4241
|
* @param formOrHeaderValue the value from the csrfToken form header or the X-CROSSAUTH-CSRF header.
|
|
4199
4242
|
* @throws {@link @crossauth/common!CrossauthError} with {@link @crossauth/common!ErrorCode} of `InvalidKey`
|
|
4200
4243
|
*/
|
|
4201
|
-
validateDoubleSubmitCsrfToken(
|
|
4244
|
+
validateDoubleSubmitCsrfToken(s, e) {
|
|
4202
4245
|
const t = this.unmaskCsrfToken(e);
|
|
4203
4246
|
let r;
|
|
4204
4247
|
try {
|
|
4205
|
-
r = T.unsignSecureToken(
|
|
4248
|
+
r = T.unsignSecureToken(s, this.secret);
|
|
4206
4249
|
} catch (i) {
|
|
4207
4250
|
throw u.logger.error(f({ err: i })), new o(l.InvalidCsrf, "Invalid CSRF cookie");
|
|
4208
4251
|
}
|
|
4209
4252
|
if (r != t)
|
|
4210
|
-
throw u.logger.warn(f({ msg: "Invalid CSRF token received - form/header value does not match", csrfCookieHash: T.hash(
|
|
4253
|
+
throw u.logger.warn(f({ msg: "Invalid CSRF token received - form/header value does not match", csrfCookieHash: T.hash(s) })), new o(l.InvalidCsrf);
|
|
4211
4254
|
}
|
|
4212
4255
|
/**
|
|
4213
4256
|
* Validates the passed CSRF cookie (doesn't check it matches the token, just that the cookie is valid).
|
|
@@ -4219,9 +4262,9 @@ class rt {
|
|
|
4219
4262
|
* @param cookieValue the CSRF cookie value to validate.
|
|
4220
4263
|
* @throws {@link @crossauth/common!CrossauthError} with {@link @crossauth/common!ErrorCode} of `InvalidKey`
|
|
4221
4264
|
*/
|
|
4222
|
-
validateCsrfCookie(
|
|
4265
|
+
validateCsrfCookie(s) {
|
|
4223
4266
|
try {
|
|
4224
|
-
return T.unsignSecureToken(
|
|
4267
|
+
return T.unsignSecureToken(s, this.secret);
|
|
4225
4268
|
} catch (e) {
|
|
4226
4269
|
throw u.logger.error(f({ err: e })), new o(l.InvalidCsrf, "Invalid CSRF cookie");
|
|
4227
4270
|
}
|
|
@@ -4235,7 +4278,7 @@ class D {
|
|
|
4235
4278
|
* @param options configurable options. See {@link SessionCookieOptions}. The
|
|
4236
4279
|
* expires option is ignored (cookies are session-only).
|
|
4237
4280
|
*/
|
|
4238
|
-
constructor(
|
|
4281
|
+
constructor(s, e = {}) {
|
|
4239
4282
|
h(this, "userStorage");
|
|
4240
4283
|
h(this, "keyStorage");
|
|
4241
4284
|
/** This is set from input options. Number of seconds before an
|
|
@@ -4247,8 +4290,8 @@ class D {
|
|
|
4247
4290
|
// cookie settings
|
|
4248
4291
|
/** Name of the CSRF Cookie, set from input options */
|
|
4249
4292
|
h(this, "cookieName", "SESSIONID");
|
|
4250
|
-
h(this, "maxAge", 60 * 60 * 24 *
|
|
4251
|
-
//
|
|
4293
|
+
h(this, "maxAge", 60 * 60 * 24 * 30);
|
|
4294
|
+
// 30 days
|
|
4252
4295
|
h(this, "domain");
|
|
4253
4296
|
h(this, "httpOnly", !1);
|
|
4254
4297
|
h(this, "path", "/");
|
|
@@ -4256,11 +4299,11 @@ class D {
|
|
|
4256
4299
|
h(this, "sameSite", "lax");
|
|
4257
4300
|
// hasher settings
|
|
4258
4301
|
h(this, "secret", "");
|
|
4259
|
-
e.userStorage && (this.userStorage = e.userStorage), this.keyStorage =
|
|
4302
|
+
e.userStorage && (this.userStorage = e.userStorage), this.keyStorage = s, w("idleTimeout", m.Number, this, e, "SESSION_IDLE_TIMEOUT"), w("persist", m.Boolean, this, e, "PERSIST_SESSION_ID"), this.filterFunction = e.filterFunction, w("cookieName", m.String, this, e, "SESSION_COOKIE_NAME"), w("maxAge", m.String, this, e, "SESSION_COOKIE_MAX_AGE"), w("domain", m.String, this, e, "SESSION_COOKIE_DOMAIN"), w("httpOnly", m.Boolean, this, e, "SESSIONCOOKIE_HTTPONLY"), w("path", m.String, this, e, "SESSION_COOKIE_PATH"), w("secure", m.Boolean, this, e, "SESSION_COOKIE_SECURE"), w("sameSite", m.String, this, e, "SESSION_COOKIE_SAMESITE"), w("secret", m.String, this, e, "SECRET", !0);
|
|
4260
4303
|
}
|
|
4261
|
-
expiry(
|
|
4304
|
+
expiry(s) {
|
|
4262
4305
|
let e;
|
|
4263
|
-
return this.maxAge > 0 && (e = /* @__PURE__ */ new Date(), e.setTime(
|
|
4306
|
+
return this.maxAge > 0 && (e = /* @__PURE__ */ new Date(), e.setTime(s.getTime() + this.maxAge * 1e3)), e;
|
|
4264
4307
|
}
|
|
4265
4308
|
///// Session IDs
|
|
4266
4309
|
/**
|
|
@@ -4269,8 +4312,8 @@ class D {
|
|
|
4269
4312
|
* @param sessionId the session ID to hash
|
|
4270
4313
|
* @returns a base64-url-encoded string that can go into the storage
|
|
4271
4314
|
*/
|
|
4272
|
-
static hashSessionId(
|
|
4273
|
-
return U.session + T.hash(
|
|
4315
|
+
static hashSessionId(s) {
|
|
4316
|
+
return U.session + T.hash(s);
|
|
4274
4317
|
}
|
|
4275
4318
|
/**
|
|
4276
4319
|
* Creates a session key and saves in storage
|
|
@@ -4288,27 +4331,27 @@ class D {
|
|
|
4288
4331
|
* {@link @crossauth/common!ErrorCode} `KeyExists` if maximum
|
|
4289
4332
|
* attempts exceeded trying to create a unique session id
|
|
4290
4333
|
*/
|
|
4291
|
-
async createSessionKey(
|
|
4292
|
-
let r = 0, i = T.randomValue(
|
|
4293
|
-
const
|
|
4294
|
-
let n = this.expiry(
|
|
4334
|
+
async createSessionKey(s, e = {}) {
|
|
4335
|
+
let r = 0, i = T.randomValue(ke);
|
|
4336
|
+
const a = /* @__PURE__ */ new Date();
|
|
4337
|
+
let n = this.expiry(a), c = !1;
|
|
4295
4338
|
for (; r < 10 && !c; ) {
|
|
4296
4339
|
const d = D.hashSessionId(i);
|
|
4297
4340
|
try {
|
|
4298
|
-
this.idleTimeout > 0 &&
|
|
4341
|
+
this.idleTimeout > 0 && s && (e = { ...e, lastActivity: /* @__PURE__ */ new Date() }), await this.keyStorage.saveKey(s, d, a, n, void 0, e), c = !0;
|
|
4299
4342
|
} catch (g) {
|
|
4300
4343
|
let y = o.asCrossauthError(g);
|
|
4301
4344
|
if (y.code == l.KeyExists || y.code == l.InvalidKey) {
|
|
4302
|
-
if (r++, i = T.randomValue(
|
|
4345
|
+
if (r++, i = T.randomValue(ke), r > 10)
|
|
4303
4346
|
throw u.logger.error(f({ msg: "Max attempts exceeded trying to create session ID" })), new o(l.KeyExists);
|
|
4304
4347
|
} else
|
|
4305
4348
|
throw u.logger.debug(f({ err: g })), g;
|
|
4306
4349
|
}
|
|
4307
4350
|
}
|
|
4308
4351
|
return {
|
|
4309
|
-
userid:
|
|
4352
|
+
userid: s,
|
|
4310
4353
|
value: i,
|
|
4311
|
-
created:
|
|
4354
|
+
created: a,
|
|
4312
4355
|
expires: n
|
|
4313
4356
|
};
|
|
4314
4357
|
}
|
|
@@ -4321,9 +4364,9 @@ class D {
|
|
|
4321
4364
|
* @param persist if passed, overrides the persistSessionId setting
|
|
4322
4365
|
* @returns a {@link Cookie } object,
|
|
4323
4366
|
*/
|
|
4324
|
-
makeCookie(
|
|
4325
|
-
let t = T.signSecureToken(
|
|
4326
|
-
return e == null && (e = this.persist), this.domain && (r.domain = this.domain),
|
|
4367
|
+
makeCookie(s, e) {
|
|
4368
|
+
let t = T.signSecureToken(s.value, this.secret), r = {};
|
|
4369
|
+
return e == null && (e = this.persist), this.domain && (r.domain = this.domain), s.expires && e && (r.expires = s.expires), this.path && (r.path = this.path), r.sameSite = this.sameSite, this.httpOnly && (r.httpOnly = this.httpOnly), this.secure && (r.secure = this.secure), {
|
|
4327
4370
|
name: this.cookieName,
|
|
4328
4371
|
value: t,
|
|
4329
4372
|
options: r
|
|
@@ -4336,9 +4379,9 @@ class D {
|
|
|
4336
4379
|
* @param cookie the cookie vlaues to make a string from
|
|
4337
4380
|
* @returns a string representation of the cookie and options.
|
|
4338
4381
|
*/
|
|
4339
|
-
makeCookieString(
|
|
4340
|
-
let e =
|
|
4341
|
-
return this.sameSite && (e += "; SameSite=" + this.sameSite),
|
|
4382
|
+
makeCookieString(s) {
|
|
4383
|
+
let e = s.name + "=" + s.value;
|
|
4384
|
+
return this.sameSite && (e += "; SameSite=" + this.sameSite), s.options.expires && (e += "; expires=" + new Date(s.options.expires).toUTCString()), this.domain && (e += "; domain=" + this.domain), this.path && (e += "; path=" + this.path), this.httpOnly && (e += "; httpOnly"), this.secure && (e += "; secure"), e;
|
|
4342
4385
|
}
|
|
4343
4386
|
/**
|
|
4344
4387
|
* Updates a session record in storage
|
|
@@ -4347,9 +4390,9 @@ class D {
|
|
|
4347
4390
|
* @throws {@link @crossauth/common!CrossauthError} if the session does
|
|
4348
4391
|
* not exist.
|
|
4349
4392
|
*/
|
|
4350
|
-
async updateSessionKey(
|
|
4351
|
-
if (!
|
|
4352
|
-
|
|
4393
|
+
async updateSessionKey(s) {
|
|
4394
|
+
if (!s.value) throw new o(l.InvalidKey, "No session when updating activity");
|
|
4395
|
+
s.value = D.hashSessionId(s.value), await this.keyStorage.updateKey(s);
|
|
4353
4396
|
}
|
|
4354
4397
|
/**
|
|
4355
4398
|
* Unsigns a cookie and returns the original value.
|
|
@@ -4358,8 +4401,8 @@ class D {
|
|
|
4358
4401
|
* @throws {@link @crossauth/common!CrossauthError} if the signature
|
|
4359
4402
|
* is invalid.
|
|
4360
4403
|
*/
|
|
4361
|
-
unsignCookie(
|
|
4362
|
-
return T.unsignSecureToken(
|
|
4404
|
+
unsignCookie(s) {
|
|
4405
|
+
return T.unsignSecureToken(s, this.secret);
|
|
4363
4406
|
}
|
|
4364
4407
|
/**
|
|
4365
4408
|
* Returns the user matching the given session key in session storage, or throws an exception.
|
|
@@ -4374,8 +4417,8 @@ class D {
|
|
|
4374
4417
|
* sessionId
|
|
4375
4418
|
* @throws a {@link @crossauth/common!CrossauthError } with {@link @crossauth/common!ErrorCode } set to `InvalidSessionId` or `Expired`.
|
|
4376
4419
|
*/
|
|
4377
|
-
async getUserForSessionId(
|
|
4378
|
-
const t = await this.getSessionKey(
|
|
4420
|
+
async getUserForSessionId(s, e) {
|
|
4421
|
+
const t = await this.getSessionKey(s);
|
|
4379
4422
|
if (!this.userStorage) return { key: t, user: void 0 };
|
|
4380
4423
|
if (t.userid) {
|
|
4381
4424
|
let { user: r } = await this.userStorage.getUserById(t.userid, e);
|
|
@@ -4396,14 +4439,14 @@ class D {
|
|
|
4396
4439
|
* {@link @crossauth/common!ErrorCode } set to `InvalidSessionId`,
|
|
4397
4440
|
* `Expired` or `UserNotExist`.
|
|
4398
4441
|
*/
|
|
4399
|
-
async getSessionKey(
|
|
4400
|
-
const e = Date.now(), t = D.hashSessionId(
|
|
4401
|
-
if (r.value =
|
|
4402
|
-
throw u.logger.warn(f({ msg: "Session id in cookie expired in key storage", hashedSessionCookie: T.hash(
|
|
4442
|
+
async getSessionKey(s) {
|
|
4443
|
+
const e = Date.now(), t = D.hashSessionId(s), r = await this.keyStorage.getKey(t);
|
|
4444
|
+
if (r.value = s, r.expires && e > r.expires.getTime())
|
|
4445
|
+
throw u.logger.warn(f({ msg: "Session id in cookie expired in key storage", hashedSessionCookie: T.hash(s) })), new o(l.Expired);
|
|
4403
4446
|
if (r.userid && this.idleTimeout > 0 && r.lastactive && e > r.lastactive.getTime() + this.idleTimeout * 1e3)
|
|
4404
|
-
throw u.logger.warn(f({ msg: "Session cookie with expired idle time received", hashedSessionCookie: T.hash(
|
|
4447
|
+
throw u.logger.warn(f({ msg: "Session cookie with expired idle time received", hashedSessionCookie: T.hash(s) })), new o(l.Expired);
|
|
4405
4448
|
if (this.filterFunction && !this.filterFunction(r))
|
|
4406
|
-
throw u.logger.warn(f({ msg: "Filter function on session id in cookie failed", hashedSessionCookie: T.hash(
|
|
4449
|
+
throw u.logger.warn(f({ msg: "Filter function on session id in cookie failed", hashedSessionCookie: T.hash(s) })), new o(l.InvalidKey);
|
|
4407
4450
|
return r;
|
|
4408
4451
|
}
|
|
4409
4452
|
/**
|
|
@@ -4411,18 +4454,18 @@ class D {
|
|
|
4411
4454
|
* @param userid the user to delete keys for
|
|
4412
4455
|
* @param except if defined, don't delete this key
|
|
4413
4456
|
*/
|
|
4414
|
-
async deleteAllForUser(
|
|
4415
|
-
e && (e = D.hashSessionId(e)), await this.keyStorage.deleteAllForUser(
|
|
4457
|
+
async deleteAllForUser(s, e) {
|
|
4458
|
+
e && (e = D.hashSessionId(e)), await this.keyStorage.deleteAllForUser(s, U.session, e);
|
|
4416
4459
|
}
|
|
4417
4460
|
}
|
|
4418
|
-
class
|
|
4461
|
+
class Lt {
|
|
4419
4462
|
/**
|
|
4420
4463
|
* Constructor
|
|
4421
4464
|
* @param keyStorage the {@link KeyStorage} instance to use, eg {@link PrismaKeyStorage}.
|
|
4422
4465
|
* @param authenticators authenticators used to validate users, eg {@link LocalPasswordAuthenticatorOptions }.
|
|
4423
4466
|
* @param options optional parameters for authentication. See {@link SessionManagerOptions }.
|
|
4424
4467
|
*/
|
|
4425
|
-
constructor(
|
|
4468
|
+
constructor(s, e, t = {}) {
|
|
4426
4469
|
h(this, "userStorage");
|
|
4427
4470
|
h(this, "keyStorage");
|
|
4428
4471
|
h(this, "emailTokenStorage");
|
|
@@ -4434,7 +4477,7 @@ class xt {
|
|
|
4434
4477
|
h(this, "enablePasswordReset", !1);
|
|
4435
4478
|
h(this, "tokenEmailer");
|
|
4436
4479
|
h(this, "allowedFactor2", []);
|
|
4437
|
-
t.userStorage && (this.userStorage = t.userStorage), this.keyStorage =
|
|
4480
|
+
t.userStorage && (this.userStorage = t.userStorage), this.keyStorage = s, this.authenticators = e;
|
|
4438
4481
|
for (let r in this.authenticators)
|
|
4439
4482
|
this.authenticators[r].factorName = r;
|
|
4440
4483
|
if (this.session = new D(this.keyStorage, { ...t == null ? void 0 : t.sessionCookieOptions, ...t ?? {} }), this.csrfTokens = new rt({ ...t == null ? void 0 : t.doubleSubmitCookieOptions, ...t ?? {} }), w("allowedFactor2", m.JsonArray, this, t, "ALLOWED_FACTOR2"), w("enableEmailVerification", m.Boolean, this, t, "ENABLE_EMAIL_VERIFICATION"), w("enablePasswordReset", m.Boolean, this, t, "ENABLE_PASSWORD_RESET"), this.emailTokenStorage = this.keyStorage, this.userStorage && (this.enableEmailVerification || this.enablePasswordReset)) {
|
|
@@ -4493,13 +4536,13 @@ class xt {
|
|
|
4493
4536
|
* {@link @crossauth/common!ErrorCode} of `Connection`, `UserNotValid`,
|
|
4494
4537
|
* `PasswordNotMatch` or `UserNotExist`.
|
|
4495
4538
|
*/
|
|
4496
|
-
async login(
|
|
4539
|
+
async login(s, e, t = {}, r, i, a = !1) {
|
|
4497
4540
|
if (!this.userStorage) throw new o(l.Configuration, "Cannot call login if no user storage provided");
|
|
4498
4541
|
let n;
|
|
4499
4542
|
if (i)
|
|
4500
4543
|
n = (await this.userStorage.getUserByUsername(i.username, { skipActiveCheck: !0, skipEmailVerifiedCheck: !0 })).secrets;
|
|
4501
4544
|
else {
|
|
4502
|
-
let p = await this.userStorage.getUserByUsername(
|
|
4545
|
+
let p = await this.userStorage.getUserByUsername(s, { skipActiveCheck: !0, skipEmailVerifiedCheck: !0 });
|
|
4503
4546
|
if (n = p.secrets, i = p.user, !i) throw new o(l.UserNotExist);
|
|
4504
4547
|
await this.authenticators[i.factor1].authenticateUser(i, n, e);
|
|
4505
4548
|
}
|
|
@@ -4508,7 +4551,7 @@ class xt {
|
|
|
4508
4551
|
c = (await this.createAnonymousSession({ data: JSON.stringify({ passwordchange: { username: i.username } }) })).sessionCookie;
|
|
4509
4552
|
else if (i.state == E.factor2ResetNeeded)
|
|
4510
4553
|
c = (await this.createAnonymousSession({ data: JSON.stringify({ factor2change: { username: i.username } }) })).sessionCookie;
|
|
4511
|
-
else if (!
|
|
4554
|
+
else if (!a && i.factor2 && i.factor2 != "") {
|
|
4512
4555
|
const { sessionCookie: p } = await this.initiateTwoFactorLogin(i);
|
|
4513
4556
|
c = p;
|
|
4514
4557
|
} else {
|
|
@@ -4522,7 +4565,7 @@ class xt {
|
|
|
4522
4565
|
U.passwordResetToken
|
|
4523
4566
|
);
|
|
4524
4567
|
} catch (p) {
|
|
4525
|
-
u.logger.warn(f({ msg: "Couldn't delete password reset tokens while logging in", user:
|
|
4568
|
+
u.logger.warn(f({ msg: "Couldn't delete password reset tokens while logging in", user: s })), u.logger.debug(f({ err: p }));
|
|
4526
4569
|
}
|
|
4527
4570
|
return {
|
|
4528
4571
|
sessionCookie: c,
|
|
@@ -4539,8 +4582,8 @@ class xt {
|
|
|
4539
4582
|
* @returns a cookie with the session ID, a cookie with the CSRF token
|
|
4540
4583
|
* and the CSRF value to put in the form or header value.
|
|
4541
4584
|
*/
|
|
4542
|
-
async createAnonymousSession(
|
|
4543
|
-
const e = await this.session.createSessionKey(void 0,
|
|
4585
|
+
async createAnonymousSession(s = {}) {
|
|
4586
|
+
const e = await this.session.createSessionKey(void 0, s), t = this.session.makeCookie(e, !1);
|
|
4544
4587
|
let { csrfCookie: r, csrfFormOrHeaderValue: i } = await this.createCsrfToken();
|
|
4545
4588
|
return {
|
|
4546
4589
|
sessionCookie: t,
|
|
@@ -4557,8 +4600,8 @@ class xt {
|
|
|
4557
4600
|
* @throws {@link @crossauth/common!CrossauthError} with
|
|
4558
4601
|
* {@link @crossauth/common!ErrorCode} of `Connection`
|
|
4559
4602
|
*/
|
|
4560
|
-
async logout(
|
|
4561
|
-
const e = await this.session.getSessionKey(
|
|
4603
|
+
async logout(s) {
|
|
4604
|
+
const e = await this.session.getSessionKey(s);
|
|
4562
4605
|
return await this.keyStorage.deleteKey(D.hashSessionId(e.value));
|
|
4563
4606
|
}
|
|
4564
4607
|
/**
|
|
@@ -4570,8 +4613,8 @@ class xt {
|
|
|
4570
4613
|
* @throws {@link @crossauth/common!CrossauthError} with
|
|
4571
4614
|
* {@link @crossauth/common!ErrorCode} of `Connection`
|
|
4572
4615
|
*/
|
|
4573
|
-
async logoutFromAll(
|
|
4574
|
-
return this.session.deleteAllForUser(
|
|
4616
|
+
async logoutFromAll(s, e) {
|
|
4617
|
+
return this.session.deleteAllForUser(s, e);
|
|
4575
4618
|
}
|
|
4576
4619
|
/**
|
|
4577
4620
|
* Returns the user (without secrets) matching the given session key.
|
|
@@ -4585,8 +4628,8 @@ class xt {
|
|
|
4585
4628
|
* `InvalidSessionId`
|
|
4586
4629
|
* `UserNotExist` or `Expired`.
|
|
4587
4630
|
*/
|
|
4588
|
-
async userForSessionId(
|
|
4589
|
-
return await this.session.getUserForSessionId(
|
|
4631
|
+
async userForSessionId(s) {
|
|
4632
|
+
return await this.session.getUserForSessionId(s);
|
|
4590
4633
|
}
|
|
4591
4634
|
/**
|
|
4592
4635
|
* Returns the data object for a session key, or undefined, as a JSON string
|
|
@@ -4600,9 +4643,9 @@ class xt {
|
|
|
4600
4643
|
* {@link @crossauth/common!ErrorCode} of `Connection`, `InvalidSessionId`
|
|
4601
4644
|
* `UserNotExist` or `Expired`.
|
|
4602
4645
|
*/
|
|
4603
|
-
async dataStringForSessionId(
|
|
4646
|
+
async dataStringForSessionId(s) {
|
|
4604
4647
|
try {
|
|
4605
|
-
let { key: e } = await this.session.getUserForSessionId(
|
|
4648
|
+
let { key: e } = await this.session.getUserForSessionId(s);
|
|
4606
4649
|
return e.data;
|
|
4607
4650
|
} catch (e) {
|
|
4608
4651
|
let t = o.asCrossauthError(e);
|
|
@@ -4625,8 +4668,8 @@ class xt {
|
|
|
4625
4668
|
* {@link @crossauth/common!ErrorCode} of `Connection`, `InvalidSessionId`
|
|
4626
4669
|
* `UserNotExist` or `Expired`.
|
|
4627
4670
|
*/
|
|
4628
|
-
async dataForSessionId(
|
|
4629
|
-
const e = await this.dataStringForSessionId(
|
|
4671
|
+
async dataForSessionId(s) {
|
|
4672
|
+
const e = await this.dataStringForSessionId(s);
|
|
4630
4673
|
return !e || e.length == 0 ? {} : JSON.parse(e);
|
|
4631
4674
|
}
|
|
4632
4675
|
/**
|
|
@@ -4635,9 +4678,9 @@ class xt {
|
|
|
4635
4678
|
*/
|
|
4636
4679
|
async createCsrfToken() {
|
|
4637
4680
|
this.csrfTokens.makeCsrfCookie(await this.csrfTokens.createCsrfToken());
|
|
4638
|
-
const
|
|
4681
|
+
const s = this.csrfTokens.createCsrfToken(), e = this.csrfTokens.makeCsrfFormOrHeaderToken(s);
|
|
4639
4682
|
return {
|
|
4640
|
-
csrfCookie: this.csrfTokens.makeCsrfCookie(
|
|
4683
|
+
csrfCookie: this.csrfTokens.makeCsrfCookie(s),
|
|
4641
4684
|
csrfFormOrHeaderValue: e
|
|
4642
4685
|
};
|
|
4643
4686
|
}
|
|
@@ -4648,8 +4691,8 @@ class xt {
|
|
|
4648
4691
|
* @param csrfCookieValue the value from the CSRF cookie
|
|
4649
4692
|
* @returns the value to put in the form or CSRF header
|
|
4650
4693
|
*/
|
|
4651
|
-
async createCsrfFormOrHeaderValue(
|
|
4652
|
-
const e = this.csrfTokens.unsignCookie(
|
|
4694
|
+
async createCsrfFormOrHeaderValue(s) {
|
|
4695
|
+
const e = this.csrfTokens.unsignCookie(s);
|
|
4653
4696
|
return this.csrfTokens.makeCsrfFormOrHeaderToken(e);
|
|
4654
4697
|
}
|
|
4655
4698
|
/**
|
|
@@ -4660,8 +4703,8 @@ class xt {
|
|
|
4660
4703
|
* @throws {@link @crossauth/common!CrossauthError} with `InvalidKey`
|
|
4661
4704
|
* if the signature is invalid.
|
|
4662
4705
|
*/
|
|
4663
|
-
getSessionId(
|
|
4664
|
-
return this.session.unsignCookie(
|
|
4706
|
+
getSessionId(s) {
|
|
4707
|
+
return this.session.unsignCookie(s);
|
|
4665
4708
|
}
|
|
4666
4709
|
/**
|
|
4667
4710
|
* Throws {@link @crossauth/common!CrossauthError} with
|
|
@@ -4672,17 +4715,17 @@ class xt {
|
|
|
4672
4715
|
* @param csrfFormOrHeaderValue the value from the form field or
|
|
4673
4716
|
* CSRF header
|
|
4674
4717
|
*/
|
|
4675
|
-
validateDoubleSubmitCsrfToken(
|
|
4676
|
-
if (!
|
|
4677
|
-
this.csrfTokens.validateDoubleSubmitCsrfToken(
|
|
4718
|
+
validateDoubleSubmitCsrfToken(s, e) {
|
|
4719
|
+
if (!s || !e) throw new o(l.InvalidCsrf, "CSRF missing from either cookie or form/header value");
|
|
4720
|
+
this.csrfTokens.validateDoubleSubmitCsrfToken(s, e);
|
|
4678
4721
|
}
|
|
4679
4722
|
/**
|
|
4680
4723
|
* Throws {@link @crossauth/common!CrossauthError} with `InvalidKey` if
|
|
4681
4724
|
* the passed CSRF cookie value is not valid (ie invalid signature)
|
|
4682
4725
|
* @param csrfCookieValue the CSRF cookie value
|
|
4683
4726
|
*/
|
|
4684
|
-
validateCsrfCookie(
|
|
4685
|
-
this.csrfTokens.validateCsrfCookie(
|
|
4727
|
+
validateCsrfCookie(s) {
|
|
4728
|
+
this.csrfTokens.validateCsrfCookie(s);
|
|
4686
4729
|
}
|
|
4687
4730
|
/**
|
|
4688
4731
|
* If sessionIdleTimeout is set, update the last activcity time in key
|
|
@@ -4690,8 +4733,8 @@ class xt {
|
|
|
4690
4733
|
*
|
|
4691
4734
|
* @param sessionId the session Id to update.
|
|
4692
4735
|
*/
|
|
4693
|
-
async updateSessionActivity(
|
|
4694
|
-
const { key: e } = await this.session.getSessionKey(
|
|
4736
|
+
async updateSessionActivity(s) {
|
|
4737
|
+
const { key: e } = await this.session.getSessionKey(s);
|
|
4695
4738
|
this.session.idleTimeout > 0 && this.session.updateSessionKey({
|
|
4696
4739
|
value: e.value,
|
|
4697
4740
|
lastactive: /* @__PURE__ */ new Date()
|
|
@@ -4706,9 +4749,9 @@ class xt {
|
|
|
4706
4749
|
* @param name of the field.
|
|
4707
4750
|
* @param value new value to store
|
|
4708
4751
|
*/
|
|
4709
|
-
async updateSessionData(
|
|
4710
|
-
const r = D.hashSessionId(
|
|
4711
|
-
u.logger.debug(f({ msg: `Updating session data value${e}`, hashedSessionCookie: T.hash(
|
|
4752
|
+
async updateSessionData(s, e, t) {
|
|
4753
|
+
const r = D.hashSessionId(s);
|
|
4754
|
+
u.logger.debug(f({ msg: `Updating session data value${e}`, hashedSessionCookie: T.hash(s) })), await this.keyStorage.updateData(r, e, t);
|
|
4712
4755
|
}
|
|
4713
4756
|
/**
|
|
4714
4757
|
* Update field sin the session data.
|
|
@@ -4718,9 +4761,9 @@ class xt {
|
|
|
4718
4761
|
* @param sessionId the session Id to update.
|
|
4719
4762
|
* @param dataArray names and values.
|
|
4720
4763
|
*/
|
|
4721
|
-
async updateManySessionData(
|
|
4722
|
-
const t = D.hashSessionId(
|
|
4723
|
-
u.logger.debug(f({ msg:
|
|
4764
|
+
async updateManySessionData(s, e) {
|
|
4765
|
+
const t = D.hashSessionId(s);
|
|
4766
|
+
u.logger.debug(f({ msg: "Updating session data", hashedSessionCookie: T.hash(s) })), await this.keyStorage.updateManyData(t, e);
|
|
4724
4767
|
}
|
|
4725
4768
|
/**
|
|
4726
4769
|
* Deletes a field from the session data.
|
|
@@ -4730,17 +4773,17 @@ class xt {
|
|
|
4730
4773
|
* @param sessionId the session Id to update.
|
|
4731
4774
|
* @param name of the field.
|
|
4732
4775
|
*/
|
|
4733
|
-
async deleteSessionData(
|
|
4734
|
-
const t = D.hashSessionId(
|
|
4735
|
-
u.logger.debug(f({ msg: `Updating session data value${e}`, hashedSessionCookie: T.hash(
|
|
4776
|
+
async deleteSessionData(s, e) {
|
|
4777
|
+
const t = D.hashSessionId(s);
|
|
4778
|
+
u.logger.debug(f({ msg: `Updating session data value${e}`, hashedSessionCookie: T.hash(s) })), await this.keyStorage.deleteData(t, e);
|
|
4736
4779
|
}
|
|
4737
4780
|
/**
|
|
4738
4781
|
* Deletes the given session ID from the key storage (not the cookie)
|
|
4739
4782
|
*
|
|
4740
4783
|
* @param sessionId the session Id to delete
|
|
4741
4784
|
*/
|
|
4742
|
-
async deleteSession(
|
|
4743
|
-
return await this.keyStorage.deleteKey(D.hashSessionId(
|
|
4785
|
+
async deleteSession(s) {
|
|
4786
|
+
return await this.keyStorage.deleteKey(D.hashSessionId(s));
|
|
4744
4787
|
}
|
|
4745
4788
|
/**
|
|
4746
4789
|
* Creates a new user, sending an email verification message if necessary.
|
|
@@ -4756,22 +4799,22 @@ class xt {
|
|
|
4756
4799
|
* performed
|
|
4757
4800
|
* @returns the new user
|
|
4758
4801
|
*/
|
|
4759
|
-
async createUser(
|
|
4802
|
+
async createUser(s, e, t, r = !1, i = !1) {
|
|
4760
4803
|
var c;
|
|
4761
4804
|
if (!this.userStorage) throw new o(l.Configuration, "Cannot call createUser if no user storage provided");
|
|
4762
|
-
if (!this.authenticators[
|
|
4763
|
-
this.authenticators[
|
|
4764
|
-
let
|
|
4765
|
-
const n = i ? await this.userStorage.createUser(
|
|
4805
|
+
if (!this.authenticators[s.factor1]) throw new o(l.Configuration, "Authenticator cannot create users");
|
|
4806
|
+
this.authenticators[s.factor1].skipEmailVerificationOnSignup() == !0 && (r = !0);
|
|
4807
|
+
let a = i ? void 0 : await this.authenticators[s.factor1].createPersistentSecrets(s.username, e, t);
|
|
4808
|
+
const n = i ? await this.userStorage.createUser(s) : await this.userStorage.createUser(s, a);
|
|
4766
4809
|
return !r && this.enableEmailVerification && this.tokenEmailer && await ((c = this.tokenEmailer) == null ? void 0 : c.sendEmailVerificationToken(n.id, void 0)), n;
|
|
4767
4810
|
}
|
|
4768
4811
|
/**
|
|
4769
4812
|
* Deletes the user matching the given username
|
|
4770
4813
|
* @param username user to delete
|
|
4771
4814
|
*/
|
|
4772
|
-
async deleteUserByUsername(
|
|
4815
|
+
async deleteUserByUsername(s) {
|
|
4773
4816
|
if (!this.userStorage) throw new o(l.Configuration, "Cannot call deleteUser if no user storage provided");
|
|
4774
|
-
this.userStorage.deleteUserByUsername(
|
|
4817
|
+
this.userStorage.deleteUserByUsername(s);
|
|
4775
4818
|
}
|
|
4776
4819
|
/** Creates a user with 2FA enabled.
|
|
4777
4820
|
*
|
|
@@ -4789,16 +4832,16 @@ class xt {
|
|
|
4789
4832
|
* complete 2FA set up (eg the secret key and QR codee for TOTP),
|
|
4790
4833
|
*
|
|
4791
4834
|
*/
|
|
4792
|
-
async initiateTwoFactorSignup(
|
|
4835
|
+
async initiateTwoFactorSignup(s, e, t, r) {
|
|
4793
4836
|
if (!this.userStorage) throw new o(l.Configuration, "Cannot call initiateTwoFactorSignup if no user storage provided");
|
|
4794
|
-
if (!this.authenticators[
|
|
4795
|
-
if (!this.authenticators[
|
|
4796
|
-
const
|
|
4797
|
-
return
|
|
4837
|
+
if (!this.authenticators[s.factor1]) throw new o(l.Configuration, "Authenticator cannot create users");
|
|
4838
|
+
if (!this.authenticators[s.factor2]) throw new o(l.Configuration, "Two factor authentication not enabled for user");
|
|
4839
|
+
const a = await this.authenticators[s.factor2].prepareConfiguration(s), n = a == null ? {} : a.userData, c = a == null ? {} : a.sessionData, d = await this.authenticators[s.factor1].createPersistentSecrets(s.username, e, r);
|
|
4840
|
+
return s.state = "awaitingtwofactorsetup", await this.keyStorage.updateData(
|
|
4798
4841
|
D.hashSessionId(t),
|
|
4799
4842
|
"2fa",
|
|
4800
4843
|
c
|
|
4801
|
-
), { userid: (await this.userStorage.createUser(
|
|
4844
|
+
), { userid: (await this.userStorage.createUser(s, d)).id, userData: n };
|
|
4802
4845
|
}
|
|
4803
4846
|
/**
|
|
4804
4847
|
* Begins the process of setting up 2FA for a user which has already been
|
|
@@ -4809,18 +4852,18 @@ class xt {
|
|
|
4809
4852
|
* @returns the 2FA data that can be displayed to the user in the confifugre 2FA
|
|
4810
4853
|
* step (such as the secret and QR code for TOTP).
|
|
4811
4854
|
*/
|
|
4812
|
-
async initiateTwoFactorSetup(
|
|
4855
|
+
async initiateTwoFactorSetup(s, e, t) {
|
|
4813
4856
|
if (!this.userStorage) throw new o(l.Configuration, "Cannot call initiateTwOFactorSetup if no user storage provided");
|
|
4814
4857
|
if (e && e != "none") {
|
|
4815
4858
|
if (!this.authenticators[e]) throw new o(l.Configuration, "Two factor authentication not enabled for user");
|
|
4816
|
-
const i = await this.authenticators[e].prepareConfiguration(
|
|
4859
|
+
const i = await this.authenticators[e].prepareConfiguration(s), a = i == null ? {} : i.userData, n = i == null ? {} : i.sessionData;
|
|
4817
4860
|
return await this.keyStorage.updateData(
|
|
4818
4861
|
D.hashSessionId(t),
|
|
4819
4862
|
"2fa",
|
|
4820
4863
|
n
|
|
4821
|
-
),
|
|
4864
|
+
), a;
|
|
4822
4865
|
}
|
|
4823
|
-
return await this.userStorage.updateUser({ id:
|
|
4866
|
+
return await this.userStorage.updateUser({ id: s.id, factor2: e ?? "" }), await this.keyStorage.updateData(
|
|
4824
4867
|
D.hashSessionId(t),
|
|
4825
4868
|
"2fa",
|
|
4826
4869
|
void 0
|
|
@@ -4839,9 +4882,9 @@ class xt {
|
|
|
4839
4882
|
* secret but only `userData` has the QR code, since it can be
|
|
4840
4883
|
* generated from the shared secret.
|
|
4841
4884
|
*/
|
|
4842
|
-
async repeatTwoFactorSignup(
|
|
4885
|
+
async repeatTwoFactorSignup(s) {
|
|
4843
4886
|
if (!this.userStorage) throw new o(l.Configuration, "Cannot call repeatTwoFactorSignup if no user storage provided");
|
|
4844
|
-
const e = (await this.dataForSessionId(
|
|
4887
|
+
const e = (await this.dataForSessionId(s))["2fa"], t = e.username, r = e.factor2, i = D.hashSessionId(s), a = await this.keyStorage.getKey(i), c = await this.authenticators[r].reprepareConfiguration(t, a), d = c == null ? {} : c.userData, g = c == null ? {} : c.secrets, y = c == null ? {} : c.newSessionData;
|
|
4845
4888
|
y && await this.keyStorage.updateData(i, "2fa", y);
|
|
4846
4889
|
const { user: p } = await this.userStorage.getUserByUsername(t, { skipActiveCheck: !0, skipEmailVerifiedCheck: !0 });
|
|
4847
4890
|
return { userid: p.id, userData: d, secrets: g };
|
|
@@ -4856,8 +4899,8 @@ class xt {
|
|
|
4856
4899
|
* @returns the user object
|
|
4857
4900
|
* @throws {@link @crossauth/common!CrossauthError} if authentication fails.
|
|
4858
4901
|
*/
|
|
4859
|
-
async completeTwoFactorSetup(
|
|
4860
|
-
var
|
|
4902
|
+
async completeTwoFactorSetup(s, e) {
|
|
4903
|
+
var _;
|
|
4861
4904
|
if (!this.userStorage) throw new o(l.Configuration, "Cannot call completeTwoFactorSetup if no user storage provided");
|
|
4862
4905
|
let t = !1, { user: r, key: i } = await this.session.getUserForSessionId(e, {
|
|
4863
4906
|
skipActiveCheck: !0
|
|
@@ -4865,23 +4908,23 @@ class xt {
|
|
|
4865
4908
|
if (r && r.state != E.active && r.state != E.factor2ResetNeeded)
|
|
4866
4909
|
throw new o(l.UserNotActive);
|
|
4867
4910
|
if (!i) throw new o(l.InvalidKey, "Session key not found");
|
|
4868
|
-
let
|
|
4869
|
-
if (!(
|
|
4870
|
-
let n =
|
|
4871
|
-
const c = this.authenticators[
|
|
4911
|
+
let a = L.decodeData(i.data)["2fa"];
|
|
4912
|
+
if (!(a != null && a.factor2) || !(a != null && a.username)) throw new o(l.Unauthorized, "Two factor authentication not initiated");
|
|
4913
|
+
let n = a.username;
|
|
4914
|
+
const c = this.authenticators[a.factor2];
|
|
4872
4915
|
if (!c) throw new o(l.Configuration, "Unrecognised second factor authentication");
|
|
4873
4916
|
const d = {}, g = c.secretNames();
|
|
4874
|
-
for (let
|
|
4875
|
-
g.includes(
|
|
4876
|
-
await c.authenticateUser(void 0,
|
|
4917
|
+
for (let C in a)
|
|
4918
|
+
g.includes(C) && (d[C] = a[C]);
|
|
4919
|
+
await c.authenticateUser(void 0, a, s), r || (t = !0, r = (await this.userStorage.getUserByUsername(n, { skipActiveCheck: !0, skipEmailVerifiedCheck: !0 })).user);
|
|
4877
4920
|
const y = c.skipEmailVerificationOnSignup() == !0;
|
|
4878
4921
|
if (!r) throw new o(l.UserNotExist, "Couldn't fetch user");
|
|
4879
4922
|
const p = {
|
|
4880
4923
|
id: r.id,
|
|
4881
4924
|
state: !y && this.enableEmailVerification ? "awaitingemailverification" : "active",
|
|
4882
|
-
factor2:
|
|
4925
|
+
factor2: a.factor2
|
|
4883
4926
|
};
|
|
4884
|
-
return c.secretNames().length > 0 ? await this.userStorage.updateUser(p, d) : await this.userStorage.updateUser(p), !y && t && this.enableEmailVerification && this.tokenEmailer && await ((
|
|
4927
|
+
return c.secretNames().length > 0 ? await this.userStorage.updateUser(p, d) : await this.userStorage.updateUser(p), !y && t && this.enableEmailVerification && this.tokenEmailer && await ((_ = this.tokenEmailer) == null ? void 0 : _.sendEmailVerificationToken(r.id, void 0)), await this.keyStorage.updateData(D.hashSessionId(i.value), "2fa", void 0), { ...r, ...p };
|
|
4885
4928
|
}
|
|
4886
4929
|
/**
|
|
4887
4930
|
* Initiates the two factor login process.
|
|
@@ -4890,11 +4933,11 @@ class xt {
|
|
|
4890
4933
|
* @param user the user, which should aleady have been authenticated with factor1
|
|
4891
4934
|
* @returns a new anonymous session cookie and corresponding CSRF cookie and token.
|
|
4892
4935
|
*/
|
|
4893
|
-
async initiateTwoFactorLogin(
|
|
4894
|
-
const t = await this.authenticators[
|
|
4936
|
+
async initiateTwoFactorLogin(s) {
|
|
4937
|
+
const t = await this.authenticators[s.factor2].createOneTimeSecrets(s), { sessionCookie: r } = await this.createAnonymousSession({ data: JSON.stringify({ "2fa": { username: s.username, twoFactorInitiated: !0, factor2: s.factor2, ...t } }) }), i = this.csrfTokens.createCsrfToken(), a = this.csrfTokens.makeCsrfCookie(i), n = this.csrfTokens.makeCsrfFormOrHeaderToken(i);
|
|
4895
4938
|
return {
|
|
4896
4939
|
sessionCookie: r,
|
|
4897
|
-
csrfCookie:
|
|
4940
|
+
csrfCookie: a,
|
|
4898
4941
|
csrfFormOrHeaderValue: n
|
|
4899
4942
|
};
|
|
4900
4943
|
}
|
|
@@ -4909,12 +4952,12 @@ class xt {
|
|
|
4909
4952
|
* @returns If a token was passed a new anonymous session cookie and
|
|
4910
4953
|
* corresponding CSRF cookie and token.
|
|
4911
4954
|
*/
|
|
4912
|
-
async initiateTwoFactorPageVisit(
|
|
4913
|
-
const n = await this.authenticators[
|
|
4955
|
+
async initiateTwoFactorPageVisit(s, e, t, r, i) {
|
|
4956
|
+
const n = await this.authenticators[s.factor2].createOneTimeSecrets(s);
|
|
4914
4957
|
let c, d, g;
|
|
4915
4958
|
const y = D.hashSessionId(e);
|
|
4916
|
-
u.logger.debug("initiateTwoFactorPageVisit " +
|
|
4917
|
-
let p = { username:
|
|
4959
|
+
u.logger.debug("initiateTwoFactorPageVisit " + s.username + " " + e + " " + y);
|
|
4960
|
+
let p = { username: s.username, factor2: s.factor2, secrets: n, body: t, url: r };
|
|
4918
4961
|
return i && (p["content-type"] = i), await this.keyStorage.updateData(y, "pre2fa", p), {
|
|
4919
4962
|
sessionCookie: c,
|
|
4920
4963
|
csrfCookie: d,
|
|
@@ -4930,18 +4973,18 @@ class xt {
|
|
|
4930
4973
|
* @param sessionId the session cookie value (ie still signed)
|
|
4931
4974
|
* @throws {@link @crossauth/common!CrossauthError} if authentication fails.
|
|
4932
4975
|
*/
|
|
4933
|
-
async completeTwoFactorPageVisit(
|
|
4976
|
+
async completeTwoFactorPageVisit(s, e) {
|
|
4934
4977
|
if (!this.userStorage) throw new o(l.Configuration, "Cannot call completeTwoFactorPageVisit if no user storage provided");
|
|
4935
4978
|
let { key: t } = await this.session.getUserForSessionId(e);
|
|
4936
4979
|
if (!t) throw new o(l.InvalidKey, "Session key not found");
|
|
4937
|
-
let r =
|
|
4980
|
+
let r = L.decodeData(t.data);
|
|
4938
4981
|
if (!("pre2fa" in r)) throw new o(l.Unauthorized, "Two factor authentication not initiated");
|
|
4939
|
-
const { secrets: i } = await this.userStorage.getUserByUsername(r.pre2fa.username),
|
|
4940
|
-
if (!
|
|
4941
|
-
const n = {}, c =
|
|
4982
|
+
const { secrets: i } = await this.userStorage.getUserByUsername(r.pre2fa.username), a = this.authenticators[r.pre2fa.factor2];
|
|
4983
|
+
if (!a) throw new o(l.Configuration, "Unrecognised second factor authentication");
|
|
4984
|
+
const n = {}, c = a.secretNames();
|
|
4942
4985
|
for (let d in i)
|
|
4943
4986
|
c.includes(d) && d in i && (n[d] = i[d]);
|
|
4944
|
-
await
|
|
4987
|
+
await a.authenticateUser(void 0, { ...n, ...r.pre2fa.secrets }, s), await this.keyStorage.updateData(D.hashSessionId(t.value), "pre2fa", void 0);
|
|
4945
4988
|
}
|
|
4946
4989
|
/**
|
|
4947
4990
|
* Cancels the 2FA that was previously initiated but not completed..
|
|
@@ -4952,10 +4995,10 @@ class xt {
|
|
|
4952
4995
|
* @throws {@link @crossauth/common!CrossauthError} of `Unauthorized`
|
|
4953
4996
|
* if 2FA was not initiated.
|
|
4954
4997
|
*/
|
|
4955
|
-
async cancelTwoFactorPageVisit(
|
|
4956
|
-
let { key: e } = await this.session.getUserForSessionId(
|
|
4998
|
+
async cancelTwoFactorPageVisit(s) {
|
|
4999
|
+
let { key: e } = await this.session.getUserForSessionId(s);
|
|
4957
5000
|
if (!e) throw new o(l.InvalidKey, "Session key not found");
|
|
4958
|
-
let t =
|
|
5001
|
+
let t = L.decodeData(e.data);
|
|
4959
5002
|
if (!("pre2fa" in t)) throw new o(l.Unauthorized, "Two factor authentication not initiated");
|
|
4960
5003
|
return await this.keyStorage.updateData(D.hashSessionId(e.value), "pre2fa", void 0), t.pre2fa;
|
|
4961
5004
|
}
|
|
@@ -4976,17 +5019,17 @@ class xt {
|
|
|
4976
5019
|
* `csrfToken` the new CSRF token corresponding to the cookie
|
|
4977
5020
|
* `user` the newly-logged in user.
|
|
4978
5021
|
*/
|
|
4979
|
-
async completeTwoFactorLogin(
|
|
5022
|
+
async completeTwoFactorLogin(s, e, t = {}, r) {
|
|
4980
5023
|
if (!this.userStorage) throw new o(l.Configuration, "Cannot call completeTwoFactorLogin if no user storage provided");
|
|
4981
5024
|
let { key: i } = await this.session.getUserForSessionId(e);
|
|
4982
5025
|
if (!i || !i.data || i.data == "") throw new o(l.Unauthorized);
|
|
4983
|
-
let
|
|
5026
|
+
let a = L.decodeData(i.data)["2fa"], n = a.username, c = a.factor2;
|
|
4984
5027
|
const { user: d, secrets: g } = await this.userStorage.getUserByUsername(n), y = this.authenticators[c];
|
|
4985
5028
|
if (!y) throw new o(l.Configuration, "Second factor " + c + " not enabled");
|
|
4986
|
-
await y.authenticateUser(d, { ...g, ...
|
|
5029
|
+
await y.authenticateUser(d, { ...g, ...a }, s);
|
|
4987
5030
|
const p = await this.session.createSessionKey(d.id, t);
|
|
4988
5031
|
await this.keyStorage.deleteKey(D.hashSessionId(i.value));
|
|
4989
|
-
const
|
|
5032
|
+
const _ = this.session.makeCookie(p, r), C = this.csrfTokens.createCsrfToken(), v = this.csrfTokens.makeCsrfCookie(C), k = this.csrfTokens.makeCsrfFormOrHeaderToken(C);
|
|
4990
5033
|
try {
|
|
4991
5034
|
this.emailTokenStorage.deleteAllForUser(
|
|
4992
5035
|
d.id,
|
|
@@ -4996,9 +5039,9 @@ class xt {
|
|
|
4996
5039
|
u.logger.warn(f({ msg: "Couldn't delete password reset tokens while logging in", user: n })), u.logger.debug(f({ err: A }));
|
|
4997
5040
|
}
|
|
4998
5041
|
return {
|
|
4999
|
-
sessionCookie:
|
|
5042
|
+
sessionCookie: _,
|
|
5000
5043
|
csrfCookie: v,
|
|
5001
|
-
csrfFormOrHeaderValue:
|
|
5044
|
+
csrfFormOrHeaderValue: k,
|
|
5002
5045
|
user: d
|
|
5003
5046
|
};
|
|
5004
5047
|
}
|
|
@@ -5006,10 +5049,10 @@ class xt {
|
|
|
5006
5049
|
* Sends a password reset token
|
|
5007
5050
|
* @param email the user's email (where the token will be sent)
|
|
5008
5051
|
. */
|
|
5009
|
-
async requestPasswordReset(
|
|
5052
|
+
async requestPasswordReset(s) {
|
|
5010
5053
|
var t;
|
|
5011
5054
|
if (!this.userStorage) throw new o(l.Configuration, "Cannot call requestPasswordReset if no user storage provided");
|
|
5012
|
-
const { user: e } = await this.userStorage.getUserByEmail(
|
|
5055
|
+
const { user: e } = await this.userStorage.getUserByEmail(s, {
|
|
5013
5056
|
skipActiveCheck: !0
|
|
5014
5057
|
});
|
|
5015
5058
|
if (e.state != E.active && e.state != E.passwordResetNeeded && e.state != E.passwordAndFactor2ResetNeeded)
|
|
@@ -5025,16 +5068,16 @@ class xt {
|
|
|
5025
5068
|
* @param token the token to apply
|
|
5026
5069
|
* @returns the new user record
|
|
5027
5070
|
*/
|
|
5028
|
-
async applyEmailVerificationToken(
|
|
5071
|
+
async applyEmailVerificationToken(s) {
|
|
5029
5072
|
if (!this.userStorage) throw new o(l.Configuration, "Cannot call applyEmailVerificationToken if no user storage provided");
|
|
5030
5073
|
if (u.logger.debug(f({ msg: "applyEmailVerificationToken" })), !this.tokenEmailer) throw new o(l.Configuration, "Email verification not enabled");
|
|
5031
5074
|
try {
|
|
5032
|
-
let { userid: e, newEmail: t } = await this.tokenEmailer.verifyEmailVerificationToken(
|
|
5075
|
+
let { userid: e, newEmail: t } = await this.tokenEmailer.verifyEmailVerificationToken(s), { user: r } = await this.userStorage.getUserById(e, { skipEmailVerifiedCheck: !0 }), i;
|
|
5033
5076
|
"email" in r && r.email != null ? i = r.email : i = r.username;
|
|
5034
|
-
let
|
|
5077
|
+
let a = {
|
|
5035
5078
|
id: r.id
|
|
5036
5079
|
};
|
|
5037
|
-
return (r.state = "awaitingemailverification") && (
|
|
5080
|
+
return (r.state = "awaitingemailverification") && (a.state = "active"), t != "" ? a.email = t : i = void 0, await this.userStorage.updateUser(a), await this.tokenEmailer.deleteEmailVerificationToken(s), { ...r, ...a, oldEmail: i };
|
|
5038
5081
|
} finally {
|
|
5039
5082
|
}
|
|
5040
5083
|
}
|
|
@@ -5044,29 +5087,29 @@ class xt {
|
|
|
5044
5087
|
* @returns the user
|
|
5045
5088
|
* @throws {@link @crossauth/common!CrossauthError} if the token is not valid.
|
|
5046
5089
|
*/
|
|
5047
|
-
async userForPasswordResetToken(
|
|
5090
|
+
async userForPasswordResetToken(s) {
|
|
5048
5091
|
if (u.logger.debug(f({ msg: "userForPasswordResetToken" })), !this.tokenEmailer) throw new o(l.Configuration, "Password reset not enabled");
|
|
5049
|
-
return await this.tokenEmailer.verifyPasswordResetToken(
|
|
5092
|
+
return await this.tokenEmailer.verifyPasswordResetToken(s);
|
|
5050
5093
|
}
|
|
5051
|
-
async changeSecrets(
|
|
5094
|
+
async changeSecrets(s, e, t, r, i) {
|
|
5052
5095
|
if (!this.userStorage) throw new o(l.Configuration, "Cannot call changeSecrets if no user storage provided");
|
|
5053
|
-
let { user:
|
|
5054
|
-
const c = e == 1 ?
|
|
5055
|
-
i != null && await this.authenticators[c].authenticateUser(
|
|
5056
|
-
const d = await this.authenticators[
|
|
5096
|
+
let { user: a, secrets: n } = await this.userStorage.getUserByUsername(s);
|
|
5097
|
+
const c = e == 1 ? a.factor1 : a.factor2;
|
|
5098
|
+
i != null && await this.authenticators[c].authenticateUser(a, n, i);
|
|
5099
|
+
const d = await this.authenticators[a.factor1].createPersistentSecrets(a.username, t, r);
|
|
5057
5100
|
await this.userStorage.updateUser(
|
|
5058
|
-
{ id:
|
|
5101
|
+
{ id: a.id },
|
|
5059
5102
|
d
|
|
5060
5103
|
);
|
|
5061
5104
|
try {
|
|
5062
5105
|
this.emailTokenStorage.deleteAllForUser(
|
|
5063
|
-
|
|
5106
|
+
a.id,
|
|
5064
5107
|
U.passwordResetToken
|
|
5065
5108
|
);
|
|
5066
5109
|
} catch (g) {
|
|
5067
|
-
u.logger.warn(f({ msg: "Couldn't delete password reset tokens while logging in", user:
|
|
5110
|
+
u.logger.warn(f({ msg: "Couldn't delete password reset tokens while logging in", user: s })), u.logger.debug(f({ err: g }));
|
|
5068
5111
|
}
|
|
5069
|
-
return
|
|
5112
|
+
return a;
|
|
5070
5113
|
}
|
|
5071
5114
|
/**
|
|
5072
5115
|
* Updates a user entry in storage
|
|
@@ -5074,28 +5117,28 @@ class xt {
|
|
|
5074
5117
|
* @param newUser the new user details
|
|
5075
5118
|
* @returns true if email verification is now needed, false otherwise
|
|
5076
5119
|
*/
|
|
5077
|
-
async updateUser(
|
|
5120
|
+
async updateUser(s, e, t = !1, r = !1) {
|
|
5078
5121
|
var y, p;
|
|
5079
5122
|
let i;
|
|
5080
5123
|
if (!this.userStorage) throw new o(l.Configuration, "Cannot call updateUser if no user storage provided");
|
|
5081
|
-
if (!("id" in
|
|
5124
|
+
if (!("id" in s) || s.id == null)
|
|
5082
5125
|
throw new o(l.UserNotExist, "Please specify a user id");
|
|
5083
|
-
if (!("username" in
|
|
5126
|
+
if (!("username" in s) || s.username == null)
|
|
5084
5127
|
throw new o(l.UserNotExist, "Please specify a userername");
|
|
5085
|
-
let { email:
|
|
5086
|
-
d.userid =
|
|
5128
|
+
let { email: a, username: n, password: c, ...d } = e;
|
|
5129
|
+
d.userid = s.userid;
|
|
5087
5130
|
let g = !1;
|
|
5088
|
-
if (
|
|
5089
|
-
i =
|
|
5131
|
+
if (a)
|
|
5132
|
+
i = a, x.validateEmail(i), g = !0;
|
|
5090
5133
|
else if (n) {
|
|
5091
5134
|
i = n;
|
|
5092
5135
|
try {
|
|
5093
|
-
x.validateEmail(
|
|
5136
|
+
x.validateEmail(s.username), g = !0;
|
|
5094
5137
|
} catch {
|
|
5095
5138
|
}
|
|
5096
5139
|
g && x.validateEmail(i);
|
|
5097
5140
|
}
|
|
5098
|
-
return !t && this.enableEmailVerification && g ? await ((y = this.tokenEmailer) == null ? void 0 : y.sendEmailVerificationToken(
|
|
5141
|
+
return !t && this.enableEmailVerification && g ? await ((y = this.tokenEmailer) == null ? void 0 : y.sendEmailVerificationToken(s.id, i)) : (a && (d.email = a), n && (d.username = n)), (e.state == E.passwordResetNeeded || e.state == E.passwordAndFactor2ResetNeeded) && await ((p = this.tokenEmailer) == null ? void 0 : p.sendPasswordResetToken(s.id, {}, r)), await this.userStorage.updateUser(d), {
|
|
5099
5142
|
emailVerificationTokenSent: !t && this.enableEmailVerification && g,
|
|
5100
5143
|
passwordResetTokenSent: e.state == E.passwordResetNeeded || e.state == E.passwordAndFactor2ResetNeeded
|
|
5101
5144
|
};
|
|
@@ -5111,15 +5154,15 @@ class xt {
|
|
|
5111
5154
|
* @throws {@link @crossauth/common!CrossauthError} if the repeatParams don't match params,
|
|
5112
5155
|
* the token is invalid or the user storage cannot be updated.
|
|
5113
5156
|
*/
|
|
5114
|
-
async resetSecret(
|
|
5157
|
+
async resetSecret(s, e, t, r) {
|
|
5115
5158
|
if (!this.userStorage) throw new o(l.Configuration, "Cannot call resetSecret if no user storage provided");
|
|
5116
5159
|
if (u.logger.debug(f({ msg: "resetSecret" })), !this.tokenEmailer) throw new o(l.Configuration, "Password reset not enabled");
|
|
5117
|
-
const i = await this.userForPasswordResetToken(
|
|
5160
|
+
const i = await this.userForPasswordResetToken(s), a = e == 1 ? i.factor1 : i.factor2;
|
|
5118
5161
|
if (!this.tokenEmailer) throw new o(l.Configuration);
|
|
5119
5162
|
let n = i.state == E.passwordAndFactor2ResetNeeded ? E.factor2ResetNeeded : E.active;
|
|
5120
5163
|
await this.userStorage.updateUser(
|
|
5121
5164
|
{ id: i.id, state: n },
|
|
5122
|
-
await this.authenticators[
|
|
5165
|
+
await this.authenticators[a].createPersistentSecrets(i.username, t, r)
|
|
5123
5166
|
);
|
|
5124
5167
|
try {
|
|
5125
5168
|
await this.emailTokenStorage.deleteAllForUser(
|
|
@@ -5139,7 +5182,7 @@ class ge {
|
|
|
5139
5182
|
* @param apiKeyStorage storage for API keys. In addition to the fields {@link KeyStorage} needs, the storage also needs a string field called `name`.
|
|
5140
5183
|
* @param options options. See {@link ApiKeyManagerOptions}
|
|
5141
5184
|
*/
|
|
5142
|
-
constructor(
|
|
5185
|
+
constructor(s, e = {}) {
|
|
5143
5186
|
h(this, "apiKeyStorage");
|
|
5144
5187
|
h(this, "keyLength", 16);
|
|
5145
5188
|
h(this, "secret", "");
|
|
@@ -5149,7 +5192,7 @@ class ge {
|
|
|
5149
5192
|
h(this, "prefix", U.apiKey);
|
|
5150
5193
|
/** The name of the speak in the Authorization header. Defaults to "ApiKey" */
|
|
5151
5194
|
h(this, "authScheme", "ApiKey");
|
|
5152
|
-
this.apiKeyStorage =
|
|
5195
|
+
this.apiKeyStorage = s, w("secret", m.String, this, e, "SECRET", !0), w("keyLength", m.String, this, e, "APIKEY_LENGTH"), w("prefix", m.String, this, e, "APIKEY_PREFIX"), w("authScheme", m.String, this, e, "APIKEY_AUTHSCHEME");
|
|
5153
5196
|
}
|
|
5154
5197
|
/**
|
|
5155
5198
|
* Creates a new random key and returns it, unsigned. It is also persisted in the key storage as a
|
|
@@ -5169,12 +5212,12 @@ class ge {
|
|
|
5169
5212
|
* @returns the new key as a {@link ApiKey} object, plus the token for the
|
|
5170
5213
|
* Authorization header (with the signature appended.)
|
|
5171
5214
|
*/
|
|
5172
|
-
async createKey(
|
|
5173
|
-
const
|
|
5174
|
-
name:
|
|
5175
|
-
value:
|
|
5215
|
+
async createKey(s, e, t, r, i) {
|
|
5216
|
+
const a = T.randomValue(this.keyLength), n = /* @__PURE__ */ new Date(), c = r ? new Date(n.getTime() + r * 1e3) : void 0, d = ge.hashApiKeyValue(a), g = {
|
|
5217
|
+
name: s,
|
|
5218
|
+
value: a,
|
|
5176
5219
|
userid: e,
|
|
5177
|
-
data:
|
|
5220
|
+
data: L.encodeData(t),
|
|
5178
5221
|
expires: c,
|
|
5179
5222
|
created: n,
|
|
5180
5223
|
...i
|
|
@@ -5185,13 +5228,13 @@ class ge {
|
|
|
5185
5228
|
n,
|
|
5186
5229
|
c,
|
|
5187
5230
|
g.data,
|
|
5188
|
-
{ name:
|
|
5231
|
+
{ name: s, ...i }
|
|
5189
5232
|
);
|
|
5190
|
-
const y = this.signApiKeyValue(
|
|
5233
|
+
const y = this.signApiKeyValue(a);
|
|
5191
5234
|
return { key: g, token: y };
|
|
5192
5235
|
}
|
|
5193
|
-
static hashApiKeyValue(
|
|
5194
|
-
return T.hash(
|
|
5236
|
+
static hashApiKeyValue(s) {
|
|
5237
|
+
return T.hash(s);
|
|
5195
5238
|
}
|
|
5196
5239
|
/**
|
|
5197
5240
|
* Returns the hash of the bearer value from the Authorization header.
|
|
@@ -5201,21 +5244,21 @@ class ge {
|
|
|
5201
5244
|
* @param unsignedValue the part of the Authorization header after "Berear ".
|
|
5202
5245
|
* @returns a hash of the value (without the prefix).
|
|
5203
5246
|
*/
|
|
5204
|
-
static hashSignedApiKeyValue(
|
|
5205
|
-
return T.hash(
|
|
5247
|
+
static hashSignedApiKeyValue(s) {
|
|
5248
|
+
return T.hash(s.split(".")[0]);
|
|
5206
5249
|
}
|
|
5207
|
-
unsignApiKeyValue(
|
|
5208
|
-
return T.unsign(
|
|
5250
|
+
unsignApiKeyValue(s) {
|
|
5251
|
+
return T.unsign(s, this.secret).v;
|
|
5209
5252
|
}
|
|
5210
|
-
signApiKeyValue(
|
|
5211
|
-
return T.sign({ v:
|
|
5253
|
+
signApiKeyValue(s) {
|
|
5254
|
+
return T.sign({ v: s }, this.secret);
|
|
5212
5255
|
}
|
|
5213
|
-
async getKey(
|
|
5214
|
-
if (this.authScheme != "" &&
|
|
5256
|
+
async getKey(s) {
|
|
5257
|
+
if (this.authScheme != "" && s.startsWith(this.authScheme + " ")) {
|
|
5215
5258
|
const i = new RegExp(`^${this.authScheme} `);
|
|
5216
|
-
|
|
5259
|
+
s = s.replace(i, "");
|
|
5217
5260
|
}
|
|
5218
|
-
const e = this.unsignApiKeyValue(
|
|
5261
|
+
const e = this.unsignApiKeyValue(s), t = ge.hashApiKeyValue(e), r = await this.apiKeyStorage.getKey(this.prefix + t);
|
|
5219
5262
|
if (!("name" in r)) throw new o(l.InvalidKey, "Not a valid API key");
|
|
5220
5263
|
return { ...r, name: r.name };
|
|
5221
5264
|
}
|
|
@@ -5225,29 +5268,29 @@ class ge {
|
|
|
5225
5268
|
* @returns The {@link ApiKey} object
|
|
5226
5269
|
* @throws {@link @crossauth/common!CrossauthError} with code `InvalidKey`
|
|
5227
5270
|
*/
|
|
5228
|
-
async validateToken(
|
|
5229
|
-
const e =
|
|
5271
|
+
async validateToken(s) {
|
|
5272
|
+
const e = s.split(" ");
|
|
5230
5273
|
if (e.length != 2 || e[0] != this.authScheme)
|
|
5231
5274
|
throw new o(l.InvalidKey, `Not a ${this.authScheme} token`);
|
|
5232
5275
|
return await this.getKey(e[1]);
|
|
5233
5276
|
}
|
|
5234
5277
|
}
|
|
5235
|
-
const it = 16,
|
|
5278
|
+
const it = 16, st = 32;
|
|
5236
5279
|
class J {
|
|
5237
5280
|
/**
|
|
5238
5281
|
* Constructor
|
|
5239
5282
|
* @param options See {@link OAuthClientManagerOptions}
|
|
5240
5283
|
*/
|
|
5241
|
-
constructor(
|
|
5284
|
+
constructor(s = {}) {
|
|
5242
5285
|
h(this, "oauthPbkdf2Digest", "sha256");
|
|
5243
5286
|
h(this, "oauthPbkdf2Iterations", 4e4);
|
|
5244
5287
|
h(this, "oauthPbkdf2KeyLength", 32);
|
|
5245
5288
|
h(this, "clientStorage");
|
|
5246
|
-
if (!
|
|
5289
|
+
if (!s.clientStorage) throw new o(
|
|
5247
5290
|
l.Configuration,
|
|
5248
5291
|
"Must specify clientStorage when adding a client manager"
|
|
5249
5292
|
);
|
|
5250
|
-
this.clientStorage =
|
|
5293
|
+
this.clientStorage = s.clientStorage, w("oauthPbkdf2Digest", m.String, this, s, "OAUTH_PBKDF2_DIGEST"), w("oauthPbkdf2KeyLength", m.String, this, s, "OAUTH_PBKDF2_KEYLENGTH"), w("requireRedirectUriRegistration", m.Boolean, this, s, "OAUTH_REQUIRE_REDIRECT_URI_REGISTRATION");
|
|
5251
5294
|
}
|
|
5252
5295
|
/**
|
|
5253
5296
|
* Creates a client and puts it in the storage
|
|
@@ -5261,8 +5304,8 @@ class J {
|
|
|
5261
5304
|
* @returns the new client. `client_id` and `client_secret` (plaintext)
|
|
5262
5305
|
* will be populated.
|
|
5263
5306
|
*/
|
|
5264
|
-
async createClient(
|
|
5265
|
-
const
|
|
5307
|
+
async createClient(s, e, t, r = !0, i) {
|
|
5308
|
+
const a = J.randomClientId();
|
|
5266
5309
|
let n, c;
|
|
5267
5310
|
r && (c = J.randomClientSecret(), n = await T.passwordHash(c, {
|
|
5268
5311
|
encode: !0,
|
|
@@ -5273,9 +5316,9 @@ class J {
|
|
|
5273
5316
|
J.validateUri(y);
|
|
5274
5317
|
}), t || (t = b.allFlows());
|
|
5275
5318
|
const d = {
|
|
5276
|
-
client_id:
|
|
5319
|
+
client_id: a,
|
|
5277
5320
|
client_secret: n,
|
|
5278
|
-
client_name:
|
|
5321
|
+
client_name: s,
|
|
5279
5322
|
redirect_uri: e,
|
|
5280
5323
|
confidential: r,
|
|
5281
5324
|
valid_flow: t,
|
|
@@ -5304,19 +5347,19 @@ class J {
|
|
|
5304
5347
|
* @returns the updated client. If it has a secret. it will be in
|
|
5305
5348
|
* `client_secret` as plaintext.
|
|
5306
5349
|
*/
|
|
5307
|
-
async updateClient(
|
|
5308
|
-
const r = await this.clientStorage.getClientById(
|
|
5309
|
-
let i = !1,
|
|
5310
|
-
e.confidential === !0 && !r.confidential || e.confidential === !0 && t ? (
|
|
5350
|
+
async updateClient(s, e, t = !1) {
|
|
5351
|
+
const r = await this.clientStorage.getClientById(s);
|
|
5352
|
+
let i = !1, a;
|
|
5353
|
+
e.confidential === !0 && !r.confidential || e.confidential === !0 && t ? (a = J.randomClientSecret(), e.client_secret = await T.passwordHash(a, {
|
|
5311
5354
|
encode: !0,
|
|
5312
5355
|
iterations: this.oauthPbkdf2Iterations,
|
|
5313
5356
|
keyLen: this.oauthPbkdf2KeyLength,
|
|
5314
5357
|
digest: this.oauthPbkdf2Digest
|
|
5315
5358
|
}), i = !0) : e.confidential === !1 && (e.client_secret = null), e.redirect_uri && e.redirect_uri.forEach((c) => {
|
|
5316
5359
|
J.validateUri(c);
|
|
5317
|
-
}), e.client_id =
|
|
5318
|
-
const n = await this.clientStorage.getClientById(
|
|
5319
|
-
return
|
|
5360
|
+
}), e.client_id = s, await this.clientStorage.updateClient(e);
|
|
5361
|
+
const n = await this.clientStorage.getClientById(s);
|
|
5362
|
+
return a && (n.client_secret = a), { client: n, newSecret: i };
|
|
5320
5363
|
}
|
|
5321
5364
|
/**
|
|
5322
5365
|
* Create a random OAuth client id
|
|
@@ -5328,7 +5371,7 @@ class J {
|
|
|
5328
5371
|
* Create a random OAuth client secret
|
|
5329
5372
|
*/
|
|
5330
5373
|
static randomClientSecret() {
|
|
5331
|
-
return T.randomValue(
|
|
5374
|
+
return T.randomValue(st);
|
|
5332
5375
|
}
|
|
5333
5376
|
/** If the passed redirect URI is not in the set of valid ones,
|
|
5334
5377
|
* throw {@link @crossauth/common!CrossauthError} with
|
|
@@ -5337,13 +5380,13 @@ class J {
|
|
|
5337
5380
|
* @throws {@link @crossauth/common!CrossauthError} with
|
|
5338
5381
|
* {@link @crossauth/common!CrossauthError} `BadRequest`.
|
|
5339
5382
|
*/
|
|
5340
|
-
static validateUri(
|
|
5383
|
+
static validateUri(s) {
|
|
5341
5384
|
let e = !1;
|
|
5342
5385
|
try {
|
|
5343
|
-
e = new URL(
|
|
5386
|
+
e = new URL(s).hash.length == 0;
|
|
5344
5387
|
} catch (t) {
|
|
5345
5388
|
try {
|
|
5346
|
-
e = new URL(
|
|
5389
|
+
e = new URL(s).hash.length == 0;
|
|
5347
5390
|
} catch {
|
|
5348
5391
|
u.logger.debug(f({ err: t }));
|
|
5349
5392
|
}
|
|
@@ -5351,12 +5394,12 @@ class J {
|
|
|
5351
5394
|
if (!e)
|
|
5352
5395
|
throw o.fromOAuthError(
|
|
5353
5396
|
"invalid_request",
|
|
5354
|
-
`Invalid redirect Uri ${
|
|
5397
|
+
`Invalid redirect Uri ${s}`
|
|
5355
5398
|
);
|
|
5356
5399
|
}
|
|
5357
5400
|
}
|
|
5358
|
-
function
|
|
5359
|
-
switch (
|
|
5401
|
+
function at(S) {
|
|
5402
|
+
switch (S) {
|
|
5360
5403
|
case "HS256":
|
|
5361
5404
|
case "HS384":
|
|
5362
5405
|
case "HS512":
|
|
@@ -5370,14 +5413,14 @@ function st(C) {
|
|
|
5370
5413
|
case "PS384":
|
|
5371
5414
|
case "PS512":
|
|
5372
5415
|
case "none":
|
|
5373
|
-
return
|
|
5416
|
+
return S;
|
|
5374
5417
|
}
|
|
5375
5418
|
throw new o(
|
|
5376
5419
|
l.Configuration,
|
|
5377
|
-
"Invalid JWT signing algorithm " +
|
|
5420
|
+
"Invalid JWT signing algorithm " + S
|
|
5378
5421
|
);
|
|
5379
5422
|
}
|
|
5380
|
-
class
|
|
5423
|
+
class zt {
|
|
5381
5424
|
/**
|
|
5382
5425
|
* Constructor
|
|
5383
5426
|
*
|
|
@@ -5389,7 +5432,7 @@ class Dt {
|
|
|
5389
5432
|
* authenticators for the Password MFA flow)
|
|
5390
5433
|
* @param options See {@link OAuthAuthorizationServerOptions }
|
|
5391
5434
|
*/
|
|
5392
|
-
constructor(
|
|
5435
|
+
constructor(s, e, t, r = {}) {
|
|
5393
5436
|
h(this, "clientStorage");
|
|
5394
5437
|
h(this, "keyStorage");
|
|
5395
5438
|
h(this, "userStorage");
|
|
@@ -5439,7 +5482,7 @@ class Dt {
|
|
|
5439
5482
|
h(this, "validFlows", ["all"]);
|
|
5440
5483
|
/** Set from options. See {@link OAuthAuthorizationServerOptions.allowedFactor2} */
|
|
5441
5484
|
h(this, "allowedFactor2", []);
|
|
5442
|
-
this.clientStorage =
|
|
5485
|
+
this.clientStorage = s, this.keyStorage = e, this.userStorage = r.userStorage, this.authStorage = r.authStorage, t && (this.authenticators = t), this.clientManager = new J({ clientStorage: s, ...r }), w("oauthIssuer", m.String, this, r, "AUTH_SERVER_BASE_URL", !0), w("audience", m.String, this, r, "OAUTH_AUDIENCE"), w("oauthPbkdf2Iterations", m.String, this, r, "OAUTH_PBKDF2_ITERATIONS"), w("requireClientSecretOrChallenge", m.Boolean, this, r, "OAUTH_REQUIRE_CLIENT_SECRET_OR_CHALLENGE"), w("jwtAlgorithm", m.String, this, r, "JWT_ALGORITHM"), w("codeLength", m.Number, this, r, "OAUTH_CODE_LENGTH"), w("jwtKeyType", m.String, this, r, "JWT_KEY_TYPE"), w("jwtSecretKeyFile", m.String, this, r, "JWT_SECRET_KEY_FILE"), w("jwtPublicKeyFile", m.String, this, r, "JWT_PUBLIC_KEY_FILE"), w("jwtPrivateKeyFile", m.String, this, r, "JWT_PRIVATE_KEY_FILE"), w("jwtSecretKey", m.String, this, r, "JWT_SECRET_KEY"), w("jwtPublicKey", m.String, this, r, "JWT_PUBLIC_KEY"), w("jwtPrivateKey", m.String, this, r, "JWT_PRIVATE_KEY"), w("jwtKid", m.String, this, r, "JWT_KID"), w("persistAccessToken", m.String, this, r, "OAUTH_PERSIST_ACCESS_TOKEN"), w("issueRefreshToken", m.String, this, r, "OAUTH_ISSUE_REFRESH_TOKEN"), w("opaqueAccessToken", m.String, this, r, "OAUTH_OPAQUE_ACCESS_TOKEN"), w("accessTokenExpiry", m.Number, this, r, "OAUTH_ACCESS_TOKEN_EXPIRY"), w("refreshTokenExpiry", m.Number, this, r, "OAUTH_REFRESH_TOKEN_EXPIRY"), w("rollingRefreshToken", m.Boolean, this, r, "OAUTH_ROLLING_REFRESH_TOKEN"), w("authorizationCodeExpiry", m.Number, this, r, "OAUTH_AUTHORIZATION_CODE_EXPIRY"), w("mfaTokenExpiry", m.Number, this, r, "OAUTH_MFA_TOKEN_EXPIRY"), w("clockTolerance", m.Number, this, r, "OAUTH_CLOCK_TOLERANCE"), w("validateScopes", m.Boolean, this, r, "OAUTH_VALIDATE_SCOPES"), w("emptyScopeIsValid", m.Boolean, this, r, "OAUTH_EMPTY_SCOPE_VALID"), w("validScopes", m.JsonArray, this, r, "OAUTH_VALID_SCOPES"), w("validFlows", m.JsonArray, this, r, "OAUTH_validFlows"), w("idTokenClaims", m.Json, this, r, "OAUTH_ID_TOKEN_CLAIMS"), w("allowedFactor2", m.JsonArray, this, r, "ALLOWED_FACTOR2"), w("userCodeExpiry", m.Number, this, r, "DEVICECODE_USERCODE_EXPIRY"), w("userCodeThrottle", m.Number, this, r, "DEVICECODE_USERCODE_THROTTLE"), w("deviceCodePollInterval", m.Number, this, r, "DEVICECODE_POLL_INTERVAL"), w("deviceCodeLength", m.Number, this, r, "DEVICECODE_LENGTH"), w("userCodeLength", m.Number, this, r, "DEVICECODE_USERCODE_LENGTH");
|
|
5443
5486
|
let i = {};
|
|
5444
5487
|
if (w("userCodeDashEvery", m.String, i, r, "DEVICECODE_USERCODE_DASH_EVERY"), i.userCodeDashEvery)
|
|
5445
5488
|
if (i.userCodeDashEvery == "" || i.userCodeDashEvery.toLowerCase() == "null") this.userCodeDashEvery = null;
|
|
@@ -5452,7 +5495,7 @@ class Dt {
|
|
|
5452
5495
|
"userCodeDashEvery must be a number or null"
|
|
5453
5496
|
);
|
|
5454
5497
|
}
|
|
5455
|
-
if (w("deviceCodeVerificationUri", m.String, this, r, "DEVICECODE_VERIFICATION_URI"), this.validFlows.length == 1 && this.validFlows[0] == b.All && (this.validFlows = b.allFlows()), this.jwtAlgorithmChecked =
|
|
5498
|
+
if (w("deviceCodeVerificationUri", m.String, this, r, "DEVICECODE_VERIFICATION_URI"), this.validFlows.length == 1 && this.validFlows[0] == b.All && (this.validFlows = b.allFlows()), this.jwtAlgorithmChecked = at(this.jwtAlgorithm), this.jwtSecretKey || this.jwtSecretKeyFile) {
|
|
5456
5499
|
if (this.jwtPublicKey || this.jwtPublicKeyFile || this.jwtPrivateKey || this.jwtPrivateKeyFile)
|
|
5457
5500
|
throw new o(
|
|
5458
5501
|
l.Configuration,
|
|
@@ -5515,19 +5558,19 @@ class Dt {
|
|
|
5515
5558
|
* JSON response.
|
|
5516
5559
|
*/
|
|
5517
5560
|
async authorizeGetEndpoint({
|
|
5518
|
-
responseType:
|
|
5561
|
+
responseType: s,
|
|
5519
5562
|
client_id: e,
|
|
5520
5563
|
redirect_uri: t,
|
|
5521
5564
|
scope: r,
|
|
5522
5565
|
state: i,
|
|
5523
|
-
codeChallenge:
|
|
5566
|
+
codeChallenge: a,
|
|
5524
5567
|
codeChallengeMethod: n,
|
|
5525
5568
|
user: c
|
|
5526
5569
|
}) {
|
|
5527
|
-
if (!this.responseTypesSupported().includes(
|
|
5570
|
+
if (!this.responseTypesSupported().includes(s))
|
|
5528
5571
|
return {
|
|
5529
5572
|
error: "unsupported_response_type",
|
|
5530
|
-
error_description: "Unsupported response type " +
|
|
5573
|
+
error_description: "Unsupported response type " + s
|
|
5531
5574
|
};
|
|
5532
5575
|
let g;
|
|
5533
5576
|
try {
|
|
@@ -5541,22 +5584,22 @@ class Dt {
|
|
|
5541
5584
|
const {
|
|
5542
5585
|
scopes: y,
|
|
5543
5586
|
error: p,
|
|
5544
|
-
error_description:
|
|
5587
|
+
error_description: _
|
|
5545
5588
|
} = await this.validateAndPersistScope(e, r, c);
|
|
5546
5589
|
if (p) return {
|
|
5547
5590
|
error: p,
|
|
5548
|
-
error_description:
|
|
5591
|
+
error_description: _
|
|
5549
5592
|
};
|
|
5550
|
-
const
|
|
5551
|
-
if (!
|
|
5593
|
+
const C = this.inferFlowFromGet(s, y || [], a);
|
|
5594
|
+
if (!C || !this.validFlows.includes(C))
|
|
5552
5595
|
return {
|
|
5553
5596
|
error: "access_denied",
|
|
5554
|
-
error_description: "Unsupported flow type " +
|
|
5597
|
+
error_description: "Unsupported flow type " + C
|
|
5555
5598
|
};
|
|
5556
|
-
if (!g.valid_flow.includes(
|
|
5599
|
+
if (!g.valid_flow.includes(C))
|
|
5557
5600
|
return {
|
|
5558
5601
|
error: "unauthorized_client",
|
|
5559
|
-
error_description: "Client does not support " +
|
|
5602
|
+
error_description: "Client does not support " + C
|
|
5560
5603
|
};
|
|
5561
5604
|
try {
|
|
5562
5605
|
this.validateState(i);
|
|
@@ -5566,17 +5609,17 @@ class Dt {
|
|
|
5566
5609
|
error_description: "Invalid state"
|
|
5567
5610
|
};
|
|
5568
5611
|
}
|
|
5569
|
-
return
|
|
5612
|
+
return s == "code" ? await this.getAuthorizationCode(
|
|
5570
5613
|
g,
|
|
5571
5614
|
t,
|
|
5572
5615
|
y,
|
|
5573
5616
|
i,
|
|
5574
|
-
|
|
5617
|
+
a,
|
|
5575
5618
|
n,
|
|
5576
5619
|
c
|
|
5577
5620
|
) : {
|
|
5578
5621
|
error: "unsupported_response_type",
|
|
5579
|
-
error_description: `Invalid response_type ${
|
|
5622
|
+
error_description: `Invalid response_type ${s}`
|
|
5580
5623
|
};
|
|
5581
5624
|
}
|
|
5582
5625
|
/**
|
|
@@ -5588,12 +5631,12 @@ class Dt {
|
|
|
5588
5631
|
* @param requestedScopes the scopes that have been requested
|
|
5589
5632
|
* @returns true or false.
|
|
5590
5633
|
*/
|
|
5591
|
-
async hasAllScopes(
|
|
5634
|
+
async hasAllScopes(s, e, t) {
|
|
5592
5635
|
if (!this.authStorage) return !1;
|
|
5593
|
-
const r = await this.authStorage.getAuthorizations(
|
|
5594
|
-
return t.filter((
|
|
5636
|
+
const r = await this.authStorage.getAuthorizations(s, e == null ? void 0 : e.id);
|
|
5637
|
+
return t.filter((a) => r.includes(a)).length == t.length;
|
|
5595
5638
|
}
|
|
5596
|
-
async validateAndPersistScope(
|
|
5639
|
+
async validateAndPersistScope(s, e, t) {
|
|
5597
5640
|
let r, i;
|
|
5598
5641
|
if (!e && !this.emptyScopeIsValid)
|
|
5599
5642
|
return {
|
|
@@ -5602,32 +5645,32 @@ class Dt {
|
|
|
5602
5645
|
};
|
|
5603
5646
|
if (e) {
|
|
5604
5647
|
const {
|
|
5605
|
-
error:
|
|
5648
|
+
error: a,
|
|
5606
5649
|
errorDescription: n,
|
|
5607
5650
|
scopes: c
|
|
5608
5651
|
} = this.validateScope(e);
|
|
5609
|
-
if (r = c, i = c,
|
|
5652
|
+
if (r = c, i = c, a)
|
|
5610
5653
|
return {
|
|
5611
|
-
error:
|
|
5654
|
+
error: a,
|
|
5612
5655
|
error_description: n ?? "Unknown error"
|
|
5613
5656
|
};
|
|
5614
5657
|
} else
|
|
5615
5658
|
i = [null];
|
|
5616
5659
|
if (this.authStorage)
|
|
5617
5660
|
try {
|
|
5618
|
-
const
|
|
5619
|
-
|
|
5661
|
+
const a = i ?? [], n = await this.authStorage.getAuthorizations(
|
|
5662
|
+
s,
|
|
5620
5663
|
t == null ? void 0 : t.id
|
|
5621
|
-
), c = [.../* @__PURE__ */ new Set([...n, ...
|
|
5664
|
+
), c = [.../* @__PURE__ */ new Set([...n, ...a])];
|
|
5622
5665
|
u.logger.debug(f({
|
|
5623
|
-
msg: "Updating authorizations for " +
|
|
5666
|
+
msg: "Updating authorizations for " + s + " to " + c
|
|
5624
5667
|
})), await this.authStorage.updateAuthorizations(
|
|
5625
|
-
|
|
5668
|
+
s,
|
|
5626
5669
|
(t == null ? void 0 : t.id) ?? null,
|
|
5627
5670
|
c
|
|
5628
5671
|
);
|
|
5629
|
-
} catch (
|
|
5630
|
-
return u.logger.debug(f({ err:
|
|
5672
|
+
} catch (a) {
|
|
5673
|
+
return u.logger.debug(f({ err: a })), {
|
|
5631
5674
|
error: "server_error",
|
|
5632
5675
|
error_description: "Couldn't save scope"
|
|
5633
5676
|
};
|
|
@@ -5639,9 +5682,9 @@ class Dt {
|
|
|
5639
5682
|
};
|
|
5640
5683
|
return { scopes: r };
|
|
5641
5684
|
}
|
|
5642
|
-
async authenticateClient(
|
|
5685
|
+
async authenticateClient(s, e, t) {
|
|
5643
5686
|
let r = !1;
|
|
5644
|
-
switch (
|
|
5687
|
+
switch (s) {
|
|
5645
5688
|
case b.AuthorizationCode:
|
|
5646
5689
|
case b.AuthorizationCodeWithPKCE:
|
|
5647
5690
|
r = e.confidential == !0 || e.client_secret != null || t != null;
|
|
@@ -5679,10 +5722,10 @@ class Dt {
|
|
|
5679
5722
|
* @param client_id
|
|
5680
5723
|
* @returns the client_id, or an error or `access_denied`.
|
|
5681
5724
|
*/
|
|
5682
|
-
async getClientById(
|
|
5725
|
+
async getClientById(s) {
|
|
5683
5726
|
let e;
|
|
5684
5727
|
try {
|
|
5685
|
-
return e = await this.clientStorage.getClientById(
|
|
5728
|
+
return e = await this.clientStorage.getClientById(s), { client: e };
|
|
5686
5729
|
} catch {
|
|
5687
5730
|
return {
|
|
5688
5731
|
error: "access_denied",
|
|
@@ -5701,30 +5744,30 @@ class Dt {
|
|
|
5701
5744
|
* endpoint JSON output.
|
|
5702
5745
|
*/
|
|
5703
5746
|
async tokenEndpoint({
|
|
5704
|
-
grantType:
|
|
5747
|
+
grantType: s,
|
|
5705
5748
|
client_id: e,
|
|
5706
5749
|
scope: t,
|
|
5707
5750
|
code: r,
|
|
5708
5751
|
client_secret: i,
|
|
5709
|
-
codeVerifier:
|
|
5752
|
+
codeVerifier: a,
|
|
5710
5753
|
refreshToken: n,
|
|
5711
5754
|
username: c,
|
|
5712
5755
|
password: d,
|
|
5713
5756
|
mfaToken: g,
|
|
5714
5757
|
oobCode: y,
|
|
5715
5758
|
bindingCode: p,
|
|
5716
|
-
otp:
|
|
5717
|
-
deviceCode:
|
|
5759
|
+
otp: _,
|
|
5760
|
+
deviceCode: C
|
|
5718
5761
|
}) {
|
|
5719
5762
|
var K, O, B;
|
|
5720
|
-
const v = this.inferFlowFromPost(
|
|
5763
|
+
const v = this.inferFlowFromPost(s, a);
|
|
5721
5764
|
if (!v) return {
|
|
5722
5765
|
error: "server_error",
|
|
5723
5766
|
error_description: "Unable to determine OAuth flow type"
|
|
5724
5767
|
};
|
|
5725
|
-
const
|
|
5726
|
-
if (!
|
|
5727
|
-
const A =
|
|
5768
|
+
const k = await this.getClientById(e);
|
|
5769
|
+
if (!k.client) return k;
|
|
5770
|
+
const A = k.client, M = await this.authenticateClient(v, A, i);
|
|
5728
5771
|
if (M.error) return M;
|
|
5729
5772
|
if (v == b.Password && !this.validFlows.includes(v) && !this.validFlows.includes(b.PasswordMfa))
|
|
5730
5773
|
return {
|
|
@@ -5744,8 +5787,8 @@ class Dt {
|
|
|
5744
5787
|
let j = !1;
|
|
5745
5788
|
this.issueRefreshToken && v != b.RefreshToken && (j = !0), this.issueRefreshToken && v == b.RefreshToken && this.rollingRefreshToken && (j = !0);
|
|
5746
5789
|
let N;
|
|
5747
|
-
if (
|
|
5748
|
-
return this.requireClientSecretOrChallenge && A && A.client_secret && !i && !
|
|
5790
|
+
if (s == "authorization_code")
|
|
5791
|
+
return this.requireClientSecretOrChallenge && A && A.client_secret && !i && !a ? {
|
|
5749
5792
|
error: "access_denied",
|
|
5750
5793
|
error_description: "Must provide either a client secret or use PKCE"
|
|
5751
5794
|
} : A && A.client_secret && !i ? {
|
|
@@ -5755,13 +5798,13 @@ class Dt {
|
|
|
5755
5798
|
client: A,
|
|
5756
5799
|
code: r,
|
|
5757
5800
|
client_secret: i,
|
|
5758
|
-
codeVerifier:
|
|
5801
|
+
codeVerifier: a,
|
|
5759
5802
|
issueRefreshToken: j
|
|
5760
5803
|
}) : {
|
|
5761
5804
|
error: "access_denied",
|
|
5762
5805
|
error_description: "No authorization code provided for authorization code flow"
|
|
5763
5806
|
};
|
|
5764
|
-
if (
|
|
5807
|
+
if (s == "refresh_token") {
|
|
5765
5808
|
const R = await this.getRefreshTokenData(n);
|
|
5766
5809
|
if (!n || !R || !this.userStorage)
|
|
5767
5810
|
return {
|
|
@@ -5793,12 +5836,12 @@ class Dt {
|
|
|
5793
5836
|
return await this.makeAccessToken({
|
|
5794
5837
|
client: A,
|
|
5795
5838
|
client_secret: i,
|
|
5796
|
-
codeVerifier:
|
|
5839
|
+
codeVerifier: a,
|
|
5797
5840
|
issueRefreshToken: j,
|
|
5798
5841
|
scopes: R.scope,
|
|
5799
5842
|
user: P
|
|
5800
5843
|
});
|
|
5801
|
-
} else if (
|
|
5844
|
+
} else if (s == "client_credentials") {
|
|
5802
5845
|
const {
|
|
5803
5846
|
scopes: R,
|
|
5804
5847
|
error: P,
|
|
@@ -5810,11 +5853,11 @@ class Dt {
|
|
|
5810
5853
|
} : await this.makeAccessToken({
|
|
5811
5854
|
client: A,
|
|
5812
5855
|
client_secret: i,
|
|
5813
|
-
codeVerifier:
|
|
5856
|
+
codeVerifier: a,
|
|
5814
5857
|
scopes: R,
|
|
5815
5858
|
issueRefreshToken: j
|
|
5816
5859
|
});
|
|
5817
|
-
} else if (
|
|
5860
|
+
} else if (s == "password") {
|
|
5818
5861
|
if (!c || !d)
|
|
5819
5862
|
return {
|
|
5820
5863
|
error: "access_denied",
|
|
@@ -5826,13 +5869,13 @@ class Dt {
|
|
|
5826
5869
|
error: "server_error",
|
|
5827
5870
|
error_description: "Password authentication not configured"
|
|
5828
5871
|
};
|
|
5829
|
-
const { user: I, secrets: $ } = await this.userStorage.getUserByUsername(c),
|
|
5830
|
-
if (!
|
|
5872
|
+
const { user: I, secrets: $ } = await this.userStorage.getUserByUsername(c), z = this.authenticators[I.factor1];
|
|
5873
|
+
if (!z || !z.secretNames().includes("password"))
|
|
5831
5874
|
return {
|
|
5832
5875
|
error: "access_denied",
|
|
5833
5876
|
error_description: "Password flow used but factor 1 authenticator does not accept passwords"
|
|
5834
5877
|
};
|
|
5835
|
-
await
|
|
5878
|
+
await z.authenticateUser(
|
|
5836
5879
|
I,
|
|
5837
5880
|
$,
|
|
5838
5881
|
{ password: d }
|
|
@@ -5857,12 +5900,12 @@ class Dt {
|
|
|
5857
5900
|
} : await this.createMfaRequest(N) : await this.makeAccessToken({
|
|
5858
5901
|
client: A,
|
|
5859
5902
|
client_secret: i,
|
|
5860
|
-
codeVerifier:
|
|
5903
|
+
codeVerifier: a,
|
|
5861
5904
|
scopes: R,
|
|
5862
5905
|
issueRefreshToken: j,
|
|
5863
5906
|
user: N
|
|
5864
5907
|
});
|
|
5865
|
-
} else if (
|
|
5908
|
+
} else if (s == "http://auth0.com/oauth/grant-type/mfa-otp") {
|
|
5866
5909
|
const {
|
|
5867
5910
|
scopes: R,
|
|
5868
5911
|
error: P,
|
|
@@ -5873,7 +5916,7 @@ class Dt {
|
|
|
5873
5916
|
error: P,
|
|
5874
5917
|
error_description: F
|
|
5875
5918
|
};
|
|
5876
|
-
if (!
|
|
5919
|
+
if (!_)
|
|
5877
5920
|
return {
|
|
5878
5921
|
error: "access_denied",
|
|
5879
5922
|
error_description: "OTP not provided"
|
|
@@ -5889,18 +5932,18 @@ class Dt {
|
|
|
5889
5932
|
error: "access_denied",
|
|
5890
5933
|
error_description: "Invalid MFA token"
|
|
5891
5934
|
};
|
|
5892
|
-
const
|
|
5893
|
-
if (!
|
|
5935
|
+
const z = this.authenticators[I.user.factor2];
|
|
5936
|
+
if (!z || !this.userStorage)
|
|
5894
5937
|
return {
|
|
5895
5938
|
error: "access_denied",
|
|
5896
5939
|
error_description: "MFA type is not supported for OAuth"
|
|
5897
5940
|
};
|
|
5898
5941
|
try {
|
|
5899
5942
|
const { secrets: V } = await this.userStorage.getUserById(I.user.id);
|
|
5900
|
-
await
|
|
5943
|
+
await z.authenticateUser(
|
|
5901
5944
|
I.user,
|
|
5902
5945
|
V,
|
|
5903
|
-
{ otp:
|
|
5946
|
+
{ otp: _ }
|
|
5904
5947
|
);
|
|
5905
5948
|
} catch (V) {
|
|
5906
5949
|
return u.logger.debug(f({ err: V })), {
|
|
@@ -5920,12 +5963,12 @@ class Dt {
|
|
|
5920
5963
|
return await this.makeAccessToken({
|
|
5921
5964
|
client: A,
|
|
5922
5965
|
client_secret: i,
|
|
5923
|
-
codeVerifier:
|
|
5966
|
+
codeVerifier: a,
|
|
5924
5967
|
scopes: R,
|
|
5925
5968
|
issueRefreshToken: j,
|
|
5926
5969
|
user: I.user
|
|
5927
5970
|
});
|
|
5928
|
-
} else if (
|
|
5971
|
+
} else if (s == "http://auth0.com/oauth/grant-type/mfa-oob") {
|
|
5929
5972
|
const {
|
|
5930
5973
|
scopes: R,
|
|
5931
5974
|
error: P,
|
|
@@ -5959,7 +6002,7 @@ class Dt {
|
|
|
5959
6002
|
error_description: "MFA type is not supported for OAuth"
|
|
5960
6003
|
};
|
|
5961
6004
|
try {
|
|
5962
|
-
const { secrets:
|
|
6005
|
+
const { secrets: z } = await this.userStorage.getUserById(I.user.id), V = L.decodeData(I.key.data).omfa;
|
|
5963
6006
|
if (!V || !V.otp || !V.oobCode)
|
|
5964
6007
|
return {
|
|
5965
6008
|
error: "server_error",
|
|
@@ -5972,20 +6015,20 @@ class Dt {
|
|
|
5972
6015
|
};
|
|
5973
6016
|
await $.authenticateUser(
|
|
5974
6017
|
I.user,
|
|
5975
|
-
{ ...
|
|
6018
|
+
{ ...z, otp: V.otp, expiry: (O = I.key.expires) == null ? void 0 : O.getTime() },
|
|
5976
6019
|
{ otp: p }
|
|
5977
6020
|
);
|
|
5978
|
-
} catch (
|
|
5979
|
-
return u.logger.debug(f({ err:
|
|
6021
|
+
} catch (z) {
|
|
6022
|
+
return u.logger.debug(f({ err: z })), {
|
|
5980
6023
|
error: "access_denied",
|
|
5981
6024
|
error_description: "Invalid OTP"
|
|
5982
6025
|
};
|
|
5983
6026
|
}
|
|
5984
6027
|
try {
|
|
5985
6028
|
await this.keyStorage.deleteKey(I.key.value);
|
|
5986
|
-
} catch (
|
|
5987
|
-
u.logger.debug(f({ err:
|
|
5988
|
-
cerr:
|
|
6029
|
+
} catch (z) {
|
|
6030
|
+
u.logger.debug(f({ err: z })), u.logger.warn(f({
|
|
6031
|
+
cerr: z,
|
|
5989
6032
|
msg: "Couldn't delete mfa token",
|
|
5990
6033
|
hashedMfaToken: I.key.value
|
|
5991
6034
|
}));
|
|
@@ -5993,20 +6036,20 @@ class Dt {
|
|
|
5993
6036
|
return await this.makeAccessToken({
|
|
5994
6037
|
client: A,
|
|
5995
6038
|
client_secret: i,
|
|
5996
|
-
codeVerifier:
|
|
6039
|
+
codeVerifier: a,
|
|
5997
6040
|
scopes: R,
|
|
5998
6041
|
issueRefreshToken: j,
|
|
5999
6042
|
user: I.user
|
|
6000
6043
|
});
|
|
6001
|
-
} else if (
|
|
6002
|
-
if (!
|
|
6044
|
+
} else if (s == "urn:ietf:params:oauth:grant-type:device_code") {
|
|
6045
|
+
if (!C)
|
|
6003
6046
|
return {
|
|
6004
6047
|
error: "invalid_request",
|
|
6005
6048
|
error_description: "No device code given"
|
|
6006
6049
|
};
|
|
6007
6050
|
let R;
|
|
6008
6051
|
try {
|
|
6009
|
-
R = await this.keyStorage.getKey(U.deviceCode +
|
|
6052
|
+
R = await this.keyStorage.getKey(U.deviceCode + C);
|
|
6010
6053
|
} catch (P) {
|
|
6011
6054
|
const F = o.asCrossauthError(P);
|
|
6012
6055
|
return u.logger.debug(f({ err: F })), u.logger.error(f({ msg: "Couldn't get device code", cerr: F })), {
|
|
@@ -6017,7 +6060,7 @@ class Dt {
|
|
|
6017
6060
|
try {
|
|
6018
6061
|
const P = JSON.parse(R.data ?? "{}"), F = (/* @__PURE__ */ new Date()).getTime();
|
|
6019
6062
|
if (R.expires && F > R.expires.getTime())
|
|
6020
|
-
return await this.deleteDeviceCode(
|
|
6063
|
+
return await this.deleteDeviceCode(C), {
|
|
6021
6064
|
error: "expired_token",
|
|
6022
6065
|
error_description: "Code has expired"
|
|
6023
6066
|
};
|
|
@@ -6028,10 +6071,10 @@ class Dt {
|
|
|
6028
6071
|
};
|
|
6029
6072
|
{
|
|
6030
6073
|
let I = P.scope ? P.scope.split(" ") : void 0, $ = P.userid ? await ((B = this.userStorage) == null ? void 0 : B.getUserById(P.userid)) : void 0;
|
|
6031
|
-
return await this.deleteDeviceCode(
|
|
6074
|
+
return await this.deleteDeviceCode(C), await this.makeAccessToken({
|
|
6032
6075
|
client: A,
|
|
6033
6076
|
client_secret: i,
|
|
6034
|
-
codeVerifier:
|
|
6077
|
+
codeVerifier: a,
|
|
6035
6078
|
scopes: I,
|
|
6036
6079
|
issueRefreshToken: j,
|
|
6037
6080
|
user: $ == null ? void 0 : $.user
|
|
@@ -6039,7 +6082,7 @@ class Dt {
|
|
|
6039
6082
|
}
|
|
6040
6083
|
} catch (P) {
|
|
6041
6084
|
const F = o.asCrossauthError(P);
|
|
6042
|
-
return u.logger.debug(f({ err: F })), u.logger.error(f({ msg: "Couldn't get device code", cerr: F })), await this.deleteDeviceCode(
|
|
6085
|
+
return u.logger.debug(f({ err: F })), u.logger.error(f({ msg: "Couldn't get device code", cerr: F })), await this.deleteDeviceCode(C), {
|
|
6043
6086
|
error: "accerss_denied",
|
|
6044
6087
|
error_description: "Invalid device code"
|
|
6045
6088
|
};
|
|
@@ -6047,20 +6090,20 @@ class Dt {
|
|
|
6047
6090
|
} else
|
|
6048
6091
|
return {
|
|
6049
6092
|
error: "invalid_request",
|
|
6050
|
-
error_description: `Invalid grant_type ${
|
|
6093
|
+
error_description: `Invalid grant_type ${s}`
|
|
6051
6094
|
};
|
|
6052
6095
|
}
|
|
6053
|
-
async deleteDeviceCode(
|
|
6096
|
+
async deleteDeviceCode(s) {
|
|
6054
6097
|
try {
|
|
6055
|
-
await this.keyStorage.deleteKey(U.deviceCode +
|
|
6098
|
+
await this.keyStorage.deleteKey(U.deviceCode + s);
|
|
6056
6099
|
} catch (e) {
|
|
6057
6100
|
const t = o.asCrossauthError(e);
|
|
6058
6101
|
u.logger.debug(f({ err: t })), u.logger.error(f({ msg: "Couldn't delete device code", cerr: t }));
|
|
6059
6102
|
}
|
|
6060
6103
|
}
|
|
6061
|
-
async deleteUserCode(
|
|
6104
|
+
async deleteUserCode(s) {
|
|
6062
6105
|
try {
|
|
6063
|
-
await this.keyStorage.deleteKey(U.userCode +
|
|
6106
|
+
await this.keyStorage.deleteKey(U.userCode + s);
|
|
6064
6107
|
} catch (e) {
|
|
6065
6108
|
const t = o.asCrossauthError(e);
|
|
6066
6109
|
u.logger.debug(f({ err: t })), u.logger.error(f({ msg: "Couldn't delete user code", cerr: t }));
|
|
@@ -6078,11 +6121,11 @@ class Dt {
|
|
|
6078
6121
|
* endpoint JSON output.
|
|
6079
6122
|
*/
|
|
6080
6123
|
async deviceAuthorizationEndpoint({
|
|
6081
|
-
client_id:
|
|
6124
|
+
client_id: s,
|
|
6082
6125
|
scope: e,
|
|
6083
6126
|
client_secret: t
|
|
6084
6127
|
}) {
|
|
6085
|
-
var
|
|
6128
|
+
var C;
|
|
6086
6129
|
if (this.deviceCodeVerificationUri == "")
|
|
6087
6130
|
return {
|
|
6088
6131
|
error: "invalid_request",
|
|
@@ -6096,9 +6139,9 @@ class Dt {
|
|
|
6096
6139
|
error_description: "Invalid deviceCodeVerificationUri"
|
|
6097
6140
|
};
|
|
6098
6141
|
}
|
|
6099
|
-
const r = b.DeviceCode, i = await this.getClientById(
|
|
6142
|
+
const r = b.DeviceCode, i = await this.getClientById(s);
|
|
6100
6143
|
if (!i.client) return i;
|
|
6101
|
-
const
|
|
6144
|
+
const a = i.client, n = await this.authenticateClient(r, a, t);
|
|
6102
6145
|
if (n.error) return n;
|
|
6103
6146
|
if (!this.validFlows.includes(r))
|
|
6104
6147
|
return {
|
|
@@ -6106,10 +6149,10 @@ class Dt {
|
|
|
6106
6149
|
error_description: "Unsupported flow type " + r
|
|
6107
6150
|
};
|
|
6108
6151
|
if (e) {
|
|
6109
|
-
const { error: v, errorDescription:
|
|
6152
|
+
const { error: v, errorDescription: k } = this.validateScope(e);
|
|
6110
6153
|
if (v) return {
|
|
6111
6154
|
error: v,
|
|
6112
|
-
error_description:
|
|
6155
|
+
error_description: k
|
|
6113
6156
|
};
|
|
6114
6157
|
}
|
|
6115
6158
|
let c, d = !1;
|
|
@@ -6121,7 +6164,7 @@ class Dt {
|
|
|
6121
6164
|
U.deviceCode + c,
|
|
6122
6165
|
g,
|
|
6123
6166
|
p,
|
|
6124
|
-
JSON.stringify({ scope: e, client_id:
|
|
6167
|
+
JSON.stringify({ scope: e, client_id: s })
|
|
6125
6168
|
), d = !0;
|
|
6126
6169
|
} catch {
|
|
6127
6170
|
u.logger.debug(f({ msg: `Attempt number${v} at creating a unique authozation code failed` }));
|
|
@@ -6131,13 +6174,13 @@ class Dt {
|
|
|
6131
6174
|
error: "server_error",
|
|
6132
6175
|
error_description: "Couldn't create device code"
|
|
6133
6176
|
};
|
|
6134
|
-
let
|
|
6177
|
+
let _;
|
|
6135
6178
|
d = !1;
|
|
6136
6179
|
for (let v = 0; v < 10 && !d; ++v)
|
|
6137
6180
|
try {
|
|
6138
|
-
|
|
6181
|
+
_ = T.randomBase32(this.userCodeLength), await this.keyStorage.saveKey(
|
|
6139
6182
|
void 0,
|
|
6140
|
-
U.userCode +
|
|
6183
|
+
U.userCode + _,
|
|
6141
6184
|
g,
|
|
6142
6185
|
p,
|
|
6143
6186
|
JSON.stringify({ deviceCode: c })
|
|
@@ -6145,20 +6188,20 @@ class Dt {
|
|
|
6145
6188
|
} catch {
|
|
6146
6189
|
u.logger.debug(f({ msg: `Attempt number${v} at creating a unique authozation code failed` }));
|
|
6147
6190
|
}
|
|
6148
|
-
if (!d || !
|
|
6191
|
+
if (!d || !_)
|
|
6149
6192
|
return await this.deleteDeviceCode(c), {
|
|
6150
6193
|
error: "server_error",
|
|
6151
6194
|
error_description: "Couldn't create device code"
|
|
6152
6195
|
};
|
|
6153
|
-
if (
|
|
6196
|
+
if (_ && this.userCodeDashEvery) {
|
|
6154
6197
|
const v = new RegExp(String.raw`(.{1,${this.userCodeDashEvery}})`, "g");
|
|
6155
|
-
|
|
6198
|
+
_ = (C = _.match(v)) == null ? void 0 : C.join("-");
|
|
6156
6199
|
}
|
|
6157
6200
|
return {
|
|
6158
6201
|
device_code: c,
|
|
6159
|
-
user_code:
|
|
6202
|
+
user_code: _,
|
|
6160
6203
|
verification_uri: this.deviceCodeVerificationUri,
|
|
6161
|
-
verification_uri_complete: this.deviceCodeVerificationUri + "?user_code=" +
|
|
6204
|
+
verification_uri_complete: this.deviceCodeVerificationUri + "?user_code=" + _,
|
|
6162
6205
|
expires_in: y,
|
|
6163
6206
|
interval: this.deviceCodePollInterval
|
|
6164
6207
|
};
|
|
@@ -6175,14 +6218,14 @@ class Dt {
|
|
|
6175
6218
|
* endpoint JSON output.
|
|
6176
6219
|
*/
|
|
6177
6220
|
async deviceEndpoint({
|
|
6178
|
-
userCode:
|
|
6221
|
+
userCode: s,
|
|
6179
6222
|
user: e
|
|
6180
6223
|
}) {
|
|
6181
6224
|
var g;
|
|
6182
|
-
|
|
6225
|
+
s = s.replace(/[ -]*/g, "");
|
|
6183
6226
|
let t, r = {};
|
|
6184
6227
|
try {
|
|
6185
|
-
t = await this.keyStorage.getKey(U.userCode +
|
|
6228
|
+
t = await this.keyStorage.getKey(U.userCode + s), r = JSON.parse((t == null ? void 0 : t.data) ?? "{}");
|
|
6186
6229
|
} catch {
|
|
6187
6230
|
return {
|
|
6188
6231
|
ok: !1,
|
|
@@ -6191,7 +6234,7 @@ class Dt {
|
|
|
6191
6234
|
};
|
|
6192
6235
|
}
|
|
6193
6236
|
if (!r.deviceCode)
|
|
6194
|
-
return u.logger.error(f({ msg: "No device code for user code", userCodeHash: T.hash(
|
|
6237
|
+
return u.logger.error(f({ msg: "No device code for user code", userCodeHash: T.hash(s) })), await this.deleteUserCode(s), {
|
|
6195
6238
|
ok: !1,
|
|
6196
6239
|
error: "server_error",
|
|
6197
6240
|
error_description: "No device code for user code"
|
|
@@ -6203,29 +6246,29 @@ class Dt {
|
|
|
6203
6246
|
const p = o.asCrossauthError(y);
|
|
6204
6247
|
return u.logger.debug(f({ err: p })), u.logger.error(f({
|
|
6205
6248
|
msg: "Invalid device code for user code",
|
|
6206
|
-
userCodeHash: T.hash(
|
|
6249
|
+
userCodeHash: T.hash(s),
|
|
6207
6250
|
deviceCodeHash: T.hash(r.deviceCode),
|
|
6208
6251
|
cerr: p
|
|
6209
|
-
})), await this.deleteUserCode(
|
|
6252
|
+
})), await this.deleteUserCode(s), {
|
|
6210
6253
|
ok: !1,
|
|
6211
6254
|
error: "server_error",
|
|
6212
6255
|
error_description: "Invalid device code user code"
|
|
6213
6256
|
};
|
|
6214
6257
|
}
|
|
6215
|
-
let
|
|
6258
|
+
let a, n;
|
|
6216
6259
|
try {
|
|
6217
6260
|
if (!i.data) throw new o(l.UnknownError);
|
|
6218
6261
|
const y = JSON.parse(i.data);
|
|
6219
|
-
if (
|
|
6262
|
+
if (a = y.scope, n = y.client_id, !n) throw new o(l.UnknownError);
|
|
6220
6263
|
} catch {
|
|
6221
|
-
return await this.deleteUserCode(
|
|
6264
|
+
return await this.deleteUserCode(s), await this.deleteDeviceCode(r.deviceCode), {
|
|
6222
6265
|
ok: !1,
|
|
6223
6266
|
error: "server_error",
|
|
6224
6267
|
error_description: "Unexpected or incomplete data in device code key"
|
|
6225
6268
|
};
|
|
6226
6269
|
}
|
|
6227
6270
|
if ((/* @__PURE__ */ new Date()).getTime() > ((g = r.expires) == null ? void 0 : g.getTime()))
|
|
6228
|
-
return await this.deleteUserCode(
|
|
6271
|
+
return await this.deleteUserCode(s), {
|
|
6229
6272
|
ok: !1,
|
|
6230
6273
|
error: "expired_token",
|
|
6231
6274
|
error_description: "User code has expired",
|
|
@@ -6241,11 +6284,11 @@ class Dt {
|
|
|
6241
6284
|
let d = !1;
|
|
6242
6285
|
if (u.logger.debug(f({
|
|
6243
6286
|
msg: "Checking scopes have been authorized",
|
|
6244
|
-
scope:
|
|
6245
|
-
})),
|
|
6287
|
+
scope: a
|
|
6288
|
+
})), a ? d = await this.hasAllScopes(
|
|
6246
6289
|
n,
|
|
6247
6290
|
e,
|
|
6248
|
-
|
|
6291
|
+
a.split(" ")
|
|
6249
6292
|
) : d = await this.hasAllScopes(
|
|
6250
6293
|
n,
|
|
6251
6294
|
e,
|
|
@@ -6255,7 +6298,7 @@ class Dt {
|
|
|
6255
6298
|
e != null && e.id && await this.keyStorage.updateData(U.deviceCode + r.deviceCode, "userid", e.id);
|
|
6256
6299
|
} catch (y) {
|
|
6257
6300
|
const p = o.asCrossauthError(y);
|
|
6258
|
-
return u.logger.debug(f({ err: p })), u.logger.warn(f({ msg: "Couldn't update user id on user code entry - deleting", cerr: p })), await this.deleteUserCode(
|
|
6301
|
+
return u.logger.debug(f({ err: p })), u.logger.warn(f({ msg: "Couldn't update user id on user code entry - deleting", cerr: p })), await this.deleteUserCode(s), await this.deleteDeviceCode(r.deviceCode), {
|
|
6259
6302
|
ok: !1,
|
|
6260
6303
|
error: "access_denied",
|
|
6261
6304
|
error_description: "Invalid user code",
|
|
@@ -6264,7 +6307,7 @@ class Dt {
|
|
|
6264
6307
|
}
|
|
6265
6308
|
return {
|
|
6266
6309
|
ok: !0,
|
|
6267
|
-
scope:
|
|
6310
|
+
scope: a,
|
|
6268
6311
|
client_id: n,
|
|
6269
6312
|
scopeAuthorizationNeeded: !0
|
|
6270
6313
|
};
|
|
@@ -6273,24 +6316,24 @@ class Dt {
|
|
|
6273
6316
|
e != null && e.id && await this.keyStorage.updateData(U.deviceCode + r.deviceCode, "userid", e.id), await this.keyStorage.updateData(U.deviceCode + r.deviceCode, "ok", !0);
|
|
6274
6317
|
} catch (y) {
|
|
6275
6318
|
const p = o.asCrossauthError(y);
|
|
6276
|
-
return u.logger.debug(f({ err: p })), u.logger.warn(f({ msg: "Couldn't update status on user code entry - deleting", cerr: p })), await this.deleteUserCode(
|
|
6319
|
+
return u.logger.debug(f({ err: p })), u.logger.warn(f({ msg: "Couldn't update status on user code entry - deleting", cerr: p })), await this.deleteUserCode(s), await this.deleteDeviceCode(r.deviceCode), {
|
|
6277
6320
|
ok: !1,
|
|
6278
6321
|
error: "access_denied",
|
|
6279
6322
|
error_description: "Invalid user code",
|
|
6280
6323
|
client_id: n
|
|
6281
6324
|
};
|
|
6282
6325
|
}
|
|
6283
|
-
return await this.deleteUserCode(
|
|
6326
|
+
return await this.deleteUserCode(s), {
|
|
6284
6327
|
ok: !0,
|
|
6285
|
-
scope:
|
|
6328
|
+
scope: a,
|
|
6286
6329
|
client_id: n
|
|
6287
6330
|
};
|
|
6288
6331
|
}
|
|
6289
|
-
async authorizeDeviceFlowScopes(
|
|
6290
|
-
|
|
6332
|
+
async authorizeDeviceFlowScopes(s) {
|
|
6333
|
+
s = s.replace(/[ -]*/g, "");
|
|
6291
6334
|
let e, t = {};
|
|
6292
6335
|
try {
|
|
6293
|
-
e = await this.keyStorage.getKey(U.userCode +
|
|
6336
|
+
e = await this.keyStorage.getKey(U.userCode + s), t = JSON.parse((e == null ? void 0 : e.data) ?? "{}");
|
|
6294
6337
|
} catch {
|
|
6295
6338
|
return {
|
|
6296
6339
|
ok: !1,
|
|
@@ -6299,7 +6342,7 @@ class Dt {
|
|
|
6299
6342
|
};
|
|
6300
6343
|
}
|
|
6301
6344
|
if (!t.deviceCode)
|
|
6302
|
-
return u.logger.error(f({ msg: "No device code for user code", userCodeHash: T.hash(
|
|
6345
|
+
return u.logger.error(f({ msg: "No device code for user code", userCodeHash: T.hash(s) })), await this.deleteUserCode(s), {
|
|
6303
6346
|
ok: !1,
|
|
6304
6347
|
error: "server_error",
|
|
6305
6348
|
error_description: "No device code for user code"
|
|
@@ -6311,22 +6354,22 @@ class Dt {
|
|
|
6311
6354
|
const c = o.asCrossauthError(n);
|
|
6312
6355
|
return u.logger.debug(f({ err: c })), u.logger.error(f({
|
|
6313
6356
|
msg: "Invalid device code for user code",
|
|
6314
|
-
userCodeHash: T.hash(
|
|
6357
|
+
userCodeHash: T.hash(s),
|
|
6315
6358
|
deviceCodeHash: T.hash(t.deviceCode),
|
|
6316
6359
|
cerr: c
|
|
6317
|
-
})), await this.deleteUserCode(
|
|
6360
|
+
})), await this.deleteUserCode(s), {
|
|
6318
6361
|
ok: !1,
|
|
6319
6362
|
error: "server_error",
|
|
6320
6363
|
error_description: "Invalid device code user code"
|
|
6321
6364
|
};
|
|
6322
6365
|
}
|
|
6323
|
-
let i,
|
|
6366
|
+
let i, a;
|
|
6324
6367
|
try {
|
|
6325
6368
|
if (!r.data) throw new o(l.UnknownError);
|
|
6326
6369
|
const n = JSON.parse(r.data);
|
|
6327
|
-
if (i = n.scope,
|
|
6370
|
+
if (i = n.scope, a = n.client_id, !a) throw new o(l.UnknownError);
|
|
6328
6371
|
} catch {
|
|
6329
|
-
return await this.deleteUserCode(
|
|
6372
|
+
return await this.deleteUserCode(s), await this.deleteDeviceCode(t.deviceCode), {
|
|
6330
6373
|
ok: !1,
|
|
6331
6374
|
error: "server_error",
|
|
6332
6375
|
error_description: "Unexpected or incomplete data in device code key"
|
|
@@ -6336,33 +6379,33 @@ class Dt {
|
|
|
6336
6379
|
await this.keyStorage.updateData(U.deviceCode + t.deviceCode, "ok", !0);
|
|
6337
6380
|
} catch (n) {
|
|
6338
6381
|
const c = o.asCrossauthError(n);
|
|
6339
|
-
return u.logger.debug(f({ err: c })), u.logger.warn(f({ msg: "Couldn't update status on user code entry - deleting", cerr: c })), await this.deleteUserCode(
|
|
6382
|
+
return u.logger.debug(f({ err: c })), u.logger.warn(f({ msg: "Couldn't update status on user code entry - deleting", cerr: c })), await this.deleteUserCode(s), await this.deleteDeviceCode(t.deviceCode), {
|
|
6340
6383
|
ok: !1,
|
|
6341
6384
|
error: "access_denied",
|
|
6342
6385
|
error_description: "Invalid user code",
|
|
6343
|
-
client_id:
|
|
6386
|
+
client_id: a
|
|
6344
6387
|
};
|
|
6345
6388
|
}
|
|
6346
|
-
return await this.deleteUserCode(
|
|
6389
|
+
return await this.deleteUserCode(s), {
|
|
6347
6390
|
ok: !0,
|
|
6348
6391
|
scope: i,
|
|
6349
|
-
client_id:
|
|
6392
|
+
client_id: a
|
|
6350
6393
|
};
|
|
6351
6394
|
}
|
|
6352
|
-
async createMfaRequest(
|
|
6395
|
+
async createMfaRequest(s) {
|
|
6353
6396
|
const e = T.randomValue(this.codeLength), t = U.mfaToken + T.hash(e), r = /* @__PURE__ */ new Date();
|
|
6354
6397
|
try {
|
|
6355
6398
|
await this.keyStorage.saveKey(
|
|
6356
|
-
|
|
6399
|
+
s.id,
|
|
6357
6400
|
t,
|
|
6358
6401
|
r,
|
|
6359
6402
|
this.mfaTokenExpiry ? new Date(r.getTime() + (this.mfaTokenExpiry + this.clockTolerance) * 1e3) : void 0,
|
|
6360
|
-
JSON.stringify({ omfaaid:
|
|
6403
|
+
JSON.stringify({ omfaaid: s.factor2 })
|
|
6361
6404
|
);
|
|
6362
6405
|
} catch (i) {
|
|
6363
|
-
const
|
|
6364
|
-
u.logger.debug(f({ err:
|
|
6365
|
-
cerr:
|
|
6406
|
+
const a = o.asCrossauthError(i);
|
|
6407
|
+
u.logger.debug(f({ err: a })), u.logger.error(f({
|
|
6408
|
+
cerr: a,
|
|
6366
6409
|
msg: "Couldn't save MFA token"
|
|
6367
6410
|
}));
|
|
6368
6411
|
}
|
|
@@ -6372,11 +6415,11 @@ class Dt {
|
|
|
6372
6415
|
error_description: "Multifactor authentication required"
|
|
6373
6416
|
};
|
|
6374
6417
|
}
|
|
6375
|
-
async validateMfaToken(
|
|
6418
|
+
async validateMfaToken(s) {
|
|
6376
6419
|
var r;
|
|
6377
6420
|
let e, t;
|
|
6378
6421
|
try {
|
|
6379
|
-
const i = U.mfaToken + T.hash(
|
|
6422
|
+
const i = U.mfaToken + T.hash(s);
|
|
6380
6423
|
if (t = await this.keyStorage.getKey(i), !t.userid)
|
|
6381
6424
|
return {
|
|
6382
6425
|
error: "access_denied",
|
|
@@ -6387,8 +6430,8 @@ class Dt {
|
|
|
6387
6430
|
error: "server_error",
|
|
6388
6431
|
error_description: "No user storage defined"
|
|
6389
6432
|
};
|
|
6390
|
-
const { user:
|
|
6391
|
-
e =
|
|
6433
|
+
const { user: a } = await ((r = this.userStorage) == null ? void 0 : r.getUserById(t.userid));
|
|
6434
|
+
e = a;
|
|
6392
6435
|
} catch (i) {
|
|
6393
6436
|
return u.logger.debug(f({ err: i })), u.logger.error(f({
|
|
6394
6437
|
cerr: i,
|
|
@@ -6404,7 +6447,7 @@ class Dt {
|
|
|
6404
6447
|
error_description: "Invalid MFA token"
|
|
6405
6448
|
};
|
|
6406
6449
|
try {
|
|
6407
|
-
if (
|
|
6450
|
+
if (L.decodeData(t.data).omfaaid != e.factor2)
|
|
6408
6451
|
return {
|
|
6409
6452
|
error: "access_denied",
|
|
6410
6453
|
error_description: "authenticatorId not valid for user"
|
|
@@ -6417,8 +6460,8 @@ class Dt {
|
|
|
6417
6460
|
}
|
|
6418
6461
|
return { user: e, key: t };
|
|
6419
6462
|
}
|
|
6420
|
-
async mfaAuthenticatorsEndpoint(
|
|
6421
|
-
const e = await this.validateMfaToken(
|
|
6463
|
+
async mfaAuthenticatorsEndpoint(s) {
|
|
6464
|
+
const e = await this.validateMfaToken(s);
|
|
6422
6465
|
if (!e.user) return e;
|
|
6423
6466
|
const t = e.user;
|
|
6424
6467
|
if (!t.factor2)
|
|
@@ -6460,12 +6503,12 @@ class Dt {
|
|
|
6460
6503
|
* @param authenticatorId as defined by the Password MFA spec
|
|
6461
6504
|
* @returns respond as defined by the Password MFA spec
|
|
6462
6505
|
*/
|
|
6463
|
-
async mfaChallengeEndpoint(
|
|
6464
|
-
const
|
|
6506
|
+
async mfaChallengeEndpoint(s, e, t, r, i) {
|
|
6507
|
+
const a = b.PasswordMfa, n = await this.getClientById(e);
|
|
6465
6508
|
if (!n.client) return n;
|
|
6466
|
-
const c = n.client, d = await this.authenticateClient(
|
|
6509
|
+
const c = n.client, d = await this.authenticateClient(a, c, t);
|
|
6467
6510
|
if (d.error) return d;
|
|
6468
|
-
const g = await this.validateMfaToken(
|
|
6511
|
+
const g = await this.validateMfaToken(s);
|
|
6469
6512
|
if (!g.user || !g.key) return g;
|
|
6470
6513
|
if (g.user.factor2 != i)
|
|
6471
6514
|
return {
|
|
@@ -6488,11 +6531,11 @@ class Dt {
|
|
|
6488
6531
|
l.Configuration,
|
|
6489
6532
|
"User's authenticator has not been loaded"
|
|
6490
6533
|
);
|
|
6491
|
-
const
|
|
6534
|
+
const _ = await p.createOneTimeSecrets(g.user);
|
|
6492
6535
|
await this.keyStorage.updateData(
|
|
6493
6536
|
g.key.value,
|
|
6494
6537
|
"omfa",
|
|
6495
|
-
{ ...y, ...
|
|
6538
|
+
{ ...y, ..._ }
|
|
6496
6539
|
);
|
|
6497
6540
|
} catch (p) {
|
|
6498
6541
|
return u.logger.debug(f({ err: p })), {
|
|
@@ -6516,10 +6559,10 @@ class Dt {
|
|
|
6516
6559
|
* @param codeChallenge the OAuth code challenge (checks if it is defined)
|
|
6517
6560
|
* @returns returns the flow key from {@link @crossauth/common!OAuthFlows}
|
|
6518
6561
|
*/
|
|
6519
|
-
inferFlowFromGet(
|
|
6520
|
-
if (
|
|
6562
|
+
inferFlowFromGet(s, e, t) {
|
|
6563
|
+
if (s == "code" && !e.includes("openid"))
|
|
6521
6564
|
return t ? b.AuthorizationCodeWithPKCE : b.AuthorizationCode;
|
|
6522
|
-
if (e.includes("openid") &&
|
|
6565
|
+
if (e.includes("openid") && s == "code")
|
|
6523
6566
|
return t ? b.AuthorizationCodeWithPKCE : b.AuthorizationCode;
|
|
6524
6567
|
}
|
|
6525
6568
|
/**
|
|
@@ -6529,75 +6572,75 @@ class Dt {
|
|
|
6529
6572
|
* @param codeVerifier the OAuth code verifier (checks if it is defined)
|
|
6530
6573
|
* @returns returns the flow key from {@link @crossauth/common!OAuthFlows}
|
|
6531
6574
|
*/
|
|
6532
|
-
inferFlowFromPost(
|
|
6533
|
-
if (
|
|
6575
|
+
inferFlowFromPost(s, e) {
|
|
6576
|
+
if (s == "authorization_code")
|
|
6534
6577
|
return e ? b.AuthorizationCodeWithPKCE : b.AuthorizationCode;
|
|
6535
|
-
if (
|
|
6578
|
+
if (s == "client_credentials")
|
|
6536
6579
|
return b.ClientCredentials;
|
|
6537
|
-
if (
|
|
6580
|
+
if (s == "refresh_token")
|
|
6538
6581
|
return b.RefreshToken;
|
|
6539
|
-
if (
|
|
6582
|
+
if (s == "urn:ietf:params:oauth:grant-type:device_code")
|
|
6540
6583
|
return b.DeviceCode;
|
|
6541
|
-
if (
|
|
6584
|
+
if (s == "password")
|
|
6542
6585
|
return b.Password;
|
|
6543
|
-
if (
|
|
6586
|
+
if (s == "http://auth0.com/oauth/grant-type/mfa-otp")
|
|
6544
6587
|
return b.PasswordMfa;
|
|
6545
|
-
if (
|
|
6588
|
+
if (s == "http://auth0.com/oauth/grant-type/mfa-oob")
|
|
6546
6589
|
return b.PasswordMfa;
|
|
6547
6590
|
}
|
|
6548
|
-
async getAuthorizationCode(
|
|
6549
|
-
if (i && (
|
|
6591
|
+
async getAuthorizationCode(s, e, t, r, i, a, n) {
|
|
6592
|
+
if (i && (a || (a = "S256"), a != "S256" && a != "plain"))
|
|
6550
6593
|
return {
|
|
6551
6594
|
error: "invalid_request",
|
|
6552
6595
|
error_description: "Code challenge method must be S256 or plain"
|
|
6553
6596
|
};
|
|
6554
6597
|
const c = e;
|
|
6555
|
-
if (J.validateUri(c), this.requireRedirectUriRegistration && !
|
|
6598
|
+
if (J.validateUri(c), this.requireRedirectUriRegistration && !s.redirect_uri.includes(c))
|
|
6556
6599
|
return {
|
|
6557
6600
|
error: "invalid_request",
|
|
6558
6601
|
error_description: `The redirect uri ${e} is invalid`
|
|
6559
6602
|
};
|
|
6560
6603
|
const d = /* @__PURE__ */ new Date(), g = this.authorizationCodeExpiry ? new Date(d.getTime() + this.authorizationCodeExpiry * 1e3 + this.clockTolerance * 1e3) : void 0, y = {};
|
|
6561
|
-
t && (y.scope = t), i && (y.challengeMethod =
|
|
6604
|
+
t && (y.scope = t), i && (y.challengeMethod = a, y.challenge = T.hash(i)), n && (y.username = n.username, y.id = n.id);
|
|
6562
6605
|
const p = JSON.stringify(y);
|
|
6563
|
-
let
|
|
6564
|
-
for (let v = 0; v < 10 && !
|
|
6606
|
+
let _ = !1, C = "";
|
|
6607
|
+
for (let v = 0; v < 10 && !_; ++v)
|
|
6565
6608
|
try {
|
|
6566
|
-
|
|
6609
|
+
C = T.randomValue(this.codeLength), await this.keyStorage.saveKey(
|
|
6567
6610
|
void 0,
|
|
6568
|
-
U.authorizationCode + T.hash(
|
|
6611
|
+
U.authorizationCode + T.hash(C),
|
|
6569
6612
|
d,
|
|
6570
6613
|
g,
|
|
6571
6614
|
p
|
|
6572
|
-
),
|
|
6615
|
+
), _ = !0;
|
|
6573
6616
|
} catch {
|
|
6574
6617
|
u.logger.debug(f({ msg: `Attempt number${v} at creating a unique authozation code failed` }));
|
|
6575
6618
|
}
|
|
6576
|
-
if (!
|
|
6619
|
+
if (!_)
|
|
6577
6620
|
throw new o(
|
|
6578
6621
|
l.KeyExists,
|
|
6579
6622
|
"Couldn't create a authorization code"
|
|
6580
6623
|
);
|
|
6581
|
-
return { code:
|
|
6624
|
+
return { code: C, state: r };
|
|
6582
6625
|
}
|
|
6583
6626
|
/**
|
|
6584
6627
|
* Create an access token
|
|
6585
6628
|
*/
|
|
6586
6629
|
async makeAccessToken({
|
|
6587
|
-
client:
|
|
6630
|
+
client: s,
|
|
6588
6631
|
code: e,
|
|
6589
6632
|
client_secret: t,
|
|
6590
6633
|
codeVerifier: r,
|
|
6591
6634
|
scopes: i,
|
|
6592
|
-
issueRefreshToken:
|
|
6635
|
+
issueRefreshToken: a = !1,
|
|
6593
6636
|
user: n
|
|
6594
6637
|
}) {
|
|
6595
6638
|
var M, j;
|
|
6596
6639
|
let c = !0;
|
|
6597
6640
|
try {
|
|
6598
|
-
|
|
6641
|
+
s.client_secret != null && (c = await T.passwordsEqual(
|
|
6599
6642
|
t ?? "",
|
|
6600
|
-
|
|
6643
|
+
s.client_secret ?? ""
|
|
6601
6644
|
));
|
|
6602
6645
|
} catch (N) {
|
|
6603
6646
|
return u.logger.error(f({ err: N })), { error: "server_error", error_description: "Couldn't validate client" };
|
|
@@ -6610,7 +6653,7 @@ class Dt {
|
|
|
6610
6653
|
if (e) {
|
|
6611
6654
|
let N;
|
|
6612
6655
|
try {
|
|
6613
|
-
N = await this.keyStorage.getKey(U.authorizationCode + T.hash(e)), d =
|
|
6656
|
+
N = await this.keyStorage.getKey(U.authorizationCode + T.hash(e)), d = L.decodeData(N.data);
|
|
6614
6657
|
} catch (K) {
|
|
6615
6658
|
return u.logger.debug(f({ err: K })), {
|
|
6616
6659
|
error: "access_denied",
|
|
@@ -6623,7 +6666,7 @@ class Dt {
|
|
|
6623
6666
|
u.logger.warn(f({
|
|
6624
6667
|
err: K,
|
|
6625
6668
|
msg: "Couldn't delete authorization code from storatge",
|
|
6626
|
-
client_id:
|
|
6669
|
+
client_id: s == null ? void 0 : s.client_id
|
|
6627
6670
|
}));
|
|
6628
6671
|
}
|
|
6629
6672
|
i = d.scope;
|
|
@@ -6643,17 +6686,17 @@ class Dt {
|
|
|
6643
6686
|
}
|
|
6644
6687
|
const g = /* @__PURE__ */ new Date(), y = Math.ceil(g.getTime() / 1e3);
|
|
6645
6688
|
let p;
|
|
6646
|
-
const
|
|
6647
|
-
jti:
|
|
6689
|
+
const _ = T.uuid(), C = {
|
|
6690
|
+
jti: _,
|
|
6648
6691
|
iat: y,
|
|
6649
6692
|
iss: this.oauthIssuer,
|
|
6650
6693
|
sub: d.username,
|
|
6651
6694
|
type: "access"
|
|
6652
6695
|
};
|
|
6653
|
-
i && (
|
|
6696
|
+
i && (C.scope = i), this.accessTokenExpiry != null && (C.exp = y + this.accessTokenExpiry, p = new Date(g.getTime() + this.accessTokenExpiry * 1e3 + this.clockTolerance * 1e3)), this.audience && (C.aud = this.audience);
|
|
6654
6697
|
const v = await new Promise((N, K) => {
|
|
6655
|
-
|
|
6656
|
-
|
|
6698
|
+
se.sign(
|
|
6699
|
+
C,
|
|
6657
6700
|
this.secretOrPrivateKey,
|
|
6658
6701
|
{ algorithm: this.jwtAlgorithmChecked, keyid: "1" },
|
|
6659
6702
|
(O, B) => {
|
|
@@ -6667,11 +6710,11 @@ class Dt {
|
|
|
6667
6710
|
this.persistAccessToken && this.keyStorage && await ((M = this.keyStorage) == null ? void 0 : M.saveKey(
|
|
6668
6711
|
void 0,
|
|
6669
6712
|
// to avoid user storage dependency, we don't set this
|
|
6670
|
-
U.accessToken + T.hash(
|
|
6713
|
+
U.accessToken + T.hash(_),
|
|
6671
6714
|
g,
|
|
6672
6715
|
p
|
|
6673
6716
|
));
|
|
6674
|
-
let
|
|
6717
|
+
let k;
|
|
6675
6718
|
if (i && i.includes("openid")) {
|
|
6676
6719
|
if (this.userStorage && d.username)
|
|
6677
6720
|
try {
|
|
@@ -6685,7 +6728,7 @@ class Dt {
|
|
|
6685
6728
|
}
|
|
6686
6729
|
const N = T.uuid();
|
|
6687
6730
|
let K = {
|
|
6688
|
-
aud:
|
|
6731
|
+
aud: s.client_id,
|
|
6689
6732
|
jti: N,
|
|
6690
6733
|
iat: y,
|
|
6691
6734
|
iss: this.oauthIssuer,
|
|
@@ -6735,8 +6778,8 @@ class Dt {
|
|
|
6735
6778
|
K[B] = n[O[B]];
|
|
6736
6779
|
}
|
|
6737
6780
|
}
|
|
6738
|
-
K.scope = i, this.accessTokenExpiry != null && (K.exp = y + this.accessTokenExpiry),
|
|
6739
|
-
|
|
6781
|
+
K.scope = i, this.accessTokenExpiry != null && (K.exp = y + this.accessTokenExpiry), k = await new Promise((O, B) => {
|
|
6782
|
+
se.sign(
|
|
6740
6783
|
K,
|
|
6741
6784
|
this.secretOrPrivateKey,
|
|
6742
6785
|
{
|
|
@@ -6753,10 +6796,10 @@ class Dt {
|
|
|
6753
6796
|
});
|
|
6754
6797
|
}
|
|
6755
6798
|
let A;
|
|
6756
|
-
if (
|
|
6799
|
+
if (a) {
|
|
6757
6800
|
const N = {
|
|
6758
6801
|
username: d.username,
|
|
6759
|
-
client_id:
|
|
6802
|
+
client_id: s.client_id
|
|
6760
6803
|
};
|
|
6761
6804
|
i && (N.scope = i);
|
|
6762
6805
|
let K;
|
|
@@ -6767,8 +6810,8 @@ class Dt {
|
|
|
6767
6810
|
sub: d.username,
|
|
6768
6811
|
type: "access"
|
|
6769
6812
|
};
|
|
6770
|
-
this.refreshTokenExpiry != null && (B.exp = y + this.refreshTokenExpiry, K = this.refreshTokenExpiry ? new Date(y + this.refreshTokenExpiry * 1e3 + this.clockTolerance * 1e3) : void 0), this.audience && (
|
|
6771
|
-
|
|
6813
|
+
this.refreshTokenExpiry != null && (B.exp = y + this.refreshTokenExpiry, K = this.refreshTokenExpiry ? new Date(y + this.refreshTokenExpiry * 1e3 + this.clockTolerance * 1e3) : void 0), this.audience && (C.aud = this.oauthIssuer), A = await new Promise((R, P) => {
|
|
6814
|
+
se.sign(
|
|
6772
6815
|
B,
|
|
6773
6816
|
this.secretOrPrivateKey,
|
|
6774
6817
|
{ algorithm: this.jwtAlgorithmChecked, keyid: "1" },
|
|
@@ -6790,7 +6833,7 @@ class Dt {
|
|
|
6790
6833
|
}
|
|
6791
6834
|
return {
|
|
6792
6835
|
access_token: v,
|
|
6793
|
-
id_token:
|
|
6836
|
+
id_token: k,
|
|
6794
6837
|
refresh_token: A,
|
|
6795
6838
|
expires_in: this.accessTokenExpiry == null ? void 0 : this.accessTokenExpiry,
|
|
6796
6839
|
token_type: "Bearer",
|
|
@@ -6803,9 +6846,9 @@ class Dt {
|
|
|
6803
6846
|
* @param code the authorization code to look up
|
|
6804
6847
|
* @returns true or false
|
|
6805
6848
|
*/
|
|
6806
|
-
async validAuthorizationCode(
|
|
6849
|
+
async validAuthorizationCode(s) {
|
|
6807
6850
|
try {
|
|
6808
|
-
const e = U.authorizationCode + T.hash(
|
|
6851
|
+
const e = U.authorizationCode + T.hash(s);
|
|
6809
6852
|
return await this.keyStorage.getKey(e), !0;
|
|
6810
6853
|
} catch (e) {
|
|
6811
6854
|
return u.logger.debug(f({ err: e })), !1;
|
|
@@ -6817,9 +6860,9 @@ class Dt {
|
|
|
6817
6860
|
* @param token the refresh token to look up
|
|
6818
6861
|
* @returns true or false
|
|
6819
6862
|
*/
|
|
6820
|
-
async validRefreshToken(
|
|
6863
|
+
async validRefreshToken(s) {
|
|
6821
6864
|
try {
|
|
6822
|
-
const e = U.refreshToken + T.hash(
|
|
6865
|
+
const e = U.refreshToken + T.hash(s);
|
|
6823
6866
|
return await this.keyStorage.getKey(e), !0;
|
|
6824
6867
|
} catch (e) {
|
|
6825
6868
|
return u.logger.debug(f({ err: e })), !1;
|
|
@@ -6831,10 +6874,10 @@ class Dt {
|
|
|
6831
6874
|
* @returns the object parsed from the stored JSON data for the token,
|
|
6832
6875
|
* or undefined if there was an error
|
|
6833
6876
|
*/
|
|
6834
|
-
async getRefreshTokenData(
|
|
6835
|
-
if (
|
|
6877
|
+
async getRefreshTokenData(s) {
|
|
6878
|
+
if (s)
|
|
6836
6879
|
try {
|
|
6837
|
-
const e = U.refreshToken + T.hash(
|
|
6880
|
+
const e = U.refreshToken + T.hash(s), t = await this.keyStorage.getKey(e);
|
|
6838
6881
|
return JSON.parse(t.data || "{}");
|
|
6839
6882
|
} catch (e) {
|
|
6840
6883
|
u.logger.debug(f({ err: e }));
|
|
@@ -6848,9 +6891,9 @@ class Dt {
|
|
|
6848
6891
|
* @param token the token to validate
|
|
6849
6892
|
* @returns the payload or undefinedf if there was an error
|
|
6850
6893
|
*/
|
|
6851
|
-
async validIdToken(
|
|
6894
|
+
async validIdToken(s) {
|
|
6852
6895
|
try {
|
|
6853
|
-
return await this.validateJwt(
|
|
6896
|
+
return await this.validateJwt(s, "id");
|
|
6854
6897
|
} catch (e) {
|
|
6855
6898
|
u.logger.debug(f({ err: e }));
|
|
6856
6899
|
return;
|
|
@@ -6864,9 +6907,9 @@ class Dt {
|
|
|
6864
6907
|
* @returns the payload or undefinedf if there was an error ir the
|
|
6865
6908
|
* `type` field in the payload is not `access`.
|
|
6866
6909
|
*/
|
|
6867
|
-
async validAccessToken(
|
|
6910
|
+
async validAccessToken(s) {
|
|
6868
6911
|
try {
|
|
6869
|
-
const e = await this.validateJwt(
|
|
6912
|
+
const e = await this.validateJwt(s, "access");
|
|
6870
6913
|
if (this.persistAccessToken) {
|
|
6871
6914
|
const t = U.accessToken + T.hash(e.payload.jti);
|
|
6872
6915
|
await this.keyStorage.getKey(t);
|
|
@@ -6877,14 +6920,14 @@ class Dt {
|
|
|
6877
6920
|
return;
|
|
6878
6921
|
}
|
|
6879
6922
|
}
|
|
6880
|
-
async validateJwt(
|
|
6923
|
+
async validateJwt(s, e) {
|
|
6881
6924
|
return new Promise((t, r) => {
|
|
6882
|
-
|
|
6883
|
-
|
|
6925
|
+
se.verify(
|
|
6926
|
+
s,
|
|
6884
6927
|
this.secretOrPublicKey,
|
|
6885
6928
|
{ clockTolerance: this.clockTolerance, complete: !0 },
|
|
6886
|
-
(i,
|
|
6887
|
-
|
|
6929
|
+
(i, a) => {
|
|
6930
|
+
a ? !e || a.payload.type == e ? t(a) : r(new o(
|
|
6888
6931
|
l.Unauthorized,
|
|
6889
6932
|
"Invalid JWT type"
|
|
6890
6933
|
)) : i ? (u.logger.debug(f({ err: i })), r(new o(
|
|
@@ -6898,12 +6941,12 @@ class Dt {
|
|
|
6898
6941
|
);
|
|
6899
6942
|
});
|
|
6900
6943
|
}
|
|
6901
|
-
validateScope(
|
|
6944
|
+
validateScope(s) {
|
|
6902
6945
|
let e = [];
|
|
6903
6946
|
try {
|
|
6904
|
-
e =
|
|
6947
|
+
e = s.split(" ");
|
|
6905
6948
|
} catch {
|
|
6906
|
-
const r = "invalid_scope", i = `Invalid scope ${
|
|
6949
|
+
const r = "invalid_scope", i = `Invalid scope ${s}`;
|
|
6907
6950
|
return u.logger.debug(f({ err: o.fromOAuthError(r, i) })), {
|
|
6908
6951
|
error: r,
|
|
6909
6952
|
errorDescription: i
|
|
@@ -6913,10 +6956,10 @@ class Dt {
|
|
|
6913
6956
|
let t;
|
|
6914
6957
|
if (e.forEach((r) => {
|
|
6915
6958
|
if (!this.validScopes.includes(r)) {
|
|
6916
|
-
const i = "invalid_scope",
|
|
6917
|
-
u.logger.debug(f({ err: o.fromOAuthError(i,
|
|
6959
|
+
const i = "invalid_scope", a = `Illegal scope ${r}`;
|
|
6960
|
+
u.logger.debug(f({ err: o.fromOAuthError(i, a) })), t = {
|
|
6918
6961
|
error: i,
|
|
6919
|
-
errorDescription:
|
|
6962
|
+
errorDescription: a
|
|
6920
6963
|
};
|
|
6921
6964
|
}
|
|
6922
6965
|
}), t) return t;
|
|
@@ -6933,16 +6976,16 @@ class Dt {
|
|
|
6933
6976
|
* @param state the state to append
|
|
6934
6977
|
* @returns the new URL as a string.
|
|
6935
6978
|
*/
|
|
6936
|
-
redirect_uri(
|
|
6937
|
-
const r =
|
|
6938
|
-
return `${
|
|
6979
|
+
redirect_uri(s, e, t) {
|
|
6980
|
+
const r = s.includes("?") ? "&" : "?";
|
|
6981
|
+
return `${s}${r}code=${e}&state=${t}`;
|
|
6939
6982
|
}
|
|
6940
6983
|
/**
|
|
6941
6984
|
* @returns all the response types that are supported.
|
|
6942
6985
|
*/
|
|
6943
6986
|
responseTypesSupported() {
|
|
6944
|
-
let
|
|
6945
|
-
return (this.validFlows.includes(b.AuthorizationCode) || this.validFlows.includes(b.AuthorizationCodeWithPKCE) || this.validFlows.includes(b.OidcAuthorizationCode)) &&
|
|
6987
|
+
let s = [];
|
|
6988
|
+
return (this.validFlows.includes(b.AuthorizationCode) || this.validFlows.includes(b.AuthorizationCodeWithPKCE) || this.validFlows.includes(b.OidcAuthorizationCode)) && s.push("code"), s;
|
|
6946
6989
|
}
|
|
6947
6990
|
/**
|
|
6948
6991
|
* Returns an OIDC configuration object based on this authorization
|
|
@@ -6957,7 +7000,7 @@ class Dt {
|
|
|
6957
7000
|
* @returns the OIDC configuration
|
|
6958
7001
|
*/
|
|
6959
7002
|
oidcConfiguration({
|
|
6960
|
-
authorizeEndpoint:
|
|
7003
|
+
authorizeEndpoint: s,
|
|
6961
7004
|
tokenEndpoint: e,
|
|
6962
7005
|
jwksUri: t,
|
|
6963
7006
|
additionalClaims: r
|
|
@@ -6967,7 +7010,7 @@ class Dt {
|
|
|
6967
7010
|
const c = b.grantType(n);
|
|
6968
7011
|
c && (i = [...i, ...c]);
|
|
6969
7012
|
});
|
|
6970
|
-
const
|
|
7013
|
+
const a = [
|
|
6971
7014
|
"HS256",
|
|
6972
7015
|
"HS384",
|
|
6973
7016
|
"HS512",
|
|
@@ -6984,7 +7027,7 @@ class Dt {
|
|
|
6984
7027
|
return r || (r = []), {
|
|
6985
7028
|
issuer: this.oauthIssuer,
|
|
6986
7029
|
authorization_endpoint: new URL(
|
|
6987
|
-
|
|
7030
|
+
s ?? "authorize",
|
|
6988
7031
|
this.oauthIssuer
|
|
6989
7032
|
).toString(),
|
|
6990
7033
|
token_endpoint: new URL(
|
|
@@ -6996,9 +7039,9 @@ class Dt {
|
|
|
6996
7039
|
response_types_supported: this.responseTypesSupported(),
|
|
6997
7040
|
response_modes_supported: ["query"],
|
|
6998
7041
|
grant_types_supported: i,
|
|
6999
|
-
token_endpoint_auth_signing_alg_values_supported:
|
|
7042
|
+
token_endpoint_auth_signing_alg_values_supported: a,
|
|
7000
7043
|
subject_types_supported: ["public"],
|
|
7001
|
-
id_token_signing_alg_values_supported:
|
|
7044
|
+
id_token_signing_alg_values_supported: a,
|
|
7002
7045
|
claims_supported: [
|
|
7003
7046
|
"iss",
|
|
7004
7047
|
"sub",
|
|
@@ -7019,15 +7062,15 @@ class Dt {
|
|
|
7019
7062
|
* @returns an array of keys with exactly one or zero entries.
|
|
7020
7063
|
*/
|
|
7021
7064
|
jwks() {
|
|
7022
|
-
let
|
|
7065
|
+
let s = [];
|
|
7023
7066
|
if (this.jwtPublicKey) {
|
|
7024
|
-
const e =
|
|
7025
|
-
e.kid = "1", e.alg = this.jwtKeyType,
|
|
7067
|
+
const e = ze(this.jwtPublicKey).export({ format: "jwk" });
|
|
7068
|
+
e.kid = "1", e.alg = this.jwtKeyType, s.push(e);
|
|
7026
7069
|
}
|
|
7027
|
-
return { keys:
|
|
7070
|
+
return { keys: s };
|
|
7028
7071
|
}
|
|
7029
|
-
validateState(
|
|
7030
|
-
if (!/^[A-Za-z0-9_-]+$/.test(
|
|
7072
|
+
validateState(s) {
|
|
7073
|
+
if (!/^[A-Za-z0-9_-]+$/.test(s))
|
|
7031
7074
|
throw o.fromOAuthError("invalid_request");
|
|
7032
7075
|
}
|
|
7033
7076
|
/**
|
|
@@ -7040,16 +7083,16 @@ class Dt {
|
|
|
7040
7083
|
* @returns an empty object or an error if the parameters were not valid
|
|
7041
7084
|
*/
|
|
7042
7085
|
validateAuthorizeParameters({
|
|
7043
|
-
response_type:
|
|
7086
|
+
response_type: s,
|
|
7044
7087
|
client_id: e,
|
|
7045
7088
|
redirect_uri: t,
|
|
7046
7089
|
scope: r,
|
|
7047
7090
|
state: i,
|
|
7048
|
-
code_challenge:
|
|
7091
|
+
code_challenge: a,
|
|
7049
7092
|
code_challenge_method: n
|
|
7050
7093
|
}) {
|
|
7051
7094
|
let c;
|
|
7052
|
-
/^[A-Za-z0-9_-]+$/.test(
|
|
7095
|
+
/^[A-Za-z0-9_-]+$/.test(s) ? /^[A-Za-z0-9_-]+$/.test(e) ? r && !/^[A-Za-z0-9_+ -]+$/.test(r) ? c = "scope is invalid" : /^[A-Za-z0-9_-]+$/.test(i) ? a && !/^[A-Za-z0-9_-]+$/.test(a) ? c = "code_challenge is invalid" : n && !/^[A-Za-z0-9_-]+$/.test(n) && (c = "code_challenge_method is invalid") : c = "state is invalid" : c = "client_id is invalid" : c = "response_type is invalid";
|
|
7053
7096
|
try {
|
|
7054
7097
|
new URL(t);
|
|
7055
7098
|
} catch {
|
|
@@ -7132,22 +7175,22 @@ class nt extends Pe {
|
|
|
7132
7175
|
const r = await super.tokenAuthorized(e, t);
|
|
7133
7176
|
if (r && t == "access" && this.persistAccessToken && this.keyStorage)
|
|
7134
7177
|
try {
|
|
7135
|
-
const
|
|
7178
|
+
const a = U.accessToken + T.hash(r.jti), n = await this.keyStorage.getKey(a), c = /* @__PURE__ */ new Date();
|
|
7136
7179
|
if (n.expires && ((i = n.expires) == null ? void 0 : i.getTime()) < c.getTime()) {
|
|
7137
7180
|
u.logger.error(f({ msg: "Access token expired in storage but not in JWT" }));
|
|
7138
7181
|
return;
|
|
7139
7182
|
}
|
|
7140
|
-
} catch (
|
|
7183
|
+
} catch (a) {
|
|
7141
7184
|
u.logger.warn(f({
|
|
7142
7185
|
msg: "Couldn't get token from database - is it valid?",
|
|
7143
7186
|
hashedAccessToken: T.hash(r.jti)
|
|
7144
|
-
})), u.logger.debug(f({ err:
|
|
7187
|
+
})), u.logger.debug(f({ err: a }));
|
|
7145
7188
|
return;
|
|
7146
7189
|
}
|
|
7147
7190
|
return r;
|
|
7148
7191
|
}
|
|
7149
7192
|
}
|
|
7150
|
-
class
|
|
7193
|
+
class Ht extends Ke {
|
|
7151
7194
|
/**
|
|
7152
7195
|
* Constructor
|
|
7153
7196
|
* @param authServerBaseUrl bsae URI for the authorization server
|
|
@@ -7173,9 +7216,14 @@ class Bt extends Ke {
|
|
|
7173
7216
|
...t
|
|
7174
7217
|
});
|
|
7175
7218
|
h(this, "deviceAuthorizationUrl", "device_authorization");
|
|
7219
|
+
h(this, "userCreationType", "idToken");
|
|
7220
|
+
h(this, "userMatchField", "username");
|
|
7221
|
+
h(this, "idTokenMatchField", "sub");
|
|
7222
|
+
h(this, "userCreationFn");
|
|
7223
|
+
h(this, "userStorage");
|
|
7176
7224
|
this.client_id = r.client_id;
|
|
7177
7225
|
let i = {};
|
|
7178
|
-
w("stateLength", m.String, this, t, "OAUTH_STATE_LENGTH"), w("verifierLength", m.String, this, t, "OAUTH_VERIFIER_LENGTH"), w("client_secret", m.String, i, t, "OAUTH_CLIENT_SECRET"), w("codeChallengeMethod", m.String, this, t, "OAUTH_CODE_CHALLENGE_METHOD"), w("deviceAuthorizationUrl", m.String, this, t, "OAUTH_DEVICE_AUTHORIZATION_URL"), this.deviceAuthorizationUrl.startsWith("/") && (this.deviceAuthorizationUrl = this.deviceAuthorizationUrl.substring(1)), i.client_secret && (this.client_secret = i.client_secret);
|
|
7226
|
+
w("stateLength", m.String, this, t, "OAUTH_STATE_LENGTH"), w("verifierLength", m.String, this, t, "OAUTH_VERIFIER_LENGTH"), w("client_secret", m.String, i, t, "OAUTH_CLIENT_SECRET"), w("codeChallengeMethod", m.String, this, t, "OAUTH_CODE_CHALLENGE_METHOD"), w("deviceAuthorizationUrl", m.String, this, t, "OAUTH_DEVICE_AUTHORIZATION_URL"), this.deviceAuthorizationUrl.startsWith("/") && (this.deviceAuthorizationUrl = this.deviceAuthorizationUrl.substring(1)), i.client_secret && (this.client_secret = i.client_secret), w("userCreationType", m.String, this, t, "OAUTH_USER_CREATION_TYPE"), w("userMatchField", m.String, this, t, "OAUTH_USER_MATCH_FIELD"), w("idTokenMatchField", m.String, this, t, "OAUTH_IDTOKEN_MaTCH_FIELD"), this.userCreationType == "merge" ? this.userCreationFn = ot : this.userCreationType == "embed" ? this.userCreationFn = lt : t.userCreationFn && this.userCreationType == "custom" ? this.userCreationFn = t.userCreationFn : this.userCreationFn = ct, t.userStorage && (this.userStorage = t.userStorage);
|
|
7179
7227
|
}
|
|
7180
7228
|
/**
|
|
7181
7229
|
* Uses {@link @crossauth/backend!Crypto.randomValue} to create a random string
|
|
@@ -7195,7 +7243,38 @@ class Bt extends Ke {
|
|
|
7195
7243
|
return T.sha256(e);
|
|
7196
7244
|
}
|
|
7197
7245
|
}
|
|
7198
|
-
|
|
7246
|
+
async function ot(S, s, e, t) {
|
|
7247
|
+
if (!s) throw new o(l.Configuration, "userCreationType set to merge but no user storage set");
|
|
7248
|
+
try {
|
|
7249
|
+
let r;
|
|
7250
|
+
return e == "username" ? r = await s.getUserByUsername(S[t]) : e == "username" ? r = await s.getUserByEmail(S[t]) : r = await s.getUserBy(e, S[t]), { ...S, ...r.user };
|
|
7251
|
+
} catch (r) {
|
|
7252
|
+
const i = o.asCrossauthError(r);
|
|
7253
|
+
if (i.code == l.UserNotExist || i.code == l.UserNotActive)
|
|
7254
|
+
return;
|
|
7255
|
+
throw u.logger.error(f({ err: r })), r;
|
|
7256
|
+
}
|
|
7257
|
+
}
|
|
7258
|
+
async function lt(S, s, e, t) {
|
|
7259
|
+
if (!s) throw new o(l.Configuration, "userCreationType set to embed but no user storage set");
|
|
7260
|
+
try {
|
|
7261
|
+
let r;
|
|
7262
|
+
return e == "username" ? r = await s.getUserByUsername(S[t]) : e == "username" ? r = await s.getUserByEmail(S[t]) : r = await s.getUserBy(e, S[t]), { ...r.user, idToken: S };
|
|
7263
|
+
} catch (r) {
|
|
7264
|
+
const i = o.asCrossauthError(r);
|
|
7265
|
+
if (i.code == l.UserNotExist || i.code == l.UserNotActive)
|
|
7266
|
+
return;
|
|
7267
|
+
throw u.logger.error({ err: r }), r;
|
|
7268
|
+
}
|
|
7269
|
+
}
|
|
7270
|
+
async function ct(S, s, e, t) {
|
|
7271
|
+
return {
|
|
7272
|
+
id: S.userid ?? S.sub,
|
|
7273
|
+
username: S.sub,
|
|
7274
|
+
state: S.state ?? "active"
|
|
7275
|
+
};
|
|
7276
|
+
}
|
|
7277
|
+
class Mt {
|
|
7199
7278
|
/**
|
|
7200
7279
|
* Constructor
|
|
7201
7280
|
* @param tokenConsumers one or more consumers that will process
|
|
@@ -7203,13 +7282,13 @@ class zt {
|
|
|
7203
7282
|
* @param _options See {@link OAuthResourceServerOptions}. Unused
|
|
7204
7283
|
* at present
|
|
7205
7284
|
*/
|
|
7206
|
-
constructor(
|
|
7285
|
+
constructor(s, e = {}) {
|
|
7207
7286
|
/** The token consumer that validates the access tokens.
|
|
7208
7287
|
* Keyed on auth server base URL then audience. The latter may be ""
|
|
7209
7288
|
* for none
|
|
7210
7289
|
*/
|
|
7211
7290
|
h(this, "tokenConsumers");
|
|
7212
|
-
this.tokenConsumers = [...
|
|
7291
|
+
this.tokenConsumers = [...s];
|
|
7213
7292
|
}
|
|
7214
7293
|
/**
|
|
7215
7294
|
* Returns a token payload if the access token has a valid signature
|
|
@@ -7224,12 +7303,12 @@ class zt {
|
|
|
7224
7303
|
* @returns The JWT payload as an object or undefinedf if the JWT is
|
|
7225
7304
|
* invalid
|
|
7226
7305
|
*/
|
|
7227
|
-
async accessTokenAuthorized(
|
|
7306
|
+
async accessTokenAuthorized(s) {
|
|
7228
7307
|
try {
|
|
7229
|
-
const e = He.decodeJwt(
|
|
7308
|
+
const e = He.decodeJwt(s);
|
|
7230
7309
|
for (let t of this.tokenConsumers)
|
|
7231
7310
|
if (e.iss == t.authServerBaseUrl && (e.aud == t.audience || e.aud == null && t.audience == ""))
|
|
7232
|
-
return await t.tokenAuthorized(
|
|
7311
|
+
return await t.tokenAuthorized(s, "access");
|
|
7233
7312
|
throw new o(l.Unauthorized, "Invalid issuer in access token");
|
|
7234
7313
|
} catch (e) {
|
|
7235
7314
|
u.logger.warn(f({ err: e }));
|
|
@@ -7242,40 +7321,40 @@ export {
|
|
|
7242
7321
|
re as Authenticator,
|
|
7243
7322
|
T as Crypto,
|
|
7244
7323
|
rt as DoubleSubmitCsrfToken,
|
|
7245
|
-
|
|
7324
|
+
Rt as DummyFactor2Authenticator,
|
|
7246
7325
|
Z as EmailAuthenticator,
|
|
7247
|
-
|
|
7248
|
-
|
|
7249
|
-
|
|
7250
|
-
|
|
7251
|
-
|
|
7252
|
-
|
|
7326
|
+
At as InMemoryKeyStorage,
|
|
7327
|
+
Pt as InMemoryOAuthAuthorizationStorage,
|
|
7328
|
+
It as InMemoryOAuthClientStorage,
|
|
7329
|
+
Ut as InMemoryUserStorage,
|
|
7330
|
+
L as KeyStorage,
|
|
7331
|
+
xt as LdapAuthenticator,
|
|
7253
7332
|
oe as LdapUserStorage,
|
|
7254
7333
|
Te as LocalPasswordAuthenticator,
|
|
7255
|
-
|
|
7334
|
+
zt as OAuthAuthorizationServer,
|
|
7256
7335
|
we as OAuthAuthorizationStorage,
|
|
7257
|
-
|
|
7336
|
+
Ht as OAuthClientBackend,
|
|
7258
7337
|
J as OAuthClientManager,
|
|
7259
7338
|
me as OAuthClientStorage,
|
|
7260
|
-
|
|
7339
|
+
Mt as OAuthResourceServer,
|
|
7261
7340
|
nt as OAuthTokenConsumer,
|
|
7262
7341
|
m as ParamType,
|
|
7263
7342
|
be as PasswordAuthenticator,
|
|
7264
|
-
|
|
7265
|
-
|
|
7266
|
-
|
|
7267
|
-
|
|
7268
|
-
|
|
7269
|
-
|
|
7270
|
-
|
|
7343
|
+
Ft as PostgresKeyStorage,
|
|
7344
|
+
Nt as PostgresOAuthAuthorizationStorage,
|
|
7345
|
+
Ot as PostgresOAuthClientStorage,
|
|
7346
|
+
Kt as PostgresUserStorage,
|
|
7347
|
+
kt as PrismaKeyStorage,
|
|
7348
|
+
bt as PrismaOAuthAuthorizationStorage,
|
|
7349
|
+
Et as PrismaOAuthClientStorage,
|
|
7271
7350
|
G as PrismaUserStorage,
|
|
7272
7351
|
D as SessionCookie,
|
|
7273
|
-
|
|
7352
|
+
Lt as SessionManager,
|
|
7274
7353
|
Q as SmsAuthenticator,
|
|
7275
7354
|
x as TokenEmailer,
|
|
7276
|
-
|
|
7355
|
+
Dt as TotpAuthenticator,
|
|
7277
7356
|
Ue as TwilioAuthenticator,
|
|
7278
7357
|
H as UserStorage,
|
|
7279
7358
|
w as setParameter,
|
|
7280
|
-
|
|
7359
|
+
Bt as toCookieSerializeOptions
|
|
7281
7360
|
};
|