directus 9.12.2 → 9.14.1
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/app.js +14 -5
- package/dist/auth/drivers/index.js +5 -1
- package/dist/auth/drivers/ldap.js +5 -1
- package/dist/auth/drivers/oauth2.js +15 -23
- package/dist/auth/drivers/openid.js +20 -25
- package/dist/cli/commands/bootstrap/index.js +5 -1
- package/dist/cli/commands/schema/apply.js +7 -3
- package/dist/cli/commands/schema/snapshot.d.ts +1 -1
- package/dist/cli/commands/schema/snapshot.js +33 -25
- package/dist/cli/index.js +1 -1
- package/dist/cli/utils/create-env/env-stub.liquid +11 -11
- package/dist/controllers/assets.js +5 -5
- package/dist/controllers/dashboards.js +4 -1
- package/dist/controllers/files.js +8 -5
- package/dist/controllers/flows.js +4 -1
- package/dist/controllers/folders.js +4 -1
- package/dist/controllers/items.js +4 -1
- package/dist/controllers/notifications.js +4 -1
- package/dist/controllers/operations.js +4 -1
- package/dist/controllers/panels.js +4 -1
- package/dist/controllers/permissions.js +4 -1
- package/dist/controllers/presets.js +4 -1
- package/dist/controllers/roles.js +4 -1
- package/dist/controllers/shares.js +4 -1
- package/dist/controllers/users.js +75 -3
- package/dist/controllers/utils.js +3 -3
- package/dist/database/helpers/date/dialects/sqlite.js +3 -0
- package/dist/database/helpers/index.js +5 -1
- package/dist/database/index.js +2 -0
- package/dist/database/migrations/20210225A-add-relations-sort-field.js +2 -2
- package/dist/database/migrations/20210506A-rename-interfaces.js +2 -2
- package/dist/database/migrations/20210802A-replace-groups.js +2 -2
- package/dist/database/migrations/20210805A-update-groups.js +2 -2
- package/dist/database/migrations/20210805B-change-image-metadata-structure.js +3 -3
- package/dist/database/migrations/20211007A-update-presets.js +5 -5
- package/dist/database/migrations/20220429A-add-flows.js +1 -2
- package/dist/database/migrations/20220614A-rename-hook-trigger-to-event.d.ts +3 -0
- package/dist/database/migrations/20220614A-rename-hook-trigger-to-event.js +11 -0
- package/dist/database/system-data/fields/dashboards.yaml +1 -0
- package/dist/emitter.js +12 -7
- package/dist/env.d.ts +1 -1
- package/dist/env.js +8 -3
- package/dist/exceptions/database/translate.js +5 -1
- package/dist/exceptions/index.js +5 -1
- package/dist/extensions.js +5 -1
- package/dist/flows.js +15 -11
- package/dist/index.js +5 -1
- package/dist/logger.js +5 -1
- package/dist/messenger.js +2 -2
- package/dist/middleware/graphql.js +2 -2
- package/dist/middleware/respond.js +10 -1
- package/dist/middleware/validate-batch.js +3 -1
- package/dist/operations/item-create/index.js +1 -2
- package/dist/operations/item-delete/index.d.ts +1 -0
- package/dist/operations/item-delete/index.js +8 -7
- package/dist/operations/item-read/index.d.ts +1 -0
- package/dist/operations/item-read/index.js +8 -7
- package/dist/operations/item-update/index.d.ts +1 -0
- package/dist/operations/item-update/index.js +9 -8
- package/dist/operations/log/index.js +1 -2
- package/dist/operations/notification/index.js +1 -2
- package/dist/operations/transform/index.js +1 -2
- package/dist/operations/trigger/index.js +1 -2
- package/dist/server.js +5 -1
- package/dist/services/assets.js +5 -1
- package/dist/services/collections.js +5 -1
- package/dist/services/fields.d.ts +3 -3
- package/dist/services/fields.js +25 -17
- package/dist/services/files.js +5 -1
- package/dist/services/flows.d.ts +1 -0
- package/dist/services/flows.js +6 -0
- package/dist/services/{graphql.d.ts → graphql/index.d.ts} +3 -5
- package/dist/services/{graphql.js → graphql/index.js} +109 -101
- package/dist/services/graphql/types/date.d.ts +2 -0
- package/dist/services/graphql/types/date.js +9 -0
- package/dist/services/graphql/types/geojson.d.ts +2 -0
- package/dist/services/graphql/types/geojson.js +10 -0
- package/dist/services/graphql/types/string-or-float.d.ts +5 -0
- package/dist/services/graphql/types/string-or-float.js +34 -0
- package/dist/services/graphql/types/void.d.ts +2 -0
- package/dist/services/graphql/types/void.js +17 -0
- package/dist/services/graphql/utils/add-path-to-validation-error.d.ts +2 -0
- package/dist/services/graphql/utils/add-path-to-validation-error.js +20 -0
- package/dist/services/import-export.js +12 -8
- package/dist/services/index.js +5 -1
- package/dist/services/items.d.ts +6 -1
- package/dist/services/items.js +43 -19
- package/dist/services/mail/index.js +8 -6
- package/dist/services/notifications.js +22 -11
- package/dist/services/operations.d.ts +1 -0
- package/dist/services/operations.js +6 -0
- package/dist/services/payload.js +13 -11
- package/dist/services/permissions.d.ts +1 -0
- package/dist/services/permissions.js +5 -0
- package/dist/services/relations.js +5 -1
- package/dist/services/roles.d.ts +1 -0
- package/dist/services/roles.js +9 -0
- package/dist/services/server.js +5 -1
- package/dist/services/users.d.ts +1 -0
- package/dist/services/users.js +17 -0
- package/dist/types/index.js +5 -1
- package/dist/utils/apply-query.js +24 -15
- package/dist/utils/calculate-field-depth.d.ts +33 -0
- package/dist/utils/calculate-field-depth.js +75 -0
- package/dist/utils/get-default-value.js +3 -13
- package/dist/utils/get-graphql-type.js +4 -3
- package/dist/utils/get-local-type.d.ts +6 -3
- package/dist/utils/get-permissions.js +3 -4
- package/dist/utils/get-schema.js +1 -2
- package/dist/utils/get-string-byte-size.d.ts +4 -0
- package/dist/utils/get-string-byte-size.js +10 -0
- package/dist/utils/jwt.js +5 -1
- package/dist/utils/sanitize-query.js +4 -5
- package/dist/utils/validate-query.js +50 -0
- package/dist/webhooks.js +5 -1
- package/package.json +74 -73
- package/dist/utils/operation-options.d.ts +0 -3
- package/dist/utils/operation-options.js +0 -45
- package/dist/utils/parse-json.d.ts +0 -5
- package/dist/utils/parse-json.js +0 -19
|
@@ -32,7 +32,7 @@ const multipartHandler = (req, res, next) => {
|
|
|
32
32
|
'content-type': 'application/octet-stream',
|
|
33
33
|
};
|
|
34
34
|
}
|
|
35
|
-
const busboy =
|
|
35
|
+
const busboy = (0, busboy_1.default)({ headers, defParamCharset: 'utf8' });
|
|
36
36
|
const savedFiles = [];
|
|
37
37
|
const service = new services_1.FilesService({ accountability: req.accountability, schema: req.schema });
|
|
38
38
|
const existingPrimaryKey = req.params.pk || undefined;
|
|
@@ -57,7 +57,7 @@ const multipartHandler = (req, res, next) => {
|
|
|
57
57
|
}
|
|
58
58
|
payload[fieldname] = fieldValue;
|
|
59
59
|
});
|
|
60
|
-
busboy.on('file', async (
|
|
60
|
+
busboy.on('file', async (_fieldname, fileStream, { filename, mimeType }) => {
|
|
61
61
|
if (!filename) {
|
|
62
62
|
return busboy.emit('error', new exceptions_1.InvalidPayloadException(`File is missing filename`));
|
|
63
63
|
}
|
|
@@ -68,7 +68,7 @@ const multipartHandler = (req, res, next) => {
|
|
|
68
68
|
const payloadWithRequiredFields = {
|
|
69
69
|
...payload,
|
|
70
70
|
filename_download: filename,
|
|
71
|
-
type:
|
|
71
|
+
type: mimeType,
|
|
72
72
|
storage: payload.storage || disk,
|
|
73
73
|
};
|
|
74
74
|
// Clear the payload for the next to-be-uploaded file
|
|
@@ -85,7 +85,7 @@ const multipartHandler = (req, res, next) => {
|
|
|
85
85
|
busboy.on('error', (error) => {
|
|
86
86
|
next(error);
|
|
87
87
|
});
|
|
88
|
-
busboy.on('
|
|
88
|
+
busboy.on('close', () => {
|
|
89
89
|
tryDone();
|
|
90
90
|
});
|
|
91
91
|
req.pipe(busboy);
|
|
@@ -204,7 +204,10 @@ router.patch('/', (0, validate_batch_1.validateBatch)('update'), (0, async_handl
|
|
|
204
204
|
schema: req.schema,
|
|
205
205
|
});
|
|
206
206
|
let keys = [];
|
|
207
|
-
if (req.body
|
|
207
|
+
if (Array.isArray(req.body)) {
|
|
208
|
+
keys = await service.updateBatch(req.body);
|
|
209
|
+
}
|
|
210
|
+
else if (req.body.keys) {
|
|
208
211
|
keys = await service.updateMany(req.body.keys, req.body.data);
|
|
209
212
|
}
|
|
210
213
|
else {
|
|
@@ -94,7 +94,10 @@ router.patch('/', (0, validate_batch_1.validateBatch)('update'), (0, async_handl
|
|
|
94
94
|
schema: req.schema,
|
|
95
95
|
});
|
|
96
96
|
let keys = [];
|
|
97
|
-
if (req.body
|
|
97
|
+
if (Array.isArray(req.body)) {
|
|
98
|
+
keys = await service.updateBatch(req.body);
|
|
99
|
+
}
|
|
100
|
+
else if (req.body.keys) {
|
|
98
101
|
keys = await service.updateMany(req.body.keys, req.body.data);
|
|
99
102
|
}
|
|
100
103
|
else {
|
|
@@ -84,7 +84,10 @@ router.patch('/', (0, validate_batch_1.validateBatch)('update'), (0, async_handl
|
|
|
84
84
|
schema: req.schema,
|
|
85
85
|
});
|
|
86
86
|
let keys = [];
|
|
87
|
-
if (req.body
|
|
87
|
+
if (Array.isArray(req.body)) {
|
|
88
|
+
keys = await service.updateBatch(req.body);
|
|
89
|
+
}
|
|
90
|
+
else if (req.body.keys) {
|
|
88
91
|
keys = await service.updateMany(req.body.keys, req.body.data);
|
|
89
92
|
}
|
|
90
93
|
else {
|
|
@@ -105,7 +105,10 @@ router.patch('/:collection', collection_exists_1.default, (0, validate_batch_1.v
|
|
|
105
105
|
return next();
|
|
106
106
|
}
|
|
107
107
|
let keys = [];
|
|
108
|
-
if (req.body
|
|
108
|
+
if (Array.isArray(req.body)) {
|
|
109
|
+
keys = await service.updateBatch(req.body);
|
|
110
|
+
}
|
|
111
|
+
else if (req.body.keys) {
|
|
109
112
|
keys = await service.updateMany(req.body.keys, req.body.data);
|
|
110
113
|
}
|
|
111
114
|
else {
|
|
@@ -84,7 +84,10 @@ router.patch('/', (0, validate_batch_1.validateBatch)('update'), (0, async_handl
|
|
|
84
84
|
schema: req.schema,
|
|
85
85
|
});
|
|
86
86
|
let keys = [];
|
|
87
|
-
if (req.body
|
|
87
|
+
if (Array.isArray(req.body)) {
|
|
88
|
+
keys = await service.updateBatch(req.body);
|
|
89
|
+
}
|
|
90
|
+
else if (req.body.keys) {
|
|
88
91
|
keys = await service.updateMany(req.body.keys, req.body.data);
|
|
89
92
|
}
|
|
90
93
|
else {
|
|
@@ -75,7 +75,10 @@ router.patch('/', (0, validate_batch_1.validateBatch)('update'), (0, async_handl
|
|
|
75
75
|
schema: req.schema,
|
|
76
76
|
});
|
|
77
77
|
let keys = [];
|
|
78
|
-
if (req.body
|
|
78
|
+
if (Array.isArray(req.body)) {
|
|
79
|
+
keys = await service.updateBatch(req.body);
|
|
80
|
+
}
|
|
81
|
+
else if (req.body.keys) {
|
|
79
82
|
keys = await service.updateMany(req.body.keys, req.body.data);
|
|
80
83
|
}
|
|
81
84
|
else {
|
|
@@ -75,7 +75,10 @@ router.patch('/', (0, validate_batch_1.validateBatch)('update'), (0, async_handl
|
|
|
75
75
|
schema: req.schema,
|
|
76
76
|
});
|
|
77
77
|
let keys = [];
|
|
78
|
-
if (req.body
|
|
78
|
+
if (Array.isArray(req.body)) {
|
|
79
|
+
keys = await service.updateBatch(req.body);
|
|
80
|
+
}
|
|
81
|
+
else if (req.body.keys) {
|
|
79
82
|
keys = await service.updateMany(req.body.keys, req.body.data);
|
|
80
83
|
}
|
|
81
84
|
else {
|
|
@@ -86,7 +86,10 @@ router.patch('/', (0, validate_batch_1.validateBatch)('update'), (0, async_handl
|
|
|
86
86
|
schema: req.schema,
|
|
87
87
|
});
|
|
88
88
|
let keys = [];
|
|
89
|
-
if (req.body
|
|
89
|
+
if (Array.isArray(req.body)) {
|
|
90
|
+
keys = await service.updateBatch(req.body);
|
|
91
|
+
}
|
|
92
|
+
else if (req.body.keys) {
|
|
90
93
|
keys = await service.updateMany(req.body.keys, req.body.data);
|
|
91
94
|
}
|
|
92
95
|
else {
|
|
@@ -84,7 +84,10 @@ router.patch('/', (0, validate_batch_1.validateBatch)('update'), (0, async_handl
|
|
|
84
84
|
schema: req.schema,
|
|
85
85
|
});
|
|
86
86
|
let keys = [];
|
|
87
|
-
if (req.body
|
|
87
|
+
if (Array.isArray(req.body)) {
|
|
88
|
+
keys = await service.updateBatch(req.body);
|
|
89
|
+
}
|
|
90
|
+
else if (req.body.keys) {
|
|
88
91
|
keys = await service.updateMany(req.body.keys, req.body.data);
|
|
89
92
|
}
|
|
90
93
|
else {
|
|
@@ -75,7 +75,10 @@ router.patch('/', (0, validate_batch_1.validateBatch)('update'), (0, async_handl
|
|
|
75
75
|
schema: req.schema,
|
|
76
76
|
});
|
|
77
77
|
let keys = [];
|
|
78
|
-
if (req.body
|
|
78
|
+
if (Array.isArray(req.body)) {
|
|
79
|
+
keys = await service.updateBatch(req.body);
|
|
80
|
+
}
|
|
81
|
+
else if (req.body.keys) {
|
|
79
82
|
keys = await service.updateMany(req.body.keys, req.body.data);
|
|
80
83
|
}
|
|
81
84
|
else {
|
|
@@ -149,7 +149,10 @@ router.patch('/', (0, validate_batch_1.validateBatch)('update'), (0, async_handl
|
|
|
149
149
|
schema: req.schema,
|
|
150
150
|
});
|
|
151
151
|
let keys = [];
|
|
152
|
-
if (req.body
|
|
152
|
+
if (Array.isArray(req.body)) {
|
|
153
|
+
keys = await service.updateBatch(req.body);
|
|
154
|
+
}
|
|
155
|
+
else if (req.body.keys) {
|
|
153
156
|
keys = await service.updateMany(req.body.keys, req.body.data);
|
|
154
157
|
}
|
|
155
158
|
else {
|
|
@@ -138,7 +138,10 @@ router.patch('/', (0, validate_batch_1.validateBatch)('update'), (0, async_handl
|
|
|
138
138
|
schema: req.schema,
|
|
139
139
|
});
|
|
140
140
|
let keys = [];
|
|
141
|
-
if (req.body
|
|
141
|
+
if (Array.isArray(req.body)) {
|
|
142
|
+
keys = await service.updateBatch(req.body);
|
|
143
|
+
}
|
|
144
|
+
else if (req.body.keys) {
|
|
142
145
|
keys = await service.updateMany(req.body.keys, req.body.data);
|
|
143
146
|
}
|
|
144
147
|
else {
|
|
@@ -251,7 +254,7 @@ router.post('/me/tfa/generate/', (0, async_handler_1.default)(async (req, res, n
|
|
|
251
254
|
return next();
|
|
252
255
|
}), respond_1.respond);
|
|
253
256
|
router.post('/me/tfa/enable/', (0, async_handler_1.default)(async (req, _res, next) => {
|
|
254
|
-
var _a;
|
|
257
|
+
var _a, _b;
|
|
255
258
|
if (!((_a = req.accountability) === null || _a === void 0 ? void 0 : _a.user)) {
|
|
256
259
|
throw new exceptions_1.InvalidCredentialsException();
|
|
257
260
|
}
|
|
@@ -261,6 +264,33 @@ router.post('/me/tfa/enable/', (0, async_handler_1.default)(async (req, _res, ne
|
|
|
261
264
|
if (!req.body.otp) {
|
|
262
265
|
throw new exceptions_1.InvalidPayloadException(`"otp" is required`);
|
|
263
266
|
}
|
|
267
|
+
// Override permissions only when enforce TFA is enabled in role
|
|
268
|
+
if (req.accountability.role) {
|
|
269
|
+
const rolesService = new services_1.RolesService({
|
|
270
|
+
schema: req.schema,
|
|
271
|
+
});
|
|
272
|
+
const role = (await rolesService.readOne(req.accountability.role));
|
|
273
|
+
if (role && role.enforce_tfa) {
|
|
274
|
+
const existingPermission = await ((_b = req.accountability.permissions) === null || _b === void 0 ? void 0 : _b.find((p) => p.collection === 'directus_users' && p.action === 'update'));
|
|
275
|
+
if (existingPermission) {
|
|
276
|
+
existingPermission.fields = ['tfa_secret'];
|
|
277
|
+
existingPermission.permissions = { id: { _eq: req.accountability.user } };
|
|
278
|
+
existingPermission.presets = null;
|
|
279
|
+
existingPermission.validation = null;
|
|
280
|
+
}
|
|
281
|
+
else {
|
|
282
|
+
(req.accountability.permissions || (req.accountability.permissions = [])).push({
|
|
283
|
+
action: 'update',
|
|
284
|
+
collection: 'directus_users',
|
|
285
|
+
fields: ['tfa_secret'],
|
|
286
|
+
permissions: { id: { _eq: req.accountability.user } },
|
|
287
|
+
presets: null,
|
|
288
|
+
role: req.accountability.role,
|
|
289
|
+
validation: null,
|
|
290
|
+
});
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
}
|
|
264
294
|
const service = new services_1.TFAService({
|
|
265
295
|
accountability: req.accountability,
|
|
266
296
|
schema: req.schema,
|
|
@@ -269,13 +299,40 @@ router.post('/me/tfa/enable/', (0, async_handler_1.default)(async (req, _res, ne
|
|
|
269
299
|
return next();
|
|
270
300
|
}), respond_1.respond);
|
|
271
301
|
router.post('/me/tfa/disable', (0, async_handler_1.default)(async (req, _res, next) => {
|
|
272
|
-
var _a;
|
|
302
|
+
var _a, _b;
|
|
273
303
|
if (!((_a = req.accountability) === null || _a === void 0 ? void 0 : _a.user)) {
|
|
274
304
|
throw new exceptions_1.InvalidCredentialsException();
|
|
275
305
|
}
|
|
276
306
|
if (!req.body.otp) {
|
|
277
307
|
throw new exceptions_1.InvalidPayloadException(`"otp" is required`);
|
|
278
308
|
}
|
|
309
|
+
// Override permissions only when enforce TFA is enabled in role
|
|
310
|
+
if (req.accountability.role) {
|
|
311
|
+
const rolesService = new services_1.RolesService({
|
|
312
|
+
schema: req.schema,
|
|
313
|
+
});
|
|
314
|
+
const role = (await rolesService.readOne(req.accountability.role));
|
|
315
|
+
if (role && role.enforce_tfa) {
|
|
316
|
+
const existingPermission = await ((_b = req.accountability.permissions) === null || _b === void 0 ? void 0 : _b.find((p) => p.collection === 'directus_users' && p.action === 'update'));
|
|
317
|
+
if (existingPermission) {
|
|
318
|
+
existingPermission.fields = ['tfa_secret'];
|
|
319
|
+
existingPermission.permissions = { id: { _eq: req.accountability.user } };
|
|
320
|
+
existingPermission.presets = null;
|
|
321
|
+
existingPermission.validation = null;
|
|
322
|
+
}
|
|
323
|
+
else {
|
|
324
|
+
(req.accountability.permissions || (req.accountability.permissions = [])).push({
|
|
325
|
+
action: 'update',
|
|
326
|
+
collection: 'directus_users',
|
|
327
|
+
fields: ['tfa_secret'],
|
|
328
|
+
permissions: { id: { _eq: req.accountability.user } },
|
|
329
|
+
presets: null,
|
|
330
|
+
role: req.accountability.role,
|
|
331
|
+
validation: null,
|
|
332
|
+
});
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
}
|
|
279
336
|
const service = new services_1.TFAService({
|
|
280
337
|
accountability: req.accountability,
|
|
281
338
|
schema: req.schema,
|
|
@@ -287,4 +344,19 @@ router.post('/me/tfa/disable', (0, async_handler_1.default)(async (req, _res, ne
|
|
|
287
344
|
await service.disableTFA(req.accountability.user);
|
|
288
345
|
return next();
|
|
289
346
|
}), respond_1.respond);
|
|
347
|
+
router.post('/:pk/tfa/disable', (0, async_handler_1.default)(async (req, _res, next) => {
|
|
348
|
+
var _a;
|
|
349
|
+
if (!((_a = req.accountability) === null || _a === void 0 ? void 0 : _a.user)) {
|
|
350
|
+
throw new exceptions_1.InvalidCredentialsException();
|
|
351
|
+
}
|
|
352
|
+
if (!req.accountability.admin || !req.params.pk) {
|
|
353
|
+
throw new exceptions_1.ForbiddenException();
|
|
354
|
+
}
|
|
355
|
+
const service = new services_1.TFAService({
|
|
356
|
+
accountability: req.accountability,
|
|
357
|
+
schema: req.schema,
|
|
358
|
+
});
|
|
359
|
+
await service.disableTFA(req.params.pk);
|
|
360
|
+
return next();
|
|
361
|
+
}), respond_1.respond);
|
|
290
362
|
exports.default = router;
|
|
@@ -82,10 +82,10 @@ router.post('/import/:collection', collection_exists_1.default, (0, async_handle
|
|
|
82
82
|
'content-type': 'application/octet-stream',
|
|
83
83
|
};
|
|
84
84
|
}
|
|
85
|
-
const busboy =
|
|
86
|
-
busboy.on('file', async (
|
|
85
|
+
const busboy = (0, busboy_1.default)({ headers });
|
|
86
|
+
busboy.on('file', async (_fieldname, fileStream, { mimeType }) => {
|
|
87
87
|
try {
|
|
88
|
-
await service.import(req.params.collection,
|
|
88
|
+
await service.import(req.params.collection, mimeType, fileStream);
|
|
89
89
|
}
|
|
90
90
|
catch (err) {
|
|
91
91
|
return next(err);
|
|
@@ -4,6 +4,9 @@ exports.DateHelperSQLite = void 0;
|
|
|
4
4
|
const types_1 = require("../types");
|
|
5
5
|
class DateHelperSQLite extends types_1.DateHelper {
|
|
6
6
|
parse(date) {
|
|
7
|
+
if (!date) {
|
|
8
|
+
return date;
|
|
9
|
+
}
|
|
7
10
|
// Return the time as string
|
|
8
11
|
if (date.length <= 8 && date.includes(':')) {
|
|
9
12
|
return date;
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
3
|
if (k2 === undefined) k2 = k;
|
|
4
|
-
Object.
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
5
9
|
}) : (function(o, m, k, k2) {
|
|
6
10
|
if (k2 === undefined) k2 = k;
|
|
7
11
|
o[k2] = m[k];
|
package/dist/database/index.js
CHANGED
|
@@ -64,6 +64,8 @@ function getDatabase() {
|
|
|
64
64
|
// Ignore warnings about returning not being supported in some DBs
|
|
65
65
|
if (msg.startsWith('.returning()'))
|
|
66
66
|
return;
|
|
67
|
+
if (msg.endsWith('does not currently support RETURNING clause'))
|
|
68
|
+
return;
|
|
67
69
|
// Ignore warning about MySQL not supporting TRX for DDL
|
|
68
70
|
if (msg.startsWith('Transaction was implicitly committed, do not mix transactions and DDL with MySQL'))
|
|
69
71
|
return;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.down = exports.up = void 0;
|
|
4
|
-
const
|
|
4
|
+
const utils_1 = require("@directus/shared/utils");
|
|
5
5
|
async function up(knex) {
|
|
6
6
|
var _a;
|
|
7
7
|
await knex.schema.alterTable('directus_relations', (table) => {
|
|
@@ -12,7 +12,7 @@ async function up(knex) {
|
|
|
12
12
|
.from('directus_fields')
|
|
13
13
|
.whereIn('interface', ['one-to-many', 'm2a-builder', 'many-to-many']);
|
|
14
14
|
for (const field of fieldsWithSort) {
|
|
15
|
-
const options = typeof field.options === 'string' ? (0,
|
|
15
|
+
const options = typeof field.options === 'string' ? (0, utils_1.parseJSON)(field.options) : (_a = field.options) !== null && _a !== void 0 ? _a : {};
|
|
16
16
|
if ('sortField' in options) {
|
|
17
17
|
await knex('directus_relations')
|
|
18
18
|
.update({
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.down = exports.up = void 0;
|
|
4
|
-
const
|
|
4
|
+
const utils_1 = require("@directus/shared/utils");
|
|
5
5
|
// [before, after, after-option additions]
|
|
6
6
|
const changes = [
|
|
7
7
|
['button-links', 'presentation-links'],
|
|
@@ -55,7 +55,7 @@ async function up(knex) {
|
|
|
55
55
|
.from('directus_fields')
|
|
56
56
|
.where({ interface: before });
|
|
57
57
|
for (const { id, options: existingOptionsRaw } of fields) {
|
|
58
|
-
const existingOptions = typeof existingOptionsRaw === 'string' ? (0,
|
|
58
|
+
const existingOptions = typeof existingOptionsRaw === 'string' ? (0, utils_1.parseJSON)(existingOptionsRaw) : existingOptionsRaw;
|
|
59
59
|
const newOptions = {
|
|
60
60
|
...(existingOptions || {}),
|
|
61
61
|
...options,
|
|
@@ -4,15 +4,15 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.down = exports.up = void 0;
|
|
7
|
+
const utils_1 = require("@directus/shared/utils");
|
|
7
8
|
const logger_1 = __importDefault(require("../../logger"));
|
|
8
|
-
const parse_json_1 = require("../../utils/parse-json");
|
|
9
9
|
async function up(knex) {
|
|
10
10
|
const dividerGroups = await knex.select('*').from('directus_fields').where('interface', '=', 'group-divider');
|
|
11
11
|
for (const dividerGroup of dividerGroups) {
|
|
12
12
|
const newOptions = { showHeader: true };
|
|
13
13
|
if (dividerGroup.options) {
|
|
14
14
|
try {
|
|
15
|
-
const options = typeof dividerGroup.options === 'string' ? (0,
|
|
15
|
+
const options = typeof dividerGroup.options === 'string' ? (0, utils_1.parseJSON)(dividerGroup.options) : dividerGroup.options;
|
|
16
16
|
if (options.icon)
|
|
17
17
|
newOptions.headerIcon = options.icon;
|
|
18
18
|
if (options.color)
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.down = exports.up = void 0;
|
|
4
|
-
const
|
|
4
|
+
const utils_1 = require("@directus/shared/utils");
|
|
5
5
|
async function up(knex) {
|
|
6
6
|
const groups = await knex.select('*').from('directus_fields').where({ interface: 'group-standard' });
|
|
7
7
|
const raw = [];
|
|
8
8
|
const detail = [];
|
|
9
9
|
for (const group of groups) {
|
|
10
|
-
const options = typeof group.options === 'string' ? (0,
|
|
10
|
+
const options = typeof group.options === 'string' ? (0, utils_1.parseJSON)(group.options) : group.options || {};
|
|
11
11
|
if (options.showHeader === true) {
|
|
12
12
|
detail.push(group);
|
|
13
13
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.down = exports.up = void 0;
|
|
4
|
-
const
|
|
4
|
+
const utils_1 = require("@directus/shared/utils");
|
|
5
5
|
// Change image metadata structure to match the output from 'exifr'
|
|
6
6
|
async function up(knex) {
|
|
7
7
|
const files = await knex
|
|
@@ -11,7 +11,7 @@ async function up(knex) {
|
|
|
11
11
|
for (const { id, metadata } of files) {
|
|
12
12
|
let prevMetadata;
|
|
13
13
|
try {
|
|
14
|
-
prevMetadata = (0,
|
|
14
|
+
prevMetadata = (0, utils_1.parseJSON)(metadata);
|
|
15
15
|
}
|
|
16
16
|
catch {
|
|
17
17
|
continue;
|
|
@@ -55,7 +55,7 @@ async function down(knex) {
|
|
|
55
55
|
.whereNotNull('metadata')
|
|
56
56
|
.whereNot('metadata', '{}');
|
|
57
57
|
for (const { id, metadata } of files) {
|
|
58
|
-
const prevMetadata = (0,
|
|
58
|
+
const prevMetadata = (0, utils_1.parseJSON)(metadata);
|
|
59
59
|
// Update only required if metadata has keys other than 'icc' and 'iptc'
|
|
60
60
|
if (Object.keys(prevMetadata).filter((key) => key !== 'icc' && key !== 'iptc').length > 0) {
|
|
61
61
|
// Put all data under 'exif' and rename/move keys afterwards
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.down = exports.up = void 0;
|
|
4
|
+
const utils_1 = require("@directus/shared/utils");
|
|
4
5
|
const nanoid_1 = require("nanoid");
|
|
5
|
-
const parse_json_1 = require("../../utils/parse-json");
|
|
6
6
|
async function up(knex) {
|
|
7
7
|
var _a;
|
|
8
8
|
await knex.schema.alterTable('directus_presets', (table) => {
|
|
@@ -13,7 +13,7 @@ async function up(knex) {
|
|
|
13
13
|
.from('directus_presets');
|
|
14
14
|
for (const preset of presets) {
|
|
15
15
|
if (preset.filters) {
|
|
16
|
-
const oldFilters = (_a = (typeof preset.filters === 'string' ? (0,
|
|
16
|
+
const oldFilters = (_a = (typeof preset.filters === 'string' ? (0, utils_1.parseJSON)(preset.filters) : preset.filters)) !== null && _a !== void 0 ? _a : [];
|
|
17
17
|
if (oldFilters.length === 0)
|
|
18
18
|
continue;
|
|
19
19
|
const newFilter = {
|
|
@@ -35,7 +35,7 @@ async function up(knex) {
|
|
|
35
35
|
}
|
|
36
36
|
}
|
|
37
37
|
if (preset.layout_query) {
|
|
38
|
-
const layoutQuery = typeof preset.layout_query === 'string' ? (0,
|
|
38
|
+
const layoutQuery = typeof preset.layout_query === 'string' ? (0, utils_1.parseJSON)(preset.layout_query) : preset.layout_query;
|
|
39
39
|
for (const [layout, query] of Object.entries(layoutQuery)) {
|
|
40
40
|
if (query.sort) {
|
|
41
41
|
query.sort = [query.sort];
|
|
@@ -62,7 +62,7 @@ async function down(knex) {
|
|
|
62
62
|
.from('directus_presets');
|
|
63
63
|
for (const preset of presets) {
|
|
64
64
|
if (preset.filter) {
|
|
65
|
-
const newFilter = (_a = (typeof preset.filter === 'string' ? (0,
|
|
65
|
+
const newFilter = (_a = (typeof preset.filter === 'string' ? (0, utils_1.parseJSON)(preset.filter) : preset.filter)) !== null && _a !== void 0 ? _a : {};
|
|
66
66
|
if (Object.keys(newFilter).length === 0)
|
|
67
67
|
continue;
|
|
68
68
|
const oldFilters = [];
|
|
@@ -86,7 +86,7 @@ async function down(knex) {
|
|
|
86
86
|
}
|
|
87
87
|
}
|
|
88
88
|
if (preset.layout_query) {
|
|
89
|
-
const layoutQuery = typeof preset.layout_query === 'string' ? (0,
|
|
89
|
+
const layoutQuery = typeof preset.layout_query === 'string' ? (0, utils_1.parseJSON)(preset.layout_query) : preset.layout_query;
|
|
90
90
|
for (const [layout, query] of Object.entries(layoutQuery)) {
|
|
91
91
|
if (query.sort && Array.isArray(query.sort)) {
|
|
92
92
|
query.sort = (_l = (_k = query.sort) === null || _k === void 0 ? void 0 : _k[0]) !== null && _l !== void 0 ? _l : null;
|
|
@@ -3,7 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.down = exports.up = void 0;
|
|
4
4
|
const utils_1 = require("@directus/shared/utils");
|
|
5
5
|
const uuid_1 = require("uuid");
|
|
6
|
-
const parse_json_1 = require("../../utils/parse-json");
|
|
7
6
|
async function up(knex) {
|
|
8
7
|
await knex.schema.createTable('directus_flows', (table) => {
|
|
9
8
|
table.uuid('id').primary().notNullable();
|
|
@@ -59,7 +58,7 @@ async function up(knex) {
|
|
|
59
58
|
position_y: 1,
|
|
60
59
|
options: JSON.stringify({
|
|
61
60
|
url: webhook.url,
|
|
62
|
-
headers: typeof webhook.headers === 'string' ? (0,
|
|
61
|
+
headers: typeof webhook.headers === 'string' ? (0, utils_1.parseJSON)(webhook.headers) : webhook.headers,
|
|
63
62
|
data: webhook.data ? '{{$trigger}}' : null,
|
|
64
63
|
method: webhook.method,
|
|
65
64
|
}),
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.down = exports.up = void 0;
|
|
4
|
+
async function up(knex) {
|
|
5
|
+
await knex('directus_flows').update({ trigger: 'event' }).where('trigger', '=', 'hook');
|
|
6
|
+
}
|
|
7
|
+
exports.up = up;
|
|
8
|
+
async function down(knex) {
|
|
9
|
+
await knex('directus_flows').update({ trigger: 'hook' }).where('trigger', '=', 'event');
|
|
10
|
+
}
|
|
11
|
+
exports.down = down;
|
package/dist/emitter.js
CHANGED
|
@@ -21,12 +21,17 @@ class Emitter {
|
|
|
21
21
|
}
|
|
22
22
|
async emitFilter(event, payload, meta, context) {
|
|
23
23
|
const events = Array.isArray(event) ? event : [event];
|
|
24
|
-
const
|
|
24
|
+
const eventListeners = events.map((event) => ({
|
|
25
|
+
event,
|
|
26
|
+
listeners: this.filterEmitter.listeners(event),
|
|
27
|
+
}));
|
|
25
28
|
let updatedPayload = payload;
|
|
26
|
-
for (const
|
|
27
|
-
const
|
|
28
|
-
|
|
29
|
-
|
|
29
|
+
for (const { event, listeners } of eventListeners) {
|
|
30
|
+
for (const listener of listeners) {
|
|
31
|
+
const result = await listener(updatedPayload, { event, ...meta }, context);
|
|
32
|
+
if (result !== undefined) {
|
|
33
|
+
updatedPayload = result;
|
|
34
|
+
}
|
|
30
35
|
}
|
|
31
36
|
}
|
|
32
37
|
return updatedPayload;
|
|
@@ -34,7 +39,7 @@ class Emitter {
|
|
|
34
39
|
emitAction(event, meta, context) {
|
|
35
40
|
const events = Array.isArray(event) ? event : [event];
|
|
36
41
|
for (const event of events) {
|
|
37
|
-
this.actionEmitter.emitAsync(event, meta, context).catch((err) => {
|
|
42
|
+
this.actionEmitter.emitAsync(event, { event, ...meta }, context).catch((err) => {
|
|
38
43
|
logger_1.default.warn(`An error was thrown while executing action "${event}"`);
|
|
39
44
|
logger_1.default.warn(err);
|
|
40
45
|
});
|
|
@@ -42,7 +47,7 @@ class Emitter {
|
|
|
42
47
|
}
|
|
43
48
|
async emitInit(event, meta) {
|
|
44
49
|
try {
|
|
45
|
-
await this.initEmitter.emitAsync(event, meta);
|
|
50
|
+
await this.initEmitter.emitAsync(event, { event, ...meta });
|
|
46
51
|
}
|
|
47
52
|
catch (err) {
|
|
48
53
|
logger_1.default.warn(`An error was thrown while executing init "${event}"`);
|
package/dist/env.d.ts
CHANGED
package/dist/env.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/**
|
|
3
3
|
* @NOTE
|
|
4
|
-
* For all possible keys, see: https://docs.directus.io/
|
|
4
|
+
* For all possible keys, see: https://docs.directus.io/self-hosted/config-options/
|
|
5
5
|
*/
|
|
6
6
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
7
7
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
@@ -14,7 +14,7 @@ const lodash_1 = require("lodash");
|
|
|
14
14
|
const path_1 = __importDefault(require("path"));
|
|
15
15
|
const require_yaml_1 = require("./utils/require-yaml");
|
|
16
16
|
const utils_1 = require("@directus/shared/utils");
|
|
17
|
-
const
|
|
17
|
+
const utils_2 = require("@directus/shared/utils");
|
|
18
18
|
// keeping this here for now to prevent a circular import to constants.ts
|
|
19
19
|
const allowedEnvironmentVars = [
|
|
20
20
|
// general
|
|
@@ -78,6 +78,7 @@ const allowedEnvironmentVars = [
|
|
|
78
78
|
'CACHE_REDIS_PORT',
|
|
79
79
|
'CACHE_REDIS_PASSWORD',
|
|
80
80
|
'CACHE_MEMCACHE',
|
|
81
|
+
'CACHE_VALUE_MAX_SIZE',
|
|
81
82
|
// storage
|
|
82
83
|
'STORAGE_LOCATIONS',
|
|
83
84
|
'STORAGE_.+_DRIVER',
|
|
@@ -140,6 +141,7 @@ const allowedEnvironmentVars = [
|
|
|
140
141
|
// emails
|
|
141
142
|
'EMAIL_FROM',
|
|
142
143
|
'EMAIL_TRANSPORT',
|
|
144
|
+
'EMAIL_VERIFY_SETUP',
|
|
143
145
|
'EMAIL_SENDMAIL_NEW_LINE',
|
|
144
146
|
'EMAIL_SENDMAIL_PATH',
|
|
145
147
|
'EMAIL_SMTP_HOST',
|
|
@@ -171,6 +173,7 @@ const defaults = {
|
|
|
171
173
|
PORT: 8055,
|
|
172
174
|
PUBLIC_URL: '/',
|
|
173
175
|
MAX_PAYLOAD_SIZE: '100kb',
|
|
176
|
+
MAX_RELATIONAL_DEPTH: 10,
|
|
174
177
|
DB_EXCLUDE_TABLES: 'spatial_ref_sys,sysdiagrams',
|
|
175
178
|
STORAGE_LOCATIONS: 'local',
|
|
176
179
|
STORAGE_LOCAL_DRIVER: 'local',
|
|
@@ -200,11 +203,13 @@ const defaults = {
|
|
|
200
203
|
CACHE_CONTROL_S_MAXAGE: '0',
|
|
201
204
|
CACHE_SCHEMA: true,
|
|
202
205
|
CACHE_PERMISSIONS: true,
|
|
206
|
+
CACHE_VALUE_MAX_SIZE: false,
|
|
203
207
|
AUTH_PROVIDERS: '',
|
|
204
208
|
AUTH_DISABLE_DEFAULT: false,
|
|
205
209
|
EXTENSIONS_PATH: './extensions',
|
|
206
210
|
EXTENSIONS_AUTO_RELOAD: false,
|
|
207
211
|
EMAIL_FROM: 'no-reply@directus.io',
|
|
212
|
+
EMAIL_VERIFY_SETUP: true,
|
|
208
213
|
EMAIL_TRANSPORT: 'sendmail',
|
|
209
214
|
EMAIL_SENDMAIL_NEW_LINE: 'unix',
|
|
210
215
|
EMAIL_SENDMAIL_PATH: '/usr/sbin/sendmail',
|
|
@@ -407,7 +412,7 @@ function processValues(env) {
|
|
|
407
412
|
}
|
|
408
413
|
function tryJSON(value) {
|
|
409
414
|
try {
|
|
410
|
-
return (0,
|
|
415
|
+
return (0, utils_2.parseJSON)(value);
|
|
411
416
|
}
|
|
412
417
|
catch {
|
|
413
418
|
return value;
|