@lenne.tech/nest-server 8.0.2 → 8.3.0

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 (166) hide show
  1. package/dist/config.env.js +3 -2
  2. package/dist/config.env.js.map +1 -1
  3. package/dist/core/common/args/pagination.args.js +1 -1
  4. package/dist/core/common/args/pagination.args.js.map +1 -1
  5. package/dist/core/common/decorators/restricted.decorator.d.ts +3 -0
  6. package/dist/core/common/decorators/restricted.decorator.js +14 -8
  7. package/dist/core/common/decorators/restricted.decorator.js.map +1 -1
  8. package/dist/core/common/enums/role.enum.d.ts +3 -2
  9. package/dist/core/common/enums/role.enum.js +3 -2
  10. package/dist/core/common/enums/role.enum.js.map +1 -1
  11. package/dist/core/common/helpers/config.helper.d.ts +2 -1
  12. package/dist/core/common/helpers/config.helper.js +11 -7
  13. package/dist/core/common/helpers/config.helper.js.map +1 -1
  14. package/dist/core/common/helpers/context.helper.d.ts +7 -1
  15. package/dist/core/common/helpers/context.helper.js +33 -29
  16. package/dist/core/common/helpers/context.helper.js.map +1 -1
  17. package/dist/core/common/helpers/db.helper.d.ts +37 -0
  18. package/dist/core/common/helpers/db.helper.js +356 -0
  19. package/dist/core/common/helpers/db.helper.js.map +1 -0
  20. package/dist/core/common/helpers/file.helper.d.ts +8 -1
  21. package/dist/core/common/helpers/file.helper.js +43 -31
  22. package/dist/core/common/helpers/file.helper.js.map +1 -1
  23. package/dist/core/common/helpers/filter.helper.d.ts +3 -0
  24. package/dist/core/common/helpers/filter.helper.js +93 -81
  25. package/dist/core/common/helpers/filter.helper.js.map +1 -1
  26. package/dist/core/common/helpers/graphql.helper.d.ts +24 -1
  27. package/dist/core/common/helpers/graphql.helper.js +144 -96
  28. package/dist/core/common/helpers/graphql.helper.js.map +1 -1
  29. package/dist/core/common/helpers/input.helper.d.ts +42 -4
  30. package/dist/core/common/helpers/input.helper.js +256 -97
  31. package/dist/core/common/helpers/input.helper.js.map +1 -1
  32. package/dist/core/common/helpers/model.helper.d.ts +11 -0
  33. package/dist/core/common/helpers/model.helper.js +41 -29
  34. package/dist/core/common/helpers/model.helper.js.map +1 -1
  35. package/dist/core/common/helpers/service.helper.d.ts +21 -1
  36. package/dist/core/common/helpers/service.helper.js +80 -72
  37. package/dist/core/common/helpers/service.helper.js.map +1 -1
  38. package/dist/core/common/inputs/combined-filter.input.js +1 -1
  39. package/dist/core/common/inputs/combined-filter.input.js.map +1 -1
  40. package/dist/core/common/inputs/core-input.input.js +1 -1
  41. package/dist/core/common/inputs/core-input.input.js.map +1 -1
  42. package/dist/core/common/interceptors/check-response.interceptor.js +1 -1
  43. package/dist/core/common/interceptors/check-response.interceptor.js.map +1 -1
  44. package/dist/core/common/interfaces/resolve-selector.interface.d.ts +5 -0
  45. package/dist/core/common/interfaces/resolve-selector.interface.js +3 -0
  46. package/dist/core/common/interfaces/resolve-selector.interface.js.map +1 -0
  47. package/dist/core/common/interfaces/service-options.interface.d.ts +36 -0
  48. package/dist/core/common/interfaces/service-options.interface.js +3 -0
  49. package/dist/core/common/interfaces/service-options.interface.js.map +1 -0
  50. package/dist/core/common/models/core-model.model.d.ts +5 -1
  51. package/dist/core/common/models/core-model.model.js +1 -1
  52. package/dist/core/common/models/core-model.model.js.map +1 -1
  53. package/dist/core/common/pipes/check-input.pipe.js +2 -2
  54. package/dist/core/common/pipes/check-input.pipe.js.map +1 -1
  55. package/dist/core/common/pipes/map-and-validate.pipe.js +1 -1
  56. package/dist/core/common/pipes/map-and-validate.pipe.js.map +1 -1
  57. package/dist/core/common/services/crud.service.d.ts +13 -0
  58. package/dist/core/common/services/crud.service.js +57 -0
  59. package/dist/core/common/services/crud.service.js.map +1 -0
  60. package/dist/core/common/services/email.service.js +8 -8
  61. package/dist/core/common/services/email.service.js.map +1 -1
  62. package/dist/core/common/services/module.service.d.ts +40 -0
  63. package/dist/core/common/services/module.service.js +80 -0
  64. package/dist/core/common/services/module.service.js.map +1 -0
  65. package/dist/core/common/types/core-model-constructor.type.d.ts +21 -0
  66. package/dist/core/common/types/core-model-constructor.type.js +3 -0
  67. package/dist/core/common/types/core-model-constructor.type.js.map +1 -0
  68. package/dist/core/common/types/field-selection.type.d.ts +4 -0
  69. package/dist/core/common/types/field-selection.type.js +3 -0
  70. package/dist/core/common/types/field-selection.type.js.map +1 -0
  71. package/dist/core/common/types/ids.type.d.ts +8 -0
  72. package/dist/core/common/types/ids.type.js +3 -0
  73. package/dist/core/common/types/ids.type.js.map +1 -0
  74. package/dist/core/common/types/string-or-object-id.type.d.ts +2 -0
  75. package/dist/core/common/types/string-or-object-id.type.js +3 -0
  76. package/dist/core/common/types/string-or-object-id.type.js.map +1 -0
  77. package/dist/core/modules/auth/core-auth.resolver.d.ts +2 -1
  78. package/dist/core/modules/auth/core-auth.resolver.js +4 -3
  79. package/dist/core/modules/auth/core-auth.resolver.js.map +1 -1
  80. package/dist/core/modules/auth/guards/roles.guard.js +1 -2
  81. package/dist/core/modules/auth/guards/roles.guard.js.map +1 -1
  82. package/dist/core/modules/auth/services/core-auth-user.service.d.ts +3 -1
  83. package/dist/core/modules/auth/services/core-auth-user.service.js.map +1 -1
  84. package/dist/core/modules/auth/services/core-auth.service.d.ts +2 -1
  85. package/dist/core/modules/auth/services/core-auth.service.js +6 -4
  86. package/dist/core/modules/auth/services/core-auth.service.js.map +1 -1
  87. package/dist/core/modules/user/core-user.model.js +1 -1
  88. package/dist/core/modules/user/core-user.model.js.map +1 -1
  89. package/dist/core/modules/user/core-user.service.d.ts +16 -25
  90. package/dist/core/modules/user/core-user.service.js +69 -90
  91. package/dist/core/modules/user/core-user.service.js.map +1 -1
  92. package/dist/core.module.js +1 -1
  93. package/dist/core.module.js.map +1 -1
  94. package/dist/index.d.ts +9 -1
  95. package/dist/index.js +9 -1
  96. package/dist/index.js.map +1 -1
  97. package/dist/server/modules/auth/auth.resolver.d.ts +2 -1
  98. package/dist/server/modules/auth/auth.resolver.js +4 -3
  99. package/dist/server/modules/auth/auth.resolver.js.map +1 -1
  100. package/dist/server/modules/file/file.controller.js +1 -1
  101. package/dist/server/modules/file/file.controller.js.map +1 -1
  102. package/dist/server/modules/user/avatar.controller.js +2 -2
  103. package/dist/server/modules/user/avatar.controller.js.map +1 -1
  104. package/dist/server/modules/user/user.model.d.ts +2 -1
  105. package/dist/server/modules/user/user.module.js +7 -3
  106. package/dist/server/modules/user/user.module.js.map +1 -1
  107. package/dist/server/modules/user/user.resolver.d.ts +8 -7
  108. package/dist/server/modules/user/user.resolver.js +85 -49
  109. package/dist/server/modules/user/user.resolver.js.map +1 -1
  110. package/dist/server/modules/user/user.service.d.ts +9 -18
  111. package/dist/server/modules/user/user.service.js +23 -30
  112. package/dist/server/modules/user/user.service.js.map +1 -1
  113. package/dist/test/test.helper.d.ts +1 -2
  114. package/dist/test/test.helper.js +1 -16
  115. package/dist/test/test.helper.js.map +1 -1
  116. package/dist/tsconfig.build.tsbuildinfo +1 -1
  117. package/package.json +58 -59
  118. package/src/config.env.ts +3 -2
  119. package/src/core/common/args/pagination.args.ts +2 -2
  120. package/src/core/common/decorators/restricted.decorator.ts +24 -12
  121. package/src/core/common/enums/role.enum.ts +23 -5
  122. package/src/core/common/helpers/config.helper.ts +26 -6
  123. package/src/core/common/helpers/context.helper.ts +42 -33
  124. package/src/core/common/helpers/db.helper.ts +595 -0
  125. package/src/core/common/helpers/file.helper.ts +76 -49
  126. package/src/core/common/helpers/filter.helper.ts +119 -96
  127. package/src/core/common/helpers/graphql.helper.ts +219 -117
  128. package/src/core/common/helpers/input.helper.ts +349 -108
  129. package/src/core/common/helpers/model.helper.ts +102 -57
  130. package/src/core/common/helpers/service.helper.ts +149 -117
  131. package/src/core/common/inputs/combined-filter.input.ts +2 -2
  132. package/src/core/common/inputs/core-input.input.ts +2 -2
  133. package/src/core/common/interceptors/check-response.interceptor.ts +2 -2
  134. package/src/core/common/interfaces/resolve-selector.interface.ts +9 -0
  135. package/src/core/common/interfaces/service-options.interface.ts +71 -0
  136. package/src/core/common/models/core-model.model.ts +7 -3
  137. package/src/core/common/pipes/check-input.pipe.ts +4 -4
  138. package/src/core/common/pipes/map-and-validate.pipe.ts +2 -2
  139. package/src/core/common/services/crud.service.ts +100 -0
  140. package/src/core/common/services/email.service.ts +9 -9
  141. package/src/core/common/services/module.service.ts +188 -0
  142. package/src/core/common/types/core-model-constructor.type.ts +30 -0
  143. package/src/core/common/types/field-selection.type.ts +8 -0
  144. package/src/core/common/types/ids.type.ts +7 -0
  145. package/src/core/common/types/string-or-object-id.type.ts +3 -0
  146. package/src/core/modules/auth/core-auth.module.ts +1 -1
  147. package/src/core/modules/auth/core-auth.resolver.ts +8 -3
  148. package/src/core/modules/auth/guards/roles.guard.ts +5 -7
  149. package/src/core/modules/auth/services/core-auth-user.service.ts +7 -1
  150. package/src/core/modules/auth/services/core-auth.service.ts +14 -4
  151. package/src/core/modules/user/core-user.model.ts +2 -1
  152. package/src/core/modules/user/core-user.service.ts +115 -185
  153. package/src/core.module.ts +2 -2
  154. package/src/index.ts +9 -1
  155. package/src/main.ts +1 -1
  156. package/src/server/modules/auth/auth.resolver.ts +8 -3
  157. package/src/server/modules/file/file.controller.ts +2 -2
  158. package/src/server/modules/user/avatar.controller.ts +3 -3
  159. package/src/server/modules/user/user.module.ts +7 -3
  160. package/src/server/modules/user/user.resolver.ts +74 -43
  161. package/src/server/modules/user/user.service.ts +30 -53
  162. package/src/test/test.helper.ts +31 -30
  163. package/dist/core/modules/user/core-basic-user.service.d.ts +0 -17
  164. package/dist/core/modules/user/core-basic-user.service.js +0 -73
  165. package/dist/core/modules/user/core-basic-user.service.js.map +0 -1
  166. package/src/core/modules/user/core-basic-user.service.ts +0 -138
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lenne.tech/nest-server",
3
- "version": "8.0.2",
3
+ "version": "8.3.0",
4
4
  "description": "Modern, fast, powerful Node.js web framework in TypeScript based on Nest with a GraphQL API and a connection to MongoDB (or other databases).",
5
5
  "keywords": [
6
6
  "node",
@@ -20,7 +20,7 @@
20
20
  "format:staged": "pretty-quick --staged",
21
21
  "lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix",
22
22
  "prestart:prod": "npm run build",
23
- "reinit": "rimraf package-lock.json && rimraf node_modules && npm cache clean --force && npm i && npm run test:e2e",
23
+ "reinit": "rimraf package-lock.json && rimraf node_modules && npm cache clean --force && npm i && npm run test:e2e && npm run build",
24
24
  "reinit:force": "rimraf package-lock.json && rimraf node_modules && npm cache clean --force && npm i --force && npm run test:e2e",
25
25
  "reinit:legacy": "rimraf package-lock.json && rimraf node_modules && npm cache clean --force && npm i --legacy-peer-deps && npm run test:e2e",
26
26
  "start": "./node_modules/.bin/grunt",
@@ -29,13 +29,13 @@
29
29
  "start:nodemon": "ts-node -r tsconfig-paths/register src/main.ts",
30
30
  "start:debug": "nodemon --config nodemon-debug.json",
31
31
  "start:dev": "nodemon",
32
- "test": "jest",
33
- "test:cov": "jest --coverage",
34
- "test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",
35
- "test:e2e": "jest --detectOpenHandles --config jest-e2e.json",
36
- "test:e2e-cov": "jest --detectOpenHandles --config jest-e2e.json --coverage",
37
- "test:ci": "jest --detectOpenHandles --config jest-e2e.json --ci",
38
- "test:watch": "jest --watch",
32
+ "test": "NODE_ENV=local jest",
33
+ "test:cov": "NODE_ENV=local jest --coverage",
34
+ "test:debug": "NODE_ENV=local node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",
35
+ "test:e2e": "NODE_ENV=local jest --config jest-e2e.json",
36
+ "test:e2e-cov": "NODE_ENV=local jest --config jest-e2e.json --coverage",
37
+ "test:ci": "NODE_ENV=local jest --config jest-e2e.json --ci",
38
+ "test:watch": "NODE_ENV=local jest --watch",
39
39
  "prepack": "npm run prestart:prod",
40
40
  "prepare": "husky install",
41
41
  "prepublishOnly": "npm run format && npm run lint && npm run test:ci",
@@ -52,72 +52,71 @@
52
52
  "node": ">= 16.13.0"
53
53
  },
54
54
  "dependencies": {
55
- "@apollo/gateway": "0.48.3",
56
- "@nestjs/apollo": "10.0.8",
57
- "@nestjs/common": "8.4.2",
58
- "@nestjs/core": "8.4.2",
59
- "@nestjs/graphql": "10.0.8",
55
+ "@apollo/gateway": "0.50.2",
56
+ "@nestjs/apollo": "10.0.11",
57
+ "@nestjs/common": "8.4.4",
58
+ "@nestjs/core": "8.4.4",
59
+ "@nestjs/graphql": "10.0.11",
60
60
  "@nestjs/jwt": "8.0.0",
61
61
  "@nestjs/mongoose": "9.0.3",
62
62
  "@nestjs/passport": "8.2.1",
63
- "@nestjs/platform-express": "8.4.2",
64
- "@nestjs/testing": "8.4.2",
65
- "@types/ejs": "3.1.0",
66
- "@types/jest": "27.4.1",
67
- "@types/lodash": "4.14.180",
68
- "@types/multer": "1.4.7",
69
- "@types/node": "17.0.22",
70
- "@types/node-mailjet": "3.3.8",
71
- "@types/nodemailer": "6.4.4",
72
- "@types/passport": "1.0.7",
73
- "@types/supertest": "2.0.12",
74
- "@typescript-eslint/eslint-plugin": "5.16.0",
75
- "@typescript-eslint/parser": "5.16.0",
76
- "apollo-server-core": "3.6.5",
77
- "apollo-server-express": "3.6.5",
63
+ "@nestjs/platform-express": "8.4.4",
64
+ "apollo-server-core": "3.6.8",
65
+ "apollo-server-express": "3.6.8",
78
66
  "bcrypt": "5.0.1",
79
67
  "class-transformer": "0.5.1",
80
68
  "class-validator": "0.13.2",
81
- "coffeescript": "2.6.1",
82
- "ejs": "3.1.6",
83
- "eslint": "8.11.0",
84
- "eslint-config-prettier": "8.5.0",
85
- "fastify": "3.27.4",
86
- "graphql": "16.3.0",
69
+ "ejs": "3.1.7",
70
+ "graphql": "16.4.0",
87
71
  "graphql-subscriptions": "2.0.0",
88
- "grunt": "1.4.1",
89
- "grunt-bg-shell": "2.3.3",
90
- "grunt-contrib-clean": "2.0.0",
91
- "grunt-contrib-watch": "1.1.0",
92
- "grunt-sync": "0.8.2",
93
- "husky": "7.0.4",
94
- "jest": "27.5.1",
95
- "json-to-graphql-query": "2.2.3",
96
- "light-my-request": "4.8.0",
72
+ "json-to-graphql-query": "2.2.4",
73
+ "light-my-request": "4.10.1",
97
74
  "lodash": "4.17.21",
98
- "mongodb": "4.4.1",
99
- "mongoose": "6.2.8",
75
+ "mongodb": "4.5.0",
76
+ "mongoose": "6.3.2",
100
77
  "multer": "1.4.4",
101
- "node-mailjet": "3.3.7",
102
- "nodemailer": "6.7.3",
103
- "nodemon": "2.0.15",
78
+ "node-mailjet": "3.4.1",
79
+ "nodemailer": "6.7.5",
80
+ "nodemon": "2.0.16",
104
81
  "passport": "0.5.2",
105
82
  "passport-jwt": "4.0.0",
106
- "prettier": "2.6.0",
107
- "pretty-quick": "3.1.3",
108
83
  "reflect-metadata": "0.1.13",
109
84
  "rimraf": "3.0.2",
110
- "rxjs": "7.5.5",
111
- "supertest": "6.2.2",
112
- "ts-jest": "27.1.3",
113
- "ts-morph": "13.0.3",
114
- "ts-node": "10.7.0",
115
- "tsconfig-paths": "3.14.1",
116
- "typescript": "4.6.2"
85
+ "rxjs": "7.5.5"
117
86
  },
118
87
  "devDependencies": {
88
+ "@nestjs/testing": "8.4.4",
89
+ "@types/ejs": "3.1.0",
90
+ "@types/jest": "27.5.0",
91
+ "@types/lodash": "4.14.182",
92
+ "@types/multer": "1.4.7",
93
+ "@types/node": "16.11.33",
94
+ "@types/node-mailjet": "3.3.8",
95
+ "@types/nodemailer": "6.4.4",
96
+ "@types/passport": "1.0.7",
97
+ "@types/supertest": "2.0.12",
98
+ "@typescript-eslint/eslint-plugin": "5.22.0",
99
+ "@typescript-eslint/parser": "5.22.0",
100
+ "coffeescript": "2.7.0",
101
+ "eslint": "8.14.0",
102
+ "eslint-config-prettier": "8.5.0",
119
103
  "find-file-up": "2.0.1",
120
- "pm2": "5.2.0"
104
+ "grunt": "1.5.2",
105
+ "grunt-bg-shell": "2.3.3",
106
+ "grunt-contrib-clean": "2.0.1",
107
+ "grunt-contrib-watch": "1.1.0",
108
+ "grunt-sync": "0.8.2",
109
+ "husky": "7.0.4",
110
+ "jest": "28.0.3",
111
+ "pm2": "5.2.0",
112
+ "prettier": "2.6.2",
113
+ "pretty-quick": "3.1.3",
114
+ "supertest": "6.2.3",
115
+ "ts-jest": "28.0.1",
116
+ "ts-morph": "14.0.0",
117
+ "ts-node": "10.7.0",
118
+ "tsconfig-paths": "4.0.0",
119
+ "typescript": "4.6.4"
121
120
  },
122
121
  "jest": {
123
122
  "collectCoverage": true,
package/src/config.env.ts CHANGED
@@ -109,8 +109,9 @@ const config: { [env: string]: IServerOptions } = {
109
109
  *
110
110
  * default: development
111
111
  */
112
- const envConfig = config[process.env['NODE' + '_ENV'] || 'development'] || config.development;
113
- console.log('Server starts in mode: ', process.env['NODE' + '_ENV'] || 'development');
112
+ const env = process.env['NODE' + '_ENV'] || 'development';
113
+ const envConfig = config[env] || config.development;
114
+ console.log('Configured for: ' + envConfig.env + (env !== envConfig.env ? ' (requested: ' + env + ')' : ''));
114
115
 
115
116
  /**
116
117
  * Export envConfig as default
@@ -1,6 +1,6 @@
1
1
  import { IsOptional, Max } from 'class-validator';
2
2
  import { ArgsType, Field, Int } from '@nestjs/graphql';
3
- import { ModelHelper } from '../helpers/model.helper';
3
+ import { maps } from '../helpers/model.helper';
4
4
  import { CoreInput } from '../inputs/core-input.input';
5
5
  import { SortInput } from '../inputs/sort.input';
6
6
 
@@ -90,7 +90,7 @@ export class PaginationArgs extends CoreInput {
90
90
  } = {}
91
91
  ): this {
92
92
  super.map(data, options);
93
- this.sort = ModelHelper.maps(data.sort, SortInput, options.cloneDeep);
93
+ this.sort = maps(data.sort, SortInput, options.cloneDeep);
94
94
  Object.keys(this).forEach((key) => this[key] === undefined && delete this[key]);
95
95
  return this;
96
96
  }
@@ -1,6 +1,8 @@
1
1
  import 'reflect-metadata';
2
2
  import { UnauthorizedException } from '@nestjs/common';
3
3
  import { RoleEnum } from '../enums/role.enum';
4
+ import { equalIds, getStringIds } from '../helpers/db.helper';
5
+ import { IdsType } from '../types/ids.type';
4
6
 
5
7
  /**
6
8
  * Restricted meta key
@@ -28,11 +30,14 @@ export const getRestricted = (object: unknown, propertyKey: string) => {
28
30
 
29
31
  /**
30
32
  * Check data for restricted properties (properties with `Restricted` decorator)
33
+ *
34
+ * If restricted roles includes RoleEnum.S_CREATOR, `creator` (createdBy) from current (DB) data must be set in options
35
+ * If restricted roles includes RoleEnum.S_OWNER, `ownerIds` from current (DB) data must be set in options
31
36
  */
32
37
  export const checkRestricted = (
33
38
  data: any,
34
39
  user: { id: any; hasRole: (roles: string[]) => boolean },
35
- options: { ignoreUndefined?: boolean; throwError?: boolean } = {},
40
+ options: { creator?: IdsType; ignoreUndefined?: boolean; ownerIds?: IdsType; throwError?: boolean } = {},
36
41
  processedObjects: any[] = []
37
42
  ) => {
38
43
  const config = {
@@ -55,7 +60,7 @@ export const checkRestricted = (
55
60
  // Array
56
61
  if (Array.isArray(data)) {
57
62
  // Check array items
58
- return data.map((item) => checkRestricted(item, user, options, processedObjects));
63
+ return data.map((item) => checkRestricted(item, user, config, processedObjects));
59
64
  }
60
65
 
61
66
  // Object
@@ -72,20 +77,27 @@ export const checkRestricted = (
72
77
  if (roles && roles.some((value) => !!value)) {
73
78
  // Check user and user roles
74
79
  if (!user || !user.hasRole(roles)) {
75
- // Check special role for owner
76
- if (user && roles.includes(RoleEnum.OWNER)) {
77
- const userId = user.id.toString();
80
+ // Check special creator role
81
+ if (user?.id && roles.includes(RoleEnum.S_CREATOR) && equalIds(user.id, config.creator)) {
82
+ continue;
83
+ }
84
+
85
+ // Check special owner role
86
+ else if (user && roles.includes(RoleEnum.S_OWNER)) {
87
+ const userId = getStringIds(user);
88
+ const ownerIds = config.ownerIds ? getStringIds(config.ownerIds) : null;
78
89
 
79
90
  if (
80
- !data.ownerIds ||
81
- !(
82
- data.ownerIds === userId ||
83
- (Array.isArray(data.ownerIds) &&
84
- data.ownerIds.some((item) => (item.id ? item.id.toString() === userId : item.toString() === userId)))
85
- )
91
+ // No owner IDs
92
+ !ownerIds ||
93
+ // User is not the owner
94
+ !(ownerIds === userId || (Array.isArray(ownerIds) && ownerIds.includes(userId)))
86
95
  ) {
87
96
  // The user does not have the required rights and is not the owner
88
97
  if (config.throwError) {
98
+ if (!config.ownerIds) {
99
+ throw new UnauthorizedException('Lack of ownerIds to verify ownership of ' + propertyKey);
100
+ }
89
101
  throw new UnauthorizedException('Current user is not allowed to set ' + propertyKey);
90
102
  }
91
103
  continue;
@@ -101,7 +113,7 @@ export const checkRestricted = (
101
113
  }
102
114
 
103
115
  // Check property data
104
- data[propertyKey] = checkRestricted(data[propertyKey], user, options, processedObjects);
116
+ data[propertyKey] = checkRestricted(data[propertyKey], user, config, processedObjects);
105
117
  }
106
118
 
107
119
  // Return processed data
@@ -2,12 +2,30 @@
2
2
  * Enums for role decorator
3
3
  */
4
4
  export enum RoleEnum {
5
- // User must be an administrator
5
+ // ===================================================================================================================
6
+ // Real roles (integrated into user.roles), which can be used via @Roles for Models (properties)
7
+ // and Resolvers (methods)
8
+ // ===================================================================================================================
9
+
10
+ // User must be an administrator (see roles of user)
6
11
  ADMIN = 'admin',
7
12
 
8
- // User must be the owner of the processed object(s)
9
- OWNER = 'owner',
13
+ // ===================================================================================================================
14
+ // Special system roles, which can be used via @Roles for Models (properties) and Resolvers (methods)
15
+ // and via ServiceOptions for Resolver methods. This roles should not be integrated into user.roles!
16
+ // ===================================================================================================================
17
+
18
+ // User must be signed in (see context user, e.g. @GraphQLUser)
19
+ S_USER = 's_user',
20
+
21
+ // ===================================================================================================================
22
+ // Special system roles that check rights for DB objects and can be used via @Roles for Models (properties)
23
+ // and via ServiceOptions for Resolver methods. These roles should not be integrated in user.roles!
24
+ // ===================================================================================================================
25
+
26
+ // User must be the creator of the processed object(s) (see createdBy property of object(s))
27
+ S_CREATOR = 's_creator',
10
28
 
11
- // User must be signed in
12
- USER = 'user',
29
+ // User must be an owner of the processed object(s) (see owners property of object(s))
30
+ S_OWNER = 's_owner',
13
31
  }
@@ -2,8 +2,9 @@ import * as _ from 'lodash';
2
2
 
3
3
  /**
4
4
  * Helper class for configurations
5
+ * @deprecated use functions directly
5
6
  */
6
- export class Config {
7
+ export default class Config {
7
8
  /**
8
9
  * Special merge function (e.g. for configurations)
9
10
  *
@@ -19,10 +20,29 @@ export class Config {
19
20
  * @returns {any}
20
21
  */
21
22
  public static merge(obj: Record<string, any>, ...sources: any[]): any {
22
- return _.mergeWith(obj, ...sources, (objValue: any, srcValue: any) => {
23
- if (Array.isArray(srcValue)) {
24
- return srcValue;
25
- }
26
- });
23
+ return merge(obj, sources);
27
24
  }
28
25
  }
26
+
27
+ /**
28
+ * Special merge function (e.g. for configurations)
29
+ *
30
+ * It acts like the merge function of lodash:
31
+ * - Source objects are merged into the destination object
32
+ * - Source objects are applied from left to right
33
+ * - Subsequent sources overwrite property assignments of previous sources
34
+ *
35
+ * except that arrays are not merged but overwrite arrays of previous sources.
36
+ *
37
+ * @param {any} obj destination object
38
+ * @param {any[]} sources source objects
39
+ * @returns {any}
40
+ */
41
+
42
+ export function merge(obj: Record<string, any>, ...sources: any[]): any {
43
+ return _.mergeWith(obj, ...sources, (objValue: any, srcValue: any) => {
44
+ if (Array.isArray(srcValue)) {
45
+ return srcValue;
46
+ }
47
+ });
48
+ }
@@ -3,48 +3,57 @@ import { GqlExecutionContext } from '@nestjs/graphql';
3
3
 
4
4
  /**
5
5
  * Helper for context processing
6
+ * @deprecated use functions directly
6
7
  */
7
- export class Context {
8
+ export default class Context {
8
9
  /**
9
10
  * Get data from Context
11
+ * @deprecated use getContextData function
10
12
  */
11
13
  public static getData(context: ExecutionContext): { currentUser: { [key: string]: any }; args: any } {
12
- // Check context
13
- if (!context) {
14
- return { currentUser: null, args: null };
15
- }
14
+ return getContextData(context);
15
+ }
16
+ }
16
17
 
17
- // Init data
18
- let user: { [key: string]: any };
19
- let ctx: any = null;
20
- try {
21
- ctx = GqlExecutionContext.create(context)?.getContext();
22
- } catch (e) {
23
- // console.log(e);
24
- }
18
+ /**
19
+ * Get data from Context
20
+ */
21
+ export function getContextData(context: ExecutionContext): { currentUser: { [key: string]: any }; args: any } {
22
+ // Check context
23
+ if (!context) {
24
+ return { currentUser: null, args: null };
25
+ }
25
26
 
26
- let args: any;
27
- try {
28
- args = GqlExecutionContext.create(context)?.getArgs();
29
- } catch (e) {
30
- // console.log(e);
31
- }
27
+ // Init data
28
+ let user: { [key: string]: any };
29
+ let ctx: any = null;
30
+ try {
31
+ ctx = GqlExecutionContext.create(context)?.getContext();
32
+ } catch (e) {
33
+ // console.log(e);
34
+ }
35
+
36
+ let args: any;
37
+ try {
38
+ args = GqlExecutionContext.create(context)?.getArgs();
39
+ } catch (e) {
40
+ // console.log(e);
41
+ }
32
42
 
33
- // Get data
34
- if (ctx) {
35
- // User from GraphQL context
36
- user = ctx?.user || ctx?.req?.user;
37
- } else {
38
- const request = context?.switchToHttp ? context.switchToHttp()?.getRequest() : null;
39
- if (request) {
40
- args = request.body;
43
+ // Get data
44
+ if (ctx) {
45
+ // User from GraphQL context
46
+ user = ctx?.user || ctx?.req?.user;
47
+ } else {
48
+ const request = context?.switchToHttp ? context.switchToHttp()?.getRequest() : null;
49
+ if (request) {
50
+ args = request.body;
41
51
 
42
- // User from REST context
43
- user = request.user;
44
- }
52
+ // User from REST context
53
+ user = request.user;
45
54
  }
46
-
47
- // Return data
48
- return { currentUser: user, args };
49
55
  }
56
+
57
+ // Return data
58
+ return { currentUser: user, args };
50
59
  }