@unchainedshop/core-users 4.0.0-rc.2 → 4.0.0-rc.21

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.
Files changed (44) hide show
  1. package/lib/db/UsersCollection.d.ts +2 -2
  2. package/lib/db/UsersCollection.d.ts.map +1 -1
  3. package/lib/db/UsersCollection.js +30 -26
  4. package/lib/db/UsersCollection.js.map +1 -1
  5. package/lib/module/configureUsersModule.d.ts +32 -31
  6. package/lib/module/configureUsersModule.d.ts.map +1 -1
  7. package/lib/module/configureUsersModule.js +81 -41
  8. package/lib/module/configureUsersModule.js.map +1 -1
  9. package/lib/module/configureUsersWebAuthnModule.d.ts +5 -5
  10. package/lib/module/configureUsersWebAuthnModule.d.ts.map +1 -1
  11. package/lib/module/configureUsersWebAuthnModule.js +9 -3
  12. package/lib/module/configureUsersWebAuthnModule.js.map +1 -1
  13. package/lib/module/pbkdf2.d.ts.map +1 -1
  14. package/lib/module/pbkdf2.js +9 -2
  15. package/lib/module/pbkdf2.js.map +1 -1
  16. package/lib/services/getUserCountryService.d.ts +3 -0
  17. package/lib/services/getUserCountryService.d.ts.map +1 -0
  18. package/lib/services/getUserCountryService.js +7 -0
  19. package/lib/services/getUserCountryService.js.map +1 -0
  20. package/lib/services/getUserLanguageService.d.ts +3 -0
  21. package/lib/services/getUserLanguageService.d.ts.map +1 -0
  22. package/lib/services/getUserLanguageService.js +7 -0
  23. package/lib/services/getUserLanguageService.js.map +1 -0
  24. package/lib/services/updateUserAvatarAfterUploadService.d.ts +3 -0
  25. package/lib/services/updateUserAvatarAfterUploadService.d.ts.map +1 -0
  26. package/lib/services/updateUserAvatarAfterUploadService.js +24 -0
  27. package/lib/services/updateUserAvatarAfterUploadService.js.map +1 -0
  28. package/lib/services/userServices.d.ts +3 -0
  29. package/lib/services/userServices.d.ts.map +1 -0
  30. package/lib/services/userServices.js +9 -0
  31. package/lib/services/userServices.js.map +1 -0
  32. package/lib/users-settings.d.ts +8 -7
  33. package/lib/users-settings.d.ts.map +1 -1
  34. package/lib/users-settings.js +34 -20
  35. package/lib/users-settings.js.map +1 -1
  36. package/package.json +10 -10
  37. package/src/db/UsersCollection.ts +33 -29
  38. package/src/module/buildFindSelector.test.ts +5 -2
  39. package/src/module/configureUsersModule.ts +126 -85
  40. package/src/module/configureUsersWebAuthnModule.ts +8 -8
  41. package/src/module/pbkdf2.ts +9 -2
  42. package/src/module/removeConfidentialServiceHashes.test.ts +1 -2
  43. package/src/users-settings.ts +43 -30
  44. package/tsconfig.json +2 -1
@@ -5,7 +5,11 @@ const PBKDF2_SALT_LENGTH = 16; // Bytes
5
5
 
6
6
  export function generateSalt(saltLength = PBKDF2_SALT_LENGTH) {
7
7
  const array = new Uint8Array(saltLength);
8
- return Buffer.from(crypto.getRandomValues(array)).toString('hex');
8
+ crypto.getRandomValues(array);
9
+ // Convert to hex string without using Buffer
10
+ return Array.from(array)
11
+ .map((b) => b.toString(16).padStart(2, '0'))
12
+ .join('');
9
13
  }
10
14
 
11
15
  export async function getDerivedKey(
@@ -30,7 +34,10 @@ export async function getDerivedKey(
30
34
  importedKey,
31
35
  keyLength,
32
36
  );
33
- return Buffer.from(bits).toString('hex');
37
+ // Convert ArrayBuffer to hex string without using Buffer
38
+ return Array.from(new Uint8Array(bits))
39
+ .map((b) => b.toString(16).padStart(2, '0'))
40
+ .join('');
34
41
  }
35
42
 
36
43
  export async function compare(password: string, hash: string, salt: string) {
@@ -7,7 +7,6 @@ import { User } from '../db/UsersCollection.js';
7
7
  describe('removeConfidentialServiceHashes', () => {
8
8
  it('Should remove sensitive user credentials ', () => {
9
9
  assert.notStrictEqual(user.services, undefined);
10
- removeConfidentialServiceHashes(user as unknown as User);
11
- assert.strictEqual(user.services, undefined);
10
+ assert.strictEqual(removeConfidentialServiceHashes(user as unknown as User)?.services, undefined);
12
11
  });
13
12
  });
@@ -1,22 +1,24 @@
1
1
  import { insensitiveTrimmedRegexOperator, mongodb } from '@unchainedshop/mongodb';
2
2
  import { User } from './db/UsersCollection.js';
3
-
4
3
  export interface UserRegistrationData extends Partial<User> {
5
4
  email?: string;
6
5
  password: string | null;
7
6
  webAuthnPublicKeyCredentials?: any;
8
7
  }
9
- export interface UserSettingsOptions {
10
- mergeUserCartsOnLogin?: boolean;
11
- autoMessagingAfterUserCreation?: boolean;
12
- validateEmail?: (email: string) => Promise<boolean>;
13
- validateUsername?: (username: string) => Promise<boolean>;
14
- validateNewUser?: (user: UserRegistrationData) => Promise<UserRegistrationData>;
15
- validatePassword?: (password: string) => Promise<boolean>;
8
+
9
+ export enum UserAccountAction {
10
+ RESET_PASSWORD = 'reset-password',
11
+ VERIFY_EMAIL = 'verify-email',
12
+ ENROLL_ACCOUNT = 'enroll-account',
13
+ PASSWORD_RESETTED = 'password-resetted',
14
+ EMAIL_VERIFIED = 'email-verified',
16
15
  }
17
16
  export interface UserSettings {
18
17
  mergeUserCartsOnLogin: boolean;
19
18
  autoMessagingAfterUserCreation: boolean;
19
+ earliestValidTokenDate: (
20
+ type: UserAccountAction.VERIFY_EMAIL | UserAccountAction.RESET_PASSWORD,
21
+ ) => Date;
20
22
  validateEmail: (email: string) => Promise<boolean>;
21
23
  validateUsername: (username: string) => Promise<boolean>;
22
24
  validateNewUser: (user: UserRegistrationData) => Promise<UserRegistrationData>;
@@ -24,28 +26,50 @@ export interface UserSettings {
24
26
  configureSettings: (options: UserSettingsOptions, db: mongodb.Db) => void;
25
27
  }
26
28
 
29
+ export type UserSettingsOptions = Omit<Partial<UserSettings>, 'configureSettings'>;
30
+
31
+ const defaultAutoMessagingAfterUserCreation = true;
32
+ const defaultMergeUserCartsOnLogin = true;
33
+
34
+ const defaultEarliestValidTokenDate = () => {
35
+ // 1 hour ago
36
+ return new Date(new Date().getTime() - 1000 * 60 * 60);
37
+ };
38
+
39
+ const defaultValidateNewUser = async (user: UserRegistrationData) => {
40
+ return {
41
+ ...user,
42
+ username: user.username?.trim().toLowerCase(),
43
+ email: user.email?.trim().toLowerCase(),
44
+ password: user.password ?? null,
45
+ };
46
+ };
47
+
48
+ const defaultValidatePassword = async (password: string) => {
49
+ return password?.length >= 8;
50
+ };
51
+
27
52
  export const userSettings: UserSettings = {
28
- autoMessagingAfterUserCreation: null,
29
- mergeUserCartsOnLogin: null,
30
- validateEmail: null,
31
- validateUsername: null,
32
- validateNewUser: null,
33
- validatePassword: null,
53
+ autoMessagingAfterUserCreation: defaultAutoMessagingAfterUserCreation,
54
+ mergeUserCartsOnLogin: defaultMergeUserCartsOnLogin,
55
+ earliestValidTokenDate: defaultEarliestValidTokenDate,
56
+ validateNewUser: defaultValidateNewUser,
57
+ validateEmail: () => Promise.resolve(true),
58
+ validateUsername: () => Promise.resolve(true),
59
+ validatePassword: () => Promise.resolve(true),
34
60
 
35
61
  configureSettings: (
36
62
  {
37
63
  mergeUserCartsOnLogin,
38
64
  autoMessagingAfterUserCreation,
65
+ earliestValidTokenDate,
39
66
  validateEmail,
40
67
  validateUsername,
41
68
  validateNewUser,
42
69
  validatePassword,
43
- }: UserSettingsOptions,
70
+ },
44
71
  db: mongodb.Db,
45
72
  ) => {
46
- const defaultAutoMessagingAfterUserCreation = true;
47
- const defaultMergeUserCartsOnLogin = true;
48
-
49
73
  const defaultValidateEmail = async (rawEmail: string) => {
50
74
  if (!rawEmail?.includes?.('@')) return false;
51
75
  const emailAlreadyExists = await db
@@ -62,22 +86,11 @@ export const userSettings: UserSettings = {
62
86
  if (usernameAlreadyExists) return false;
63
87
  return true;
64
88
  };
65
- const defaultValidateNewUser = async (user: UserRegistrationData) => {
66
- return {
67
- ...user,
68
- username: user.username?.trim().toLowerCase(),
69
- email: user.email?.trim().toLowerCase(),
70
- password: user.password ?? null,
71
- };
72
- };
73
-
74
- const defaultValidatePassword = async (password: string) => {
75
- return password?.length >= 8;
76
- };
77
89
 
78
90
  userSettings.mergeUserCartsOnLogin = mergeUserCartsOnLogin ?? defaultMergeUserCartsOnLogin;
79
91
  userSettings.autoMessagingAfterUserCreation =
80
92
  autoMessagingAfterUserCreation ?? defaultAutoMessagingAfterUserCreation;
93
+ userSettings.earliestValidTokenDate = earliestValidTokenDate || defaultEarliestValidTokenDate;
81
94
  userSettings.validateEmail = validateEmail || defaultValidateEmail;
82
95
  userSettings.validateUsername = validateUsername || defaultValidateUsername;
83
96
  userSettings.validateNewUser = validateNewUser || defaultValidateNewUser;
package/tsconfig.json CHANGED
@@ -3,7 +3,8 @@
3
3
  "compilerOptions": {
4
4
  "declarationDir": "./lib",
5
5
  "rootDir": "./src",
6
- "outDir": "./lib"
6
+ "outDir": "./lib",
7
+
7
8
  },
8
9
  "exclude": ["**/*.test.ts", "**/*.test.js", "tests", "lib"]
9
10
  }