directus 9.7.0 → 9.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/__mocks__/cache.d.ts +5 -0
- package/dist/__mocks__/cache.js +7 -0
- package/dist/auth/drivers/ldap.js +10 -11
- package/dist/auth/drivers/oauth2.js +9 -4
- package/dist/auth/drivers/openid.js +7 -4
- package/dist/cache.js +2 -2
- package/dist/cli/commands/schema/apply.js +9 -3
- package/dist/controllers/assets.js +5 -0
- package/dist/controllers/files.d.ts +2 -0
- package/dist/controllers/files.js +10 -5
- package/dist/database/helpers/date/dialects/default.d.ts +3 -0
- package/dist/database/helpers/date/dialects/default.js +7 -0
- package/dist/database/helpers/date/dialects/mssql.d.ts +1 -9
- package/dist/database/helpers/date/dialects/mssql.js +4 -23
- package/dist/database/helpers/date/dialects/mysql.d.ts +2 -9
- package/dist/database/helpers/date/dialects/mysql.js +7 -22
- package/dist/database/helpers/date/dialects/oracle.d.ts +1 -9
- package/dist/database/helpers/date/dialects/oracle.js +7 -23
- package/dist/database/helpers/date/dialects/sqlite.d.ts +1 -9
- package/dist/database/helpers/date/dialects/sqlite.js +8 -24
- package/dist/database/helpers/date/index.d.ts +4 -4
- package/dist/database/helpers/date/index.js +9 -9
- package/dist/database/helpers/date/types.d.ts +3 -9
- package/dist/database/helpers/date/types.js +10 -0
- package/dist/database/helpers/fn/dialects/mssql.d.ts +13 -0
- package/dist/database/helpers/fn/dialects/mssql.js +42 -0
- package/dist/database/helpers/{date/dialects/postgres.d.ts → fn/dialects/mysql.d.ts} +3 -2
- package/dist/database/helpers/fn/dialects/mysql.js +42 -0
- package/dist/database/helpers/fn/dialects/oracle.d.ts +13 -0
- package/dist/database/helpers/fn/dialects/oracle.js +42 -0
- package/dist/database/helpers/fn/dialects/postgres.d.ts +13 -0
- package/dist/database/helpers/{date → fn}/dialects/postgres.js +14 -3
- package/dist/database/helpers/fn/dialects/sqlite.d.ts +13 -0
- package/dist/database/helpers/fn/dialects/sqlite.js +42 -0
- package/dist/database/helpers/fn/index.d.ts +7 -0
- package/dist/database/helpers/fn/index.js +17 -0
- package/dist/database/helpers/fn/types.d.ts +18 -0
- package/dist/database/helpers/fn/types.js +27 -0
- package/dist/database/helpers/index.d.ts +4 -1
- package/dist/database/helpers/index.js +7 -1
- package/dist/database/index.js +0 -3
- package/dist/database/migrations/20220308A-add-bookmark-icon-and-color.d.ts +3 -0
- package/dist/database/migrations/20220308A-add-bookmark-icon-and-color.js +17 -0
- package/dist/database/migrations/20220314A-add-translation-strings.d.ts +3 -0
- package/dist/database/migrations/20220314A-add-translation-strings.js +15 -0
- package/dist/database/migrations/20220322A-rename-field-typecast-flags.d.ts +3 -0
- package/dist/database/migrations/20220322A-rename-field-typecast-flags.js +77 -0
- package/dist/database/migrations/20220323A-add-field-validation.d.ts +3 -0
- package/dist/database/migrations/20220323A-add-field-validation.js +17 -0
- package/dist/database/migrations/20220325A-fix-typecast-flags.d.ts +3 -0
- package/dist/database/migrations/20220325A-fix-typecast-flags.js +49 -0
- package/dist/database/migrations/20220325B-add-default-language.d.ts +3 -0
- package/dist/database/migrations/20220325B-add-default-language.js +28 -0
- package/dist/database/migrations/20220402A-remove-default-value-panel-icon.d.ts +3 -0
- package/dist/database/migrations/20220402A-remove-default-value-panel-icon.js +22 -0
- package/dist/database/migrations/run.js +1 -1
- package/dist/database/run-ast.js +4 -2
- package/dist/database/system-data/fields/activity.yaml +4 -4
- package/dist/database/system-data/fields/collections.yaml +4 -4
- package/dist/database/system-data/fields/fields.yaml +17 -8
- package/dist/database/system-data/fields/files.yaml +2 -2
- package/dist/database/system-data/fields/panels.yaml +2 -2
- package/dist/database/system-data/fields/permissions.yaml +4 -4
- package/dist/database/system-data/fields/presets.yaml +17 -3
- package/dist/database/system-data/fields/relations.yaml +1 -1
- package/dist/database/system-data/fields/revisions.yaml +2 -2
- package/dist/database/system-data/fields/roles.yaml +4 -4
- package/dist/database/system-data/fields/settings.yaml +18 -4
- package/dist/database/system-data/fields/users.yaml +5 -2
- package/dist/database/system-data/fields/webhooks.yaml +4 -4
- package/dist/env.js +4 -1
- package/dist/exceptions/index.d.ts +1 -0
- package/dist/exceptions/index.js +1 -0
- package/dist/exceptions/token-expired.d.ts +4 -0
- package/dist/exceptions/token-expired.js +10 -0
- package/dist/logger.js +2 -1
- package/dist/middleware/cache.js +10 -0
- package/dist/services/activity.js +4 -1
- package/dist/services/authorization.d.ts +1 -1
- package/dist/services/authorization.js +198 -14
- package/dist/services/collections.d.ts +2 -0
- package/dist/services/collections.js +230 -198
- package/dist/services/fields.js +208 -174
- package/dist/services/files.d.ts +5 -1
- package/dist/services/files.js +59 -40
- package/dist/services/graphql.d.ts +2 -3
- package/dist/services/graphql.js +39 -9
- package/dist/services/items.js +1 -0
- package/dist/services/payload.d.ts +1 -0
- package/dist/services/payload.js +29 -24
- package/dist/services/relations.js +93 -81
- package/dist/services/server.js +1 -0
- package/dist/services/shares.js +2 -1
- package/dist/services/users.js +3 -1
- package/dist/types/files.d.ts +8 -0
- package/dist/utils/apply-query.js +38 -10
- package/dist/utils/apply-snapshot.d.ts +3 -1
- package/dist/utils/apply-snapshot.js +34 -5
- package/dist/utils/get-column.d.ts +6 -5
- package/dist/utils/get-column.js +16 -8
- package/dist/utils/get-graphql-type.js +1 -0
- package/dist/utils/get-local-type.js +7 -2
- package/dist/utils/get-schema.d.ts +1 -1
- package/dist/utils/get-schema.js +15 -10
- package/dist/utils/jwt.js +1 -1
- package/dist/utils/track.js +3 -2
- package/dist/utils/url.d.ts +1 -1
- package/dist/utils/url.js +1 -1
- package/dist/utils/validate-query.js +19 -15
- package/dist/utils/validate-storage.js +3 -1
- package/example.env +4 -0
- package/package.json +14 -13
|
@@ -4,14 +4,14 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.AuthorizationService = void 0;
|
|
7
|
+
const exceptions_1 = require("@directus/shared/exceptions");
|
|
8
|
+
const utils_1 = require("@directus/shared/utils");
|
|
7
9
|
const lodash_1 = require("lodash");
|
|
8
10
|
const database_1 = __importDefault(require("../database"));
|
|
9
|
-
const
|
|
10
|
-
const
|
|
11
|
-
const utils_1 = require("@directus/shared/utils");
|
|
11
|
+
const exceptions_2 = require("../exceptions");
|
|
12
|
+
const strip_function_1 = require("../utils/strip-function");
|
|
12
13
|
const items_1 = require("./items");
|
|
13
14
|
const payload_1 = require("./payload");
|
|
14
|
-
const strip_function_1 = require("../utils/strip-function");
|
|
15
15
|
class AuthorizationService {
|
|
16
16
|
constructor(options) {
|
|
17
17
|
this.knex = options.knex || (0, database_1.default)();
|
|
@@ -32,9 +32,10 @@ class AuthorizationService {
|
|
|
32
32
|
// If the permissions don't match the collections, you don't have permission to read all of them
|
|
33
33
|
const uniqueCollectionsRequestedCount = (0, lodash_1.uniq)(collectionsRequested.map(({ collection }) => collection)).length;
|
|
34
34
|
if (uniqueCollectionsRequestedCount !== permissionsForCollections.length) {
|
|
35
|
-
throw new
|
|
35
|
+
throw new exceptions_2.ForbiddenException();
|
|
36
36
|
}
|
|
37
37
|
validateFields(ast);
|
|
38
|
+
validateFilterPermissions(ast, this.schema, action, this.accountability);
|
|
38
39
|
applyFilters(ast, this.accountability);
|
|
39
40
|
return ast;
|
|
40
41
|
/**
|
|
@@ -86,8 +87,10 @@ class AuthorizationService {
|
|
|
86
87
|
if (!aliasMap)
|
|
87
88
|
continue;
|
|
88
89
|
for (const column of Object.values(aliasMap)) {
|
|
90
|
+
if (column === '*')
|
|
91
|
+
continue;
|
|
89
92
|
if (allowedFields.includes(column) === false)
|
|
90
|
-
throw new
|
|
93
|
+
throw new exceptions_2.ForbiddenException();
|
|
91
94
|
}
|
|
92
95
|
}
|
|
93
96
|
}
|
|
@@ -100,7 +103,176 @@ class AuthorizationService {
|
|
|
100
103
|
continue;
|
|
101
104
|
const fieldKey = (0, strip_function_1.stripFunction)(childNode.name);
|
|
102
105
|
if (allowedFields.includes(fieldKey) === false) {
|
|
103
|
-
throw new
|
|
106
|
+
throw new exceptions_2.ForbiddenException();
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
function validateFilterPermissions(ast, schema, action, accountability) {
|
|
112
|
+
var _a, _b, _c, _d, _e;
|
|
113
|
+
let requiredFieldPermissions = {};
|
|
114
|
+
if (ast.type !== 'field') {
|
|
115
|
+
if (ast.type === 'a2o') {
|
|
116
|
+
for (const collection of Object.keys(ast.children)) {
|
|
117
|
+
requiredFieldPermissions = mergeRequiredFieldPermissions(requiredFieldPermissions, extractRequiredFieldPermissions(collection, (_c = (_b = (_a = ast.query) === null || _a === void 0 ? void 0 : _a[collection]) === null || _b === void 0 ? void 0 : _b.filter) !== null && _c !== void 0 ? _c : {}));
|
|
118
|
+
for (const child of ast.children[collection]) {
|
|
119
|
+
const childPermissions = validateFilterPermissions(child, schema, action, accountability);
|
|
120
|
+
if (Object.keys(childPermissions).length > 0) {
|
|
121
|
+
//Only add relational field if deep child has a filter
|
|
122
|
+
if (child.type !== 'field') {
|
|
123
|
+
(requiredFieldPermissions[collection] || (requiredFieldPermissions[collection] = new Set())).add(child.fieldKey);
|
|
124
|
+
}
|
|
125
|
+
requiredFieldPermissions = mergeRequiredFieldPermissions(requiredFieldPermissions, childPermissions);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
else {
|
|
131
|
+
requiredFieldPermissions = mergeRequiredFieldPermissions(requiredFieldPermissions, extractRequiredFieldPermissions(ast.name, (_e = (_d = ast.query) === null || _d === void 0 ? void 0 : _d.filter) !== null && _e !== void 0 ? _e : {}));
|
|
132
|
+
for (const child of ast.children) {
|
|
133
|
+
const childPermissions = validateFilterPermissions(child, schema, action, accountability);
|
|
134
|
+
if (Object.keys(childPermissions).length > 0) {
|
|
135
|
+
// Only add relational field if deep child has a filter
|
|
136
|
+
if (child.type !== 'field') {
|
|
137
|
+
(requiredFieldPermissions[ast.name] || (requiredFieldPermissions[ast.name] = new Set())).add(child.fieldKey);
|
|
138
|
+
}
|
|
139
|
+
requiredFieldPermissions = mergeRequiredFieldPermissions(requiredFieldPermissions, childPermissions);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
if (ast.type === 'root') {
|
|
145
|
+
// Validate all required permissions once at the root level
|
|
146
|
+
checkFieldPermissions(ast.name, schema, action, requiredFieldPermissions);
|
|
147
|
+
}
|
|
148
|
+
return requiredFieldPermissions;
|
|
149
|
+
function extractRequiredFieldPermissions(collection, filter, parentCollection, parentField) {
|
|
150
|
+
return (0, lodash_1.reduce)(filter, function (result, filterValue, filterKey) {
|
|
151
|
+
if (filterKey.startsWith('_')) {
|
|
152
|
+
if (filterKey === '_and' || filterKey === '_or') {
|
|
153
|
+
if ((0, lodash_1.isArray)(filterValue)) {
|
|
154
|
+
for (const filter of filterValue) {
|
|
155
|
+
const requiredPermissions = extractRequiredFieldPermissions(collection, filter, parentCollection, parentField);
|
|
156
|
+
result = mergeRequiredFieldPermissions(result, requiredPermissions);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
return result;
|
|
160
|
+
}
|
|
161
|
+
// Filter value is not a filter, so we should skip it
|
|
162
|
+
return result;
|
|
163
|
+
}
|
|
164
|
+
// m2a filter in the form of `item:collection`
|
|
165
|
+
else if (filterKey.includes(':')) {
|
|
166
|
+
const [field, collectionScope] = filterKey.split(':');
|
|
167
|
+
if (collection) {
|
|
168
|
+
// Add the `item` field to the required permissions
|
|
169
|
+
(result[collection] || (result[collection] = new Set())).add(field);
|
|
170
|
+
// Add the `collection` field to the required permissions
|
|
171
|
+
result[collection].add('collection');
|
|
172
|
+
}
|
|
173
|
+
else {
|
|
174
|
+
const relation = schema.relations.find((relation) => {
|
|
175
|
+
var _a;
|
|
176
|
+
return ((relation.collection === parentCollection && relation.field === parentField) ||
|
|
177
|
+
(relation.related_collection === parentCollection && ((_a = relation.meta) === null || _a === void 0 ? void 0 : _a.one_field) === parentField));
|
|
178
|
+
});
|
|
179
|
+
// Filter key not found in parent collection
|
|
180
|
+
if (!relation)
|
|
181
|
+
throw new exceptions_2.ForbiddenException();
|
|
182
|
+
const relatedCollectionName = relation.related_collection === parentCollection ? relation.collection : relation.related_collection;
|
|
183
|
+
// Add the `item` field to the required permissions
|
|
184
|
+
(result[relatedCollectionName] || (result[relatedCollectionName] = new Set())).add(field);
|
|
185
|
+
// Add the `collection` field to the required permissions
|
|
186
|
+
result[relatedCollectionName].add('collection');
|
|
187
|
+
}
|
|
188
|
+
// Continue to parse the filter for nested `collection` afresh
|
|
189
|
+
const requiredPermissions = extractRequiredFieldPermissions(collectionScope, filterValue);
|
|
190
|
+
result = mergeRequiredFieldPermissions(result, requiredPermissions);
|
|
191
|
+
}
|
|
192
|
+
else {
|
|
193
|
+
if (collection) {
|
|
194
|
+
(result[collection] || (result[collection] = new Set())).add(filterKey);
|
|
195
|
+
}
|
|
196
|
+
else {
|
|
197
|
+
const relation = schema.relations.find((relation) => {
|
|
198
|
+
var _a;
|
|
199
|
+
return ((relation.collection === parentCollection && relation.field === parentField) ||
|
|
200
|
+
(relation.related_collection === parentCollection && ((_a = relation.meta) === null || _a === void 0 ? void 0 : _a.one_field) === parentField));
|
|
201
|
+
});
|
|
202
|
+
// Filter key not found in parent collection
|
|
203
|
+
if (!relation)
|
|
204
|
+
throw new exceptions_2.ForbiddenException();
|
|
205
|
+
parentCollection =
|
|
206
|
+
relation.related_collection === parentCollection ? relation.collection : relation.related_collection;
|
|
207
|
+
(result[parentCollection] || (result[parentCollection] = new Set())).add(filterKey);
|
|
208
|
+
}
|
|
209
|
+
if (typeof filterValue === 'object') {
|
|
210
|
+
// Parent collection is undefined when we process the top level filter
|
|
211
|
+
if (!parentCollection)
|
|
212
|
+
parentCollection = collection;
|
|
213
|
+
for (const [childFilterKey, childFilterValue] of Object.entries(filterValue)) {
|
|
214
|
+
if (childFilterKey.startsWith('_')) {
|
|
215
|
+
if (childFilterKey === '_and' || childFilterKey === '_or') {
|
|
216
|
+
if ((0, lodash_1.isArray)(childFilterValue)) {
|
|
217
|
+
for (const filter of childFilterValue) {
|
|
218
|
+
const requiredPermissions = extractRequiredFieldPermissions('', filter, parentCollection, filterKey);
|
|
219
|
+
result = mergeRequiredFieldPermissions(result, requiredPermissions);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
else {
|
|
225
|
+
const requiredPermissions = extractRequiredFieldPermissions('', filterValue, parentCollection, filterKey);
|
|
226
|
+
result = mergeRequiredFieldPermissions(result, requiredPermissions);
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
return result;
|
|
232
|
+
}, {});
|
|
233
|
+
}
|
|
234
|
+
function mergeRequiredFieldPermissions(current, child) {
|
|
235
|
+
for (const collection of Object.keys(child)) {
|
|
236
|
+
if (!current[collection]) {
|
|
237
|
+
current[collection] = child[collection];
|
|
238
|
+
}
|
|
239
|
+
else {
|
|
240
|
+
current[collection] = new Set([...current[collection], ...child[collection]]);
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
return current;
|
|
244
|
+
}
|
|
245
|
+
function checkFieldPermissions(rootCollection, schema, action, requiredPermissions) {
|
|
246
|
+
var _a, _b;
|
|
247
|
+
if ((accountability === null || accountability === void 0 ? void 0 : accountability.admin) === true)
|
|
248
|
+
return;
|
|
249
|
+
for (const collection of Object.keys(requiredPermissions)) {
|
|
250
|
+
const permission = (_a = accountability === null || accountability === void 0 ? void 0 : accountability.permissions) === null || _a === void 0 ? void 0 : _a.find((permission) => permission.collection === collection && permission.action === 'read');
|
|
251
|
+
let allowedFields;
|
|
252
|
+
// Allow the filtering of top level ID for actions such as update and delete
|
|
253
|
+
if (action !== 'read' && collection === rootCollection) {
|
|
254
|
+
const actionPermission = (_b = accountability === null || accountability === void 0 ? void 0 : accountability.permissions) === null || _b === void 0 ? void 0 : _b.find((permission) => permission.collection === collection && permission.action === action);
|
|
255
|
+
if (!actionPermission || !actionPermission.fields) {
|
|
256
|
+
throw new exceptions_2.ForbiddenException();
|
|
257
|
+
}
|
|
258
|
+
allowedFields = (permission === null || permission === void 0 ? void 0 : permission.fields)
|
|
259
|
+
? [...permission.fields, schema.collections[collection].primary]
|
|
260
|
+
: [schema.collections[collection].primary];
|
|
261
|
+
}
|
|
262
|
+
else if (!permission || !permission.fields) {
|
|
263
|
+
throw new exceptions_2.ForbiddenException();
|
|
264
|
+
}
|
|
265
|
+
else {
|
|
266
|
+
allowedFields = permission.fields;
|
|
267
|
+
}
|
|
268
|
+
if (allowedFields.includes('*'))
|
|
269
|
+
continue;
|
|
270
|
+
// Allow legacy permissions with an empty fields array, where id can be accessed
|
|
271
|
+
if (allowedFields.length === 0)
|
|
272
|
+
allowedFields.push(schema.collections[collection].primary);
|
|
273
|
+
for (const field of requiredPermissions[collection]) {
|
|
274
|
+
if (!allowedFields.includes(field))
|
|
275
|
+
throw new exceptions_2.ForbiddenException();
|
|
104
276
|
}
|
|
105
277
|
}
|
|
106
278
|
}
|
|
@@ -164,20 +336,24 @@ class AuthorizationService {
|
|
|
164
336
|
return permission.collection === collection && permission.action === action;
|
|
165
337
|
});
|
|
166
338
|
if (!permission)
|
|
167
|
-
throw new
|
|
339
|
+
throw new exceptions_2.ForbiddenException();
|
|
168
340
|
// Check if you have permission to access the fields you're trying to access
|
|
169
341
|
const allowedFields = permission.fields || [];
|
|
170
342
|
if (allowedFields.includes('*') === false) {
|
|
171
343
|
const keysInData = Object.keys(payload);
|
|
172
344
|
const invalidKeys = keysInData.filter((fieldKey) => allowedFields.includes(fieldKey) === false);
|
|
173
345
|
if (invalidKeys.length > 0) {
|
|
174
|
-
throw new
|
|
346
|
+
throw new exceptions_2.ForbiddenException();
|
|
175
347
|
}
|
|
176
348
|
}
|
|
177
349
|
}
|
|
178
350
|
const preset = (_e = permission.presets) !== null && _e !== void 0 ? _e : {};
|
|
179
351
|
const payloadWithPresets = (0, lodash_1.merge)({}, preset, payload);
|
|
352
|
+
const fieldValidationRules = Object.values(this.schema.collections[collection].fields)
|
|
353
|
+
.map((field) => field.validation)
|
|
354
|
+
.filter((v) => v);
|
|
180
355
|
const hasValidationRules = (0, lodash_1.isNil)(permission.validation) === false && Object.keys((_f = permission.validation) !== null && _f !== void 0 ? _f : {}).length > 0;
|
|
356
|
+
const hasFieldValidationRules = fieldValidationRules && fieldValidationRules.length > 0;
|
|
181
357
|
const requiredColumns = [];
|
|
182
358
|
for (const field of Object.values(this.schema.collections[collection].fields)) {
|
|
183
359
|
const specials = (_g = field === null || field === void 0 ? void 0 : field.special) !== null && _g !== void 0 ? _g : [];
|
|
@@ -187,7 +363,7 @@ class AuthorizationService {
|
|
|
187
363
|
requiredColumns.push(field);
|
|
188
364
|
}
|
|
189
365
|
}
|
|
190
|
-
if (hasValidationRules === false && requiredColumns.length === 0) {
|
|
366
|
+
if (hasValidationRules === false && hasFieldValidationRules === false && requiredColumns.length === 0) {
|
|
191
367
|
return payloadWithPresets;
|
|
192
368
|
}
|
|
193
369
|
if (requiredColumns.length > 0) {
|
|
@@ -207,8 +383,16 @@ class AuthorizationService {
|
|
|
207
383
|
});
|
|
208
384
|
}
|
|
209
385
|
}
|
|
386
|
+
if (hasFieldValidationRules) {
|
|
387
|
+
if (permission.validation && Object.keys(permission.validation).length > 0) {
|
|
388
|
+
permission.validation = { _and: [permission.validation, ...fieldValidationRules] };
|
|
389
|
+
}
|
|
390
|
+
else {
|
|
391
|
+
permission.validation = { _and: fieldValidationRules };
|
|
392
|
+
}
|
|
393
|
+
}
|
|
210
394
|
const validationErrors = [];
|
|
211
|
-
validationErrors.push(...(0, lodash_1.flatten)((0, utils_1.validatePayload)(permission.validation, payloadWithPresets).map((error) => error.details.map((details) => new
|
|
395
|
+
validationErrors.push(...(0, lodash_1.flatten)((0, utils_1.validatePayload)(permission.validation, payloadWithPresets).map((error) => error.details.map((details) => new exceptions_1.FailedValidationException(details)))));
|
|
212
396
|
if (validationErrors.length > 0)
|
|
213
397
|
throw validationErrors;
|
|
214
398
|
return payloadWithPresets;
|
|
@@ -228,14 +412,14 @@ class AuthorizationService {
|
|
|
228
412
|
if (Array.isArray(pk)) {
|
|
229
413
|
const result = await itemsService.readMany(pk, { ...query, limit: pk.length }, { permissionsAction: action });
|
|
230
414
|
if (!result)
|
|
231
|
-
throw new
|
|
415
|
+
throw new exceptions_2.ForbiddenException();
|
|
232
416
|
if (result.length !== pk.length)
|
|
233
|
-
throw new
|
|
417
|
+
throw new exceptions_2.ForbiddenException();
|
|
234
418
|
}
|
|
235
419
|
else {
|
|
236
420
|
const result = await itemsService.readOne(pk, query, { permissionsAction: action });
|
|
237
421
|
if (!result)
|
|
238
|
-
throw new
|
|
422
|
+
throw new exceptions_2.ForbiddenException();
|
|
239
423
|
}
|
|
240
424
|
}
|
|
241
425
|
}
|
|
@@ -4,6 +4,7 @@ import Keyv from 'keyv';
|
|
|
4
4
|
import { AbstractServiceOptions, Collection, CollectionMeta, MutationOptions } from '../types';
|
|
5
5
|
import { Accountability, RawField, SchemaOverview } from '@directus/shared/types';
|
|
6
6
|
import { Table } from 'knex-schema-inspector/dist/types/table';
|
|
7
|
+
import { Helpers } from '../database/helpers';
|
|
7
8
|
export declare type RawCollection = {
|
|
8
9
|
collection: string;
|
|
9
10
|
fields?: RawField[];
|
|
@@ -12,6 +13,7 @@ export declare type RawCollection = {
|
|
|
12
13
|
};
|
|
13
14
|
export declare class CollectionsService {
|
|
14
15
|
knex: Knex;
|
|
16
|
+
helpers: Helpers;
|
|
15
17
|
accountability: Accountability | null;
|
|
16
18
|
schemaInspector: ReturnType<typeof SchemaInspector>;
|
|
17
19
|
schema: SchemaOverview;
|