@eaccess/auth 0.1.0 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +143 -106
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +36 -1
- package/dist/index.d.ts +36 -1
- package/dist/index.js +142 -106
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -67,6 +67,7 @@ __export(index_exports, {
|
|
|
67
67
|
cleanupExpiredTokens: () => cleanupExpiredTokens,
|
|
68
68
|
createAuthMiddleware: () => createAuthMiddleware,
|
|
69
69
|
createAuthTables: () => createAuthTables,
|
|
70
|
+
createUser: () => createUser,
|
|
70
71
|
dropAuthTables: () => dropAuthTables,
|
|
71
72
|
getAuthTableStats: () => getAuthTableStats,
|
|
72
73
|
isValidEmail: () => isValidEmail,
|
|
@@ -75,71 +76,9 @@ __export(index_exports, {
|
|
|
75
76
|
module.exports = __toCommonJS(index_exports);
|
|
76
77
|
|
|
77
78
|
// src/auth-admin-manager.ts
|
|
78
|
-
var
|
|
79
|
+
var import_hash2 = require("@prsm/hash");
|
|
79
80
|
var import_ms = __toESM(require("@prsm/ms"), 1);
|
|
80
81
|
|
|
81
|
-
// src/types.ts
|
|
82
|
-
var import_express_session = require("express-session");
|
|
83
|
-
var TwoFactorMechanism = /* @__PURE__ */ ((TwoFactorMechanism2) => {
|
|
84
|
-
TwoFactorMechanism2[TwoFactorMechanism2["TOTP"] = 1] = "TOTP";
|
|
85
|
-
TwoFactorMechanism2[TwoFactorMechanism2["EMAIL"] = 2] = "EMAIL";
|
|
86
|
-
TwoFactorMechanism2[TwoFactorMechanism2["SMS"] = 3] = "SMS";
|
|
87
|
-
return TwoFactorMechanism2;
|
|
88
|
-
})(TwoFactorMechanism || {});
|
|
89
|
-
var AuthStatus = {
|
|
90
|
-
Normal: 0,
|
|
91
|
-
Archived: 1,
|
|
92
|
-
Banned: 2,
|
|
93
|
-
Locked: 3,
|
|
94
|
-
PendingReview: 4,
|
|
95
|
-
Suspended: 5
|
|
96
|
-
};
|
|
97
|
-
var AuthRole = {
|
|
98
|
-
Admin: 1,
|
|
99
|
-
Author: 2,
|
|
100
|
-
Collaborator: 4,
|
|
101
|
-
Consultant: 8,
|
|
102
|
-
Consumer: 16,
|
|
103
|
-
Contributor: 32,
|
|
104
|
-
Coordinator: 64,
|
|
105
|
-
Creator: 128,
|
|
106
|
-
Developer: 256,
|
|
107
|
-
Director: 512,
|
|
108
|
-
Editor: 1024,
|
|
109
|
-
Employee: 2048,
|
|
110
|
-
Maintainer: 4096,
|
|
111
|
-
Manager: 8192,
|
|
112
|
-
Moderator: 16384,
|
|
113
|
-
Publisher: 32768,
|
|
114
|
-
Reviewer: 65536,
|
|
115
|
-
Subscriber: 131072,
|
|
116
|
-
SuperAdmin: 262144,
|
|
117
|
-
SuperEditor: 524288,
|
|
118
|
-
SuperModerator: 1048576,
|
|
119
|
-
Translator: 2097152
|
|
120
|
-
};
|
|
121
|
-
var AuthActivityAction = {
|
|
122
|
-
Login: "login",
|
|
123
|
-
Logout: "logout",
|
|
124
|
-
FailedLogin: "failed_login",
|
|
125
|
-
Register: "register",
|
|
126
|
-
EmailConfirmed: "email_confirmed",
|
|
127
|
-
PasswordResetRequested: "password_reset_requested",
|
|
128
|
-
PasswordResetCompleted: "password_reset_completed",
|
|
129
|
-
PasswordChanged: "password_changed",
|
|
130
|
-
EmailChanged: "email_changed",
|
|
131
|
-
RoleChanged: "role_changed",
|
|
132
|
-
StatusChanged: "status_changed",
|
|
133
|
-
ForceLogout: "force_logout",
|
|
134
|
-
OAuthConnected: "oauth_connected",
|
|
135
|
-
RememberTokenCreated: "remember_token_created",
|
|
136
|
-
TwoFactorSetup: "two_factor_setup",
|
|
137
|
-
TwoFactorVerified: "two_factor_verified",
|
|
138
|
-
TwoFactorFailed: "two_factor_failed",
|
|
139
|
-
TwoFactorDisabled: "two_factor_disabled",
|
|
140
|
-
BackupCodeUsed: "backup_code_used"
|
|
141
|
-
};
|
|
142
|
-
|
|
143
82
|
// src/queries.ts
|
|
144
83
|
var AuthQueries = class {
|
|
145
84
|
constructor(config) {
|
|
@@ -516,6 +455,9 @@ var TwoFactorSetupIncompleteError = class extends AuthError {
|
|
|
516
455
|
}
|
|
517
456
|
};
|
|
518
457
|
|
|
458
|
+
// src/create-user.ts
|
|
459
|
+
var import_hash = require("@prsm/hash");
|
|
460
|
+
|
|
519
461
|
// src/util.ts
|
|
520
462
|
var isValidEmail = (email) => {
|
|
521
463
|
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
@@ -534,6 +476,123 @@ var validateEmail = (email) => {
|
|
|
534
476
|
};
|
|
535
477
|
var createMapFromEnum = (enumObj) => Object.fromEntries(Object.entries(enumObj).map(([key, value]) => [value, key]));
|
|
536
478
|
|
|
479
|
+
// src/types.ts
|
|
480
|
+
var import_express_session = require("express-session");
|
|
481
|
+
var TwoFactorMechanism = /* @__PURE__ */ ((TwoFactorMechanism2) => {
|
|
482
|
+
TwoFactorMechanism2[TwoFactorMechanism2["TOTP"] = 1] = "TOTP";
|
|
483
|
+
TwoFactorMechanism2[TwoFactorMechanism2["EMAIL"] = 2] = "EMAIL";
|
|
484
|
+
TwoFactorMechanism2[TwoFactorMechanism2["SMS"] = 3] = "SMS";
|
|
485
|
+
return TwoFactorMechanism2;
|
|
486
|
+
})(TwoFactorMechanism || {});
|
|
487
|
+
var AuthStatus = {
|
|
488
|
+
Normal: 0,
|
|
489
|
+
Archived: 1,
|
|
490
|
+
Banned: 2,
|
|
491
|
+
Locked: 3,
|
|
492
|
+
PendingReview: 4,
|
|
493
|
+
Suspended: 5
|
|
494
|
+
};
|
|
495
|
+
var AuthRole = {
|
|
496
|
+
Admin: 1,
|
|
497
|
+
Author: 2,
|
|
498
|
+
Collaborator: 4,
|
|
499
|
+
Consultant: 8,
|
|
500
|
+
Consumer: 16,
|
|
501
|
+
Contributor: 32,
|
|
502
|
+
Coordinator: 64,
|
|
503
|
+
Creator: 128,
|
|
504
|
+
Developer: 256,
|
|
505
|
+
Director: 512,
|
|
506
|
+
Editor: 1024,
|
|
507
|
+
Employee: 2048,
|
|
508
|
+
Maintainer: 4096,
|
|
509
|
+
Manager: 8192,
|
|
510
|
+
Moderator: 16384,
|
|
511
|
+
Publisher: 32768,
|
|
512
|
+
Reviewer: 65536,
|
|
513
|
+
Subscriber: 131072,
|
|
514
|
+
SuperAdmin: 262144,
|
|
515
|
+
SuperEditor: 524288,
|
|
516
|
+
SuperModerator: 1048576,
|
|
517
|
+
Translator: 2097152
|
|
518
|
+
};
|
|
519
|
+
var AuthActivityAction = {
|
|
520
|
+
Login: "login",
|
|
521
|
+
Logout: "logout",
|
|
522
|
+
FailedLogin: "failed_login",
|
|
523
|
+
Register: "register",
|
|
524
|
+
EmailConfirmed: "email_confirmed",
|
|
525
|
+
PasswordResetRequested: "password_reset_requested",
|
|
526
|
+
PasswordResetCompleted: "password_reset_completed",
|
|
527
|
+
PasswordChanged: "password_changed",
|
|
528
|
+
EmailChanged: "email_changed",
|
|
529
|
+
RoleChanged: "role_changed",
|
|
530
|
+
StatusChanged: "status_changed",
|
|
531
|
+
ForceLogout: "force_logout",
|
|
532
|
+
OAuthConnected: "oauth_connected",
|
|
533
|
+
RememberTokenCreated: "remember_token_created",
|
|
534
|
+
TwoFactorSetup: "two_factor_setup",
|
|
535
|
+
TwoFactorVerified: "two_factor_verified",
|
|
536
|
+
TwoFactorFailed: "two_factor_failed",
|
|
537
|
+
TwoFactorDisabled: "two_factor_disabled",
|
|
538
|
+
BackupCodeUsed: "backup_code_used"
|
|
539
|
+
};
|
|
540
|
+
|
|
541
|
+
// src/create-user.ts
|
|
542
|
+
function validatePassword(password, config) {
|
|
543
|
+
const minLength = config.minPasswordLength || 8;
|
|
544
|
+
const maxLength = config.maxPasswordLength || 64;
|
|
545
|
+
if (typeof password !== "string") {
|
|
546
|
+
throw new InvalidPasswordError();
|
|
547
|
+
}
|
|
548
|
+
if (password.length < minLength) {
|
|
549
|
+
throw new InvalidPasswordError();
|
|
550
|
+
}
|
|
551
|
+
if (password.length > maxLength) {
|
|
552
|
+
throw new InvalidPasswordError();
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
function generateAutoUserId() {
|
|
556
|
+
return crypto.randomUUID();
|
|
557
|
+
}
|
|
558
|
+
async function createConfirmationToken(queries, account, email, callback) {
|
|
559
|
+
const token = import_hash.hash.encode(email);
|
|
560
|
+
const expires = new Date(Date.now() + 1e3 * 60 * 60 * 24 * 7);
|
|
561
|
+
await queries.createConfirmation({
|
|
562
|
+
accountId: account.id,
|
|
563
|
+
token,
|
|
564
|
+
email,
|
|
565
|
+
expires
|
|
566
|
+
});
|
|
567
|
+
if (callback) {
|
|
568
|
+
callback(token);
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
async function createUser(config, credentials, userId, callback) {
|
|
572
|
+
validateEmail(credentials.email);
|
|
573
|
+
validatePassword(credentials.password, config);
|
|
574
|
+
const queries = new AuthQueries(config);
|
|
575
|
+
const existing = await queries.findAccountByEmail(credentials.email);
|
|
576
|
+
if (existing) {
|
|
577
|
+
throw new EmailTakenError();
|
|
578
|
+
}
|
|
579
|
+
const finalUserId = userId || generateAutoUserId();
|
|
580
|
+
const hashedPassword = import_hash.hash.encode(credentials.password);
|
|
581
|
+
const verified = typeof callback !== "function";
|
|
582
|
+
const account = await queries.createAccount({
|
|
583
|
+
userId: finalUserId,
|
|
584
|
+
email: credentials.email,
|
|
585
|
+
password: hashedPassword,
|
|
586
|
+
verified,
|
|
587
|
+
status: AuthStatus.Normal,
|
|
588
|
+
rolemask: 0
|
|
589
|
+
});
|
|
590
|
+
if (!verified && callback) {
|
|
591
|
+
await createConfirmationToken(queries, account, credentials.email, callback);
|
|
592
|
+
}
|
|
593
|
+
return account;
|
|
594
|
+
}
|
|
595
|
+
|
|
537
596
|
// src/auth-admin-manager.ts
|
|
538
597
|
var AuthAdminManager = class {
|
|
539
598
|
constructor(req, res, config, auth) {
|
|
@@ -556,9 +615,6 @@ var AuthAdminManager = class {
|
|
|
556
615
|
throw new InvalidPasswordError();
|
|
557
616
|
}
|
|
558
617
|
}
|
|
559
|
-
generateAutoUserId() {
|
|
560
|
-
return crypto.randomUUID();
|
|
561
|
-
}
|
|
562
618
|
async findAccountByIdentifier(identifier) {
|
|
563
619
|
if (identifier.accountId !== void 0) {
|
|
564
620
|
return await this.queries.findAccountById(identifier.accountId);
|
|
@@ -570,7 +626,7 @@ var AuthAdminManager = class {
|
|
|
570
626
|
return null;
|
|
571
627
|
}
|
|
572
628
|
async createConfirmationToken(account, email, callback) {
|
|
573
|
-
const token =
|
|
629
|
+
const token = import_hash2.hash.encode(email);
|
|
574
630
|
const expires = new Date(Date.now() + 1e3 * 60 * 60 * 24 * 7);
|
|
575
631
|
await this.queries.createConfirmation({
|
|
576
632
|
accountId: account.id,
|
|
@@ -593,27 +649,7 @@ var AuthAdminManager = class {
|
|
|
593
649
|
* @throws {InvalidPasswordError} Password doesn't meet length requirements
|
|
594
650
|
*/
|
|
595
651
|
async createUser(credentials, userId, callback) {
|
|
596
|
-
|
|
597
|
-
this.validatePassword(credentials.password);
|
|
598
|
-
const existing = await this.queries.findAccountByEmail(credentials.email);
|
|
599
|
-
if (existing) {
|
|
600
|
-
throw new EmailTakenError();
|
|
601
|
-
}
|
|
602
|
-
const finalUserId = userId || this.generateAutoUserId();
|
|
603
|
-
const hashedPassword = import_hash.hash.encode(credentials.password);
|
|
604
|
-
const verified = typeof callback !== "function";
|
|
605
|
-
const account = await this.queries.createAccount({
|
|
606
|
-
userId: finalUserId,
|
|
607
|
-
email: credentials.email,
|
|
608
|
-
password: hashedPassword,
|
|
609
|
-
verified,
|
|
610
|
-
status: AuthStatus.Normal,
|
|
611
|
-
rolemask: 0
|
|
612
|
-
});
|
|
613
|
-
if (!verified && callback) {
|
|
614
|
-
await this.createConfirmationToken(account, credentials.email, callback);
|
|
615
|
-
}
|
|
616
|
-
return account;
|
|
652
|
+
return createUser(this.config, credentials, userId, callback);
|
|
617
653
|
}
|
|
618
654
|
/**
|
|
619
655
|
* Log in as another user (admin function).
|
|
@@ -706,7 +742,7 @@ var AuthAdminManager = class {
|
|
|
706
742
|
throw new UserNotFoundError();
|
|
707
743
|
}
|
|
708
744
|
await this.queries.updateAccount(account.id, {
|
|
709
|
-
password:
|
|
745
|
+
password: import_hash2.hash.encode(password)
|
|
710
746
|
});
|
|
711
747
|
}
|
|
712
748
|
/**
|
|
@@ -742,7 +778,7 @@ var AuthAdminManager = class {
|
|
|
742
778
|
throw new EmailNotVerifiedError();
|
|
743
779
|
}
|
|
744
780
|
const expiry = !expiresAfter ? (0, import_ms.default)("6h") : (0, import_ms.default)(expiresAfter);
|
|
745
|
-
const token =
|
|
781
|
+
const token = import_hash2.hash.encode(account.email);
|
|
746
782
|
const expires = new Date(Date.now() + expiry);
|
|
747
783
|
await this.queries.createResetToken({
|
|
748
784
|
accountId: account.id,
|
|
@@ -774,7 +810,7 @@ var AuthAdminManager = class {
|
|
|
774
810
|
};
|
|
775
811
|
|
|
776
812
|
// src/auth-manager.ts
|
|
777
|
-
var
|
|
813
|
+
var import_hash5 = require("@prsm/hash");
|
|
778
814
|
var import_ms3 = __toESM(require("@prsm/ms"), 1);
|
|
779
815
|
|
|
780
816
|
// src/activity-logger.ts
|
|
@@ -1172,7 +1208,7 @@ var AzureProvider = class extends BaseOAuthProvider {
|
|
|
1172
1208
|
|
|
1173
1209
|
// src/two-factor/totp-provider.ts
|
|
1174
1210
|
var import_totp = __toESM(require("@eaccess/totp"), 1);
|
|
1175
|
-
var
|
|
1211
|
+
var import_hash3 = require("@prsm/hash");
|
|
1176
1212
|
var TotpProvider = class {
|
|
1177
1213
|
constructor(config) {
|
|
1178
1214
|
this.config = config;
|
|
@@ -1201,11 +1237,11 @@ var TotpProvider = class {
|
|
|
1201
1237
|
return codes;
|
|
1202
1238
|
}
|
|
1203
1239
|
hashBackupCodes(codes) {
|
|
1204
|
-
return codes.map((code) =>
|
|
1240
|
+
return codes.map((code) => import_hash3.hash.encode(code));
|
|
1205
1241
|
}
|
|
1206
1242
|
verifyBackupCode(hashedCodes, inputCode) {
|
|
1207
1243
|
for (let i = 0; i < hashedCodes.length; i++) {
|
|
1208
|
-
if (
|
|
1244
|
+
if (import_hash3.hash.verify(hashedCodes[i], inputCode.toUpperCase())) {
|
|
1209
1245
|
return { isValid: true, index: i };
|
|
1210
1246
|
}
|
|
1211
1247
|
}
|
|
@@ -1222,7 +1258,7 @@ var TotpProvider = class {
|
|
|
1222
1258
|
|
|
1223
1259
|
// src/two-factor/otp-provider.ts
|
|
1224
1260
|
var import_ms2 = __toESM(require("@prsm/ms"), 1);
|
|
1225
|
-
var
|
|
1261
|
+
var import_hash4 = require("@prsm/hash");
|
|
1226
1262
|
var OtpProvider = class {
|
|
1227
1263
|
constructor(config) {
|
|
1228
1264
|
this.config = config;
|
|
@@ -1247,7 +1283,7 @@ var OtpProvider = class {
|
|
|
1247
1283
|
async createAndStoreOTP(accountId, mechanism) {
|
|
1248
1284
|
const otp = this.generateOTP();
|
|
1249
1285
|
const selector = this.generateSelector();
|
|
1250
|
-
const tokenHash =
|
|
1286
|
+
const tokenHash = import_hash4.hash.encode(otp);
|
|
1251
1287
|
const expiryDuration = this.config.twoFactor?.tokenExpiry || "5m";
|
|
1252
1288
|
const expiresAt = new Date(Date.now() + (0, import_ms2.default)(expiryDuration));
|
|
1253
1289
|
await this.queries.deleteTwoFactorTokensByAccountAndMechanism(accountId, mechanism);
|
|
@@ -1269,7 +1305,7 @@ var OtpProvider = class {
|
|
|
1269
1305
|
await this.queries.deleteTwoFactorToken(token.id);
|
|
1270
1306
|
return { isValid: false };
|
|
1271
1307
|
}
|
|
1272
|
-
const isValid =
|
|
1308
|
+
const isValid = import_hash4.hash.verify(token.token_hash, inputCode);
|
|
1273
1309
|
if (isValid) {
|
|
1274
1310
|
await this.queries.deleteTwoFactorToken(token.id);
|
|
1275
1311
|
return { isValid: true, token };
|
|
@@ -1858,7 +1894,7 @@ var AuthManager = class {
|
|
|
1858
1894
|
});
|
|
1859
1895
|
}
|
|
1860
1896
|
async createRememberDirective(account) {
|
|
1861
|
-
const token =
|
|
1897
|
+
const token = import_hash5.hash.encode(account.email);
|
|
1862
1898
|
const duration = this.config.rememberDuration || "30d";
|
|
1863
1899
|
const expires = new Date(Date.now() + (0, import_ms3.default)(duration));
|
|
1864
1900
|
await this.queries.createRememberToken({
|
|
@@ -1896,7 +1932,7 @@ var AuthManager = class {
|
|
|
1896
1932
|
await this.activityLogger.logActivity(null, AuthActivityAction.FailedLogin, this.req, false, { email, reason: "account_not_found" });
|
|
1897
1933
|
throw new UserNotFoundError();
|
|
1898
1934
|
}
|
|
1899
|
-
if (!account.password || !
|
|
1935
|
+
if (!account.password || !import_hash5.hash.verify(account.password, password)) {
|
|
1900
1936
|
await this.activityLogger.logActivity(account.id, AuthActivityAction.FailedLogin, this.req, false, { email, reason: "invalid_password" });
|
|
1901
1937
|
throw new InvalidPasswordError();
|
|
1902
1938
|
}
|
|
@@ -2008,7 +2044,7 @@ var AuthManager = class {
|
|
|
2008
2044
|
throw new EmailTakenError();
|
|
2009
2045
|
}
|
|
2010
2046
|
const finalUserId = userId || this.generateAutoUserId();
|
|
2011
|
-
const hashedPassword =
|
|
2047
|
+
const hashedPassword = import_hash5.hash.encode(password);
|
|
2012
2048
|
const verified = typeof callback !== "function";
|
|
2013
2049
|
const account = await this.queries.createAccount({
|
|
2014
2050
|
userId: finalUserId,
|
|
@@ -2025,7 +2061,7 @@ var AuthManager = class {
|
|
|
2025
2061
|
return account;
|
|
2026
2062
|
}
|
|
2027
2063
|
async createConfirmationToken(account, email, callback) {
|
|
2028
|
-
const token =
|
|
2064
|
+
const token = import_hash5.hash.encode(email);
|
|
2029
2065
|
const expires = new Date(Date.now() + 1e3 * 60 * 60 * 24 * 7);
|
|
2030
2066
|
await this.queries.createConfirmation({
|
|
2031
2067
|
accountId: account.id,
|
|
@@ -2159,7 +2195,7 @@ var AuthManager = class {
|
|
|
2159
2195
|
if (new Date(confirmation.expires) < /* @__PURE__ */ new Date()) {
|
|
2160
2196
|
throw new ConfirmationExpiredError();
|
|
2161
2197
|
}
|
|
2162
|
-
if (!
|
|
2198
|
+
if (!import_hash5.hash.verify(token, confirmation.email)) {
|
|
2163
2199
|
throw new InvalidTokenError();
|
|
2164
2200
|
}
|
|
2165
2201
|
await this.queries.updateAccount(confirmation.account_id, {
|
|
@@ -2256,7 +2292,7 @@ var AuthManager = class {
|
|
|
2256
2292
|
if (openRequests >= maxRequests) {
|
|
2257
2293
|
throw new TooManyResetsError();
|
|
2258
2294
|
}
|
|
2259
|
-
const token =
|
|
2295
|
+
const token = import_hash5.hash.encode(email);
|
|
2260
2296
|
const expires = new Date(Date.now() + expiry);
|
|
2261
2297
|
await this.queries.createResetToken({
|
|
2262
2298
|
accountId: account.id,
|
|
@@ -2298,11 +2334,11 @@ var AuthManager = class {
|
|
|
2298
2334
|
throw new ResetDisabledError();
|
|
2299
2335
|
}
|
|
2300
2336
|
this.validatePassword(password);
|
|
2301
|
-
if (!
|
|
2337
|
+
if (!import_hash5.hash.verify(token, account.email)) {
|
|
2302
2338
|
throw new InvalidTokenError();
|
|
2303
2339
|
}
|
|
2304
2340
|
await this.queries.updateAccount(account.id, {
|
|
2305
|
-
password:
|
|
2341
|
+
password: import_hash5.hash.encode(password)
|
|
2306
2342
|
});
|
|
2307
2343
|
if (logout) {
|
|
2308
2344
|
await this.forceLogoutForAccountById(account.id);
|
|
@@ -2330,7 +2366,7 @@ var AuthManager = class {
|
|
|
2330
2366
|
if (!account.password) {
|
|
2331
2367
|
return false;
|
|
2332
2368
|
}
|
|
2333
|
-
return
|
|
2369
|
+
return import_hash5.hash.verify(account.password, password);
|
|
2334
2370
|
}
|
|
2335
2371
|
async forceLogoutForAccountById(accountId) {
|
|
2336
2372
|
await this.queries.deleteRememberTokensForAccount(accountId);
|
|
@@ -2624,6 +2660,7 @@ async function getAuthTableStats(config) {
|
|
|
2624
2660
|
cleanupExpiredTokens,
|
|
2625
2661
|
createAuthMiddleware,
|
|
2626
2662
|
createAuthTables,
|
|
2663
|
+
createUser,
|
|
2627
2664
|
dropAuthTables,
|
|
2628
2665
|
getAuthTableStats,
|
|
2629
2666
|
isValidEmail,
|