@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.d.cts CHANGED
@@ -15,6 +15,24 @@ interface AzureProviderConfig extends OAuthProviderConfig {
15
15
  }
16
16
  interface AuthConfig {
17
17
  db: Pool;
18
+ /**
19
+ * If a user logs in with an OAuth provider, but a matching account (identified by the OAuth user's email address) doesn't
20
+ * exist, createUser will be called:
21
+ *
22
+ * @example:
23
+ *
24
+ * if (this.authConfig.createUser) {
25
+ * userId = await this.authConfig.createUser(userData);
26
+ * } else {
27
+ * // Generate UUID for OAuth users when no createUser function is provided
28
+ * userId = crypto.randomUUID();
29
+ * }
30
+ *
31
+ * This callback is your opportunity to create a user account in *your* database, and return
32
+ * the user ID of the newly-created user for this provider account to be linked to.
33
+ * @param userData
34
+ * @returns
35
+ */
18
36
  createUser?: (userData: OAuthUserData) => string | number | Promise<string | number>;
19
37
  tablePrefix?: string;
20
38
  minPasswordLength?: number;
@@ -513,6 +531,67 @@ declare function getAuthTableStats(config: AuthConfig): Promise<{
513
531
  expiredTwoFactorTokens: number;
514
532
  }>;
515
533
 
534
+ /**
535
+ * Create a new user account without requiring Express request/response objects.
536
+ * This function is suitable for use in seeders, CLI tools, and other standalone contexts.
537
+ *
538
+ * @param config - Auth configuration containing database connection and settings
539
+ * @param credentials - Email and password for new account
540
+ * @param userId - Optional user ID to link this auth account to. If not provided, a UUID will be generated automatically.
541
+ * @param callback - If provided, account is created unverified and callback receives confirmation token. Create a URL like /confirm/{token} and call confirmEmail() in that handler. If omitted, account is immediately verified.
542
+ * @returns The created account record
543
+ * @throws {EmailTakenError} Email is already registered
544
+ * @throws {InvalidPasswordError} Password doesn't meet length requirements
545
+ */
546
+ declare function createUser(config: AuthConfig, credentials: {
547
+ email: string;
548
+ password: string;
549
+ }, userId?: string | number, callback?: TokenCallback): Promise<AuthAccount>;
550
+
551
+ type UserIdentifier = {
552
+ accountId?: number;
553
+ email?: string;
554
+ userId?: string;
555
+ };
556
+ /**
557
+ * Add a role to a user's account.
558
+ * Uses bitwise OR to add role to existing rolemask.
559
+ *
560
+ * @param config - Auth configuration containing database connection
561
+ * @param identifier - Find user by accountId, email, or userId
562
+ * @param role - Role bitmask to add (e.g., AuthRole.Admin)
563
+ * @throws {UserNotFoundError} No account matches the identifier
564
+ */
565
+ declare function addRoleToUser(config: AuthConfig, identifier: UserIdentifier, role: number): Promise<void>;
566
+ /**
567
+ * Remove a role from a user's account.
568
+ * Uses bitwise operations to remove role from rolemask.
569
+ *
570
+ * @param config - Auth configuration containing database connection
571
+ * @param identifier - Find user by accountId, email, or userId
572
+ * @param role - Role bitmask to remove (e.g., AuthRole.Admin)
573
+ * @throws {UserNotFoundError} No account matches the identifier
574
+ */
575
+ declare function removeRoleFromUser(config: AuthConfig, identifier: UserIdentifier, role: number): Promise<void>;
576
+ /**
577
+ * Set a user's complete role mask, replacing any existing roles.
578
+ *
579
+ * @param config - Auth configuration containing database connection
580
+ * @param identifier - Find user by accountId, email, or userId
581
+ * @param rolemask - Complete role bitmask to set
582
+ * @throws {UserNotFoundError} No account matches the identifier
583
+ */
584
+ declare function setUserRoles(config: AuthConfig, identifier: UserIdentifier, rolemask: number): Promise<void>;
585
+ /**
586
+ * Get a user's current role mask.
587
+ *
588
+ * @param config - Auth configuration containing database connection
589
+ * @param identifier - Find user by accountId, email, or userId
590
+ * @returns The user's current role bitmask
591
+ * @throws {UserNotFoundError} No account matches the identifier
592
+ */
593
+ declare function getUserRoles(config: AuthConfig, identifier: UserIdentifier): Promise<number>;
594
+
516
595
  declare class AuthError extends Error {
517
596
  constructor(message: string);
518
597
  }
@@ -927,4 +1006,4 @@ declare class AzureProvider extends BaseOAuthProvider {
927
1006
  protected exchangeCodeForToken(code: string, tokenUrl: string): Promise<string>;
928
1007
  }
929
1008
 
930
- export { ActivityLogger, type AuthAccount, type AuthActivity, AuthActivityAction, type AuthActivityActionType, type AuthAdminManager, type AuthConfig, type AuthConfirmation, AuthError, type AuthManager$1 as AuthManager, type AuthProvider, type AuthRemember, type AuthReset, AuthRole, type AuthSession, AuthStatus, AzureProvider, type AzureProviderConfig, BaseOAuthProvider, ConfirmationExpiredError, ConfirmationNotFoundError, EmailNotVerifiedError, EmailTakenError, GitHubProvider, type GitHubProviderConfig, GoogleProvider, type GoogleProviderConfig, InvalidBackupCodeError, InvalidEmailError, InvalidPasswordError, InvalidTokenError, InvalidTwoFactorCodeError, type OAuthProvider, type OAuthProviderConfig, type OAuthUserData, OtpProvider, ResetDisabledError, ResetExpiredError, ResetNotFoundError, SecondFactorRequiredError, type TokenCallback, TooManyResetsError, TotpProvider, TwoFactorAlreadyEnabledError, type TwoFactorChallenge, TwoFactorExpiredError, TwoFactorManager, TwoFactorMechanism, type TwoFactorMethod, TwoFactorNotSetupError, TwoFactorSetupIncompleteError, type TwoFactorSetupResult, type TwoFactorToken, UserInactiveError, UserNotFoundError, UserNotLoggedInError, cleanupExpiredTokens, createAuthMiddleware, createAuthTables, dropAuthTables, getAuthTableStats, isValidEmail, validateEmail };
1009
+ export { ActivityLogger, type AuthAccount, type AuthActivity, AuthActivityAction, type AuthActivityActionType, type AuthAdminManager, type AuthConfig, type AuthConfirmation, AuthError, type AuthManager$1 as AuthManager, type AuthProvider, type AuthRemember, type AuthReset, AuthRole, type AuthSession, AuthStatus, AzureProvider, type AzureProviderConfig, BaseOAuthProvider, ConfirmationExpiredError, ConfirmationNotFoundError, EmailNotVerifiedError, EmailTakenError, GitHubProvider, type GitHubProviderConfig, GoogleProvider, type GoogleProviderConfig, InvalidBackupCodeError, InvalidEmailError, InvalidPasswordError, InvalidTokenError, InvalidTwoFactorCodeError, type OAuthProvider, type OAuthProviderConfig, type OAuthUserData, OtpProvider, ResetDisabledError, ResetExpiredError, ResetNotFoundError, SecondFactorRequiredError, type TokenCallback, TooManyResetsError, TotpProvider, TwoFactorAlreadyEnabledError, type TwoFactorChallenge, TwoFactorExpiredError, TwoFactorManager, TwoFactorMechanism, type TwoFactorMethod, TwoFactorNotSetupError, TwoFactorSetupIncompleteError, type TwoFactorSetupResult, type TwoFactorToken, type UserIdentifier, UserInactiveError, UserNotFoundError, UserNotLoggedInError, addRoleToUser, cleanupExpiredTokens, createAuthMiddleware, createAuthTables, createUser, dropAuthTables, getAuthTableStats, getUserRoles, isValidEmail, removeRoleFromUser, setUserRoles, validateEmail };
package/dist/index.d.ts CHANGED
@@ -15,6 +15,24 @@ interface AzureProviderConfig extends OAuthProviderConfig {
15
15
  }
16
16
  interface AuthConfig {
17
17
  db: Pool;
18
+ /**
19
+ * If a user logs in with an OAuth provider, but a matching account (identified by the OAuth user's email address) doesn't
20
+ * exist, createUser will be called:
21
+ *
22
+ * @example:
23
+ *
24
+ * if (this.authConfig.createUser) {
25
+ * userId = await this.authConfig.createUser(userData);
26
+ * } else {
27
+ * // Generate UUID for OAuth users when no createUser function is provided
28
+ * userId = crypto.randomUUID();
29
+ * }
30
+ *
31
+ * This callback is your opportunity to create a user account in *your* database, and return
32
+ * the user ID of the newly-created user for this provider account to be linked to.
33
+ * @param userData
34
+ * @returns
35
+ */
18
36
  createUser?: (userData: OAuthUserData) => string | number | Promise<string | number>;
19
37
  tablePrefix?: string;
20
38
  minPasswordLength?: number;
@@ -513,6 +531,67 @@ declare function getAuthTableStats(config: AuthConfig): Promise<{
513
531
  expiredTwoFactorTokens: number;
514
532
  }>;
515
533
 
534
+ /**
535
+ * Create a new user account without requiring Express request/response objects.
536
+ * This function is suitable for use in seeders, CLI tools, and other standalone contexts.
537
+ *
538
+ * @param config - Auth configuration containing database connection and settings
539
+ * @param credentials - Email and password for new account
540
+ * @param userId - Optional user ID to link this auth account to. If not provided, a UUID will be generated automatically.
541
+ * @param callback - If provided, account is created unverified and callback receives confirmation token. Create a URL like /confirm/{token} and call confirmEmail() in that handler. If omitted, account is immediately verified.
542
+ * @returns The created account record
543
+ * @throws {EmailTakenError} Email is already registered
544
+ * @throws {InvalidPasswordError} Password doesn't meet length requirements
545
+ */
546
+ declare function createUser(config: AuthConfig, credentials: {
547
+ email: string;
548
+ password: string;
549
+ }, userId?: string | number, callback?: TokenCallback): Promise<AuthAccount>;
550
+
551
+ type UserIdentifier = {
552
+ accountId?: number;
553
+ email?: string;
554
+ userId?: string;
555
+ };
556
+ /**
557
+ * Add a role to a user's account.
558
+ * Uses bitwise OR to add role to existing rolemask.
559
+ *
560
+ * @param config - Auth configuration containing database connection
561
+ * @param identifier - Find user by accountId, email, or userId
562
+ * @param role - Role bitmask to add (e.g., AuthRole.Admin)
563
+ * @throws {UserNotFoundError} No account matches the identifier
564
+ */
565
+ declare function addRoleToUser(config: AuthConfig, identifier: UserIdentifier, role: number): Promise<void>;
566
+ /**
567
+ * Remove a role from a user's account.
568
+ * Uses bitwise operations to remove role from rolemask.
569
+ *
570
+ * @param config - Auth configuration containing database connection
571
+ * @param identifier - Find user by accountId, email, or userId
572
+ * @param role - Role bitmask to remove (e.g., AuthRole.Admin)
573
+ * @throws {UserNotFoundError} No account matches the identifier
574
+ */
575
+ declare function removeRoleFromUser(config: AuthConfig, identifier: UserIdentifier, role: number): Promise<void>;
576
+ /**
577
+ * Set a user's complete role mask, replacing any existing roles.
578
+ *
579
+ * @param config - Auth configuration containing database connection
580
+ * @param identifier - Find user by accountId, email, or userId
581
+ * @param rolemask - Complete role bitmask to set
582
+ * @throws {UserNotFoundError} No account matches the identifier
583
+ */
584
+ declare function setUserRoles(config: AuthConfig, identifier: UserIdentifier, rolemask: number): Promise<void>;
585
+ /**
586
+ * Get a user's current role mask.
587
+ *
588
+ * @param config - Auth configuration containing database connection
589
+ * @param identifier - Find user by accountId, email, or userId
590
+ * @returns The user's current role bitmask
591
+ * @throws {UserNotFoundError} No account matches the identifier
592
+ */
593
+ declare function getUserRoles(config: AuthConfig, identifier: UserIdentifier): Promise<number>;
594
+
516
595
  declare class AuthError extends Error {
517
596
  constructor(message: string);
518
597
  }
@@ -927,4 +1006,4 @@ declare class AzureProvider extends BaseOAuthProvider {
927
1006
  protected exchangeCodeForToken(code: string, tokenUrl: string): Promise<string>;
928
1007
  }
929
1008
 
930
- export { ActivityLogger, type AuthAccount, type AuthActivity, AuthActivityAction, type AuthActivityActionType, type AuthAdminManager, type AuthConfig, type AuthConfirmation, AuthError, type AuthManager$1 as AuthManager, type AuthProvider, type AuthRemember, type AuthReset, AuthRole, type AuthSession, AuthStatus, AzureProvider, type AzureProviderConfig, BaseOAuthProvider, ConfirmationExpiredError, ConfirmationNotFoundError, EmailNotVerifiedError, EmailTakenError, GitHubProvider, type GitHubProviderConfig, GoogleProvider, type GoogleProviderConfig, InvalidBackupCodeError, InvalidEmailError, InvalidPasswordError, InvalidTokenError, InvalidTwoFactorCodeError, type OAuthProvider, type OAuthProviderConfig, type OAuthUserData, OtpProvider, ResetDisabledError, ResetExpiredError, ResetNotFoundError, SecondFactorRequiredError, type TokenCallback, TooManyResetsError, TotpProvider, TwoFactorAlreadyEnabledError, type TwoFactorChallenge, TwoFactorExpiredError, TwoFactorManager, TwoFactorMechanism, type TwoFactorMethod, TwoFactorNotSetupError, TwoFactorSetupIncompleteError, type TwoFactorSetupResult, type TwoFactorToken, UserInactiveError, UserNotFoundError, UserNotLoggedInError, cleanupExpiredTokens, createAuthMiddleware, createAuthTables, dropAuthTables, getAuthTableStats, isValidEmail, validateEmail };
1009
+ export { ActivityLogger, type AuthAccount, type AuthActivity, AuthActivityAction, type AuthActivityActionType, type AuthAdminManager, type AuthConfig, type AuthConfirmation, AuthError, type AuthManager$1 as AuthManager, type AuthProvider, type AuthRemember, type AuthReset, AuthRole, type AuthSession, AuthStatus, AzureProvider, type AzureProviderConfig, BaseOAuthProvider, ConfirmationExpiredError, ConfirmationNotFoundError, EmailNotVerifiedError, EmailTakenError, GitHubProvider, type GitHubProviderConfig, GoogleProvider, type GoogleProviderConfig, InvalidBackupCodeError, InvalidEmailError, InvalidPasswordError, InvalidTokenError, InvalidTwoFactorCodeError, type OAuthProvider, type OAuthProviderConfig, type OAuthUserData, OtpProvider, ResetDisabledError, ResetExpiredError, ResetNotFoundError, SecondFactorRequiredError, type TokenCallback, TooManyResetsError, TotpProvider, TwoFactorAlreadyEnabledError, type TwoFactorChallenge, TwoFactorExpiredError, TwoFactorManager, TwoFactorMechanism, type TwoFactorMethod, TwoFactorNotSetupError, TwoFactorSetupIncompleteError, type TwoFactorSetupResult, type TwoFactorToken, type UserIdentifier, UserInactiveError, UserNotFoundError, UserNotLoggedInError, addRoleToUser, cleanupExpiredTokens, createAuthMiddleware, createAuthTables, createUser, dropAuthTables, getAuthTableStats, getUserRoles, isValidEmail, removeRoleFromUser, setUserRoles, validateEmail };
package/dist/index.js CHANGED
@@ -1,69 +1,7 @@
1
1
  // src/auth-admin-manager.ts
2
- import { hash } from "@prsm/hash";
2
+ import { hash as hash2 } from "@prsm/hash";
3
3
  import ms from "@prsm/ms";
4
4
 
5
- // src/types.ts
6
- import "express-session";
7
- var TwoFactorMechanism = /* @__PURE__ */ ((TwoFactorMechanism2) => {
8
- TwoFactorMechanism2[TwoFactorMechanism2["TOTP"] = 1] = "TOTP";
9
- TwoFactorMechanism2[TwoFactorMechanism2["EMAIL"] = 2] = "EMAIL";
10
- TwoFactorMechanism2[TwoFactorMechanism2["SMS"] = 3] = "SMS";
11
- return TwoFactorMechanism2;
12
- })(TwoFactorMechanism || {});
13
- var AuthStatus = {
14
- Normal: 0,
15
- Archived: 1,
16
- Banned: 2,
17
- Locked: 3,
18
- PendingReview: 4,
19
- Suspended: 5
20
- };
21
- var AuthRole = {
22
- Admin: 1,
23
- Author: 2,
24
- Collaborator: 4,
25
- Consultant: 8,
26
- Consumer: 16,
27
- Contributor: 32,
28
- Coordinator: 64,
29
- Creator: 128,
30
- Developer: 256,
31
- Director: 512,
32
- Editor: 1024,
33
- Employee: 2048,
34
- Maintainer: 4096,
35
- Manager: 8192,
36
- Moderator: 16384,
37
- Publisher: 32768,
38
- Reviewer: 65536,
39
- Subscriber: 131072,
40
- SuperAdmin: 262144,
41
- SuperEditor: 524288,
42
- SuperModerator: 1048576,
43
- Translator: 2097152
44
- };
45
- var AuthActivityAction = {
46
- Login: "login",
47
- Logout: "logout",
48
- FailedLogin: "failed_login",
49
- Register: "register",
50
- EmailConfirmed: "email_confirmed",
51
- PasswordResetRequested: "password_reset_requested",
52
- PasswordResetCompleted: "password_reset_completed",
53
- PasswordChanged: "password_changed",
54
- EmailChanged: "email_changed",
55
- RoleChanged: "role_changed",
56
- StatusChanged: "status_changed",
57
- ForceLogout: "force_logout",
58
- OAuthConnected: "oauth_connected",
59
- RememberTokenCreated: "remember_token_created",
60
- TwoFactorSetup: "two_factor_setup",
61
- TwoFactorVerified: "two_factor_verified",
62
- TwoFactorFailed: "two_factor_failed",
63
- TwoFactorDisabled: "two_factor_disabled",
64
- BackupCodeUsed: "backup_code_used"
65
- };
66
-
67
5
  // src/queries.ts
68
6
  var AuthQueries = class {
69
7
  constructor(config) {
@@ -440,6 +378,9 @@ var TwoFactorSetupIncompleteError = class extends AuthError {
440
378
  }
441
379
  };
442
380
 
381
+ // src/create-user.ts
382
+ import { hash } from "@prsm/hash";
383
+
443
384
  // src/util.ts
444
385
  var isValidEmail = (email) => {
445
386
  const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
@@ -458,6 +399,123 @@ var validateEmail = (email) => {
458
399
  };
459
400
  var createMapFromEnum = (enumObj) => Object.fromEntries(Object.entries(enumObj).map(([key, value]) => [value, key]));
460
401
 
402
+ // src/types.ts
403
+ import "express-session";
404
+ var TwoFactorMechanism = /* @__PURE__ */ ((TwoFactorMechanism2) => {
405
+ TwoFactorMechanism2[TwoFactorMechanism2["TOTP"] = 1] = "TOTP";
406
+ TwoFactorMechanism2[TwoFactorMechanism2["EMAIL"] = 2] = "EMAIL";
407
+ TwoFactorMechanism2[TwoFactorMechanism2["SMS"] = 3] = "SMS";
408
+ return TwoFactorMechanism2;
409
+ })(TwoFactorMechanism || {});
410
+ var AuthStatus = {
411
+ Normal: 0,
412
+ Archived: 1,
413
+ Banned: 2,
414
+ Locked: 3,
415
+ PendingReview: 4,
416
+ Suspended: 5
417
+ };
418
+ var AuthRole = {
419
+ Admin: 1,
420
+ Author: 2,
421
+ Collaborator: 4,
422
+ Consultant: 8,
423
+ Consumer: 16,
424
+ Contributor: 32,
425
+ Coordinator: 64,
426
+ Creator: 128,
427
+ Developer: 256,
428
+ Director: 512,
429
+ Editor: 1024,
430
+ Employee: 2048,
431
+ Maintainer: 4096,
432
+ Manager: 8192,
433
+ Moderator: 16384,
434
+ Publisher: 32768,
435
+ Reviewer: 65536,
436
+ Subscriber: 131072,
437
+ SuperAdmin: 262144,
438
+ SuperEditor: 524288,
439
+ SuperModerator: 1048576,
440
+ Translator: 2097152
441
+ };
442
+ var AuthActivityAction = {
443
+ Login: "login",
444
+ Logout: "logout",
445
+ FailedLogin: "failed_login",
446
+ Register: "register",
447
+ EmailConfirmed: "email_confirmed",
448
+ PasswordResetRequested: "password_reset_requested",
449
+ PasswordResetCompleted: "password_reset_completed",
450
+ PasswordChanged: "password_changed",
451
+ EmailChanged: "email_changed",
452
+ RoleChanged: "role_changed",
453
+ StatusChanged: "status_changed",
454
+ ForceLogout: "force_logout",
455
+ OAuthConnected: "oauth_connected",
456
+ RememberTokenCreated: "remember_token_created",
457
+ TwoFactorSetup: "two_factor_setup",
458
+ TwoFactorVerified: "two_factor_verified",
459
+ TwoFactorFailed: "two_factor_failed",
460
+ TwoFactorDisabled: "two_factor_disabled",
461
+ BackupCodeUsed: "backup_code_used"
462
+ };
463
+
464
+ // src/create-user.ts
465
+ function validatePassword(password, config) {
466
+ const minLength = config.minPasswordLength || 8;
467
+ const maxLength = config.maxPasswordLength || 64;
468
+ if (typeof password !== "string") {
469
+ throw new InvalidPasswordError();
470
+ }
471
+ if (password.length < minLength) {
472
+ throw new InvalidPasswordError();
473
+ }
474
+ if (password.length > maxLength) {
475
+ throw new InvalidPasswordError();
476
+ }
477
+ }
478
+ function generateAutoUserId() {
479
+ return crypto.randomUUID();
480
+ }
481
+ async function createConfirmationToken(queries, account, email, callback) {
482
+ const token = hash.encode(email);
483
+ const expires = new Date(Date.now() + 1e3 * 60 * 60 * 24 * 7);
484
+ await queries.createConfirmation({
485
+ accountId: account.id,
486
+ token,
487
+ email,
488
+ expires
489
+ });
490
+ if (callback) {
491
+ callback(token);
492
+ }
493
+ }
494
+ async function createUser(config, credentials, userId, callback) {
495
+ validateEmail(credentials.email);
496
+ validatePassword(credentials.password, config);
497
+ const queries = new AuthQueries(config);
498
+ const existing = await queries.findAccountByEmail(credentials.email);
499
+ if (existing) {
500
+ throw new EmailTakenError();
501
+ }
502
+ const finalUserId = userId || generateAutoUserId();
503
+ const hashedPassword = hash.encode(credentials.password);
504
+ const verified = typeof callback !== "function";
505
+ const account = await queries.createAccount({
506
+ userId: finalUserId,
507
+ email: credentials.email,
508
+ password: hashedPassword,
509
+ verified,
510
+ status: AuthStatus.Normal,
511
+ rolemask: 0
512
+ });
513
+ if (!verified && callback) {
514
+ await createConfirmationToken(queries, account, credentials.email, callback);
515
+ }
516
+ return account;
517
+ }
518
+
461
519
  // src/auth-admin-manager.ts
462
520
  var AuthAdminManager = class {
463
521
  constructor(req, res, config, auth) {
@@ -480,9 +538,6 @@ var AuthAdminManager = class {
480
538
  throw new InvalidPasswordError();
481
539
  }
482
540
  }
483
- generateAutoUserId() {
484
- return crypto.randomUUID();
485
- }
486
541
  async findAccountByIdentifier(identifier) {
487
542
  if (identifier.accountId !== void 0) {
488
543
  return await this.queries.findAccountById(identifier.accountId);
@@ -494,7 +549,7 @@ var AuthAdminManager = class {
494
549
  return null;
495
550
  }
496
551
  async createConfirmationToken(account, email, callback) {
497
- const token = hash.encode(email);
552
+ const token = hash2.encode(email);
498
553
  const expires = new Date(Date.now() + 1e3 * 60 * 60 * 24 * 7);
499
554
  await this.queries.createConfirmation({
500
555
  accountId: account.id,
@@ -517,27 +572,7 @@ var AuthAdminManager = class {
517
572
  * @throws {InvalidPasswordError} Password doesn't meet length requirements
518
573
  */
519
574
  async createUser(credentials, userId, callback) {
520
- validateEmail(credentials.email);
521
- this.validatePassword(credentials.password);
522
- const existing = await this.queries.findAccountByEmail(credentials.email);
523
- if (existing) {
524
- throw new EmailTakenError();
525
- }
526
- const finalUserId = userId || this.generateAutoUserId();
527
- const hashedPassword = hash.encode(credentials.password);
528
- const verified = typeof callback !== "function";
529
- const account = await this.queries.createAccount({
530
- userId: finalUserId,
531
- email: credentials.email,
532
- password: hashedPassword,
533
- verified,
534
- status: AuthStatus.Normal,
535
- rolemask: 0
536
- });
537
- if (!verified && callback) {
538
- await this.createConfirmationToken(account, credentials.email, callback);
539
- }
540
- return account;
575
+ return createUser(this.config, credentials, userId, callback);
541
576
  }
542
577
  /**
543
578
  * Log in as another user (admin function).
@@ -630,7 +665,7 @@ var AuthAdminManager = class {
630
665
  throw new UserNotFoundError();
631
666
  }
632
667
  await this.queries.updateAccount(account.id, {
633
- password: hash.encode(password)
668
+ password: hash2.encode(password)
634
669
  });
635
670
  }
636
671
  /**
@@ -666,7 +701,7 @@ var AuthAdminManager = class {
666
701
  throw new EmailNotVerifiedError();
667
702
  }
668
703
  const expiry = !expiresAfter ? ms("6h") : ms(expiresAfter);
669
- const token = hash.encode(account.email);
704
+ const token = hash2.encode(account.email);
670
705
  const expires = new Date(Date.now() + expiry);
671
706
  await this.queries.createResetToken({
672
707
  accountId: account.id,
@@ -698,7 +733,7 @@ var AuthAdminManager = class {
698
733
  };
699
734
 
700
735
  // src/auth-manager.ts
701
- import { hash as hash4 } from "@prsm/hash";
736
+ import { hash as hash5 } from "@prsm/hash";
702
737
  import ms3 from "@prsm/ms";
703
738
 
704
739
  // src/activity-logger.ts
@@ -1096,7 +1131,7 @@ var AzureProvider = class extends BaseOAuthProvider {
1096
1131
 
1097
1132
  // src/two-factor/totp-provider.ts
1098
1133
  import Otp from "@eaccess/totp";
1099
- import { hash as hash2 } from "@prsm/hash";
1134
+ import { hash as hash3 } from "@prsm/hash";
1100
1135
  var TotpProvider = class {
1101
1136
  constructor(config) {
1102
1137
  this.config = config;
@@ -1125,11 +1160,11 @@ var TotpProvider = class {
1125
1160
  return codes;
1126
1161
  }
1127
1162
  hashBackupCodes(codes) {
1128
- return codes.map((code) => hash2.encode(code));
1163
+ return codes.map((code) => hash3.encode(code));
1129
1164
  }
1130
1165
  verifyBackupCode(hashedCodes, inputCode) {
1131
1166
  for (let i = 0; i < hashedCodes.length; i++) {
1132
- if (hash2.verify(hashedCodes[i], inputCode.toUpperCase())) {
1167
+ if (hash3.verify(hashedCodes[i], inputCode.toUpperCase())) {
1133
1168
  return { isValid: true, index: i };
1134
1169
  }
1135
1170
  }
@@ -1146,7 +1181,7 @@ var TotpProvider = class {
1146
1181
 
1147
1182
  // src/two-factor/otp-provider.ts
1148
1183
  import ms2 from "@prsm/ms";
1149
- import { hash as hash3 } from "@prsm/hash";
1184
+ import { hash as hash4 } from "@prsm/hash";
1150
1185
  var OtpProvider = class {
1151
1186
  constructor(config) {
1152
1187
  this.config = config;
@@ -1171,7 +1206,7 @@ var OtpProvider = class {
1171
1206
  async createAndStoreOTP(accountId, mechanism) {
1172
1207
  const otp = this.generateOTP();
1173
1208
  const selector = this.generateSelector();
1174
- const tokenHash = hash3.encode(otp);
1209
+ const tokenHash = hash4.encode(otp);
1175
1210
  const expiryDuration = this.config.twoFactor?.tokenExpiry || "5m";
1176
1211
  const expiresAt = new Date(Date.now() + ms2(expiryDuration));
1177
1212
  await this.queries.deleteTwoFactorTokensByAccountAndMechanism(accountId, mechanism);
@@ -1193,7 +1228,7 @@ var OtpProvider = class {
1193
1228
  await this.queries.deleteTwoFactorToken(token.id);
1194
1229
  return { isValid: false };
1195
1230
  }
1196
- const isValid = hash3.verify(token.token_hash, inputCode);
1231
+ const isValid = hash4.verify(token.token_hash, inputCode);
1197
1232
  if (isValid) {
1198
1233
  await this.queries.deleteTwoFactorToken(token.id);
1199
1234
  return { isValid: true, token };
@@ -1782,7 +1817,7 @@ var AuthManager = class {
1782
1817
  });
1783
1818
  }
1784
1819
  async createRememberDirective(account) {
1785
- const token = hash4.encode(account.email);
1820
+ const token = hash5.encode(account.email);
1786
1821
  const duration = this.config.rememberDuration || "30d";
1787
1822
  const expires = new Date(Date.now() + ms3(duration));
1788
1823
  await this.queries.createRememberToken({
@@ -1820,7 +1855,7 @@ var AuthManager = class {
1820
1855
  await this.activityLogger.logActivity(null, AuthActivityAction.FailedLogin, this.req, false, { email, reason: "account_not_found" });
1821
1856
  throw new UserNotFoundError();
1822
1857
  }
1823
- if (!account.password || !hash4.verify(account.password, password)) {
1858
+ if (!account.password || !hash5.verify(account.password, password)) {
1824
1859
  await this.activityLogger.logActivity(account.id, AuthActivityAction.FailedLogin, this.req, false, { email, reason: "invalid_password" });
1825
1860
  throw new InvalidPasswordError();
1826
1861
  }
@@ -1932,7 +1967,7 @@ var AuthManager = class {
1932
1967
  throw new EmailTakenError();
1933
1968
  }
1934
1969
  const finalUserId = userId || this.generateAutoUserId();
1935
- const hashedPassword = hash4.encode(password);
1970
+ const hashedPassword = hash5.encode(password);
1936
1971
  const verified = typeof callback !== "function";
1937
1972
  const account = await this.queries.createAccount({
1938
1973
  userId: finalUserId,
@@ -1949,7 +1984,7 @@ var AuthManager = class {
1949
1984
  return account;
1950
1985
  }
1951
1986
  async createConfirmationToken(account, email, callback) {
1952
- const token = hash4.encode(email);
1987
+ const token = hash5.encode(email);
1953
1988
  const expires = new Date(Date.now() + 1e3 * 60 * 60 * 24 * 7);
1954
1989
  await this.queries.createConfirmation({
1955
1990
  accountId: account.id,
@@ -2083,7 +2118,7 @@ var AuthManager = class {
2083
2118
  if (new Date(confirmation.expires) < /* @__PURE__ */ new Date()) {
2084
2119
  throw new ConfirmationExpiredError();
2085
2120
  }
2086
- if (!hash4.verify(token, confirmation.email)) {
2121
+ if (!hash5.verify(token, confirmation.email)) {
2087
2122
  throw new InvalidTokenError();
2088
2123
  }
2089
2124
  await this.queries.updateAccount(confirmation.account_id, {
@@ -2180,7 +2215,7 @@ var AuthManager = class {
2180
2215
  if (openRequests >= maxRequests) {
2181
2216
  throw new TooManyResetsError();
2182
2217
  }
2183
- const token = hash4.encode(email);
2218
+ const token = hash5.encode(email);
2184
2219
  const expires = new Date(Date.now() + expiry);
2185
2220
  await this.queries.createResetToken({
2186
2221
  accountId: account.id,
@@ -2222,11 +2257,11 @@ var AuthManager = class {
2222
2257
  throw new ResetDisabledError();
2223
2258
  }
2224
2259
  this.validatePassword(password);
2225
- if (!hash4.verify(token, account.email)) {
2260
+ if (!hash5.verify(token, account.email)) {
2226
2261
  throw new InvalidTokenError();
2227
2262
  }
2228
2263
  await this.queries.updateAccount(account.id, {
2229
- password: hash4.encode(password)
2264
+ password: hash5.encode(password)
2230
2265
  });
2231
2266
  if (logout) {
2232
2267
  await this.forceLogoutForAccountById(account.id);
@@ -2254,7 +2289,7 @@ var AuthManager = class {
2254
2289
  if (!account.password) {
2255
2290
  return false;
2256
2291
  }
2257
- return hash4.verify(account.password, password);
2292
+ return hash5.verify(account.password, password);
2258
2293
  }
2259
2294
  async forceLogoutForAccountById(accountId) {
2260
2295
  await this.queries.deleteRememberTokensForAccount(accountId);
@@ -2509,6 +2544,44 @@ async function getAuthTableStats(config) {
2509
2544
  expiredTwoFactorTokens: parseInt(expiredTwoFactorTokensResult.rows[0]?.count || "0")
2510
2545
  };
2511
2546
  }
2547
+
2548
+ // src/user-roles.ts
2549
+ async function findAccountByIdentifier(queries, identifier) {
2550
+ let account = null;
2551
+ if (identifier.accountId !== void 0) {
2552
+ account = await queries.findAccountById(identifier.accountId);
2553
+ } else if (identifier.email !== void 0) {
2554
+ account = await queries.findAccountByEmail(identifier.email);
2555
+ } else if (identifier.userId !== void 0) {
2556
+ account = await queries.findAccountByUserId(identifier.userId);
2557
+ }
2558
+ if (!account) {
2559
+ throw new UserNotFoundError();
2560
+ }
2561
+ return account;
2562
+ }
2563
+ async function addRoleToUser(config, identifier, role) {
2564
+ const queries = new AuthQueries(config);
2565
+ const account = await findAccountByIdentifier(queries, identifier);
2566
+ const rolemask = account.rolemask | role;
2567
+ await queries.updateAccount(account.id, { rolemask });
2568
+ }
2569
+ async function removeRoleFromUser(config, identifier, role) {
2570
+ const queries = new AuthQueries(config);
2571
+ const account = await findAccountByIdentifier(queries, identifier);
2572
+ const rolemask = account.rolemask & ~role;
2573
+ await queries.updateAccount(account.id, { rolemask });
2574
+ }
2575
+ async function setUserRoles(config, identifier, rolemask) {
2576
+ const queries = new AuthQueries(config);
2577
+ const account = await findAccountByIdentifier(queries, identifier);
2578
+ await queries.updateAccount(account.id, { rolemask });
2579
+ }
2580
+ async function getUserRoles(config, identifier) {
2581
+ const queries = new AuthQueries(config);
2582
+ const account = await findAccountByIdentifier(queries, identifier);
2583
+ return account.rolemask;
2584
+ }
2512
2585
  export {
2513
2586
  ActivityLogger,
2514
2587
  AuthActivityAction,
@@ -2544,12 +2617,17 @@ export {
2544
2617
  UserInactiveError,
2545
2618
  UserNotFoundError,
2546
2619
  UserNotLoggedInError,
2620
+ addRoleToUser,
2547
2621
  cleanupExpiredTokens,
2548
2622
  createAuthMiddleware,
2549
2623
  createAuthTables,
2624
+ createUser,
2550
2625
  dropAuthTables,
2551
2626
  getAuthTableStats,
2627
+ getUserRoles,
2552
2628
  isValidEmail,
2629
+ removeRoleFromUser,
2630
+ setUserRoles,
2553
2631
  validateEmail
2554
2632
  };
2555
2633
  //# sourceMappingURL=index.js.map