@unchainedshop/core-users 3.0.0-alpha2 → 3.0.0-alpha3

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 (59) hide show
  1. package/lib/db/UsersCollection.d.ts +1 -1
  2. package/lib/db/UsersCollection.d.ts.map +1 -1
  3. package/lib/db/WebAuthnCredentialsCreationRequestsCollection.d.ts +1 -1
  4. package/lib/db/WebAuthnCredentialsCreationRequestsCollection.d.ts.map +1 -1
  5. package/lib/module/addMigrations.d.ts +1 -1
  6. package/lib/module/addMigrations.d.ts.map +1 -1
  7. package/lib/module/configureUsersModule.d.ts +66 -27
  8. package/lib/module/configureUsersModule.d.ts.map +1 -1
  9. package/lib/module/configureUsersModule.js +3 -5
  10. package/lib/module/configureUsersModule.js.map +1 -1
  11. package/lib/module/configureUsersWebAuthnModule.d.ts +9 -22
  12. package/lib/module/configureUsersWebAuthnModule.d.ts.map +1 -1
  13. package/lib/module/configureUsersWebAuthnModule.js +1 -1
  14. package/lib/module/configureUsersWebAuthnModule.js.map +1 -1
  15. package/lib/services/migrateUserDataService.d.ts +2 -1
  16. package/lib/services/migrateUserDataService.d.ts.map +1 -1
  17. package/lib/services/migrateUserDataService.js.map +1 -1
  18. package/lib/services/updateUserAvatarAfterUploadService.d.ts +5 -1
  19. package/lib/services/updateUserAvatarAfterUploadService.d.ts.map +1 -1
  20. package/lib/services/updateUserAvatarAfterUploadService.js.map +1 -1
  21. package/lib/services/userServices.d.ts +7 -6
  22. package/lib/services/userServices.d.ts.map +1 -1
  23. package/lib/services/userServices.js +1 -5
  24. package/lib/services/userServices.js.map +1 -1
  25. package/lib/types.d.ts +88 -0
  26. package/lib/types.d.ts.map +1 -0
  27. package/lib/types.js +2 -0
  28. package/lib/types.js.map +1 -0
  29. package/lib/users-index.d.ts +4 -3
  30. package/lib/users-index.d.ts.map +1 -1
  31. package/lib/users-index.js +4 -3
  32. package/lib/users-index.js.map +1 -1
  33. package/lib/users-settings.d.ts +19 -1
  34. package/lib/users-settings.d.ts.map +1 -1
  35. package/lib/users-settings.js +1 -4
  36. package/lib/users-settings.js.map +1 -1
  37. package/package.json +9 -12
  38. package/src/db/UsersCollection.ts +1 -1
  39. package/src/db/WebAuthnCredentialsCreationRequestsCollection.ts +1 -1
  40. package/src/module/addMigrations.ts +1 -1
  41. package/src/module/configureUsersModule.ts +83 -20
  42. package/src/module/configureUsersWebAuthnModule.ts +22 -2
  43. package/src/module/removeConfidentialServiceHashes.test.ts +1 -1
  44. package/src/services/migrateUserDataService.ts +7 -1
  45. package/src/services/updateUserAvatarAfterUploadService.ts +7 -1
  46. package/src/services/userServices.ts +11 -7
  47. package/src/types.ts +101 -0
  48. package/src/users-index.ts +4 -4
  49. package/src/users-settings.ts +20 -13
  50. package/lib/services/getUserCountryService.d.ts +0 -3
  51. package/lib/services/getUserCountryService.d.ts.map +0 -1
  52. package/lib/services/getUserCountryService.js +0 -7
  53. package/lib/services/getUserCountryService.js.map +0 -1
  54. package/lib/services/getUserLanguageService.d.ts +0 -3
  55. package/lib/services/getUserLanguageService.d.ts.map +0 -1
  56. package/lib/services/getUserLanguageService.js +0 -7
  57. package/lib/services/getUserLanguageService.js.map +0 -1
  58. package/src/services/getUserCountryService.ts +0 -8
  59. package/src/services/getUserLanguageService.ts +0 -8
@@ -1,3 +1,21 @@
1
- import { UserSettings } from '@unchainedshop/types/user.js';
1
+ import { User } from './types.js';
2
+ import { mongodb } from '@unchainedshop/mongodb';
3
+ export interface UserSettingsOptions {
4
+ mergeUserCartsOnLogin?: boolean;
5
+ autoMessagingAfterUserCreation?: boolean;
6
+ validateEmail?: (email: string) => Promise<boolean>;
7
+ validateUsername?: (username: string) => Promise<boolean>;
8
+ validateNewUser?: (user: Partial<User>) => Promise<User>;
9
+ validatePassword?: (password: string) => Promise<boolean>;
10
+ }
11
+ export interface UserSettings {
12
+ mergeUserCartsOnLogin: boolean;
13
+ autoMessagingAfterUserCreation: boolean;
14
+ validateEmail: (email: string) => Promise<boolean>;
15
+ validateUsername: (username: string) => Promise<boolean>;
16
+ validateNewUser: (user: Partial<User>) => Promise<User>;
17
+ validatePassword: (password: string) => Promise<boolean>;
18
+ configureSettings: (options: UserSettingsOptions, db: mongodb.Db) => void;
19
+ }
2
20
  export declare const userSettings: UserSettings;
3
21
  //# sourceMappingURL=users-settings.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"users-settings.d.ts","sourceRoot":"","sources":["../src/users-settings.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,YAAY,EAAuB,MAAM,8BAA8B,CAAC;AAIvF,eAAO,MAAM,YAAY,EAAE,YAkE1B,CAAC"}
1
+ {"version":3,"file":"users-settings.d.ts","sourceRoot":"","sources":["../src/users-settings.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAClC,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AAEjD,MAAM,WAAW,mBAAmB;IAClC,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,8BAA8B,CAAC,EAAE,OAAO,CAAC;IACzC,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IACpD,gBAAgB,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAC1D,eAAe,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACzD,gBAAgB,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;CAC3D;AACD,MAAM,WAAW,YAAY;IAC3B,qBAAqB,EAAE,OAAO,CAAC;IAC/B,8BAA8B,EAAE,OAAO,CAAC;IACxC,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IACnD,gBAAgB,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IACzD,eAAe,EAAE,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACxD,gBAAgB,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IACzD,iBAAiB,EAAE,CAAC,OAAO,EAAE,mBAAmB,EAAE,EAAE,EAAE,OAAO,CAAC,EAAE,KAAK,IAAI,CAAC;CAC3E;AAED,eAAO,MAAM,YAAY,EAAE,YAwD1B,CAAC"}
@@ -1,4 +1,3 @@
1
- import { Schemas } from '@unchainedshop/utils';
2
1
  export const userSettings = {
3
2
  autoMessagingAfterUserCreation: null,
4
3
  mergeUserCartsOnLogin: null,
@@ -32,9 +31,7 @@ export const userSettings = {
32
31
  return true;
33
32
  };
34
33
  const defaultValidateNewUser = async (user) => {
35
- const customSchema = Schemas.User.omit('_id', 'created', 'roles', 'emails', 'services', 'username', 'initialPassword');
36
- customSchema.validate(user);
37
- return Schemas.User.clean(user);
34
+ return user;
38
35
  };
39
36
  const defaultValidatePassword = async (password) => {
40
37
  return password?.length >= 8;
@@ -1 +1 @@
1
- {"version":3,"file":"users-settings.js","sourceRoot":"","sources":["../src/users-settings.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAG/C,MAAM,CAAC,MAAM,YAAY,GAAiB;IACxC,8BAA8B,EAAE,IAAI;IACpC,qBAAqB,EAAE,IAAI;IAC3B,aAAa,EAAE,IAAI;IACnB,gBAAgB,EAAE,IAAI;IACtB,eAAe,EAAE,IAAI;IACrB,gBAAgB,EAAE,IAAI;IAEtB,iBAAiB,EAAE,CACjB,EACE,qBAAqB,EACrB,8BAA8B,EAC9B,aAAa,EACb,gBAAgB,EAChB,eAAe,EACf,gBAAgB,GACI,EACtB,EAAc,EACd,EAAE;QACF,MAAM,qCAAqC,GAAG,IAAI,CAAC;QACnD,MAAM,4BAA4B,GAAG,IAAI,CAAC;QAE1C,MAAM,oBAAoB,GAAG,KAAK,EAAE,QAAgB,EAAE,EAAE;YACtD,MAAM,KAAK,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC,IAAI,EAAE,CAAC;YAC5C,IAAI,CAAC,KAAK,EAAE,QAAQ,EAAE,CAAC,GAAG,CAAC;gBAAE,OAAO,KAAK,CAAC;YAC1C,MAAM,kBAAkB,GAAG,MAAM,EAAE;iBAChC,UAAU,CAAC,OAAO,CAAC;iBACnB,cAAc,CAAC,EAAE,gBAAgB,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC;YACxF,IAAI,kBAAkB;gBAAE,OAAO,KAAK,CAAC;YACrC,OAAO,IAAI,CAAC;QACd,CAAC,CAAC;QACF,MAAM,uBAAuB,GAAG,KAAK,EAAE,WAAmB,EAAE,EAAE;YAC5D,MAAM,QAAQ,GAAG,WAAW,CAAC,WAAW,EAAE,CAAC,IAAI,EAAE,CAAC;YAClD,IAAI,QAAQ,EAAE,MAAM,GAAG,CAAC;gBAAE,OAAO,KAAK,CAAC;YACvC,MAAM,qBAAqB,GAAG,MAAM,EAAE;iBACnC,UAAU,CAAC,OAAO,CAAC;iBACnB,cAAc,CAAC,EAAE,QAAQ,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC;YACnF,IAAI,qBAAqB;gBAAE,OAAO,KAAK,CAAC;YACxC,OAAO,IAAI,CAAC;QACd,CAAC,CAAC;QACF,MAAM,sBAAsB,GAAG,KAAK,EAAE,IAAU,EAAE,EAAE;YAClD,MAAM,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,CACpC,KAAK,EACL,SAAS,EACT,OAAO,EACP,QAAQ,EACR,UAAU,EACV,UAAU,EACV,iBAAiB,CAClB,CAAC;YACF,YAAY,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;YAC5B,OAAO,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAS,CAAC;QAC1C,CAAC,CAAC;QAEF,MAAM,uBAAuB,GAAG,KAAK,EAAE,QAAgB,EAAE,EAAE;YACzD,OAAO,QAAQ,EAAE,MAAM,IAAI,CAAC,CAAC;QAC/B,CAAC,CAAC;QAEF,YAAY,CAAC,qBAAqB,GAAG,qBAAqB,IAAI,4BAA4B,CAAC;QAC3F,YAAY,CAAC,8BAA8B;YACzC,8BAA8B,IAAI,qCAAqC,CAAC;QAC1E,YAAY,CAAC,aAAa,GAAG,aAAa,IAAI,oBAAoB,CAAC;QACnE,YAAY,CAAC,gBAAgB,GAAG,gBAAgB,IAAI,uBAAuB,CAAC;QAC5E,YAAY,CAAC,eAAe,GAAG,eAAe,IAAI,sBAAsB,CAAC;QACzE,YAAY,CAAC,gBAAgB,GAAG,gBAAgB,IAAI,uBAAuB,CAAC;IAC9E,CAAC;CACF,CAAC"}
1
+ {"version":3,"file":"users-settings.js","sourceRoot":"","sources":["../src/users-settings.ts"],"names":[],"mappings":"AAqBA,MAAM,CAAC,MAAM,YAAY,GAAiB;IACxC,8BAA8B,EAAE,IAAI;IACpC,qBAAqB,EAAE,IAAI;IAC3B,aAAa,EAAE,IAAI;IACnB,gBAAgB,EAAE,IAAI;IACtB,eAAe,EAAE,IAAI;IACrB,gBAAgB,EAAE,IAAI;IAEtB,iBAAiB,EAAE,CACjB,EACE,qBAAqB,EACrB,8BAA8B,EAC9B,aAAa,EACb,gBAAgB,EAChB,eAAe,EACf,gBAAgB,GACI,EACtB,EAAc,EACd,EAAE;QACF,MAAM,qCAAqC,GAAG,IAAI,CAAC;QACnD,MAAM,4BAA4B,GAAG,IAAI,CAAC;QAE1C,MAAM,oBAAoB,GAAG,KAAK,EAAE,QAAgB,EAAE,EAAE;YACtD,MAAM,KAAK,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC,IAAI,EAAE,CAAC;YAC5C,IAAI,CAAC,KAAK,EAAE,QAAQ,EAAE,CAAC,GAAG,CAAC;gBAAE,OAAO,KAAK,CAAC;YAC1C,MAAM,kBAAkB,GAAG,MAAM,EAAE;iBAChC,UAAU,CAAC,OAAO,CAAC;iBACnB,cAAc,CAAC,EAAE,gBAAgB,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC;YACxF,IAAI,kBAAkB;gBAAE,OAAO,KAAK,CAAC;YACrC,OAAO,IAAI,CAAC;QACd,CAAC,CAAC;QACF,MAAM,uBAAuB,GAAG,KAAK,EAAE,WAAmB,EAAE,EAAE;YAC5D,MAAM,QAAQ,GAAG,WAAW,CAAC,WAAW,EAAE,CAAC,IAAI,EAAE,CAAC;YAClD,IAAI,QAAQ,EAAE,MAAM,GAAG,CAAC;gBAAE,OAAO,KAAK,CAAC;YACvC,MAAM,qBAAqB,GAAG,MAAM,EAAE;iBACnC,UAAU,CAAC,OAAO,CAAC;iBACnB,cAAc,CAAC,EAAE,QAAQ,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC;YACnF,IAAI,qBAAqB;gBAAE,OAAO,KAAK,CAAC;YACxC,OAAO,IAAI,CAAC;QACd,CAAC,CAAC;QACF,MAAM,sBAAsB,GAAG,KAAK,EAAE,IAAU,EAAE,EAAE;YAClD,OAAO,IAAI,CAAC;QACd,CAAC,CAAC;QAEF,MAAM,uBAAuB,GAAG,KAAK,EAAE,QAAgB,EAAE,EAAE;YACzD,OAAO,QAAQ,EAAE,MAAM,IAAI,CAAC,CAAC;QAC/B,CAAC,CAAC;QAEF,YAAY,CAAC,qBAAqB,GAAG,qBAAqB,IAAI,4BAA4B,CAAC;QAC3F,YAAY,CAAC,8BAA8B;YACzC,8BAA8B,IAAI,qCAAqC,CAAC;QAC1E,YAAY,CAAC,aAAa,GAAG,aAAa,IAAI,oBAAoB,CAAC;QACnE,YAAY,CAAC,gBAAgB,GAAG,gBAAgB,IAAI,uBAAuB,CAAC;QAC5E,YAAY,CAAC,eAAe,GAAG,eAAe,IAAI,sBAAsB,CAAC;QACzE,YAAY,CAAC,gBAAgB,GAAG,gBAAgB,IAAI,uBAAuB,CAAC;IAC9E,CAAC;CACF,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@unchainedshop/core-users",
3
- "version": "3.0.0-alpha2",
3
+ "version": "3.0.0-alpha3",
4
4
  "main": "lib/users-index.js",
5
5
  "exports": {
6
6
  ".": "./lib/users-index.js",
@@ -31,22 +31,19 @@
31
31
  },
32
32
  "homepage": "https://github.com/unchainedshop/unchained#readme",
33
33
  "dependencies": {
34
- "@unchainedshop/events": "^3.0.0-alpha2",
35
- "@unchainedshop/file-upload": "^3.0.0-alpha2",
36
- "@unchainedshop/logger": "^3.0.0-alpha2",
37
- "@unchainedshop/roles": "^3.0.0-alpha2",
38
- "@unchainedshop/utils": "^3.0.0-alpha2",
34
+ "@unchainedshop/events": "^3.0.0-alpha3",
35
+ "@unchainedshop/file-upload": "^3.0.0-alpha3",
36
+ "@unchainedshop/logger": "^3.0.0-alpha3",
37
+ "@unchainedshop/roles": "^3.0.0-alpha3",
38
+ "@unchainedshop/utils": "^3.0.0-alpha3",
39
39
  "bcryptjs": "^2.4.3",
40
40
  "fido2-lib": "^3.5.3",
41
- "locale": "^0.1.0",
42
- "simpl-schema": "^3.4.6",
43
41
  "uuid": "^10.0.0"
44
42
  },
45
43
  "devDependencies": {
46
- "@types/node": "^20.14.12",
47
- "@unchainedshop/types": "^3.0.0-alpha2",
44
+ "@types/node": "^22.5.5",
48
45
  "jest": "^29.7.0",
49
- "ts-jest": "^29.2.3",
50
- "typescript": "^5.5.4"
46
+ "ts-jest": "^29.2.5",
47
+ "typescript": "^5.6.2"
51
48
  }
52
49
  }
@@ -1,5 +1,5 @@
1
1
  import { mongodb, buildDbIndexes } from '@unchainedshop/mongodb';
2
- import { User } from '@unchainedshop/types/user.js';
2
+ import { User } from '../types.js';
3
3
 
4
4
  export const UsersCollection = async (db: mongodb.Db) => {
5
5
  const Users = db.collection<User>('users');
@@ -1,4 +1,4 @@
1
- import { WebAuthnCredentialsCreationRequest } from '@unchainedshop/types/user.js';
1
+ import { WebAuthnCredentialsCreationRequest } from '../types.js';
2
2
  import { mongodb, buildDbIndexes } from '@unchainedshop/mongodb';
3
3
 
4
4
  type Collection = WebAuthnCredentialsCreationRequest & { _id: number };
@@ -1,4 +1,4 @@
1
- import { Migration, MigrationRepository } from '@unchainedshop/types/core.js';
1
+ import { Migration, MigrationRepository } from '@unchainedshop/core';
2
2
  import { UsersCollection } from '../db/UsersCollection.js';
3
3
 
4
4
  const convertTagsToLowerCase = async (collection: Awaited<ReturnType<typeof UsersCollection>>) => {
@@ -1,16 +1,6 @@
1
- import localePkg from 'locale';
2
1
  import bcrypt from 'bcryptjs';
3
- import { Address, Contact } from '@unchainedshop/types/common.js';
4
- import { ModuleInput, UnchainedCore } from '@unchainedshop/types/core.js';
5
- import {
6
- User,
7
- UserQuery,
8
- Email,
9
- UserLastLogin,
10
- UserProfile,
11
- UserSettingsOptions,
12
- UserData,
13
- } from '@unchainedshop/types/user.js';
2
+ import { ModuleInput, UnchainedCore } from '@unchainedshop/core';
3
+ import { User, UserQuery, Email, UserLastLogin, UserProfile, UserData } from '../types.js';
14
4
  import { emit, registerEvents } from '@unchainedshop/events';
15
5
  import {
16
6
  generateDbFilterById,
@@ -20,15 +10,88 @@ import {
20
10
  } from '@unchainedshop/mongodb';
21
11
  import { systemLocale } from '@unchainedshop/utils';
22
12
  import { FileDirector } from '@unchainedshop/file-upload';
23
- import { SortDirection, SortOption } from '@unchainedshop/types/api.js';
13
+ import { SortDirection, SortOption } from '@unchainedshop/utils';
24
14
  import { UsersCollection } from '../db/UsersCollection.js';
25
15
  import addMigrations from './addMigrations.js';
26
- import { userSettings } from '../users-settings.js';
27
- import { configureUsersWebAuthnModule } from './configureUsersWebAuthnModule.js';
16
+ import { userSettings, UserSettingsOptions } from '../users-settings.js';
17
+ import { configureUsersWebAuthnModule, UsersWebAuthnModule } from './configureUsersWebAuthnModule.js';
28
18
  import * as pbkdf2 from './pbkdf2.js';
29
19
  import * as sha256 from './sha256.js';
30
-
31
- const { Locale } = localePkg;
20
+ import type { Address, Contact } from '@unchainedshop/mongodb';
21
+
22
+ export type UsersModule = {
23
+ // Submodules
24
+ webAuthn: UsersWebAuthnModule;
25
+
26
+ // Queries
27
+ count: (query: UserQuery) => Promise<number>;
28
+ findUserById: (userId: string) => Promise<User>;
29
+ findUserByToken: (hashedToken?: string) => Promise<User>;
30
+ findUserByResetToken: (token: string) => Promise<User>;
31
+ findUnverifiedEmailToken: (token: string) => Promise<{
32
+ userId: string;
33
+ address: string;
34
+ when: Date;
35
+ }>;
36
+ findUserByEmail(email: string): Promise<User>;
37
+ findUserByUsername(username: string): Promise<User>;
38
+ findUser: (
39
+ selector: UserQuery & { sort?: Array<SortOption> },
40
+ options?: mongodb.FindOptions,
41
+ ) => Promise<User>;
42
+ findUsers: (
43
+ query: UserQuery & {
44
+ sort?: Array<SortOption>;
45
+ limit?: number;
46
+ offset?: number;
47
+ },
48
+ ) => Promise<Array<User>>;
49
+ userExists: (query: { userId: string }) => Promise<boolean>;
50
+ // Transformations
51
+ primaryEmail: (user: User) => Email;
52
+ userLocale: (user: User) => Intl.Locale;
53
+
54
+ // Mutations
55
+ createUser: (
56
+ userData: UserData,
57
+ options: { skipMessaging?: boolean; skipPasswordEnrollment?: boolean },
58
+ ) => Promise<string>;
59
+ addEmail: (userId: string, email: string) => Promise<void>;
60
+ removeEmail: (userId: string, email: string) => Promise<void>;
61
+ sendVerificationEmail: (userId: string, email: string) => Promise<void>;
62
+ sendResetPasswordEmail: (userId: string, email: string, isEnrollment?: boolean) => Promise<void>;
63
+ verifyEmail: (userId: string, email: string) => Promise<void>;
64
+ setUsername: (userId: string, newUsername: string) => Promise<void>;
65
+ setPassword: (userId: string, newPassword?: string) => Promise<void>;
66
+ verifyPassword: (hashObject: Record<string, string>, password: string) => Promise<boolean>;
67
+ addRoles: (userId: string, roles: Array<string>) => Promise<number>;
68
+ updateAvatar: (_id: string, fileId: string) => Promise<User>;
69
+ updateGuest: (user: User, guest: boolean) => Promise<void>;
70
+ updateHeartbeat: (userId: string, doc: UserLastLogin) => Promise<User>;
71
+ updateLastBillingAddress: (_id: string, lastAddress: Address) => Promise<User>;
72
+ updateLastContact: (_id: string, lastContact: Contact) => Promise<User>;
73
+ updateProfile: (
74
+ _id: string,
75
+ { profile, meta }: { profile?: UserProfile; meta?: any },
76
+ ) => Promise<User>;
77
+ delete: (userId: string) => Promise<User>;
78
+ updateRoles: (_id: string, roles: Array<string>) => Promise<User>;
79
+ updateTags: (_id: string, tags: Array<string>) => Promise<User>;
80
+ updateUser: (
81
+ selector: mongodb.Filter<User>,
82
+ modifier: mongodb.UpdateFilter<User>,
83
+ options: mongodb.FindOneAndUpdateOptions,
84
+ ) => Promise<User>;
85
+ addPushSubscription: (
86
+ userId: string,
87
+ subscription: any,
88
+ options?: {
89
+ userAgent: string;
90
+ unsubscribeFromOtherUsers: boolean;
91
+ },
92
+ ) => Promise<void>;
93
+ removePushSubscription: (userId: string, p256dh: string) => Promise<void>;
94
+ };
32
95
 
33
96
  const USER_EVENTS = [
34
97
  'USER_ACCOUNT_ACTION',
@@ -235,9 +298,9 @@ export const configureUsersModule = async ({
235
298
  )?.[0];
236
299
  },
237
300
 
238
- userLocale(user: User): localePkg.Locale {
301
+ userLocale(user: User): Intl.Locale {
239
302
  if (!user?.lastLogin?.locale) return systemLocale;
240
- return new Locale(user.lastLogin.locale);
303
+ return new Intl.Locale(user.lastLogin.locale);
241
304
  },
242
305
 
243
306
  // Mutations
@@ -313,7 +376,7 @@ export const configureUsersModule = async ({
313
376
  await this.sendVerificationEmail(userId, email);
314
377
  }
315
378
  }
316
- } catch (e) {
379
+ } catch {
317
380
  /* */
318
381
  }
319
382
 
@@ -1,5 +1,5 @@
1
1
  /// <reference lib="dom" />
2
- import { ModuleInput } from '@unchainedshop/types/core.js';
2
+ import { ModuleInput } from '@unchainedshop/core';
3
3
  import {
4
4
  Fido2Lib,
5
5
  PublicKeyCredentialCreationOptions,
@@ -8,6 +8,24 @@ import {
8
8
  import { createLogger } from '@unchainedshop/logger';
9
9
  import { WebAuthnCredentialsCreationRequestsCollection } from '../db/WebAuthnCredentialsCreationRequestsCollection.js';
10
10
 
11
+ export interface UsersWebAuthnModule {
12
+ findMDSMetadataForAAGUID: (aaguid: string) => Promise<any>;
13
+
14
+ createCredentialCreationOptions: (
15
+ origin: string,
16
+ username: string,
17
+ extensionOptions?: any,
18
+ ) => Promise<any>;
19
+ verifyCredentialCreation: (username: string, credentials: any) => Promise<any>;
20
+
21
+ createCredentialRequestOptions: (
22
+ origin: string,
23
+ username?: string,
24
+ extensionOptions?: any,
25
+ ) => Promise<any>;
26
+ verifyCredentialRequest: (userPublicKeys: any[], username: string, credentials: any) => Promise<any>;
27
+ }
28
+
11
29
  const logger = createLogger('unchained:core-users');
12
30
 
13
31
  const { ROOT_URL, EMAIL_WEBSITE_NAME } = process.env;
@@ -48,7 +66,9 @@ export function buf2hex(buffer) {
48
66
  .join('');
49
67
  }
50
68
 
51
- export const configureUsersWebAuthnModule = async ({ db }: ModuleInput<any>) => {
69
+ export const configureUsersWebAuthnModule = async ({
70
+ db,
71
+ }: ModuleInput<any>): Promise<UsersWebAuthnModule> => {
52
72
  const WebAuthnCredentialsCreationRequests = await WebAuthnCredentialsCreationRequestsCollection(db);
53
73
 
54
74
  const thisDomain = new URL(ROOT_URL).hostname;
@@ -1,4 +1,4 @@
1
- import { User } from '@unchainedshop/types/user.js';
1
+ import { User } from '../types.js';
2
2
  import { removeConfidentialServiceHashes } from './configureUsersModule.js';
3
3
  import user from '../../tests/mock/user-mock.js';
4
4
 
@@ -1,6 +1,12 @@
1
- import { MigrateUserDataService } from '@unchainedshop/types/user.js';
1
+ import { UnchainedCore } from '@unchainedshop/core';
2
2
  import { userSettings } from '../users-settings.js';
3
3
 
4
+ export type MigrateUserDataService = (
5
+ userIdBeforeLogin,
6
+ userId,
7
+ unchainedAPI: UnchainedCore,
8
+ ) => Promise<void>;
9
+
4
10
  export const migrateUserDataService: MigrateUserDataService = async (
5
11
  userIdBeforeLogin,
6
12
  userId,
@@ -1,5 +1,11 @@
1
- import { UpdateUserAvatarAfterUploadService } from '@unchainedshop/types/user.js';
1
+ import { File } from '@unchainedshop/core-files';
2
2
  import { log, LogLevel } from '@unchainedshop/logger';
3
+ import { UnchainedCore } from '@unchainedshop/core';
4
+
5
+ export type UpdateUserAvatarAfterUploadService = (
6
+ params: { file: File },
7
+ context: UnchainedCore,
8
+ ) => Promise<void>;
3
9
 
4
10
  export const updateUserAvatarAfterUploadService: UpdateUserAvatarAfterUploadService = async (
5
11
  { file },
@@ -1,11 +1,15 @@
1
- import { getUserCountryService } from './getUserCountryService.js';
2
- import { getUserLanguageService } from './getUserLanguageService.js';
3
- import { updateUserAvatarAfterUploadService } from './updateUserAvatarAfterUploadService.js';
4
- import { migrateUserDataService } from './migrateUserDataService.js';
1
+ import {
2
+ updateUserAvatarAfterUploadService,
3
+ UpdateUserAvatarAfterUploadService,
4
+ } from './updateUserAvatarAfterUploadService.js';
5
+ import { migrateUserDataService, MigrateUserDataService } from './migrateUserDataService.js';
5
6
 
6
- export const userServices = {
7
- getUserCountry: getUserCountryService,
8
- getUserLanguage: getUserLanguageService,
7
+ export interface UserServices {
8
+ updateUserAvatarAfterUpload: UpdateUserAvatarAfterUploadService;
9
+ migrateUserData: MigrateUserDataService;
10
+ }
11
+
12
+ export const userServices: UserServices = {
9
13
  updateUserAvatarAfterUpload: updateUserAvatarAfterUploadService,
10
14
  migrateUserData: migrateUserDataService,
11
15
  };
package/src/types.ts ADDED
@@ -0,0 +1,101 @@
1
+ import type { TimestampFields, Address, Contact, mongodb } from '@unchainedshop/mongodb';
2
+
3
+ export interface PushSubscription {
4
+ _id: string;
5
+ userAgent: string;
6
+ expirationTime: number;
7
+ endpoint: string;
8
+ }
9
+
10
+ export interface UserProfile {
11
+ displayName?: string;
12
+ birthday?: Date;
13
+ phoneMobile?: string;
14
+ gender?: string;
15
+ address?: Address;
16
+ }
17
+
18
+ export interface UserLastLogin {
19
+ timestamp?: Date;
20
+ locale?: string;
21
+ countryCode?: string;
22
+ remoteAddress?: string;
23
+ remotePort?: string;
24
+ userAgent?: string;
25
+ }
26
+
27
+ export interface Email {
28
+ address: string;
29
+ verified: boolean;
30
+ }
31
+
32
+ export interface WebAuthnCredentials {
33
+ id: string;
34
+ publicKey: string;
35
+ created: Date;
36
+ aaguid: string;
37
+ counter: number;
38
+ mdsMetadata: any;
39
+ }
40
+
41
+ export interface Web3Address {
42
+ address: string;
43
+ nonce?: number;
44
+ verified: boolean;
45
+ }
46
+
47
+ export interface PushSubscriptionObject {
48
+ userAgent: string;
49
+ endpoint: string;
50
+ expirationTime?: number;
51
+ keys: {
52
+ auth: string;
53
+ p256dh: string;
54
+ };
55
+ }
56
+
57
+ export type User = {
58
+ _id?: string;
59
+ deleted?: Date;
60
+ avatarId?: string;
61
+ emails: Array<Email>;
62
+ guest: boolean;
63
+ initialPassword: boolean;
64
+ lastBillingAddress?: Address;
65
+ lastContact?: Contact;
66
+ lastLogin?: UserLastLogin;
67
+ profile?: UserProfile;
68
+ roles: Array<string>;
69
+ services: any;
70
+ tags?: Array<string>;
71
+ pushSubscriptions: Array<PushSubscriptionObject>;
72
+ username?: string;
73
+ meta?: any;
74
+ } & TimestampFields;
75
+
76
+ export type UserQuery = mongodb.Filter<User> & {
77
+ includeGuests?: boolean;
78
+ queryString?: string;
79
+ };
80
+
81
+ export interface WebAuthnCredentialsCreationRequest {
82
+ challenge: string;
83
+ username: string;
84
+ origin: string;
85
+ factor: 'first' | 'second' | 'either';
86
+ }
87
+
88
+ /*
89
+ * Module
90
+ */
91
+ export interface UserData {
92
+ email?: string;
93
+ guest?: boolean;
94
+ initialPassword?: boolean;
95
+ lastBillingAddress?: User['lastBillingAddress'];
96
+ password: string | null;
97
+ webAuthnPublicKeyCredentials?: any;
98
+ profile?: UserProfile;
99
+ roles?: Array<string>;
100
+ username?: string;
101
+ }
@@ -1,4 +1,4 @@
1
- export { configureUsersModule } from './module/configureUsersModule.js';
2
-
3
- export { userServices } from './services/userServices.js';
4
- export { userSettings } from './users-settings.js';
1
+ export * from './types.js';
2
+ export * from './module/configureUsersModule.js';
3
+ export * from './services/userServices.js';
4
+ export * from './users-settings.js';
@@ -1,7 +1,24 @@
1
- import { User, UserSettings, UserSettingsOptions } from '@unchainedshop/types/user.js';
2
- import { Schemas } from '@unchainedshop/utils';
1
+ import { User } from './types.js';
3
2
  import { mongodb } from '@unchainedshop/mongodb';
4
3
 
4
+ export interface UserSettingsOptions {
5
+ mergeUserCartsOnLogin?: boolean;
6
+ autoMessagingAfterUserCreation?: boolean;
7
+ validateEmail?: (email: string) => Promise<boolean>;
8
+ validateUsername?: (username: string) => Promise<boolean>;
9
+ validateNewUser?: (user: Partial<User>) => Promise<User>;
10
+ validatePassword?: (password: string) => Promise<boolean>;
11
+ }
12
+ export interface UserSettings {
13
+ mergeUserCartsOnLogin: boolean;
14
+ autoMessagingAfterUserCreation: boolean;
15
+ validateEmail: (email: string) => Promise<boolean>;
16
+ validateUsername: (username: string) => Promise<boolean>;
17
+ validateNewUser: (user: Partial<User>) => Promise<User>;
18
+ validatePassword: (password: string) => Promise<boolean>;
19
+ configureSettings: (options: UserSettingsOptions, db: mongodb.Db) => void;
20
+ }
21
+
5
22
  export const userSettings: UserSettings = {
6
23
  autoMessagingAfterUserCreation: null,
7
24
  mergeUserCartsOnLogin: null,
@@ -43,17 +60,7 @@ export const userSettings: UserSettings = {
43
60
  return true;
44
61
  };
45
62
  const defaultValidateNewUser = async (user: User) => {
46
- const customSchema = Schemas.User.omit(
47
- '_id',
48
- 'created',
49
- 'roles',
50
- 'emails',
51
- 'services',
52
- 'username',
53
- 'initialPassword',
54
- );
55
- customSchema.validate(user);
56
- return Schemas.User.clean(user) as User;
63
+ return user;
57
64
  };
58
65
 
59
66
  const defaultValidatePassword = async (password: string) => {
@@ -1,3 +0,0 @@
1
- import { GetUserCountryService } from '@unchainedshop/types/user.js';
2
- export declare const getUserCountryService: GetUserCountryService;
3
- //# sourceMappingURL=getUserCountryService.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"getUserCountryService.d.ts","sourceRoot":"","sources":["../../src/services/getUserCountryService.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AAErE,eAAO,MAAM,qBAAqB,EAAE,qBAKnC,CAAC"}
@@ -1,7 +0,0 @@
1
- export const getUserCountryService = async (user, { modules }) => {
2
- const userLocale = modules.users.userLocale(user);
3
- return modules.countries.findCountry({
4
- isoCode: userLocale.country.toUpperCase(),
5
- });
6
- };
7
- //# sourceMappingURL=getUserCountryService.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"getUserCountryService.js","sourceRoot":"","sources":["../../src/services/getUserCountryService.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,qBAAqB,GAA0B,KAAK,EAAE,IAAI,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE;IACtF,MAAM,UAAU,GAAG,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;IAClD,OAAO,OAAO,CAAC,SAAS,CAAC,WAAW,CAAC;QACnC,OAAO,EAAE,UAAU,CAAC,OAAO,CAAC,WAAW,EAAE;KAC1C,CAAC,CAAC;AACL,CAAC,CAAC"}
@@ -1,3 +0,0 @@
1
- import { GetUserLanguageService } from '@unchainedshop/types/user.js';
2
- export declare const getUserLanguageService: GetUserLanguageService;
3
- //# sourceMappingURL=getUserLanguageService.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"getUserLanguageService.d.ts","sourceRoot":"","sources":["../../src/services/getUserLanguageService.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,8BAA8B,CAAC;AAEtE,eAAO,MAAM,sBAAsB,EAAE,sBAKpC,CAAC"}
@@ -1,7 +0,0 @@
1
- export const getUserLanguageService = async (user, { modules }) => {
2
- const userLocale = modules.users.userLocale(user);
3
- return modules.languages.findLanguage({
4
- isoCode: userLocale.language,
5
- });
6
- };
7
- //# sourceMappingURL=getUserLanguageService.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"getUserLanguageService.js","sourceRoot":"","sources":["../../src/services/getUserLanguageService.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,sBAAsB,GAA2B,KAAK,EAAE,IAAI,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE;IACxF,MAAM,UAAU,GAAG,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;IAClD,OAAO,OAAO,CAAC,SAAS,CAAC,YAAY,CAAC;QACpC,OAAO,EAAE,UAAU,CAAC,QAAQ;KAC7B,CAAC,CAAC;AACL,CAAC,CAAC"}
@@ -1,8 +0,0 @@
1
- import { GetUserCountryService } from '@unchainedshop/types/user.js';
2
-
3
- export const getUserCountryService: GetUserCountryService = async (user, { modules }) => {
4
- const userLocale = modules.users.userLocale(user);
5
- return modules.countries.findCountry({
6
- isoCode: userLocale.country.toUpperCase(),
7
- });
8
- };
@@ -1,8 +0,0 @@
1
- import { GetUserLanguageService } from '@unchainedshop/types/user.js';
2
-
3
- export const getUserLanguageService: GetUserLanguageService = async (user, { modules }) => {
4
- const userLocale = modules.users.userLocale(user);
5
- return modules.languages.findLanguage({
6
- isoCode: userLocale.language,
7
- });
8
- };