@crossauth/backend 0.0.14 → 0.0.16
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/dummyfactor2.d.ts +1 -3
- package/dist/authenticators/dummyfactor2.d.ts.map +1 -1
- package/dist/authenticators/tests/excl_ldapauth.test.d.ts +2 -0
- package/dist/authenticators/tests/excl_ldapauth.test.d.ts.map +1 -0
- package/dist/cookieauth.d.ts +2 -4
- package/dist/cookieauth.d.ts.map +1 -1
- package/dist/crypto.d.ts +22 -1
- package/dist/crypto.d.ts.map +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.js +526 -403
- package/dist/oauth/authserver.d.ts.map +1 -1
- package/dist/oauth/client.d.ts +62 -1
- package/dist/oauth/client.d.ts.map +1 -1
- package/dist/oauth/resserver.d.ts +5 -4
- package/dist/oauth/resserver.d.ts.map +1 -1
- package/dist/oauth/tokenconsumer.d.ts +2 -3
- package/dist/oauth/tokenconsumer.d.ts.map +1 -1
- package/dist/session.d.ts +1 -2
- package/dist/session.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 +12 -1
- 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/postgresstorage.d.ts +2 -2
- package/dist/storage/prismastorage.d.ts +12 -0
- package/dist/storage/prismastorage.d.ts.map +1 -1
- package/dist/storage/sqlitestorage.d.ts +2 -2
- package/dist/storage/tests/excl_ldapstorage.test.d.ts +2 -0
- package/dist/storage/tests/excl_ldapstorage.test.d.ts.map +1 -0
- package/dist/storage/tests/excl_postgresstorage.test.d.ts +2 -0
- package/dist/storage/tests/excl_postgresstorage.test.d.ts.map +1 -0
- package/dist/storage/tests/excl_sqlitestorage.test.d.ts +2 -0
- package/dist/storage/tests/excl_sqlitestorage.test.d.ts.map +1 -0
- package/dist/storage.d.ts +16 -0
- package/dist/storage.d.ts.map +1 -1
- package/package.json +6 -4
- package/dist/authenticators/tests/ldapauth.test.d.ts +0 -2
- package/dist/authenticators/tests/ldapauth.test.d.ts.map +0 -1
- package/dist/storage/tests/ldapstorage.test.d.ts +0 -2
- package/dist/storage/tests/ldapstorage.test.d.ts.map +0 -1
- package/dist/storage/tests/postgresstorage.test.d.ts +0 -2
- package/dist/storage/tests/postgresstorage.test.d.ts.map +0 -1
- package/dist/storage/tests/sqlitestorage.test.d.ts +0 -2
- package/dist/storage/tests/sqlitestorage.test.d.ts.map +0 -1
package/dist/index.js
CHANGED
|
@@ -2,20 +2,20 @@ var Ae = Object.defineProperty;
|
|
|
2
2
|
var Ie = (S, s, e) => s in S ? Ae(S, s, { enumerable: !0, configurable: !0, writable: !0, value: e }) : S[s] = e;
|
|
3
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
|
-
import { PrismaClient as
|
|
6
|
-
import
|
|
7
|
-
import { timingSafeEqual as
|
|
8
|
-
import { promisify as
|
|
5
|
+
import { PrismaClient as ce, Prisma as X } from "@prisma/client";
|
|
6
|
+
import ye from "ldapjs";
|
|
7
|
+
import { timingSafeEqual as he, randomBytes as ue, randomUUID as Fe, createHash as Oe, pbkdf2 as Ne, createHmac as ie, createCipheriv as Re, createDecipheriv as xe, randomInt as ee } from "node:crypto";
|
|
8
|
+
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
|
|
13
|
-
import { authenticator as
|
|
14
|
-
import
|
|
15
|
-
import { createPublicKey as
|
|
12
|
+
import Le from "qrcode";
|
|
13
|
+
import { authenticator as fe } from "otplib";
|
|
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
|
|
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
19
|
function Me(S, s) {
|
|
20
20
|
let e = S.split("."), t = s;
|
|
21
21
|
for (let r in e) {
|
|
@@ -25,7 +25,7 @@ function Me(S, s) {
|
|
|
25
25
|
}
|
|
26
26
|
return t;
|
|
27
27
|
}
|
|
28
|
-
function
|
|
28
|
+
function pe(S, s) {
|
|
29
29
|
let e = S.split("."), t = s;
|
|
30
30
|
for (let r in e) {
|
|
31
31
|
const i = e[r];
|
|
@@ -59,11 +59,11 @@ function Ve(S, s, e, t) {
|
|
|
59
59
|
break;
|
|
60
60
|
}
|
|
61
61
|
}
|
|
62
|
-
function
|
|
62
|
+
function w(S, s, e, t, r, i = !1) {
|
|
63
63
|
const a = "CROSSAUTH_" + r;
|
|
64
|
-
if (i && !
|
|
64
|
+
if (i && !pe(S, t) && !(a && a in process.env))
|
|
65
65
|
throw new o(l.Configuration, S + " is required");
|
|
66
|
-
|
|
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
|
/**
|
|
@@ -75,7 +75,7 @@ class H {
|
|
|
75
75
|
h(this, "adminEditableFields", []);
|
|
76
76
|
h(this, "normalizeUsername", !0);
|
|
77
77
|
h(this, "normalizeEmail", !0);
|
|
78
|
-
|
|
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.
|
|
@@ -98,7 +98,7 @@ class H {
|
|
|
98
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
|
|
@@ -150,7 +150,7 @@ class z {
|
|
|
150
150
|
return e in s ? (delete s[e], !0) : !1;
|
|
151
151
|
}
|
|
152
152
|
}
|
|
153
|
-
class
|
|
153
|
+
class me {
|
|
154
154
|
/**
|
|
155
155
|
* Constructor
|
|
156
156
|
* @param _options see {@link OAuthClientStorageOptions}
|
|
@@ -158,7 +158,7 @@ class ue {
|
|
|
158
158
|
constructor(s = {}) {
|
|
159
159
|
}
|
|
160
160
|
}
|
|
161
|
-
class
|
|
161
|
+
class we {
|
|
162
162
|
/**
|
|
163
163
|
* Constructor
|
|
164
164
|
* @param _options see {@link OAuthAuthorizationStorageOptions}
|
|
@@ -181,9 +181,9 @@ class G extends H {
|
|
|
181
181
|
h(this, "includes", ["secrets"]);
|
|
182
182
|
h(this, "includesObject", {});
|
|
183
183
|
h(this, "forceIdToNumber", !0);
|
|
184
|
-
|
|
184
|
+
w("userTable", m.String, this, e, "USER_TABLE"), w("userSecretsTable", m.String, this, e, "USER_SECRETS_TABLE"), w("idColumn", m.String, this, e, "USER_ID_COLUMN"), w("useridForeignKeyColumn", m.String, this, e, "USER_ID_FOREIGN_KEY_COLUMN"), w("includes", m.String, this, e, "USER_INCLUDES"), w("forceIdToNumber", m.String, this, e, "USER_FORCE_ID_TO_NUMBER"), this.includes.forEach((t) => {
|
|
185
185
|
this.includesObject[t] = !0;
|
|
186
|
-
}), e && e.prismaClient ? this.prismaClient = e.prismaClient : this.prismaClient = new
|
|
186
|
+
}), e && e.prismaClient ? this.prismaClient = e.prismaClient : this.prismaClient = new ce();
|
|
187
187
|
}
|
|
188
188
|
async getUser(e, t, r) {
|
|
189
189
|
let i, a;
|
|
@@ -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
|
*
|
|
@@ -277,7 +288,7 @@ class G extends H {
|
|
|
277
288
|
});
|
|
278
289
|
} catch {
|
|
279
290
|
}
|
|
280
|
-
let { userid:
|
|
291
|
+
let { userid: g, ...y } = d ?? {};
|
|
281
292
|
n = { ...y, ...n }, await c[this.userTable].update({
|
|
282
293
|
where: {
|
|
283
294
|
[this.idColumn]: e.id
|
|
@@ -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
|
*
|
|
@@ -414,7 +425,7 @@ class vt extends z {
|
|
|
414
425
|
h(this, "prismaClient");
|
|
415
426
|
h(this, "transactionTimeout", 5e3);
|
|
416
427
|
h(this, "useridForeignKeyColumn", "userid");
|
|
417
|
-
|
|
428
|
+
w("transactionTimeout", m.Number, this, e, "TRANSACTION_TIMEOUT"), w("useridForeignKeyColumn", m.Number, this, e, "USER_ID_FOREIGN_KEY_COLUMN"), e.keyTable && (this.keyTable = e.keyTable), e.prismaClient == null ? this.prismaClient = new ce() : this.prismaClient = e.prismaClient;
|
|
418
429
|
}
|
|
419
430
|
async getKey(e) {
|
|
420
431
|
return await this.getKeyWithTransaction(e, this.prismaClient);
|
|
@@ -672,7 +683,7 @@ class vt extends z {
|
|
|
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
|
*
|
|
@@ -688,7 +699,7 @@ class Tt extends ue {
|
|
|
688
699
|
h(this, "transactionTimeout", 5e3);
|
|
689
700
|
h(this, "updateMode", "DeleteAndInsert");
|
|
690
701
|
h(this, "useridForeignKeyColumn", "userid");
|
|
691
|
-
|
|
702
|
+
w("clientTable", m.String, this, e, "OAUTH_CLIENT_TABLE"), w("redirectUriTable", m.String, this, e, "OAUTH_REDIRECTURI_TABLE"), w("validFlowTable", m.String, this, e, "OAUTH_VALID_FLOW_TABLE"), w("transactionTimeout", m.Number, this, e, "TRANSACTION_TIMEOUT"), w("updateMode", m.String, this, e, "OAUTHCLIENT_UPDATE_MODE"), w("useridForeignKeyColumn", m.String, this, e, "USER_ID_FOREIGN_KEY_COLUMN"), e.prismaClient == null ? this.prismaClient = new ce() : this.prismaClient = e.prismaClient;
|
|
692
703
|
}
|
|
693
704
|
async getClientById(e) {
|
|
694
705
|
return (await this.getClientWithTransaction("client_id", e, this.prismaClient, !0, void 0))[0];
|
|
@@ -706,14 +717,14 @@ class Tt extends ue {
|
|
|
706
717
|
...n
|
|
707
718
|
},
|
|
708
719
|
include: { redirect_uri: !0, valid_flow: !0 }
|
|
709
|
-
}), d = c.redirect_uri,
|
|
720
|
+
}), d = c.redirect_uri, g = c.valid_flow;
|
|
710
721
|
let y = c[this.useridForeignKeyColumn];
|
|
711
722
|
return y === null && (y = void 0), this.useridForeignKeyColumn != "userid" && delete c[this.useridForeignKeyColumn], [{
|
|
712
723
|
...c,
|
|
713
724
|
userid: y,
|
|
714
725
|
client_secret: c.client_secret ?? void 0,
|
|
715
726
|
redirect_uri: d.map((p) => p.uri),
|
|
716
|
-
valid_flow:
|
|
727
|
+
valid_flow: g.map((p) => p.flow)
|
|
717
728
|
}];
|
|
718
729
|
} else {
|
|
719
730
|
const c = await r[this.clientTable].findMany({
|
|
@@ -724,9 +735,9 @@ class Tt extends ue {
|
|
|
724
735
|
include: { redirect_uri: !0, valid_flow: !0 }
|
|
725
736
|
});
|
|
726
737
|
for (let d of c) {
|
|
727
|
-
const
|
|
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 =
|
|
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
|
}
|
|
@@ -935,7 +946,7 @@ class Tt extends ue {
|
|
|
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
|
*
|
|
@@ -948,7 +959,7 @@ class _t extends fe {
|
|
|
948
959
|
// PrismaClient;
|
|
949
960
|
h(this, "transactionTimeout", 5e3);
|
|
950
961
|
h(this, "useridForeignKeyColumn", "userid");
|
|
951
|
-
|
|
962
|
+
w("authorizationTable", m.String, this, e, "OAUTH_CLIENT_TABLE"), w("transactionTimeout", m.Number, this, e, "TRANSACTION_TIMEOUT"), w("useridForeignKeyColumn", m.String, this, e, "USER_ID_FOREIGN_KEY_COLUMN"), e.prismaClient == null ? this.prismaClient = new ce() : this.prismaClient = e.prismaClient;
|
|
952
963
|
}
|
|
953
964
|
async getAuthorizations(e, t) {
|
|
954
965
|
try {
|
|
@@ -1000,10 +1011,10 @@ class _t extends fe {
|
|
|
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
|
-
* @param options
|
|
1017
|
+
* @param options see {@link InMemoryUserStorageOptions}
|
|
1007
1018
|
*/
|
|
1008
1019
|
constructor(e = {}) {
|
|
1009
1020
|
super(e);
|
|
@@ -1089,6 +1100,16 @@ class kt 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.
|
|
@@ -1136,7 +1157,7 @@ class kt extends H {
|
|
|
1136
1157
|
return i;
|
|
1137
1158
|
}
|
|
1138
1159
|
}
|
|
1139
|
-
class
|
|
1160
|
+
class At extends L {
|
|
1140
1161
|
/**
|
|
1141
1162
|
* Constructor
|
|
1142
1163
|
*/
|
|
@@ -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
|
*/
|
|
@@ -1380,7 +1401,7 @@ class bt extends ue {
|
|
|
1380
1401
|
return a;
|
|
1381
1402
|
}
|
|
1382
1403
|
}
|
|
1383
|
-
class
|
|
1404
|
+
class Pt extends we {
|
|
1384
1405
|
/**
|
|
1385
1406
|
* Constructor
|
|
1386
1407
|
*/
|
|
@@ -1418,7 +1439,7 @@ class Ut extends fe {
|
|
|
1418
1439
|
function $e(S, s) {
|
|
1419
1440
|
return { username: Array.isArray(s.uid) ? s.uid[0] : s.uid, state: "active", ...S };
|
|
1420
1441
|
}
|
|
1421
|
-
class
|
|
1442
|
+
class oe extends H {
|
|
1422
1443
|
/**
|
|
1423
1444
|
* Constructor.
|
|
1424
1445
|
* @param localStorage the underlying storage where users are kept (without passwords)
|
|
@@ -1431,7 +1452,7 @@ class ae extends H {
|
|
|
1431
1452
|
h(this, "ldapUserSearchBase", "");
|
|
1432
1453
|
h(this, "ldapUsernameAttribute", "cn");
|
|
1433
1454
|
h(this, "createUserFn", $e);
|
|
1434
|
-
this.localStorage = e,
|
|
1455
|
+
this.localStorage = e, w("ldapUrls", m.JsonArray, this, t, "LDAP_URL", !0), w("ldapUserSearchBase", m.String, this, t, "LDAP_USER_SEARCH_BASE"), w("ldapUsernameAttribute", m.String, this, t, "LDAP_USENAME_ATTRIBUTE"), t.createUserFn && (this.createUserFn = t.createUserFn);
|
|
1435
1456
|
}
|
|
1436
1457
|
/**
|
|
1437
1458
|
* Authenticates the user in LDAP and, if valid, creates a user in local
|
|
@@ -1474,7 +1495,18 @@ class ae 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,20 +1546,20 @@ class ae extends H {
|
|
|
1514
1546
|
async getLdapUser(e, t) {
|
|
1515
1547
|
let r;
|
|
1516
1548
|
try {
|
|
1517
|
-
const i =
|
|
1549
|
+
const i = oe.sanitizeLdapDnForSerach(e), a = [this.ldapUsernameAttribute + "=" + i, this.ldapUserSearchBase].join(",");
|
|
1518
1550
|
if (!t) throw new o(l.PasswordInvalid);
|
|
1519
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
1554
|
const a = o.asCrossauthError(i);
|
|
1523
|
-
throw i instanceof
|
|
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 a =
|
|
1562
|
+
let a = ye.createClient({ url: this.ldapUrls });
|
|
1531
1563
|
a.on("connect", function() {
|
|
1532
1564
|
a.bind(e, t, function(n) {
|
|
1533
1565
|
if (n) {
|
|
@@ -1559,17 +1591,17 @@ class ae extends H {
|
|
|
1559
1591
|
t,
|
|
1560
1592
|
n,
|
|
1561
1593
|
function(c, d) {
|
|
1562
|
-
let
|
|
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 ? a(new o(l.Connection, "LDAP onnection failed")) :
|
|
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
|
);
|
|
@@ -1595,7 +1627,7 @@ class ae extends H {
|
|
|
1595
1627
|
* @returns a sanitized dn
|
|
1596
1628
|
*/
|
|
1597
1629
|
static sanitizeLdapDnForSerach(e) {
|
|
1598
|
-
return
|
|
1630
|
+
return oe.sanitizeLdapDn(e).replace("*", "*").replace("(", "(").replace(")", ")");
|
|
1599
1631
|
}
|
|
1600
1632
|
}
|
|
1601
1633
|
class Y extends H {
|
|
@@ -1612,7 +1644,7 @@ class Y extends H {
|
|
|
1612
1644
|
h(this, "useridForeignKeyColumn", "userid");
|
|
1613
1645
|
h(this, "forceIdToNumber", !0);
|
|
1614
1646
|
h(this, "dbPool");
|
|
1615
|
-
this.dbPool = e,
|
|
1647
|
+
this.dbPool = e, w("userTable", m.String, this, t, "USER_TABLE"), w("userSecretsTable", m.String, this, t, "USER_SECRETS_TABLE"), w("idColumn", m.String, this, t, "USER_ID_COLUMN"), w("forceIdToNumber", m.String, this, t, "USER_FORCE_ID_TO_NUMBER"), w("useridForeignKeyColumn", m.String, this, t, "USER_ID_FOREIGN_KEY_COLUMN");
|
|
1616
1648
|
}
|
|
1617
1649
|
/**
|
|
1618
1650
|
* Returns user matching the given id, or throws an exception.
|
|
@@ -1649,29 +1681,40 @@ 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(), a, n;
|
|
1696
|
+
let i = await this.dbPool.connect(), a, n, c = this.dbPool.parameters();
|
|
1654
1697
|
try {
|
|
1655
1698
|
await i.startTransaction();
|
|
1656
|
-
let
|
|
1657
|
-
if (
|
|
1699
|
+
let d = `select * from ${this.userTable} where ${e} = ` + c.nextParameter(), g = await i.execute(d, [t]);
|
|
1700
|
+
if (g.length == 0)
|
|
1658
1701
|
throw new o(l.UserNotExist);
|
|
1659
|
-
let
|
|
1660
|
-
if (this.idColumn in
|
|
1702
|
+
let y, p, _;
|
|
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
|
-
if ("username" in
|
|
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
|
|
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
1709
|
if (a = {
|
|
1667
|
-
...
|
|
1668
|
-
id:
|
|
1669
|
-
username:
|
|
1670
|
-
state:
|
|
1710
|
+
...g[0],
|
|
1711
|
+
id: y,
|
|
1712
|
+
username: p,
|
|
1713
|
+
state: _
|
|
1671
1714
|
}, !a) throw new o(l.UserNotExist);
|
|
1672
|
-
if (c = `select * from ${this.userSecretsTable} where ${this.useridForeignKeyColumn} =
|
|
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 (
|
|
1717
|
+
if (g.length > 0 ? n = { userid: a.id, ...g[0] } : n = { userid: a.id }, !n) throw new o(l.UserNotExist);
|
|
1675
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
1720
|
if ((r == null ? void 0 : r.skipActiveCheck) != !0 && a.state == E.disabled)
|
|
@@ -1685,8 +1728,8 @@ class Y extends H {
|
|
|
1685
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
1730
|
return { user: a, secrets: n };
|
|
1688
|
-
} catch (
|
|
1689
|
-
throw await i.rollback(),
|
|
1731
|
+
} catch (d) {
|
|
1732
|
+
throw await i.rollback(), d;
|
|
1690
1733
|
} finally {
|
|
1691
1734
|
i.release();
|
|
1692
1735
|
}
|
|
@@ -1702,7 +1745,7 @@ class Y extends H {
|
|
|
1702
1745
|
let i = [], a = [], n = "", c = "", d = this.dbPool.parameters();
|
|
1703
1746
|
e && (c = "OFFSET " + d.nextParameter()), t && (a.push(t), n = "LIMIT " + d.nextParameter());
|
|
1704
1747
|
try {
|
|
1705
|
-
let
|
|
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) {
|
|
@@ -1722,8 +1765,8 @@ class Y extends H {
|
|
|
1722
1765
|
i.push(k);
|
|
1723
1766
|
}
|
|
1724
1767
|
return i;
|
|
1725
|
-
} catch (
|
|
1726
|
-
throw
|
|
1768
|
+
} catch (g) {
|
|
1769
|
+
throw g;
|
|
1727
1770
|
} finally {
|
|
1728
1771
|
r.release();
|
|
1729
1772
|
}
|
|
@@ -1748,21 +1791,21 @@ class Y extends H {
|
|
|
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();
|
|
1751
|
-
let
|
|
1794
|
+
let g = [], y = [];
|
|
1752
1795
|
for (let p in c)
|
|
1753
|
-
c[p] != null && p != "id" && (
|
|
1754
|
-
if (
|
|
1755
|
-
let p =
|
|
1796
|
+
c[p] != null && p != "id" && (g.push(p + "= " + i.nextParameter()), y.push(c[p]));
|
|
1797
|
+
if (g.length > 0) {
|
|
1798
|
+
let p = g.join(", ");
|
|
1756
1799
|
y.push(e.id);
|
|
1757
1800
|
let _ = `update ${this.userTable} set ${p} where ${this.idColumn} = ` + i.nextParameter();
|
|
1758
1801
|
await r.execute(_, y);
|
|
1759
1802
|
}
|
|
1760
1803
|
if (t) {
|
|
1761
|
-
|
|
1804
|
+
g = [], y = [], i = this.dbPool.parameters();
|
|
1762
1805
|
for (let p in d)
|
|
1763
|
-
d[p] != null && p != "userid" && (
|
|
1764
|
-
if (
|
|
1765
|
-
let p =
|
|
1806
|
+
d[p] != null && p != "userid" && (g.push(p + "= " + i.nextParameter()), y.push(d[p]));
|
|
1807
|
+
if (g.length > 0) {
|
|
1808
|
+
let p = g.join(", ");
|
|
1766
1809
|
y.push(e.id);
|
|
1767
1810
|
let _ = `update ${this.userSecretsTable} set ${p} where userid = ` + i.nextParameter();
|
|
1768
1811
|
await r.execute(_, y);
|
|
@@ -1793,27 +1836,27 @@ class Y extends H {
|
|
|
1793
1836
|
await r.startTransaction();
|
|
1794
1837
|
let a = { ...e }, n = t ? { ...t } : void 0;
|
|
1795
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
|
-
let c = [], d = [],
|
|
1839
|
+
let c = [], d = [], g = [];
|
|
1797
1840
|
const y = this.dbPool.parameters();
|
|
1798
1841
|
for (let _ in a)
|
|
1799
|
-
a[_] != null && _ != "id" && (c.push(_), d.push(y.nextParameter()),
|
|
1842
|
+
a[_] != null && _ != "id" && (c.push(_), d.push(y.nextParameter()), g.push(a[_]));
|
|
1800
1843
|
if (c.length > 0) {
|
|
1801
1844
|
let _ = c.join(", "), C = d.join(", ");
|
|
1802
|
-
const v = `insert into ${this.userTable} (${_}) values (${C}) returning ${this.idColumn}`, k = await r.execute(v,
|
|
1845
|
+
const v = `insert into ${this.userTable} (${_}) values (${C}) returning ${this.idColumn}`, k = await r.execute(v, g);
|
|
1803
1846
|
if (k.length == 0 || !k[0][this.idColumn]) throw new o(l.Connection, "Couldn't create user");
|
|
1804
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
|
-
c = [], d = [],
|
|
1851
|
+
c = [], d = [], g = [];
|
|
1809
1852
|
const _ = this.dbPool.parameters();
|
|
1810
|
-
c.push("userid"), d.push(_.nextParameter()),
|
|
1853
|
+
c.push("userid"), d.push(_.nextParameter()), g.push(i);
|
|
1811
1854
|
for (let C in n)
|
|
1812
|
-
n[C] != null && C != "userid" && (c.push(C), d.push(_.nextParameter()),
|
|
1855
|
+
n[C] != null && C != "userid" && (c.push(C), d.push(_.nextParameter()), g.push(n[C]));
|
|
1813
1856
|
if (c.length > 0) {
|
|
1814
1857
|
let C = c.join(", "), v = d.join(", ");
|
|
1815
1858
|
const k = `insert into ${this.userSecretsTable} (${C}) values (${v})`;
|
|
1816
|
-
u.logger.debug(f({ msg: "Executing query", query: k })), await r.execute(k,
|
|
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;
|
|
@@ -1830,8 +1873,8 @@ 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 a = `delete from ${this.userSecretsTable} where ${this.useridForeignKeyColumn}
|
|
1834
|
-
await t.execute(
|
|
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();
|
|
1835
1878
|
} catch (a) {
|
|
1836
1879
|
throw await t.rollback(), a;
|
|
1837
1880
|
} finally {
|
|
@@ -1851,8 +1894,8 @@ class Y extends H {
|
|
|
1851
1894
|
const t = await this.dbPool.connect();
|
|
1852
1895
|
try {
|
|
1853
1896
|
await t.startTransaction();
|
|
1854
|
-
let r = `delete from ${this.userSecretsTable} where ${this.useridForeignKeyColumn}
|
|
1855
|
-
await t.execute(
|
|
1897
|
+
let r = this.dbPool.parameters(), i = `delete from ${this.userSecretsTable} where ${this.useridForeignKeyColumn}=` + r.nextParameter();
|
|
1898
|
+
await t.execute(i, [e]), r = this.dbPool.parameters(), i = `delete from ${this.userTable} where ${this.idColumn}=` + r.nextParameter(), await t.execute(i, [e]), await t.commit();
|
|
1856
1899
|
} catch (r) {
|
|
1857
1900
|
throw await t.rollback(), r;
|
|
1858
1901
|
} finally {
|
|
@@ -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
|
*
|
|
@@ -1872,7 +1915,7 @@ class qe extends z {
|
|
|
1872
1915
|
h(this, "keyTable", "keys");
|
|
1873
1916
|
h(this, "dbPool");
|
|
1874
1917
|
h(this, "useridForeignKeyColumn", "userid");
|
|
1875
|
-
|
|
1918
|
+
w("transactionTimeout", m.Number, this, t, "TRANSACTION_TIMEOUT"), w("useridForeignKeyColumn", m.String, this, t, "USER_ID_FOREIGN_KEY_COLUMN"), t.keyTable && (this.keyTable = t.keyTable), this.dbPool = e;
|
|
1876
1919
|
}
|
|
1877
1920
|
async getKey(e) {
|
|
1878
1921
|
const t = await this.dbPool.connect();
|
|
@@ -1919,14 +1962,17 @@ class qe extends z {
|
|
|
1919
1962
|
* @throws {@link @crossauth/common!CrossauthError } if the key could not be stored.
|
|
1920
1963
|
*/
|
|
1921
1964
|
async saveKey(e, t, r, i, a, n = {}) {
|
|
1922
|
-
let c, d = [this.useridForeignKeyColumn, "value", "created", "expires", "data"],
|
|
1965
|
+
let c, d = [this.useridForeignKeyColumn, "value", "created", "expires", "data"], g = this.dbPool.parameters(), y = [];
|
|
1966
|
+
for (let k = 0; k < 5; ++k)
|
|
1967
|
+
y.push(g.nextParameter());
|
|
1968
|
+
let p = [e ?? null, t, r, i ?? null, a ?? ""];
|
|
1923
1969
|
for (let k in n)
|
|
1924
|
-
d.push(k),
|
|
1925
|
-
let _ = d.join(", "), C =
|
|
1970
|
+
d.push(k), y.push(g.nextParameter()), p.push(n[k]);
|
|
1971
|
+
let _ = d.join(", "), C = y.join(", ");
|
|
1926
1972
|
const v = await this.dbPool.connect();
|
|
1927
1973
|
try {
|
|
1928
1974
|
const k = `insert into ${this.keyTable} (${_}) values (${C})`;
|
|
1929
|
-
await v.execute(k,
|
|
1975
|
+
await v.execute(k, p);
|
|
1930
1976
|
} catch (k) {
|
|
1931
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"));
|
|
1932
1978
|
} finally {
|
|
@@ -1938,8 +1984,8 @@ class qe extends z {
|
|
|
1938
1984
|
async deleteKey(e) {
|
|
1939
1985
|
const t = await this.dbPool.connect();
|
|
1940
1986
|
try {
|
|
1941
|
-
let r = `delete from ${this.keyTable} where value
|
|
1942
|
-
u.logger.debug(f({ msg: "Executing query", query:
|
|
1987
|
+
let r = this.dbPool.parameters(), i = `delete from ${this.keyTable} where value=`;
|
|
1988
|
+
i += r.nextParameter(), u.logger.debug(f({ msg: "Executing query", query: i })), await t.execute(i, [e]);
|
|
1943
1989
|
} finally {
|
|
1944
1990
|
t.release();
|
|
1945
1991
|
}
|
|
@@ -1947,8 +1993,15 @@ class qe extends z {
|
|
|
1947
1993
|
async deleteAllForUser(e, t, r) {
|
|
1948
1994
|
const i = await this.dbPool.connect();
|
|
1949
1995
|
try {
|
|
1950
|
-
let a, n = [], c = "", d =
|
|
1951
|
-
|
|
1996
|
+
let a, n = [], c = "", d = this.dbPool.parameters();
|
|
1997
|
+
if (e) {
|
|
1998
|
+
const g = d.nextParameter(), y = d.nextParameter();
|
|
1999
|
+
a = `delete from ${this.keyTable} where ${this.useridForeignKeyColumn} = ${g} and value like ${y} `, n = [e];
|
|
2000
|
+
} else {
|
|
2001
|
+
const g = d.nextParameter();
|
|
2002
|
+
a = `delete from ${this.keyTable} where ${this.useridForeignKeyColumn} is null and value like ${g}`;
|
|
2003
|
+
}
|
|
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);
|
|
1952
2005
|
} catch (a) {
|
|
1953
2006
|
throw a;
|
|
1954
2007
|
} finally {
|
|
@@ -1961,8 +2014,8 @@ class qe extends z {
|
|
|
1961
2014
|
let r = [], i = [];
|
|
1962
2015
|
const a = this.dbPool.parameters();
|
|
1963
2016
|
for (let d in e) {
|
|
1964
|
-
let
|
|
1965
|
-
e[d] == null ? r.push(
|
|
2017
|
+
let g = d == "userid" ? this.useridForeignKeyColumn : d;
|
|
2018
|
+
e[d] == null ? r.push(g + " is null") : (r.push(g + " = " + a.nextParameter()), i.push(e[d]));
|
|
1966
2019
|
}
|
|
1967
2020
|
let n = r.join(" and "), c = `delete from ${this.keyTable} where ${n}`;
|
|
1968
2021
|
await t.execute(c, i);
|
|
@@ -2001,8 +2054,8 @@ class qe extends z {
|
|
|
2001
2054
|
if (c.length == 0)
|
|
2002
2055
|
return [];
|
|
2003
2056
|
for (let d of c) {
|
|
2004
|
-
let
|
|
2005
|
-
this.useridForeignKeyColumn != "userid" && (
|
|
2057
|
+
let g = this.makeKey(d);
|
|
2058
|
+
this.useridForeignKeyColumn != "userid" && (g.userid = g[this.useridForeignKeyColumn], delete g[this.useridForeignKeyColumn]), r.push(g);
|
|
2006
2059
|
}
|
|
2007
2060
|
return r;
|
|
2008
2061
|
} catch (r) {
|
|
@@ -2101,7 +2154,7 @@ class qe extends z {
|
|
|
2101
2154
|
}
|
|
2102
2155
|
}
|
|
2103
2156
|
}
|
|
2104
|
-
class We extends
|
|
2157
|
+
class We extends me {
|
|
2105
2158
|
/**
|
|
2106
2159
|
* Constructor with user storage object to use plus optional parameters.
|
|
2107
2160
|
*
|
|
@@ -2114,7 +2167,7 @@ class We extends ue {
|
|
|
2114
2167
|
h(this, "validFlowTable", "oauthclientvalidflow");
|
|
2115
2168
|
h(this, "dbPool");
|
|
2116
2169
|
h(this, "useridForeignKeyColumn", "userid");
|
|
2117
|
-
|
|
2170
|
+
w("clientTable", m.String, this, t, "OAUTH_CLIENT_TABLE"), w("redirectUriTable", m.String, this, t, "OAUTH_REDIRECTURI_TABLE"), w("validFlowTable", m.String, this, t, "OAUTH_VALID_FLOW_TABLE"), w("updateMode", m.String, this, t, "OAUTHCLIENT_UPDATE_MODE"), w("useridForeignKeyColumn", m.String, this, t, "USER_ID_FOREIGN_KEY_COLUMN"), this.dbPool = e;
|
|
2118
2171
|
}
|
|
2119
2172
|
async getClientById(e) {
|
|
2120
2173
|
let t = await this.dbPool.connect();
|
|
@@ -2157,12 +2210,12 @@ class We extends ue {
|
|
|
2157
2210
|
};
|
|
2158
2211
|
}
|
|
2159
2212
|
async getClientWithTransaction(e, t, r, i, a, n) {
|
|
2160
|
-
let c = [], d = this.dbPool.parameters(),
|
|
2161
|
-
t && r && (p = `where c.${t} = ` + d.nextParameter(),
|
|
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 = "";
|
|
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)));
|
|
2162
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 = "";
|
|
2163
|
-
t && r && (C = `where c.${t} = ` + d.nextParameter(),
|
|
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;
|
|
2164
2217
|
let v = y + " union " + _ + " order by client_id";
|
|
2165
|
-
const k = await e.execute(v,
|
|
2218
|
+
const k = await e.execute(v, g);
|
|
2166
2219
|
let A;
|
|
2167
2220
|
for (let M of k)
|
|
2168
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);
|
|
@@ -2202,14 +2255,14 @@ class We extends ue {
|
|
|
2202
2255
|
for (let C = 0; C < i.length; ++C)
|
|
2203
2256
|
if (!b.isValidFlow(i[C])) throw new o(l.InvalidOAuthFlow, "Invalid flow " + i[C]);
|
|
2204
2257
|
}
|
|
2205
|
-
let c = [], d = [],
|
|
2258
|
+
let c = [], d = [], g = [], y = this.dbPool.parameters();
|
|
2206
2259
|
try {
|
|
2207
2260
|
for (let C in n)
|
|
2208
|
-
c.push(C), d.push(y.nextParameter()),
|
|
2261
|
+
c.push(C), d.push(y.nextParameter()), g.push(n[C]);
|
|
2209
2262
|
if (c.length > 0) {
|
|
2210
2263
|
let C = c.join(", "), v = d.join(", ");
|
|
2211
2264
|
const k = `insert into ${this.clientTable} (${C}) values (${v})`;
|
|
2212
|
-
await e.execute(k,
|
|
2265
|
+
await e.execute(k, g);
|
|
2213
2266
|
}
|
|
2214
2267
|
} catch (C) {
|
|
2215
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"));
|
|
@@ -2220,15 +2273,15 @@ class We extends ue {
|
|
|
2220
2273
|
let _ = p[0];
|
|
2221
2274
|
if (r)
|
|
2222
2275
|
for (let C = 0; C < r.length; ++C) {
|
|
2223
|
-
|
|
2276
|
+
g = [], y = this.dbPool.parameters();
|
|
2224
2277
|
let v = `insert into ${this.redirectUriTable} (client_id, uri) values (` + y.nextParameter() + ", " + y.nextParameter() + ")";
|
|
2225
|
-
|
|
2278
|
+
g.push(_.client_id), g.push(r[C]), await e.execute(v, g);
|
|
2226
2279
|
}
|
|
2227
2280
|
if (i)
|
|
2228
2281
|
for (let C = 0; C < i.length; ++C) {
|
|
2229
|
-
|
|
2282
|
+
g = [], y = this.dbPool.parameters();
|
|
2230
2283
|
let v = `insert into ${this.validFlowTable} (client_id, flow) values (` + y.nextParameter() + ", " + y.nextParameter() + ")";
|
|
2231
|
-
|
|
2284
|
+
g.push(_.client_id), g.push(i[C]), await e.execute(v, g);
|
|
2232
2285
|
}
|
|
2233
2286
|
return { ..._, redirect_uri: r, valid_flow: i };
|
|
2234
2287
|
}
|
|
@@ -2290,26 +2343,26 @@ class We extends ue {
|
|
|
2290
2343
|
if (!t.client_id) throw new o(l.InvalidClientId, "No client ig given");
|
|
2291
2344
|
let { client_id: a, redirect_uri: n, valid_flow: c, ...d } = t;
|
|
2292
2345
|
n || (n = []), c || (c = []);
|
|
2293
|
-
let
|
|
2294
|
-
await e.execute(y, [t.client_id]),
|
|
2346
|
+
let g = this.dbPool.parameters(), y = `delete from ${this.redirectUriTable} where client_id = ` + g.nextParameter();
|
|
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]);
|
|
2295
2348
|
let p = [], _ = [], C = [];
|
|
2296
|
-
|
|
2349
|
+
g = this.dbPool.parameters(), y = `delete from ${this.validFlowTable} where client_id = ` + g.nextParameter();
|
|
2297
2350
|
for (let v in d)
|
|
2298
|
-
p.push(v), _.push(
|
|
2351
|
+
p.push(v), _.push(g.nextParameter()), C.push(d[v]);
|
|
2299
2352
|
if (p.length > 0) {
|
|
2300
2353
|
let v = p.join(", "), k = _.join(", ");
|
|
2301
2354
|
y = `update ${this.clientTable} set (${v}) values (${k})`, await e.execute(y, C);
|
|
2302
2355
|
}
|
|
2303
2356
|
if (n)
|
|
2304
2357
|
for (let v = 0; v < n.length; ++v) {
|
|
2305
|
-
C = [],
|
|
2306
|
-
let k = `insert into ${this.redirectUriTable} (client_id, uri) values (` +
|
|
2358
|
+
C = [], g = this.dbPool.parameters();
|
|
2359
|
+
let k = `insert into ${this.redirectUriTable} (client_id, uri) values (` + g.nextParameter() + ", " + g.nextParameter() + ")";
|
|
2307
2360
|
C.push(t.client_id), C.push(n[v]), await e.execute(k, C);
|
|
2308
2361
|
}
|
|
2309
2362
|
if (c)
|
|
2310
2363
|
for (let v = 0; v < c.length; ++v) {
|
|
2311
|
-
C = [],
|
|
2312
|
-
let k = `insert into ${this.validFlowTable} (client_id, flow) values (` +
|
|
2364
|
+
C = [], g = this.dbPool.parameters();
|
|
2365
|
+
let k = `insert into ${this.validFlowTable} (client_id, flow) values (` + g.nextParameter() + ", " + g.nextParameter() + ")";
|
|
2313
2366
|
C.push(t.client_id), C.push(c[v]), await e.execute(k, C);
|
|
2314
2367
|
}
|
|
2315
2368
|
}
|
|
@@ -2326,7 +2379,7 @@ class We extends ue {
|
|
|
2326
2379
|
}
|
|
2327
2380
|
}
|
|
2328
2381
|
}
|
|
2329
|
-
class Je extends
|
|
2382
|
+
class Je extends we {
|
|
2330
2383
|
/**
|
|
2331
2384
|
* Constructor with user storage object to use plus optional parameters.
|
|
2332
2385
|
*
|
|
@@ -2337,14 +2390,14 @@ class Je extends fe {
|
|
|
2337
2390
|
h(this, "authorizationTable", "oauthauthorization");
|
|
2338
2391
|
h(this, "useridForeignKeyColumn", "userid");
|
|
2339
2392
|
h(this, "dbPool");
|
|
2340
|
-
|
|
2393
|
+
w("authorizationTable", m.String, this, t, "OAUTH_CLIENT_TABLE"), w("useridForeignKeyColumn", m.String, this, t, "USER_ID_FOREIGN_KEY_COLUMN"), this.dbPool = e;
|
|
2341
2394
|
}
|
|
2342
2395
|
async getAuthorizations(e, t) {
|
|
2343
2396
|
let r = await this.dbPool.connect();
|
|
2344
2397
|
try {
|
|
2345
2398
|
const i = this.dbPool.parameters(), a = [];
|
|
2346
2399
|
let n = `select scope from ${this.authorizationTable} where client_id = ` + i.nextParameter();
|
|
2347
|
-
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((
|
|
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);
|
|
2348
2401
|
} catch (i) {
|
|
2349
2402
|
throw i;
|
|
2350
2403
|
} finally {
|
|
@@ -2377,7 +2430,7 @@ class Ge {
|
|
|
2377
2430
|
}
|
|
2378
2431
|
class Ze {
|
|
2379
2432
|
}
|
|
2380
|
-
class
|
|
2433
|
+
class de extends Ye {
|
|
2381
2434
|
constructor(e) {
|
|
2382
2435
|
super();
|
|
2383
2436
|
h(this, "pgPool");
|
|
@@ -2435,44 +2488,44 @@ class Qe extends Ge {
|
|
|
2435
2488
|
return "$" + this.nextParam++;
|
|
2436
2489
|
}
|
|
2437
2490
|
}
|
|
2438
|
-
class
|
|
2491
|
+
class Kt extends Y {
|
|
2439
2492
|
/**
|
|
2440
2493
|
* Creates a PostgresUserStorage object, optionally overriding defaults.
|
|
2441
2494
|
* @param pgPool the instance of the Posrgres client.
|
|
2442
2495
|
* @param options see {@link PostgresUserStorageOptions}.
|
|
2443
2496
|
*/
|
|
2444
2497
|
constructor(s, e = {}) {
|
|
2445
|
-
super(new
|
|
2498
|
+
super(new de(s), e);
|
|
2446
2499
|
}
|
|
2447
2500
|
}
|
|
2448
|
-
class
|
|
2501
|
+
class Ft extends qe {
|
|
2449
2502
|
/**
|
|
2450
2503
|
* Creates a PostgresKeyStorage object, optionally overriding defaults.
|
|
2451
2504
|
* @param pgPool the instance of the Posrgres client.
|
|
2452
2505
|
* @param options see {@link PostgresKeyStorageOptions}.
|
|
2453
2506
|
*/
|
|
2454
2507
|
constructor(s, e = {}) {
|
|
2455
|
-
super(new
|
|
2508
|
+
super(new de(s), e);
|
|
2456
2509
|
}
|
|
2457
2510
|
}
|
|
2458
|
-
class
|
|
2511
|
+
class Ot extends We {
|
|
2459
2512
|
/**
|
|
2460
2513
|
* Creates a PostgresOAuthClientStorage object, optionally overriding defaults.
|
|
2461
2514
|
* @param pgPool the instance of the Posrgres client.
|
|
2462
|
-
* @param options see {@link
|
|
2515
|
+
* @param options see {@link PostgresOAuthClientStorageOptions}.
|
|
2463
2516
|
*/
|
|
2464
2517
|
constructor(s, e = {}) {
|
|
2465
|
-
super(new
|
|
2518
|
+
super(new de(s), e);
|
|
2466
2519
|
}
|
|
2467
2520
|
}
|
|
2468
|
-
class
|
|
2521
|
+
class Nt extends Je {
|
|
2469
2522
|
/**
|
|
2470
|
-
* Creates a
|
|
2523
|
+
* Creates a PostgresOAuthClientStorage object, optionally overriding defaults.
|
|
2471
2524
|
* @param pgPool the instance of the Posrgres client.
|
|
2472
2525
|
* @param options see {@link PostgresOAuthAuthorizationStorageOptions}.
|
|
2473
2526
|
*/
|
|
2474
2527
|
constructor(s, e = {}) {
|
|
2475
|
-
super(new
|
|
2528
|
+
super(new de(s), e);
|
|
2476
2529
|
}
|
|
2477
2530
|
}
|
|
2478
2531
|
class re {
|
|
@@ -2513,7 +2566,7 @@ class be extends re {
|
|
|
2513
2566
|
return "none";
|
|
2514
2567
|
}
|
|
2515
2568
|
}
|
|
2516
|
-
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 {
|
|
2517
2570
|
/**
|
|
2518
2571
|
* Returns true if the plaintext password, when hashed, equals the one in the hash, using
|
|
2519
2572
|
* it's hasher settings
|
|
@@ -2533,7 +2586,7 @@ const pe = process.env.PBKDF2_DIGEST || "sha256", Ce = Number(process.env.PBKDF2
|
|
|
2533
2586
|
});
|
|
2534
2587
|
if (i.length != r.hashedPassword.length)
|
|
2535
2588
|
throw new o(l.PasswordInvalid);
|
|
2536
|
-
return
|
|
2589
|
+
return he(Buffer.from(i), Buffer.from(r.hashedPassword));
|
|
2537
2590
|
}
|
|
2538
2591
|
/**
|
|
2539
2592
|
* Decodes a string from base64 to UTF-89
|
|
@@ -2541,7 +2594,7 @@ const pe = process.env.PBKDF2_DIGEST || "sha256", Ce = Number(process.env.PBKDF2
|
|
|
2541
2594
|
* @returns URF-8 text
|
|
2542
2595
|
*/
|
|
2543
2596
|
static base64Decode(s) {
|
|
2544
|
-
return Buffer.from(s, "
|
|
2597
|
+
return Buffer.from(s, "base64url").toString("utf-8");
|
|
2545
2598
|
}
|
|
2546
2599
|
/**
|
|
2547
2600
|
* Base64-encodes UTF-8 text
|
|
@@ -2549,7 +2602,7 @@ const pe = process.env.PBKDF2_DIGEST || "sha256", Ce = Number(process.env.PBKDF2
|
|
|
2549
2602
|
* @returns Base64 text
|
|
2550
2603
|
*/
|
|
2551
2604
|
static base64Encode(s) {
|
|
2552
|
-
return Buffer.from(s, "utf-8").toString("
|
|
2605
|
+
return Buffer.from(s, "utf-8").toString("base64url");
|
|
2553
2606
|
}
|
|
2554
2607
|
/**
|
|
2555
2608
|
* Splits a hashed password into its component parts. Return it as a {@link PasswordHash }.
|
|
@@ -2609,7 +2662,7 @@ const pe = process.env.PBKDF2_DIGEST || "sha256", Ce = Number(process.env.PBKDF2
|
|
|
2609
2662
|
* @returns the random value as a string. Number of bytes will be greater as it is base64 encoded.
|
|
2610
2663
|
*/
|
|
2611
2664
|
static randomValue(s) {
|
|
2612
|
-
return
|
|
2665
|
+
return ue(s).toString("base64url");
|
|
2613
2666
|
}
|
|
2614
2667
|
// not real base32 - omits 1,i,0,o
|
|
2615
2668
|
/**
|
|
@@ -2619,7 +2672,7 @@ const pe = process.env.PBKDF2_DIGEST || "sha256", Ce = Number(process.env.PBKDF2
|
|
|
2619
2672
|
*/
|
|
2620
2673
|
static randomBase32(s, e) {
|
|
2621
2674
|
var i;
|
|
2622
|
-
const r = [...
|
|
2675
|
+
const r = [...ue(s)].map((a) => q.Base32[a % 32]).join("");
|
|
2623
2676
|
return e ? ((i = r.match(/(.{1,4})/g)) == null ? void 0 : i.join("-")) ?? r : r;
|
|
2624
2677
|
}
|
|
2625
2678
|
/**
|
|
@@ -2660,21 +2713,21 @@ const pe = process.env.PBKDF2_DIGEST || "sha256", Ce = Number(process.env.PBKDF2
|
|
|
2660
2713
|
t || (t = q.randomSalt());
|
|
2661
2714
|
let a = r != null, n = a ? t + "!" + r : t;
|
|
2662
2715
|
i == null && (i = !1);
|
|
2663
|
-
let
|
|
2716
|
+
let g = (await De(Ne)(
|
|
2664
2717
|
s,
|
|
2665
2718
|
n,
|
|
2666
|
-
e.iterations ??
|
|
2667
|
-
e.keyLen ??
|
|
2668
|
-
e.digest ??
|
|
2719
|
+
e.iterations ?? Se,
|
|
2720
|
+
e.keyLen ?? ve,
|
|
2721
|
+
e.digest ?? Ce
|
|
2669
2722
|
)).toString("base64url");
|
|
2670
|
-
return i && (
|
|
2671
|
-
|
|
2723
|
+
return i && (g = this.encodePasswordHash(
|
|
2724
|
+
g,
|
|
2672
2725
|
t,
|
|
2673
2726
|
a,
|
|
2674
|
-
e.iterations ??
|
|
2675
|
-
e.keyLen ??
|
|
2676
|
-
e.digest ??
|
|
2677
|
-
)),
|
|
2727
|
+
e.iterations ?? Se,
|
|
2728
|
+
e.keyLen ?? ve,
|
|
2729
|
+
e.digest ?? Ce
|
|
2730
|
+
)), g;
|
|
2678
2731
|
}
|
|
2679
2732
|
/**
|
|
2680
2733
|
* For creating non-JWT tokens (eg password reset tokens.) The
|
|
@@ -2699,9 +2752,21 @@ const pe = process.env.PBKDF2_DIGEST || "sha256", Ce = Number(process.env.PBKDF2
|
|
|
2699
2752
|
* @returns Base64-url encoded hash
|
|
2700
2753
|
*/
|
|
2701
2754
|
static sign(s, e, t, r) {
|
|
2702
|
-
|
|
2703
|
-
|
|
2704
|
-
|
|
2755
|
+
const i = q.signableToken(s, t, r), a = ie(ae, e);
|
|
2756
|
+
return i + "." + a.update(i).digest("base64url");
|
|
2757
|
+
}
|
|
2758
|
+
/**
|
|
2759
|
+
* This can be called for a string payload that is a cryptographically
|
|
2760
|
+
* secure random string. No salt is added and the token is assumed to
|
|
2761
|
+
* be Base64Url already
|
|
2762
|
+
*
|
|
2763
|
+
* @param payload string to sign
|
|
2764
|
+
* @param secret the secret to sign with
|
|
2765
|
+
* @returns Base64-url encoded hash
|
|
2766
|
+
*/
|
|
2767
|
+
static signSecureToken(s, e) {
|
|
2768
|
+
const t = ie(ae, e);
|
|
2769
|
+
return s + "." + t.update(s).digest("base64url");
|
|
2705
2770
|
}
|
|
2706
2771
|
/**
|
|
2707
2772
|
* Validates a signature and, if valid, return the unstringified payload
|
|
@@ -2719,13 +2784,33 @@ const pe = process.env.PBKDF2_DIGEST || "sha256", Ce = Number(process.env.PBKDF2
|
|
|
2719
2784
|
const i = r[0], a = r[1], n = JSON.parse(Buffer.from(i, "base64url").toString());
|
|
2720
2785
|
if (t && n.t + t * 1e3 > (/* @__PURE__ */ new Date()).getTime())
|
|
2721
2786
|
throw new o(l.Expired);
|
|
2722
|
-
const d =
|
|
2787
|
+
const d = ie(ae, e).update(i).digest("base64url");
|
|
2723
2788
|
if (d.length != a.length)
|
|
2724
2789
|
throw new o(l.InvalidKey, "Signature does not match payload");
|
|
2725
|
-
if (!
|
|
2790
|
+
if (!he(Buffer.from(d), Buffer.from(a)))
|
|
2726
2791
|
throw new o(l.InvalidKey, "Signature does not match payload");
|
|
2727
2792
|
return n;
|
|
2728
2793
|
}
|
|
2794
|
+
/**
|
|
2795
|
+
* Validates a signature signed with `signSecureToken` and, if valid,
|
|
2796
|
+
* return the unstringified payload
|
|
2797
|
+
* @param signedMessage signed message (base64-url encoded)
|
|
2798
|
+
* @param secret secret key, which must be a string
|
|
2799
|
+
* @returns if signature is valid, the payload as a string
|
|
2800
|
+
* @throws {@link @crossauth/common!CrossauthError} with
|
|
2801
|
+
* {@link @crossauth/common!ErrorCode} of `InvalidKey` if signature
|
|
2802
|
+
* is invalid or has expired.
|
|
2803
|
+
*/
|
|
2804
|
+
static unsignSecureToken(s, e) {
|
|
2805
|
+
const t = s.split(".");
|
|
2806
|
+
if (t.length != 2) throw new o(l.InvalidKey);
|
|
2807
|
+
const r = t[0], i = t[1], a = r, c = ie(ae, e).update(r).digest("base64url");
|
|
2808
|
+
if (c.length != i.length)
|
|
2809
|
+
throw new o(l.InvalidKey, "Signature does not match payload");
|
|
2810
|
+
if (!he(Buffer.from(c), Buffer.from(i)))
|
|
2811
|
+
throw new o(l.InvalidKey, "Signature does not match payload");
|
|
2812
|
+
return a;
|
|
2813
|
+
}
|
|
2729
2814
|
/**
|
|
2730
2815
|
* XOR's two arrays of base64url-encoded strings
|
|
2731
2816
|
* @param value to XOR
|
|
@@ -2744,7 +2829,7 @@ const pe = process.env.PBKDF2_DIGEST || "sha256", Ce = Number(process.env.PBKDF2
|
|
|
2744
2829
|
* @returns Encrypted text Base64-url encoded.
|
|
2745
2830
|
*/
|
|
2746
2831
|
static symmetricEncrypt(s, e, t = void 0) {
|
|
2747
|
-
t || (t =
|
|
2832
|
+
t || (t = ue(16));
|
|
2748
2833
|
let r = Buffer.from(e, "base64url");
|
|
2749
2834
|
var i = Re("aes-256-cbc", r, t);
|
|
2750
2835
|
let a = i.update(s);
|
|
@@ -2762,7 +2847,7 @@ const pe = process.env.PBKDF2_DIGEST || "sha256", Ce = Number(process.env.PBKDF2
|
|
|
2762
2847
|
const r = s.split(".");
|
|
2763
2848
|
if (r.length != 2) throw new o(l.InvalidHash, "Not AES-256-CBC ciphertext");
|
|
2764
2849
|
let i = Buffer.from(r[0], "base64url"), a = Buffer.from(r[1], "base64url");
|
|
2765
|
-
var n =
|
|
2850
|
+
var n = xe("aes-256-cbc", t, i);
|
|
2766
2851
|
let c = n.update(a);
|
|
2767
2852
|
return c = Buffer.concat([c, n.final()]), c.toString();
|
|
2768
2853
|
}
|
|
@@ -2778,7 +2863,7 @@ function tt(S) {
|
|
|
2778
2863
|
}
|
|
2779
2864
|
return s;
|
|
2780
2865
|
}
|
|
2781
|
-
const
|
|
2866
|
+
const le = class le extends be {
|
|
2782
2867
|
/**
|
|
2783
2868
|
* Create a new authenticator.
|
|
2784
2869
|
*
|
|
@@ -2802,7 +2887,7 @@ const ne = class ne extends be {
|
|
|
2802
2887
|
h(this, "pbkdf2KeyLength", 32);
|
|
2803
2888
|
/** See {@link LocalPasswordAuthenticatorOptions.validatePasswordFn} */
|
|
2804
2889
|
h(this, "validatePasswordFn", tt);
|
|
2805
|
-
|
|
2890
|
+
w("secret", m.String, this, t, "HASHER_SECRET"), w("enableSecretForPasswordHash", m.Boolean, this, t, "ENABLE_SECRET_FOR_PASSWORDS"), w("pbkdf2Digest", m.String, this, t, "PASSWORD_PBKDF2_DIGEST"), w("pbkdf2Iterations", m.String, this, t, "PASSWORD_PBKDF2_ITERATIONS"), w("pbkdf2SaltLength", m.String, this, t, "PASSWORD_PBKDF2_SALTLENGTH"), w("pbkdf2KeyLength", m.String, this, t, "PASSWORD_PBKDF2_KEYLENGTH"), t.validatePasswordFn && (this.validatePasswordFn = t.validatePasswordFn);
|
|
2806
2891
|
}
|
|
2807
2892
|
/**
|
|
2808
2893
|
* Authenticates the user, returning a the user as a {@link User} object.
|
|
@@ -2877,7 +2962,7 @@ const ne = class ne extends be {
|
|
|
2877
2962
|
* @returns true if match, false otherwise
|
|
2878
2963
|
*/
|
|
2879
2964
|
async passwordMatchesHash(e, t, r) {
|
|
2880
|
-
return t ==
|
|
2965
|
+
return t == le.NoPassword ? !1 : await T.passwordsEqual(e, t, r);
|
|
2881
2966
|
}
|
|
2882
2967
|
/**
|
|
2883
2968
|
* This will return p hash of the passed password.
|
|
@@ -2934,8 +3019,8 @@ const ne = class ne extends be {
|
|
|
2934
3019
|
async reprepareConfiguration(e, t) {
|
|
2935
3020
|
}
|
|
2936
3021
|
};
|
|
2937
|
-
h(
|
|
2938
|
-
let Te =
|
|
3022
|
+
h(le, "NoPassword", "********");
|
|
3023
|
+
let Te = le;
|
|
2939
3024
|
class Z extends re {
|
|
2940
3025
|
/**
|
|
2941
3026
|
* Constructor
|
|
@@ -2956,7 +3041,7 @@ class Z extends re {
|
|
|
2956
3041
|
h(this, "smtpPassword");
|
|
2957
3042
|
h(this, "emailAuthenticatorTokenExpires", 60 * 5);
|
|
2958
3043
|
h(this, "render");
|
|
2959
|
-
|
|
3044
|
+
w("views", m.String, this, e, "VIEWS"), w("emailAuthenticatorTextBody", m.String, this, e, "EMAIL_AUTHENTICATOR_TEXT_BODY"), w("emailAuthenticatorHtmlBody", m.String, this, e, "EMAIL_AUTHENTICATOR_HTML_BODY"), w("emailAuthenticatorSubject", m.String, this, e, "EMAIL_AUTHENTICATOR_SUBJECT"), w("emailFrom", m.String, this, e, "EMAIL_FROM", !0), w("smtpHost", m.String, this, e, "SMTP_HOST", !0), w("smtpPort", m.Number, this, e, "SMTP_PORT"), w("smtpUsername", m.String, this, e, "SMTP_USERNAME"), w("smtpPassword", m.String, this, e, "SMTP_PASSWORD"), w("smtpUseTls", m.Boolean, this, e, "SMTP_USE_TLS"), w("emailAuthenticatorTokenExpires", m.Number, this, e, "EMAIL_AUTHENTICATOR_TOKEN_EXPIRES"), e.render ? this.render = e.render : W.configure(this.views, { autoescape: !0 });
|
|
2960
3045
|
}
|
|
2961
3046
|
/**
|
|
2962
3047
|
* Used by the OAuth password_mfa grant type.
|
|
@@ -3027,7 +3112,7 @@ class Z extends re {
|
|
|
3027
3112
|
* @returns
|
|
3028
3113
|
*/
|
|
3029
3114
|
async reprepareConfiguration(e, t) {
|
|
3030
|
-
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);
|
|
3031
3116
|
return u.logger.info(f({
|
|
3032
3117
|
msg: "Sent factor otp email",
|
|
3033
3118
|
emailMessageId: c,
|
|
@@ -3164,7 +3249,7 @@ class Q extends re {
|
|
|
3164
3249
|
h(this, "smsAuthenticatorFrom", "");
|
|
3165
3250
|
h(this, "smsAuthenticatorTokenExpires", 60 * 5);
|
|
3166
3251
|
h(this, "render");
|
|
3167
|
-
|
|
3252
|
+
w("views", m.String, this, e, "VIEWS"), w("smsAuthenticatorBody", m.String, this, e, "SMS_AUTHENTICATOR_BODY"), w("smsAuthenticatorFrom", m.String, this, e, "SMS_AUTHENTICATOR_FROM", !0), w("smsAuthenticatorTokenExpires", m.Number, this, e, "SMS_AUTHENTICATOR_TOKEN_EXPIRES"), e.render ? this.render = e.render : W.configure(this.views, { autoescape: !0 });
|
|
3168
3253
|
}
|
|
3169
3254
|
/**
|
|
3170
3255
|
* Used by the OAuth password_mfa grant type.
|
|
@@ -3204,7 +3289,7 @@ class Q extends re {
|
|
|
3204
3289
|
otp: t
|
|
3205
3290
|
};
|
|
3206
3291
|
let d = { otp: t };
|
|
3207
|
-
const
|
|
3292
|
+
const g = this.render ? this.render(this.smsAuthenticatorBody, d) : W.render(this.smsAuthenticatorBody, d), y = this.sendSms(r, g);
|
|
3208
3293
|
return u.logger.info(f({
|
|
3209
3294
|
msg: "Sent factor otp sms",
|
|
3210
3295
|
smsMessageId: y,
|
|
@@ -3218,7 +3303,7 @@ class Q extends re {
|
|
|
3218
3303
|
* @returns
|
|
3219
3304
|
*/
|
|
3220
3305
|
async reprepareConfiguration(e, t) {
|
|
3221
|
-
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);
|
|
3222
3307
|
return u.logger.info(f({
|
|
3223
3308
|
msg: "Sent factor otp sms",
|
|
3224
3309
|
smsMessageId: c,
|
|
@@ -3382,7 +3467,7 @@ class Ue extends Q {
|
|
|
3382
3467
|
return (await Be(this.accountSid, this.authToken).messages.create(r)).sid;
|
|
3383
3468
|
}
|
|
3384
3469
|
}
|
|
3385
|
-
class
|
|
3470
|
+
class Rt extends re {
|
|
3386
3471
|
/**
|
|
3387
3472
|
* Constructor
|
|
3388
3473
|
*
|
|
@@ -3437,7 +3522,7 @@ class Ft extends re {
|
|
|
3437
3522
|
* @returns
|
|
3438
3523
|
*/
|
|
3439
3524
|
async reprepareConfiguration(e, t) {
|
|
3440
|
-
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();
|
|
3441
3526
|
return {
|
|
3442
3527
|
userData: { factor2: r.factor2, otp: i },
|
|
3443
3528
|
secrets: {},
|
|
@@ -3472,9 +3557,7 @@ class Ft extends re {
|
|
|
3472
3557
|
}
|
|
3473
3558
|
/**
|
|
3474
3559
|
* Creates and emails a new one-time code.
|
|
3475
|
-
* @param
|
|
3476
|
-
* present, `username` otherwise (which in this case is
|
|
3477
|
-
* expected to contain an email address)
|
|
3560
|
+
* @param _user ignored
|
|
3478
3561
|
* @returns `otp` and `expiry` as a Unix time (number).
|
|
3479
3562
|
*/
|
|
3480
3563
|
async createOneTimeSecrets(e) {
|
|
@@ -3545,7 +3628,7 @@ class Ft extends re {
|
|
|
3545
3628
|
return Array(+(r > 0 && r)).join("0") + e;
|
|
3546
3629
|
}
|
|
3547
3630
|
}
|
|
3548
|
-
class
|
|
3631
|
+
class xt extends be {
|
|
3549
3632
|
/**
|
|
3550
3633
|
* Create a new authenticator.
|
|
3551
3634
|
*
|
|
@@ -3556,7 +3639,7 @@ class Ot extends be {
|
|
|
3556
3639
|
super({ friendlyName: "LDAP", ...t });
|
|
3557
3640
|
h(this, "ldapAutoCreateAccount", !1);
|
|
3558
3641
|
h(this, "ldapStorage");
|
|
3559
|
-
|
|
3642
|
+
w("ldapAutoCreateAccount", m.Boolean, this, t, "LDAP_AUTO_CREATE_ACCOUNT"), this.ldapStorage = e;
|
|
3560
3643
|
}
|
|
3561
3644
|
/**
|
|
3562
3645
|
* Authenticates the user, returning a the user as a {@link User} object.
|
|
@@ -3638,7 +3721,7 @@ class Ot extends be {
|
|
|
3638
3721
|
async reprepareConfiguration(e, t) {
|
|
3639
3722
|
}
|
|
3640
3723
|
}
|
|
3641
|
-
class
|
|
3724
|
+
class Dt extends re {
|
|
3642
3725
|
/**
|
|
3643
3726
|
* Constructor
|
|
3644
3727
|
* @param appName this forms part of the QR code that users scan into
|
|
@@ -3663,9 +3746,9 @@ class Nt extends re {
|
|
|
3663
3746
|
return "none";
|
|
3664
3747
|
}
|
|
3665
3748
|
async createSecret(e, t) {
|
|
3666
|
-
t || (t =
|
|
3749
|
+
t || (t = fe.generateSecret());
|
|
3667
3750
|
let r = "";
|
|
3668
|
-
return await
|
|
3751
|
+
return await Le.toDataURL(fe.keyuri(e, this.appName, t)).then((i) => {
|
|
3669
3752
|
r = i;
|
|
3670
3753
|
}).catch((i) => {
|
|
3671
3754
|
throw u.logger.debug(f({ err: i })), new o(
|
|
@@ -3675,7 +3758,7 @@ class Nt extends re {
|
|
|
3675
3758
|
}), { qrUrl: r, secret: t };
|
|
3676
3759
|
}
|
|
3677
3760
|
async getSecretFromSession(e, t) {
|
|
3678
|
-
const r =
|
|
3761
|
+
const r = L.decodeData(t.data);
|
|
3679
3762
|
if (!("totpsecret" in r))
|
|
3680
3763
|
throw new o(
|
|
3681
3764
|
l.Unauthorized,
|
|
@@ -3748,7 +3831,7 @@ class Nt extends re {
|
|
|
3748
3831
|
"TOTP secret or code not given"
|
|
3749
3832
|
);
|
|
3750
3833
|
const i = r.otp, a = t.totpsecret;
|
|
3751
|
-
if (!
|
|
3834
|
+
if (!fe.check(i, a))
|
|
3752
3835
|
throw new o(
|
|
3753
3836
|
l.InvalidToken,
|
|
3754
3837
|
"Invalid TOTP code"
|
|
@@ -3818,8 +3901,8 @@ class Nt extends re {
|
|
|
3818
3901
|
return !1;
|
|
3819
3902
|
}
|
|
3820
3903
|
}
|
|
3821
|
-
const
|
|
3822
|
-
class
|
|
3904
|
+
const ne = 16;
|
|
3905
|
+
class x {
|
|
3823
3906
|
/**
|
|
3824
3907
|
* Construct a new EmailVerifier.
|
|
3825
3908
|
*
|
|
@@ -3850,7 +3933,7 @@ class D {
|
|
|
3850
3933
|
h(this, "verifyEmailExpires", 60 * 60 * 24);
|
|
3851
3934
|
h(this, "passwordResetExpires", 60 * 60 * 24);
|
|
3852
3935
|
h(this, "render");
|
|
3853
|
-
this.userStorage = s, this.keyStorage = e,
|
|
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 });
|
|
3854
3937
|
}
|
|
3855
3938
|
createEmailer() {
|
|
3856
3939
|
let s = {};
|
|
@@ -3879,11 +3962,11 @@ class D {
|
|
|
3879
3962
|
let r = 0;
|
|
3880
3963
|
const i = /* @__PURE__ */ new Date(), a = new Date(i.getTime() + 1e3 * this.verifyEmailExpires);
|
|
3881
3964
|
for (; r < 10; ) {
|
|
3882
|
-
let n = T.randomValue(
|
|
3965
|
+
let n = T.randomValue(ne), c = x.hashEmailVerificationToken(n);
|
|
3883
3966
|
try {
|
|
3884
3967
|
return await this.keyStorage.saveKey(s, c, i, a, e), n;
|
|
3885
3968
|
} catch {
|
|
3886
|
-
n = T.randomValue(
|
|
3969
|
+
n = T.randomValue(ne), c = x.hashEmailVerificationToken(n), r++;
|
|
3887
3970
|
}
|
|
3888
3971
|
}
|
|
3889
3972
|
throw new o(l.Connection, "failed creating a unique key");
|
|
@@ -3924,7 +4007,7 @@ class D {
|
|
|
3924
4007
|
"Either emailVerificationTextBody or emailVerificationHtmlBody must be set to send email verification emails"
|
|
3925
4008
|
);
|
|
3926
4009
|
let { user: r } = await this.userStorage.getUserById(s, { skipEmailVerifiedCheck: !0 }), i = e;
|
|
3927
|
-
i != "" ?
|
|
4010
|
+
i != "" ? x.validateEmail(i) : (i = r.email ?? r.username, i || (i = r.username), x.validateEmail(i)), x.validateEmail(i);
|
|
3928
4011
|
const a = await this.createAndSaveEmailVerificationToken(s, e), n = await this._sendEmailVerificationToken(a, i, t);
|
|
3929
4012
|
u.logger.info(f({ msg: "Sent email verification email", emailMessageId: n, email: i }));
|
|
3930
4013
|
}
|
|
@@ -3944,20 +4027,20 @@ class D {
|
|
|
3944
4027
|
* address the user is validating
|
|
3945
4028
|
*/
|
|
3946
4029
|
async verifyEmailVerificationToken(s) {
|
|
3947
|
-
const e =
|
|
4030
|
+
const e = x.hashEmailVerificationToken(s);
|
|
3948
4031
|
let t = await this.keyStorage.getKey(e);
|
|
3949
4032
|
try {
|
|
3950
4033
|
if (!t.userid || !t.expires) throw new o(l.InvalidKey);
|
|
3951
4034
|
const { user: r } = await this.userStorage.getUserById(t.userid, { skipEmailVerifiedCheck: !0 });
|
|
3952
4035
|
let i = (r.email ?? r.username).toLowerCase();
|
|
3953
|
-
if (i || (i = r.username.toLowerCase()),
|
|
4036
|
+
if (i || (i = r.username.toLowerCase()), x.validateEmail(i), (/* @__PURE__ */ new Date()).getTime() > t.expires.getTime()) throw new o(l.Expired);
|
|
3954
4037
|
return { userid: t.userid, newEmail: t.data ?? "" };
|
|
3955
4038
|
} finally {
|
|
3956
4039
|
}
|
|
3957
4040
|
}
|
|
3958
4041
|
async deleteEmailVerificationToken(s) {
|
|
3959
4042
|
try {
|
|
3960
|
-
const e =
|
|
4043
|
+
const e = x.hashEmailVerificationToken(s);
|
|
3961
4044
|
await this.keyStorage.deleteKey(e);
|
|
3962
4045
|
} catch (e) {
|
|
3963
4046
|
const t = o.asCrossauthError(e);
|
|
@@ -3968,11 +4051,11 @@ class D {
|
|
|
3968
4051
|
let t = 0;
|
|
3969
4052
|
const r = /* @__PURE__ */ new Date(), i = new Date(r.getTime() + 1e3 * this.passwordResetExpires);
|
|
3970
4053
|
for (; t < 10; ) {
|
|
3971
|
-
let a = T.randomValue(
|
|
4054
|
+
let a = T.randomValue(ne), n = x.hashPasswordResetToken(a);
|
|
3972
4055
|
try {
|
|
3973
4056
|
return await this.keyStorage.saveKey(s, n, r, i), a;
|
|
3974
4057
|
} catch {
|
|
3975
|
-
a = T.randomValue(
|
|
4058
|
+
a = T.randomValue(ne), n = x.hashPasswordResetToken(a), t++;
|
|
3976
4059
|
}
|
|
3977
4060
|
}
|
|
3978
4061
|
throw new o(l.Connection, "failed creating a unique key");
|
|
@@ -3992,7 +4075,7 @@ class D {
|
|
|
3992
4075
|
* @returns the user that the token is for
|
|
3993
4076
|
*/
|
|
3994
4077
|
async verifyPasswordResetToken(s) {
|
|
3995
|
-
const e =
|
|
4078
|
+
const e = x.hashPasswordResetToken(s);
|
|
3996
4079
|
u.logger.debug("verifyPasswordResetToken " + s + " " + e);
|
|
3997
4080
|
let t = await this.keyStorage.getKey(e);
|
|
3998
4081
|
if (!t.userid) throw new o(l.InvalidKey);
|
|
@@ -4041,7 +4124,7 @@ class D {
|
|
|
4041
4124
|
if (!t && r.state != E.active && r.state != E.passwordResetNeeded && r.state != E.passwordAndFactor2ResetNeeded)
|
|
4042
4125
|
throw new o(l.UserNotActive);
|
|
4043
4126
|
let i = (r.email ?? r.username).toLowerCase();
|
|
4044
|
-
i || (i = r.username.toLowerCase()),
|
|
4127
|
+
i || (i = r.username.toLowerCase()), x.validateEmail(i);
|
|
4045
4128
|
const a = await this.createAndSavePasswordResetToken(s), n = await this._sendPasswordResetToken(a, i, e);
|
|
4046
4129
|
u.logger.info(f({ msg: "Sent password reset email", emailMessageId: n, email: i }));
|
|
4047
4130
|
}
|
|
@@ -4063,11 +4146,11 @@ class D {
|
|
|
4063
4146
|
* @param email the email to validate
|
|
4064
4147
|
*/
|
|
4065
4148
|
static validateEmail(s) {
|
|
4066
|
-
if (s == null || !
|
|
4149
|
+
if (s == null || !x.isEmailValid(s)) throw new o(l.InvalidEmail);
|
|
4067
4150
|
}
|
|
4068
4151
|
}
|
|
4069
4152
|
const _e = 16, ke = 16;
|
|
4070
|
-
function
|
|
4153
|
+
function Bt(S) {
|
|
4071
4154
|
return {
|
|
4072
4155
|
...S,
|
|
4073
4156
|
path: S.path ?? "/"
|
|
@@ -4094,7 +4177,7 @@ class rt {
|
|
|
4094
4177
|
h(this, "sameSite", "lax");
|
|
4095
4178
|
// hasher settings
|
|
4096
4179
|
h(this, "secret", "");
|
|
4097
|
-
|
|
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);
|
|
4098
4181
|
}
|
|
4099
4182
|
/**
|
|
4100
4183
|
* Creates a session key and saves in storage
|
|
@@ -4109,13 +4192,11 @@ class rt {
|
|
|
4109
4192
|
/**
|
|
4110
4193
|
* Returns a {@link Cookie } object with the given session key.
|
|
4111
4194
|
*
|
|
4112
|
-
* This class is compatible, for example, with Express.
|
|
4113
|
-
*
|
|
4114
4195
|
* @param token the value of the csrf token, with signature
|
|
4115
4196
|
* @returns a {@link Cookie } object,
|
|
4116
4197
|
*/
|
|
4117
4198
|
makeCsrfCookie(s) {
|
|
4118
|
-
const e = T.
|
|
4199
|
+
const e = T.signSecureToken(s, this.secret);
|
|
4119
4200
|
let t = {};
|
|
4120
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), {
|
|
4121
4202
|
name: this.cookieName,
|
|
@@ -4127,7 +4208,7 @@ class rt {
|
|
|
4127
4208
|
return this.maskCsrfToken(s);
|
|
4128
4209
|
}
|
|
4129
4210
|
unsignCookie(s) {
|
|
4130
|
-
return T.
|
|
4211
|
+
return T.unsignSecureToken(s, this.secret);
|
|
4131
4212
|
}
|
|
4132
4213
|
/**
|
|
4133
4214
|
* Takes a session ID and creates a string representation of the cookie (value of the HTTP `Cookie` header).
|
|
@@ -4156,7 +4237,7 @@ class rt {
|
|
|
4156
4237
|
* * The signature in the cookie must match the token in the cookie
|
|
4157
4238
|
* * The token in the cookie must matched the value in the form or header after unmasking
|
|
4158
4239
|
*
|
|
4159
|
-
* @param cookieValue the
|
|
4240
|
+
* @param cookieValue the CSRF cookie value to validate.
|
|
4160
4241
|
* @param formOrHeaderValue the value from the csrfToken form header or the X-CROSSAUTH-CSRF header.
|
|
4161
4242
|
* @throws {@link @crossauth/common!CrossauthError} with {@link @crossauth/common!ErrorCode} of `InvalidKey`
|
|
4162
4243
|
*/
|
|
@@ -4164,7 +4245,7 @@ class rt {
|
|
|
4164
4245
|
const t = this.unmaskCsrfToken(e);
|
|
4165
4246
|
let r;
|
|
4166
4247
|
try {
|
|
4167
|
-
r = T.
|
|
4248
|
+
r = T.unsignSecureToken(s, this.secret);
|
|
4168
4249
|
} catch (i) {
|
|
4169
4250
|
throw u.logger.error(f({ err: i })), new o(l.InvalidCsrf, "Invalid CSRF cookie");
|
|
4170
4251
|
}
|
|
@@ -4183,13 +4264,13 @@ class rt {
|
|
|
4183
4264
|
*/
|
|
4184
4265
|
validateCsrfCookie(s) {
|
|
4185
4266
|
try {
|
|
4186
|
-
return T.
|
|
4267
|
+
return T.unsignSecureToken(s, this.secret);
|
|
4187
4268
|
} catch (e) {
|
|
4188
4269
|
throw u.logger.error(f({ err: e })), new o(l.InvalidCsrf, "Invalid CSRF cookie");
|
|
4189
4270
|
}
|
|
4190
4271
|
}
|
|
4191
4272
|
}
|
|
4192
|
-
class
|
|
4273
|
+
class D {
|
|
4193
4274
|
/**
|
|
4194
4275
|
* Constructor.
|
|
4195
4276
|
*
|
|
@@ -4218,7 +4299,7 @@ class x {
|
|
|
4218
4299
|
h(this, "sameSite", "lax");
|
|
4219
4300
|
// hasher settings
|
|
4220
4301
|
h(this, "secret", "");
|
|
4221
|
-
e.userStorage && (this.userStorage = e.userStorage), this.keyStorage = s,
|
|
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);
|
|
4222
4303
|
}
|
|
4223
4304
|
expiry(s) {
|
|
4224
4305
|
let e;
|
|
@@ -4255,16 +4336,16 @@ class x {
|
|
|
4255
4336
|
const a = /* @__PURE__ */ new Date();
|
|
4256
4337
|
let n = this.expiry(a), c = !1;
|
|
4257
4338
|
for (; r < 10 && !c; ) {
|
|
4258
|
-
const d =
|
|
4339
|
+
const d = D.hashSessionId(i);
|
|
4259
4340
|
try {
|
|
4260
4341
|
this.idleTimeout > 0 && s && (e = { ...e, lastActivity: /* @__PURE__ */ new Date() }), await this.keyStorage.saveKey(s, d, a, n, void 0, e), c = !0;
|
|
4261
|
-
} catch (
|
|
4262
|
-
let y = o.asCrossauthError(
|
|
4342
|
+
} catch (g) {
|
|
4343
|
+
let y = o.asCrossauthError(g);
|
|
4263
4344
|
if (y.code == l.KeyExists || y.code == l.InvalidKey) {
|
|
4264
4345
|
if (r++, i = T.randomValue(ke), r > 10)
|
|
4265
4346
|
throw u.logger.error(f({ msg: "Max attempts exceeded trying to create session ID" })), new o(l.KeyExists);
|
|
4266
4347
|
} else
|
|
4267
|
-
throw u.logger.debug(f({ err:
|
|
4348
|
+
throw u.logger.debug(f({ err: g })), g;
|
|
4268
4349
|
}
|
|
4269
4350
|
}
|
|
4270
4351
|
return {
|
|
@@ -4284,7 +4365,7 @@ class x {
|
|
|
4284
4365
|
* @returns a {@link Cookie } object,
|
|
4285
4366
|
*/
|
|
4286
4367
|
makeCookie(s, e) {
|
|
4287
|
-
let t = T.
|
|
4368
|
+
let t = T.signSecureToken(s.value, this.secret), r = {};
|
|
4288
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), {
|
|
4289
4370
|
name: this.cookieName,
|
|
4290
4371
|
value: t,
|
|
@@ -4311,7 +4392,7 @@ class x {
|
|
|
4311
4392
|
*/
|
|
4312
4393
|
async updateSessionKey(s) {
|
|
4313
4394
|
if (!s.value) throw new o(l.InvalidKey, "No session when updating activity");
|
|
4314
|
-
s.value =
|
|
4395
|
+
s.value = D.hashSessionId(s.value), await this.keyStorage.updateKey(s);
|
|
4315
4396
|
}
|
|
4316
4397
|
/**
|
|
4317
4398
|
* Unsigns a cookie and returns the original value.
|
|
@@ -4321,7 +4402,7 @@ class x {
|
|
|
4321
4402
|
* is invalid.
|
|
4322
4403
|
*/
|
|
4323
4404
|
unsignCookie(s) {
|
|
4324
|
-
return T.
|
|
4405
|
+
return T.unsignSecureToken(s, this.secret);
|
|
4325
4406
|
}
|
|
4326
4407
|
/**
|
|
4327
4408
|
* Returns the user matching the given session key in session storage, or throws an exception.
|
|
@@ -4359,7 +4440,7 @@ class x {
|
|
|
4359
4440
|
* `Expired` or `UserNotExist`.
|
|
4360
4441
|
*/
|
|
4361
4442
|
async getSessionKey(s) {
|
|
4362
|
-
const e = Date.now(), t =
|
|
4443
|
+
const e = Date.now(), t = D.hashSessionId(s), r = await this.keyStorage.getKey(t);
|
|
4363
4444
|
if (r.value = s, r.expires && e > r.expires.getTime())
|
|
4364
4445
|
throw u.logger.warn(f({ msg: "Session id in cookie expired in key storage", hashedSessionCookie: T.hash(s) })), new o(l.Expired);
|
|
4365
4446
|
if (r.userid && this.idleTimeout > 0 && r.lastactive && e > r.lastactive.getTime() + this.idleTimeout * 1e3)
|
|
@@ -4374,10 +4455,10 @@ class x {
|
|
|
4374
4455
|
* @param except if defined, don't delete this key
|
|
4375
4456
|
*/
|
|
4376
4457
|
async deleteAllForUser(s, e) {
|
|
4377
|
-
e && (e =
|
|
4458
|
+
e && (e = D.hashSessionId(e)), await this.keyStorage.deleteAllForUser(s, U.session, e);
|
|
4378
4459
|
}
|
|
4379
4460
|
}
|
|
4380
|
-
class
|
|
4461
|
+
class Lt {
|
|
4381
4462
|
/**
|
|
4382
4463
|
* Constructor
|
|
4383
4464
|
* @param keyStorage the {@link KeyStorage} instance to use, eg {@link PrismaKeyStorage}.
|
|
@@ -4399,9 +4480,9 @@ class Dt {
|
|
|
4399
4480
|
t.userStorage && (this.userStorage = t.userStorage), this.keyStorage = s, this.authenticators = e;
|
|
4400
4481
|
for (let r in this.authenticators)
|
|
4401
4482
|
this.authenticators[r].factorName = r;
|
|
4402
|
-
if (this.session = new
|
|
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)) {
|
|
4403
4484
|
let r = this.keyStorage;
|
|
4404
|
-
t.emailTokenStorage && (this.emailTokenStorage = t.emailTokenStorage), this.tokenEmailer = new
|
|
4485
|
+
t.emailTokenStorage && (this.emailTokenStorage = t.emailTokenStorage), this.tokenEmailer = new x(this.userStorage, r, t);
|
|
4405
4486
|
}
|
|
4406
4487
|
}
|
|
4407
4488
|
/**
|
|
@@ -4477,7 +4558,7 @@ class Dt {
|
|
|
4477
4558
|
const p = await this.session.createSessionKey(i.id, t);
|
|
4478
4559
|
c = this.session.makeCookie(p, r);
|
|
4479
4560
|
}
|
|
4480
|
-
const d = this.csrfTokens.createCsrfToken(),
|
|
4561
|
+
const d = this.csrfTokens.createCsrfToken(), g = this.csrfTokens.makeCsrfCookie(d), y = this.csrfTokens.makeCsrfFormOrHeaderToken(d);
|
|
4481
4562
|
try {
|
|
4482
4563
|
this.emailTokenStorage.deleteAllForUser(
|
|
4483
4564
|
i.id,
|
|
@@ -4488,7 +4569,7 @@ class Dt {
|
|
|
4488
4569
|
}
|
|
4489
4570
|
return {
|
|
4490
4571
|
sessionCookie: c,
|
|
4491
|
-
csrfCookie:
|
|
4572
|
+
csrfCookie: g,
|
|
4492
4573
|
csrfFormOrHeaderValue: y,
|
|
4493
4574
|
user: i,
|
|
4494
4575
|
secrets: n
|
|
@@ -4521,7 +4602,7 @@ class Dt {
|
|
|
4521
4602
|
*/
|
|
4522
4603
|
async logout(s) {
|
|
4523
4604
|
const e = await this.session.getSessionKey(s);
|
|
4524
|
-
return await this.keyStorage.deleteKey(
|
|
4605
|
+
return await this.keyStorage.deleteKey(D.hashSessionId(e.value));
|
|
4525
4606
|
}
|
|
4526
4607
|
/**
|
|
4527
4608
|
* Logs a user out from all sessions.
|
|
@@ -4669,7 +4750,7 @@ class Dt {
|
|
|
4669
4750
|
* @param value new value to store
|
|
4670
4751
|
*/
|
|
4671
4752
|
async updateSessionData(s, e, t) {
|
|
4672
|
-
const r =
|
|
4753
|
+
const r = D.hashSessionId(s);
|
|
4673
4754
|
u.logger.debug(f({ msg: `Updating session data value${e}`, hashedSessionCookie: T.hash(s) })), await this.keyStorage.updateData(r, e, t);
|
|
4674
4755
|
}
|
|
4675
4756
|
/**
|
|
@@ -4678,12 +4759,11 @@ class Dt {
|
|
|
4678
4759
|
* The `data` field in the session entry is assumed to be a JSON string.
|
|
4679
4760
|
* The field with the given name is updated or set if not already set.
|
|
4680
4761
|
* @param sessionId the session Id to update.
|
|
4681
|
-
* @param
|
|
4682
|
-
* @param value new value to store
|
|
4762
|
+
* @param dataArray names and values.
|
|
4683
4763
|
*/
|
|
4684
4764
|
async updateManySessionData(s, e) {
|
|
4685
|
-
const t =
|
|
4686
|
-
u.logger.debug(f({ msg:
|
|
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);
|
|
4687
4767
|
}
|
|
4688
4768
|
/**
|
|
4689
4769
|
* Deletes a field from the session data.
|
|
@@ -4694,7 +4774,7 @@ class Dt {
|
|
|
4694
4774
|
* @param name of the field.
|
|
4695
4775
|
*/
|
|
4696
4776
|
async deleteSessionData(s, e) {
|
|
4697
|
-
const t =
|
|
4777
|
+
const t = D.hashSessionId(s);
|
|
4698
4778
|
u.logger.debug(f({ msg: `Updating session data value${e}`, hashedSessionCookie: T.hash(s) })), await this.keyStorage.deleteData(t, e);
|
|
4699
4779
|
}
|
|
4700
4780
|
/**
|
|
@@ -4703,7 +4783,7 @@ class Dt {
|
|
|
4703
4783
|
* @param sessionId the session Id to delete
|
|
4704
4784
|
*/
|
|
4705
4785
|
async deleteSession(s) {
|
|
4706
|
-
return await this.keyStorage.deleteKey(
|
|
4786
|
+
return await this.keyStorage.deleteKey(D.hashSessionId(s));
|
|
4707
4787
|
}
|
|
4708
4788
|
/**
|
|
4709
4789
|
* Creates a new user, sending an email verification message if necessary.
|
|
@@ -4758,7 +4838,7 @@ class Dt {
|
|
|
4758
4838
|
if (!this.authenticators[s.factor2]) throw new o(l.Configuration, "Two factor authentication not enabled for user");
|
|
4759
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);
|
|
4760
4840
|
return s.state = "awaitingtwofactorsetup", await this.keyStorage.updateData(
|
|
4761
|
-
|
|
4841
|
+
D.hashSessionId(t),
|
|
4762
4842
|
"2fa",
|
|
4763
4843
|
c
|
|
4764
4844
|
), { userid: (await this.userStorage.createUser(s, d)).id, userData: n };
|
|
@@ -4778,13 +4858,13 @@ class Dt {
|
|
|
4778
4858
|
if (!this.authenticators[e]) throw new o(l.Configuration, "Two factor authentication not enabled for user");
|
|
4779
4859
|
const i = await this.authenticators[e].prepareConfiguration(s), a = i == null ? {} : i.userData, n = i == null ? {} : i.sessionData;
|
|
4780
4860
|
return await this.keyStorage.updateData(
|
|
4781
|
-
|
|
4861
|
+
D.hashSessionId(t),
|
|
4782
4862
|
"2fa",
|
|
4783
4863
|
n
|
|
4784
4864
|
), a;
|
|
4785
4865
|
}
|
|
4786
4866
|
return await this.userStorage.updateUser({ id: s.id, factor2: e ?? "" }), await this.keyStorage.updateData(
|
|
4787
|
-
|
|
4867
|
+
D.hashSessionId(t),
|
|
4788
4868
|
"2fa",
|
|
4789
4869
|
void 0
|
|
4790
4870
|
), {};
|
|
@@ -4804,10 +4884,10 @@ class Dt {
|
|
|
4804
4884
|
*/
|
|
4805
4885
|
async repeatTwoFactorSignup(s) {
|
|
4806
4886
|
if (!this.userStorage) throw new o(l.Configuration, "Cannot call repeatTwoFactorSignup if no user storage provided");
|
|
4807
|
-
const e = (await this.dataForSessionId(s))["2fa"], t = e.username, r = e.factor2, i =
|
|
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;
|
|
4808
4888
|
y && await this.keyStorage.updateData(i, "2fa", y);
|
|
4809
4889
|
const { user: p } = await this.userStorage.getUserByUsername(t, { skipActiveCheck: !0, skipEmailVerifiedCheck: !0 });
|
|
4810
|
-
return { userid: p.id, userData: d, secrets:
|
|
4890
|
+
return { userid: p.id, userData: d, secrets: g };
|
|
4811
4891
|
}
|
|
4812
4892
|
/**
|
|
4813
4893
|
* Authenticates with the second factor.
|
|
@@ -4828,14 +4908,14 @@ class Dt {
|
|
|
4828
4908
|
if (r && r.state != E.active && r.state != E.factor2ResetNeeded)
|
|
4829
4909
|
throw new o(l.UserNotActive);
|
|
4830
4910
|
if (!i) throw new o(l.InvalidKey, "Session key not found");
|
|
4831
|
-
let a =
|
|
4911
|
+
let a = L.decodeData(i.data)["2fa"];
|
|
4832
4912
|
if (!(a != null && a.factor2) || !(a != null && a.username)) throw new o(l.Unauthorized, "Two factor authentication not initiated");
|
|
4833
4913
|
let n = a.username;
|
|
4834
4914
|
const c = this.authenticators[a.factor2];
|
|
4835
4915
|
if (!c) throw new o(l.Configuration, "Unrecognised second factor authentication");
|
|
4836
|
-
const d = {},
|
|
4916
|
+
const d = {}, g = c.secretNames();
|
|
4837
4917
|
for (let C in a)
|
|
4838
|
-
|
|
4918
|
+
g.includes(C) && (d[C] = a[C]);
|
|
4839
4919
|
await c.authenticateUser(void 0, a, s), r || (t = !0, r = (await this.userStorage.getUserByUsername(n, { skipActiveCheck: !0, skipEmailVerifiedCheck: !0 })).user);
|
|
4840
4920
|
const y = c.skipEmailVerificationOnSignup() == !0;
|
|
4841
4921
|
if (!r) throw new o(l.UserNotExist, "Couldn't fetch user");
|
|
@@ -4844,7 +4924,7 @@ class Dt {
|
|
|
4844
4924
|
state: !y && this.enableEmailVerification ? "awaitingemailverification" : "active",
|
|
4845
4925
|
factor2: a.factor2
|
|
4846
4926
|
};
|
|
4847
|
-
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(
|
|
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 };
|
|
4848
4928
|
}
|
|
4849
4929
|
/**
|
|
4850
4930
|
* Initiates the two factor login process.
|
|
@@ -4874,14 +4954,14 @@ class Dt {
|
|
|
4874
4954
|
*/
|
|
4875
4955
|
async initiateTwoFactorPageVisit(s, e, t, r, i) {
|
|
4876
4956
|
const n = await this.authenticators[s.factor2].createOneTimeSecrets(s);
|
|
4877
|
-
let c, d,
|
|
4878
|
-
const y =
|
|
4957
|
+
let c, d, g;
|
|
4958
|
+
const y = D.hashSessionId(e);
|
|
4879
4959
|
u.logger.debug("initiateTwoFactorPageVisit " + s.username + " " + e + " " + y);
|
|
4880
4960
|
let p = { username: s.username, factor2: s.factor2, secrets: n, body: t, url: r };
|
|
4881
4961
|
return i && (p["content-type"] = i), await this.keyStorage.updateData(y, "pre2fa", p), {
|
|
4882
4962
|
sessionCookie: c,
|
|
4883
4963
|
csrfCookie: d,
|
|
4884
|
-
csrfFormOrHeaderValue:
|
|
4964
|
+
csrfFormOrHeaderValue: g
|
|
4885
4965
|
};
|
|
4886
4966
|
}
|
|
4887
4967
|
/**
|
|
@@ -4897,14 +4977,14 @@ class Dt {
|
|
|
4897
4977
|
if (!this.userStorage) throw new o(l.Configuration, "Cannot call completeTwoFactorPageVisit if no user storage provided");
|
|
4898
4978
|
let { key: t } = await this.session.getUserForSessionId(e);
|
|
4899
4979
|
if (!t) throw new o(l.InvalidKey, "Session key not found");
|
|
4900
|
-
let r =
|
|
4980
|
+
let r = L.decodeData(t.data);
|
|
4901
4981
|
if (!("pre2fa" in r)) throw new o(l.Unauthorized, "Two factor authentication not initiated");
|
|
4902
4982
|
const { secrets: i } = await this.userStorage.getUserByUsername(r.pre2fa.username), a = this.authenticators[r.pre2fa.factor2];
|
|
4903
4983
|
if (!a) throw new o(l.Configuration, "Unrecognised second factor authentication");
|
|
4904
4984
|
const n = {}, c = a.secretNames();
|
|
4905
4985
|
for (let d in i)
|
|
4906
4986
|
c.includes(d) && d in i && (n[d] = i[d]);
|
|
4907
|
-
await a.authenticateUser(void 0, { ...n, ...r.pre2fa.secrets }, s), await this.keyStorage.updateData(
|
|
4987
|
+
await a.authenticateUser(void 0, { ...n, ...r.pre2fa.secrets }, s), await this.keyStorage.updateData(D.hashSessionId(t.value), "pre2fa", void 0);
|
|
4908
4988
|
}
|
|
4909
4989
|
/**
|
|
4910
4990
|
* Cancels the 2FA that was previously initiated but not completed..
|
|
@@ -4918,9 +4998,9 @@ class Dt {
|
|
|
4918
4998
|
async cancelTwoFactorPageVisit(s) {
|
|
4919
4999
|
let { key: e } = await this.session.getUserForSessionId(s);
|
|
4920
5000
|
if (!e) throw new o(l.InvalidKey, "Session key not found");
|
|
4921
|
-
let t =
|
|
5001
|
+
let t = L.decodeData(e.data);
|
|
4922
5002
|
if (!("pre2fa" in t)) throw new o(l.Unauthorized, "Two factor authentication not initiated");
|
|
4923
|
-
return await this.keyStorage.updateData(
|
|
5003
|
+
return await this.keyStorage.updateData(D.hashSessionId(e.value), "pre2fa", void 0), t.pre2fa;
|
|
4924
5004
|
}
|
|
4925
5005
|
/**
|
|
4926
5006
|
* Performs the second factor authentication as the second step of the login
|
|
@@ -4943,12 +5023,12 @@ class Dt {
|
|
|
4943
5023
|
if (!this.userStorage) throw new o(l.Configuration, "Cannot call completeTwoFactorLogin if no user storage provided");
|
|
4944
5024
|
let { key: i } = await this.session.getUserForSessionId(e);
|
|
4945
5025
|
if (!i || !i.data || i.data == "") throw new o(l.Unauthorized);
|
|
4946
|
-
let a =
|
|
4947
|
-
const { user: d, secrets:
|
|
5026
|
+
let a = L.decodeData(i.data)["2fa"], n = a.username, c = a.factor2;
|
|
5027
|
+
const { user: d, secrets: g } = await this.userStorage.getUserByUsername(n), y = this.authenticators[c];
|
|
4948
5028
|
if (!y) throw new o(l.Configuration, "Second factor " + c + " not enabled");
|
|
4949
|
-
await y.authenticateUser(d, { ...
|
|
5029
|
+
await y.authenticateUser(d, { ...g, ...a }, s);
|
|
4950
5030
|
const p = await this.session.createSessionKey(d.id, t);
|
|
4951
|
-
await this.keyStorage.deleteKey(
|
|
5031
|
+
await this.keyStorage.deleteKey(D.hashSessionId(i.value));
|
|
4952
5032
|
const _ = this.session.makeCookie(p, r), C = this.csrfTokens.createCsrfToken(), v = this.csrfTokens.makeCsrfCookie(C), k = this.csrfTokens.makeCsrfFormOrHeaderToken(C);
|
|
4953
5033
|
try {
|
|
4954
5034
|
this.emailTokenStorage.deleteAllForUser(
|
|
@@ -5026,8 +5106,8 @@ class Dt {
|
|
|
5026
5106
|
a.id,
|
|
5027
5107
|
U.passwordResetToken
|
|
5028
5108
|
);
|
|
5029
|
-
} catch (
|
|
5030
|
-
u.logger.warn(f({ msg: "Couldn't delete password reset tokens while logging in", user: s })), u.logger.debug(f({ err:
|
|
5109
|
+
} catch (g) {
|
|
5110
|
+
u.logger.warn(f({ msg: "Couldn't delete password reset tokens while logging in", user: s })), u.logger.debug(f({ err: g }));
|
|
5031
5111
|
}
|
|
5032
5112
|
return a;
|
|
5033
5113
|
}
|
|
@@ -5047,19 +5127,19 @@ class Dt {
|
|
|
5047
5127
|
throw new o(l.UserNotExist, "Please specify a userername");
|
|
5048
5128
|
let { email: a, username: n, password: c, ...d } = e;
|
|
5049
5129
|
d.userid = s.userid;
|
|
5050
|
-
let
|
|
5130
|
+
let g = !1;
|
|
5051
5131
|
if (a)
|
|
5052
|
-
i = a,
|
|
5132
|
+
i = a, x.validateEmail(i), g = !0;
|
|
5053
5133
|
else if (n) {
|
|
5054
5134
|
i = n;
|
|
5055
5135
|
try {
|
|
5056
|
-
|
|
5136
|
+
x.validateEmail(s.username), g = !0;
|
|
5057
5137
|
} catch {
|
|
5058
5138
|
}
|
|
5059
|
-
|
|
5139
|
+
g && x.validateEmail(i);
|
|
5060
5140
|
}
|
|
5061
|
-
return !t && this.enableEmailVerification &&
|
|
5062
|
-
emailVerificationTokenSent: !t && this.enableEmailVerification &&
|
|
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), {
|
|
5142
|
+
emailVerificationTokenSent: !t && this.enableEmailVerification && g,
|
|
5063
5143
|
passwordResetTokenSent: e.state == E.passwordResetNeeded || e.state == E.passwordAndFactor2ResetNeeded
|
|
5064
5144
|
};
|
|
5065
5145
|
}
|
|
@@ -5095,7 +5175,7 @@ class Dt {
|
|
|
5095
5175
|
return { ...i, state: n };
|
|
5096
5176
|
}
|
|
5097
5177
|
}
|
|
5098
|
-
class
|
|
5178
|
+
class ge {
|
|
5099
5179
|
/**
|
|
5100
5180
|
* Constructor.
|
|
5101
5181
|
*
|
|
@@ -5112,7 +5192,7 @@ class he {
|
|
|
5112
5192
|
h(this, "prefix", U.apiKey);
|
|
5113
5193
|
/** The name of the speak in the Authorization header. Defaults to "ApiKey" */
|
|
5114
5194
|
h(this, "authScheme", "ApiKey");
|
|
5115
|
-
this.apiKeyStorage = s,
|
|
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");
|
|
5116
5196
|
}
|
|
5117
5197
|
/**
|
|
5118
5198
|
* Creates a new random key and returns it, unsigned. It is also persisted in the key storage as a
|
|
@@ -5133,11 +5213,11 @@ class he {
|
|
|
5133
5213
|
* Authorization header (with the signature appended.)
|
|
5134
5214
|
*/
|
|
5135
5215
|
async createKey(s, e, t, r, i) {
|
|
5136
|
-
const a = T.randomValue(this.keyLength), n = /* @__PURE__ */ new Date(), c = r ? new Date(n.getTime() + r * 1e3) : void 0, d =
|
|
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 = {
|
|
5137
5217
|
name: s,
|
|
5138
5218
|
value: a,
|
|
5139
5219
|
userid: e,
|
|
5140
|
-
data:
|
|
5220
|
+
data: L.encodeData(t),
|
|
5141
5221
|
expires: c,
|
|
5142
5222
|
created: n,
|
|
5143
5223
|
...i
|
|
@@ -5147,11 +5227,11 @@ class he {
|
|
|
5147
5227
|
this.prefix + d,
|
|
5148
5228
|
n,
|
|
5149
5229
|
c,
|
|
5150
|
-
|
|
5230
|
+
g.data,
|
|
5151
5231
|
{ name: s, ...i }
|
|
5152
5232
|
);
|
|
5153
5233
|
const y = this.signApiKeyValue(a);
|
|
5154
|
-
return { key:
|
|
5234
|
+
return { key: g, token: y };
|
|
5155
5235
|
}
|
|
5156
5236
|
static hashApiKeyValue(s) {
|
|
5157
5237
|
return T.hash(s);
|
|
@@ -5178,7 +5258,7 @@ class he {
|
|
|
5178
5258
|
const i = new RegExp(`^${this.authScheme} `);
|
|
5179
5259
|
s = s.replace(i, "");
|
|
5180
5260
|
}
|
|
5181
|
-
const e = this.unsignApiKeyValue(s), t =
|
|
5261
|
+
const e = this.unsignApiKeyValue(s), t = ge.hashApiKeyValue(e), r = await this.apiKeyStorage.getKey(this.prefix + t);
|
|
5182
5262
|
if (!("name" in r)) throw new o(l.InvalidKey, "Not a valid API key");
|
|
5183
5263
|
return { ...r, name: r.name };
|
|
5184
5264
|
}
|
|
@@ -5210,7 +5290,7 @@ class J {
|
|
|
5210
5290
|
l.Configuration,
|
|
5211
5291
|
"Must specify clientStorage when adding a client manager"
|
|
5212
5292
|
);
|
|
5213
|
-
this.clientStorage = s.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");
|
|
5214
5294
|
}
|
|
5215
5295
|
/**
|
|
5216
5296
|
* Creates a client and puts it in the storage
|
|
@@ -5244,10 +5324,10 @@ class J {
|
|
|
5244
5324
|
valid_flow: t,
|
|
5245
5325
|
userid: i
|
|
5246
5326
|
};
|
|
5247
|
-
let
|
|
5327
|
+
let g;
|
|
5248
5328
|
for (let y = 0; y < 5; ++y)
|
|
5249
5329
|
try {
|
|
5250
|
-
|
|
5330
|
+
g = await this.clientStorage.createClient(d);
|
|
5251
5331
|
break;
|
|
5252
5332
|
} catch (p) {
|
|
5253
5333
|
if (y == 4) {
|
|
@@ -5255,8 +5335,8 @@ class J {
|
|
|
5255
5335
|
} else
|
|
5256
5336
|
d.client_id = J.randomClientId();
|
|
5257
5337
|
}
|
|
5258
|
-
if (!
|
|
5259
|
-
return
|
|
5338
|
+
if (!g) throw new o(l.ClientExists);
|
|
5339
|
+
return g.client_secret && c && (g.client_secret = c), g;
|
|
5260
5340
|
}
|
|
5261
5341
|
/**
|
|
5262
5342
|
* Updates a client
|
|
@@ -5340,7 +5420,7 @@ function at(S) {
|
|
|
5340
5420
|
"Invalid JWT signing algorithm " + S
|
|
5341
5421
|
);
|
|
5342
5422
|
}
|
|
5343
|
-
class
|
|
5423
|
+
class zt {
|
|
5344
5424
|
/**
|
|
5345
5425
|
* Constructor
|
|
5346
5426
|
*
|
|
@@ -5402,9 +5482,9 @@ class xt {
|
|
|
5402
5482
|
h(this, "validFlows", ["all"]);
|
|
5403
5483
|
/** Set from options. See {@link OAuthAuthorizationServerOptions.allowedFactor2} */
|
|
5404
5484
|
h(this, "allowedFactor2", []);
|
|
5405
|
-
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 }),
|
|
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");
|
|
5406
5486
|
let i = {};
|
|
5407
|
-
if (
|
|
5487
|
+
if (w("userCodeDashEvery", m.String, i, r, "DEVICECODE_USERCODE_DASH_EVERY"), i.userCodeDashEvery)
|
|
5408
5488
|
if (i.userCodeDashEvery == "" || i.userCodeDashEvery.toLowerCase() == "null") this.userCodeDashEvery = null;
|
|
5409
5489
|
else
|
|
5410
5490
|
try {
|
|
@@ -5415,7 +5495,7 @@ class xt {
|
|
|
5415
5495
|
"userCodeDashEvery must be a number or null"
|
|
5416
5496
|
);
|
|
5417
5497
|
}
|
|
5418
|
-
if (
|
|
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) {
|
|
5419
5499
|
if (this.jwtPublicKey || this.jwtPublicKeyFile || this.jwtPrivateKey || this.jwtPrivateKeyFile)
|
|
5420
5500
|
throw new o(
|
|
5421
5501
|
l.Configuration,
|
|
@@ -5492,9 +5572,9 @@ class xt {
|
|
|
5492
5572
|
error: "unsupported_response_type",
|
|
5493
5573
|
error_description: "Unsupported response type " + s
|
|
5494
5574
|
};
|
|
5495
|
-
let
|
|
5575
|
+
let g;
|
|
5496
5576
|
try {
|
|
5497
|
-
|
|
5577
|
+
g = await this.clientStorage.getClientById(e);
|
|
5498
5578
|
} catch (v) {
|
|
5499
5579
|
return u.logger.debug(f({ err: v })), {
|
|
5500
5580
|
error: "unauthorized_client",
|
|
@@ -5516,7 +5596,7 @@ class xt {
|
|
|
5516
5596
|
error: "access_denied",
|
|
5517
5597
|
error_description: "Unsupported flow type " + C
|
|
5518
5598
|
};
|
|
5519
|
-
if (!
|
|
5599
|
+
if (!g.valid_flow.includes(C))
|
|
5520
5600
|
return {
|
|
5521
5601
|
error: "unauthorized_client",
|
|
5522
5602
|
error_description: "Client does not support " + C
|
|
@@ -5530,7 +5610,7 @@ class xt {
|
|
|
5530
5610
|
};
|
|
5531
5611
|
}
|
|
5532
5612
|
return s == "code" ? await this.getAuthorizationCode(
|
|
5533
|
-
|
|
5613
|
+
g,
|
|
5534
5614
|
t,
|
|
5535
5615
|
y,
|
|
5536
5616
|
i,
|
|
@@ -5673,7 +5753,7 @@ class xt {
|
|
|
5673
5753
|
refreshToken: n,
|
|
5674
5754
|
username: c,
|
|
5675
5755
|
password: d,
|
|
5676
|
-
mfaToken:
|
|
5756
|
+
mfaToken: g,
|
|
5677
5757
|
oobCode: y,
|
|
5678
5758
|
bindingCode: p,
|
|
5679
5759
|
otp: _,
|
|
@@ -5706,7 +5786,7 @@ class xt {
|
|
|
5706
5786
|
};
|
|
5707
5787
|
let j = !1;
|
|
5708
5788
|
this.issueRefreshToken && v != b.RefreshToken && (j = !0), this.issueRefreshToken && v == b.RefreshToken && this.rollingRefreshToken && (j = !0);
|
|
5709
|
-
let
|
|
5789
|
+
let N;
|
|
5710
5790
|
if (s == "authorization_code")
|
|
5711
5791
|
return this.requireClientSecretOrChallenge && A && A.client_secret && !i && !a ? {
|
|
5712
5792
|
error: "access_denied",
|
|
@@ -5725,22 +5805,22 @@ class xt {
|
|
|
5725
5805
|
error_description: "No authorization code provided for authorization code flow"
|
|
5726
5806
|
};
|
|
5727
5807
|
if (s == "refresh_token") {
|
|
5728
|
-
const
|
|
5729
|
-
if (!n || !
|
|
5808
|
+
const R = await this.getRefreshTokenData(n);
|
|
5809
|
+
if (!n || !R || !this.userStorage)
|
|
5730
5810
|
return {
|
|
5731
5811
|
error: "access_denied",
|
|
5732
5812
|
error_description: "Refresh token is invalid"
|
|
5733
5813
|
};
|
|
5734
5814
|
let P;
|
|
5735
|
-
if (
|
|
5815
|
+
if (R.username)
|
|
5736
5816
|
try {
|
|
5737
|
-
const { user: F } = await ((K = this.userStorage) == null ? void 0 : K.getUserByUsername(
|
|
5817
|
+
const { user: F } = await ((K = this.userStorage) == null ? void 0 : K.getUserByUsername(R.username));
|
|
5738
5818
|
P = F;
|
|
5739
5819
|
} catch (F) {
|
|
5740
5820
|
return u.logger.error(f({
|
|
5741
5821
|
err: F,
|
|
5742
5822
|
msg: "Couldn't get user for refresh token. Doesn't exist?",
|
|
5743
|
-
username:
|
|
5823
|
+
username: R.username
|
|
5744
5824
|
})), {
|
|
5745
5825
|
error: "access_denied",
|
|
5746
5826
|
error_description: "Refresh token is invalid"
|
|
@@ -5758,12 +5838,12 @@ class xt {
|
|
|
5758
5838
|
client_secret: i,
|
|
5759
5839
|
codeVerifier: a,
|
|
5760
5840
|
issueRefreshToken: j,
|
|
5761
|
-
scopes:
|
|
5841
|
+
scopes: R.scope,
|
|
5762
5842
|
user: P
|
|
5763
5843
|
});
|
|
5764
5844
|
} else if (s == "client_credentials") {
|
|
5765
5845
|
const {
|
|
5766
|
-
scopes:
|
|
5846
|
+
scopes: R,
|
|
5767
5847
|
error: P,
|
|
5768
5848
|
error_description: F
|
|
5769
5849
|
} = await this.validateAndPersistScope(e, t, void 0);
|
|
@@ -5774,7 +5854,7 @@ class xt {
|
|
|
5774
5854
|
client: A,
|
|
5775
5855
|
client_secret: i,
|
|
5776
5856
|
codeVerifier: a,
|
|
5777
|
-
scopes:
|
|
5857
|
+
scopes: R,
|
|
5778
5858
|
issueRefreshToken: j
|
|
5779
5859
|
});
|
|
5780
5860
|
} else if (s == "password") {
|
|
@@ -5789,17 +5869,17 @@ class xt {
|
|
|
5789
5869
|
error: "server_error",
|
|
5790
5870
|
error_description: "Password authentication not configured"
|
|
5791
5871
|
};
|
|
5792
|
-
const { user: I, secrets: $ } = await this.userStorage.getUserByUsername(c),
|
|
5793
|
-
if (!
|
|
5872
|
+
const { user: I, secrets: $ } = await this.userStorage.getUserByUsername(c), z = this.authenticators[I.factor1];
|
|
5873
|
+
if (!z || !z.secretNames().includes("password"))
|
|
5794
5874
|
return {
|
|
5795
5875
|
error: "access_denied",
|
|
5796
5876
|
error_description: "Password flow used but factor 1 authenticator does not accept passwords"
|
|
5797
5877
|
};
|
|
5798
|
-
await
|
|
5878
|
+
await z.authenticateUser(
|
|
5799
5879
|
I,
|
|
5800
5880
|
$,
|
|
5801
5881
|
{ password: d }
|
|
5802
|
-
),
|
|
5882
|
+
), N = I;
|
|
5803
5883
|
} catch (I) {
|
|
5804
5884
|
return u.logger.debug(f({ err: I })), {
|
|
5805
5885
|
error: "access_denied",
|
|
@@ -5807,27 +5887,27 @@ class xt {
|
|
|
5807
5887
|
};
|
|
5808
5888
|
}
|
|
5809
5889
|
const {
|
|
5810
|
-
scopes:
|
|
5890
|
+
scopes: R,
|
|
5811
5891
|
error: P,
|
|
5812
5892
|
error_description: F
|
|
5813
|
-
} = await this.validateAndPersistScope(e, t,
|
|
5893
|
+
} = await this.validateAndPersistScope(e, t, N);
|
|
5814
5894
|
return P ? {
|
|
5815
5895
|
error: P,
|
|
5816
5896
|
error_description: F
|
|
5817
|
-
} :
|
|
5897
|
+
} : N.factor2 ? this.allowedFactor2.length > 0 && (N.state == E.factor2ResetNeeded || !this.allowedFactor2.includes(N.factor2 ? N.factor2 : "none")) ? {
|
|
5818
5898
|
error: "access_denied",
|
|
5819
5899
|
error_description: "2FA method not allowed or needs to be reconfigured"
|
|
5820
|
-
} : await this.createMfaRequest(
|
|
5900
|
+
} : await this.createMfaRequest(N) : await this.makeAccessToken({
|
|
5821
5901
|
client: A,
|
|
5822
5902
|
client_secret: i,
|
|
5823
5903
|
codeVerifier: a,
|
|
5824
|
-
scopes:
|
|
5904
|
+
scopes: R,
|
|
5825
5905
|
issueRefreshToken: j,
|
|
5826
|
-
user:
|
|
5906
|
+
user: N
|
|
5827
5907
|
});
|
|
5828
5908
|
} else if (s == "http://auth0.com/oauth/grant-type/mfa-otp") {
|
|
5829
5909
|
const {
|
|
5830
|
-
scopes:
|
|
5910
|
+
scopes: R,
|
|
5831
5911
|
error: P,
|
|
5832
5912
|
error_description: F
|
|
5833
5913
|
} = await this.validateAndPersistScope(e, t, void 0);
|
|
@@ -5841,26 +5921,26 @@ class xt {
|
|
|
5841
5921
|
error: "access_denied",
|
|
5842
5922
|
error_description: "OTP not provided"
|
|
5843
5923
|
};
|
|
5844
|
-
if (!
|
|
5924
|
+
if (!g)
|
|
5845
5925
|
return {
|
|
5846
5926
|
error: "access_denied",
|
|
5847
5927
|
error_description: "MFA token not provided"
|
|
5848
5928
|
};
|
|
5849
|
-
const I = await this.validateMfaToken(
|
|
5929
|
+
const I = await this.validateMfaToken(g), $ = U.mfaToken + T.hash(g);
|
|
5850
5930
|
if (!I.user || !I.key)
|
|
5851
5931
|
return {
|
|
5852
5932
|
error: "access_denied",
|
|
5853
5933
|
error_description: "Invalid MFA token"
|
|
5854
5934
|
};
|
|
5855
|
-
const
|
|
5856
|
-
if (!
|
|
5935
|
+
const z = this.authenticators[I.user.factor2];
|
|
5936
|
+
if (!z || !this.userStorage)
|
|
5857
5937
|
return {
|
|
5858
5938
|
error: "access_denied",
|
|
5859
5939
|
error_description: "MFA type is not supported for OAuth"
|
|
5860
5940
|
};
|
|
5861
5941
|
try {
|
|
5862
5942
|
const { secrets: V } = await this.userStorage.getUserById(I.user.id);
|
|
5863
|
-
await
|
|
5943
|
+
await z.authenticateUser(
|
|
5864
5944
|
I.user,
|
|
5865
5945
|
V,
|
|
5866
5946
|
{ otp: _ }
|
|
@@ -5884,13 +5964,13 @@ class xt {
|
|
|
5884
5964
|
client: A,
|
|
5885
5965
|
client_secret: i,
|
|
5886
5966
|
codeVerifier: a,
|
|
5887
|
-
scopes:
|
|
5967
|
+
scopes: R,
|
|
5888
5968
|
issueRefreshToken: j,
|
|
5889
5969
|
user: I.user
|
|
5890
5970
|
});
|
|
5891
5971
|
} else if (s == "http://auth0.com/oauth/grant-type/mfa-oob") {
|
|
5892
5972
|
const {
|
|
5893
|
-
scopes:
|
|
5973
|
+
scopes: R,
|
|
5894
5974
|
error: P,
|
|
5895
5975
|
error_description: F
|
|
5896
5976
|
} = await this.validateAndPersistScope(e, t, void 0);
|
|
@@ -5904,12 +5984,12 @@ class xt {
|
|
|
5904
5984
|
error: "access_denied",
|
|
5905
5985
|
error_description: "OOB code or binding code not provided"
|
|
5906
5986
|
};
|
|
5907
|
-
if (!
|
|
5987
|
+
if (!g)
|
|
5908
5988
|
return {
|
|
5909
5989
|
error: "access_denied",
|
|
5910
5990
|
error_description: "MFA token not provided"
|
|
5911
5991
|
};
|
|
5912
|
-
const I = await this.validateMfaToken(
|
|
5992
|
+
const I = await this.validateMfaToken(g);
|
|
5913
5993
|
if (!I.user || !I.key)
|
|
5914
5994
|
return {
|
|
5915
5995
|
error: "access_denied",
|
|
@@ -5922,7 +6002,7 @@ class xt {
|
|
|
5922
6002
|
error_description: "MFA type is not supported for OAuth"
|
|
5923
6003
|
};
|
|
5924
6004
|
try {
|
|
5925
|
-
const { secrets:
|
|
6005
|
+
const { secrets: z } = await this.userStorage.getUserById(I.user.id), V = L.decodeData(I.key.data).omfa;
|
|
5926
6006
|
if (!V || !V.otp || !V.oobCode)
|
|
5927
6007
|
return {
|
|
5928
6008
|
error: "server_error",
|
|
@@ -5935,20 +6015,20 @@ class xt {
|
|
|
5935
6015
|
};
|
|
5936
6016
|
await $.authenticateUser(
|
|
5937
6017
|
I.user,
|
|
5938
|
-
{ ...
|
|
6018
|
+
{ ...z, otp: V.otp, expiry: (O = I.key.expires) == null ? void 0 : O.getTime() },
|
|
5939
6019
|
{ otp: p }
|
|
5940
6020
|
);
|
|
5941
|
-
} catch (
|
|
5942
|
-
return u.logger.debug(f({ err:
|
|
6021
|
+
} catch (z) {
|
|
6022
|
+
return u.logger.debug(f({ err: z })), {
|
|
5943
6023
|
error: "access_denied",
|
|
5944
6024
|
error_description: "Invalid OTP"
|
|
5945
6025
|
};
|
|
5946
6026
|
}
|
|
5947
6027
|
try {
|
|
5948
6028
|
await this.keyStorage.deleteKey(I.key.value);
|
|
5949
|
-
} catch (
|
|
5950
|
-
u.logger.debug(f({ err:
|
|
5951
|
-
cerr:
|
|
6029
|
+
} catch (z) {
|
|
6030
|
+
u.logger.debug(f({ err: z })), u.logger.warn(f({
|
|
6031
|
+
cerr: z,
|
|
5952
6032
|
msg: "Couldn't delete mfa token",
|
|
5953
6033
|
hashedMfaToken: I.key.value
|
|
5954
6034
|
}));
|
|
@@ -5957,7 +6037,7 @@ class xt {
|
|
|
5957
6037
|
client: A,
|
|
5958
6038
|
client_secret: i,
|
|
5959
6039
|
codeVerifier: a,
|
|
5960
|
-
scopes:
|
|
6040
|
+
scopes: R,
|
|
5961
6041
|
issueRefreshToken: j,
|
|
5962
6042
|
user: I.user
|
|
5963
6043
|
});
|
|
@@ -5967,9 +6047,9 @@ class xt {
|
|
|
5967
6047
|
error: "invalid_request",
|
|
5968
6048
|
error_description: "No device code given"
|
|
5969
6049
|
};
|
|
5970
|
-
let
|
|
6050
|
+
let R;
|
|
5971
6051
|
try {
|
|
5972
|
-
|
|
6052
|
+
R = await this.keyStorage.getKey(U.deviceCode + C);
|
|
5973
6053
|
} catch (P) {
|
|
5974
6054
|
const F = o.asCrossauthError(P);
|
|
5975
6055
|
return u.logger.debug(f({ err: F })), u.logger.error(f({ msg: "Couldn't get device code", cerr: F })), {
|
|
@@ -5978,8 +6058,8 @@ class xt {
|
|
|
5978
6058
|
};
|
|
5979
6059
|
}
|
|
5980
6060
|
try {
|
|
5981
|
-
const P = JSON.parse(
|
|
5982
|
-
if (
|
|
6061
|
+
const P = JSON.parse(R.data ?? "{}"), F = (/* @__PURE__ */ new Date()).getTime();
|
|
6062
|
+
if (R.expires && F > R.expires.getTime())
|
|
5983
6063
|
return await this.deleteDeviceCode(C), {
|
|
5984
6064
|
error: "expired_token",
|
|
5985
6065
|
error_description: "Code has expired"
|
|
@@ -6076,13 +6156,13 @@ class xt {
|
|
|
6076
6156
|
};
|
|
6077
6157
|
}
|
|
6078
6158
|
let c, d = !1;
|
|
6079
|
-
const
|
|
6159
|
+
const g = /* @__PURE__ */ new Date(), y = this.userCodeExpiry, p = new Date(g.getTime() + this.userCodeExpiry * 1e3 + this.clockTolerance * 1e3);
|
|
6080
6160
|
for (let v = 0; v < 10 && !d; ++v)
|
|
6081
6161
|
try {
|
|
6082
6162
|
c = T.randomValue(this.deviceCodeLength), await this.keyStorage.saveKey(
|
|
6083
6163
|
void 0,
|
|
6084
6164
|
U.deviceCode + c,
|
|
6085
|
-
|
|
6165
|
+
g,
|
|
6086
6166
|
p,
|
|
6087
6167
|
JSON.stringify({ scope: e, client_id: s })
|
|
6088
6168
|
), d = !0;
|
|
@@ -6101,7 +6181,7 @@ class xt {
|
|
|
6101
6181
|
_ = T.randomBase32(this.userCodeLength), await this.keyStorage.saveKey(
|
|
6102
6182
|
void 0,
|
|
6103
6183
|
U.userCode + _,
|
|
6104
|
-
|
|
6184
|
+
g,
|
|
6105
6185
|
p,
|
|
6106
6186
|
JSON.stringify({ deviceCode: c })
|
|
6107
6187
|
), d = !0;
|
|
@@ -6141,7 +6221,7 @@ class xt {
|
|
|
6141
6221
|
userCode: s,
|
|
6142
6222
|
user: e
|
|
6143
6223
|
}) {
|
|
6144
|
-
var
|
|
6224
|
+
var g;
|
|
6145
6225
|
s = s.replace(/[ -]*/g, "");
|
|
6146
6226
|
let t, r = {};
|
|
6147
6227
|
try {
|
|
@@ -6187,7 +6267,7 @@ class xt {
|
|
|
6187
6267
|
error_description: "Unexpected or incomplete data in device code key"
|
|
6188
6268
|
};
|
|
6189
6269
|
}
|
|
6190
|
-
if ((/* @__PURE__ */ new Date()).getTime() > ((
|
|
6270
|
+
if ((/* @__PURE__ */ new Date()).getTime() > ((g = r.expires) == null ? void 0 : g.getTime()))
|
|
6191
6271
|
return await this.deleteUserCode(s), {
|
|
6192
6272
|
ok: !1,
|
|
6193
6273
|
error: "expired_token",
|
|
@@ -6367,7 +6447,7 @@ class xt {
|
|
|
6367
6447
|
error_description: "Invalid MFA token"
|
|
6368
6448
|
};
|
|
6369
6449
|
try {
|
|
6370
|
-
if (
|
|
6450
|
+
if (L.decodeData(t.data).omfaaid != e.factor2)
|
|
6371
6451
|
return {
|
|
6372
6452
|
error: "access_denied",
|
|
6373
6453
|
error_description: "authenticatorId not valid for user"
|
|
@@ -6428,9 +6508,9 @@ class xt {
|
|
|
6428
6508
|
if (!n.client) return n;
|
|
6429
6509
|
const c = n.client, d = await this.authenticateClient(a, c, t);
|
|
6430
6510
|
if (d.error) return d;
|
|
6431
|
-
const
|
|
6432
|
-
if (!
|
|
6433
|
-
if (
|
|
6511
|
+
const g = await this.validateMfaToken(s);
|
|
6512
|
+
if (!g.user || !g.key) return g;
|
|
6513
|
+
if (g.user.factor2 != i)
|
|
6434
6514
|
return {
|
|
6435
6515
|
error: "access_denied",
|
|
6436
6516
|
error_description: "Invalid MFA authenticator"
|
|
@@ -6445,15 +6525,15 @@ class xt {
|
|
|
6445
6525
|
oobCode: T.randomValue(this.codeLength)
|
|
6446
6526
|
});
|
|
6447
6527
|
try {
|
|
6448
|
-
const p = this.authenticators[
|
|
6528
|
+
const p = this.authenticators[g.user.factor2];
|
|
6449
6529
|
if (!p)
|
|
6450
6530
|
throw new o(
|
|
6451
6531
|
l.Configuration,
|
|
6452
6532
|
"User's authenticator has not been loaded"
|
|
6453
6533
|
);
|
|
6454
|
-
const _ = await p.createOneTimeSecrets(
|
|
6534
|
+
const _ = await p.createOneTimeSecrets(g.user);
|
|
6455
6535
|
await this.keyStorage.updateData(
|
|
6456
|
-
|
|
6536
|
+
g.key.value,
|
|
6457
6537
|
"omfa",
|
|
6458
6538
|
{ ...y, ..._ }
|
|
6459
6539
|
);
|
|
@@ -6520,7 +6600,7 @@ class xt {
|
|
|
6520
6600
|
error: "invalid_request",
|
|
6521
6601
|
error_description: `The redirect uri ${e} is invalid`
|
|
6522
6602
|
};
|
|
6523
|
-
const d = /* @__PURE__ */ new Date(),
|
|
6603
|
+
const d = /* @__PURE__ */ new Date(), g = this.authorizationCodeExpiry ? new Date(d.getTime() + this.authorizationCodeExpiry * 1e3 + this.clockTolerance * 1e3) : void 0, y = {};
|
|
6524
6604
|
t && (y.scope = t), i && (y.challengeMethod = a, y.challenge = T.hash(i)), n && (y.username = n.username, y.id = n.id);
|
|
6525
6605
|
const p = JSON.stringify(y);
|
|
6526
6606
|
let _ = !1, C = "";
|
|
@@ -6530,7 +6610,7 @@ class xt {
|
|
|
6530
6610
|
void 0,
|
|
6531
6611
|
U.authorizationCode + T.hash(C),
|
|
6532
6612
|
d,
|
|
6533
|
-
|
|
6613
|
+
g,
|
|
6534
6614
|
p
|
|
6535
6615
|
), _ = !0;
|
|
6536
6616
|
} catch {
|
|
@@ -6562,8 +6642,8 @@ class xt {
|
|
|
6562
6642
|
t ?? "",
|
|
6563
6643
|
s.client_secret ?? ""
|
|
6564
6644
|
));
|
|
6565
|
-
} catch (
|
|
6566
|
-
return u.logger.error(f({ err:
|
|
6645
|
+
} catch (N) {
|
|
6646
|
+
return u.logger.error(f({ err: N })), { error: "server_error", error_description: "Couldn't validate client" };
|
|
6567
6647
|
}
|
|
6568
6648
|
if (!c) return {
|
|
6569
6649
|
error: "access_denied",
|
|
@@ -6571,9 +6651,9 @@ class xt {
|
|
|
6571
6651
|
};
|
|
6572
6652
|
let d = {};
|
|
6573
6653
|
if (e) {
|
|
6574
|
-
let
|
|
6654
|
+
let N;
|
|
6575
6655
|
try {
|
|
6576
|
-
|
|
6656
|
+
N = await this.keyStorage.getKey(U.authorizationCode + T.hash(e)), d = L.decodeData(N.data);
|
|
6577
6657
|
} catch (K) {
|
|
6578
6658
|
return u.logger.debug(f({ err: K })), {
|
|
6579
6659
|
error: "access_denied",
|
|
@@ -6581,7 +6661,7 @@ class xt {
|
|
|
6581
6661
|
};
|
|
6582
6662
|
}
|
|
6583
6663
|
try {
|
|
6584
|
-
await this.keyStorage.deleteKey(
|
|
6664
|
+
await this.keyStorage.deleteKey(N.value);
|
|
6585
6665
|
} catch (K) {
|
|
6586
6666
|
u.logger.warn(f({
|
|
6587
6667
|
err: K,
|
|
@@ -6597,14 +6677,14 @@ class xt {
|
|
|
6597
6677
|
error_description: "Invalid code challenge/code challenge method method for authorization code"
|
|
6598
6678
|
};
|
|
6599
6679
|
if (d.challenge) {
|
|
6600
|
-
const
|
|
6601
|
-
if (T.hash(
|
|
6680
|
+
const N = d.challengeMethod == "plain" ? r ?? "" : T.sha256(r ?? "");
|
|
6681
|
+
if (T.hash(N) != d.challenge)
|
|
6602
6682
|
return {
|
|
6603
6683
|
error: "access_denied",
|
|
6604
6684
|
error_description: "Code verifier is incorrect"
|
|
6605
6685
|
};
|
|
6606
6686
|
}
|
|
6607
|
-
const
|
|
6687
|
+
const g = /* @__PURE__ */ new Date(), y = Math.ceil(g.getTime() / 1e3);
|
|
6608
6688
|
let p;
|
|
6609
6689
|
const _ = T.uuid(), C = {
|
|
6610
6690
|
jti: _,
|
|
@@ -6613,14 +6693,14 @@ class xt {
|
|
|
6613
6693
|
sub: d.username,
|
|
6614
6694
|
type: "access"
|
|
6615
6695
|
};
|
|
6616
|
-
i && (C.scope = i), this.accessTokenExpiry != null && (C.exp = y + this.accessTokenExpiry, p = new Date(
|
|
6617
|
-
const v = await new Promise((
|
|
6618
|
-
|
|
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);
|
|
6697
|
+
const v = await new Promise((N, K) => {
|
|
6698
|
+
se.sign(
|
|
6619
6699
|
C,
|
|
6620
6700
|
this.secretOrPrivateKey,
|
|
6621
6701
|
{ algorithm: this.jwtAlgorithmChecked, keyid: "1" },
|
|
6622
6702
|
(O, B) => {
|
|
6623
|
-
B ?
|
|
6703
|
+
B ? N(B) : K(O || new o(
|
|
6624
6704
|
l.Unauthorized,
|
|
6625
6705
|
"Couldn't create jwt"
|
|
6626
6706
|
));
|
|
@@ -6631,7 +6711,7 @@ class xt {
|
|
|
6631
6711
|
void 0,
|
|
6632
6712
|
// to avoid user storage dependency, we don't set this
|
|
6633
6713
|
U.accessToken + T.hash(_),
|
|
6634
|
-
|
|
6714
|
+
g,
|
|
6635
6715
|
p
|
|
6636
6716
|
));
|
|
6637
6717
|
let k;
|
|
@@ -6646,8 +6726,10 @@ class xt {
|
|
|
6646
6726
|
error_description: "Couldn't load user data"
|
|
6647
6727
|
};
|
|
6648
6728
|
}
|
|
6729
|
+
const N = T.uuid();
|
|
6649
6730
|
let K = {
|
|
6650
|
-
|
|
6731
|
+
aud: s.client_id,
|
|
6732
|
+
jti: N,
|
|
6651
6733
|
iat: y,
|
|
6652
6734
|
iss: this.oauthIssuer,
|
|
6653
6735
|
sub: d.username,
|
|
@@ -6697,15 +6779,15 @@ class xt {
|
|
|
6697
6779
|
}
|
|
6698
6780
|
}
|
|
6699
6781
|
K.scope = i, this.accessTokenExpiry != null && (K.exp = y + this.accessTokenExpiry), k = await new Promise((O, B) => {
|
|
6700
|
-
|
|
6782
|
+
se.sign(
|
|
6701
6783
|
K,
|
|
6702
6784
|
this.secretOrPrivateKey,
|
|
6703
6785
|
{
|
|
6704
6786
|
algorithm: this.jwtAlgorithmChecked,
|
|
6705
6787
|
keyid: this.jwtKid
|
|
6706
6788
|
},
|
|
6707
|
-
(
|
|
6708
|
-
P ? O(P) : B(
|
|
6789
|
+
(R, P) => {
|
|
6790
|
+
P ? O(P) : B(R || new o(
|
|
6709
6791
|
l.Unauthorized,
|
|
6710
6792
|
"Couldn't create jwt"
|
|
6711
6793
|
));
|
|
@@ -6715,11 +6797,11 @@ class xt {
|
|
|
6715
6797
|
}
|
|
6716
6798
|
let A;
|
|
6717
6799
|
if (a) {
|
|
6718
|
-
const
|
|
6800
|
+
const N = {
|
|
6719
6801
|
username: d.username,
|
|
6720
6802
|
client_id: s.client_id
|
|
6721
6803
|
};
|
|
6722
|
-
i && (
|
|
6804
|
+
i && (N.scope = i);
|
|
6723
6805
|
let K;
|
|
6724
6806
|
const B = {
|
|
6725
6807
|
jti: T.uuid(),
|
|
@@ -6728,13 +6810,13 @@ class xt {
|
|
|
6728
6810
|
sub: d.username,
|
|
6729
6811
|
type: "access"
|
|
6730
6812
|
};
|
|
6731
|
-
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((
|
|
6732
|
-
|
|
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(
|
|
6733
6815
|
B,
|
|
6734
6816
|
this.secretOrPrivateKey,
|
|
6735
6817
|
{ algorithm: this.jwtAlgorithmChecked, keyid: "1" },
|
|
6736
6818
|
(F, I) => {
|
|
6737
|
-
I ?
|
|
6819
|
+
I ? R(I) : P(F || new o(
|
|
6738
6820
|
l.Unauthorized,
|
|
6739
6821
|
"Couldn't create jwt"
|
|
6740
6822
|
));
|
|
@@ -6744,9 +6826,9 @@ class xt {
|
|
|
6744
6826
|
void 0,
|
|
6745
6827
|
// to avoid user storage dependency
|
|
6746
6828
|
U.refreshToken + T.hash(A),
|
|
6747
|
-
|
|
6829
|
+
g,
|
|
6748
6830
|
K,
|
|
6749
|
-
JSON.stringify(
|
|
6831
|
+
JSON.stringify(N)
|
|
6750
6832
|
));
|
|
6751
6833
|
}
|
|
6752
6834
|
return {
|
|
@@ -6840,7 +6922,7 @@ class xt {
|
|
|
6840
6922
|
}
|
|
6841
6923
|
async validateJwt(s, e) {
|
|
6842
6924
|
return new Promise((t, r) => {
|
|
6843
|
-
|
|
6925
|
+
se.verify(
|
|
6844
6926
|
s,
|
|
6845
6927
|
this.secretOrPublicKey,
|
|
6846
6928
|
{ clockTolerance: this.clockTolerance, complete: !0 },
|
|
@@ -6982,7 +7064,7 @@ class xt {
|
|
|
6982
7064
|
jwks() {
|
|
6983
7065
|
let s = [];
|
|
6984
7066
|
if (this.jwtPublicKey) {
|
|
6985
|
-
const e =
|
|
7067
|
+
const e = ze(this.jwtPublicKey).export({ format: "jwk" });
|
|
6986
7068
|
e.kid = "1", e.alg = this.jwtKeyType, s.push(e);
|
|
6987
7069
|
}
|
|
6988
7070
|
return { keys: s };
|
|
@@ -7028,10 +7110,10 @@ class nt extends Pe {
|
|
|
7028
7110
|
*
|
|
7029
7111
|
* @param options see {@link OAuthTokenConsumerOptions}
|
|
7030
7112
|
*/
|
|
7031
|
-
constructor(e = {}) {
|
|
7032
|
-
const
|
|
7033
|
-
|
|
7034
|
-
super(
|
|
7113
|
+
constructor(e, t = {}) {
|
|
7114
|
+
const r = {};
|
|
7115
|
+
w("jwtKeyType", m.String, r, t, "JWT_KEY_TYPE");
|
|
7116
|
+
super(e, { ...t, ...r });
|
|
7035
7117
|
/**
|
|
7036
7118
|
* Value passed to the constructor. The `aud` claim must match it
|
|
7037
7119
|
*/
|
|
@@ -7044,7 +7126,7 @@ class nt extends Pe {
|
|
|
7044
7126
|
h(this, "keyStorage");
|
|
7045
7127
|
h(this, "jwtSecretKeyFile", "");
|
|
7046
7128
|
h(this, "jwtPublicKeyFile", "");
|
|
7047
|
-
if (this.audience =
|
|
7129
|
+
if (this.audience = e, w("authServerBaseUrl", m.String, this, t, "AUTH_SERVER_BASE_URL", !0), w("jwtSecretKeyFile", m.String, this, t, "JWT_SECRET_KEY_FILE"), w("jwtPublicKeyFile", m.String, this, t, "JWT_PUBLIC_KEY_FILE"), w("jwtSecretKey", m.String, this, t, "JWT_SECRET_KEY"), w("jwtPublicKey", m.String, this, t, "JWT_PUBLIC_KEY"), w("clockTolerance", m.Number, this, t, "OAUTH_CLOCK_TOLERANCE"), w("persistAccessToken", m.Boolean, this, t, "OAUTH_PERSIST_ACCESS_TOKEN"), this.keyStorage = t.keyStorage, this.jwtSecretKey || this.jwtSecretKeyFile) {
|
|
7048
7130
|
if (this.jwtPublicKey || this.jwtPublicKeyFile)
|
|
7049
7131
|
throw new o(
|
|
7050
7132
|
l.Configuration,
|
|
@@ -7087,7 +7169,6 @@ class nt extends Pe {
|
|
|
7087
7169
|
* @param token The token to validate
|
|
7088
7170
|
* @param tokenType If defined, the `type` claim in the payload must
|
|
7089
7171
|
* match this value
|
|
7090
|
-
* @returns
|
|
7091
7172
|
*/
|
|
7092
7173
|
async tokenAuthorized(e, t) {
|
|
7093
7174
|
var i;
|
|
@@ -7109,7 +7190,7 @@ class nt extends Pe {
|
|
|
7109
7190
|
return r;
|
|
7110
7191
|
}
|
|
7111
7192
|
}
|
|
7112
|
-
class
|
|
7193
|
+
class Ht extends Ke {
|
|
7113
7194
|
/**
|
|
7114
7195
|
* Constructor
|
|
7115
7196
|
* @param authServerBaseUrl bsae URI for the authorization server
|
|
@@ -7121,20 +7202,28 @@ class Bt extends Ke {
|
|
|
7121
7202
|
const r = {
|
|
7122
7203
|
client_id: ""
|
|
7123
7204
|
};
|
|
7124
|
-
|
|
7205
|
+
w("client_id", m.String, r, t, "OAUTH_CLIENT_ID", !0);
|
|
7125
7206
|
super({
|
|
7126
7207
|
authServerBaseUrl: e,
|
|
7127
|
-
tokenConsumer: new nt(
|
|
7128
|
-
|
|
7129
|
-
|
|
7130
|
-
|
|
7131
|
-
|
|
7208
|
+
tokenConsumer: new nt(
|
|
7209
|
+
r.client_id,
|
|
7210
|
+
{
|
|
7211
|
+
audience: r.client_id,
|
|
7212
|
+
authServerBaseUrl: e,
|
|
7213
|
+
...t
|
|
7214
|
+
}
|
|
7215
|
+
),
|
|
7132
7216
|
...t
|
|
7133
7217
|
});
|
|
7134
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");
|
|
7135
7224
|
this.client_id = r.client_id;
|
|
7136
7225
|
let i = {};
|
|
7137
|
-
|
|
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);
|
|
7138
7227
|
}
|
|
7139
7228
|
/**
|
|
7140
7229
|
* Uses {@link @crossauth/backend!Crypto.randomValue} to create a random string
|
|
@@ -7154,7 +7243,38 @@ class Bt extends Ke {
|
|
|
7154
7243
|
return T.sha256(e);
|
|
7155
7244
|
}
|
|
7156
7245
|
}
|
|
7157
|
-
|
|
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 {
|
|
7158
7278
|
/**
|
|
7159
7279
|
* Constructor
|
|
7160
7280
|
* @param tokenConsumers one or more consumers that will process
|
|
@@ -7163,10 +7283,12 @@ class zt {
|
|
|
7163
7283
|
* at present
|
|
7164
7284
|
*/
|
|
7165
7285
|
constructor(s, e = {}) {
|
|
7166
|
-
/** The token consumer that validates the access tokens.
|
|
7167
|
-
|
|
7168
|
-
|
|
7169
|
-
|
|
7286
|
+
/** The token consumer that validates the access tokens.
|
|
7287
|
+
* Keyed on auth server base URL then audience. The latter may be ""
|
|
7288
|
+
* for none
|
|
7289
|
+
*/
|
|
7290
|
+
h(this, "tokenConsumers");
|
|
7291
|
+
this.tokenConsumers = [...s];
|
|
7170
7292
|
}
|
|
7171
7293
|
/**
|
|
7172
7294
|
* Returns a token payload if the access token has a valid signature
|
|
@@ -7184,8 +7306,9 @@ class zt {
|
|
|
7184
7306
|
async accessTokenAuthorized(s) {
|
|
7185
7307
|
try {
|
|
7186
7308
|
const e = He.decodeJwt(s);
|
|
7187
|
-
|
|
7188
|
-
|
|
7309
|
+
for (let t of this.tokenConsumers)
|
|
7310
|
+
if (e.iss == t.authServerBaseUrl && (e.aud == t.audience || e.aud == null && t.audience == ""))
|
|
7311
|
+
return await t.tokenAuthorized(s, "access");
|
|
7189
7312
|
throw new o(l.Unauthorized, "Invalid issuer in access token");
|
|
7190
7313
|
} catch (e) {
|
|
7191
7314
|
u.logger.warn(f({ err: e }));
|
|
@@ -7194,44 +7317,44 @@ class zt {
|
|
|
7194
7317
|
}
|
|
7195
7318
|
}
|
|
7196
7319
|
export {
|
|
7197
|
-
|
|
7320
|
+
ge as ApiKeyManager,
|
|
7198
7321
|
re as Authenticator,
|
|
7199
7322
|
T as Crypto,
|
|
7200
7323
|
rt as DoubleSubmitCsrfToken,
|
|
7201
|
-
|
|
7324
|
+
Rt as DummyFactor2Authenticator,
|
|
7202
7325
|
Z as EmailAuthenticator,
|
|
7203
|
-
|
|
7204
|
-
|
|
7205
|
-
|
|
7206
|
-
|
|
7207
|
-
|
|
7208
|
-
|
|
7209
|
-
|
|
7326
|
+
At as InMemoryKeyStorage,
|
|
7327
|
+
Pt as InMemoryOAuthAuthorizationStorage,
|
|
7328
|
+
It as InMemoryOAuthClientStorage,
|
|
7329
|
+
Ut as InMemoryUserStorage,
|
|
7330
|
+
L as KeyStorage,
|
|
7331
|
+
xt as LdapAuthenticator,
|
|
7332
|
+
oe as LdapUserStorage,
|
|
7210
7333
|
Te as LocalPasswordAuthenticator,
|
|
7211
|
-
|
|
7212
|
-
|
|
7213
|
-
|
|
7334
|
+
zt as OAuthAuthorizationServer,
|
|
7335
|
+
we as OAuthAuthorizationStorage,
|
|
7336
|
+
Ht as OAuthClientBackend,
|
|
7214
7337
|
J as OAuthClientManager,
|
|
7215
|
-
|
|
7216
|
-
|
|
7338
|
+
me as OAuthClientStorage,
|
|
7339
|
+
Mt as OAuthResourceServer,
|
|
7217
7340
|
nt as OAuthTokenConsumer,
|
|
7218
|
-
|
|
7341
|
+
m as ParamType,
|
|
7219
7342
|
be as PasswordAuthenticator,
|
|
7220
|
-
|
|
7221
|
-
|
|
7222
|
-
|
|
7223
|
-
|
|
7224
|
-
|
|
7225
|
-
|
|
7226
|
-
|
|
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,
|
|
7227
7350
|
G as PrismaUserStorage,
|
|
7228
|
-
|
|
7229
|
-
|
|
7351
|
+
D as SessionCookie,
|
|
7352
|
+
Lt as SessionManager,
|
|
7230
7353
|
Q as SmsAuthenticator,
|
|
7231
|
-
|
|
7232
|
-
|
|
7354
|
+
x as TokenEmailer,
|
|
7355
|
+
Dt as TotpAuthenticator,
|
|
7233
7356
|
Ue as TwilioAuthenticator,
|
|
7234
7357
|
H as UserStorage,
|
|
7235
|
-
|
|
7236
|
-
|
|
7358
|
+
w as setParameter,
|
|
7359
|
+
Bt as toCookieSerializeOptions
|
|
7237
7360
|
};
|