@strapi/utils 5.12.0 → 5.12.2
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/dist/async.js +28 -0
- package/dist/async.js.map +1 -0
- package/dist/async.mjs +24 -0
- package/dist/async.mjs.map +1 -0
- package/dist/content-types.js +201 -0
- package/dist/content-types.js.map +1 -0
- package/dist/content-types.mjs +167 -0
- package/dist/content-types.mjs.map +1 -0
- package/dist/convert-query-params.js +512 -0
- package/dist/convert-query-params.js.map +1 -0
- package/dist/convert-query-params.mjs +510 -0
- package/dist/convert-query-params.mjs.map +1 -0
- package/dist/env-helper.js +81 -0
- package/dist/env-helper.js.map +1 -0
- package/dist/env-helper.mjs +79 -0
- package/dist/env-helper.mjs.map +1 -0
- package/dist/errors.js +104 -0
- package/dist/errors.js.map +1 -0
- package/dist/errors.mjs +88 -0
- package/dist/errors.mjs.map +1 -0
- package/dist/file.js +57 -0
- package/dist/file.js.map +1 -0
- package/dist/file.mjs +50 -0
- package/dist/file.mjs.map +1 -0
- package/dist/format-yup-error.js +19 -0
- package/dist/format-yup-error.js.map +1 -0
- package/dist/format-yup-error.mjs +17 -0
- package/dist/format-yup-error.mjs.map +1 -0
- package/dist/hooks.js +86 -0
- package/dist/hooks.js.map +1 -0
- package/dist/hooks.mjs +80 -0
- package/dist/hooks.mjs.map +1 -0
- package/dist/import-default.js +9 -0
- package/dist/import-default.js.map +1 -0
- package/dist/import-default.mjs +7 -0
- package/dist/import-default.mjs.map +1 -0
- package/dist/index.js +54 -4358
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +48 -4317
- package/dist/index.mjs.map +1 -1
- package/dist/machine-id.js +17 -0
- package/dist/machine-id.js.map +1 -0
- package/dist/machine-id.mjs +15 -0
- package/dist/machine-id.mjs.map +1 -0
- package/dist/operators.js +79 -0
- package/dist/operators.js.map +1 -0
- package/dist/operators.mjs +76 -0
- package/dist/operators.mjs.map +1 -0
- package/dist/package-manager.js +36 -0
- package/dist/package-manager.js.map +1 -0
- package/dist/package-manager.mjs +33 -0
- package/dist/package-manager.mjs.map +1 -0
- package/dist/pagination.js +163 -0
- package/dist/pagination.js.map +1 -0
- package/dist/pagination.mjs +159 -0
- package/dist/pagination.mjs.map +1 -0
- package/dist/parse-type.js +140 -0
- package/dist/parse-type.js.map +1 -0
- package/dist/parse-type.mjs +118 -0
- package/dist/parse-type.mjs.map +1 -0
- package/dist/policy.js +33 -0
- package/dist/policy.js.map +1 -0
- package/dist/policy.mjs +30 -0
- package/dist/policy.mjs.map +1 -0
- package/dist/primitives/arrays.js +7 -0
- package/dist/primitives/arrays.js.map +1 -0
- package/dist/primitives/arrays.mjs +5 -0
- package/dist/primitives/arrays.mjs.map +1 -0
- package/dist/primitives/dates.js +11 -0
- package/dist/primitives/dates.js.map +1 -0
- package/dist/primitives/dates.mjs +9 -0
- package/dist/primitives/dates.mjs.map +1 -0
- package/dist/primitives/objects.js +13 -0
- package/dist/primitives/objects.js.map +1 -0
- package/dist/primitives/objects.mjs +11 -0
- package/dist/primitives/objects.mjs.map +1 -0
- package/dist/primitives/strings.js +49 -0
- package/dist/primitives/strings.js.map +1 -0
- package/dist/primitives/strings.mjs +38 -0
- package/dist/primitives/strings.mjs.map +1 -0
- package/dist/print-value.js +42 -0
- package/dist/print-value.js.map +1 -0
- package/dist/print-value.mjs +40 -0
- package/dist/print-value.mjs.map +1 -0
- package/dist/provider-factory.js +82 -0
- package/dist/provider-factory.js.map +1 -0
- package/dist/provider-factory.mjs +80 -0
- package/dist/provider-factory.mjs.map +1 -0
- package/dist/relations.js +54 -0
- package/dist/relations.js.map +1 -0
- package/dist/relations.mjs +45 -0
- package/dist/relations.mjs.map +1 -0
- package/dist/sanitize/index.js +195 -0
- package/dist/sanitize/index.js.map +1 -0
- package/dist/sanitize/index.mjs +194 -0
- package/dist/sanitize/index.mjs.map +1 -0
- package/dist/sanitize/sanitizers.js +173 -0
- package/dist/sanitize/sanitizers.js.map +1 -0
- package/dist/sanitize/sanitizers.mjs +166 -0
- package/dist/sanitize/sanitizers.mjs.map +1 -0
- package/dist/sanitize/visitors/expand-wildcard-populate.js +20 -0
- package/dist/sanitize/visitors/expand-wildcard-populate.js.map +1 -0
- package/dist/sanitize/visitors/expand-wildcard-populate.mjs +18 -0
- package/dist/sanitize/visitors/expand-wildcard-populate.mjs.map +1 -0
- package/dist/sanitize/visitors/index.js +22 -0
- package/dist/sanitize/visitors/index.js.map +1 -0
- package/dist/sanitize/visitors/index.mjs +9 -0
- package/dist/sanitize/visitors/index.mjs.map +1 -0
- package/dist/sanitize/visitors/remove-disallowed-fields.js +87 -0
- package/dist/sanitize/visitors/remove-disallowed-fields.js.map +1 -0
- package/dist/sanitize/visitors/remove-disallowed-fields.mjs +85 -0
- package/dist/sanitize/visitors/remove-disallowed-fields.mjs.map +1 -0
- package/dist/sanitize/visitors/remove-dynamic-zones.js +12 -0
- package/dist/sanitize/visitors/remove-dynamic-zones.js.map +1 -0
- package/dist/sanitize/visitors/remove-dynamic-zones.mjs +10 -0
- package/dist/sanitize/visitors/remove-dynamic-zones.mjs.map +1 -0
- package/dist/sanitize/visitors/remove-morph-to-relations.js +12 -0
- package/dist/sanitize/visitors/remove-morph-to-relations.js.map +1 -0
- package/dist/sanitize/visitors/remove-morph-to-relations.mjs +10 -0
- package/dist/sanitize/visitors/remove-morph-to-relations.mjs.map +1 -0
- package/dist/sanitize/visitors/remove-password.js +10 -0
- package/dist/sanitize/visitors/remove-password.js.map +1 -0
- package/dist/sanitize/visitors/remove-password.mjs +8 -0
- package/dist/sanitize/visitors/remove-password.mjs.map +1 -0
- package/dist/sanitize/visitors/remove-private.js +16 -0
- package/dist/sanitize/visitors/remove-private.js.map +1 -0
- package/dist/sanitize/visitors/remove-private.mjs +14 -0
- package/dist/sanitize/visitors/remove-private.mjs.map +1 -0
- package/dist/sanitize/visitors/remove-restricted-fields.js +28 -0
- package/dist/sanitize/visitors/remove-restricted-fields.js.map +1 -0
- package/dist/sanitize/visitors/remove-restricted-fields.mjs +26 -0
- package/dist/sanitize/visitors/remove-restricted-fields.mjs.map +1 -0
- package/dist/sanitize/visitors/remove-restricted-relations.js +116 -0
- package/dist/sanitize/visitors/remove-restricted-relations.js.map +1 -0
- package/dist/sanitize/visitors/remove-restricted-relations.mjs +114 -0
- package/dist/sanitize/visitors/remove-restricted-relations.mjs.map +1 -0
- package/dist/set-creator-fields.js +18 -0
- package/dist/set-creator-fields.js.map +1 -0
- package/dist/set-creator-fields.mjs +16 -0
- package/dist/set-creator-fields.mjs.map +1 -0
- package/dist/template.js +18 -0
- package/dist/template.js.map +1 -0
- package/dist/template.mjs +15 -0
- package/dist/template.mjs.map +1 -0
- package/dist/traverse/factory.js +158 -0
- package/dist/traverse/factory.js.map +1 -0
- package/dist/traverse/factory.mjs +156 -0
- package/dist/traverse/factory.mjs.map +1 -0
- package/dist/traverse/index.js +14 -0
- package/dist/traverse/index.js.map +1 -0
- package/dist/traverse/index.mjs +5 -0
- package/dist/traverse/index.mjs.map +1 -0
- package/dist/traverse/query-fields.js +41 -0
- package/dist/traverse/query-fields.js.map +1 -0
- package/dist/traverse/query-fields.mjs +39 -0
- package/dist/traverse/query-fields.mjs.map +1 -0
- package/dist/traverse/query-filters.js +114 -0
- package/dist/traverse/query-filters.js.map +1 -0
- package/dist/traverse/query-filters.mjs +112 -0
- package/dist/traverse/query-filters.mjs.map +1 -0
- package/dist/traverse/query-populate.js +280 -0
- package/dist/traverse/query-populate.js.map +1 -0
- package/dist/traverse/query-populate.mjs +278 -0
- package/dist/traverse/query-populate.mjs.map +1 -0
- package/dist/traverse/query-sort.js +144 -0
- package/dist/traverse/query-sort.js.map +1 -0
- package/dist/traverse/query-sort.mjs +142 -0
- package/dist/traverse/query-sort.mjs.map +1 -0
- package/dist/traverse-entity.js +170 -0
- package/dist/traverse-entity.js.map +1 -0
- package/dist/traverse-entity.mjs +168 -0
- package/dist/traverse-entity.mjs.map +1 -0
- package/dist/validate/index.js +218 -0
- package/dist/validate/index.js.map +1 -0
- package/dist/validate/index.mjs +217 -0
- package/dist/validate/index.mjs.map +1 -0
- package/dist/validate/utils.js +27 -0
- package/dist/validate/utils.js.map +1 -0
- package/dist/validate/utils.mjs +24 -0
- package/dist/validate/utils.mjs.map +1 -0
- package/dist/validate/validators.js +369 -0
- package/dist/validate/validators.js.map +1 -0
- package/dist/validate/validators.mjs +356 -0
- package/dist/validate/validators.mjs.map +1 -0
- package/dist/validate/visitors/index.js +22 -0
- package/dist/validate/visitors/index.js.map +1 -0
- package/dist/validate/visitors/index.mjs +9 -0
- package/dist/validate/visitors/index.mjs.map +1 -0
- package/dist/validate/visitors/throw-disallowed-fields.js +91 -0
- package/dist/validate/visitors/throw-disallowed-fields.js.map +1 -0
- package/dist/validate/visitors/throw-disallowed-fields.mjs +89 -0
- package/dist/validate/visitors/throw-disallowed-fields.mjs.map +1 -0
- package/dist/validate/visitors/throw-dynamic-zones.js +16 -0
- package/dist/validate/visitors/throw-dynamic-zones.js.map +1 -0
- package/dist/validate/visitors/throw-dynamic-zones.mjs +14 -0
- package/dist/validate/visitors/throw-dynamic-zones.mjs.map +1 -0
- package/dist/validate/visitors/throw-morph-to-relations.js +16 -0
- package/dist/validate/visitors/throw-morph-to-relations.js.map +1 -0
- package/dist/validate/visitors/throw-morph-to-relations.mjs +14 -0
- package/dist/validate/visitors/throw-morph-to-relations.mjs.map +1 -0
- package/dist/validate/visitors/throw-password.js +15 -0
- package/dist/validate/visitors/throw-password.js.map +1 -0
- package/dist/validate/visitors/throw-password.mjs +13 -0
- package/dist/validate/visitors/throw-password.mjs.map +1 -0
- package/dist/validate/visitors/throw-private.js +20 -0
- package/dist/validate/visitors/throw-private.js.map +1 -0
- package/dist/validate/visitors/throw-private.mjs +18 -0
- package/dist/validate/visitors/throw-private.mjs.map +1 -0
- package/dist/validate/visitors/throw-restricted-fields.js +36 -0
- package/dist/validate/visitors/throw-restricted-fields.js.map +1 -0
- package/dist/validate/visitors/throw-restricted-fields.mjs +34 -0
- package/dist/validate/visitors/throw-restricted-fields.mjs.map +1 -0
- package/dist/validate/visitors/throw-restricted-relations.js +125 -0
- package/dist/validate/visitors/throw-restricted-relations.js.map +1 -0
- package/dist/validate/visitors/throw-restricted-relations.mjs +123 -0
- package/dist/validate/visitors/throw-restricted-relations.mjs.map +1 -0
- package/dist/validate/visitors/throw-unrecognized-fields.js +66 -0
- package/dist/validate/visitors/throw-unrecognized-fields.js.map +1 -0
- package/dist/validate/visitors/throw-unrecognized-fields.mjs +64 -0
- package/dist/validate/visitors/throw-unrecognized-fields.mjs.map +1 -0
- package/dist/validators.js +60 -0
- package/dist/validators.js.map +1 -0
- package/dist/validators.mjs +37 -0
- package/dist/validators.mjs.map +1 -0
- package/dist/yup.js +101 -0
- package/dist/yup.js.map +1 -0
- package/dist/yup.mjs +74 -0
- package/dist/yup.mjs.map +1 -0
- package/dist/zod.js +31 -0
- package/dist/zod.js.map +1 -0
- package/dist/zod.mjs +29 -0
- package/dist/zod.mjs.map +1 -0
- package/package.json +3 -3
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var contentTypes = require('../../content-types.js');
|
|
4
|
+
var utils = require('../utils.js');
|
|
5
|
+
|
|
6
|
+
const visitor = ({ key, attribute, path })=>{
|
|
7
|
+
if (contentTypes.isDynamicZoneAttribute(attribute)) {
|
|
8
|
+
utils.throwInvalidKey({
|
|
9
|
+
key,
|
|
10
|
+
path: path.attribute
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
module.exports = visitor;
|
|
16
|
+
//# sourceMappingURL=throw-dynamic-zones.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"throw-dynamic-zones.js","sources":["../../../src/validate/visitors/throw-dynamic-zones.ts"],"sourcesContent":["import { isDynamicZoneAttribute } from '../../content-types';\nimport { throwInvalidKey } from '../utils';\nimport type { Visitor } from '../../traverse/factory';\n\nconst visitor: Visitor = ({ key, attribute, path }) => {\n if (isDynamicZoneAttribute(attribute)) {\n throwInvalidKey({ key, path: path.attribute });\n }\n};\n\nexport default visitor;\n"],"names":["visitor","key","attribute","path","isDynamicZoneAttribute","throwInvalidKey"],"mappings":";;;;;AAIMA,MAAAA,OAAAA,GAAmB,CAAC,EAAEC,GAAG,EAAEC,SAAS,EAAEC,IAAI,EAAE,GAAA;AAChD,IAAA,IAAIC,oCAAuBF,SAAY,CAAA,EAAA;QACrCG,qBAAgB,CAAA;AAAEJ,YAAAA,GAAAA;AAAKE,YAAAA,IAAAA,EAAMA,KAAKD;AAAU,SAAA,CAAA;AAC9C;AACF;;;;"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { isDynamicZoneAttribute } from '../../content-types.mjs';
|
|
2
|
+
import { throwInvalidKey } from '../utils.mjs';
|
|
3
|
+
|
|
4
|
+
const visitor = ({ key, attribute, path })=>{
|
|
5
|
+
if (isDynamicZoneAttribute(attribute)) {
|
|
6
|
+
throwInvalidKey({
|
|
7
|
+
key,
|
|
8
|
+
path: path.attribute
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export { visitor as default };
|
|
14
|
+
//# sourceMappingURL=throw-dynamic-zones.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"throw-dynamic-zones.mjs","sources":["../../../src/validate/visitors/throw-dynamic-zones.ts"],"sourcesContent":["import { isDynamicZoneAttribute } from '../../content-types';\nimport { throwInvalidKey } from '../utils';\nimport type { Visitor } from '../../traverse/factory';\n\nconst visitor: Visitor = ({ key, attribute, path }) => {\n if (isDynamicZoneAttribute(attribute)) {\n throwInvalidKey({ key, path: path.attribute });\n }\n};\n\nexport default visitor;\n"],"names":["visitor","key","attribute","path","isDynamicZoneAttribute","throwInvalidKey"],"mappings":";;;AAIMA,MAAAA,OAAAA,GAAmB,CAAC,EAAEC,GAAG,EAAEC,SAAS,EAAEC,IAAI,EAAE,GAAA;AAChD,IAAA,IAAIC,uBAAuBF,SAAY,CAAA,EAAA;QACrCG,eAAgB,CAAA;AAAEJ,YAAAA,GAAAA;AAAKE,YAAAA,IAAAA,EAAMA,KAAKD;AAAU,SAAA,CAAA;AAC9C;AACF;;;;"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var contentTypes = require('../../content-types.js');
|
|
4
|
+
var utils = require('../utils.js');
|
|
5
|
+
|
|
6
|
+
const visitor = ({ key, attribute, path })=>{
|
|
7
|
+
if (contentTypes.isMorphToRelationalAttribute(attribute)) {
|
|
8
|
+
utils.throwInvalidKey({
|
|
9
|
+
key,
|
|
10
|
+
path: path.attribute
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
module.exports = visitor;
|
|
16
|
+
//# sourceMappingURL=throw-morph-to-relations.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"throw-morph-to-relations.js","sources":["../../../src/validate/visitors/throw-morph-to-relations.ts"],"sourcesContent":["import { isMorphToRelationalAttribute } from '../../content-types';\nimport { throwInvalidKey } from '../utils';\nimport type { Visitor } from '../../traverse/factory';\n\nconst visitor: Visitor = ({ key, attribute, path }) => {\n if (isMorphToRelationalAttribute(attribute)) {\n throwInvalidKey({ key, path: path.attribute });\n }\n};\n\nexport default visitor;\n"],"names":["visitor","key","attribute","path","isMorphToRelationalAttribute","throwInvalidKey"],"mappings":";;;;;AAIMA,MAAAA,OAAAA,GAAmB,CAAC,EAAEC,GAAG,EAAEC,SAAS,EAAEC,IAAI,EAAE,GAAA;AAChD,IAAA,IAAIC,0CAA6BF,SAAY,CAAA,EAAA;QAC3CG,qBAAgB,CAAA;AAAEJ,YAAAA,GAAAA;AAAKE,YAAAA,IAAAA,EAAMA,KAAKD;AAAU,SAAA,CAAA;AAC9C;AACF;;;;"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { isMorphToRelationalAttribute } from '../../content-types.mjs';
|
|
2
|
+
import { throwInvalidKey } from '../utils.mjs';
|
|
3
|
+
|
|
4
|
+
const visitor = ({ key, attribute, path })=>{
|
|
5
|
+
if (isMorphToRelationalAttribute(attribute)) {
|
|
6
|
+
throwInvalidKey({
|
|
7
|
+
key,
|
|
8
|
+
path: path.attribute
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export { visitor as default };
|
|
14
|
+
//# sourceMappingURL=throw-morph-to-relations.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"throw-morph-to-relations.mjs","sources":["../../../src/validate/visitors/throw-morph-to-relations.ts"],"sourcesContent":["import { isMorphToRelationalAttribute } from '../../content-types';\nimport { throwInvalidKey } from '../utils';\nimport type { Visitor } from '../../traverse/factory';\n\nconst visitor: Visitor = ({ key, attribute, path }) => {\n if (isMorphToRelationalAttribute(attribute)) {\n throwInvalidKey({ key, path: path.attribute });\n }\n};\n\nexport default visitor;\n"],"names":["visitor","key","attribute","path","isMorphToRelationalAttribute","throwInvalidKey"],"mappings":";;;AAIMA,MAAAA,OAAAA,GAAmB,CAAC,EAAEC,GAAG,EAAEC,SAAS,EAAEC,IAAI,EAAE,GAAA;AAChD,IAAA,IAAIC,6BAA6BF,SAAY,CAAA,EAAA;QAC3CG,eAAgB,CAAA;AAAEJ,YAAAA,GAAAA;AAAKE,YAAAA,IAAAA,EAAMA,KAAKD;AAAU,SAAA,CAAA;AAC9C;AACF;;;;"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var utils = require('../utils.js');
|
|
4
|
+
|
|
5
|
+
const visitor = ({ key, attribute, path })=>{
|
|
6
|
+
if (attribute?.type === 'password') {
|
|
7
|
+
utils.throwInvalidKey({
|
|
8
|
+
key,
|
|
9
|
+
path: path.attribute
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
module.exports = visitor;
|
|
15
|
+
//# sourceMappingURL=throw-password.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"throw-password.js","sources":["../../../src/validate/visitors/throw-password.ts"],"sourcesContent":["import { throwInvalidKey } from '../utils';\nimport type { Visitor } from '../../traverse/factory';\n\nconst visitor: Visitor = ({ key, attribute, path }) => {\n if (attribute?.type === 'password') {\n throwInvalidKey({ key, path: path.attribute });\n }\n};\n\nexport default visitor;\n"],"names":["visitor","key","attribute","path","type","throwInvalidKey"],"mappings":";;;;AAGMA,MAAAA,OAAAA,GAAmB,CAAC,EAAEC,GAAG,EAAEC,SAAS,EAAEC,IAAI,EAAE,GAAA;IAChD,IAAID,SAAAA,EAAWE,SAAS,UAAY,EAAA;QAClCC,qBAAgB,CAAA;AAAEJ,YAAAA,GAAAA;AAAKE,YAAAA,IAAAA,EAAMA,KAAKD;AAAU,SAAA,CAAA;AAC9C;AACF;;;;"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { throwInvalidKey } from '../utils.mjs';
|
|
2
|
+
|
|
3
|
+
const visitor = ({ key, attribute, path })=>{
|
|
4
|
+
if (attribute?.type === 'password') {
|
|
5
|
+
throwInvalidKey({
|
|
6
|
+
key,
|
|
7
|
+
path: path.attribute
|
|
8
|
+
});
|
|
9
|
+
}
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export { visitor as default };
|
|
13
|
+
//# sourceMappingURL=throw-password.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"throw-password.mjs","sources":["../../../src/validate/visitors/throw-password.ts"],"sourcesContent":["import { throwInvalidKey } from '../utils';\nimport type { Visitor } from '../../traverse/factory';\n\nconst visitor: Visitor = ({ key, attribute, path }) => {\n if (attribute?.type === 'password') {\n throwInvalidKey({ key, path: path.attribute });\n }\n};\n\nexport default visitor;\n"],"names":["visitor","key","attribute","path","type","throwInvalidKey"],"mappings":";;AAGMA,MAAAA,OAAAA,GAAmB,CAAC,EAAEC,GAAG,EAAEC,SAAS,EAAEC,IAAI,EAAE,GAAA;IAChD,IAAID,SAAAA,EAAWE,SAAS,UAAY,EAAA;QAClCC,eAAgB,CAAA;AAAEJ,YAAAA,GAAAA;AAAKE,YAAAA,IAAAA,EAAMA,KAAKD;AAAU,SAAA,CAAA;AAC9C;AACF;;;;"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var contentTypes = require('../../content-types.js');
|
|
4
|
+
var utils = require('../utils.js');
|
|
5
|
+
|
|
6
|
+
const visitor = ({ schema, key, attribute, path })=>{
|
|
7
|
+
if (!attribute) {
|
|
8
|
+
return;
|
|
9
|
+
}
|
|
10
|
+
const isPrivate = attribute.private === true || contentTypes.isPrivateAttribute(schema, key);
|
|
11
|
+
if (isPrivate) {
|
|
12
|
+
utils.throwInvalidKey({
|
|
13
|
+
key,
|
|
14
|
+
path: path.attribute
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
module.exports = visitor;
|
|
20
|
+
//# sourceMappingURL=throw-private.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"throw-private.js","sources":["../../../src/validate/visitors/throw-private.ts"],"sourcesContent":["import { isPrivateAttribute } from '../../content-types';\nimport { throwInvalidKey } from '../utils';\nimport type { Visitor } from '../../traverse/factory';\n\nconst visitor: Visitor = ({ schema, key, attribute, path }) => {\n if (!attribute) {\n return;\n }\n\n const isPrivate = attribute.private === true || isPrivateAttribute(schema, key);\n\n if (isPrivate) {\n throwInvalidKey({ key, path: path.attribute });\n }\n};\n\nexport default visitor;\n"],"names":["visitor","schema","key","attribute","path","isPrivate","private","isPrivateAttribute","throwInvalidKey"],"mappings":";;;;;AAIMA,MAAAA,OAAAA,GAAmB,CAAC,EAAEC,MAAM,EAAEC,GAAG,EAAEC,SAAS,EAAEC,IAAI,EAAE,GAAA;AACxD,IAAA,IAAI,CAACD,SAAW,EAAA;AACd,QAAA;AACF;AAEA,IAAA,MAAME,YAAYF,SAAUG,CAAAA,OAAO,KAAK,IAAA,IAAQC,gCAAmBN,MAAQC,EAAAA,GAAAA,CAAAA;AAE3E,IAAA,IAAIG,SAAW,EAAA;QACbG,qBAAgB,CAAA;AAAEN,YAAAA,GAAAA;AAAKE,YAAAA,IAAAA,EAAMA,KAAKD;AAAU,SAAA,CAAA;AAC9C;AACF;;;;"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { isPrivateAttribute } from '../../content-types.mjs';
|
|
2
|
+
import { throwInvalidKey } from '../utils.mjs';
|
|
3
|
+
|
|
4
|
+
const visitor = ({ schema, key, attribute, path })=>{
|
|
5
|
+
if (!attribute) {
|
|
6
|
+
return;
|
|
7
|
+
}
|
|
8
|
+
const isPrivate = attribute.private === true || isPrivateAttribute(schema, key);
|
|
9
|
+
if (isPrivate) {
|
|
10
|
+
throwInvalidKey({
|
|
11
|
+
key,
|
|
12
|
+
path: path.attribute
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export { visitor as default };
|
|
18
|
+
//# sourceMappingURL=throw-private.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"throw-private.mjs","sources":["../../../src/validate/visitors/throw-private.ts"],"sourcesContent":["import { isPrivateAttribute } from '../../content-types';\nimport { throwInvalidKey } from '../utils';\nimport type { Visitor } from '../../traverse/factory';\n\nconst visitor: Visitor = ({ schema, key, attribute, path }) => {\n if (!attribute) {\n return;\n }\n\n const isPrivate = attribute.private === true || isPrivateAttribute(schema, key);\n\n if (isPrivate) {\n throwInvalidKey({ key, path: path.attribute });\n }\n};\n\nexport default visitor;\n"],"names":["visitor","schema","key","attribute","path","isPrivate","private","isPrivateAttribute","throwInvalidKey"],"mappings":";;;AAIMA,MAAAA,OAAAA,GAAmB,CAAC,EAAEC,MAAM,EAAEC,GAAG,EAAEC,SAAS,EAAEC,IAAI,EAAE,GAAA;AACxD,IAAA,IAAI,CAACD,SAAW,EAAA;AACd,QAAA;AACF;AAEA,IAAA,MAAME,YAAYF,SAAUG,CAAAA,OAAO,KAAK,IAAA,IAAQC,mBAAmBN,MAAQC,EAAAA,GAAAA,CAAAA;AAE3E,IAAA,IAAIG,SAAW,EAAA;QACbG,eAAgB,CAAA;AAAEN,YAAAA,GAAAA;AAAKE,YAAAA,IAAAA,EAAMA,KAAKD;AAAU,SAAA,CAAA;AAC9C;AACF;;;;"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var fp = require('lodash/fp');
|
|
4
|
+
var utils = require('../utils.js');
|
|
5
|
+
|
|
6
|
+
var throwRestrictedFields = ((restrictedFields = null)=>({ key, path: { attribute: path } })=>{
|
|
7
|
+
// all fields
|
|
8
|
+
if (restrictedFields === null) {
|
|
9
|
+
utils.throwInvalidKey({
|
|
10
|
+
key,
|
|
11
|
+
path
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
// Throw on invalid formats
|
|
15
|
+
if (!(fp.isArray(restrictedFields) && restrictedFields.every(fp.isString))) {
|
|
16
|
+
throw new TypeError(`Expected array of strings for restrictedFields but got "${typeof restrictedFields}"`);
|
|
17
|
+
}
|
|
18
|
+
// if an exact match was found
|
|
19
|
+
if (restrictedFields.includes(path)) {
|
|
20
|
+
utils.throwInvalidKey({
|
|
21
|
+
key,
|
|
22
|
+
path
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
// nested matches
|
|
26
|
+
const isRestrictedNested = restrictedFields.some((allowedPath)=>path?.toString().startsWith(`${allowedPath}.`));
|
|
27
|
+
if (isRestrictedNested) {
|
|
28
|
+
utils.throwInvalidKey({
|
|
29
|
+
key,
|
|
30
|
+
path
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
module.exports = throwRestrictedFields;
|
|
36
|
+
//# sourceMappingURL=throw-restricted-fields.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"throw-restricted-fields.js","sources":["../../../src/validate/visitors/throw-restricted-fields.ts"],"sourcesContent":["import { isArray, isString } from 'lodash/fp';\nimport type { Visitor } from '../../traverse/factory';\nimport { throwInvalidKey } from '../utils';\n\nexport default (restrictedFields: string[] | null = null): Visitor =>\n ({ key, path: { attribute: path } }) => {\n // all fields\n if (restrictedFields === null) {\n throwInvalidKey({ key, path });\n }\n\n // Throw on invalid formats\n if (!(isArray(restrictedFields) && restrictedFields.every(isString))) {\n throw new TypeError(\n `Expected array of strings for restrictedFields but got \"${typeof restrictedFields}\"`\n );\n }\n\n // if an exact match was found\n if (restrictedFields.includes(path as string)) {\n throwInvalidKey({ key, path });\n }\n\n // nested matches\n const isRestrictedNested = restrictedFields.some((allowedPath) =>\n path?.toString().startsWith(`${allowedPath}.`)\n );\n if (isRestrictedNested) {\n throwInvalidKey({ key, path });\n }\n };\n"],"names":["restrictedFields","key","path","attribute","throwInvalidKey","isArray","every","isString","TypeError","includes","isRestrictedNested","some","allowedPath","toString","startsWith"],"mappings":";;;;;AAIA,4BAAe,CAAA,CAACA,gBAAoC,GAAA,IAAI,GACtD,CAAC,EAAEC,GAAG,EAAEC,IAAM,EAAA,EAAEC,SAAWD,EAAAA,IAAI,EAAE,EAAE,GAAA;;AAEjC,QAAA,IAAIF,qBAAqB,IAAM,EAAA;YAC7BI,qBAAgB,CAAA;AAAEH,gBAAAA,GAAAA;AAAKC,gBAAAA;AAAK,aAAA,CAAA;AAC9B;;QAGA,IAAI,EAAEG,UAAQL,CAAAA,gBAAAA,CAAAA,IAAqBA,iBAAiBM,KAAK,CAACC,YAAQ,CAAI,EAAA;YACpE,MAAM,IAAIC,UACR,CAAC,wDAAwD,EAAE,OAAOR,gBAAAA,CAAiB,CAAC,CAAC,CAAA;AAEzF;;QAGA,IAAIA,gBAAAA,CAAiBS,QAAQ,CAACP,IAAiB,CAAA,EAAA;YAC7CE,qBAAgB,CAAA;AAAEH,gBAAAA,GAAAA;AAAKC,gBAAAA;AAAK,aAAA,CAAA;AAC9B;;AAGA,QAAA,MAAMQ,kBAAqBV,GAAAA,gBAAAA,CAAiBW,IAAI,CAAC,CAACC,WAAAA,GAChDV,IAAMW,EAAAA,QAAAA,EAAAA,CAAWC,UAAW,CAAA,CAAC,EAAEF,WAAAA,CAAY,CAAC,CAAC,CAAA,CAAA;AAE/C,QAAA,IAAIF,kBAAoB,EAAA;YACtBN,qBAAgB,CAAA;AAAEH,gBAAAA,GAAAA;AAAKC,gBAAAA;AAAK,aAAA,CAAA;AAC9B;AACF,KAAA;;;;"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { isArray, isString } from 'lodash/fp';
|
|
2
|
+
import { throwInvalidKey } from '../utils.mjs';
|
|
3
|
+
|
|
4
|
+
var throwRestrictedFields = ((restrictedFields = null)=>({ key, path: { attribute: path } })=>{
|
|
5
|
+
// all fields
|
|
6
|
+
if (restrictedFields === null) {
|
|
7
|
+
throwInvalidKey({
|
|
8
|
+
key,
|
|
9
|
+
path
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
// Throw on invalid formats
|
|
13
|
+
if (!(isArray(restrictedFields) && restrictedFields.every(isString))) {
|
|
14
|
+
throw new TypeError(`Expected array of strings for restrictedFields but got "${typeof restrictedFields}"`);
|
|
15
|
+
}
|
|
16
|
+
// if an exact match was found
|
|
17
|
+
if (restrictedFields.includes(path)) {
|
|
18
|
+
throwInvalidKey({
|
|
19
|
+
key,
|
|
20
|
+
path
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
// nested matches
|
|
24
|
+
const isRestrictedNested = restrictedFields.some((allowedPath)=>path?.toString().startsWith(`${allowedPath}.`));
|
|
25
|
+
if (isRestrictedNested) {
|
|
26
|
+
throwInvalidKey({
|
|
27
|
+
key,
|
|
28
|
+
path
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
export { throwRestrictedFields as default };
|
|
34
|
+
//# sourceMappingURL=throw-restricted-fields.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"throw-restricted-fields.mjs","sources":["../../../src/validate/visitors/throw-restricted-fields.ts"],"sourcesContent":["import { isArray, isString } from 'lodash/fp';\nimport type { Visitor } from '../../traverse/factory';\nimport { throwInvalidKey } from '../utils';\n\nexport default (restrictedFields: string[] | null = null): Visitor =>\n ({ key, path: { attribute: path } }) => {\n // all fields\n if (restrictedFields === null) {\n throwInvalidKey({ key, path });\n }\n\n // Throw on invalid formats\n if (!(isArray(restrictedFields) && restrictedFields.every(isString))) {\n throw new TypeError(\n `Expected array of strings for restrictedFields but got \"${typeof restrictedFields}\"`\n );\n }\n\n // if an exact match was found\n if (restrictedFields.includes(path as string)) {\n throwInvalidKey({ key, path });\n }\n\n // nested matches\n const isRestrictedNested = restrictedFields.some((allowedPath) =>\n path?.toString().startsWith(`${allowedPath}.`)\n );\n if (isRestrictedNested) {\n throwInvalidKey({ key, path });\n }\n };\n"],"names":["restrictedFields","key","path","attribute","throwInvalidKey","isArray","every","isString","TypeError","includes","isRestrictedNested","some","allowedPath","toString","startsWith"],"mappings":";;;AAIA,4BAAe,CAAA,CAACA,gBAAoC,GAAA,IAAI,GACtD,CAAC,EAAEC,GAAG,EAAEC,IAAM,EAAA,EAAEC,SAAWD,EAAAA,IAAI,EAAE,EAAE,GAAA;;AAEjC,QAAA,IAAIF,qBAAqB,IAAM,EAAA;YAC7BI,eAAgB,CAAA;AAAEH,gBAAAA,GAAAA;AAAKC,gBAAAA;AAAK,aAAA,CAAA;AAC9B;;QAGA,IAAI,EAAEG,OAAQL,CAAAA,gBAAAA,CAAAA,IAAqBA,iBAAiBM,KAAK,CAACC,SAAQ,CAAI,EAAA;YACpE,MAAM,IAAIC,UACR,CAAC,wDAAwD,EAAE,OAAOR,gBAAAA,CAAiB,CAAC,CAAC,CAAA;AAEzF;;QAGA,IAAIA,gBAAAA,CAAiBS,QAAQ,CAACP,IAAiB,CAAA,EAAA;YAC7CE,eAAgB,CAAA;AAAEH,gBAAAA,GAAAA;AAAKC,gBAAAA;AAAK,aAAA,CAAA;AAC9B;;AAGA,QAAA,MAAMQ,kBAAqBV,GAAAA,gBAAAA,CAAiBW,IAAI,CAAC,CAACC,WAAAA,GAChDV,IAAMW,EAAAA,QAAAA,EAAAA,CAAWC,UAAW,CAAA,CAAC,EAAEF,WAAAA,CAAY,CAAC,CAAC,CAAA,CAAA;AAE/C,QAAA,IAAIF,kBAAoB,EAAA;YACtBN,eAAgB,CAAA;AAAEH,gBAAAA,GAAAA;AAAKC,gBAAAA;AAAK,aAAA,CAAA;AAC9B;AACF,KAAA;;;;"}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var fp = require('lodash/fp');
|
|
4
|
+
var contentTypes = require('../../content-types.js');
|
|
5
|
+
var utils = require('../utils.js');
|
|
6
|
+
var relations = require('../../relations.js');
|
|
7
|
+
|
|
8
|
+
const ACTIONS_TO_VERIFY = [
|
|
9
|
+
'find'
|
|
10
|
+
];
|
|
11
|
+
const { CREATED_BY_ATTRIBUTE, UPDATED_BY_ATTRIBUTE } = contentTypes.constants;
|
|
12
|
+
var throwRestrictedRelations = ((auth)=>async ({ data, key, attribute, schema, path })=>{
|
|
13
|
+
if (!attribute) {
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
const isRelation = attribute.type === 'relation';
|
|
17
|
+
if (!isRelation) {
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
const handleMorphRelation = async ()=>{
|
|
21
|
+
const elements = data[key];
|
|
22
|
+
if ('connect' in elements || 'set' in elements || 'disconnect' in elements || 'options' in elements) {
|
|
23
|
+
await handleMorphElements(elements.connect || []);
|
|
24
|
+
await handleMorphElements(elements.set || []);
|
|
25
|
+
await handleMorphElements(elements.disconnect || []);
|
|
26
|
+
// TODO: this should technically be in its own visitor to check morph options, but for now we'll handle it here
|
|
27
|
+
if ('options' in elements) {
|
|
28
|
+
if (elements.options === null || elements.options === undefined) {
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
if (typeof elements.options !== 'object') {
|
|
32
|
+
utils.throwInvalidKey({
|
|
33
|
+
key,
|
|
34
|
+
path: path.attribute
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
const optionKeys = Object.keys(elements.options);
|
|
38
|
+
// Validate each key based on its validator function
|
|
39
|
+
for (const key of optionKeys){
|
|
40
|
+
if (!(key in relations.VALID_RELATION_ORDERING_KEYS)) {
|
|
41
|
+
utils.throwInvalidKey({
|
|
42
|
+
key,
|
|
43
|
+
path: path.attribute
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
if (!relations.VALID_RELATION_ORDERING_KEYS[key](elements.options[key])) {
|
|
47
|
+
utils.throwInvalidKey({
|
|
48
|
+
key,
|
|
49
|
+
path: path.attribute
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
} else {
|
|
55
|
+
await handleMorphElements(elements);
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
const handleMorphElements = async (elements)=>{
|
|
59
|
+
if (!fp.isArray(elements)) {
|
|
60
|
+
utils.throwInvalidKey({
|
|
61
|
+
key,
|
|
62
|
+
path: path.attribute
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
for (const element of elements){
|
|
66
|
+
if (!fp.isObject(element) || !('__type' in element)) {
|
|
67
|
+
utils.throwInvalidKey({
|
|
68
|
+
key,
|
|
69
|
+
path: path.attribute
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
const scopes = ACTIONS_TO_VERIFY.map((action)=>`${element.__type}.${action}`);
|
|
73
|
+
const isAllowed = await hasAccessToSomeScopes(scopes, auth);
|
|
74
|
+
if (!isAllowed) {
|
|
75
|
+
utils.throwInvalidKey({
|
|
76
|
+
key,
|
|
77
|
+
path: path.attribute
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
const handleRegularRelation = async ()=>{
|
|
83
|
+
const scopes = ACTIONS_TO_VERIFY.map((action)=>`${attribute.target}.${action}`);
|
|
84
|
+
const isAllowed = await hasAccessToSomeScopes(scopes, auth);
|
|
85
|
+
// If the authenticated user don't have access to any of the scopes
|
|
86
|
+
if (!isAllowed) {
|
|
87
|
+
utils.throwInvalidKey({
|
|
88
|
+
key,
|
|
89
|
+
path: path.attribute
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
};
|
|
93
|
+
const isCreatorRelation = [
|
|
94
|
+
CREATED_BY_ATTRIBUTE,
|
|
95
|
+
UPDATED_BY_ATTRIBUTE
|
|
96
|
+
].includes(key);
|
|
97
|
+
// Polymorphic relations
|
|
98
|
+
if (contentTypes.isMorphToRelationalAttribute(attribute)) {
|
|
99
|
+
await handleMorphRelation();
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
// Creator relations
|
|
103
|
+
if (isCreatorRelation && schema.options?.populateCreatorFields) {
|
|
104
|
+
// do nothing
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
// Regular relations
|
|
108
|
+
await handleRegularRelation();
|
|
109
|
+
});
|
|
110
|
+
const hasAccessToSomeScopes = async (scopes, auth)=>{
|
|
111
|
+
for (const scope of scopes){
|
|
112
|
+
try {
|
|
113
|
+
await strapi.auth.verify(auth, {
|
|
114
|
+
scope
|
|
115
|
+
});
|
|
116
|
+
return true;
|
|
117
|
+
} catch {
|
|
118
|
+
continue;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
return false;
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
module.exports = throwRestrictedRelations;
|
|
125
|
+
//# sourceMappingURL=throw-restricted-relations.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"throw-restricted-relations.js","sources":["../../../src/validate/visitors/throw-restricted-relations.ts"],"sourcesContent":["import { isArray, isObject } from 'lodash/fp';\nimport * as contentTypeUtils from '../../content-types';\nimport { throwInvalidKey } from '../utils';\nimport type { Visitor } from '../../traverse/factory';\nimport { VALID_RELATION_ORDERING_KEYS } from '../../relations';\n\nconst ACTIONS_TO_VERIFY = ['find'];\nconst { CREATED_BY_ATTRIBUTE, UPDATED_BY_ATTRIBUTE } = contentTypeUtils.constants;\n\ntype MorphArray = Array<{ __type: string }>;\n\nexport default (auth: unknown): Visitor =>\n async ({ data, key, attribute, schema, path }) => {\n if (!attribute) {\n return;\n }\n\n const isRelation = attribute.type === 'relation';\n\n if (!isRelation) {\n return;\n }\n\n const handleMorphRelation = async () => {\n const elements: any = (data as Record<string, MorphArray>)[key];\n\n if (\n 'connect' in elements ||\n 'set' in elements ||\n 'disconnect' in elements ||\n 'options' in elements\n ) {\n await handleMorphElements(elements.connect || []);\n await handleMorphElements(elements.set || []);\n await handleMorphElements(elements.disconnect || []);\n\n // TODO: this should technically be in its own visitor to check morph options, but for now we'll handle it here\n if ('options' in elements) {\n if (elements.options === null || elements.options === undefined) {\n return;\n }\n\n if (typeof elements.options !== 'object') {\n throwInvalidKey({ key, path: path.attribute });\n }\n\n const optionKeys = Object.keys(elements.options);\n\n // Validate each key based on its validator function\n for (const key of optionKeys) {\n if (!(key in VALID_RELATION_ORDERING_KEYS)) {\n throwInvalidKey({ key, path: path.attribute });\n }\n if (!VALID_RELATION_ORDERING_KEYS[key](elements.options[key])) {\n throwInvalidKey({ key, path: path.attribute });\n }\n }\n }\n } else {\n await handleMorphElements(elements);\n }\n };\n\n const handleMorphElements = async (elements: any[]) => {\n if (!isArray(elements)) {\n throwInvalidKey({ key, path: path.attribute });\n }\n\n for (const element of elements) {\n if (!isObject(element) || !('__type' in element)) {\n throwInvalidKey({ key, path: path.attribute });\n }\n\n const scopes = ACTIONS_TO_VERIFY.map((action) => `${element.__type}.${action}`);\n const isAllowed = await hasAccessToSomeScopes(scopes, auth);\n\n if (!isAllowed) {\n throwInvalidKey({ key, path: path.attribute });\n }\n }\n };\n\n const handleRegularRelation = async () => {\n const scopes = ACTIONS_TO_VERIFY.map((action) => `${attribute.target}.${action}`);\n\n const isAllowed = await hasAccessToSomeScopes(scopes, auth);\n\n // If the authenticated user don't have access to any of the scopes\n if (!isAllowed) {\n throwInvalidKey({ key, path: path.attribute });\n }\n };\n\n const isCreatorRelation = [CREATED_BY_ATTRIBUTE, UPDATED_BY_ATTRIBUTE].includes(key);\n\n // Polymorphic relations\n if (contentTypeUtils.isMorphToRelationalAttribute(attribute)) {\n await handleMorphRelation();\n return;\n }\n\n // Creator relations\n if (isCreatorRelation && schema.options?.populateCreatorFields) {\n // do nothing\n return;\n }\n\n // Regular relations\n await handleRegularRelation();\n };\n\nconst hasAccessToSomeScopes = async (scopes: string[], auth: unknown) => {\n for (const scope of scopes) {\n try {\n await strapi.auth.verify(auth, { scope });\n return true;\n } catch {\n continue;\n }\n }\n\n return false;\n};\n"],"names":["ACTIONS_TO_VERIFY","CREATED_BY_ATTRIBUTE","UPDATED_BY_ATTRIBUTE","contentTypeUtils","auth","data","key","attribute","schema","path","isRelation","type","handleMorphRelation","elements","handleMorphElements","connect","set","disconnect","options","undefined","throwInvalidKey","optionKeys","Object","keys","VALID_RELATION_ORDERING_KEYS","isArray","element","isObject","scopes","map","action","__type","isAllowed","hasAccessToSomeScopes","handleRegularRelation","target","isCreatorRelation","includes","populateCreatorFields","scope","strapi","verify"],"mappings":"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"}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import { isArray, isObject } from 'lodash/fp';
|
|
2
|
+
import { isMorphToRelationalAttribute, constants } from '../../content-types.mjs';
|
|
3
|
+
import { throwInvalidKey } from '../utils.mjs';
|
|
4
|
+
import { VALID_RELATION_ORDERING_KEYS } from '../../relations.mjs';
|
|
5
|
+
|
|
6
|
+
const ACTIONS_TO_VERIFY = [
|
|
7
|
+
'find'
|
|
8
|
+
];
|
|
9
|
+
const { CREATED_BY_ATTRIBUTE, UPDATED_BY_ATTRIBUTE } = constants;
|
|
10
|
+
var throwRestrictedRelations = ((auth)=>async ({ data, key, attribute, schema, path })=>{
|
|
11
|
+
if (!attribute) {
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
const isRelation = attribute.type === 'relation';
|
|
15
|
+
if (!isRelation) {
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
const handleMorphRelation = async ()=>{
|
|
19
|
+
const elements = data[key];
|
|
20
|
+
if ('connect' in elements || 'set' in elements || 'disconnect' in elements || 'options' in elements) {
|
|
21
|
+
await handleMorphElements(elements.connect || []);
|
|
22
|
+
await handleMorphElements(elements.set || []);
|
|
23
|
+
await handleMorphElements(elements.disconnect || []);
|
|
24
|
+
// TODO: this should technically be in its own visitor to check morph options, but for now we'll handle it here
|
|
25
|
+
if ('options' in elements) {
|
|
26
|
+
if (elements.options === null || elements.options === undefined) {
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
if (typeof elements.options !== 'object') {
|
|
30
|
+
throwInvalidKey({
|
|
31
|
+
key,
|
|
32
|
+
path: path.attribute
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
const optionKeys = Object.keys(elements.options);
|
|
36
|
+
// Validate each key based on its validator function
|
|
37
|
+
for (const key of optionKeys){
|
|
38
|
+
if (!(key in VALID_RELATION_ORDERING_KEYS)) {
|
|
39
|
+
throwInvalidKey({
|
|
40
|
+
key,
|
|
41
|
+
path: path.attribute
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
if (!VALID_RELATION_ORDERING_KEYS[key](elements.options[key])) {
|
|
45
|
+
throwInvalidKey({
|
|
46
|
+
key,
|
|
47
|
+
path: path.attribute
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
} else {
|
|
53
|
+
await handleMorphElements(elements);
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
const handleMorphElements = async (elements)=>{
|
|
57
|
+
if (!isArray(elements)) {
|
|
58
|
+
throwInvalidKey({
|
|
59
|
+
key,
|
|
60
|
+
path: path.attribute
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
for (const element of elements){
|
|
64
|
+
if (!isObject(element) || !('__type' in element)) {
|
|
65
|
+
throwInvalidKey({
|
|
66
|
+
key,
|
|
67
|
+
path: path.attribute
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
const scopes = ACTIONS_TO_VERIFY.map((action)=>`${element.__type}.${action}`);
|
|
71
|
+
const isAllowed = await hasAccessToSomeScopes(scopes, auth);
|
|
72
|
+
if (!isAllowed) {
|
|
73
|
+
throwInvalidKey({
|
|
74
|
+
key,
|
|
75
|
+
path: path.attribute
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
const handleRegularRelation = async ()=>{
|
|
81
|
+
const scopes = ACTIONS_TO_VERIFY.map((action)=>`${attribute.target}.${action}`);
|
|
82
|
+
const isAllowed = await hasAccessToSomeScopes(scopes, auth);
|
|
83
|
+
// If the authenticated user don't have access to any of the scopes
|
|
84
|
+
if (!isAllowed) {
|
|
85
|
+
throwInvalidKey({
|
|
86
|
+
key,
|
|
87
|
+
path: path.attribute
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
const isCreatorRelation = [
|
|
92
|
+
CREATED_BY_ATTRIBUTE,
|
|
93
|
+
UPDATED_BY_ATTRIBUTE
|
|
94
|
+
].includes(key);
|
|
95
|
+
// Polymorphic relations
|
|
96
|
+
if (isMorphToRelationalAttribute(attribute)) {
|
|
97
|
+
await handleMorphRelation();
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
// Creator relations
|
|
101
|
+
if (isCreatorRelation && schema.options?.populateCreatorFields) {
|
|
102
|
+
// do nothing
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
// Regular relations
|
|
106
|
+
await handleRegularRelation();
|
|
107
|
+
});
|
|
108
|
+
const hasAccessToSomeScopes = async (scopes, auth)=>{
|
|
109
|
+
for (const scope of scopes){
|
|
110
|
+
try {
|
|
111
|
+
await strapi.auth.verify(auth, {
|
|
112
|
+
scope
|
|
113
|
+
});
|
|
114
|
+
return true;
|
|
115
|
+
} catch {
|
|
116
|
+
continue;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
return false;
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
export { throwRestrictedRelations as default };
|
|
123
|
+
//# sourceMappingURL=throw-restricted-relations.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"throw-restricted-relations.mjs","sources":["../../../src/validate/visitors/throw-restricted-relations.ts"],"sourcesContent":["import { isArray, isObject } from 'lodash/fp';\nimport * as contentTypeUtils from '../../content-types';\nimport { throwInvalidKey } from '../utils';\nimport type { Visitor } from '../../traverse/factory';\nimport { VALID_RELATION_ORDERING_KEYS } from '../../relations';\n\nconst ACTIONS_TO_VERIFY = ['find'];\nconst { CREATED_BY_ATTRIBUTE, UPDATED_BY_ATTRIBUTE } = contentTypeUtils.constants;\n\ntype MorphArray = Array<{ __type: string }>;\n\nexport default (auth: unknown): Visitor =>\n async ({ data, key, attribute, schema, path }) => {\n if (!attribute) {\n return;\n }\n\n const isRelation = attribute.type === 'relation';\n\n if (!isRelation) {\n return;\n }\n\n const handleMorphRelation = async () => {\n const elements: any = (data as Record<string, MorphArray>)[key];\n\n if (\n 'connect' in elements ||\n 'set' in elements ||\n 'disconnect' in elements ||\n 'options' in elements\n ) {\n await handleMorphElements(elements.connect || []);\n await handleMorphElements(elements.set || []);\n await handleMorphElements(elements.disconnect || []);\n\n // TODO: this should technically be in its own visitor to check morph options, but for now we'll handle it here\n if ('options' in elements) {\n if (elements.options === null || elements.options === undefined) {\n return;\n }\n\n if (typeof elements.options !== 'object') {\n throwInvalidKey({ key, path: path.attribute });\n }\n\n const optionKeys = Object.keys(elements.options);\n\n // Validate each key based on its validator function\n for (const key of optionKeys) {\n if (!(key in VALID_RELATION_ORDERING_KEYS)) {\n throwInvalidKey({ key, path: path.attribute });\n }\n if (!VALID_RELATION_ORDERING_KEYS[key](elements.options[key])) {\n throwInvalidKey({ key, path: path.attribute });\n }\n }\n }\n } else {\n await handleMorphElements(elements);\n }\n };\n\n const handleMorphElements = async (elements: any[]) => {\n if (!isArray(elements)) {\n throwInvalidKey({ key, path: path.attribute });\n }\n\n for (const element of elements) {\n if (!isObject(element) || !('__type' in element)) {\n throwInvalidKey({ key, path: path.attribute });\n }\n\n const scopes = ACTIONS_TO_VERIFY.map((action) => `${element.__type}.${action}`);\n const isAllowed = await hasAccessToSomeScopes(scopes, auth);\n\n if (!isAllowed) {\n throwInvalidKey({ key, path: path.attribute });\n }\n }\n };\n\n const handleRegularRelation = async () => {\n const scopes = ACTIONS_TO_VERIFY.map((action) => `${attribute.target}.${action}`);\n\n const isAllowed = await hasAccessToSomeScopes(scopes, auth);\n\n // If the authenticated user don't have access to any of the scopes\n if (!isAllowed) {\n throwInvalidKey({ key, path: path.attribute });\n }\n };\n\n const isCreatorRelation = [CREATED_BY_ATTRIBUTE, UPDATED_BY_ATTRIBUTE].includes(key);\n\n // Polymorphic relations\n if (contentTypeUtils.isMorphToRelationalAttribute(attribute)) {\n await handleMorphRelation();\n return;\n }\n\n // Creator relations\n if (isCreatorRelation && schema.options?.populateCreatorFields) {\n // do nothing\n return;\n }\n\n // Regular relations\n await handleRegularRelation();\n };\n\nconst hasAccessToSomeScopes = async (scopes: string[], auth: unknown) => {\n for (const scope of scopes) {\n try {\n await strapi.auth.verify(auth, { scope });\n return true;\n } catch {\n continue;\n }\n }\n\n return false;\n};\n"],"names":["ACTIONS_TO_VERIFY","CREATED_BY_ATTRIBUTE","UPDATED_BY_ATTRIBUTE","contentTypeUtils","auth","data","key","attribute","schema","path","isRelation","type","handleMorphRelation","elements","handleMorphElements","connect","set","disconnect","options","undefined","throwInvalidKey","optionKeys","Object","keys","VALID_RELATION_ORDERING_KEYS","isArray","element","isObject","scopes","map","action","__type","isAllowed","hasAccessToSomeScopes","handleRegularRelation","target","isCreatorRelation","includes","populateCreatorFields","scope","strapi","verify"],"mappings":"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"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var contentTypes = require('../../content-types.js');
|
|
4
|
+
var utils = require('../utils.js');
|
|
5
|
+
|
|
6
|
+
// TODO these should all be centralized somewhere instead of maintaining a list
|
|
7
|
+
const ID_FIELDS = [
|
|
8
|
+
contentTypes.constants.DOC_ID_ATTRIBUTE,
|
|
9
|
+
contentTypes.constants.DOC_ID_ATTRIBUTE
|
|
10
|
+
];
|
|
11
|
+
const ALLOWED_ROOT_LEVEL_FIELDS = [
|
|
12
|
+
...ID_FIELDS
|
|
13
|
+
];
|
|
14
|
+
const MORPH_TO_ALLOWED_FIELDS = [
|
|
15
|
+
'__type'
|
|
16
|
+
];
|
|
17
|
+
const DYNAMIC_ZONE_ALLOWED_FIELDS = [
|
|
18
|
+
'__component'
|
|
19
|
+
];
|
|
20
|
+
const RELATION_REORDERING_FIELDS = [
|
|
21
|
+
'connect',
|
|
22
|
+
'disconnect',
|
|
23
|
+
'set',
|
|
24
|
+
'options'
|
|
25
|
+
];
|
|
26
|
+
const throwUnrecognizedFields = ({ key, attribute, path, schema, parent })=>{
|
|
27
|
+
// We only look at properties that are not attributes
|
|
28
|
+
if (attribute) {
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
// At root level (path.attribute === null), only accept allowed fields
|
|
32
|
+
if (path.attribute === null) {
|
|
33
|
+
if (ALLOWED_ROOT_LEVEL_FIELDS.includes(key)) {
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
return utils.throwInvalidKey({
|
|
37
|
+
key,
|
|
38
|
+
path: attribute
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
// allow special morphTo keys
|
|
42
|
+
if (contentTypes.isMorphToRelationalAttribute(parent?.attribute) && MORPH_TO_ALLOWED_FIELDS.includes(key)) {
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
// allow special dz keys
|
|
46
|
+
if (contentTypes.isComponentSchema(schema) && contentTypes.isDynamicZoneAttribute(parent?.attribute) && DYNAMIC_ZONE_ALLOWED_FIELDS.includes(key)) {
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
// allow special relation reordering keys in manyToX and XtoMany relations
|
|
50
|
+
if (contentTypes.hasRelationReordering(parent?.attribute) && RELATION_REORDERING_FIELDS.includes(key)) {
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
// allow id fields where it is needed for setting a relational id rather than trying to create with a given id
|
|
54
|
+
const canUseID = contentTypes.isRelationalAttribute(parent?.attribute) || contentTypes.isMediaAttribute(parent?.attribute);
|
|
55
|
+
if (canUseID && !ID_FIELDS.includes(key)) {
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
// if we couldn't find any reason for it to be here, throw
|
|
59
|
+
utils.throwInvalidKey({
|
|
60
|
+
key,
|
|
61
|
+
path: attribute
|
|
62
|
+
});
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
module.exports = throwUnrecognizedFields;
|
|
66
|
+
//# sourceMappingURL=throw-unrecognized-fields.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"throw-unrecognized-fields.js","sources":["../../../src/validate/visitors/throw-unrecognized-fields.ts"],"sourcesContent":["import {\n isDynamicZoneAttribute,\n isMorphToRelationalAttribute,\n isRelationalAttribute,\n constants,\n isComponentSchema,\n isMediaAttribute,\n hasRelationReordering,\n} from '../../content-types';\nimport type { Visitor } from '../../traverse-entity';\nimport { throwInvalidKey } from '../utils';\n\n// TODO these should all be centralized somewhere instead of maintaining a list\nconst ID_FIELDS = [constants.DOC_ID_ATTRIBUTE, constants.DOC_ID_ATTRIBUTE];\nconst ALLOWED_ROOT_LEVEL_FIELDS = [...ID_FIELDS];\nconst MORPH_TO_ALLOWED_FIELDS = ['__type'];\nconst DYNAMIC_ZONE_ALLOWED_FIELDS = ['__component'];\nconst RELATION_REORDERING_FIELDS = ['connect', 'disconnect', 'set', 'options'];\n\nconst throwUnrecognizedFields: Visitor = ({ key, attribute, path, schema, parent }) => {\n // We only look at properties that are not attributes\n if (attribute) {\n return;\n }\n\n // At root level (path.attribute === null), only accept allowed fields\n if (path.attribute === null) {\n if (ALLOWED_ROOT_LEVEL_FIELDS.includes(key)) {\n return;\n }\n\n return throwInvalidKey({ key, path: attribute });\n }\n\n // allow special morphTo keys\n if (isMorphToRelationalAttribute(parent?.attribute) && MORPH_TO_ALLOWED_FIELDS.includes(key)) {\n return;\n }\n\n // allow special dz keys\n if (\n isComponentSchema(schema) &&\n isDynamicZoneAttribute(parent?.attribute) &&\n DYNAMIC_ZONE_ALLOWED_FIELDS.includes(key)\n ) {\n return;\n }\n\n // allow special relation reordering keys in manyToX and XtoMany relations\n if (hasRelationReordering(parent?.attribute) && RELATION_REORDERING_FIELDS.includes(key)) {\n return;\n }\n\n // allow id fields where it is needed for setting a relational id rather than trying to create with a given id\n const canUseID = isRelationalAttribute(parent?.attribute) || isMediaAttribute(parent?.attribute);\n if (canUseID && !ID_FIELDS.includes(key)) {\n return;\n }\n\n // if we couldn't find any reason for it to be here, throw\n throwInvalidKey({ key, path: attribute });\n};\n\nexport default throwUnrecognizedFields;\n"],"names":["ID_FIELDS","constants","DOC_ID_ATTRIBUTE","ALLOWED_ROOT_LEVEL_FIELDS","MORPH_TO_ALLOWED_FIELDS","DYNAMIC_ZONE_ALLOWED_FIELDS","RELATION_REORDERING_FIELDS","throwUnrecognizedFields","key","attribute","path","schema","parent","includes","throwInvalidKey","isMorphToRelationalAttribute","isComponentSchema","isDynamicZoneAttribute","hasRelationReordering","canUseID","isRelationalAttribute","isMediaAttribute"],"mappings":";;;;;AAYA;AACA,MAAMA,SAAY,GAAA;AAACC,IAAAA,sBAAAA,CAAUC,gBAAgB;AAAED,IAAAA,sBAAAA,CAAUC;AAAiB,CAAA;AAC1E,MAAMC,yBAA4B,GAAA;AAAIH,IAAAA,GAAAA;AAAU,CAAA;AAChD,MAAMI,uBAA0B,GAAA;AAAC,IAAA;AAAS,CAAA;AAC1C,MAAMC,2BAA8B,GAAA;AAAC,IAAA;AAAc,CAAA;AACnD,MAAMC,0BAA6B,GAAA;AAAC,IAAA,SAAA;AAAW,IAAA,YAAA;AAAc,IAAA,KAAA;AAAO,IAAA;AAAU,CAAA;AAE9E,MAAMC,uBAAmC,GAAA,CAAC,EAAEC,GAAG,EAAEC,SAAS,EAAEC,IAAI,EAAEC,MAAM,EAAEC,MAAM,EAAE,GAAA;;AAEhF,IAAA,IAAIH,SAAW,EAAA;AACb,QAAA;AACF;;IAGA,IAAIC,IAAAA,CAAKD,SAAS,KAAK,IAAM,EAAA;QAC3B,IAAIN,yBAAAA,CAA0BU,QAAQ,CAACL,GAAM,CAAA,EAAA;AAC3C,YAAA;AACF;AAEA,QAAA,OAAOM,qBAAgB,CAAA;AAAEN,YAAAA,GAAAA;YAAKE,IAAMD,EAAAA;AAAU,SAAA,CAAA;AAChD;;AAGA,IAAA,IAAIM,0CAA6BH,MAAQH,EAAAA,SAAAA,CAAAA,IAAcL,uBAAwBS,CAAAA,QAAQ,CAACL,GAAM,CAAA,EAAA;AAC5F,QAAA;AACF;;IAGA,IACEQ,8BAAAA,CAAkBL,WAClBM,mCAAuBL,CAAAA,MAAAA,EAAQH,cAC/BJ,2BAA4BQ,CAAAA,QAAQ,CAACL,GACrC,CAAA,EAAA;AACA,QAAA;AACF;;AAGA,IAAA,IAAIU,mCAAsBN,MAAQH,EAAAA,SAAAA,CAAAA,IAAcH,0BAA2BO,CAAAA,QAAQ,CAACL,GAAM,CAAA,EAAA;AACxF,QAAA;AACF;;AAGA,IAAA,MAAMW,QAAWC,GAAAA,kCAAAA,CAAsBR,MAAQH,EAAAA,SAAAA,CAAAA,IAAcY,8BAAiBT,MAAQH,EAAAA,SAAAA,CAAAA;AACtF,IAAA,IAAIU,QAAY,IAAA,CAACnB,SAAUa,CAAAA,QAAQ,CAACL,GAAM,CAAA,EAAA;AACxC,QAAA;AACF;;IAGAM,qBAAgB,CAAA;AAAEN,QAAAA,GAAAA;QAAKE,IAAMD,EAAAA;AAAU,KAAA,CAAA;AACzC;;;;"}
|