directus 9.23.4 → 9.24.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/app.js +3 -3
- package/dist/controllers/activity.js +1 -1
- package/dist/controllers/assets.js +1 -1
- package/dist/controllers/auth.js +3 -3
- package/dist/controllers/collections.js +1 -1
- package/dist/controllers/dashboards.js +2 -2
- package/dist/controllers/fields.js +1 -1
- package/dist/controllers/files.js +2 -2
- package/dist/controllers/flows.js +2 -2
- package/dist/controllers/folders.js +2 -2
- package/dist/controllers/items.js +2 -2
- package/dist/controllers/notifications.js +2 -2
- package/dist/controllers/operations.js +2 -2
- package/dist/controllers/panels.js +2 -2
- package/dist/controllers/permissions.js +2 -2
- package/dist/controllers/presets.js +2 -2
- package/dist/controllers/relations.js +1 -1
- package/dist/controllers/roles.js +2 -2
- package/dist/controllers/shares.js +1 -1
- package/dist/controllers/utils.js +2 -2
- package/dist/controllers/webhooks.js +2 -2
- package/dist/database/run-ast.js +2 -2
- package/dist/exceptions/database/dialects/mssql.js +2 -2
- package/dist/exceptions/database/dialects/mysql.js +6 -6
- package/dist/exceptions/database/record-not-unique.d.ts +1 -1
- package/dist/middleware/authenticate.d.ts +1 -1
- package/dist/middleware/authenticate.js +1 -1
- package/dist/middleware/collection-exists.js +1 -1
- package/dist/middleware/cors.js +1 -1
- package/dist/middleware/extract-token.js +1 -1
- package/dist/middleware/get-permissions.js +1 -1
- package/dist/middleware/schema.js +1 -1
- package/dist/middleware/use-collection.js +1 -1
- package/dist/middleware/validate-batch.js +1 -1
- package/dist/services/files.js +6 -6
- package/dist/services/graphql/index.js +70 -18
- package/dist/services/relations.js +4 -4
- package/dist/services/users.js +1 -1
- package/dist/utils/apply-diff.js +12 -12
- package/dist/utils/apply-query.js +1 -1
- package/dist/utils/get-ast-from-query.js +1 -1
- package/dist/utils/get-column-path.js +2 -1
- package/dist/utils/get-schema.js +3 -3
- package/dist/utils/get-snapshot-diff.js +1 -1
- package/dist/utils/parse-image-metadata.js +3 -3
- package/dist/utils/reduce-schema.js +5 -5
- package/dist/utils/should-skip-cache.js +12 -3
- package/dist/utils/strip-function.js +1 -1
- package/dist/utils/telemetry.d.ts +1 -0
- package/dist/utils/telemetry.js +30 -0
- package/dist/utils/validate-keys.js +1 -1
- package/package.json +13 -13
- package/dist/utils/track.d.ts +0 -1
- package/dist/utils/track.js +0 -81
package/dist/app.js
CHANGED
|
@@ -81,7 +81,7 @@ const lodash_1 = require("lodash");
|
|
|
81
81
|
const auth_2 = require("./auth");
|
|
82
82
|
const cache_2 = require("./cache");
|
|
83
83
|
const get_config_from_env_1 = require("./utils/get-config-from-env");
|
|
84
|
-
const
|
|
84
|
+
const telemetry_1 = require("./utils/telemetry");
|
|
85
85
|
const url_1 = require("./utils/url");
|
|
86
86
|
const validate_env_1 = require("./utils/validate-env");
|
|
87
87
|
const validate_storage_1 = require("./utils/validate-storage");
|
|
@@ -198,7 +198,7 @@ async function createApp() {
|
|
|
198
198
|
if (env_1.default['RATE_LIMITER_ENABLED'] === true) {
|
|
199
199
|
app.use(rate_limiter_ip_1.default);
|
|
200
200
|
}
|
|
201
|
-
app.get('/server/ping', (
|
|
201
|
+
app.get('/server/ping', (_req, res) => res.send('pong'));
|
|
202
202
|
app.use(authenticate_1.default);
|
|
203
203
|
app.use(check_ip_1.checkIP);
|
|
204
204
|
app.use(sanitize_query_1.default);
|
|
@@ -243,7 +243,7 @@ async function createApp() {
|
|
|
243
243
|
await emitter_1.default.emitInit('routes.after', { app });
|
|
244
244
|
// Register all webhooks
|
|
245
245
|
await (0, webhooks_2.init)();
|
|
246
|
-
(0,
|
|
246
|
+
(0, telemetry_1.collectTelemetry)();
|
|
247
247
|
await emitter_1.default.emitInit('app.after', { app });
|
|
248
248
|
return app;
|
|
249
249
|
}
|
|
@@ -117,7 +117,7 @@ router.patch('/comment/:pk', (0, async_handler_1.default)(async (req, res, next)
|
|
|
117
117
|
}
|
|
118
118
|
return next();
|
|
119
119
|
}), respond_1.respond);
|
|
120
|
-
router.delete('/comment/:pk', (0, async_handler_1.default)(async (req,
|
|
120
|
+
router.delete('/comment/:pk', (0, async_handler_1.default)(async (req, _res, next) => {
|
|
121
121
|
const service = new services_1.ActivityService({
|
|
122
122
|
accountability: req.accountability,
|
|
123
123
|
schema: req.schema,
|
|
@@ -103,7 +103,7 @@ router.get('/:pk/:filename?',
|
|
|
103
103
|
}),
|
|
104
104
|
// Return file
|
|
105
105
|
(0, async_handler_1.default)(async (req, res) => {
|
|
106
|
-
const id = req.params['pk']
|
|
106
|
+
const id = req.params['pk'].substring(0, 36);
|
|
107
107
|
const service = new services_1.AssetsService({
|
|
108
108
|
accountability: req.accountability,
|
|
109
109
|
schema: req.schema,
|
package/dist/controllers/auth.js
CHANGED
|
@@ -107,7 +107,7 @@ router.post('/logout', (0, async_handler_1.default)(async (req, res, next) => {
|
|
|
107
107
|
}
|
|
108
108
|
return next();
|
|
109
109
|
}), respond_1.respond);
|
|
110
|
-
router.post('/password/request', (0, async_handler_1.default)(async (req,
|
|
110
|
+
router.post('/password/request', (0, async_handler_1.default)(async (req, _res, next) => {
|
|
111
111
|
if (typeof req.body.email !== 'string') {
|
|
112
112
|
throw new exceptions_1.InvalidPayloadException(`"email" field is required.`);
|
|
113
113
|
}
|
|
@@ -136,7 +136,7 @@ router.post('/password/request', (0, async_handler_1.default)(async (req, res, n
|
|
|
136
136
|
}
|
|
137
137
|
}
|
|
138
138
|
}), respond_1.respond);
|
|
139
|
-
router.post('/password/reset', (0, async_handler_1.default)(async (req,
|
|
139
|
+
router.post('/password/reset', (0, async_handler_1.default)(async (req, _res, next) => {
|
|
140
140
|
if (typeof req.body.token !== 'string') {
|
|
141
141
|
throw new exceptions_1.InvalidPayloadException(`"token" field is required.`);
|
|
142
142
|
}
|
|
@@ -157,7 +157,7 @@ router.post('/password/reset', (0, async_handler_1.default)(async (req, res, nex
|
|
|
157
157
|
await service.resetPassword(req.body.token, req.body.password);
|
|
158
158
|
return next();
|
|
159
159
|
}), respond_1.respond);
|
|
160
|
-
router.get('/', (0, async_handler_1.default)(async (
|
|
160
|
+
router.get('/', (0, async_handler_1.default)(async (_req, res, next) => {
|
|
161
161
|
res.locals['payload'] = {
|
|
162
162
|
data: (0, get_auth_providers_1.getAuthProviders)(),
|
|
163
163
|
disableDefault: env_1.default['AUTH_DISABLE_DEFAULT'],
|
|
@@ -94,7 +94,7 @@ router.patch('/:collection', (0, async_handler_1.default)(async (req, res, next)
|
|
|
94
94
|
}
|
|
95
95
|
return next();
|
|
96
96
|
}), respond_1.respond);
|
|
97
|
-
router.delete('/:collection', (0, async_handler_1.default)(async (req,
|
|
97
|
+
router.delete('/:collection', (0, async_handler_1.default)(async (req, _res, next) => {
|
|
98
98
|
const collectionsService = new services_1.CollectionsService({
|
|
99
99
|
accountability: req.accountability,
|
|
100
100
|
schema: req.schema,
|
|
@@ -116,7 +116,7 @@ router.patch('/:pk', (0, async_handler_1.default)(async (req, res, next) => {
|
|
|
116
116
|
}
|
|
117
117
|
return next();
|
|
118
118
|
}), respond_1.respond);
|
|
119
|
-
router.delete('/', (0, async_handler_1.default)(async (req,
|
|
119
|
+
router.delete('/', (0, async_handler_1.default)(async (req, _res, next) => {
|
|
120
120
|
const service = new services_1.DashboardsService({
|
|
121
121
|
accountability: req.accountability,
|
|
122
122
|
schema: req.schema,
|
|
@@ -133,7 +133,7 @@ router.delete('/', (0, async_handler_1.default)(async (req, res, next) => {
|
|
|
133
133
|
}
|
|
134
134
|
return next();
|
|
135
135
|
}), respond_1.respond);
|
|
136
|
-
router.delete('/:pk', (0, async_handler_1.default)(async (req,
|
|
136
|
+
router.delete('/:pk', (0, async_handler_1.default)(async (req, _res, next) => {
|
|
137
137
|
const service = new services_1.DashboardsService({
|
|
138
138
|
accountability: req.accountability,
|
|
139
139
|
schema: req.schema,
|
|
@@ -149,7 +149,7 @@ router.patch('/:collection/:field', collection_exists_1.default, (0, async_handl
|
|
|
149
149
|
}
|
|
150
150
|
return next();
|
|
151
151
|
}), respond_1.respond);
|
|
152
|
-
router.delete('/:collection/:field', collection_exists_1.default, (0, async_handler_1.default)(async (req,
|
|
152
|
+
router.delete('/:collection/:field', collection_exists_1.default, (0, async_handler_1.default)(async (req, _res, next) => {
|
|
153
153
|
const service = new fields_1.FieldsService({
|
|
154
154
|
accountability: req.accountability,
|
|
155
155
|
schema: req.schema,
|
|
@@ -246,7 +246,7 @@ router.patch('/:pk', (0, async_handler_1.default)(exports.multipartHandler), (0,
|
|
|
246
246
|
}
|
|
247
247
|
return next();
|
|
248
248
|
}), respond_1.respond);
|
|
249
|
-
router.delete('/', (0, validate_batch_1.validateBatch)('delete'), (0, async_handler_1.default)(async (req,
|
|
249
|
+
router.delete('/', (0, validate_batch_1.validateBatch)('delete'), (0, async_handler_1.default)(async (req, _res, next) => {
|
|
250
250
|
const service = new services_1.FilesService({
|
|
251
251
|
accountability: req.accountability,
|
|
252
252
|
schema: req.schema,
|
|
@@ -263,7 +263,7 @@ router.delete('/', (0, validate_batch_1.validateBatch)('delete'), (0, async_hand
|
|
|
263
263
|
}
|
|
264
264
|
return next();
|
|
265
265
|
}), respond_1.respond);
|
|
266
|
-
router.delete('/:pk', (0, async_handler_1.default)(async (req,
|
|
266
|
+
router.delete('/:pk', (0, async_handler_1.default)(async (req, _res, next) => {
|
|
267
267
|
const service = new services_1.FilesService({
|
|
268
268
|
accountability: req.accountability,
|
|
269
269
|
schema: req.schema,
|
|
@@ -135,7 +135,7 @@ router.patch('/:pk', (0, async_handler_1.default)(async (req, res, next) => {
|
|
|
135
135
|
}
|
|
136
136
|
return next();
|
|
137
137
|
}), respond_1.respond);
|
|
138
|
-
router.delete('/', (0, async_handler_1.default)(async (req,
|
|
138
|
+
router.delete('/', (0, async_handler_1.default)(async (req, _res, next) => {
|
|
139
139
|
const service = new services_1.FlowsService({
|
|
140
140
|
accountability: req.accountability,
|
|
141
141
|
schema: req.schema,
|
|
@@ -152,7 +152,7 @@ router.delete('/', (0, async_handler_1.default)(async (req, res, next) => {
|
|
|
152
152
|
}
|
|
153
153
|
return next();
|
|
154
154
|
}), respond_1.respond);
|
|
155
|
-
router.delete('/:pk', (0, async_handler_1.default)(async (req,
|
|
155
|
+
router.delete('/:pk', (0, async_handler_1.default)(async (req, _res, next) => {
|
|
156
156
|
const service = new services_1.FlowsService({
|
|
157
157
|
accountability: req.accountability,
|
|
158
158
|
schema: req.schema,
|
|
@@ -125,7 +125,7 @@ router.patch('/:pk', (0, async_handler_1.default)(async (req, res, next) => {
|
|
|
125
125
|
}
|
|
126
126
|
return next();
|
|
127
127
|
}), respond_1.respond);
|
|
128
|
-
router.delete('/', (0, validate_batch_1.validateBatch)('delete'), (0, async_handler_1.default)(async (req,
|
|
128
|
+
router.delete('/', (0, validate_batch_1.validateBatch)('delete'), (0, async_handler_1.default)(async (req, _res, next) => {
|
|
129
129
|
const service = new services_1.FoldersService({
|
|
130
130
|
accountability: req.accountability,
|
|
131
131
|
schema: req.schema,
|
|
@@ -142,7 +142,7 @@ router.delete('/', (0, validate_batch_1.validateBatch)('delete'), (0, async_hand
|
|
|
142
142
|
}
|
|
143
143
|
return next();
|
|
144
144
|
}), respond_1.respond);
|
|
145
|
-
router.delete('/:pk', (0, async_handler_1.default)(async (req,
|
|
145
|
+
router.delete('/:pk', (0, async_handler_1.default)(async (req, _res, next) => {
|
|
146
146
|
const service = new services_1.FoldersService({
|
|
147
147
|
accountability: req.accountability,
|
|
148
148
|
schema: req.schema,
|
|
@@ -151,7 +151,7 @@ router.patch('/:collection/:pk', collection_exists_1.default, (0, async_handler_
|
|
|
151
151
|
}
|
|
152
152
|
return next();
|
|
153
153
|
}), respond_1.respond);
|
|
154
|
-
router.delete('/:collection', collection_exists_1.default, (0, validate_batch_1.validateBatch)('delete'), (0, async_handler_1.default)(async (req,
|
|
154
|
+
router.delete('/:collection', collection_exists_1.default, (0, validate_batch_1.validateBatch)('delete'), (0, async_handler_1.default)(async (req, _res, next) => {
|
|
155
155
|
if (req.params['collection'].startsWith('directus_'))
|
|
156
156
|
throw new exceptions_1.ForbiddenException();
|
|
157
157
|
const service = new services_1.ItemsService(req.collection, {
|
|
@@ -170,7 +170,7 @@ router.delete('/:collection', collection_exists_1.default, (0, validate_batch_1.
|
|
|
170
170
|
}
|
|
171
171
|
return next();
|
|
172
172
|
}), respond_1.respond);
|
|
173
|
-
router.delete('/:collection/:pk', collection_exists_1.default, (0, async_handler_1.default)(async (req,
|
|
173
|
+
router.delete('/:collection/:pk', collection_exists_1.default, (0, async_handler_1.default)(async (req, _res, next) => {
|
|
174
174
|
if (req.params['collection'].startsWith('directus_'))
|
|
175
175
|
throw new exceptions_1.ForbiddenException();
|
|
176
176
|
const service = new services_1.ItemsService(req.collection, {
|
|
@@ -125,7 +125,7 @@ router.patch('/:pk', (0, async_handler_1.default)(async (req, res, next) => {
|
|
|
125
125
|
}
|
|
126
126
|
return next();
|
|
127
127
|
}), respond_1.respond);
|
|
128
|
-
router.delete('/', (0, validate_batch_1.validateBatch)('delete'), (0, async_handler_1.default)(async (req,
|
|
128
|
+
router.delete('/', (0, validate_batch_1.validateBatch)('delete'), (0, async_handler_1.default)(async (req, _res, next) => {
|
|
129
129
|
const service = new services_1.NotificationsService({
|
|
130
130
|
accountability: req.accountability,
|
|
131
131
|
schema: req.schema,
|
|
@@ -142,7 +142,7 @@ router.delete('/', (0, validate_batch_1.validateBatch)('delete'), (0, async_hand
|
|
|
142
142
|
}
|
|
143
143
|
return next();
|
|
144
144
|
}), respond_1.respond);
|
|
145
|
-
router.delete('/:pk', (0, async_handler_1.default)(async (req,
|
|
145
|
+
router.delete('/:pk', (0, async_handler_1.default)(async (req, _res, next) => {
|
|
146
146
|
const service = new services_1.NotificationsService({
|
|
147
147
|
accountability: req.accountability,
|
|
148
148
|
schema: req.schema,
|
|
@@ -116,7 +116,7 @@ router.patch('/:pk', (0, async_handler_1.default)(async (req, res, next) => {
|
|
|
116
116
|
}
|
|
117
117
|
return next();
|
|
118
118
|
}), respond_1.respond);
|
|
119
|
-
router.delete('/', (0, async_handler_1.default)(async (req,
|
|
119
|
+
router.delete('/', (0, async_handler_1.default)(async (req, _res, next) => {
|
|
120
120
|
const service = new services_1.OperationsService({
|
|
121
121
|
accountability: req.accountability,
|
|
122
122
|
schema: req.schema,
|
|
@@ -133,7 +133,7 @@ router.delete('/', (0, async_handler_1.default)(async (req, res, next) => {
|
|
|
133
133
|
}
|
|
134
134
|
return next();
|
|
135
135
|
}), respond_1.respond);
|
|
136
|
-
router.delete('/:pk', (0, async_handler_1.default)(async (req,
|
|
136
|
+
router.delete('/:pk', (0, async_handler_1.default)(async (req, _res, next) => {
|
|
137
137
|
const service = new services_1.OperationsService({
|
|
138
138
|
accountability: req.accountability,
|
|
139
139
|
schema: req.schema,
|
|
@@ -116,7 +116,7 @@ router.patch('/:pk', (0, async_handler_1.default)(async (req, res, next) => {
|
|
|
116
116
|
}
|
|
117
117
|
return next();
|
|
118
118
|
}), respond_1.respond);
|
|
119
|
-
router.delete('/', (0, async_handler_1.default)(async (req,
|
|
119
|
+
router.delete('/', (0, async_handler_1.default)(async (req, _res, next) => {
|
|
120
120
|
const service = new services_1.PanelsService({
|
|
121
121
|
accountability: req.accountability,
|
|
122
122
|
schema: req.schema,
|
|
@@ -133,7 +133,7 @@ router.delete('/', (0, async_handler_1.default)(async (req, res, next) => {
|
|
|
133
133
|
}
|
|
134
134
|
return next();
|
|
135
135
|
}), respond_1.respond);
|
|
136
|
-
router.delete('/:pk', (0, async_handler_1.default)(async (req,
|
|
136
|
+
router.delete('/:pk', (0, async_handler_1.default)(async (req, _res, next) => {
|
|
137
137
|
const service = new services_1.PanelsService({
|
|
138
138
|
accountability: req.accountability,
|
|
139
139
|
schema: req.schema,
|
|
@@ -127,7 +127,7 @@ router.patch('/:pk', (0, async_handler_1.default)(async (req, res, next) => {
|
|
|
127
127
|
}
|
|
128
128
|
return next();
|
|
129
129
|
}), respond_1.respond);
|
|
130
|
-
router.delete('/', (0, validate_batch_1.validateBatch)('delete'), (0, async_handler_1.default)(async (req,
|
|
130
|
+
router.delete('/', (0, validate_batch_1.validateBatch)('delete'), (0, async_handler_1.default)(async (req, _res, next) => {
|
|
131
131
|
const service = new services_1.PermissionsService({
|
|
132
132
|
accountability: req.accountability,
|
|
133
133
|
schema: req.schema,
|
|
@@ -144,7 +144,7 @@ router.delete('/', (0, validate_batch_1.validateBatch)('delete'), (0, async_hand
|
|
|
144
144
|
}
|
|
145
145
|
return next();
|
|
146
146
|
}), respond_1.respond);
|
|
147
|
-
router.delete('/:pk', (0, async_handler_1.default)(async (req,
|
|
147
|
+
router.delete('/:pk', (0, async_handler_1.default)(async (req, _res, next) => {
|
|
148
148
|
const service = new services_1.PermissionsService({
|
|
149
149
|
accountability: req.accountability,
|
|
150
150
|
schema: req.schema,
|
|
@@ -125,7 +125,7 @@ router.patch('/:pk', (0, async_handler_1.default)(async (req, res, next) => {
|
|
|
125
125
|
}
|
|
126
126
|
return next();
|
|
127
127
|
}), respond_1.respond);
|
|
128
|
-
router.delete('/', (0, validate_batch_1.validateBatch)('delete'), (0, async_handler_1.default)(async (req,
|
|
128
|
+
router.delete('/', (0, validate_batch_1.validateBatch)('delete'), (0, async_handler_1.default)(async (req, _res, next) => {
|
|
129
129
|
const service = new services_1.PresetsService({
|
|
130
130
|
accountability: req.accountability,
|
|
131
131
|
schema: req.schema,
|
|
@@ -142,7 +142,7 @@ router.delete('/', (0, validate_batch_1.validateBatch)('delete'), (0, async_hand
|
|
|
142
142
|
}
|
|
143
143
|
return next();
|
|
144
144
|
}), respond_1.respond);
|
|
145
|
-
router.delete('/:pk', (0, async_handler_1.default)(async (req,
|
|
145
|
+
router.delete('/:pk', (0, async_handler_1.default)(async (req, _res, next) => {
|
|
146
146
|
const service = new services_1.PresetsService({
|
|
147
147
|
accountability: req.accountability,
|
|
148
148
|
schema: req.schema,
|
|
@@ -106,7 +106,7 @@ router.patch('/:collection/:field', collection_exists_1.default, (0, async_handl
|
|
|
106
106
|
}
|
|
107
107
|
return next();
|
|
108
108
|
}), respond_1.respond);
|
|
109
|
-
router.delete('/:collection/:field', collection_exists_1.default, (0, async_handler_1.default)(async (req,
|
|
109
|
+
router.delete('/:collection/:field', collection_exists_1.default, (0, async_handler_1.default)(async (req, _res, next) => {
|
|
110
110
|
const service = new services_1.RelationsService({
|
|
111
111
|
accountability: req.accountability,
|
|
112
112
|
schema: req.schema,
|
|
@@ -116,7 +116,7 @@ router.patch('/:pk', (0, async_handler_1.default)(async (req, res, next) => {
|
|
|
116
116
|
}
|
|
117
117
|
return next();
|
|
118
118
|
}), respond_1.respond);
|
|
119
|
-
router.delete('/', (0, validate_batch_1.validateBatch)('delete'), (0, async_handler_1.default)(async (req,
|
|
119
|
+
router.delete('/', (0, validate_batch_1.validateBatch)('delete'), (0, async_handler_1.default)(async (req, _res, next) => {
|
|
120
120
|
const service = new services_1.RolesService({
|
|
121
121
|
accountability: req.accountability,
|
|
122
122
|
schema: req.schema,
|
|
@@ -133,7 +133,7 @@ router.delete('/', (0, validate_batch_1.validateBatch)('delete'), (0, async_hand
|
|
|
133
133
|
}
|
|
134
134
|
return next();
|
|
135
135
|
}), respond_1.respond);
|
|
136
|
-
router.delete('/:pk', (0, async_handler_1.default)(async (req,
|
|
136
|
+
router.delete('/:pk', (0, async_handler_1.default)(async (req, _res, next) => {
|
|
137
137
|
const service = new services_1.RolesService({
|
|
138
138
|
accountability: req.accountability,
|
|
139
139
|
schema: req.schema,
|
|
@@ -38,7 +38,7 @@ const sharedInviteSchema = joi_1.default.object({
|
|
|
38
38
|
share: joi_1.default.string().required(),
|
|
39
39
|
emails: joi_1.default.array().items(joi_1.default.string()),
|
|
40
40
|
}).unknown();
|
|
41
|
-
router.post('/invite', (0, async_handler_1.default)(async (req,
|
|
41
|
+
router.post('/invite', (0, async_handler_1.default)(async (req, _res, next) => {
|
|
42
42
|
const service = new services_1.SharesService({
|
|
43
43
|
schema: req.schema,
|
|
44
44
|
accountability: req.accountability,
|
|
@@ -55,7 +55,7 @@ router.post('/sort/:collection', collection_exists_1.default, (0, async_handler_
|
|
|
55
55
|
await service.sort(req.collection, req.body);
|
|
56
56
|
return res.status(200).end();
|
|
57
57
|
}));
|
|
58
|
-
router.post('/revert/:revision', (0, async_handler_1.default)(async (req,
|
|
58
|
+
router.post('/revert/:revision', (0, async_handler_1.default)(async (req, _res, next) => {
|
|
59
59
|
const service = new services_1.RevisionsService({
|
|
60
60
|
accountability: req.accountability,
|
|
61
61
|
schema: req.schema,
|
|
@@ -93,7 +93,7 @@ router.post('/import/:collection', collection_exists_1.default, (0, async_handle
|
|
|
93
93
|
busboy.on('error', (err) => next(err));
|
|
94
94
|
req.pipe(busboy);
|
|
95
95
|
}));
|
|
96
|
-
router.post('/export/:collection', collection_exists_1.default, (0, async_handler_1.default)(async (req,
|
|
96
|
+
router.post('/export/:collection', collection_exists_1.default, (0, async_handler_1.default)(async (req, _res, next) => {
|
|
97
97
|
if (!req.body.query) {
|
|
98
98
|
throw new exceptions_1.InvalidPayloadException(`"query" is required.`);
|
|
99
99
|
}
|
|
@@ -113,7 +113,7 @@ router.patch('/:pk', (0, async_handler_1.default)(async (req, res, next) => {
|
|
|
113
113
|
}
|
|
114
114
|
return next();
|
|
115
115
|
}), respond_1.respond);
|
|
116
|
-
router.delete('/', (0, async_handler_1.default)(async (req,
|
|
116
|
+
router.delete('/', (0, async_handler_1.default)(async (req, _res, next) => {
|
|
117
117
|
const service = new services_1.WebhooksService({
|
|
118
118
|
accountability: req.accountability,
|
|
119
119
|
schema: req.schema,
|
|
@@ -130,7 +130,7 @@ router.delete('/', (0, async_handler_1.default)(async (req, res, next) => {
|
|
|
130
130
|
}
|
|
131
131
|
return next();
|
|
132
132
|
}), respond_1.respond);
|
|
133
|
-
router.delete('/:pk', (0, async_handler_1.default)(async (req,
|
|
133
|
+
router.delete('/:pk', (0, async_handler_1.default)(async (req, _res, next) => {
|
|
134
134
|
const service = new services_1.WebhooksService({
|
|
135
135
|
accountability: req.accountability,
|
|
136
136
|
schema: req.schema,
|
package/dist/database/run-ast.js
CHANGED
|
@@ -280,7 +280,7 @@ function applyParentFilters(schema, nestedCollectionNodes, parentItem) {
|
|
|
280
280
|
continue;
|
|
281
281
|
if (nestedNode.type === 'm2o') {
|
|
282
282
|
const foreignField = schema.collections[nestedNode.relation.related_collection].primary;
|
|
283
|
-
const foreignIds = (0, lodash_1.uniq)(parentItems.map((res) => res[nestedNode.relation.field])).filter((id) => id);
|
|
283
|
+
const foreignIds = (0, lodash_1.uniq)(parentItems.map((res) => res[nestedNode.relation.field])).filter((id) => !(0, lodash_1.isNil)(id));
|
|
284
284
|
(0, lodash_1.merge)(nestedNode, { query: { filter: { [foreignField]: { _in: foreignIds } } } });
|
|
285
285
|
}
|
|
286
286
|
else if (nestedNode.type === 'o2m') {
|
|
@@ -302,7 +302,7 @@ function applyParentFilters(schema, nestedCollectionNodes, parentItem) {
|
|
|
302
302
|
});
|
|
303
303
|
}
|
|
304
304
|
const foreignField = nestedNode.relation.field;
|
|
305
|
-
const foreignIds = (0, lodash_1.uniq)(parentItems.map((res) => res[nestedNode.parentKey])).filter((id) => id);
|
|
305
|
+
const foreignIds = (0, lodash_1.uniq)(parentItems.map((res) => res[nestedNode.parentKey])).filter((id) => !(0, lodash_1.isNil)(id));
|
|
306
306
|
(0, lodash_1.merge)(nestedNode, { query: { filter: { [foreignField]: { _in: foreignIds } } } });
|
|
307
307
|
}
|
|
308
308
|
else if (nestedNode.type === 'a2o') {
|
|
@@ -54,8 +54,8 @@ async function uniqueViolation(error) {
|
|
|
54
54
|
const parenMatches = error.message.match(betweenParens);
|
|
55
55
|
if (!quoteMatches || !parenMatches)
|
|
56
56
|
return error;
|
|
57
|
-
const keyName = quoteMatches[1]
|
|
58
|
-
let collection = quoteMatches[0]
|
|
57
|
+
const keyName = quoteMatches[1].slice(1, -1);
|
|
58
|
+
let collection = quoteMatches[0].slice(1, -1);
|
|
59
59
|
let field = null;
|
|
60
60
|
if (keyName) {
|
|
61
61
|
const database = (0, database_1.default)();
|
|
@@ -49,7 +49,7 @@ function uniqueViolation(error) {
|
|
|
49
49
|
*/
|
|
50
50
|
/** MySQL 8+ style error message */
|
|
51
51
|
if (matches[1].includes('.')) {
|
|
52
|
-
const collection = matches[1]
|
|
52
|
+
const collection = matches[1].slice(1, -1).split('.')[0];
|
|
53
53
|
let field = null;
|
|
54
54
|
const indexName = matches[1]?.slice(1, -1).split('.')[1];
|
|
55
55
|
if (indexName?.startsWith(`${collection}_`) && indexName.endsWith('_unique')) {
|
|
@@ -64,7 +64,7 @@ function uniqueViolation(error) {
|
|
|
64
64
|
}
|
|
65
65
|
else {
|
|
66
66
|
/** MySQL 5.7 style error message */
|
|
67
|
-
const indexName = matches[1]
|
|
67
|
+
const indexName = matches[1].slice(1, -1);
|
|
68
68
|
const collection = indexName.split('_')[0];
|
|
69
69
|
let field = null;
|
|
70
70
|
if (indexName?.startsWith(`${collection}_`) && indexName.endsWith('_unique')) {
|
|
@@ -127,9 +127,9 @@ function foreignKeyViolation(error) {
|
|
|
127
127
|
const parenMatches = error.sql.match(betweenParens);
|
|
128
128
|
if (!tickMatches || !parenMatches)
|
|
129
129
|
return error;
|
|
130
|
-
const collection = tickMatches[1]
|
|
131
|
-
const field = tickMatches[3]
|
|
132
|
-
const invalid = parenMatches[1]
|
|
130
|
+
const collection = tickMatches[1].slice(1, -1);
|
|
131
|
+
const field = tickMatches[3].slice(1, -1);
|
|
132
|
+
const invalid = parenMatches[1].slice(1, -1);
|
|
133
133
|
return new invalid_foreign_key_1.InvalidForeignKeyException(field, {
|
|
134
134
|
collection,
|
|
135
135
|
field,
|
|
@@ -143,6 +143,6 @@ function containsNullValues(error) {
|
|
|
143
143
|
const tickMatches = error.sql.match(betweenTicks);
|
|
144
144
|
if (!tickMatches)
|
|
145
145
|
return error;
|
|
146
|
-
const field = tickMatches[1]
|
|
146
|
+
const field = tickMatches[1].slice(1, -1);
|
|
147
147
|
return new contains_null_values_1.ContainsNullValuesException(field);
|
|
148
148
|
}
|
|
@@ -2,7 +2,7 @@ import { BaseException } from '@directus/shared/exceptions';
|
|
|
2
2
|
type Extensions = {
|
|
3
3
|
collection: string;
|
|
4
4
|
field: string | null;
|
|
5
|
-
invalid?: string;
|
|
5
|
+
invalid?: string | undefined;
|
|
6
6
|
};
|
|
7
7
|
export declare class RecordNotUniqueException extends BaseException {
|
|
8
8
|
constructor(field: string | null, extensions?: Extensions);
|
|
@@ -3,6 +3,6 @@ import type { NextFunction, Request, Response } from 'express';
|
|
|
3
3
|
/**
|
|
4
4
|
* Verify the passed JWT and assign the user ID and role to `req`
|
|
5
5
|
*/
|
|
6
|
-
export declare const handler: (req: Request,
|
|
6
|
+
export declare const handler: (req: Request, _res: Response, next: NextFunction) => Promise<void>;
|
|
7
7
|
declare const _default: (req: Request<import("express-serve-static-core").ParamsDictionary, any, any, import("qs").ParsedQs, Record<string, any>>, res: Response<any, Record<string, any>>, next: NextFunction) => Promise<void>;
|
|
8
8
|
export default _default;
|
|
@@ -16,7 +16,7 @@ const jwt_1 = require("../utils/jwt");
|
|
|
16
16
|
/**
|
|
17
17
|
* Verify the passed JWT and assign the user ID and role to `req`
|
|
18
18
|
*/
|
|
19
|
-
const handler = async (req,
|
|
19
|
+
const handler = async (req, _res, next) => {
|
|
20
20
|
const defaultAccountability = {
|
|
21
21
|
user: null,
|
|
22
22
|
role: null,
|
|
@@ -9,7 +9,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
9
9
|
const collections_1 = require("../database/system-data/collections");
|
|
10
10
|
const exceptions_1 = require("../exceptions");
|
|
11
11
|
const async_handler_1 = __importDefault(require("../utils/async-handler"));
|
|
12
|
-
const collectionExists = (0, async_handler_1.default)(async (req,
|
|
12
|
+
const collectionExists = (0, async_handler_1.default)(async (req, _res, next) => {
|
|
13
13
|
if (!req.params['collection'])
|
|
14
14
|
return next();
|
|
15
15
|
if (req.params['collection'] in req.schema.collections === false) {
|
package/dist/middleware/cors.js
CHANGED
|
@@ -5,7 +5,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
const cors_1 = __importDefault(require("cors"));
|
|
7
7
|
const env_1 = __importDefault(require("../env"));
|
|
8
|
-
let corsMiddleware = (
|
|
8
|
+
let corsMiddleware = (_req, _res, next) => next();
|
|
9
9
|
if (env_1.default['CORS_ENABLED'] === true) {
|
|
10
10
|
corsMiddleware = (0, cors_1.default)({
|
|
11
11
|
origin: env_1.default['CORS_ORIGIN'] || true,
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* and store in req.token
|
|
9
9
|
*/
|
|
10
10
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
-
const extractToken = (req,
|
|
11
|
+
const extractToken = (req, _res, next) => {
|
|
12
12
|
let token = null;
|
|
13
13
|
if (req.query && req.query['access_token']) {
|
|
14
14
|
token = req.query['access_token'];
|
|
@@ -5,7 +5,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
const async_handler_1 = __importDefault(require("../utils/async-handler"));
|
|
7
7
|
const get_permissions_1 = require("../utils/get-permissions");
|
|
8
|
-
const getPermissions = (0, async_handler_1.default)(async (req,
|
|
8
|
+
const getPermissions = (0, async_handler_1.default)(async (req, _res, next) => {
|
|
9
9
|
if (!req.accountability) {
|
|
10
10
|
throw new Error('getPermissions middleware needs to be called after authenticate');
|
|
11
11
|
}
|
|
@@ -5,7 +5,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
const async_handler_1 = __importDefault(require("../utils/async-handler"));
|
|
7
7
|
const get_schema_1 = require("../utils/get-schema");
|
|
8
|
-
const schema = (0, async_handler_1.default)(async (req,
|
|
8
|
+
const schema = (0, async_handler_1.default)(async (req, _res, next) => {
|
|
9
9
|
req.schema = await (0, get_schema_1.getSchema)();
|
|
10
10
|
return next();
|
|
11
11
|
});
|
|
@@ -4,7 +4,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
const async_handler_1 = __importDefault(require("../utils/async-handler"));
|
|
7
|
-
const useCollection = (collection) => (0, async_handler_1.default)(async (req,
|
|
7
|
+
const useCollection = (collection) => (0, async_handler_1.default)(async (req, _res, next) => {
|
|
8
8
|
req.collection = collection;
|
|
9
9
|
next();
|
|
10
10
|
});
|
|
@@ -9,7 +9,7 @@ const exceptions_1 = require("../exceptions");
|
|
|
9
9
|
const exceptions_2 = require("@directus/shared/exceptions");
|
|
10
10
|
const async_handler_1 = __importDefault(require("../utils/async-handler"));
|
|
11
11
|
const sanitize_query_1 = require("../utils/sanitize-query");
|
|
12
|
-
const validateBatch = (scope) => (0, async_handler_1.default)(async (req,
|
|
12
|
+
const validateBatch = (scope) => (0, async_handler_1.default)(async (req, _res, next) => {
|
|
13
13
|
if (req.method.toLowerCase() === 'get') {
|
|
14
14
|
req.body = {};
|
|
15
15
|
return next();
|
package/dist/services/files.js
CHANGED
|
@@ -79,12 +79,12 @@ class FilesService extends items_1.ItemsService {
|
|
|
79
79
|
if (['image/jpeg', 'image/png', 'image/webp', 'image/gif', 'image/tiff'].includes(payload.type)) {
|
|
80
80
|
const stream = await storage.location(data.storage).read(payload.filename_disk);
|
|
81
81
|
const { height, width, description, title, tags, metadata } = await this.getMetadata(stream);
|
|
82
|
-
payload.height
|
|
83
|
-
payload.width
|
|
84
|
-
payload.description
|
|
85
|
-
payload.title
|
|
86
|
-
payload.tags
|
|
87
|
-
payload.metadata
|
|
82
|
+
payload.height ??= height ?? null;
|
|
83
|
+
payload.width ??= width ?? null;
|
|
84
|
+
payload.description ??= description ?? null;
|
|
85
|
+
payload.title ??= title ?? null;
|
|
86
|
+
payload.tags ??= tags ?? null;
|
|
87
|
+
payload.metadata ??= metadata ?? null;
|
|
88
88
|
}
|
|
89
89
|
// We do this in a service without accountability. Even if you don't have update permissions to the file,
|
|
90
90
|
// we still want to be able to set the extracted values from the file on create
|
|
@@ -378,7 +378,7 @@ class GraphQLService {
|
|
|
378
378
|
type: new graphql_1.GraphQLUnionType({
|
|
379
379
|
name: `${relation.collection}_${relation.field}_union`,
|
|
380
380
|
types: relation.meta.one_allowed_collections.map((collection) => CollectionTypes[collection].getType()),
|
|
381
|
-
resolveType(
|
|
381
|
+
resolveType(_value, context, info) {
|
|
382
382
|
let path = [];
|
|
383
383
|
let currentPath = info.path;
|
|
384
384
|
while (currentPath.prev) {
|
|
@@ -959,9 +959,7 @@ class GraphQLService {
|
|
|
959
959
|
resolve: async ({ args, info }) => await self.resolveMutation(args, info),
|
|
960
960
|
};
|
|
961
961
|
if (collectionIsReadable) {
|
|
962
|
-
resolverDefinition.args = ReadCollectionTypes[collection.collection]
|
|
963
|
-
.getResolver(collection.collection)
|
|
964
|
-
.getArgs();
|
|
962
|
+
resolverDefinition.args = ReadCollectionTypes[collection.collection].getResolver(collection.collection).getArgs();
|
|
965
963
|
}
|
|
966
964
|
CreateCollectionTypes[collection.collection].addResolver(resolverDefinition);
|
|
967
965
|
CreateCollectionTypes[collection.collection].addResolver({
|
|
@@ -970,17 +968,13 @@ class GraphQLService {
|
|
|
970
968
|
resolve: async ({ args, info }) => await self.resolveMutation(args, info),
|
|
971
969
|
});
|
|
972
970
|
CreateCollectionTypes[collection.collection].getResolver(`create_${collection.collection}_items`).addArgs({
|
|
973
|
-
...CreateCollectionTypes[collection.collection]
|
|
974
|
-
.getResolver(`create_${collection.collection}_items`)
|
|
975
|
-
.getArgs(),
|
|
971
|
+
...CreateCollectionTypes[collection.collection].getResolver(`create_${collection.collection}_items`).getArgs(),
|
|
976
972
|
data: [
|
|
977
973
|
(0, graphql_compose_1.toInputObjectType)(CreateCollectionTypes[collection.collection]).setTypeName(`create_${collection.collection}_input`).NonNull,
|
|
978
974
|
],
|
|
979
975
|
});
|
|
980
976
|
CreateCollectionTypes[collection.collection].getResolver(`create_${collection.collection}_item`).addArgs({
|
|
981
|
-
...CreateCollectionTypes[collection.collection]
|
|
982
|
-
.getResolver(`create_${collection.collection}_item`)
|
|
983
|
-
.getArgs(),
|
|
977
|
+
...CreateCollectionTypes[collection.collection].getResolver(`create_${collection.collection}_item`).getArgs(),
|
|
984
978
|
data: (0, graphql_compose_1.toInputObjectType)(CreateCollectionTypes[collection.collection]).setTypeName(`create_${collection.collection}_input`).NonNull,
|
|
985
979
|
});
|
|
986
980
|
}
|
|
@@ -1343,7 +1337,7 @@ class GraphQLService {
|
|
|
1343
1337
|
if (!query.deep)
|
|
1344
1338
|
query.deep = {};
|
|
1345
1339
|
const args = this.parseArgs(selection.arguments, variableValues);
|
|
1346
|
-
(0, lodash_1.set)(query.deep, currentAlias ?? current, (0, lodash_1.merge)({}, (0, lodash_1.get)(query.deep, currentAlias ?? current), (0, lodash_1.mapKeys)((0, sanitize_query_1.sanitizeQuery)(args, this.accountability), (
|
|
1340
|
+
(0, lodash_1.set)(query.deep, currentAlias ?? current, (0, lodash_1.merge)({}, (0, lodash_1.get)(query.deep, currentAlias ?? current), (0, lodash_1.mapKeys)((0, sanitize_query_1.sanitizeQuery)(args, this.accountability), (_value, key) => `_${key}`)));
|
|
1347
1341
|
}
|
|
1348
1342
|
}
|
|
1349
1343
|
}
|
|
@@ -1498,15 +1492,60 @@ class GraphQLService {
|
|
|
1498
1492
|
const ServerInfo = schemaComposer.createObjectTC({
|
|
1499
1493
|
name: 'server_info',
|
|
1500
1494
|
fields: {
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1495
|
+
project: {
|
|
1496
|
+
type: new graphql_1.GraphQLObjectType({
|
|
1497
|
+
name: 'server_info_project',
|
|
1498
|
+
fields: {
|
|
1499
|
+
project_name: { type: graphql_1.GraphQLString },
|
|
1500
|
+
project_descriptor: { type: graphql_1.GraphQLString },
|
|
1501
|
+
project_logo: { type: graphql_1.GraphQLString },
|
|
1502
|
+
project_color: { type: graphql_1.GraphQLString },
|
|
1503
|
+
default_language: { type: graphql_1.GraphQLString },
|
|
1504
|
+
public_foreground: { type: graphql_1.GraphQLString },
|
|
1505
|
+
public_background: { type: graphql_1.GraphQLString },
|
|
1506
|
+
public_note: { type: graphql_1.GraphQLString },
|
|
1507
|
+
custom_css: { type: graphql_1.GraphQLString },
|
|
1508
|
+
},
|
|
1509
|
+
}),
|
|
1510
|
+
},
|
|
1508
1511
|
},
|
|
1509
1512
|
});
|
|
1513
|
+
if (this.accountability?.user) {
|
|
1514
|
+
ServerInfo.addFields({
|
|
1515
|
+
rateLimit: env_1.default['RATE_LIMITER_ENABLED']
|
|
1516
|
+
? {
|
|
1517
|
+
type: new graphql_1.GraphQLObjectType({
|
|
1518
|
+
name: 'server_info_rate_limit',
|
|
1519
|
+
fields: {
|
|
1520
|
+
points: { type: graphql_1.GraphQLInt },
|
|
1521
|
+
duration: { type: graphql_1.GraphQLInt },
|
|
1522
|
+
},
|
|
1523
|
+
}),
|
|
1524
|
+
}
|
|
1525
|
+
: graphql_1.GraphQLBoolean,
|
|
1526
|
+
rateLimitGlobal: env_1.default['RATE_LIMITER_GLOBAL_ENABLED']
|
|
1527
|
+
? {
|
|
1528
|
+
type: new graphql_1.GraphQLObjectType({
|
|
1529
|
+
name: 'server_info_rate_limit_global',
|
|
1530
|
+
fields: {
|
|
1531
|
+
points: { type: graphql_1.GraphQLInt },
|
|
1532
|
+
duration: { type: graphql_1.GraphQLInt },
|
|
1533
|
+
},
|
|
1534
|
+
}),
|
|
1535
|
+
}
|
|
1536
|
+
: graphql_1.GraphQLBoolean,
|
|
1537
|
+
flows: {
|
|
1538
|
+
type: new graphql_1.GraphQLObjectType({
|
|
1539
|
+
name: 'server_info_flows',
|
|
1540
|
+
fields: {
|
|
1541
|
+
execAllowedModules: {
|
|
1542
|
+
type: new graphql_1.GraphQLList(graphql_1.GraphQLString),
|
|
1543
|
+
},
|
|
1544
|
+
},
|
|
1545
|
+
}),
|
|
1546
|
+
},
|
|
1547
|
+
});
|
|
1548
|
+
}
|
|
1510
1549
|
if (this.accountability?.admin === true) {
|
|
1511
1550
|
ServerInfo.addFields({
|
|
1512
1551
|
directus: {
|
|
@@ -1860,6 +1899,19 @@ class GraphQLService {
|
|
|
1860
1899
|
return true;
|
|
1861
1900
|
},
|
|
1862
1901
|
},
|
|
1902
|
+
utils_random_string: {
|
|
1903
|
+
type: graphql_1.GraphQLString,
|
|
1904
|
+
args: {
|
|
1905
|
+
length: graphql_1.GraphQLInt,
|
|
1906
|
+
},
|
|
1907
|
+
resolve: async (_, args) => {
|
|
1908
|
+
const { nanoid } = await import('nanoid');
|
|
1909
|
+
if (args['length'] && Number(args['length']) > 500) {
|
|
1910
|
+
throw new exceptions_1.InvalidPayloadException(`"length" can't be more than 500 characters`);
|
|
1911
|
+
}
|
|
1912
|
+
return nanoid(args['length'] ? Number(args['length']) : 32);
|
|
1913
|
+
},
|
|
1914
|
+
},
|
|
1863
1915
|
utils_hash_generate: {
|
|
1864
1916
|
type: graphql_1.GraphQLString,
|
|
1865
1917
|
args: {
|
|
@@ -442,15 +442,15 @@ class RelationsService {
|
|
|
442
442
|
collectionsAllowed = false;
|
|
443
443
|
}
|
|
444
444
|
if (!allowedFields[relation.collection] ||
|
|
445
|
-
(allowedFields[relation.collection]
|
|
446
|
-
allowedFields[relation.collection]
|
|
445
|
+
(allowedFields[relation.collection]?.includes('*') === false &&
|
|
446
|
+
allowedFields[relation.collection]?.includes(relation.field) === false)) {
|
|
447
447
|
fieldsAllowed = false;
|
|
448
448
|
}
|
|
449
449
|
if (relation.related_collection &&
|
|
450
450
|
relation.meta?.one_field &&
|
|
451
451
|
(!allowedFields[relation.related_collection] ||
|
|
452
|
-
(allowedFields[relation.related_collection]
|
|
453
|
-
allowedFields[relation.related_collection]
|
|
452
|
+
(allowedFields[relation.related_collection]?.includes('*') === false &&
|
|
453
|
+
allowedFields[relation.related_collection]?.includes(relation.meta.one_field) === false))) {
|
|
454
454
|
fieldsAllowed = false;
|
|
455
455
|
}
|
|
456
456
|
return collectionsAllowed && fieldsAllowed;
|
package/dist/services/users.js
CHANGED
|
@@ -335,7 +335,7 @@ class UsersService extends items_1.ItemsService {
|
|
|
335
335
|
const token = jsonwebtoken_1.default.sign(payload, env_1.default['SECRET'], { expiresIn: '1d', issuer: 'directus' });
|
|
336
336
|
const acceptURL = url
|
|
337
337
|
? new url_1.Url(url).setQuery('token', token).toString()
|
|
338
|
-
: new url_1.Url(env_1.default['PUBLIC_URL']).addPath('admin', 'reset-password').setQuery('token', token);
|
|
338
|
+
: new url_1.Url(env_1.default['PUBLIC_URL']).addPath('admin', 'reset-password').setQuery('token', token).toString();
|
|
339
339
|
const subjectLine = subject ? subject : 'Password Reset Request';
|
|
340
340
|
await mailService.send({
|
|
341
341
|
to: email,
|
package/dist/utils/apply-diff.js
CHANGED
|
@@ -27,7 +27,7 @@ async function applyDiff(currentSnapshot, snapshotDiff, options) {
|
|
|
27
27
|
const getNestedCollectionsToDelete = (currentLevelCollection) => snapshotDiff.collections.filter(({ diff }) => diff[0].lhs?.meta?.group === currentLevelCollection);
|
|
28
28
|
const createCollections = async (collections) => {
|
|
29
29
|
for (const { collection, diff } of collections) {
|
|
30
|
-
if (diff?.[0]
|
|
30
|
+
if (diff?.[0]?.kind === types_1.DiffKind.NEW && diff[0].rhs) {
|
|
31
31
|
// We'll nest the to-be-created fields in the same collection creation, to prevent
|
|
32
32
|
// creating a collection without a primary key
|
|
33
33
|
const fields = snapshotDiff.fields
|
|
@@ -64,7 +64,7 @@ async function applyDiff(currentSnapshot, snapshotDiff, options) {
|
|
|
64
64
|
};
|
|
65
65
|
const deleteCollections = async (collections) => {
|
|
66
66
|
for (const { collection, diff } of collections) {
|
|
67
|
-
if (diff?.[0]
|
|
67
|
+
if (diff?.[0]?.kind === types_1.DiffKind.DELETE) {
|
|
68
68
|
const relations = schema.relations.filter((r) => r.related_collection === collection || r.collection === collection);
|
|
69
69
|
if (relations.length > 0) {
|
|
70
70
|
const relationsService = new services_1.RelationsService({ knex: trx, schema });
|
|
@@ -94,7 +94,7 @@ async function applyDiff(currentSnapshot, snapshotDiff, options) {
|
|
|
94
94
|
// Finds all collections that need to be created
|
|
95
95
|
const filterCollectionsForCreation = ({ diff }) => {
|
|
96
96
|
// Check new collections only
|
|
97
|
-
const isNewCollection = diff[0]
|
|
97
|
+
const isNewCollection = diff[0]?.kind === types_1.DiffKind.NEW;
|
|
98
98
|
if (!isNewCollection)
|
|
99
99
|
return false;
|
|
100
100
|
// Create now if no group
|
|
@@ -111,7 +111,7 @@ async function applyDiff(currentSnapshot, snapshotDiff, options) {
|
|
|
111
111
|
// TopLevelCollection - I exist in current schema
|
|
112
112
|
// NestedCollection - I exist in snapshotDiff as a new collection
|
|
113
113
|
// TheCurrentCollectionInIteration - I exist in snapshotDiff as a new collection but will be created as part of NestedCollection
|
|
114
|
-
const parentWillBeCreatedInThisApply = snapshotDiff.collections.filter(({ collection, diff }) => diff[0]
|
|
114
|
+
const parentWillBeCreatedInThisApply = snapshotDiff.collections.filter(({ collection, diff }) => diff[0]?.kind === types_1.DiffKind.NEW && collection === groupName).length > 0;
|
|
115
115
|
// Has group, but parent is not new, parent is also not being created in this snapshot apply
|
|
116
116
|
if (parentExists && !parentWillBeCreatedInThisApply)
|
|
117
117
|
return true;
|
|
@@ -121,9 +121,9 @@ async function applyDiff(currentSnapshot, snapshotDiff, options) {
|
|
|
121
121
|
// then continue with nested collections recursively
|
|
122
122
|
await createCollections(snapshotDiff.collections.filter(filterCollectionsForCreation));
|
|
123
123
|
// delete top level collections (no group) first, then continue with nested collections recursively
|
|
124
|
-
await deleteCollections(snapshotDiff.collections.filter(({ diff }) => diff[0]
|
|
124
|
+
await deleteCollections(snapshotDiff.collections.filter(({ diff }) => diff[0]?.kind === types_1.DiffKind.DELETE && diff[0].lhs.meta?.group === null));
|
|
125
125
|
for (const { collection, diff } of snapshotDiff.collections) {
|
|
126
|
-
if (diff?.[0]
|
|
126
|
+
if (diff?.[0]?.kind === types_1.DiffKind.EDIT || diff?.[0]?.kind === types_1.DiffKind.ARRAY) {
|
|
127
127
|
const currentCollection = currentSnapshot.collections.find((field) => {
|
|
128
128
|
return field.collection === collection;
|
|
129
129
|
});
|
|
@@ -147,7 +147,7 @@ async function applyDiff(currentSnapshot, snapshotDiff, options) {
|
|
|
147
147
|
schema: await (0, get_schema_1.getSchema)({ database: trx, bypassCache: true }),
|
|
148
148
|
});
|
|
149
149
|
for (const { collection, field, diff } of snapshotDiff.fields) {
|
|
150
|
-
if (diff?.[0]
|
|
150
|
+
if (diff?.[0]?.kind === types_1.DiffKind.NEW && !isNestedMetaUpdate(diff?.[0])) {
|
|
151
151
|
try {
|
|
152
152
|
await fieldsService.createField(collection, diff[0].rhs, undefined, mutationOptions);
|
|
153
153
|
}
|
|
@@ -156,7 +156,7 @@ async function applyDiff(currentSnapshot, snapshotDiff, options) {
|
|
|
156
156
|
throw err;
|
|
157
157
|
}
|
|
158
158
|
}
|
|
159
|
-
if (diff?.[0]
|
|
159
|
+
if (diff?.[0]?.kind === types_1.DiffKind.EDIT || diff?.[0]?.kind === types_1.DiffKind.ARRAY || isNestedMetaUpdate(diff[0])) {
|
|
160
160
|
const currentField = currentSnapshot.fields.find((snapshotField) => {
|
|
161
161
|
return snapshotField.collection === collection && snapshotField.field === field;
|
|
162
162
|
});
|
|
@@ -174,7 +174,7 @@ async function applyDiff(currentSnapshot, snapshotDiff, options) {
|
|
|
174
174
|
}
|
|
175
175
|
}
|
|
176
176
|
}
|
|
177
|
-
if (diff?.[0]
|
|
177
|
+
if (diff?.[0]?.kind === types_1.DiffKind.DELETE && !isNestedMetaUpdate(diff?.[0])) {
|
|
178
178
|
try {
|
|
179
179
|
await fieldsService.deleteField(collection, field, mutationOptions);
|
|
180
180
|
}
|
|
@@ -196,7 +196,7 @@ async function applyDiff(currentSnapshot, snapshotDiff, options) {
|
|
|
196
196
|
for (const diffEdit of diff) {
|
|
197
197
|
(0, lodash_1.set)(structure, diffEdit.path, undefined);
|
|
198
198
|
}
|
|
199
|
-
if (diff?.[0]
|
|
199
|
+
if (diff?.[0]?.kind === types_1.DiffKind.NEW) {
|
|
200
200
|
try {
|
|
201
201
|
await relationsService.createOne(diff[0].rhs, mutationOptions);
|
|
202
202
|
}
|
|
@@ -205,7 +205,7 @@ async function applyDiff(currentSnapshot, snapshotDiff, options) {
|
|
|
205
205
|
throw err;
|
|
206
206
|
}
|
|
207
207
|
}
|
|
208
|
-
if (diff?.[0]
|
|
208
|
+
if (diff?.[0]?.kind === types_1.DiffKind.EDIT || diff?.[0]?.kind === types_1.DiffKind.ARRAY) {
|
|
209
209
|
const currentRelation = currentSnapshot.relations.find((relation) => {
|
|
210
210
|
return relation.collection === collection && relation.field === field;
|
|
211
211
|
});
|
|
@@ -223,7 +223,7 @@ async function applyDiff(currentSnapshot, snapshotDiff, options) {
|
|
|
223
223
|
}
|
|
224
224
|
}
|
|
225
225
|
}
|
|
226
|
-
if (diff?.[0]
|
|
226
|
+
if (diff?.[0]?.kind === types_1.DiffKind.DELETE) {
|
|
227
227
|
try {
|
|
228
228
|
await relationsService.deleteOne(collection, field, mutationOptions);
|
|
229
229
|
}
|
|
@@ -362,7 +362,7 @@ function applyFilter(knex, schema, rootQuery, rootFilter, collection, aliasMap)
|
|
|
362
362
|
}
|
|
363
363
|
// Cast filter value (compareValue) based on type of field being filtered against
|
|
364
364
|
const [collection, field] = key.split('.');
|
|
365
|
-
const mappedCollection = originalCollectionName || collection;
|
|
365
|
+
const mappedCollection = (originalCollectionName || collection);
|
|
366
366
|
if (mappedCollection in schema.collections && field in schema.collections[mappedCollection].fields) {
|
|
367
367
|
const type = schema.collections[mappedCollection].fields[field].type;
|
|
368
368
|
if (['date', 'dateTime', 'time', 'timestamp'].includes(type)) {
|
|
@@ -296,5 +296,5 @@ async function getASTFromQuery(collection, query, schema, options) {
|
|
|
296
296
|
}
|
|
297
297
|
exports.default = getASTFromQuery;
|
|
298
298
|
function getDeepQuery(query) {
|
|
299
|
-
return (0, lodash_1.mapKeys)((0, lodash_1.omitBy)(query, (
|
|
299
|
+
return (0, lodash_1.mapKeys)((0, lodash_1.omitBy)(query, (_value, key) => key.startsWith('_') === false), (_value, key) => key.substring(1));
|
|
300
300
|
}
|
|
@@ -43,7 +43,8 @@ function getColumnPath({ path, collection, aliasMap, relations, schema }) {
|
|
|
43
43
|
addNestedPkField = schema.collections[parent].primary;
|
|
44
44
|
}
|
|
45
45
|
// Nested level alias field
|
|
46
|
-
else if (remainingParts.length === 1 &&
|
|
46
|
+
else if (remainingParts.length === 1 &&
|
|
47
|
+
schema.collections[parent].fields[remainingParts[0]].type === 'alias') {
|
|
47
48
|
remainingParts.push(schema.collections[relation.related_collection].primary);
|
|
48
49
|
addNestedPkField = schema.collections[relation.related_collection].primary;
|
|
49
50
|
}
|
package/dist/utils/get-schema.js
CHANGED
|
@@ -81,7 +81,7 @@ async function getDatabaseSchema(database, schemaInspector) {
|
|
|
81
81
|
note: collectionMeta?.note || null,
|
|
82
82
|
sortField: collectionMeta?.sort_field || null,
|
|
83
83
|
accountability: collectionMeta ? collectionMeta.accountability : 'all',
|
|
84
|
-
fields: (0, lodash_1.mapValues)(schemaOverview[collection]
|
|
84
|
+
fields: (0, lodash_1.mapValues)(schemaOverview[collection]?.columns, (column) => {
|
|
85
85
|
return {
|
|
86
86
|
field: column.column_name,
|
|
87
87
|
defaultValue: (0, get_default_value_1.default)(column) ?? null,
|
|
@@ -108,8 +108,8 @@ async function getDatabaseSchema(database, schemaInspector) {
|
|
|
108
108
|
for (const field of fields) {
|
|
109
109
|
if (!result.collections[field.collection])
|
|
110
110
|
continue;
|
|
111
|
-
const existing = result.collections[field.collection]
|
|
112
|
-
const column = schemaOverview[field.collection]
|
|
111
|
+
const existing = result.collections[field.collection]?.fields[field.field];
|
|
112
|
+
const column = schemaOverview[field.collection]?.columns[field.field];
|
|
113
113
|
const special = field.special ? (0, utils_1.toArray)(field.special) : [];
|
|
114
114
|
if (constants_1.ALIAS_TYPES.some((type) => special.includes(type)) === false && !existing)
|
|
115
115
|
continue;
|
|
@@ -73,7 +73,7 @@ function getSnapshotDiff(current, after) {
|
|
|
73
73
|
* When you delete a collection, we don't have to individually drop all the fields/relations as well
|
|
74
74
|
*/
|
|
75
75
|
const deletedCollections = diffedSnapshot.collections
|
|
76
|
-
.filter((collection) => collection.diff?.[0]
|
|
76
|
+
.filter((collection) => collection.diff?.[0]?.kind === types_1.DiffKind.DELETE)
|
|
77
77
|
.map(({ collection }) => collection);
|
|
78
78
|
diffedSnapshot.fields = diffedSnapshot.fields.filter((field) => deletedCollections.includes(field.collection) === false);
|
|
79
79
|
diffedSnapshot.relations = diffedSnapshot.relations.filter((relation) => deletedCollections.includes(relation.collection) === false);
|
|
@@ -53,8 +53,8 @@ function parseXmp(buffer) {
|
|
|
53
53
|
if (!tagMatches || tagMatches.length === 0) {
|
|
54
54
|
return;
|
|
55
55
|
}
|
|
56
|
-
const value = tagMatches[1]
|
|
57
|
-
if (value
|
|
56
|
+
const value = tagMatches[1]?.trim();
|
|
57
|
+
if (value?.toLowerCase().indexOf('<rdf:bag>') === 0) {
|
|
58
58
|
const r = new RegExp('<rdf:li>(.*?)</rdf:li>', 'smig');
|
|
59
59
|
let match = r.exec(value);
|
|
60
60
|
const result = [];
|
|
@@ -65,7 +65,7 @@ function parseXmp(buffer) {
|
|
|
65
65
|
xmp[x] = result;
|
|
66
66
|
}
|
|
67
67
|
else {
|
|
68
|
-
xmp[x] = value
|
|
68
|
+
xmp[x] = value?.replace(/<[^>]*>?/gm, '').trim();
|
|
69
69
|
}
|
|
70
70
|
});
|
|
71
71
|
return xmp;
|
|
@@ -56,7 +56,7 @@ function reduceSchema(schema, permissions, actions = ['create', 'read', 'update'
|
|
|
56
56
|
if (relation.related_collection &&
|
|
57
57
|
(Object.keys(allowedFieldsInCollection).includes(relation.related_collection) === false ||
|
|
58
58
|
// Ignore legacy permissions with an empty fields array
|
|
59
|
-
allowedFieldsInCollection[relation.related_collection]
|
|
59
|
+
allowedFieldsInCollection[relation.related_collection]?.length === 0)) {
|
|
60
60
|
collectionsAllowed = false;
|
|
61
61
|
}
|
|
62
62
|
if (relation.meta?.one_allowed_collections &&
|
|
@@ -64,15 +64,15 @@ function reduceSchema(schema, permissions, actions = ['create', 'read', 'update'
|
|
|
64
64
|
collectionsAllowed = false;
|
|
65
65
|
}
|
|
66
66
|
if (!allowedFieldsInCollection[relation.collection] ||
|
|
67
|
-
(allowedFieldsInCollection[relation.collection]
|
|
68
|
-
allowedFieldsInCollection[relation.collection]
|
|
67
|
+
(allowedFieldsInCollection[relation.collection]?.includes('*') === false &&
|
|
68
|
+
allowedFieldsInCollection[relation.collection]?.includes(relation.field) === false)) {
|
|
69
69
|
fieldsAllowed = false;
|
|
70
70
|
}
|
|
71
71
|
if (relation.related_collection &&
|
|
72
72
|
relation.meta?.one_field &&
|
|
73
73
|
(!allowedFieldsInCollection[relation.related_collection] ||
|
|
74
|
-
(allowedFieldsInCollection[relation.related_collection]
|
|
75
|
-
allowedFieldsInCollection[relation.related_collection]
|
|
74
|
+
(allowedFieldsInCollection[relation.related_collection]?.includes('*') === false &&
|
|
75
|
+
allowedFieldsInCollection[relation.related_collection]?.includes(relation.meta?.one_field) === false))) {
|
|
76
76
|
fieldsAllowed = false;
|
|
77
77
|
}
|
|
78
78
|
return collectionsAllowed && fieldsAllowed;
|
|
@@ -11,9 +11,18 @@ const url_1 = require("./url");
|
|
|
11
11
|
function shouldSkipCache(req) {
|
|
12
12
|
const env = (0, env_1.getEnv)();
|
|
13
13
|
// Always skip cache for requests coming from the data studio based on Referer header
|
|
14
|
-
const
|
|
15
|
-
if (
|
|
16
|
-
|
|
14
|
+
const referer = req.get('Referer');
|
|
15
|
+
if (referer) {
|
|
16
|
+
const adminUrl = new url_1.Url(env['PUBLIC_URL']).addPath('admin');
|
|
17
|
+
if (adminUrl.isRootRelative()) {
|
|
18
|
+
const refererUrl = new url_1.Url(referer);
|
|
19
|
+
if (refererUrl.path.join('/').startsWith(adminUrl.path.join('/')))
|
|
20
|
+
return true;
|
|
21
|
+
}
|
|
22
|
+
else if (referer.startsWith(adminUrl.toString())) {
|
|
23
|
+
return true;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
17
26
|
if (env['CACHE_SKIP_ALLOWED'] && req.get('cache-control')?.includes('no-store'))
|
|
18
27
|
return true;
|
|
19
28
|
return false;
|
|
@@ -7,7 +7,7 @@ const constants_1 = require("@directus/shared/constants");
|
|
|
7
7
|
*/
|
|
8
8
|
function stripFunction(field) {
|
|
9
9
|
if (field.includes('(') && field.includes(')')) {
|
|
10
|
-
return field.match(constants_1.REGEX_BETWEEN_PARENS)[1]
|
|
10
|
+
return field.match(constants_1.REGEX_BETWEEN_PARENS)?.[1]?.trim() ?? field;
|
|
11
11
|
}
|
|
12
12
|
else {
|
|
13
13
|
return field;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function collectTelemetry(): Promise<void>;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.collectTelemetry = void 0;
|
|
7
|
+
const node_machine_id_1 = require("node-machine-id");
|
|
8
|
+
const package_json_1 = require("../../package.json");
|
|
9
|
+
const env_1 = __importDefault(require("../env"));
|
|
10
|
+
const logger_1 = __importDefault(require("../logger"));
|
|
11
|
+
async function collectTelemetry() {
|
|
12
|
+
const axios = (await import('axios')).default;
|
|
13
|
+
if (env_1.default['TELEMETRY'] !== false) {
|
|
14
|
+
try {
|
|
15
|
+
await axios.post('https://telemetry.directus.io/', {
|
|
16
|
+
version: package_json_1.version,
|
|
17
|
+
public_url: env_1.default['PUBLIC_URL'],
|
|
18
|
+
project_id: env_1.default['KEY'],
|
|
19
|
+
machine_id: await (0, node_machine_id_1.machineId)(),
|
|
20
|
+
db_client: env_1.default['DB_CLIENT'],
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
catch (err) {
|
|
24
|
+
if (env_1.default['NODE_ENV'] === 'development') {
|
|
25
|
+
logger_1.default.error(err);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
exports.collectTelemetry = collectTelemetry;
|
|
@@ -16,7 +16,7 @@ function validateKeys(schema, collection, keyField, keys) {
|
|
|
16
16
|
}
|
|
17
17
|
}
|
|
18
18
|
else {
|
|
19
|
-
const primaryKeyFieldType = schema.collections[collection]
|
|
19
|
+
const primaryKeyFieldType = schema.collections[collection]?.fields[keyField]?.type;
|
|
20
20
|
if (primaryKeyFieldType === 'uuid' && !(0, uuid_validate_1.default)(String(keys))) {
|
|
21
21
|
throw new exceptions_1.ForbiddenException();
|
|
22
22
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "directus",
|
|
3
|
-
"version": "9.
|
|
3
|
+
"version": "9.24.0",
|
|
4
4
|
"description": "Directus is a real-time API and App dashboard for managing SQL database content",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"directus",
|
|
@@ -144,18 +144,18 @@
|
|
|
144
144
|
"uuid-validate": "0.0.3",
|
|
145
145
|
"vm2": "3.9.14",
|
|
146
146
|
"wellknown": "0.5.0",
|
|
147
|
-
"@directus/app": "9.
|
|
148
|
-
"@directus/
|
|
149
|
-
"@directus/
|
|
150
|
-
"@directus/shared": "9.
|
|
151
|
-
"@directus/
|
|
152
|
-
"@directus/
|
|
153
|
-
"@directus/storage-driver-azure": "9.
|
|
154
|
-
"@directus/storage-driver-cloudinary": "9.
|
|
155
|
-
"@directus/storage-driver-gcs": "9.
|
|
156
|
-
"@directus/storage-driver-local": "9.
|
|
157
|
-
"@directus/storage-driver-s3": "9.
|
|
158
|
-
"@directus/utils": "9.
|
|
147
|
+
"@directus/app": "9.24.0",
|
|
148
|
+
"@directus/extensions-sdk": "9.24.0",
|
|
149
|
+
"@directus/schema": "9.24.0",
|
|
150
|
+
"@directus/shared": "9.24.0",
|
|
151
|
+
"@directus/specs": "9.24.0",
|
|
152
|
+
"@directus/storage": "9.24.0",
|
|
153
|
+
"@directus/storage-driver-azure": "9.24.0",
|
|
154
|
+
"@directus/storage-driver-cloudinary": "9.24.0",
|
|
155
|
+
"@directus/storage-driver-gcs": "9.24.0",
|
|
156
|
+
"@directus/storage-driver-local": "9.24.0",
|
|
157
|
+
"@directus/storage-driver-s3": "9.24.0",
|
|
158
|
+
"@directus/utils": "9.24.0"
|
|
159
159
|
},
|
|
160
160
|
"devDependencies": {
|
|
161
161
|
"@ngneat/falso": "6.4.0",
|
package/dist/utils/track.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare function track(event: string): Promise<void>;
|
package/dist/utils/track.js
DELETED
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.track = void 0;
|
|
7
|
-
const node_machine_id_1 = require("node-machine-id");
|
|
8
|
-
const os_1 = __importDefault(require("os"));
|
|
9
|
-
// @ts-ignore
|
|
10
|
-
const utils_1 = require("@directus/shared/utils");
|
|
11
|
-
const package_json_1 = require("../../package.json");
|
|
12
|
-
const env_1 = __importDefault(require("../env"));
|
|
13
|
-
const logger_1 = __importDefault(require("../logger"));
|
|
14
|
-
const get_milliseconds_1 = require("./get-milliseconds");
|
|
15
|
-
async function track(event) {
|
|
16
|
-
const axios = (await import('axios')).default;
|
|
17
|
-
if (env_1.default['TELEMETRY'] !== false) {
|
|
18
|
-
const info = await getEnvInfo(event);
|
|
19
|
-
try {
|
|
20
|
-
await axios.post('https://telemetry.directus.io/', info);
|
|
21
|
-
}
|
|
22
|
-
catch (err) {
|
|
23
|
-
if (env_1.default['NODE_ENV'] === 'development') {
|
|
24
|
-
logger_1.default.error(err);
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
exports.track = track;
|
|
30
|
-
async function getEnvInfo(event) {
|
|
31
|
-
return {
|
|
32
|
-
version: package_json_1.version,
|
|
33
|
-
event: event,
|
|
34
|
-
project_id: env_1.default['KEY'],
|
|
35
|
-
machine_id: await (0, node_machine_id_1.machineId)(),
|
|
36
|
-
environment: env_1.default['NODE_ENV'],
|
|
37
|
-
stack: 'node',
|
|
38
|
-
os: {
|
|
39
|
-
arch: os_1.default.arch(),
|
|
40
|
-
platform: os_1.default.platform(),
|
|
41
|
-
release: os_1.default.release(),
|
|
42
|
-
},
|
|
43
|
-
rate_limiter: {
|
|
44
|
-
enabled: env_1.default['RATE_LIMITER_ENABLED'],
|
|
45
|
-
points: +env_1.default['RATE_LIMITER_POINTS'],
|
|
46
|
-
duration: +env_1.default['RATE_LIMITER_DURATION'],
|
|
47
|
-
store: env_1.default['RATE_LIMITER_STORE'],
|
|
48
|
-
},
|
|
49
|
-
cache: {
|
|
50
|
-
enabled: env_1.default['CACHE_ENABLED'],
|
|
51
|
-
ttl: (0, get_milliseconds_1.getMilliseconds)(env_1.default['CACHE_TTL']),
|
|
52
|
-
store: env_1.default['CACHE_STORE'],
|
|
53
|
-
},
|
|
54
|
-
storage: {
|
|
55
|
-
drivers: getStorageDrivers(),
|
|
56
|
-
},
|
|
57
|
-
cors: {
|
|
58
|
-
enabled: env_1.default['CORS_ENABLED'],
|
|
59
|
-
},
|
|
60
|
-
email: {
|
|
61
|
-
transport: env_1.default['EMAIL_TRANSPORT'],
|
|
62
|
-
},
|
|
63
|
-
auth: {
|
|
64
|
-
providers: (0, utils_1.toArray)(env_1.default['AUTH_PROVIDERS'])
|
|
65
|
-
.map((v) => v.trim())
|
|
66
|
-
.filter((v) => v),
|
|
67
|
-
},
|
|
68
|
-
db_client: env_1.default['DB_CLIENT'],
|
|
69
|
-
};
|
|
70
|
-
}
|
|
71
|
-
function getStorageDrivers() {
|
|
72
|
-
const drivers = [];
|
|
73
|
-
const locations = (0, utils_1.toArray)(env_1.default['STORAGE_LOCATIONS'])
|
|
74
|
-
.map((v) => v.trim())
|
|
75
|
-
.filter((v) => v);
|
|
76
|
-
for (const location of locations) {
|
|
77
|
-
const driver = env_1.default[`STORAGE_${location.toUpperCase()}_DRIVER`];
|
|
78
|
-
drivers.push(driver);
|
|
79
|
-
}
|
|
80
|
-
return drivers;
|
|
81
|
-
}
|