@unchainedshop/core-users 4.8.16 → 4.8.18
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.
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { normalizePhoneNumber } from '@unchainedshop/utils';
|
|
2
|
+
import { UsersCollection } from "../db/UsersCollection.js";
|
|
3
|
+
export default function normalizeProfilePhone(repository) {
|
|
4
|
+
repository?.register({
|
|
5
|
+
id: 20260625120200,
|
|
6
|
+
name: 'Normalize user.profile.phoneMobile and user.lastContact.telNumber to E.164 format',
|
|
7
|
+
up: async ({ logger }) => {
|
|
8
|
+
const Users = await UsersCollection(repository.db);
|
|
9
|
+
const users = await Users.find({
|
|
10
|
+
$or: [
|
|
11
|
+
{ 'profile.phoneMobile': { $exists: true, $nin: [null, ''] } },
|
|
12
|
+
{ 'lastContact.telNumber': { $exists: true, $nin: [null, ''] } },
|
|
13
|
+
],
|
|
14
|
+
}, {
|
|
15
|
+
projection: {
|
|
16
|
+
_id: true,
|
|
17
|
+
profile: true,
|
|
18
|
+
lastContact: true,
|
|
19
|
+
lastBillingAddress: true,
|
|
20
|
+
lastLogin: true,
|
|
21
|
+
},
|
|
22
|
+
}).toArray();
|
|
23
|
+
let changed = 0;
|
|
24
|
+
let skipped = 0;
|
|
25
|
+
for (const user of users) {
|
|
26
|
+
const defaultCountry = user.lastBillingAddress?.countryCode ||
|
|
27
|
+
user.profile?.address?.countryCode ||
|
|
28
|
+
user.lastLogin?.countryCode;
|
|
29
|
+
const $set = {};
|
|
30
|
+
const phoneMobile = user.profile?.phoneMobile;
|
|
31
|
+
const normalizedPhoneMobile = normalizePhoneNumber(phoneMobile, defaultCountry);
|
|
32
|
+
if (normalizedPhoneMobile && normalizedPhoneMobile !== phoneMobile) {
|
|
33
|
+
$set['profile.phoneMobile'] = normalizedPhoneMobile;
|
|
34
|
+
}
|
|
35
|
+
const telNumber = user.lastContact?.telNumber;
|
|
36
|
+
const normalizedTelNumber = normalizePhoneNumber(telNumber, defaultCountry);
|
|
37
|
+
if (normalizedTelNumber && normalizedTelNumber !== telNumber) {
|
|
38
|
+
$set['lastContact.telNumber'] = normalizedTelNumber;
|
|
39
|
+
}
|
|
40
|
+
if (Object.keys($set).length === 0) {
|
|
41
|
+
if ((phoneMobile && !normalizedPhoneMobile) || (telNumber && !normalizedTelNumber)) {
|
|
42
|
+
skipped += 1;
|
|
43
|
+
}
|
|
44
|
+
continue;
|
|
45
|
+
}
|
|
46
|
+
await Users.updateOne({ _id: user._id }, { $set });
|
|
47
|
+
changed += 1;
|
|
48
|
+
}
|
|
49
|
+
logger?.info(`Normalize user phone numbers: ${changed} updated, ${skipped} left unchanged (unparseable)`);
|
|
50
|
+
},
|
|
51
|
+
});
|
|
52
|
+
}
|
|
@@ -2,12 +2,13 @@ import * as bcrypt from 'bcryptjs';
|
|
|
2
2
|
import { generateDbFilterById, buildSortOptions, generateDbObjectId, insensitiveTrimmedRegexOperator, escapeRegexString, } from '@unchainedshop/mongodb';
|
|
3
3
|
import { UsersCollection, } from "../db/UsersCollection.js";
|
|
4
4
|
import { emit, registerEvents } from '@unchainedshop/events';
|
|
5
|
-
import { systemLocale, SortDirection, sha256 } from '@unchainedshop/utils';
|
|
5
|
+
import { systemLocale, SortDirection, sha256, normalizePhoneNumber, } from '@unchainedshop/utils';
|
|
6
6
|
import { UserAccountAction, userSettings, } from "../users-settings.js";
|
|
7
7
|
import { configureUsersWebAuthnModule } from "./configureUsersWebAuthnModule.js";
|
|
8
8
|
import * as pbkdf2 from "./pbkdf2.js";
|
|
9
9
|
import { verifyWeb3Signature } from "../utils/web3-verification.js";
|
|
10
10
|
import convertUserLocale from "../migrations/20241218092300-convert-locale.js";
|
|
11
|
+
import normalizeProfilePhone from "../migrations/20260625120200-normalize-profile-phone.js";
|
|
11
12
|
const USER_EVENTS = [
|
|
12
13
|
'USER_ACCOUNT_ACTION',
|
|
13
14
|
'USER_CREATE',
|
|
@@ -82,6 +83,7 @@ export const buildFindSelector = ({ includeGuests, includeDeleted, queryString,
|
|
|
82
83
|
export const configureUsersModule = async (moduleInput) => {
|
|
83
84
|
const { db, options, migrationRepository } = moduleInput;
|
|
84
85
|
convertUserLocale(migrationRepository);
|
|
86
|
+
normalizeProfilePhone(migrationRepository);
|
|
85
87
|
userSettings.configureSettings(options || {}, db);
|
|
86
88
|
registerEvents(USER_EVENTS);
|
|
87
89
|
const Users = await UsersCollection(db);
|
|
@@ -202,14 +204,9 @@ export const configureUsersModule = async (moduleInput) => {
|
|
|
202
204
|
guest: true,
|
|
203
205
|
deleted: null,
|
|
204
206
|
created: { $lte: before },
|
|
205
|
-
$
|
|
206
|
-
{
|
|
207
|
-
|
|
208
|
-
{ 'lastLogin.timestamp': { $exists: false } },
|
|
209
|
-
{ 'lastLogin.timestamp': { $lte: before } },
|
|
210
|
-
],
|
|
211
|
-
},
|
|
212
|
-
{ $or: [{ updated: { $exists: false } }, { updated: { $lte: before } }] },
|
|
207
|
+
$or: [
|
|
208
|
+
{ 'lastLogin.timestamp': { $exists: false } },
|
|
209
|
+
{ 'lastLogin.timestamp': { $lte: before } },
|
|
213
210
|
],
|
|
214
211
|
}, { projection: { _id: 1 } }).toArray();
|
|
215
212
|
return users.map((u) => u._id);
|
|
@@ -647,11 +644,28 @@ export const configureUsersModule = async (moduleInput) => {
|
|
|
647
644
|
return Users.findOne(userFilter, {});
|
|
648
645
|
}
|
|
649
646
|
const modifier = { $set: {} };
|
|
650
|
-
|
|
651
|
-
|
|
647
|
+
let normalizedProfile = profile;
|
|
648
|
+
if (profile?.phoneMobile) {
|
|
649
|
+
let defaultCountry = profile.address?.countryCode;
|
|
650
|
+
if (!defaultCountry) {
|
|
651
|
+
const existing = await Users.findOne(userFilter, {
|
|
652
|
+
projection: { lastBillingAddress: true, profile: true, lastLogin: true },
|
|
653
|
+
});
|
|
654
|
+
defaultCountry =
|
|
655
|
+
existing?.lastBillingAddress?.countryCode ||
|
|
656
|
+
existing?.profile?.address?.countryCode ||
|
|
657
|
+
existing?.lastLogin?.countryCode;
|
|
658
|
+
}
|
|
659
|
+
normalizedProfile = {
|
|
660
|
+
...profile,
|
|
661
|
+
phoneMobile: normalizePhoneNumber(profile.phoneMobile, defaultCountry) || profile.phoneMobile,
|
|
662
|
+
};
|
|
663
|
+
}
|
|
664
|
+
if (normalizedProfile) {
|
|
665
|
+
modifier.$set = Object.keys(normalizedProfile).reduce((acc, profileKey) => {
|
|
652
666
|
return {
|
|
653
667
|
...acc,
|
|
654
|
-
[`profile.${profileKey}`]:
|
|
668
|
+
[`profile.${profileKey}`]: normalizedProfile[profileKey],
|
|
655
669
|
};
|
|
656
670
|
}, {});
|
|
657
671
|
}
|
|
@@ -708,14 +722,23 @@ export const configureUsersModule = async (moduleInput) => {
|
|
|
708
722
|
return null;
|
|
709
723
|
const profile = user.profile || {};
|
|
710
724
|
const isGuest = !!user.guest;
|
|
725
|
+
const defaultCountry = user.lastBillingAddress?.countryCode ||
|
|
726
|
+
profile.address?.countryCode ||
|
|
727
|
+
user.lastLogin?.countryCode;
|
|
728
|
+
const normalizedContact = lastContact?.telNumber
|
|
729
|
+
? {
|
|
730
|
+
...lastContact,
|
|
731
|
+
telNumber: normalizePhoneNumber(lastContact.telNumber, defaultCountry) || lastContact.telNumber,
|
|
732
|
+
}
|
|
733
|
+
: lastContact;
|
|
711
734
|
const modifier = {
|
|
712
735
|
$set: {
|
|
713
736
|
updated: new Date(),
|
|
714
|
-
lastContact,
|
|
737
|
+
lastContact: normalizedContact,
|
|
715
738
|
},
|
|
716
739
|
};
|
|
717
|
-
if ((!profile.phoneMobile || isGuest) &&
|
|
718
|
-
modifier.$set['profile.phoneMobile'] =
|
|
740
|
+
if ((!profile.phoneMobile || isGuest) && normalizedContact.telNumber) {
|
|
741
|
+
modifier.$set['profile.phoneMobile'] = normalizedContact.telNumber;
|
|
719
742
|
}
|
|
720
743
|
const updatedUser = await Users.findOneAndUpdate(userFilter, modifier, {
|
|
721
744
|
returnDocument: 'after',
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@unchainedshop/core-users",
|
|
3
3
|
"description": "User management module for the Unchained Engine with authentication support",
|
|
4
|
-
"version": "4.8.
|
|
4
|
+
"version": "4.8.18",
|
|
5
5
|
"main": "lib/users-index.js",
|
|
6
6
|
"types": "lib/users-index.d.ts",
|
|
7
7
|
"type": "module",
|