@eaccess/auth 0.1.20 → 1.0.0

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
@@ -1,5 +1,6 @@
1
1
  import { Request, Response, NextFunction } from 'express';
2
2
  import { Pool } from 'pg';
3
+ import { IncomingMessage } from 'http';
3
4
 
4
5
  interface OAuthProviderConfig {
5
6
  clientId: string;
@@ -35,6 +36,7 @@ interface AuthConfig {
35
36
  */
36
37
  createUser?: (userData: OAuthUserData) => string | number | Promise<string | number>;
37
38
  tablePrefix?: string;
39
+ roles?: Record<string, number>;
38
40
  minPasswordLength?: number;
39
41
  maxPasswordLength?: number;
40
42
  rememberDuration?: string;
@@ -119,6 +121,10 @@ interface AuthRemember {
119
121
  token: string;
120
122
  expires: Date;
121
123
  }
124
+ interface AuthenticateRequestResult {
125
+ account: AuthAccount | null;
126
+ source: "session" | "remember" | null;
127
+ }
122
128
  interface AuthReset {
123
129
  id: number;
124
130
  account_id: number;
@@ -599,6 +605,7 @@ interface AuthContext {
599
605
  }
600
606
  declare function createAuthContext(config: AuthConfig): AuthContext;
601
607
 
608
+ declare function authenticateRequest(config: AuthConfig, req: IncomingMessage, sessionMiddleware?: (req: any, res: any, next: () => void) => void): Promise<AuthenticateRequestResult>;
602
609
  declare function createUser(config: AuthConfig, credentials: {
603
610
  email: string;
604
611
  password: string;
@@ -654,6 +661,7 @@ declare function forceLogoutForUserBy(config: AuthConfig, identifier: {
654
661
  }>;
655
662
 
656
663
  declare const authFunctions_addRoleForUserBy: typeof addRoleForUserBy;
664
+ declare const authFunctions_authenticateRequest: typeof authenticateRequest;
657
665
  declare const authFunctions_changePasswordForUserBy: typeof changePasswordForUserBy;
658
666
  declare const authFunctions_confirmResetPassword: typeof confirmResetPassword;
659
667
  declare const authFunctions_createUser: typeof createUser;
@@ -667,9 +675,10 @@ declare const authFunctions_resetPassword: typeof resetPassword;
667
675
  declare const authFunctions_setStatusForUserBy: typeof setStatusForUserBy;
668
676
  declare const authFunctions_userExistsByEmail: typeof userExistsByEmail;
669
677
  declare namespace authFunctions {
670
- export { authFunctions_addRoleForUserBy as addRoleForUserBy, authFunctions_changePasswordForUserBy as changePasswordForUserBy, authFunctions_confirmResetPassword as confirmResetPassword, authFunctions_createUser as createUser, authFunctions_deleteUserBy as deleteUserBy, authFunctions_forceLogoutForUserBy as forceLogoutForUserBy, authFunctions_hasRoleForUserBy as hasRoleForUserBy, authFunctions_initiatePasswordResetForUserBy as initiatePasswordResetForUserBy, authFunctions_register as register, authFunctions_removeRoleForUserBy as removeRoleForUserBy, authFunctions_resetPassword as resetPassword, authFunctions_setStatusForUserBy as setStatusForUserBy, authFunctions_userExistsByEmail as userExistsByEmail };
678
+ export { authFunctions_addRoleForUserBy as addRoleForUserBy, authFunctions_authenticateRequest as authenticateRequest, authFunctions_changePasswordForUserBy as changePasswordForUserBy, authFunctions_confirmResetPassword as confirmResetPassword, authFunctions_createUser as createUser, authFunctions_deleteUserBy as deleteUserBy, authFunctions_forceLogoutForUserBy as forceLogoutForUserBy, authFunctions_hasRoleForUserBy as hasRoleForUserBy, authFunctions_initiatePasswordResetForUserBy as initiatePasswordResetForUserBy, authFunctions_register as register, authFunctions_removeRoleForUserBy as removeRoleForUserBy, authFunctions_resetPassword as resetPassword, authFunctions_setStatusForUserBy as setStatusForUserBy, authFunctions_userExistsByEmail as userExistsByEmail };
671
679
  }
672
680
 
681
+ declare function defineRoles<const T extends readonly string[]>(...names: T): Readonly<Record<T[number], number>>;
673
682
  type UserIdentifier = {
674
683
  accountId?: number;
675
684
  email?: string;
@@ -866,11 +875,11 @@ declare class TotpProvider {
866
875
  generateQRCode(email: string, secret: string): string;
867
876
  verify(secret: string, code: string): boolean;
868
877
  generateBackupCodes(count?: number): string[];
869
- hashBackupCodes(codes: string[]): string[];
870
- verifyBackupCode(hashedCodes: string[], inputCode: string): {
878
+ hashBackupCodes(codes: string[]): Promise<string[]>;
879
+ verifyBackupCode(hashedCodes: string[], inputCode: string): Promise<{
871
880
  isValid: boolean;
872
881
  index: number;
873
- };
882
+ }>;
874
883
  maskEmail(email: string): string;
875
884
  }
876
885
 
@@ -1193,4 +1202,4 @@ declare class AzureProvider extends BaseOAuthProvider {
1193
1202
  protected exchangeCodeForToken(code: string, tokenUrl: string): Promise<string>;
1194
1203
  }
1195
1204
 
1196
- export { ActivityLogger, type AuthAccount, type AuthActivity, AuthActivityAction, type AuthActivityActionType, type AuthConfig, type AuthConfirmation, type AuthContext, 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 OAuthCallbackResult, 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, addRoleForUserBy, addRoleToUser, authFunctions, changePasswordForUserBy, cleanupExpiredTokens, confirmResetPassword, createAuthContext, createAuthMiddleware, createAuthTables, createUser, deleteUserBy, dropAuthTables, forceLogoutForUserBy, getAuthTableStats, getUserRoles, hasRoleForUserBy, initiatePasswordResetForUserBy, isValidEmail, register, removeRoleForUserBy, removeRoleFromUser, resetPassword, setStatusForUserBy, setUserRoles, userExistsByEmail, validateEmail };
1205
+ export { ActivityLogger, type AuthAccount, type AuthActivity, AuthActivityAction, type AuthActivityActionType, type AuthConfig, type AuthConfirmation, type AuthContext, AuthError, type AuthManager$1 as AuthManager, type AuthProvider, type AuthRemember, type AuthReset, AuthRole, type AuthSession, AuthStatus, type AuthenticateRequestResult, AzureProvider, type AzureProviderConfig, BaseOAuthProvider, ConfirmationExpiredError, ConfirmationNotFoundError, EmailNotVerifiedError, EmailTakenError, GitHubProvider, type GitHubProviderConfig, GoogleProvider, type GoogleProviderConfig, InvalidBackupCodeError, InvalidEmailError, InvalidPasswordError, InvalidTokenError, InvalidTwoFactorCodeError, type OAuthCallbackResult, 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, addRoleForUserBy, addRoleToUser, authFunctions, authenticateRequest, changePasswordForUserBy, cleanupExpiredTokens, confirmResetPassword, createAuthContext, createAuthMiddleware, createAuthTables, createUser, defineRoles, deleteUserBy, dropAuthTables, forceLogoutForUserBy, getAuthTableStats, getUserRoles, hasRoleForUserBy, initiatePasswordResetForUserBy, isValidEmail, register, removeRoleForUserBy, removeRoleFromUser, resetPassword, setStatusForUserBy, setUserRoles, userExistsByEmail, validateEmail };
package/dist/index.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import { Request, Response, NextFunction } from 'express';
2
2
  import { Pool } from 'pg';
3
+ import { IncomingMessage } from 'http';
3
4
 
4
5
  interface OAuthProviderConfig {
5
6
  clientId: string;
@@ -35,6 +36,7 @@ interface AuthConfig {
35
36
  */
36
37
  createUser?: (userData: OAuthUserData) => string | number | Promise<string | number>;
37
38
  tablePrefix?: string;
39
+ roles?: Record<string, number>;
38
40
  minPasswordLength?: number;
39
41
  maxPasswordLength?: number;
40
42
  rememberDuration?: string;
@@ -119,6 +121,10 @@ interface AuthRemember {
119
121
  token: string;
120
122
  expires: Date;
121
123
  }
124
+ interface AuthenticateRequestResult {
125
+ account: AuthAccount | null;
126
+ source: "session" | "remember" | null;
127
+ }
122
128
  interface AuthReset {
123
129
  id: number;
124
130
  account_id: number;
@@ -599,6 +605,7 @@ interface AuthContext {
599
605
  }
600
606
  declare function createAuthContext(config: AuthConfig): AuthContext;
601
607
 
608
+ declare function authenticateRequest(config: AuthConfig, req: IncomingMessage, sessionMiddleware?: (req: any, res: any, next: () => void) => void): Promise<AuthenticateRequestResult>;
602
609
  declare function createUser(config: AuthConfig, credentials: {
603
610
  email: string;
604
611
  password: string;
@@ -654,6 +661,7 @@ declare function forceLogoutForUserBy(config: AuthConfig, identifier: {
654
661
  }>;
655
662
 
656
663
  declare const authFunctions_addRoleForUserBy: typeof addRoleForUserBy;
664
+ declare const authFunctions_authenticateRequest: typeof authenticateRequest;
657
665
  declare const authFunctions_changePasswordForUserBy: typeof changePasswordForUserBy;
658
666
  declare const authFunctions_confirmResetPassword: typeof confirmResetPassword;
659
667
  declare const authFunctions_createUser: typeof createUser;
@@ -667,9 +675,10 @@ declare const authFunctions_resetPassword: typeof resetPassword;
667
675
  declare const authFunctions_setStatusForUserBy: typeof setStatusForUserBy;
668
676
  declare const authFunctions_userExistsByEmail: typeof userExistsByEmail;
669
677
  declare namespace authFunctions {
670
- export { authFunctions_addRoleForUserBy as addRoleForUserBy, authFunctions_changePasswordForUserBy as changePasswordForUserBy, authFunctions_confirmResetPassword as confirmResetPassword, authFunctions_createUser as createUser, authFunctions_deleteUserBy as deleteUserBy, authFunctions_forceLogoutForUserBy as forceLogoutForUserBy, authFunctions_hasRoleForUserBy as hasRoleForUserBy, authFunctions_initiatePasswordResetForUserBy as initiatePasswordResetForUserBy, authFunctions_register as register, authFunctions_removeRoleForUserBy as removeRoleForUserBy, authFunctions_resetPassword as resetPassword, authFunctions_setStatusForUserBy as setStatusForUserBy, authFunctions_userExistsByEmail as userExistsByEmail };
678
+ export { authFunctions_addRoleForUserBy as addRoleForUserBy, authFunctions_authenticateRequest as authenticateRequest, authFunctions_changePasswordForUserBy as changePasswordForUserBy, authFunctions_confirmResetPassword as confirmResetPassword, authFunctions_createUser as createUser, authFunctions_deleteUserBy as deleteUserBy, authFunctions_forceLogoutForUserBy as forceLogoutForUserBy, authFunctions_hasRoleForUserBy as hasRoleForUserBy, authFunctions_initiatePasswordResetForUserBy as initiatePasswordResetForUserBy, authFunctions_register as register, authFunctions_removeRoleForUserBy as removeRoleForUserBy, authFunctions_resetPassword as resetPassword, authFunctions_setStatusForUserBy as setStatusForUserBy, authFunctions_userExistsByEmail as userExistsByEmail };
671
679
  }
672
680
 
681
+ declare function defineRoles<const T extends readonly string[]>(...names: T): Readonly<Record<T[number], number>>;
673
682
  type UserIdentifier = {
674
683
  accountId?: number;
675
684
  email?: string;
@@ -866,11 +875,11 @@ declare class TotpProvider {
866
875
  generateQRCode(email: string, secret: string): string;
867
876
  verify(secret: string, code: string): boolean;
868
877
  generateBackupCodes(count?: number): string[];
869
- hashBackupCodes(codes: string[]): string[];
870
- verifyBackupCode(hashedCodes: string[], inputCode: string): {
878
+ hashBackupCodes(codes: string[]): Promise<string[]>;
879
+ verifyBackupCode(hashedCodes: string[], inputCode: string): Promise<{
871
880
  isValid: boolean;
872
881
  index: number;
873
- };
882
+ }>;
874
883
  maskEmail(email: string): string;
875
884
  }
876
885
 
@@ -1193,4 +1202,4 @@ declare class AzureProvider extends BaseOAuthProvider {
1193
1202
  protected exchangeCodeForToken(code: string, tokenUrl: string): Promise<string>;
1194
1203
  }
1195
1204
 
1196
- export { ActivityLogger, type AuthAccount, type AuthActivity, AuthActivityAction, type AuthActivityActionType, type AuthConfig, type AuthConfirmation, type AuthContext, 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 OAuthCallbackResult, 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, addRoleForUserBy, addRoleToUser, authFunctions, changePasswordForUserBy, cleanupExpiredTokens, confirmResetPassword, createAuthContext, createAuthMiddleware, createAuthTables, createUser, deleteUserBy, dropAuthTables, forceLogoutForUserBy, getAuthTableStats, getUserRoles, hasRoleForUserBy, initiatePasswordResetForUserBy, isValidEmail, register, removeRoleForUserBy, removeRoleFromUser, resetPassword, setStatusForUserBy, setUserRoles, userExistsByEmail, validateEmail };
1205
+ export { ActivityLogger, type AuthAccount, type AuthActivity, AuthActivityAction, type AuthActivityActionType, type AuthConfig, type AuthConfirmation, type AuthContext, AuthError, type AuthManager$1 as AuthManager, type AuthProvider, type AuthRemember, type AuthReset, AuthRole, type AuthSession, AuthStatus, type AuthenticateRequestResult, AzureProvider, type AzureProviderConfig, BaseOAuthProvider, ConfirmationExpiredError, ConfirmationNotFoundError, EmailNotVerifiedError, EmailTakenError, GitHubProvider, type GitHubProviderConfig, GoogleProvider, type GoogleProviderConfig, InvalidBackupCodeError, InvalidEmailError, InvalidPasswordError, InvalidTokenError, InvalidTwoFactorCodeError, type OAuthCallbackResult, 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, addRoleForUserBy, addRoleToUser, authFunctions, authenticateRequest, changePasswordForUserBy, cleanupExpiredTokens, confirmResetPassword, createAuthContext, createAuthMiddleware, createAuthTables, createUser, defineRoles, deleteUserBy, dropAuthTables, forceLogoutForUserBy, getAuthTableStats, getUserRoles, hasRoleForUserBy, initiatePasswordResetForUserBy, isValidEmail, register, removeRoleForUserBy, removeRoleFromUser, resetPassword, setStatusForUserBy, setUserRoles, userExistsByEmail, validateEmail };
package/dist/index.js CHANGED
@@ -5,7 +5,7 @@ var __export = (target, all) => {
5
5
  };
6
6
 
7
7
  // src/auth-manager.ts
8
- import { hash as hash4 } from "@prsm/hash";
8
+ import hash4 from "@prsm/hash";
9
9
  import ms3 from "@prsm/ms";
10
10
 
11
11
  // src/types.ts
@@ -721,7 +721,7 @@ var GitHubProvider = class extends BaseOAuthProvider {
721
721
  client_id: this.config.clientId,
722
722
  redirect_uri: this.config.redirectUri,
723
723
  scope: scopes?.join(" ") || "user:email",
724
- state: state || Math.random().toString(36).substring(2),
724
+ state: state || crypto.randomUUID(),
725
725
  response_type: "code"
726
726
  });
727
727
  return `https://github.com/login/oauth/authorize?${params}`;
@@ -770,7 +770,7 @@ var GoogleProvider = class extends BaseOAuthProvider {
770
770
  client_id: this.config.clientId,
771
771
  redirect_uri: this.config.redirectUri,
772
772
  scope: scopes?.join(" ") || "openid profile email",
773
- state: state || Math.random().toString(36).substring(2),
773
+ state: state || crypto.randomUUID(),
774
774
  response_type: "code",
775
775
  access_type: "offline",
776
776
  prompt: "consent"
@@ -812,7 +812,7 @@ var AzureProvider = class extends BaseOAuthProvider {
812
812
  client_id: azureConfig.clientId,
813
813
  redirect_uri: azureConfig.redirectUri,
814
814
  scope: scopes?.join(" ") || "openid profile email User.Read",
815
- state: state || Math.random().toString(36).substring(2),
815
+ state: state || crypto.randomUUID(),
816
816
  response_type: "code",
817
817
  response_mode: "query"
818
818
  });
@@ -871,7 +871,7 @@ var AzureProvider = class extends BaseOAuthProvider {
871
871
 
872
872
  // src/two-factor/totp-provider.ts
873
873
  import Otp from "@eaccess/totp";
874
- import { hash } from "@prsm/hash";
874
+ import hash from "@prsm/hash";
875
875
  var TotpProvider = class {
876
876
  constructor(config) {
877
877
  this.config = config;
@@ -888,23 +888,20 @@ var TotpProvider = class {
888
888
  return Otp.verifyTotp(secret, code, window);
889
889
  }
890
890
  generateBackupCodes(count = 10) {
891
+ const chars = "23456789ABCDEFGHJKLMNPQRSTUVWXYZ";
891
892
  const codes = [];
892
893
  for (let i = 0; i < count; i++) {
893
- const chars = "23456789ABCDEFGHJKLMNPQRSTUVWXYZ";
894
- let code = "";
895
- for (let j = 0; j < 8; j++) {
896
- code += chars.charAt(Math.floor(Math.random() * chars.length));
897
- }
898
- codes.push(code);
894
+ const bytes = crypto.getRandomValues(new Uint8Array(8));
895
+ codes.push(Array.from(bytes, (b) => chars[b % chars.length]).join(""));
899
896
  }
900
897
  return codes;
901
898
  }
902
- hashBackupCodes(codes) {
903
- return codes.map((code) => hash.encode(code));
899
+ async hashBackupCodes(codes) {
900
+ return await Promise.all(codes.map((code) => hash.encode(code)));
904
901
  }
905
- verifyBackupCode(hashedCodes, inputCode) {
902
+ async verifyBackupCode(hashedCodes, inputCode) {
906
903
  for (let i = 0; i < hashedCodes.length; i++) {
907
- if (hash.verify(hashedCodes[i], inputCode.toUpperCase())) {
904
+ if (await hash.verify(hashedCodes[i], inputCode.toUpperCase())) {
908
905
  return { isValid: true, index: i };
909
906
  }
910
907
  }
@@ -921,7 +918,7 @@ var TotpProvider = class {
921
918
 
922
919
  // src/two-factor/otp-provider.ts
923
920
  import ms from "@prsm/ms";
924
- import { hash as hash2 } from "@prsm/hash";
921
+ import hash2 from "@prsm/hash";
925
922
  var OtpProvider = class {
926
923
  constructor(config) {
927
924
  this.config = config;
@@ -929,24 +926,16 @@ var OtpProvider = class {
929
926
  }
930
927
  generateOTP() {
931
928
  const length = this.config.twoFactor?.codeLength || 6;
932
- let otp = "";
933
- for (let i = 0; i < length; i++) {
934
- otp += Math.floor(Math.random() * 10).toString();
935
- }
936
- return otp;
929
+ const bytes = crypto.getRandomValues(new Uint8Array(length));
930
+ return Array.from(bytes, (b) => (b % 10).toString()).join("");
937
931
  }
938
932
  generateSelector() {
939
- const chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
940
- let selector = "";
941
- for (let i = 0; i < 32; i++) {
942
- selector += chars.charAt(Math.floor(Math.random() * chars.length));
943
- }
944
- return selector;
933
+ return crypto.randomUUID().replace(/-/g, "");
945
934
  }
946
935
  async createAndStoreOTP(accountId, mechanism) {
947
936
  const otp = this.generateOTP();
948
937
  const selector = this.generateSelector();
949
- const tokenHash = hash2.encode(otp);
938
+ const tokenHash = await hash2.encode(otp);
950
939
  const expiryDuration = this.config.twoFactor?.tokenExpiry || "5m";
951
940
  const expiresAt = new Date(Date.now() + ms(expiryDuration));
952
941
  await this.queries.deleteTwoFactorTokensByAccountAndMechanism(accountId, mechanism);
@@ -968,7 +957,7 @@ var OtpProvider = class {
968
957
  await this.queries.deleteTwoFactorToken(token.id);
969
958
  return { isValid: false };
970
959
  }
971
- const isValid = hash2.verify(token.token_hash, inputCode);
960
+ const isValid = await hash2.verify(token.token_hash, inputCode);
972
961
  if (isValid) {
973
962
  await this.queries.deleteTwoFactorToken(token.id);
974
963
  return { isValid: true, token };
@@ -1015,7 +1004,7 @@ var TwoFactorManager = class {
1015
1004
  const backupCodesCount = this.config.twoFactor?.backupCodesCount || 10;
1016
1005
  backupCodes = this.totpProvider.generateBackupCodes(backupCodesCount);
1017
1006
  }
1018
- const hashedBackupCodes = backupCodes ? this.totpProvider.hashBackupCodes(backupCodes) : void 0;
1007
+ const hashedBackupCodes = backupCodes ? await this.totpProvider.hashBackupCodes(backupCodes) : void 0;
1019
1008
  const verified = !requireVerification;
1020
1009
  if (existingMethod) {
1021
1010
  await this.queries.updateTwoFactorMethod(existingMethod.id, {
@@ -1113,7 +1102,7 @@ var TwoFactorManager = class {
1113
1102
  }
1114
1103
  const backupCodesCount = this.config.twoFactor?.backupCodesCount || 10;
1115
1104
  const backupCodes = this.totpProvider.generateBackupCodes(backupCodesCount);
1116
- const hashedBackupCodes = this.totpProvider.hashBackupCodes(backupCodes);
1105
+ const hashedBackupCodes = await this.totpProvider.hashBackupCodes(backupCodes);
1117
1106
  await this.queries.updateTwoFactorMethod(method.id, {
1118
1107
  verified: true,
1119
1108
  backup_codes: hashedBackupCodes,
@@ -1165,7 +1154,7 @@ var TwoFactorManager = class {
1165
1154
  if (!method || !method.verified || !method.backup_codes) {
1166
1155
  throw new TwoFactorNotSetupError();
1167
1156
  }
1168
- const { isValid, index } = this.totpProvider.verifyBackupCode(method.backup_codes, code);
1157
+ const { isValid, index } = await this.totpProvider.verifyBackupCode(method.backup_codes, code);
1169
1158
  if (!isValid) {
1170
1159
  await this.activityLogger.logActivity(twoFactorState.accountId, AuthActivityAction.TwoFactorFailed, this.req, false, { mechanism: "backup_code", reason: "invalid_code" });
1171
1160
  throw new InvalidBackupCodeError();
@@ -1314,7 +1303,7 @@ var TwoFactorManager = class {
1314
1303
  }
1315
1304
  const backupCodesCount = this.config.twoFactor?.backupCodesCount || 10;
1316
1305
  const backupCodes = this.totpProvider.generateBackupCodes(backupCodesCount);
1317
- const hashedBackupCodes = this.totpProvider.hashBackupCodes(backupCodes);
1306
+ const hashedBackupCodes = await this.totpProvider.hashBackupCodes(backupCodes);
1318
1307
  await this.queries.updateTwoFactorMethod(method.id, {
1319
1308
  backup_codes: hashedBackupCodes
1320
1309
  });
@@ -1382,6 +1371,7 @@ var TwoFactorManager = class {
1382
1371
  var auth_functions_exports = {};
1383
1372
  __export(auth_functions_exports, {
1384
1373
  addRoleForUserBy: () => addRoleForUserBy,
1374
+ authenticateRequest: () => authenticateRequest,
1385
1375
  changePasswordForUserBy: () => changePasswordForUserBy,
1386
1376
  confirmResetPassword: () => confirmResetPassword,
1387
1377
  createUser: () => createUser,
@@ -1395,8 +1385,50 @@ __export(auth_functions_exports, {
1395
1385
  setStatusForUserBy: () => setStatusForUserBy,
1396
1386
  userExistsByEmail: () => userExistsByEmail
1397
1387
  });
1398
- import { hash as hash3 } from "@prsm/hash";
1388
+ import hash3 from "@prsm/hash";
1399
1389
  import ms2 from "@prsm/ms";
1390
+ function parseCookies(cookieHeader) {
1391
+ const cookies = {};
1392
+ if (!cookieHeader) return cookies;
1393
+ for (const pair of cookieHeader.split(";")) {
1394
+ const idx = pair.indexOf("=");
1395
+ if (idx === -1) continue;
1396
+ const key = pair.slice(0, idx).trim();
1397
+ const value = pair.slice(idx + 1).trim();
1398
+ if (key) cookies[key] = decodeURIComponent(value);
1399
+ }
1400
+ return cookies;
1401
+ }
1402
+ async function authenticateRequest(config, req, sessionMiddleware) {
1403
+ const queries = new AuthQueries(config);
1404
+ if (sessionMiddleware) {
1405
+ await new Promise((resolve) => {
1406
+ sessionMiddleware(req, {}, resolve);
1407
+ });
1408
+ }
1409
+ const session = req.session;
1410
+ if (session?.auth?.loggedIn && session.auth.accountId) {
1411
+ const account2 = await queries.findAccountById(session.auth.accountId);
1412
+ if (account2 && account2.status === AuthStatus.Normal) {
1413
+ return { account: account2, source: "session" };
1414
+ }
1415
+ }
1416
+ const cookies = parseCookies(req.headers.cookie || "");
1417
+ const cookieName = config.rememberCookieName || "remember_token";
1418
+ const token = cookies[cookieName];
1419
+ if (!token) {
1420
+ return { account: null, source: null };
1421
+ }
1422
+ const remember = await queries.findRememberToken(token);
1423
+ if (!remember || /* @__PURE__ */ new Date() > remember.expires) {
1424
+ return { account: null, source: null };
1425
+ }
1426
+ const account = await queries.findAccountById(remember.account_id);
1427
+ if (!account || account.status !== AuthStatus.Normal) {
1428
+ return { account: null, source: null };
1429
+ }
1430
+ return { account, source: "remember" };
1431
+ }
1400
1432
  function validatePassword(password, config) {
1401
1433
  const minLength = config.minPasswordLength || 8;
1402
1434
  const maxLength = config.maxPasswordLength || 64;
@@ -1424,7 +1456,7 @@ async function findAccountByIdentifier(queries, identifier) {
1424
1456
  return null;
1425
1457
  }
1426
1458
  async function createConfirmationToken(queries, account, email, callback) {
1427
- const token = hash3.encode(email);
1459
+ const token = await hash3.encode(email);
1428
1460
  const expires = new Date(Date.now() + 1e3 * 60 * 60 * 24 * 7);
1429
1461
  await queries.createConfirmation({
1430
1462
  accountId: account.id,
@@ -1445,7 +1477,7 @@ async function createUser(config, credentials, userId, callback) {
1445
1477
  throw new EmailTakenError();
1446
1478
  }
1447
1479
  const finalUserId = userId || generateAutoUserId();
1448
- const hashedPassword = hash3.encode(credentials.password);
1480
+ const hashedPassword = await hash3.encode(credentials.password);
1449
1481
  const verified = typeof callback !== "function";
1450
1482
  const account = await queries.createAccount({
1451
1483
  userId: finalUserId,
@@ -1469,7 +1501,7 @@ async function register(config, email, password, userId, callback) {
1469
1501
  throw new EmailTakenError();
1470
1502
  }
1471
1503
  const finalUserId = userId || generateAutoUserId();
1472
- const hashedPassword = hash3.encode(password);
1504
+ const hashedPassword = await hash3.encode(password);
1473
1505
  const verified = typeof callback !== "function";
1474
1506
  const account = await queries.createAccount({
1475
1507
  userId: finalUserId,
@@ -1526,7 +1558,7 @@ async function changePasswordForUserBy(config, identifier, password) {
1526
1558
  throw new UserNotFoundError();
1527
1559
  }
1528
1560
  await queries.updateAccount(account.id, {
1529
- password: hash3.encode(password)
1561
+ password: await hash3.encode(password)
1530
1562
  });
1531
1563
  }
1532
1564
  async function setStatusForUserBy(config, identifier, status) {
@@ -1547,7 +1579,7 @@ async function initiatePasswordResetForUserBy(config, identifier, expiresAfter =
1547
1579
  throw new EmailNotVerifiedError();
1548
1580
  }
1549
1581
  const expiry = !expiresAfter ? ms2("6h") : ms2(expiresAfter);
1550
- const token = hash3.encode(account.email);
1582
+ const token = await hash3.encode(account.email);
1551
1583
  const expires = new Date(Date.now() + expiry);
1552
1584
  await queries.createResetToken({
1553
1585
  accountId: account.id,
@@ -1574,7 +1606,7 @@ async function resetPassword(config, email, expiresAfter = null, maxOpenRequests
1574
1606
  if (openRequests >= maxRequests) {
1575
1607
  throw new TooManyResetsError();
1576
1608
  }
1577
- const token = hash3.encode(email);
1609
+ const token = await hash3.encode(email);
1578
1610
  const expires = new Date(Date.now() + expiry);
1579
1611
  await queries.createResetToken({
1580
1612
  accountId: account.id,
@@ -1602,11 +1634,11 @@ async function confirmResetPassword(config, token, password) {
1602
1634
  throw new ResetDisabledError();
1603
1635
  }
1604
1636
  validatePassword(password, config);
1605
- if (!hash3.verify(token, account.email)) {
1637
+ if (!await hash3.verify(token, account.email)) {
1606
1638
  throw new InvalidTokenError();
1607
1639
  }
1608
1640
  await queries.updateAccount(account.id, {
1609
- password: hash3.encode(password)
1641
+ password: await hash3.encode(password)
1610
1642
  });
1611
1643
  await queries.deleteResetToken(token);
1612
1644
  return { accountId: account.id, email: account.email };
@@ -1676,7 +1708,7 @@ var AuthManager = class {
1676
1708
  }
1677
1709
  }
1678
1710
  getRoleMap() {
1679
- return createMapFromEnum(AuthRole);
1711
+ return createMapFromEnum(this.config.roles || AuthRole);
1680
1712
  }
1681
1713
  getStatusMap() {
1682
1714
  return createMapFromEnum(AuthStatus);
@@ -1827,7 +1859,7 @@ var AuthManager = class {
1827
1859
  });
1828
1860
  }
1829
1861
  async createRememberDirective(account) {
1830
- const token = hash4.encode(account.email);
1862
+ const token = await hash4.encode(account.email);
1831
1863
  const duration = this.config.rememberDuration || "30d";
1832
1864
  const expires = new Date(Date.now() + ms3(duration));
1833
1865
  await this.queries.createRememberToken({
@@ -1865,7 +1897,7 @@ var AuthManager = class {
1865
1897
  await this.activityLogger.logActivity(null, AuthActivityAction.FailedLogin, this.req, false, { email, reason: "account_not_found" });
1866
1898
  throw new UserNotFoundError();
1867
1899
  }
1868
- if (!account.password || !hash4.verify(account.password, password)) {
1900
+ if (!account.password || !await hash4.verify(account.password, password)) {
1869
1901
  await this.activityLogger.logActivity(account.id, AuthActivityAction.FailedLogin, this.req, false, { email, reason: "invalid_password" });
1870
1902
  throw new InvalidPasswordError();
1871
1903
  }
@@ -1978,7 +2010,7 @@ var AuthManager = class {
1978
2010
  throw new EmailTakenError();
1979
2011
  }
1980
2012
  const finalUserId = userId || this.generateAutoUserId();
1981
- const hashedPassword = hash4.encode(password);
2013
+ const hashedPassword = await hash4.encode(password);
1982
2014
  const verified = typeof callback !== "function";
1983
2015
  const account = await this.queries.createAccount({
1984
2016
  userId: finalUserId,
@@ -1995,7 +2027,7 @@ var AuthManager = class {
1995
2027
  return account;
1996
2028
  }
1997
2029
  async createConfirmationToken(account, email, callback) {
1998
- const token = hash4.encode(email);
2030
+ const token = await hash4.encode(email);
1999
2031
  const expires = new Date(Date.now() + 1e3 * 60 * 60 * 24 * 7);
2000
2032
  await this.queries.createConfirmation({
2001
2033
  accountId: account.id,
@@ -2137,7 +2169,7 @@ var AuthManager = class {
2137
2169
  if (new Date(confirmation.expires) < /* @__PURE__ */ new Date()) {
2138
2170
  throw new ConfirmationExpiredError();
2139
2171
  }
2140
- if (!hash4.verify(token, confirmation.email)) {
2172
+ if (!await hash4.verify(token, confirmation.email)) {
2141
2173
  throw new InvalidTokenError();
2142
2174
  }
2143
2175
  await this.queries.updateAccount(confirmation.account_id, {
@@ -2235,7 +2267,7 @@ var AuthManager = class {
2235
2267
  if (openRequests >= maxRequests) {
2236
2268
  throw new TooManyResetsError();
2237
2269
  }
2238
- const token = hash4.encode(email);
2270
+ const token = await hash4.encode(email);
2239
2271
  const expires = new Date(Date.now() + expiry);
2240
2272
  await this.queries.createResetToken({
2241
2273
  accountId: account.id,
@@ -2277,11 +2309,11 @@ var AuthManager = class {
2277
2309
  throw new ResetDisabledError();
2278
2310
  }
2279
2311
  this.validatePassword(password);
2280
- if (!hash4.verify(token, account.email)) {
2312
+ if (!await hash4.verify(token, account.email)) {
2281
2313
  throw new InvalidTokenError();
2282
2314
  }
2283
2315
  await this.queries.updateAccount(account.id, {
2284
- password: hash4.encode(password)
2316
+ password: await hash4.encode(password)
2285
2317
  });
2286
2318
  if (logout) {
2287
2319
  await this.forceLogoutForAccountById(account.id);
@@ -2309,7 +2341,7 @@ var AuthManager = class {
2309
2341
  if (!account.password) {
2310
2342
  return false;
2311
2343
  }
2312
- return hash4.verify(account.password, password);
2344
+ return await hash4.verify(account.password, password);
2313
2345
  }
2314
2346
  async forceLogoutForAccountById(accountId) {
2315
2347
  await this.queries.deleteRememberTokensForAccount(accountId);
@@ -2641,6 +2673,26 @@ function createAuthContext(config) {
2641
2673
  }
2642
2674
 
2643
2675
  // src/user-roles.ts
2676
+ var MAX_ROLES = 31;
2677
+ function defineRoles(...names) {
2678
+ if (names.length > MAX_ROLES) {
2679
+ throw new Error(`Cannot define more than ${MAX_ROLES} roles (postgres INTEGER is 32-bit signed)`);
2680
+ }
2681
+ if (names.length === 0) {
2682
+ throw new Error("At least one role name is required");
2683
+ }
2684
+ const seen = /* @__PURE__ */ new Set();
2685
+ const roles = {};
2686
+ for (let i = 0; i < names.length; i++) {
2687
+ const name = names[i];
2688
+ if (seen.has(name)) {
2689
+ throw new Error(`Duplicate role name: ${name}`);
2690
+ }
2691
+ seen.add(name);
2692
+ roles[name] = 1 << i;
2693
+ }
2694
+ return Object.freeze(roles);
2695
+ }
2644
2696
  async function findAccountByIdentifier2(queries, identifier) {
2645
2697
  let account = null;
2646
2698
  if (identifier.accountId !== void 0) {
@@ -2715,6 +2767,7 @@ export {
2715
2767
  addRoleForUserBy,
2716
2768
  addRoleToUser,
2717
2769
  auth_functions_exports as authFunctions,
2770
+ authenticateRequest,
2718
2771
  changePasswordForUserBy,
2719
2772
  cleanupExpiredTokens,
2720
2773
  confirmResetPassword,
@@ -2722,6 +2775,7 @@ export {
2722
2775
  createAuthMiddleware,
2723
2776
  createAuthTables,
2724
2777
  createUser,
2778
+ defineRoles,
2725
2779
  deleteUserBy,
2726
2780
  dropAuthTables,
2727
2781
  forceLogoutForUserBy,