@strapi/utils 4.0.0-beta.11 → 4.0.0-beta.15
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/lib/content-types.js +16 -4
- package/lib/index.js +2 -0
- package/lib/{sanitize/utils.js → pipe-async.js} +1 -5
- package/lib/policy.js +53 -44
- package/lib/sanitize/index.js +7 -19
- package/lib/sanitize/sanitizers.js +26 -0
- package/lib/sanitize/visitors/allowed-fields.js +1 -1
- package/package.json +2 -2
package/lib/content-types.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const _ = require('lodash');
|
|
4
|
+
const { has } = require('lodash/fp');
|
|
4
5
|
|
|
5
6
|
const SINGLE_TYPE = 'singleType';
|
|
6
7
|
const COLLECTION_TYPE = 'collectionType';
|
|
@@ -31,8 +32,18 @@ const constants = {
|
|
|
31
32
|
COLLECTION_TYPE,
|
|
32
33
|
};
|
|
33
34
|
|
|
34
|
-
const getTimestamps =
|
|
35
|
-
|
|
35
|
+
const getTimestamps = model => {
|
|
36
|
+
const attributes = [];
|
|
37
|
+
|
|
38
|
+
if (has(CREATED_AT_ATTRIBUTE, model.attributes)) {
|
|
39
|
+
attributes.push(CREATED_AT_ATTRIBUTE);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
if (has(UPDATED_AT_ATTRIBUTE, model.attributes)) {
|
|
43
|
+
attributes.push(UPDATED_AT_ATTRIBUTE);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
return attributes;
|
|
36
47
|
};
|
|
37
48
|
|
|
38
49
|
const getNonWritableAttributes = (model = {}) => {
|
|
@@ -42,7 +53,7 @@ const getNonWritableAttributes = (model = {}) => {
|
|
|
42
53
|
[]
|
|
43
54
|
);
|
|
44
55
|
|
|
45
|
-
return _.uniq([ID_ATTRIBUTE, ...getTimestamps(), ...nonWritableAttributes]);
|
|
56
|
+
return _.uniq([ID_ATTRIBUTE, ...getTimestamps(model), ...nonWritableAttributes]);
|
|
46
57
|
};
|
|
47
58
|
|
|
48
59
|
const getWritableAttributes = (model = {}) => {
|
|
@@ -60,7 +71,7 @@ const getNonVisibleAttributes = model => {
|
|
|
60
71
|
[]
|
|
61
72
|
);
|
|
62
73
|
|
|
63
|
-
return _.uniq([ID_ATTRIBUTE, ...getTimestamps(), ...nonVisibleAttributes]);
|
|
74
|
+
return _.uniq([ID_ATTRIBUTE, ...getTimestamps(model), ...nonVisibleAttributes]);
|
|
64
75
|
};
|
|
65
76
|
|
|
66
77
|
const getVisibleAttributes = model => {
|
|
@@ -137,6 +148,7 @@ module.exports = {
|
|
|
137
148
|
isWritableAttribute,
|
|
138
149
|
getNonVisibleAttributes,
|
|
139
150
|
getVisibleAttributes,
|
|
151
|
+
getTimestamps,
|
|
140
152
|
isVisibleAttribute,
|
|
141
153
|
hasDraftAndPublish,
|
|
142
154
|
isDraft,
|
package/lib/index.js
CHANGED
|
@@ -33,6 +33,7 @@ const providerFactory = require('./provider-factory');
|
|
|
33
33
|
const pagination = require('./pagination');
|
|
34
34
|
const sanitize = require('./sanitize');
|
|
35
35
|
const traverseEntity = require('./traverse-entity');
|
|
36
|
+
const pipeAsync = require('./pipe-async');
|
|
36
37
|
|
|
37
38
|
module.exports = {
|
|
38
39
|
yup,
|
|
@@ -66,6 +67,7 @@ module.exports = {
|
|
|
66
67
|
hooks,
|
|
67
68
|
providerFactory,
|
|
68
69
|
pagination,
|
|
70
|
+
pipeAsync,
|
|
69
71
|
errors,
|
|
70
72
|
validateYupSchema,
|
|
71
73
|
validateYupSchemaSync,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
module.exports = (...methods) => async data => {
|
|
4
4
|
let res = data;
|
|
5
5
|
|
|
6
6
|
for (const method of methods) {
|
|
@@ -9,7 +9,3 @@ const pipeAsync = (...methods) => async data => {
|
|
|
9
9
|
|
|
10
10
|
return res;
|
|
11
11
|
};
|
|
12
|
-
|
|
13
|
-
module.exports = {
|
|
14
|
-
pipeAsync,
|
|
15
|
-
};
|
package/lib/policy.js
CHANGED
|
@@ -9,36 +9,22 @@ const { eq } = require('lodash/fp');
|
|
|
9
9
|
const PLUGIN_PREFIX = 'plugin::';
|
|
10
10
|
const API_PREFIX = 'api::';
|
|
11
11
|
|
|
12
|
-
const createPolicy = (policyName, config) => ({ policyName, config });
|
|
13
|
-
|
|
14
|
-
const resolveHandler = policy => {
|
|
15
|
-
return _.has('handler', policy) ? policy.handler : policy;
|
|
16
|
-
};
|
|
17
|
-
|
|
18
12
|
const parsePolicy = policy => {
|
|
19
13
|
if (typeof policy === 'string') {
|
|
20
|
-
return
|
|
14
|
+
return { policyName: policy, config: {} };
|
|
21
15
|
}
|
|
22
16
|
|
|
23
|
-
const { name, config
|
|
24
|
-
return
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
const resolvePolicy = policyName => {
|
|
28
|
-
const policy = strapi.policy(policyName);
|
|
29
|
-
|
|
30
|
-
return resolveHandler(policy);
|
|
17
|
+
const { name, config } = policy;
|
|
18
|
+
return { policyName: name, config };
|
|
31
19
|
};
|
|
32
20
|
|
|
33
21
|
const searchLocalPolicy = (policyName, { pluginName, apiName }) => {
|
|
34
22
|
if (pluginName) {
|
|
35
|
-
|
|
36
|
-
return resolveHandler(policy);
|
|
23
|
+
return strapi.policy(`${PLUGIN_PREFIX}${pluginName}.${policyName}`);
|
|
37
24
|
}
|
|
38
25
|
|
|
39
26
|
if (apiName) {
|
|
40
|
-
|
|
41
|
-
return resolveHandler(policy);
|
|
27
|
+
return strapi.policy(`${API_PREFIX}${apiName}.${policyName}`);
|
|
42
28
|
}
|
|
43
29
|
};
|
|
44
30
|
|
|
@@ -56,45 +42,68 @@ const globalPolicy = ({ method, endpoint, controller, action, plugin }) => {
|
|
|
56
42
|
};
|
|
57
43
|
};
|
|
58
44
|
|
|
59
|
-
const
|
|
60
|
-
|
|
61
|
-
return
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
45
|
+
const resolvePolicies = (config, { pluginName, apiName } = {}) => {
|
|
46
|
+
return config.map(policyConfig => {
|
|
47
|
+
return {
|
|
48
|
+
handler: getPolicy(policyConfig, { pluginName, apiName }),
|
|
49
|
+
config: policyConfig.config || {},
|
|
50
|
+
};
|
|
51
|
+
});
|
|
52
|
+
};
|
|
65
53
|
|
|
66
|
-
|
|
54
|
+
const findPolicy = (name, { pluginName, apiName } = {}) => {
|
|
55
|
+
const resolvedPolicy = strapi.policy(name);
|
|
67
56
|
|
|
68
57
|
if (resolvedPolicy !== undefined) {
|
|
69
|
-
return
|
|
58
|
+
return resolvedPolicy;
|
|
70
59
|
}
|
|
71
60
|
|
|
72
|
-
const localPolicy = searchLocalPolicy(
|
|
61
|
+
const localPolicy = searchLocalPolicy(name, { pluginName, apiName });
|
|
73
62
|
|
|
74
63
|
if (localPolicy !== undefined) {
|
|
75
64
|
return localPolicy;
|
|
76
65
|
}
|
|
77
66
|
|
|
78
|
-
throw new Error(`Could not find policy "${
|
|
67
|
+
throw new Error(`Could not find policy "${name}"`);
|
|
79
68
|
};
|
|
80
69
|
|
|
81
|
-
const
|
|
82
|
-
|
|
70
|
+
const getPolicy = (policyConfig, { pluginName, apiName } = {}) => {
|
|
71
|
+
if (typeof policyConfig === 'function') {
|
|
72
|
+
return policyConfig;
|
|
73
|
+
}
|
|
83
74
|
|
|
84
|
-
const
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
} catch (e) {
|
|
88
|
-
throw new Error(`Invalid objects submitted to "${name}" policy.`);
|
|
89
|
-
}
|
|
90
|
-
};
|
|
75
|
+
const { policyName, config } = parsePolicy(policyConfig);
|
|
76
|
+
|
|
77
|
+
const policy = findPolicy(policyName, { pluginName, apiName });
|
|
91
78
|
|
|
92
|
-
|
|
79
|
+
if (typeof policy === 'function') {
|
|
80
|
+
return policy;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
if (policy.validator) {
|
|
84
|
+
policy.validator(config);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
return policy.handler;
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
const createPolicy = options => {
|
|
91
|
+
const { name = 'unnamed', validator, handler } = options;
|
|
92
|
+
|
|
93
|
+
const wrappedValidator = config => {
|
|
93
94
|
if (validator) {
|
|
94
|
-
|
|
95
|
+
try {
|
|
96
|
+
validator(config);
|
|
97
|
+
} catch (e) {
|
|
98
|
+
throw new Error(`Invalid config passed to "${name}" policy.`);
|
|
99
|
+
}
|
|
95
100
|
}
|
|
101
|
+
};
|
|
96
102
|
|
|
97
|
-
|
|
103
|
+
return {
|
|
104
|
+
name,
|
|
105
|
+
validator: wrappedValidator,
|
|
106
|
+
handler,
|
|
98
107
|
};
|
|
99
108
|
};
|
|
100
109
|
|
|
@@ -102,7 +111,6 @@ const createPolicyContext = (type, ctx) => {
|
|
|
102
111
|
return Object.assign(
|
|
103
112
|
{
|
|
104
113
|
is: eq(type),
|
|
105
|
-
|
|
106
114
|
get type() {
|
|
107
115
|
return type;
|
|
108
116
|
},
|
|
@@ -112,8 +120,9 @@ const createPolicyContext = (type, ctx) => {
|
|
|
112
120
|
};
|
|
113
121
|
|
|
114
122
|
module.exports = {
|
|
115
|
-
get,
|
|
123
|
+
get: getPolicy,
|
|
124
|
+
resolve: resolvePolicies,
|
|
116
125
|
globalPolicy,
|
|
117
|
-
|
|
126
|
+
createPolicy,
|
|
118
127
|
createPolicyContext,
|
|
119
128
|
};
|
package/lib/sanitize/index.js
CHANGED
|
@@ -4,8 +4,10 @@ const { isArray } = require('lodash/fp');
|
|
|
4
4
|
|
|
5
5
|
const traverseEntity = require('../traverse-entity');
|
|
6
6
|
const { getNonWritableAttributes } = require('../content-types');
|
|
7
|
+
const pipeAsync = require('../pipe-async');
|
|
8
|
+
|
|
7
9
|
const visitors = require('./visitors');
|
|
8
|
-
const
|
|
10
|
+
const sanitizers = require('./sanitizers');
|
|
9
11
|
|
|
10
12
|
module.exports = {
|
|
11
13
|
contentAPI: {
|
|
@@ -26,7 +28,7 @@ module.exports = {
|
|
|
26
28
|
transforms.push(traverseEntity(visitors.removeRestrictedRelations(auth), { schema }));
|
|
27
29
|
}
|
|
28
30
|
|
|
29
|
-
return
|
|
31
|
+
return pipeAsync(...transforms)(data);
|
|
30
32
|
},
|
|
31
33
|
|
|
32
34
|
output(data, schema, { auth } = {}) {
|
|
@@ -34,30 +36,16 @@ module.exports = {
|
|
|
34
36
|
return Promise.all(data.map(entry => this.output(entry, schema, { auth })));
|
|
35
37
|
}
|
|
36
38
|
|
|
37
|
-
const transforms = [
|
|
38
|
-
traverseEntity(visitors.removePassword, { schema }),
|
|
39
|
-
traverseEntity(visitors.removePrivate, { schema }),
|
|
40
|
-
];
|
|
39
|
+
const transforms = [sanitizers.defaultSanitizeOutput(schema)];
|
|
41
40
|
|
|
42
41
|
if (auth) {
|
|
43
42
|
transforms.push(traverseEntity(visitors.removeRestrictedRelations(auth), { schema }));
|
|
44
43
|
}
|
|
45
44
|
|
|
46
|
-
return
|
|
45
|
+
return pipeAsync(...transforms)(data);
|
|
47
46
|
},
|
|
48
47
|
},
|
|
49
48
|
|
|
50
|
-
|
|
51
|
-
if (isArray(data)) {
|
|
52
|
-
return Promise.all(data.map(entry => this.eventHub(entry, schema)));
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
return utils.pipeAsync(
|
|
56
|
-
traverseEntity(visitors.removePassword, { schema }),
|
|
57
|
-
traverseEntity(visitors.removePrivate, { schema })
|
|
58
|
-
)(data);
|
|
59
|
-
},
|
|
60
|
-
|
|
61
|
-
utils,
|
|
49
|
+
sanitizers,
|
|
62
50
|
visitors,
|
|
63
51
|
};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const { curry } = require('lodash/fp');
|
|
4
|
+
|
|
5
|
+
const pipeAsync = require('../pipe-async');
|
|
6
|
+
const traverseEntity = require('../traverse-entity');
|
|
7
|
+
|
|
8
|
+
const { removePassword, removePrivate } = require('./visitors');
|
|
9
|
+
|
|
10
|
+
const sanitizePasswords = curry((schema, entity) => {
|
|
11
|
+
return traverseEntity(removePassword, { schema }, entity);
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
const sanitizePrivates = curry((schema, entity) => {
|
|
15
|
+
return traverseEntity(removePrivate, { schema }, entity);
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
const defaultSanitizeOutput = curry((schema, entity) => {
|
|
19
|
+
return pipeAsync(sanitizePrivates(schema), sanitizePasswords(schema))(entity);
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
module.exports = {
|
|
23
|
+
sanitizePasswords,
|
|
24
|
+
sanitizePrivates,
|
|
25
|
+
defaultSanitizeOutput,
|
|
26
|
+
};
|
|
@@ -16,7 +16,7 @@ module.exports = (allowedFields = null) => ({ key, path }, { remove }) => {
|
|
|
16
16
|
const containedPaths = getContainedPaths(path);
|
|
17
17
|
|
|
18
18
|
/**
|
|
19
|
-
* Tells if the current path should be
|
|
19
|
+
* Tells if the current path should be kept or not based
|
|
20
20
|
* on the success of the check functions for any of the allowed paths.
|
|
21
21
|
*
|
|
22
22
|
* The check functions are defined as follow:
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@strapi/utils",
|
|
3
|
-
"version": "4.0.0-beta.
|
|
3
|
+
"version": "4.0.0-beta.15",
|
|
4
4
|
"description": "Shared utilities for the Strapi packages",
|
|
5
5
|
"homepage": "https://strapi.io",
|
|
6
6
|
"keywords": [
|
|
@@ -42,5 +42,5 @@
|
|
|
42
42
|
"npm": ">=6.0.0"
|
|
43
43
|
},
|
|
44
44
|
"license": "SEE LICENSE IN LICENSE",
|
|
45
|
-
"gitHead": "
|
|
45
|
+
"gitHead": "c69713bf7f437a7cee66ffdeed95227d6246a872"
|
|
46
46
|
}
|