not-node 6.3.78 → 6.3.80

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "not-node",
3
- "version": "6.3.78",
3
+ "version": "6.3.80",
4
4
  "description": "node complimentary part for client side notFramework.",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -37,22 +37,22 @@
37
37
  },
38
38
  "dependencies": {
39
39
  "body-parser": "^1.20.2",
40
- "commander": "^12.0.0",
40
+ "commander": "^12.1.0",
41
41
  "compression": "^1.7.4",
42
42
  "connect-mongodb-session": "^5.0.0",
43
43
  "connect-redis": "^7.1.1",
44
44
  "cors": "^2.8.5",
45
45
  "deep-diff": "*",
46
46
  "deepmerge": "^4.3.1",
47
- "ejs": "^3.1.9",
47
+ "ejs": "^3.1.10",
48
48
  "escape-string-regexp": "*",
49
- "express": "^4.19.1",
49
+ "express": "^4.19.2",
50
50
  "express-fileupload": "^1.5.0",
51
51
  "express-session": "^1.18.0",
52
52
  "fs-extra": "*",
53
53
  "generate-password": "^1.7.1",
54
54
  "helmet": "^7.1.0",
55
- "inquirer": "^9.2.16",
55
+ "inquirer": "^9.3.4",
56
56
  "jsonwebtoken": "^9.0.2",
57
57
  "lower-case": "*",
58
58
  "method-override": "^3.0.0",
@@ -65,11 +65,11 @@
65
65
  "not-log": "*",
66
66
  "not-monitor": "*",
67
67
  "not-path": "*",
68
- "rate-limiter-flexible": "^5.0.0",
69
- "redis": "^4.6.13",
68
+ "rate-limiter-flexible": "^5.0.3",
69
+ "redis": "^4.6.15",
70
70
  "redlock": "^5.0.0-beta.2",
71
- "rfdc": "^1.3.1",
72
- "rimraf": "^5.0.5",
71
+ "rfdc": "^1.4.1",
72
+ "rimraf": "^5.0.8",
73
73
  "serve-static": "*",
74
74
  "simple-git": "*",
75
75
  "validator": "*",
@@ -80,23 +80,23 @@
80
80
  "babel-eslint": "^10.1.0",
81
81
  "chai": "*",
82
82
  "chai-as-promised": "*",
83
- "eslint": "^8.57.0",
83
+ "eslint": "^9.6.0",
84
84
  "eslint-plugin-node": "^11.1.0",
85
- "eslint-plugin-sonarjs": "^0.24.0",
85
+ "eslint-plugin-sonarjs": "^1.0.3",
86
86
  "husky": "^9.0.11",
87
87
  "ink-docstrap": "^1.3.2",
88
- "ioredis": "^5.3.2",
89
- "jsdoc": "^4.0.2",
88
+ "ioredis": "^5.4.1",
89
+ "jsdoc": "^4.0.3",
90
90
  "mocha": "*",
91
91
  "mocha-suppress-logs": "^0.5.1",
92
92
  "mock-require": "^3.0.3",
93
- "mongodb-memory-server": "^9.1.7",
94
- "mongoose": "^8.2.3",
93
+ "mongodb-memory-server": "^9.4.0",
94
+ "mongoose": "^8.4.5",
95
95
  "not-error": "^0.2.9",
96
96
  "not-validation": "^0.0.9",
97
97
  "npm-run-all": "^4.1.5",
98
- "nyc": "^15.1.0",
99
- "retire": "^4.4.2"
98
+ "nyc": "^17.0.0",
99
+ "retire": "^5.1.1"
100
100
  },
101
101
  "homepage": "https://github.com/interrupter/not-node#readme",
102
102
  "nyc": {
package/src/auth/const.js CHANGED
@@ -23,6 +23,7 @@ const METHOD_SIGNAURES = {
23
23
  GET: ACTION_SIGNATURES.READ,
24
24
  PUT: ACTION_SIGNATURES.CREATE,
25
25
  POST: ACTION_SIGNATURES.UPDATE,
26
+ PATCH: ACTION_SIGNATURES.UPDATE,
26
27
  DELETE: ACTION_SIGNATURES.DELETE,
27
28
  };
28
29
 
@@ -95,7 +95,10 @@ module.exports = class notManifestFilter {
95
95
  root,
96
96
  modelName,
97
97
  moduleName,
98
- actionSignature: actionSet.actionSignature,
98
+ actionSignature:
99
+ notManifestFilter.detectActionSignature(
100
+ actionSet
101
+ ),
99
102
  }
100
103
  );
101
104
  break;
@@ -113,7 +116,10 @@ module.exports = class notManifestFilter {
113
116
  root,
114
117
  modelName,
115
118
  moduleName,
116
- actionSignature: actionSet.actionSignature,
119
+ actionSignature:
120
+ notManifestFilter.detectActionSignature(
121
+ actionSet
122
+ ),
117
123
  }
118
124
  );
119
125
  }
@@ -165,6 +171,24 @@ module.exports = class notManifestFilter {
165
171
  );
166
172
  }
167
173
 
174
+ /**
175
+ * Return true if ruleSet object has not empty list of return and return is an Array<string>
176
+ * @param {Object} ruleSet specific set of rules for action
177
+ * @return {boolean} if rule set has not empty fields list
178
+ */
179
+ static ruleSetHasReturnDirectiveInAllStringFormat(ruleSet) {
180
+ return (
181
+ typeof ruleSet !== "undefined" &&
182
+ ruleSet !== null &&
183
+ ruleSet.return &&
184
+ Array.isArray(ruleSet.return) &&
185
+ ruleSet.return.length &&
186
+ ruleSet.return.every(
187
+ (returnFieldName) => typeof returnFieldName === "string"
188
+ )
189
+ );
190
+ }
191
+
168
192
  static composeFullModelName(moduleName, modelName) {
169
193
  if (modelName) {
170
194
  if (moduleName) {
@@ -184,6 +208,69 @@ module.exports = class notManifestFilter {
184
208
  }
185
209
  }
186
210
 
211
+ /**
212
+ *
213
+ * Returns Action signature for action
214
+ * @static
215
+ * @param {import('../types').notActionData} action
216
+ * @return {string}
217
+ */
218
+ static detectActionSignature(action) {
219
+ if (action) {
220
+ switch (action?.method?.toLocaleLowerCase()) {
221
+ case "get":
222
+ return Auth.ACTION_SIGNATURES.READ;
223
+
224
+ case "post":
225
+ case "patch":
226
+ return Auth.ACTION_SIGNATURES.UPDATE;
227
+
228
+ case "put":
229
+ return Auth.ACTION_SIGNATURES.CREATE;
230
+
231
+ case "delete":
232
+ return Auth.ACTION_SIGNATURES.DELETE;
233
+
234
+ default:
235
+ return Auth.ACTION_SIGNATURES.READ;
236
+ }
237
+ }
238
+ return Auth.ACTION_SIGNATURES.READ;
239
+ }
240
+
241
+ static filterReturnSet(
242
+ returnSet,
243
+ modelSchema,
244
+ {
245
+ auth = false,
246
+ role = [Auth.DEFAULT_USER_ROLE_FOR_GUEST],
247
+ root = false,
248
+ modelName = "",
249
+ actionSignature = undefined,
250
+ } = {
251
+ auth: false,
252
+ role: [Auth.DEFAULT_USER_ROLE_FOR_GUEST],
253
+ root: false,
254
+ modelName: "",
255
+ actionSignature: undefined,
256
+ }
257
+ ) {
258
+ if (
259
+ notManifestFilter.ruleSetHasReturnDirectiveInAllStringFormat({
260
+ return: returnSet,
261
+ })
262
+ ) {
263
+ return notFieldsFilter.filter([...returnSet], modelSchema, {
264
+ action: actionSignature,
265
+ roles: role,
266
+ auth,
267
+ root,
268
+ modelName,
269
+ });
270
+ }
271
+ return returnSet;
272
+ }
273
+
187
274
  /**
188
275
  * Clear action definition from rules of access
189
276
  * @param {object} action action data
@@ -221,17 +308,29 @@ module.exports = class notManifestFilter {
221
308
  //copy fields list from rule to action if it exists
222
309
  //fields list is used to restrict fields of data that could be accessed via
223
310
  //this action
311
+ const fullModelName = this.composeFullModelName(moduleName, modelName);
312
+ const modelSchema = this.loadSchema(fullModelName);
224
313
  if (notManifestFilter.ruleSetHasFieldsDirective(ruleSet)) {
225
- const fullModelName = this.composeFullModelName(
226
- moduleName,
227
- modelName
228
- );
229
314
  copy.fields = notFieldsFilter.filter(
230
315
  [...ruleSet.fields],
231
- this.loadSchema(fullModelName),
316
+ modelSchema,
232
317
  { action: actionSignature, roles: role, auth, root, modelName }
233
318
  );
234
319
  }
320
+ if (ruleSet && ruleSet.return) {
321
+ copy.return = notManifestFilter.filterReturnSet(
322
+ ruleSet.return,
323
+ modelSchema,
324
+ {
325
+ auth,
326
+ role,
327
+ root,
328
+ modelName,
329
+ moduleName,
330
+ actionSignature,
331
+ }
332
+ );
333
+ }
235
334
  return copy;
236
335
  }
237
336
 
@@ -1,5 +1,8 @@
1
1
  const notPath = require("not-path");
2
2
  const { objHas, copyObj } = require("../common");
3
+ const notManifestFilter = require("./manifest.filter");
4
+
5
+ const Auth = require("../auth/const");
3
6
 
4
7
  const PROP_NAME_RETURN_ROOT = "returnRoot"; //path to object to filter
5
8
  const PROP_NAME_RETURN_RULE = "return"; //filtering rule
@@ -62,15 +65,38 @@ module.exports = class notManifestRouteResultFilter {
62
65
  * if presented
63
66
  * @param {object} notRouteData request rules and preferencies
64
67
  * @param {object} result result returned by main action processor
68
+ * @param {import('../types').notAppIdentityShortData} identity
65
69
  */
66
- static filter(notRouteData, result) {
70
+ static filter(
71
+ notRouteData,
72
+ result,
73
+ identity = {
74
+ auth: false,
75
+ admin: false,
76
+ root: false,
77
+ primaryRole: Auth.DEFAULT_USER_ROLE_FOR_GUEST,
78
+ role: [Auth.DEFAULT_USER_ROLE_FOR_GUEST],
79
+ }
80
+ ) {
67
81
  if (!(result && typeof result === "object")) return;
68
- const filteringRule = this.getFilteringRule(notRouteData);
82
+ let filteringRule = this.getFilteringRule(notRouteData);
69
83
  if (!filteringRule) return;
70
84
  const filteringTarget = this.getFilteringTarget(result, notRouteData);
71
85
  if (!filteringTarget) {
72
86
  return;
73
87
  }
88
+ filteringRule = notManifestFilter.filterReturnSet(
89
+ filteringRule,
90
+ notManifestFilter.loadSchema(notRouteData.modelPath),
91
+ {
92
+ auth: identity.auth,
93
+ role: identity.role,
94
+ root: identity.root,
95
+ modelName: notRouteData.modelName,
96
+ moduleName: notRouteData.moduleName,
97
+ actionSignature: notRouteData.actionSignature,
98
+ }
99
+ );
74
100
  if (Array.isArray(filteringTarget)) {
75
101
  filteringTarget.forEach((filteringTargetItem) => {
76
102
  this.filterByRule(
@@ -8,7 +8,13 @@ const Auth = require("../auth"),
8
8
  HttpError = require("../error").Http;
9
9
 
10
10
  const notManifestRouteResultFilter = require("./result.filter");
11
- const { copyObj, executeObjectFunction } = require("../common");
11
+ const notManifestFilter = require("./manifest.filter");
12
+
13
+ const {
14
+ copyObj,
15
+ executeObjectFunction,
16
+ firstLetterToUpper,
17
+ } = require("../common");
12
18
 
13
19
  /**
14
20
  * Route representation
@@ -105,8 +111,15 @@ class notRoute {
105
111
  return {
106
112
  actionName,
107
113
  modelName: this.routeName,
114
+ moduleName: this.moduleName,
115
+ modelPath: `${this.moduleName}//${firstLetterToUpper(
116
+ this.routeName
117
+ )}`,
108
118
  rule: copyObj(rule),
109
119
  actionData: copyObj(this.actionData),
120
+ actionSignature: notManifestFilter.detectActionSignature(
121
+ this.actionData
122
+ ),
110
123
  };
111
124
  }
112
125
 
@@ -234,7 +247,11 @@ class notRoute {
234
247
  itm && itm.toObject ? itm.toObject() : itm
235
248
  );
236
249
  }
237
- notManifestRouteResultFilter.filter(req.notRouteData, result);
250
+ notManifestRouteResultFilter.filter(
251
+ req.notRouteData,
252
+ result,
253
+ notAppIdentity.extractAuthData(req)
254
+ );
238
255
  }
239
256
  //run after with results, continue without waiting when it finished
240
257
  if (modRoute[CONST_AFTER_ACTION]) {
package/src/types.js CHANGED
@@ -65,8 +65,11 @@
65
65
  * @typedef {Object} notRouteData
66
66
  * @property {string} actionName name of action
67
67
  * @property {string} modelName first letter should not be not capital
68
+ * @property {string} moduleName first letter should not be not capital
69
+ * @property {string} modelPath arg for getModel/getSchema
68
70
  * @property {notRouteRule} rule current rule
69
71
  * @property {notActionData} actionData action details
72
+ * @property {string} actionSignature action signature
70
73
  */
71
74
 
72
75
  /**
@@ -104,6 +107,16 @@
104
107
  * @property {string} provider //provider class name
105
108
  */
106
109
 
110
+ /**
111
+ *
112
+ * @typedef {object} notAppIdentityShortData
113
+ * @property {boolean} root //system configuration administrator
114
+ * @property {boolean} admin //system content administrator
115
+ * @property {boolean} auth //authenticated user
116
+ * @property {Array<string>} role //list of roles, exactly one should be primary role
117
+ * @property {string} primaryRole //primary role
118
+ */
119
+
107
120
  /**
108
121
  * @typedef {string|function} notAppFormPropertyProcessingPipeInstruction
109
122
  */
@@ -23,7 +23,7 @@ describe("notManifestRouteResultFilter", function () {
23
23
  const notRouteData = {
24
24
  rule: { returnRoot: "result", return: ["some"] },
25
25
  };
26
- notManifestRouteResultFilter.filter(notRouteData, reqRes);
26
+ notManifestRouteResultFilter.filter(notRouteData, reqRes, {});
27
27
  expect(reqRes).to.be.deep.equal({ some: "data" });
28
28
  });
29
29
 
@@ -32,7 +32,7 @@ describe("notManifestRouteResultFilter", function () {
32
32
  const notRouteData = {
33
33
  rule: { return: ["some"] },
34
34
  };
35
- notManifestRouteResultFilter.filter(notRouteData, reqRes);
35
+ notManifestRouteResultFilter.filter(notRouteData, reqRes, {});
36
36
  expect(reqRes).to.be.deep.equal({ some: "data" });
37
37
  });
38
38
 
@@ -45,7 +45,7 @@ describe("notManifestRouteResultFilter", function () {
45
45
  const notRouteData = {
46
46
  rule: { return: ["id"] },
47
47
  };
48
- notManifestRouteResultFilter.filter(notRouteData, reqRes);
48
+ notManifestRouteResultFilter.filter(notRouteData, reqRes, {});
49
49
  expect(reqRes).to.be.deep.equal([
50
50
  { id: 1 },
51
51
  { id: 11 },