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 +17 -17
- package/src/auth/const.js +1 -0
- package/src/manifest/manifest.filter.js +106 -7
- package/src/manifest/result.filter.js +28 -2
- package/src/manifest/route.js +19 -2
- package/src/types.js +13 -0
- package/test/result.filter.js +3 -3
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "not-node",
|
|
3
|
-
"version": "6.3.
|
|
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.
|
|
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.
|
|
47
|
+
"ejs": "^3.1.10",
|
|
48
48
|
"escape-string-regexp": "*",
|
|
49
|
-
"express": "^4.19.
|
|
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.
|
|
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.
|
|
69
|
-
"redis": "^4.6.
|
|
68
|
+
"rate-limiter-flexible": "^5.0.3",
|
|
69
|
+
"redis": "^4.6.15",
|
|
70
70
|
"redlock": "^5.0.0-beta.2",
|
|
71
|
-
"rfdc": "^1.
|
|
72
|
-
"rimraf": "^5.0.
|
|
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": "^
|
|
83
|
+
"eslint": "^9.6.0",
|
|
84
84
|
"eslint-plugin-node": "^11.1.0",
|
|
85
|
-
"eslint-plugin-sonarjs": "^0.
|
|
85
|
+
"eslint-plugin-sonarjs": "^1.0.3",
|
|
86
86
|
"husky": "^9.0.11",
|
|
87
87
|
"ink-docstrap": "^1.3.2",
|
|
88
|
-
"ioredis": "^5.
|
|
89
|
-
"jsdoc": "^4.0.
|
|
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.
|
|
94
|
-
"mongoose": "^8.
|
|
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": "^
|
|
99
|
-
"retire": "^
|
|
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
|
@@ -95,7 +95,10 @@ module.exports = class notManifestFilter {
|
|
|
95
95
|
root,
|
|
96
96
|
modelName,
|
|
97
97
|
moduleName,
|
|
98
|
-
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:
|
|
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
|
-
|
|
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(
|
|
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
|
-
|
|
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(
|
package/src/manifest/route.js
CHANGED
|
@@ -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
|
|
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(
|
|
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
|
*/
|
package/test/result.filter.js
CHANGED
|
@@ -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 },
|