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

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 (61) 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 +2 -2
  6. package/lib/module/addMigrations.d.ts.map +1 -1
  7. package/lib/module/addMigrations.js.map +1 -1
  8. package/lib/module/configureUsersModule.d.ts +66 -27
  9. package/lib/module/configureUsersModule.d.ts.map +1 -1
  10. package/lib/module/configureUsersModule.js +3 -5
  11. package/lib/module/configureUsersModule.js.map +1 -1
  12. package/lib/module/configureUsersWebAuthnModule.d.ts +9 -22
  13. package/lib/module/configureUsersWebAuthnModule.d.ts.map +1 -1
  14. package/lib/module/configureUsersWebAuthnModule.js +1 -1
  15. package/lib/module/configureUsersWebAuthnModule.js.map +1 -1
  16. package/lib/services/migrateUserDataService.d.ts +2 -1
  17. package/lib/services/migrateUserDataService.d.ts.map +1 -1
  18. package/lib/services/migrateUserDataService.js.map +1 -1
  19. package/lib/services/updateUserAvatarAfterUploadService.d.ts +13 -1
  20. package/lib/services/updateUserAvatarAfterUploadService.d.ts.map +1 -1
  21. package/lib/services/updateUserAvatarAfterUploadService.js.map +1 -1
  22. package/lib/services/userServices.d.ts +7 -6
  23. package/lib/services/userServices.d.ts.map +1 -1
  24. package/lib/services/userServices.js +1 -5
  25. package/lib/services/userServices.js.map +1 -1
  26. package/lib/types.d.ts +88 -0
  27. package/lib/types.d.ts.map +1 -0
  28. package/lib/types.js +2 -0
  29. package/lib/types.js.map +1 -0
  30. package/lib/users-index.d.ts +4 -3
  31. package/lib/users-index.d.ts.map +1 -1
  32. package/lib/users-index.js +4 -3
  33. package/lib/users-index.js.map +1 -1
  34. package/lib/users-settings.d.ts +19 -1
  35. package/lib/users-settings.d.ts.map +1 -1
  36. package/lib/users-settings.js +1 -4
  37. package/lib/users-settings.js.map +1 -1
  38. package/package.json +9 -12
  39. package/src/db/UsersCollection.ts +1 -1
  40. package/src/db/WebAuthnCredentialsCreationRequestsCollection.ts +1 -1
  41. package/src/module/addMigrations.ts +2 -2
  42. package/src/module/buildFindSelector.test.ts +23 -18
  43. package/src/module/configureUsersModule.ts +95 -22
  44. package/src/module/configureUsersWebAuthnModule.ts +22 -2
  45. package/src/module/removeConfidentialServiceHashes.test.ts +2 -2
  46. package/src/services/migrateUserDataService.ts +7 -1
  47. package/src/services/updateUserAvatarAfterUploadService.ts +10 -1
  48. package/src/services/userServices.ts +11 -7
  49. package/src/types.ts +101 -0
  50. package/src/users-index.ts +4 -4
  51. package/src/users-settings.ts +20 -13
  52. package/lib/services/getUserCountryService.d.ts +0 -3
  53. package/lib/services/getUserCountryService.d.ts.map +0 -1
  54. package/lib/services/getUserCountryService.js +0 -7
  55. package/lib/services/getUserCountryService.js.map +0 -1
  56. package/lib/services/getUserLanguageService.d.ts +0 -3
  57. package/lib/services/getUserLanguageService.d.ts.map +0 -1
  58. package/lib/services/getUserLanguageService.js +0 -7
  59. package/lib/services/getUserLanguageService.js.map +0 -1
  60. package/src/services/getUserCountryService.ts +0 -8
  61. package/src/services/getUserLanguageService.ts +0 -8
@@ -1 +1 @@
1
- {"version":3,"file":"users-index.d.ts","sourceRoot":"","sources":["../src/users-index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,kCAAkC,CAAC;AAExE,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC1D,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC"}
1
+ {"version":3,"file":"users-index.d.ts","sourceRoot":"","sources":["../src/users-index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,kCAAkC,CAAC;AACjD,cAAc,4BAA4B,CAAC;AAC3C,cAAc,qBAAqB,CAAC"}
@@ -1,4 +1,5 @@
1
- export { configureUsersModule } from './module/configureUsersModule.js';
2
- export { userServices } from './services/userServices.js';
3
- 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';
4
5
  //# sourceMappingURL=users-index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"users-index.js","sourceRoot":"","sources":["../src/users-index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,kCAAkC,CAAC;AAExE,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC1D,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC"}
1
+ {"version":3,"file":"users-index.js","sourceRoot":"","sources":["../src/users-index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,kCAAkC,CAAC;AACjD,cAAc,4BAA4B,CAAC;AAC3C,cAAc,qBAAqB,CAAC"}
@@ -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-alpha4",
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-alpha4",
35
+ "@unchainedshop/file-upload": "^3.0.0-alpha4",
36
+ "@unchainedshop/logger": "^3.0.0-alpha4",
37
+ "@unchainedshop/roles": "^3.0.0-alpha4",
38
+ "@unchainedshop/utils": "^3.0.0-alpha4",
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.7.8",
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.3"
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 { MigrationRepository } from '@unchainedshop/mongodb';
2
2
  import { UsersCollection } from '../db/UsersCollection.js';
3
3
 
4
4
  const convertTagsToLowerCase = async (collection: Awaited<ReturnType<typeof UsersCollection>>) => {
@@ -20,7 +20,7 @@ const convertTagsToLowerCase = async (collection: Awaited<ReturnType<typeof User
20
20
  if (count > 0) bulk.execute();
21
21
  };
22
22
 
23
- export default function addMigrations(repository: MigrationRepository<Migration>) {
23
+ export default function addMigrations(repository: MigrationRepository) {
24
24
  repository?.register({
25
25
  id: 20220603115000,
26
26
  name: 'Copy user.profile.customFields to user.meta',
@@ -1,23 +1,28 @@
1
- import { buildFindSelector } from "./configureUsersModule.js";
1
+ import { buildFindSelector } from './configureUsersModule.js';
2
2
 
3
-
4
-
5
- describe('buildFindSelector', () => {
6
- it('Return the correct filter when no parameter is passed', async () => {
7
- expect(buildFindSelector({})).toEqual({ "deleted": null, guest: { '$in': [false, null] },
8
- })
9
- });
10
- it('Return the correct filter when no parameter is passed queryString and includeGuest: true', async () => {
11
- expect(buildFindSelector({queryString: "Hello world", includeGuests: true})).toEqual({ "deleted": null,'$text': { '$search': 'Hello world' } })
3
+ describe('buildFindSelector', () => {
4
+ it('Return the correct filter when no parameter is passed', () => {
5
+ expect(buildFindSelector({})).toEqual({ deleted: null, guest: { $in: [false, null] } });
6
+ });
7
+ it('Return the correct filter when no parameter is passed queryString and includeGuest: true', () => {
8
+ expect(buildFindSelector({ queryString: 'Hello world', includeGuests: true })).toEqual({
9
+ deleted: null,
10
+ $text: { $search: 'Hello world' },
12
11
  });
12
+ });
13
13
 
14
- it('Should include additional user field selector in addition too queryString and includeGuests', async () => {
15
- expect(buildFindSelector({queryString: "Hello world", includeGuests: false, "profile.displayName": "mikael"})).toEqual({
14
+ it('Should include additional user field selector in addition too queryString and includeGuests', () => {
15
+ expect(
16
+ buildFindSelector({
17
+ queryString: 'Hello world',
18
+ includeGuests: false,
16
19
  'profile.displayName': 'mikael',
17
- "deleted": null,
18
- guest: { '$in': [false, null] },
19
- '$text': { '$search': 'Hello world' }
20
- })
20
+ }),
21
+ ).toEqual({
22
+ 'profile.displayName': 'mikael',
23
+ deleted: null,
24
+ guest: { $in: [false, null] },
25
+ $text: { $search: 'Hello world' },
21
26
  });
22
- })
23
-
27
+ });
28
+ });
@@ -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 } from '@unchainedshop/mongodb';
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,90 @@ 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
+ import { UserServices } from '../services/userServices.js';
22
+ import { FileServices, FilesModule } from '@unchainedshop/core-files';
23
+
24
+ export type UsersModule = {
25
+ // Submodules
26
+ webAuthn: UsersWebAuthnModule;
27
+
28
+ // Queries
29
+ count: (query: UserQuery) => Promise<number>;
30
+ findUserById: (userId: string) => Promise<User>;
31
+ findUserByToken: (hashedToken?: string) => Promise<User>;
32
+ findUserByResetToken: (token: string) => Promise<User>;
33
+ findUnverifiedEmailToken: (token: string) => Promise<{
34
+ userId: string;
35
+ address: string;
36
+ when: Date;
37
+ }>;
38
+ findUserByEmail(email: string): Promise<User>;
39
+ findUserByUsername(username: string): Promise<User>;
40
+ findUser: (
41
+ selector: UserQuery & { sort?: Array<SortOption> },
42
+ options?: mongodb.FindOptions,
43
+ ) => Promise<User>;
44
+ findUsers: (
45
+ query: UserQuery & {
46
+ sort?: Array<SortOption>;
47
+ limit?: number;
48
+ offset?: number;
49
+ },
50
+ ) => Promise<Array<User>>;
51
+ userExists: (query: { userId: string }) => Promise<boolean>;
52
+ // Transformations
53
+ primaryEmail: (user: User) => Email;
54
+ userLocale: (user: User) => Intl.Locale;
55
+
56
+ // Mutations
57
+ createUser: (
58
+ userData: UserData,
59
+ options: { skipMessaging?: boolean; skipPasswordEnrollment?: boolean },
60
+ ) => Promise<string>;
61
+ addEmail: (userId: string, email: string) => Promise<void>;
62
+ removeEmail: (userId: string, email: string) => Promise<void>;
63
+ sendVerificationEmail: (userId: string, email: string) => Promise<void>;
64
+ sendResetPasswordEmail: (userId: string, email: string, isEnrollment?: boolean) => Promise<void>;
65
+ verifyEmail: (userId: string, email: string) => Promise<void>;
66
+ setUsername: (userId: string, newUsername: string) => Promise<void>;
67
+ setPassword: (userId: string, newPassword?: string) => Promise<void>;
68
+ verifyPassword: (hashObject: Record<string, string>, password: string) => Promise<boolean>;
69
+ addRoles: (userId: string, roles: Array<string>) => Promise<number>;
70
+ updateAvatar: (_id: string, fileId: string) => Promise<User>;
71
+ updateGuest: (user: User, guest: boolean) => Promise<void>;
72
+ updateHeartbeat: (userId: string, doc: UserLastLogin) => Promise<User>;
73
+ updateLastBillingAddress: (_id: string, lastAddress: Address) => Promise<User>;
74
+ updateLastContact: (_id: string, lastContact: Contact) => Promise<User>;
75
+ updateProfile: (
76
+ _id: string,
77
+ { profile, meta }: { profile?: UserProfile; meta?: any },
78
+ ) => Promise<User>;
79
+ delete: (userId: string) => Promise<User>;
80
+ updateRoles: (_id: string, roles: Array<string>) => Promise<User>;
81
+ updateTags: (_id: string, tags: Array<string>) => Promise<User>;
82
+ updateUser: (
83
+ selector: mongodb.Filter<User>,
84
+ modifier: mongodb.UpdateFilter<User>,
85
+ options: mongodb.FindOneAndUpdateOptions,
86
+ ) => Promise<User>;
87
+ addPushSubscription: (
88
+ userId: string,
89
+ subscription: any,
90
+ options?: {
91
+ userAgent: string;
92
+ unsubscribeFromOtherUsers: boolean;
93
+ },
94
+ ) => Promise<void>;
95
+ removePushSubscription: (userId: string, p256dh: string) => Promise<void>;
96
+ };
32
97
 
33
98
  const USER_EVENTS = [
34
99
  'USER_ACCOUNT_ACTION',
@@ -62,9 +127,17 @@ export const buildFindSelector = ({ includeGuests, queryString, ...rest }: UserQ
62
127
  return selector;
63
128
  };
64
129
 
65
- FileDirector.registerFileUploadCallback('user-avatars', async (file, context: UnchainedCore) => {
130
+ FileDirector.registerFileUploadCallback<{
131
+ services: {
132
+ users: UserServices;
133
+ files: FileServices;
134
+ };
135
+ modules: {
136
+ users: UsersModule;
137
+ files: FilesModule;
138
+ };
139
+ }>('user-avatars', async (file, context) => {
66
140
  const { services } = context;
67
-
68
141
  return services.users.updateUserAvatarAfterUpload({ file }, context);
69
142
  });
70
143
 
@@ -235,9 +308,9 @@ export const configureUsersModule = async ({
235
308
  )?.[0];
236
309
  },
237
310
 
238
- userLocale(user: User): localePkg.Locale {
311
+ userLocale(user: User): Intl.Locale {
239
312
  if (!user?.lastLogin?.locale) return systemLocale;
240
- return new Locale(user.lastLogin.locale);
313
+ return new Intl.Locale(user.lastLogin.locale);
241
314
  },
242
315
 
243
316
  // Mutations
@@ -313,7 +386,7 @@ export const configureUsersModule = async ({
313
386
  await this.sendVerificationEmail(userId, email);
314
387
  }
315
388
  }
316
- } catch (e) {
389
+ } catch {
317
390
  /* */
318
391
  }
319
392
 
@@ -1,5 +1,5 @@
1
1
  /// <reference lib="dom" />
2
- import { ModuleInput } from '@unchainedshop/types/core.js';
2
+ import { ModuleInput } from '@unchainedshop/mongodb';
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,9 +1,9 @@
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
 
5
5
  describe('removeConfidentialServiceHashes', () => {
6
- it('Should remove sensitive user credentials ', async () => {
6
+ it('Should remove sensitive user credentials ', () => {
7
7
  expect(user.services).not.toBeUndefined();
8
8
  removeConfidentialServiceHashes(user as unknown as User);
9
9
  expect(user.services).toBeUndefined();
@@ -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,14 @@
1
- import { UpdateUserAvatarAfterUploadService } from '@unchainedshop/types/user.js';
1
+ import { File, FileServices, FilesModule } from '@unchainedshop/core-files';
2
2
  import { log, LogLevel } from '@unchainedshop/logger';
3
+ import { UsersModule } from '../users-index.js';
4
+
5
+ export type UpdateUserAvatarAfterUploadService = (
6
+ params: { file: File },
7
+ context: {
8
+ modules: { files: FilesModule; users: UsersModule };
9
+ services: { files: FileServices };
10
+ },
11
+ ) => Promise<void>;
3
12
 
4
13
  export const updateUserAvatarAfterUploadService: UpdateUserAvatarAfterUploadService = async (
5
14
  { 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"}