@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.
- package/lib/db/UsersCollection.d.ts +2 -2
- package/lib/db/UsersCollection.d.ts.map +1 -1
- package/lib/db/UsersCollection.js +30 -26
- package/lib/db/UsersCollection.js.map +1 -1
- package/lib/module/configureUsersModule.d.ts +32 -31
- package/lib/module/configureUsersModule.d.ts.map +1 -1
- package/lib/module/configureUsersModule.js +81 -41
- package/lib/module/configureUsersModule.js.map +1 -1
- package/lib/module/configureUsersWebAuthnModule.d.ts +5 -5
- package/lib/module/configureUsersWebAuthnModule.d.ts.map +1 -1
- package/lib/module/configureUsersWebAuthnModule.js +9 -3
- package/lib/module/configureUsersWebAuthnModule.js.map +1 -1
- package/lib/module/pbkdf2.d.ts.map +1 -1
- package/lib/module/pbkdf2.js +9 -2
- package/lib/module/pbkdf2.js.map +1 -1
- package/lib/services/getUserCountryService.d.ts +3 -0
- package/lib/services/getUserCountryService.d.ts.map +1 -0
- package/lib/services/getUserCountryService.js +7 -0
- package/lib/services/getUserCountryService.js.map +1 -0
- package/lib/services/getUserLanguageService.d.ts +3 -0
- package/lib/services/getUserLanguageService.d.ts.map +1 -0
- package/lib/services/getUserLanguageService.js +7 -0
- package/lib/services/getUserLanguageService.js.map +1 -0
- package/lib/services/updateUserAvatarAfterUploadService.d.ts +3 -0
- package/lib/services/updateUserAvatarAfterUploadService.d.ts.map +1 -0
- package/lib/services/updateUserAvatarAfterUploadService.js +24 -0
- package/lib/services/updateUserAvatarAfterUploadService.js.map +1 -0
- package/lib/services/userServices.d.ts +3 -0
- package/lib/services/userServices.d.ts.map +1 -0
- package/lib/services/userServices.js +9 -0
- package/lib/services/userServices.js.map +1 -0
- package/lib/users-settings.d.ts +8 -7
- package/lib/users-settings.d.ts.map +1 -1
- package/lib/users-settings.js +34 -20
- package/lib/users-settings.js.map +1 -1
- package/package.json +10 -10
- package/src/db/UsersCollection.ts +33 -29
- package/src/module/buildFindSelector.test.ts +5 -2
- package/src/module/configureUsersModule.ts +126 -85
- package/src/module/configureUsersWebAuthnModule.ts +8 -8
- package/src/module/pbkdf2.ts +9 -2
- package/src/module/removeConfidentialServiceHashes.test.ts +1 -2
- package/src/users-settings.ts +43 -30
- package/tsconfig.json +2 -1
package/src/module/pbkdf2.ts
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
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
|
});
|
package/src/users-settings.ts
CHANGED
|
@@ -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
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
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:
|
|
29
|
-
mergeUserCartsOnLogin:
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
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
|
-
}
|
|
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;
|