@unchainedshop/core-users 4.0.0-rc.16 → 4.0.0-rc.17

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 (43) 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/addMigrations.d.ts +3 -0
  6. package/lib/module/addMigrations.d.ts.map +1 -0
  7. package/lib/module/addMigrations.js +48 -0
  8. package/lib/module/addMigrations.js.map +1 -0
  9. package/lib/module/configureUsersModule.d.ts +30 -30
  10. package/lib/module/configureUsersModule.d.ts.map +1 -1
  11. package/lib/module/configureUsersModule.js +63 -36
  12. package/lib/module/configureUsersModule.js.map +1 -1
  13. package/lib/module/configureUsersWebAuthnModule.d.ts +5 -5
  14. package/lib/module/configureUsersWebAuthnModule.d.ts.map +1 -1
  15. package/lib/module/configureUsersWebAuthnModule.js +5 -1
  16. package/lib/module/configureUsersWebAuthnModule.js.map +1 -1
  17. package/lib/services/getUserCountryService.d.ts +3 -0
  18. package/lib/services/getUserCountryService.d.ts.map +1 -0
  19. package/lib/services/getUserCountryService.js +7 -0
  20. package/lib/services/getUserCountryService.js.map +1 -0
  21. package/lib/services/getUserLanguageService.d.ts +3 -0
  22. package/lib/services/getUserLanguageService.d.ts.map +1 -0
  23. package/lib/services/getUserLanguageService.js +7 -0
  24. package/lib/services/getUserLanguageService.js.map +1 -0
  25. package/lib/services/updateUserAvatarAfterUploadService.d.ts +3 -0
  26. package/lib/services/updateUserAvatarAfterUploadService.d.ts.map +1 -0
  27. package/lib/services/updateUserAvatarAfterUploadService.js +24 -0
  28. package/lib/services/updateUserAvatarAfterUploadService.js.map +1 -0
  29. package/lib/services/userServices.d.ts +3 -0
  30. package/lib/services/userServices.d.ts.map +1 -0
  31. package/lib/services/userServices.js +9 -0
  32. package/lib/services/userServices.js.map +1 -0
  33. package/lib/users-settings.d.ts +1 -14
  34. package/lib/users-settings.d.ts.map +1 -1
  35. package/lib/users-settings.js +24 -24
  36. package/lib/users-settings.js.map +1 -1
  37. package/package.json +7 -7
  38. package/src/db/UsersCollection.ts +33 -29
  39. package/src/module/buildFindSelector.test.ts +13 -4
  40. package/src/module/configureUsersModule.ts +102 -80
  41. package/src/module/configureUsersWebAuthnModule.ts +4 -6
  42. package/src/users-settings.ts +31 -45
  43. package/tsconfig.json +2 -1
@@ -62,8 +62,8 @@ export const buildFindSelector = ({
62
62
  ...rest
63
63
  }: UserQuery) => {
64
64
  const selector: mongodb.Filter<User> = { ...rest };
65
- if (!includeDeleted) selector.deleted = null;
66
- if (!includeGuests) selector.guest = { $in: [false, null] };
65
+ if (!includeDeleted) selector.deleted = { $exists: false };
66
+ if (!includeGuests) selector.guest = { $ne: true };
67
67
  if (emailVerified === true) {
68
68
  selector['emails.verified'] = true;
69
69
  }
@@ -91,12 +91,13 @@ export const buildFindSelector = ({
91
91
  return selector;
92
92
  };
93
93
 
94
- export const configureUsersModule = async ({ db, options }: ModuleInput<UserSettingsOptions>) => {
94
+ export const configureUsersModule = async (moduleInput: ModuleInput<UserSettingsOptions>) => {
95
+ const { db, options } = moduleInput;
95
96
  userSettings.configureSettings(options || {}, db);
96
97
  registerEvents(USER_EVENTS);
97
98
  const Users = await UsersCollection(db);
98
99
 
99
- const webAuthn = await configureUsersWebAuthnModule({ db, options });
100
+ const webAuthn = await configureUsersWebAuthnModule(moduleInput);
100
101
 
101
102
  return {
102
103
  // Queries
@@ -106,17 +107,17 @@ export const configureUsersModule = async ({ db, options }: ModuleInput<UserSett
106
107
  return userCount;
107
108
  },
108
109
 
109
- async findUserById(userId: string): Promise<User> {
110
+ async findUserById(userId: string) {
110
111
  if (!userId) return null;
111
112
  return Users.findOne(generateDbFilterById(userId), {});
112
113
  },
113
114
 
114
- async findUserByUsername(username: string): Promise<User> {
115
+ async findUserByUsername(username: string) {
115
116
  if (!username) return null;
116
117
  return Users.findOne({ username: insensitiveTrimmedRegexOperator(username) }, {});
117
118
  },
118
119
 
119
- async findUserByEmail(email: string): Promise<User> {
120
+ async findUserByEmail(email: string) {
120
121
  if (!email) return null;
121
122
  return Users.findOne({ 'emails.address': insensitiveTrimmedRegexOperator(email) }, {});
122
123
  },
@@ -125,7 +126,7 @@ export const configureUsersModule = async ({ db, options }: ModuleInput<UserSett
125
126
  userId: string;
126
127
  address: string;
127
128
  when: Date;
128
- }> {
129
+ } | null> {
129
130
  if (!plainToken) return null;
130
131
  const token = await sha256(plainToken);
131
132
  const user = await Users.findOne(
@@ -178,7 +179,7 @@ export const configureUsersModule = async ({ db, options }: ModuleInput<UserSett
178
179
  userId: string;
179
180
  address: string;
180
181
  when: Date;
181
- }> {
182
+ } | null> {
182
183
  const token = await sha256(plainToken);
183
184
  const user = await Users.findOne(
184
185
  {
@@ -199,7 +200,7 @@ export const configureUsersModule = async ({ db, options }: ModuleInput<UserSett
199
200
  };
200
201
  },
201
202
 
202
- async findUserByToken(plainToken: string): Promise<User> {
203
+ async findUserByToken(plainToken: string) {
203
204
  const token = await sha256(plainToken);
204
205
 
205
206
  if (token) {
@@ -211,10 +212,7 @@ export const configureUsersModule = async ({ db, options }: ModuleInput<UserSett
211
212
  return null;
212
213
  },
213
214
 
214
- async findUser(
215
- query: UserQuery & { sort?: SortOption[] },
216
- findOptions?: mongodb.FindOptions,
217
- ): Promise<User> {
215
+ async findUser(query: UserQuery & { sort?: SortOption[] }, findOptions?: mongodb.FindOptions) {
218
216
  const selector = buildFindSelector(query);
219
217
  return Users.findOne(selector, findOptions);
220
218
  },
@@ -248,7 +246,10 @@ export const configureUsersModule = async ({ db, options }: ModuleInput<UserSett
248
246
  },
249
247
 
250
248
  async userExists({ userId }: { userId: string }): Promise<boolean> {
251
- const userCount = await Users.countDocuments({ _id: userId, deleted: null }, { limit: 1 });
249
+ const userCount = await Users.countDocuments(
250
+ { _id: userId, deleted: { $exists: false } },
251
+ { limit: 1 },
252
+ );
252
253
  return userCount === 1;
253
254
  },
254
255
 
@@ -259,7 +260,7 @@ export const configureUsersModule = async ({ db, options }: ModuleInput<UserSett
259
260
  )?.[0];
260
261
  },
261
262
 
262
- userLocale(user: User): Intl.Locale {
263
+ userLocale(user: User | null): Intl.Locale {
263
264
  if (!user?.lastLogin?.locale) return systemLocale;
264
265
  try {
265
266
  return new Intl.Locale(user.lastLogin.locale);
@@ -348,7 +349,7 @@ export const configureUsersModule = async ({ db, options }: ModuleInput<UserSett
348
349
  /* */
349
350
  }
350
351
 
351
- const user = await Users.findOne({ _id: userId }, {});
352
+ const user = (await Users.findOne({ _id: userId }, {})) as User;
352
353
  await emit('USER_CREATE', {
353
354
  user: removeConfidentialServiceHashes(user),
354
355
  });
@@ -457,39 +458,46 @@ export const configureUsersModule = async ({ db, options }: ModuleInput<UserSett
457
458
  });
458
459
  },
459
460
 
460
- addRoles: async (userId: string, roles: string[]): Promise<number> => {
461
+ addRoles: async (userId: string, roles: string[]) => {
461
462
  const selector = generateDbFilterById(userId);
462
- const updateResult = await Users.updateOne(selector, {
463
- $addToSet: { roles: { $each: roles } },
464
- });
463
+ const user = await Users.findOneAndUpdate(
464
+ selector,
465
+ {
466
+ $addToSet: { roles: { $each: roles } },
467
+ },
468
+ { returnDocument: 'after' },
469
+ );
470
+
471
+ if (!user) return null;
465
472
 
466
- const user = await Users.findOne(selector, {});
467
473
  await emit('USER_ADD_ROLES', {
468
474
  user: removeConfidentialServiceHashes(user),
469
475
  });
470
476
 
471
- return updateResult.modifiedCount;
477
+ return user;
472
478
  },
473
479
 
474
480
  async setUsername(userId: string, username: string) {
475
481
  if (!(await userSettings.validateUsername(username))) {
476
482
  throw new Error(`Username ${username} is invalid`, { cause: 'USERNAME_INVALID' });
477
483
  }
478
- await Users.updateOne(
484
+ const user = await Users.findOneAndUpdate(
479
485
  { _id: userId },
480
486
  {
481
487
  $set: {
482
488
  username: username.trim(),
483
489
  },
484
490
  },
491
+ { returnDocument: 'after' },
485
492
  );
486
- const user = await Users.findOne({ _id: userId }, {});
493
+ if (!user) return null;
487
494
  await emit('USER_UPDATE_USERNAME', {
488
495
  user: removeConfidentialServiceHashes(user),
489
496
  });
497
+ return user;
490
498
  },
491
499
 
492
- async setPassword(userId: string, plainPassword: string): Promise<User> {
500
+ async setPassword(userId: string, plainPassword: string) {
493
501
  if (!(await userSettings.validatePassword(plainPassword))) {
494
502
  throw new Error(`Password ***** is invalid`, { cause: 'PASSWORD_INVALID' });
495
503
  }
@@ -506,13 +514,14 @@ export const configureUsersModule = async ({ db, options }: ModuleInput<UserSett
506
514
  },
507
515
  { returnDocument: 'after' },
508
516
  );
517
+ if (!user) return null;
509
518
  await emit('USER_UPDATE_PASSWORD', {
510
519
  user: removeConfidentialServiceHashes(user),
511
520
  });
512
521
  return user;
513
522
  },
514
523
 
515
- async resetPassword(token: string, newPassword: string): Promise<User> {
524
+ async resetPassword(token: string, newPassword: string) {
516
525
  const resetToken = await this.findResetToken(token);
517
526
  if (!resetToken) return null;
518
527
  const updatedUser = await this.setPassword(resetToken.userId, newPassword);
@@ -540,7 +549,7 @@ export const configureUsersModule = async ({ db, options }: ModuleInput<UserSett
540
549
  return updatedUser;
541
550
  },
542
551
 
543
- updateAvatar: async (_id: string, fileId: string): Promise<User> => {
552
+ updateAvatar: async (_id: string, fileId: string) => {
544
553
  const userFilter = generateDbFilterById(_id);
545
554
  const modifier = {
546
555
  $set: {
@@ -553,44 +562,54 @@ export const configureUsersModule = async ({ db, options }: ModuleInput<UserSett
553
562
  returnDocument: 'after',
554
563
  });
555
564
 
565
+ if (!user) return null;
556
566
  await emit('USER_UPDATE_AVATAR', {
557
567
  user: removeConfidentialServiceHashes(user),
558
568
  });
559
569
  return user;
560
570
  },
561
571
 
562
- updateGuest: async (user: User, guest: boolean): Promise<void> => {
563
- const modifier = { $set: { guest } };
564
- await Users.updateOne(generateDbFilterById(user._id), modifier);
572
+ updateGuest: async (user: User, guest: boolean) => {
573
+ const updatedUser = await Users.findOneAndUpdate(
574
+ generateDbFilterById(user._id),
575
+ {
576
+ $set: { guest },
577
+ },
578
+ { returnDocument: 'after' },
579
+ );
580
+ if (!updatedUser) return null;
565
581
  await emit('USER_UPDATE_GUEST', {
566
582
  user: removeConfidentialServiceHashes({
567
- ...user,
583
+ ...updatedUser,
568
584
  guest,
569
585
  }),
570
586
  });
587
+ return updatedUser;
571
588
  },
572
589
 
573
- updateHeartbeat: async (userId: string, lastLogin: UserLastLogin): Promise<User> => {
574
- const modifier = {
575
- $set: {
576
- lastLogin: {
577
- timestamp: new Date(),
578
- ...lastLogin,
590
+ updateHeartbeat: async (userId: string, lastLogin: UserLastLogin) => {
591
+ const user = await Users.findOneAndUpdate(
592
+ generateDbFilterById(userId),
593
+ {
594
+ $set: {
595
+ lastLogin: {
596
+ timestamp: new Date(),
597
+ ...lastLogin,
598
+ },
579
599
  },
580
600
  },
581
- };
582
-
583
- const user = await Users.findOneAndUpdate(generateDbFilterById(userId), modifier, {
584
- returnDocument: 'after',
585
- });
586
-
601
+ {
602
+ returnDocument: 'after',
603
+ },
604
+ );
605
+ if (!user) return null;
587
606
  await emit('USER_UPDATE_HEARTBEAT', {
588
607
  user: removeConfidentialServiceHashes(user),
589
608
  });
590
609
  return user;
591
610
  },
592
611
 
593
- markDeleted: async (userId: string): Promise<User> => {
612
+ markDeleted: async (userId: string) => {
594
613
  await db.collection('sessions').deleteMany({
595
614
  session: insensitiveTrimmedRegexOperator(`"user":"${userId}"`),
596
615
  });
@@ -602,18 +621,21 @@ export const configureUsersModule = async ({ db, options }: ModuleInput<UserSett
602
621
  deleted: new Date(),
603
622
  emails: [],
604
623
  roles: [],
605
- profile: null,
606
- lastBillingAddress: null,
607
624
  services: {},
608
625
  pushSubscriptions: [],
609
- avatarId: null,
610
626
  initialPassword: false,
611
- lastContact: null,
612
- lastLogin: null,
627
+ },
628
+ $unset: {
629
+ profile: 1,
630
+ lastBillingAddress: 1,
631
+ lastContact: 1,
632
+ lastLogin: 1,
633
+ avatarId: 1,
613
634
  },
614
635
  },
615
636
  { returnDocument: 'after' },
616
637
  );
638
+ if (!user) return null;
617
639
 
618
640
  await emit('USER_REMOVE', {
619
641
  user,
@@ -621,14 +643,11 @@ export const configureUsersModule = async ({ db, options }: ModuleInput<UserSett
621
643
  return user;
622
644
  },
623
645
 
624
- deletePermanently: async ({ userId }: { userId: string }): Promise<User> => {
646
+ deletePermanently: async ({ userId }: { userId: string }) => {
625
647
  return Users.findOneAndDelete({ _id: userId });
626
648
  },
627
649
 
628
- updateProfile: async (
629
- userId: string,
630
- updatedData: { profile?: UserProfile; meta?: any },
631
- ): Promise<User> => {
650
+ updateProfile: async (userId: string, updatedData: { profile?: UserProfile; meta?: any }) => {
632
651
  const userFilter = generateDbFilterById(userId);
633
652
  const { meta, profile } = updatedData;
634
653
 
@@ -657,16 +676,17 @@ export const configureUsersModule = async ({ db, options }: ModuleInput<UserSett
657
676
  returnDocument: 'after',
658
677
  });
659
678
 
679
+ if (!user) return null;
660
680
  await emit('USER_UPDATE_PROFILE', {
661
681
  user: removeConfidentialServiceHashes(user),
662
682
  });
663
683
  return user;
664
684
  },
665
685
 
666
- updateLastBillingAddress: async (_id: string, lastBillingAddress: Address): Promise<User> => {
686
+ updateLastBillingAddress: async (_id: string, lastBillingAddress: Address) => {
667
687
  const userFilter = generateDbFilterById(_id);
668
688
  const user = await Users.findOne(userFilter, {});
669
-
689
+ if (!user) return null;
670
690
  if (!lastBillingAddress) return user;
671
691
 
672
692
  const modifier = {
@@ -691,18 +711,17 @@ export const configureUsersModule = async ({ db, options }: ModuleInput<UserSett
691
711
  returnDocument: 'after',
692
712
  });
693
713
 
694
- if (updatedUser) {
695
- await emit('USER_UPDATE_BILLING_ADDRESS', {
696
- user: removeConfidentialServiceHashes(updatedUser),
697
- });
698
- }
699
-
714
+ if (!updatedUser) return null;
715
+ await emit('USER_UPDATE_BILLING_ADDRESS', {
716
+ user: removeConfidentialServiceHashes(updatedUser),
717
+ });
700
718
  return updatedUser;
701
719
  },
702
720
 
703
- updateLastContact: async (_id: string, lastContact: Contact): Promise<User> => {
721
+ updateLastContact: async (_id: string, lastContact: Contact) => {
704
722
  const userFilter = generateDbFilterById(_id);
705
723
  const user = await Users.findOne(userFilter, {});
724
+ if (!user) return null;
706
725
  const profile = user.profile || {};
707
726
  const isGuest = !!user.guest;
708
727
 
@@ -722,13 +741,14 @@ export const configureUsersModule = async ({ db, options }: ModuleInput<UserSett
722
741
  returnDocument: 'after',
723
742
  });
724
743
 
744
+ if (!updatedUser) return null;
725
745
  await emit('USER_UPDATE_LAST_CONTACT', {
726
746
  user: removeConfidentialServiceHashes(user),
727
747
  });
728
748
  return updatedUser;
729
749
  },
730
750
 
731
- updateRoles: async (_id: string, roles: string[]): Promise<User> => {
751
+ updateRoles: async (_id: string, roles: string[]) => {
732
752
  const modifier = {
733
753
  $set: {
734
754
  updated: new Date(),
@@ -739,23 +759,27 @@ export const configureUsersModule = async ({ db, options }: ModuleInput<UserSett
739
759
  const user = await Users.findOneAndUpdate(generateDbFilterById(_id), modifier, {
740
760
  returnDocument: 'after',
741
761
  });
742
-
762
+ if (!user) return null;
743
763
  await emit('USER_UPDATE_ROLE', {
744
764
  user: removeConfidentialServiceHashes(user),
745
765
  });
746
766
  return user;
747
767
  },
748
768
 
749
- updateTags: async (_id: string, tags: string[]): Promise<User> => {
750
- const modifier = {
751
- $set: {
752
- updated: new Date(),
753
- tags,
769
+ updateTags: async (_id: string, tags: string[]) => {
770
+ const user = await Users.findOneAndUpdate(
771
+ generateDbFilterById(_id),
772
+ {
773
+ $set: {
774
+ updated: new Date(),
775
+ tags,
776
+ },
754
777
  },
755
- };
756
- const user = await Users.findOneAndUpdate(generateDbFilterById(_id), modifier, {
757
- returnDocument: 'after',
758
- });
778
+ {
779
+ returnDocument: 'after',
780
+ },
781
+ );
782
+ if (!user) return null;
759
783
  await emit('USER_UPDATE_TAGS', {
760
784
  user: removeConfidentialServiceHashes(user),
761
785
  });
@@ -766,11 +790,12 @@ export const configureUsersModule = async ({ db, options }: ModuleInput<UserSett
766
790
  selector: mongodb.Filter<User>,
767
791
  modifier: mongodb.UpdateFilter<User>,
768
792
  updateOptions?: mongodb.FindOneAndUpdateOptions,
769
- ): Promise<User> => {
793
+ ) => {
770
794
  const user = await Users.findOneAndUpdate(selector, modifier, {
771
795
  ...updateOptions,
772
796
  returnDocument: 'after',
773
797
  });
798
+ if (!user) return null;
774
799
  await emit('USER_UPDATE', {
775
800
  user: removeConfidentialServiceHashes(user),
776
801
  });
@@ -825,10 +850,7 @@ export const configureUsersModule = async ({ db, options }: ModuleInput<UserSett
825
850
  tags: { $exists: true },
826
851
  deleted: { $exists: false },
827
852
  })) as string[];
828
- return tags
829
- .filter(Boolean)
830
- .map((t) => t.trim())
831
- .filter(Boolean);
853
+ return tags.filter(Boolean).toSorted();
832
854
  },
833
855
  };
834
856
  };
@@ -6,7 +6,7 @@ import type { PublicKeyCredentialCreationOptions, PublicKeyCredentialRequestOpti
6
6
 
7
7
  const logger = createLogger('unchained:core-users');
8
8
 
9
- const { ROOT_URL, EMAIL_WEBSITE_NAME } = process.env;
9
+ const { ROOT_URL = 'http://localhost:4010', EMAIL_WEBSITE_NAME = 'Unchained' } = process.env;
10
10
 
11
11
  type SerializedOptions<T> = Omit<T, 'challenge' | 'requestId'> & {
12
12
  challenge: string;
@@ -103,11 +103,7 @@ export const configureUsersWebAuthnModule = async ({ db }: ModuleInput<any>) =>
103
103
  } as SerializedOptions<PublicKeyCredentialCreationOptions>;
104
104
  },
105
105
 
106
- createCredentialRequestOptions: async (
107
- origin: string,
108
- username?: string,
109
- extensionOptions?: any,
110
- ) => {
106
+ createCredentialRequestOptions: async (origin: string, username: string, extensionOptions?: any) => {
111
107
  if (!f2l) return null;
112
108
 
113
109
  const loginOptions = await f2l.assertionOptions(extensionOptions);
@@ -137,6 +133,7 @@ export const configureUsersWebAuthnModule = async ({ db }: ModuleInput<any>) =>
137
133
  },
138
134
  { sort: { _id: -1 } },
139
135
  );
136
+ if (!request) return null;
140
137
 
141
138
  const attestationExpectations = {
142
139
  challenge: request.challenge,
@@ -186,6 +183,7 @@ export const configureUsersWebAuthnModule = async ({ db }: ModuleInput<any>) =>
186
183
  },
187
184
  { sort: { _id: -1 } },
188
185
  );
186
+ if (!request) return null;
189
187
 
190
188
  const id = Buffer.from(credentials.id, 'base64');
191
189
  const authenticatorData = Buffer.from(credentials.response.authenticatorData, 'base64');
@@ -1,6 +1,5 @@
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;
@@ -14,22 +13,6 @@ export enum UserAccountAction {
14
13
  PASSWORD_RESETTED = 'password-resetted',
15
14
  EMAIL_VERIFIED = 'email-verified',
16
15
  }
17
- export interface UserSettingsOptions {
18
- mergeUserCartsOnLogin?: boolean;
19
- autoMessagingAfterUserCreation?: boolean;
20
- /**
21
- * Function to calculate the earliest valid token date. Defaults to 1h if not set.
22
- * @param type The type of user account action.
23
- * @returns A date. All tokens created after that date are considered valid.
24
- */
25
- earliestValidTokenDate?: (
26
- type: UserAccountAction.VERIFY_EMAIL | UserAccountAction.RESET_PASSWORD,
27
- ) => Date;
28
- validateEmail?: (email: string) => Promise<boolean>;
29
- validateUsername?: (username: string) => Promise<boolean>;
30
- validateNewUser?: (user: UserRegistrationData) => Promise<UserRegistrationData>;
31
- validatePassword?: (password: string) => Promise<boolean>;
32
- }
33
16
  export interface UserSettings {
34
17
  mergeUserCartsOnLogin: boolean;
35
18
  autoMessagingAfterUserCreation: boolean;
@@ -43,14 +26,37 @@ export interface UserSettings {
43
26
  configureSettings: (options: UserSettingsOptions, db: mongodb.Db) => void;
44
27
  }
45
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
+
46
52
  export const userSettings: UserSettings = {
47
- autoMessagingAfterUserCreation: null,
48
- mergeUserCartsOnLogin: null,
49
- earliestValidTokenDate: null,
50
- validateEmail: null,
51
- validateUsername: null,
52
- validateNewUser: null,
53
- 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),
54
60
 
55
61
  configureSettings: (
56
62
  {
@@ -61,17 +67,9 @@ export const userSettings: UserSettings = {
61
67
  validateUsername,
62
68
  validateNewUser,
63
69
  validatePassword,
64
- }: UserSettingsOptions,
70
+ },
65
71
  db: mongodb.Db,
66
72
  ) => {
67
- const defaultAutoMessagingAfterUserCreation = true;
68
- const defaultMergeUserCartsOnLogin = true;
69
-
70
- const defaultEarliestValidTokenDate = () => {
71
- // 1 hour ago
72
- return new Date(new Date().getTime() - 1000 * 60 * 60);
73
- };
74
-
75
73
  const defaultValidateEmail = async (rawEmail: string) => {
76
74
  if (!rawEmail?.includes?.('@')) return false;
77
75
  const emailAlreadyExists = await db
@@ -88,18 +86,6 @@ export const userSettings: UserSettings = {
88
86
  if (usernameAlreadyExists) return false;
89
87
  return true;
90
88
  };
91
- const defaultValidateNewUser = async (user: UserRegistrationData) => {
92
- return {
93
- ...user,
94
- username: user.username?.trim().toLowerCase(),
95
- email: user.email?.trim().toLowerCase(),
96
- password: user.password ?? null,
97
- };
98
- };
99
-
100
- const defaultValidatePassword = async (password: string) => {
101
- return password?.length >= 8;
102
- };
103
89
 
104
90
  userSettings.mergeUserCartsOnLogin = mergeUserCartsOnLogin ?? defaultMergeUserCartsOnLogin;
105
91
  userSettings.autoMessagingAfterUserCreation =
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
  }