@eaccess/auth 0.1.1 → 0.1.3

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 CHANGED
@@ -64,82 +64,25 @@ __export(index_exports, {
64
64
  UserInactiveError: () => UserInactiveError,
65
65
  UserNotFoundError: () => UserNotFoundError,
66
66
  UserNotLoggedInError: () => UserNotLoggedInError,
67
+ addRoleToUser: () => addRoleToUser,
67
68
  cleanupExpiredTokens: () => cleanupExpiredTokens,
68
69
  createAuthMiddleware: () => createAuthMiddleware,
69
70
  createAuthTables: () => createAuthTables,
71
+ createUser: () => createUser,
70
72
  dropAuthTables: () => dropAuthTables,
71
73
  getAuthTableStats: () => getAuthTableStats,
74
+ getUserRoles: () => getUserRoles,
72
75
  isValidEmail: () => isValidEmail,
76
+ removeRoleFromUser: () => removeRoleFromUser,
77
+ setUserRoles: () => setUserRoles,
73
78
  validateEmail: () => validateEmail
74
79
  });
75
80
  module.exports = __toCommonJS(index_exports);
76
81
 
77
82
  // src/auth-admin-manager.ts
78
- var import_hash = require("@prsm/hash");
83
+ var import_hash2 = require("@prsm/hash");
79
84
  var import_ms = __toESM(require("@prsm/ms"), 1);
80
85
 
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
86
  // src/queries.ts
144
87
  var AuthQueries = class {
145
88
  constructor(config) {
@@ -516,6 +459,9 @@ var TwoFactorSetupIncompleteError = class extends AuthError {
516
459
  }
517
460
  };
518
461
 
462
+ // src/create-user.ts
463
+ var import_hash = require("@prsm/hash");
464
+
519
465
  // src/util.ts
520
466
  var isValidEmail = (email) => {
521
467
  const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
@@ -534,6 +480,123 @@ var validateEmail = (email) => {
534
480
  };
535
481
  var createMapFromEnum = (enumObj) => Object.fromEntries(Object.entries(enumObj).map(([key, value]) => [value, key]));
536
482
 
483
+ // src/types.ts
484
+ var import_express_session = require("express-session");
485
+ var TwoFactorMechanism = /* @__PURE__ */ ((TwoFactorMechanism2) => {
486
+ TwoFactorMechanism2[TwoFactorMechanism2["TOTP"] = 1] = "TOTP";
487
+ TwoFactorMechanism2[TwoFactorMechanism2["EMAIL"] = 2] = "EMAIL";
488
+ TwoFactorMechanism2[TwoFactorMechanism2["SMS"] = 3] = "SMS";
489
+ return TwoFactorMechanism2;
490
+ })(TwoFactorMechanism || {});
491
+ var AuthStatus = {
492
+ Normal: 0,
493
+ Archived: 1,
494
+ Banned: 2,
495
+ Locked: 3,
496
+ PendingReview: 4,
497
+ Suspended: 5
498
+ };
499
+ var AuthRole = {
500
+ Admin: 1,
501
+ Author: 2,
502
+ Collaborator: 4,
503
+ Consultant: 8,
504
+ Consumer: 16,
505
+ Contributor: 32,
506
+ Coordinator: 64,
507
+ Creator: 128,
508
+ Developer: 256,
509
+ Director: 512,
510
+ Editor: 1024,
511
+ Employee: 2048,
512
+ Maintainer: 4096,
513
+ Manager: 8192,
514
+ Moderator: 16384,
515
+ Publisher: 32768,
516
+ Reviewer: 65536,
517
+ Subscriber: 131072,
518
+ SuperAdmin: 262144,
519
+ SuperEditor: 524288,
520
+ SuperModerator: 1048576,
521
+ Translator: 2097152
522
+ };
523
+ var AuthActivityAction = {
524
+ Login: "login",
525
+ Logout: "logout",
526
+ FailedLogin: "failed_login",
527
+ Register: "register",
528
+ EmailConfirmed: "email_confirmed",
529
+ PasswordResetRequested: "password_reset_requested",
530
+ PasswordResetCompleted: "password_reset_completed",
531
+ PasswordChanged: "password_changed",
532
+ EmailChanged: "email_changed",
533
+ RoleChanged: "role_changed",
534
+ StatusChanged: "status_changed",
535
+ ForceLogout: "force_logout",
536
+ OAuthConnected: "oauth_connected",
537
+ RememberTokenCreated: "remember_token_created",
538
+ TwoFactorSetup: "two_factor_setup",
539
+ TwoFactorVerified: "two_factor_verified",
540
+ TwoFactorFailed: "two_factor_failed",
541
+ TwoFactorDisabled: "two_factor_disabled",
542
+ BackupCodeUsed: "backup_code_used"
543
+ };
544
+
545
+ // src/create-user.ts
546
+ function validatePassword(password, config) {
547
+ const minLength = config.minPasswordLength || 8;
548
+ const maxLength = config.maxPasswordLength || 64;
549
+ if (typeof password !== "string") {
550
+ throw new InvalidPasswordError();
551
+ }
552
+ if (password.length < minLength) {
553
+ throw new InvalidPasswordError();
554
+ }
555
+ if (password.length > maxLength) {
556
+ throw new InvalidPasswordError();
557
+ }
558
+ }
559
+ function generateAutoUserId() {
560
+ return crypto.randomUUID();
561
+ }
562
+ async function createConfirmationToken(queries, account, email, callback) {
563
+ const token = import_hash.hash.encode(email);
564
+ const expires = new Date(Date.now() + 1e3 * 60 * 60 * 24 * 7);
565
+ await queries.createConfirmation({
566
+ accountId: account.id,
567
+ token,
568
+ email,
569
+ expires
570
+ });
571
+ if (callback) {
572
+ callback(token);
573
+ }
574
+ }
575
+ async function createUser(config, credentials, userId, callback) {
576
+ validateEmail(credentials.email);
577
+ validatePassword(credentials.password, config);
578
+ const queries = new AuthQueries(config);
579
+ const existing = await queries.findAccountByEmail(credentials.email);
580
+ if (existing) {
581
+ throw new EmailTakenError();
582
+ }
583
+ const finalUserId = userId || generateAutoUserId();
584
+ const hashedPassword = import_hash.hash.encode(credentials.password);
585
+ const verified = typeof callback !== "function";
586
+ const account = await queries.createAccount({
587
+ userId: finalUserId,
588
+ email: credentials.email,
589
+ password: hashedPassword,
590
+ verified,
591
+ status: AuthStatus.Normal,
592
+ rolemask: 0
593
+ });
594
+ if (!verified && callback) {
595
+ await createConfirmationToken(queries, account, credentials.email, callback);
596
+ }
597
+ return account;
598
+ }
599
+
537
600
  // src/auth-admin-manager.ts
538
601
  var AuthAdminManager = class {
539
602
  constructor(req, res, config, auth) {
@@ -556,9 +619,6 @@ var AuthAdminManager = class {
556
619
  throw new InvalidPasswordError();
557
620
  }
558
621
  }
559
- generateAutoUserId() {
560
- return crypto.randomUUID();
561
- }
562
622
  async findAccountByIdentifier(identifier) {
563
623
  if (identifier.accountId !== void 0) {
564
624
  return await this.queries.findAccountById(identifier.accountId);
@@ -570,7 +630,7 @@ var AuthAdminManager = class {
570
630
  return null;
571
631
  }
572
632
  async createConfirmationToken(account, email, callback) {
573
- const token = import_hash.hash.encode(email);
633
+ const token = import_hash2.hash.encode(email);
574
634
  const expires = new Date(Date.now() + 1e3 * 60 * 60 * 24 * 7);
575
635
  await this.queries.createConfirmation({
576
636
  accountId: account.id,
@@ -593,27 +653,7 @@ var AuthAdminManager = class {
593
653
  * @throws {InvalidPasswordError} Password doesn't meet length requirements
594
654
  */
595
655
  async createUser(credentials, userId, callback) {
596
- validateEmail(credentials.email);
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;
656
+ return createUser(this.config, credentials, userId, callback);
617
657
  }
618
658
  /**
619
659
  * Log in as another user (admin function).
@@ -706,7 +746,7 @@ var AuthAdminManager = class {
706
746
  throw new UserNotFoundError();
707
747
  }
708
748
  await this.queries.updateAccount(account.id, {
709
- password: import_hash.hash.encode(password)
749
+ password: import_hash2.hash.encode(password)
710
750
  });
711
751
  }
712
752
  /**
@@ -742,7 +782,7 @@ var AuthAdminManager = class {
742
782
  throw new EmailNotVerifiedError();
743
783
  }
744
784
  const expiry = !expiresAfter ? (0, import_ms.default)("6h") : (0, import_ms.default)(expiresAfter);
745
- const token = import_hash.hash.encode(account.email);
785
+ const token = import_hash2.hash.encode(account.email);
746
786
  const expires = new Date(Date.now() + expiry);
747
787
  await this.queries.createResetToken({
748
788
  accountId: account.id,
@@ -774,7 +814,7 @@ var AuthAdminManager = class {
774
814
  };
775
815
 
776
816
  // src/auth-manager.ts
777
- var import_hash4 = require("@prsm/hash");
817
+ var import_hash5 = require("@prsm/hash");
778
818
  var import_ms3 = __toESM(require("@prsm/ms"), 1);
779
819
 
780
820
  // src/activity-logger.ts
@@ -1172,7 +1212,7 @@ var AzureProvider = class extends BaseOAuthProvider {
1172
1212
 
1173
1213
  // src/two-factor/totp-provider.ts
1174
1214
  var import_totp = __toESM(require("@eaccess/totp"), 1);
1175
- var import_hash2 = require("@prsm/hash");
1215
+ var import_hash3 = require("@prsm/hash");
1176
1216
  var TotpProvider = class {
1177
1217
  constructor(config) {
1178
1218
  this.config = config;
@@ -1201,11 +1241,11 @@ var TotpProvider = class {
1201
1241
  return codes;
1202
1242
  }
1203
1243
  hashBackupCodes(codes) {
1204
- return codes.map((code) => import_hash2.hash.encode(code));
1244
+ return codes.map((code) => import_hash3.hash.encode(code));
1205
1245
  }
1206
1246
  verifyBackupCode(hashedCodes, inputCode) {
1207
1247
  for (let i = 0; i < hashedCodes.length; i++) {
1208
- if (import_hash2.hash.verify(hashedCodes[i], inputCode.toUpperCase())) {
1248
+ if (import_hash3.hash.verify(hashedCodes[i], inputCode.toUpperCase())) {
1209
1249
  return { isValid: true, index: i };
1210
1250
  }
1211
1251
  }
@@ -1222,7 +1262,7 @@ var TotpProvider = class {
1222
1262
 
1223
1263
  // src/two-factor/otp-provider.ts
1224
1264
  var import_ms2 = __toESM(require("@prsm/ms"), 1);
1225
- var import_hash3 = require("@prsm/hash");
1265
+ var import_hash4 = require("@prsm/hash");
1226
1266
  var OtpProvider = class {
1227
1267
  constructor(config) {
1228
1268
  this.config = config;
@@ -1247,7 +1287,7 @@ var OtpProvider = class {
1247
1287
  async createAndStoreOTP(accountId, mechanism) {
1248
1288
  const otp = this.generateOTP();
1249
1289
  const selector = this.generateSelector();
1250
- const tokenHash = import_hash3.hash.encode(otp);
1290
+ const tokenHash = import_hash4.hash.encode(otp);
1251
1291
  const expiryDuration = this.config.twoFactor?.tokenExpiry || "5m";
1252
1292
  const expiresAt = new Date(Date.now() + (0, import_ms2.default)(expiryDuration));
1253
1293
  await this.queries.deleteTwoFactorTokensByAccountAndMechanism(accountId, mechanism);
@@ -1269,7 +1309,7 @@ var OtpProvider = class {
1269
1309
  await this.queries.deleteTwoFactorToken(token.id);
1270
1310
  return { isValid: false };
1271
1311
  }
1272
- const isValid = import_hash3.hash.verify(token.token_hash, inputCode);
1312
+ const isValid = import_hash4.hash.verify(token.token_hash, inputCode);
1273
1313
  if (isValid) {
1274
1314
  await this.queries.deleteTwoFactorToken(token.id);
1275
1315
  return { isValid: true, token };
@@ -1858,7 +1898,7 @@ var AuthManager = class {
1858
1898
  });
1859
1899
  }
1860
1900
  async createRememberDirective(account) {
1861
- const token = import_hash4.hash.encode(account.email);
1901
+ const token = import_hash5.hash.encode(account.email);
1862
1902
  const duration = this.config.rememberDuration || "30d";
1863
1903
  const expires = new Date(Date.now() + (0, import_ms3.default)(duration));
1864
1904
  await this.queries.createRememberToken({
@@ -1896,7 +1936,7 @@ var AuthManager = class {
1896
1936
  await this.activityLogger.logActivity(null, AuthActivityAction.FailedLogin, this.req, false, { email, reason: "account_not_found" });
1897
1937
  throw new UserNotFoundError();
1898
1938
  }
1899
- if (!account.password || !import_hash4.hash.verify(account.password, password)) {
1939
+ if (!account.password || !import_hash5.hash.verify(account.password, password)) {
1900
1940
  await this.activityLogger.logActivity(account.id, AuthActivityAction.FailedLogin, this.req, false, { email, reason: "invalid_password" });
1901
1941
  throw new InvalidPasswordError();
1902
1942
  }
@@ -2008,7 +2048,7 @@ var AuthManager = class {
2008
2048
  throw new EmailTakenError();
2009
2049
  }
2010
2050
  const finalUserId = userId || this.generateAutoUserId();
2011
- const hashedPassword = import_hash4.hash.encode(password);
2051
+ const hashedPassword = import_hash5.hash.encode(password);
2012
2052
  const verified = typeof callback !== "function";
2013
2053
  const account = await this.queries.createAccount({
2014
2054
  userId: finalUserId,
@@ -2025,7 +2065,7 @@ var AuthManager = class {
2025
2065
  return account;
2026
2066
  }
2027
2067
  async createConfirmationToken(account, email, callback) {
2028
- const token = import_hash4.hash.encode(email);
2068
+ const token = import_hash5.hash.encode(email);
2029
2069
  const expires = new Date(Date.now() + 1e3 * 60 * 60 * 24 * 7);
2030
2070
  await this.queries.createConfirmation({
2031
2071
  accountId: account.id,
@@ -2159,7 +2199,7 @@ var AuthManager = class {
2159
2199
  if (new Date(confirmation.expires) < /* @__PURE__ */ new Date()) {
2160
2200
  throw new ConfirmationExpiredError();
2161
2201
  }
2162
- if (!import_hash4.hash.verify(token, confirmation.email)) {
2202
+ if (!import_hash5.hash.verify(token, confirmation.email)) {
2163
2203
  throw new InvalidTokenError();
2164
2204
  }
2165
2205
  await this.queries.updateAccount(confirmation.account_id, {
@@ -2256,7 +2296,7 @@ var AuthManager = class {
2256
2296
  if (openRequests >= maxRequests) {
2257
2297
  throw new TooManyResetsError();
2258
2298
  }
2259
- const token = import_hash4.hash.encode(email);
2299
+ const token = import_hash5.hash.encode(email);
2260
2300
  const expires = new Date(Date.now() + expiry);
2261
2301
  await this.queries.createResetToken({
2262
2302
  accountId: account.id,
@@ -2298,11 +2338,11 @@ var AuthManager = class {
2298
2338
  throw new ResetDisabledError();
2299
2339
  }
2300
2340
  this.validatePassword(password);
2301
- if (!import_hash4.hash.verify(token, account.email)) {
2341
+ if (!import_hash5.hash.verify(token, account.email)) {
2302
2342
  throw new InvalidTokenError();
2303
2343
  }
2304
2344
  await this.queries.updateAccount(account.id, {
2305
- password: import_hash4.hash.encode(password)
2345
+ password: import_hash5.hash.encode(password)
2306
2346
  });
2307
2347
  if (logout) {
2308
2348
  await this.forceLogoutForAccountById(account.id);
@@ -2330,7 +2370,7 @@ var AuthManager = class {
2330
2370
  if (!account.password) {
2331
2371
  return false;
2332
2372
  }
2333
- return import_hash4.hash.verify(account.password, password);
2373
+ return import_hash5.hash.verify(account.password, password);
2334
2374
  }
2335
2375
  async forceLogoutForAccountById(accountId) {
2336
2376
  await this.queries.deleteRememberTokensForAccount(accountId);
@@ -2585,6 +2625,44 @@ async function getAuthTableStats(config) {
2585
2625
  expiredTwoFactorTokens: parseInt(expiredTwoFactorTokensResult.rows[0]?.count || "0")
2586
2626
  };
2587
2627
  }
2628
+
2629
+ // src/user-roles.ts
2630
+ async function findAccountByIdentifier(queries, identifier) {
2631
+ let account = null;
2632
+ if (identifier.accountId !== void 0) {
2633
+ account = await queries.findAccountById(identifier.accountId);
2634
+ } else if (identifier.email !== void 0) {
2635
+ account = await queries.findAccountByEmail(identifier.email);
2636
+ } else if (identifier.userId !== void 0) {
2637
+ account = await queries.findAccountByUserId(identifier.userId);
2638
+ }
2639
+ if (!account) {
2640
+ throw new UserNotFoundError();
2641
+ }
2642
+ return account;
2643
+ }
2644
+ async function addRoleToUser(config, identifier, role) {
2645
+ const queries = new AuthQueries(config);
2646
+ const account = await findAccountByIdentifier(queries, identifier);
2647
+ const rolemask = account.rolemask | role;
2648
+ await queries.updateAccount(account.id, { rolemask });
2649
+ }
2650
+ async function removeRoleFromUser(config, identifier, role) {
2651
+ const queries = new AuthQueries(config);
2652
+ const account = await findAccountByIdentifier(queries, identifier);
2653
+ const rolemask = account.rolemask & ~role;
2654
+ await queries.updateAccount(account.id, { rolemask });
2655
+ }
2656
+ async function setUserRoles(config, identifier, rolemask) {
2657
+ const queries = new AuthQueries(config);
2658
+ const account = await findAccountByIdentifier(queries, identifier);
2659
+ await queries.updateAccount(account.id, { rolemask });
2660
+ }
2661
+ async function getUserRoles(config, identifier) {
2662
+ const queries = new AuthQueries(config);
2663
+ const account = await findAccountByIdentifier(queries, identifier);
2664
+ return account.rolemask;
2665
+ }
2588
2666
  // Annotate the CommonJS export names for ESM import in node:
2589
2667
  0 && (module.exports = {
2590
2668
  ActivityLogger,
@@ -2621,12 +2699,17 @@ async function getAuthTableStats(config) {
2621
2699
  UserInactiveError,
2622
2700
  UserNotFoundError,
2623
2701
  UserNotLoggedInError,
2702
+ addRoleToUser,
2624
2703
  cleanupExpiredTokens,
2625
2704
  createAuthMiddleware,
2626
2705
  createAuthTables,
2706
+ createUser,
2627
2707
  dropAuthTables,
2628
2708
  getAuthTableStats,
2709
+ getUserRoles,
2629
2710
  isValidEmail,
2711
+ removeRoleFromUser,
2712
+ setUserRoles,
2630
2713
  validateEmail
2631
2714
  });
2632
2715
  //# sourceMappingURL=index.cjs.map