directus 9.23.3 → 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 +15 -15
- package/dist/auth/drivers/ldap.js +22 -22
- package/dist/auth/drivers/local.js +7 -7
- package/dist/auth/drivers/oauth2.js +27 -25
- package/dist/auth/drivers/openid.js +32 -30
- package/dist/auth/drivers/saml.js +10 -10
- package/dist/auth.js +4 -3
- package/dist/cache.js +16 -11
- package/dist/cli/commands/bootstrap/index.js +5 -4
- package/dist/cli/utils/create-db-connection.js +1 -1
- package/dist/cli/utils/create-env/index.js +1 -1
- package/dist/constants.d.ts +1 -0
- package/dist/constants.js +6 -5
- package/dist/controllers/activity.js +10 -10
- package/dist/controllers/assets.js +19 -18
- package/dist/controllers/auth.js +16 -16
- package/dist/controllers/collections.js +11 -11
- package/dist/controllers/dashboards.js +11 -11
- package/dist/controllers/extensions.js +3 -3
- package/dist/controllers/fields.js +17 -17
- package/dist/controllers/files.js +18 -17
- package/dist/controllers/flows.js +13 -13
- package/dist/controllers/folders.js +11 -11
- package/dist/controllers/graphql.js +6 -6
- package/dist/controllers/items.js +19 -19
- package/dist/controllers/notifications.js +11 -11
- package/dist/controllers/operations.js +11 -11
- package/dist/controllers/panels.js +11 -11
- package/dist/controllers/permissions.js +11 -11
- package/dist/controllers/presets.js +11 -11
- package/dist/controllers/relations.js +11 -11
- package/dist/controllers/revisions.js +3 -3
- package/dist/controllers/roles.js +11 -11
- package/dist/controllers/schema.js +5 -5
- package/dist/controllers/server.js +7 -7
- package/dist/controllers/settings.js +2 -2
- package/dist/controllers/shares.js +14 -14
- package/dist/controllers/users.js +16 -16
- package/dist/controllers/utils.js +7 -7
- package/dist/controllers/webhooks.js +11 -11
- package/dist/database/helpers/fn/types.d.ts +0 -1
- package/dist/database/helpers/fn/types.js +0 -2
- package/dist/database/helpers/index.d.ts +3 -3
- package/dist/database/index.js +5 -5
- package/dist/database/migrations/20210805B-change-image-metadata-structure.js +15 -15
- package/dist/database/migrations/run.js +1 -1
- package/dist/database/run-ast.js +6 -6
- package/dist/database/system-data/collections/index.js +2 -2
- package/dist/database/system-data/fields/index.js +3 -3
- package/dist/env.js +1 -1
- 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/extensions.js +10 -10
- package/dist/flows.js +33 -31
- package/dist/logger.d.ts +1 -0
- package/dist/logger.js +32 -32
- package/dist/mailer.js +16 -16
- package/dist/messenger.js +4 -4
- package/dist/middleware/authenticate.d.ts +1 -1
- package/dist/middleware/authenticate.js +2 -2
- package/dist/middleware/cache.js +11 -11
- package/dist/middleware/collection-exists.js +4 -4
- package/dist/middleware/cors.js +8 -8
- package/dist/middleware/error-handler.js +2 -2
- package/dist/middleware/extract-token.js +3 -3
- package/dist/middleware/get-permissions.js +1 -1
- package/dist/middleware/graphql.js +12 -6
- package/dist/middleware/rate-limiter-global.js +5 -5
- package/dist/middleware/rate-limiter-ip.js +2 -2
- package/dist/middleware/respond.js +16 -16
- package/dist/middleware/sanitize-query.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/operations/exec/index.js +2 -2
- package/dist/rate-limiter.js +1 -1
- package/dist/request/validate-ip.js +2 -2
- package/dist/server.js +4 -4
- package/dist/services/activity.js +14 -14
- package/dist/services/assets.js +6 -6
- package/dist/services/authentication.js +9 -9
- package/dist/services/collections.js +9 -9
- package/dist/services/fields.js +5 -5
- package/dist/services/files.js +18 -18
- package/dist/services/graphql/index.js +170 -116
- package/dist/services/import-export.js +6 -6
- package/dist/services/items.js +6 -6
- package/dist/services/mail/index.js +5 -5
- package/dist/services/meta.js +1 -0
- package/dist/services/notifications.js +4 -4
- package/dist/services/relations.js +4 -4
- package/dist/services/revisions.js +3 -3
- package/dist/services/roles.js +5 -5
- package/dist/services/server.js +27 -27
- package/dist/services/shares.js +9 -9
- package/dist/services/specifications.js +5 -3
- package/dist/services/users.d.ts +1 -5
- package/dist/services/users.js +24 -27
- package/dist/storage/register-locations.js +1 -1
- package/dist/utils/apply-diff.js +12 -12
- package/dist/utils/apply-query.js +3 -2
- package/dist/utils/dynamic-import.js +1 -1
- package/dist/utils/generate-hash.js +1 -1
- package/dist/utils/get-ast-from-query.js +2 -2
- package/dist/utils/get-auth-providers.js +1 -1
- package/dist/utils/get-cache-headers.js +3 -3
- package/dist/utils/get-collection-from-alias.js +1 -0
- package/dist/utils/get-column-path.js +2 -1
- package/dist/utils/get-default-value.js +1 -1
- package/dist/utils/get-ip-from-req.js +2 -2
- package/dist/utils/get-permissions.js +11 -11
- package/dist/utils/get-schema.js +5 -5
- package/dist/utils/get-snapshot-diff.js +1 -1
- package/dist/utils/is-url-allowed.js +5 -2
- package/dist/utils/parse-image-metadata.js +3 -3
- package/dist/utils/reduce-schema.js +5 -5
- package/dist/utils/sanitize-query.js +26 -26
- package/dist/utils/should-skip-cache.js +13 -4
- 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/dist/utils/validate-query.js +1 -1
- package/dist/utils/validate-storage.js +8 -8
- package/dist/webhooks.js +2 -2
- package/package.json +13 -13
- package/dist/utils/redact-header-cookies.d.ts +0 -1
- package/dist/utils/redact-header-cookies.js +0 -11
- package/dist/utils/track.d.ts +0 -1
- package/dist/utils/track.js +0 -81
- /package/dist/{utils/redact-header-cookies.test.d.ts → logger.test.d.ts} +0 -0
|
@@ -182,20 +182,20 @@ class ExportService {
|
|
|
182
182
|
count: ['*'],
|
|
183
183
|
},
|
|
184
184
|
})
|
|
185
|
-
.then((result) => Number(result?.[0]?.count ?? 0));
|
|
185
|
+
.then((result) => Number(result?.[0]?.['count'] ?? 0));
|
|
186
186
|
const count = query.limit ? Math.min(totalCount, query.limit) : totalCount;
|
|
187
187
|
const requestedLimit = query.limit ?? -1;
|
|
188
|
-
const batchesRequired = Math.ceil(count / env_1.default
|
|
188
|
+
const batchesRequired = Math.ceil(count / env_1.default['EXPORT_BATCH_SIZE']);
|
|
189
189
|
let readCount = 0;
|
|
190
190
|
for (let batch = 0; batch < batchesRequired; batch++) {
|
|
191
|
-
let limit = env_1.default
|
|
192
|
-
if (requestedLimit > 0 && env_1.default
|
|
191
|
+
let limit = env_1.default['EXPORT_BATCH_SIZE'];
|
|
192
|
+
if (requestedLimit > 0 && env_1.default['EXPORT_BATCH_SIZE'] > requestedLimit - readCount) {
|
|
193
193
|
limit = requestedLimit - readCount;
|
|
194
194
|
}
|
|
195
195
|
const result = await service.readByQuery({
|
|
196
196
|
...query,
|
|
197
197
|
limit,
|
|
198
|
-
offset: batch * env_1.default
|
|
198
|
+
offset: batch * env_1.default['EXPORT_BATCH_SIZE'],
|
|
199
199
|
});
|
|
200
200
|
readCount += result.length;
|
|
201
201
|
if (result.length) {
|
|
@@ -210,7 +210,7 @@ class ExportService {
|
|
|
210
210
|
accountability: this.accountability,
|
|
211
211
|
schema: this.schema,
|
|
212
212
|
});
|
|
213
|
-
const storage = (0, utils_1.toArray)(env_1.default
|
|
213
|
+
const storage = (0, utils_1.toArray)(env_1.default['STORAGE_LOCATIONS'])[0];
|
|
214
214
|
const title = `export-${collection}-${(0, get_date_formatted_1.getDateFormatted)()}`;
|
|
215
215
|
const filename = `${title}.${format}`;
|
|
216
216
|
const fileWithDefaults = {
|
package/dist/services/items.js
CHANGED
|
@@ -205,7 +205,7 @@ class ItemsService {
|
|
|
205
205
|
}
|
|
206
206
|
}
|
|
207
207
|
}
|
|
208
|
-
if (this.cache && env_1.default
|
|
208
|
+
if (this.cache && env_1.default['CACHE_AUTO_PURGE'] && opts?.autoPurgeCache !== false) {
|
|
209
209
|
await this.cache.clear();
|
|
210
210
|
}
|
|
211
211
|
return primaryKey;
|
|
@@ -242,7 +242,7 @@ class ItemsService {
|
|
|
242
242
|
}
|
|
243
243
|
}
|
|
244
244
|
}
|
|
245
|
-
if (this.cache && env_1.default
|
|
245
|
+
if (this.cache && env_1.default['CACHE_AUTO_PURGE'] && opts?.autoPurgeCache !== false) {
|
|
246
246
|
await this.cache.clear();
|
|
247
247
|
}
|
|
248
248
|
return primaryKeys;
|
|
@@ -381,7 +381,7 @@ class ItemsService {
|
|
|
381
381
|
});
|
|
382
382
|
}
|
|
383
383
|
finally {
|
|
384
|
-
if (this.cache && env_1.default
|
|
384
|
+
if (this.cache && env_1.default['CACHE_AUTO_PURGE'] && opts?.autoPurgeCache !== false) {
|
|
385
385
|
await this.cache.clear();
|
|
386
386
|
}
|
|
387
387
|
}
|
|
@@ -506,7 +506,7 @@ class ItemsService {
|
|
|
506
506
|
}
|
|
507
507
|
}
|
|
508
508
|
});
|
|
509
|
-
if (this.cache && env_1.default
|
|
509
|
+
if (this.cache && env_1.default['CACHE_AUTO_PURGE'] && opts?.autoPurgeCache !== false) {
|
|
510
510
|
await this.cache.clear();
|
|
511
511
|
}
|
|
512
512
|
if (opts?.emitEvents !== false) {
|
|
@@ -581,7 +581,7 @@ class ItemsService {
|
|
|
581
581
|
}
|
|
582
582
|
return primaryKeys;
|
|
583
583
|
});
|
|
584
|
-
if (this.cache && env_1.default
|
|
584
|
+
if (this.cache && env_1.default['CACHE_AUTO_PURGE'] && opts?.autoPurgeCache !== false) {
|
|
585
585
|
await this.cache.clear();
|
|
586
586
|
}
|
|
587
587
|
return primaryKeys;
|
|
@@ -648,7 +648,7 @@ class ItemsService {
|
|
|
648
648
|
})));
|
|
649
649
|
}
|
|
650
650
|
});
|
|
651
|
-
if (this.cache && env_1.default
|
|
651
|
+
if (this.cache && env_1.default['CACHE_AUTO_PURGE'] && opts?.autoPurgeCache !== false) {
|
|
652
652
|
await this.cache.clear();
|
|
653
653
|
}
|
|
654
654
|
if (opts?.emitEvents !== false) {
|
|
@@ -14,7 +14,7 @@ const logger_1 = __importDefault(require("../../logger"));
|
|
|
14
14
|
const mailer_1 = __importDefault(require("../../mailer"));
|
|
15
15
|
const url_1 = require("../../utils/url");
|
|
16
16
|
const liquidEngine = new liquidjs_1.Liquid({
|
|
17
|
-
root: [path_1.default.resolve(env_1.default
|
|
17
|
+
root: [path_1.default.resolve(env_1.default['EXTENSIONS_PATH'], 'templates'), path_1.default.resolve(__dirname, 'templates')],
|
|
18
18
|
extname: '.liquid',
|
|
19
19
|
});
|
|
20
20
|
class MailService {
|
|
@@ -27,7 +27,7 @@ class MailService {
|
|
|
27
27
|
this.accountability = opts.accountability || null;
|
|
28
28
|
this.knex = opts?.knex || (0, database_1.default)();
|
|
29
29
|
this.mailer = (0, mailer_1.default)();
|
|
30
|
-
if (env_1.default
|
|
30
|
+
if (env_1.default['EMAIL_VERIFY_SETUP']) {
|
|
31
31
|
this.mailer.verify((error) => {
|
|
32
32
|
if (error) {
|
|
33
33
|
logger_1.default.warn(`Email connection failed:`);
|
|
@@ -40,7 +40,7 @@ class MailService {
|
|
|
40
40
|
const { template, ...emailOptions } = options;
|
|
41
41
|
let { html } = options;
|
|
42
42
|
const defaultTemplateData = await this.getDefaultTemplateData();
|
|
43
|
-
const from = `${defaultTemplateData.projectName} <${options.from || env_1.default
|
|
43
|
+
const from = `${defaultTemplateData.projectName} <${options.from || env_1.default['EMAIL_FROM']}>`;
|
|
44
44
|
if (template) {
|
|
45
45
|
let templateData = template.data;
|
|
46
46
|
templateData = {
|
|
@@ -60,7 +60,7 @@ class MailService {
|
|
|
60
60
|
return info;
|
|
61
61
|
}
|
|
62
62
|
async renderTemplate(template, variables) {
|
|
63
|
-
const customTemplatePath = path_1.default.resolve(env_1.default
|
|
63
|
+
const customTemplatePath = path_1.default.resolve(env_1.default['EXTENSIONS_PATH'], 'templates', template + '.liquid');
|
|
64
64
|
const systemTemplatePath = path_1.default.join(__dirname, 'templates', template + '.liquid');
|
|
65
65
|
const templatePath = (await fs_extra_1.default.pathExists(customTemplatePath)) ? customTemplatePath : systemTemplatePath;
|
|
66
66
|
if ((await fs_extra_1.default.pathExists(templatePath)) === false) {
|
|
@@ -82,7 +82,7 @@ class MailService {
|
|
|
82
82
|
projectUrl: projectInfo?.project_url || '',
|
|
83
83
|
};
|
|
84
84
|
function getProjectLogoURL(logoID) {
|
|
85
|
-
const projectLogoUrl = new url_1.Url(env_1.default
|
|
85
|
+
const projectLogoUrl = new url_1.Url(env_1.default['PUBLIC_URL']);
|
|
86
86
|
if (logoID) {
|
|
87
87
|
projectLogoUrl.addPath('assets', logoID);
|
|
88
88
|
}
|
package/dist/services/meta.js
CHANGED
|
@@ -36,16 +36,16 @@ class NotificationsService extends items_1.ItemsService {
|
|
|
36
36
|
const user = await this.usersService.readOne(data.recipient, {
|
|
37
37
|
fields: ['id', 'email', 'email_notifications', 'role.app_access'],
|
|
38
38
|
});
|
|
39
|
-
const manageUserAccountUrl = new url_1.Url(env_1.default
|
|
39
|
+
const manageUserAccountUrl = new url_1.Url(env_1.default['PUBLIC_URL']).addPath('admin', 'users', user['id']).toString();
|
|
40
40
|
const html = data.message ? (0, md_1.md)(data.message) : '';
|
|
41
|
-
if (user
|
|
41
|
+
if (user['email'] && user['email_notifications'] === true) {
|
|
42
42
|
try {
|
|
43
43
|
await this.mailService.send({
|
|
44
44
|
template: {
|
|
45
45
|
name: 'base',
|
|
46
|
-
data: user
|
|
46
|
+
data: user['role']?.app_access ? { url: manageUserAccountUrl, html } : { html },
|
|
47
47
|
},
|
|
48
|
-
to: user
|
|
48
|
+
to: user['email'],
|
|
49
49
|
subject: data.subject,
|
|
50
50
|
});
|
|
51
51
|
}
|
|
@@ -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;
|
|
@@ -11,14 +11,14 @@ class RevisionsService extends index_1.ItemsService {
|
|
|
11
11
|
const revision = await super.readOne(pk);
|
|
12
12
|
if (!revision)
|
|
13
13
|
throw new exceptions_1.ForbiddenException();
|
|
14
|
-
if (!revision
|
|
14
|
+
if (!revision['data'])
|
|
15
15
|
throw new exceptions_1.InvalidPayloadException(`Revision doesn't contain data to revert to`);
|
|
16
|
-
const service = new index_1.ItemsService(revision
|
|
16
|
+
const service = new index_1.ItemsService(revision['collection'], {
|
|
17
17
|
accountability: this.accountability,
|
|
18
18
|
knex: this.knex,
|
|
19
19
|
schema: this.schema,
|
|
20
20
|
});
|
|
21
|
-
await service.updateOne(revision
|
|
21
|
+
await service.updateOne(revision['item'], revision['data']);
|
|
22
22
|
}
|
|
23
23
|
}
|
|
24
24
|
exports.RevisionsService = RevisionsService;
|
package/dist/services/roles.js
CHANGED
|
@@ -29,10 +29,10 @@ class RolesService extends items_1.ItemsService {
|
|
|
29
29
|
// The users that will now be in this new non-admin role
|
|
30
30
|
let userKeys = [];
|
|
31
31
|
if (Array.isArray(users)) {
|
|
32
|
-
userKeys = users.map((user) => (typeof user === 'string' ? user : user
|
|
32
|
+
userKeys = users.map((user) => (typeof user === 'string' ? user : user['id'])).filter((id) => id);
|
|
33
33
|
}
|
|
34
34
|
else {
|
|
35
|
-
userKeys = users.update.map((user) => user
|
|
35
|
+
userKeys = users.update.map((user) => user['id']).filter((id) => id);
|
|
36
36
|
}
|
|
37
37
|
const usersThatWereInRoleBefore = (await this.knex.select('id').from('directus_users').where('role', '=', key)).map((user) => user.id);
|
|
38
38
|
const usersThatAreRemoved = usersThatWereInRoleBefore.filter((id) => Array.isArray(users) ? userKeys.includes(id) === false : users.delete.includes(id) === true);
|
|
@@ -58,7 +58,7 @@ class RolesService extends items_1.ItemsService {
|
|
|
58
58
|
async updateOne(key, data, opts) {
|
|
59
59
|
try {
|
|
60
60
|
if ('users' in data) {
|
|
61
|
-
await this.checkForOtherAdminUsers(key, data
|
|
61
|
+
await this.checkForOtherAdminUsers(key, data['users']);
|
|
62
62
|
}
|
|
63
63
|
}
|
|
64
64
|
catch (err) {
|
|
@@ -69,7 +69,7 @@ class RolesService extends items_1.ItemsService {
|
|
|
69
69
|
async updateBatch(data, opts) {
|
|
70
70
|
const primaryKeyField = this.schema.collections[this.collection].primary;
|
|
71
71
|
const keys = data.map((item) => item[primaryKeyField]);
|
|
72
|
-
const setsToNoAdmin = data.some((item) => item
|
|
72
|
+
const setsToNoAdmin = data.some((item) => item['admin_access'] === false);
|
|
73
73
|
try {
|
|
74
74
|
if (setsToNoAdmin) {
|
|
75
75
|
await this.checkForOtherAdminRoles(keys);
|
|
@@ -82,7 +82,7 @@ class RolesService extends items_1.ItemsService {
|
|
|
82
82
|
}
|
|
83
83
|
async updateMany(keys, data, opts) {
|
|
84
84
|
try {
|
|
85
|
-
if ('admin_access' in data && data
|
|
85
|
+
if ('admin_access' in data && data['admin_access'] === false) {
|
|
86
86
|
await this.checkForOtherAdminRoles(keys);
|
|
87
87
|
}
|
|
88
88
|
}
|
package/dist/services/server.js
CHANGED
|
@@ -70,40 +70,40 @@ class ServerService {
|
|
|
70
70
|
'custom_css',
|
|
71
71
|
],
|
|
72
72
|
});
|
|
73
|
-
info
|
|
73
|
+
info['project'] = projectInfo;
|
|
74
74
|
if (this.accountability?.user) {
|
|
75
|
-
if (env_1.default
|
|
76
|
-
info
|
|
77
|
-
points: env_1.default
|
|
78
|
-
duration: env_1.default
|
|
75
|
+
if (env_1.default['RATE_LIMITER_ENABLED']) {
|
|
76
|
+
info['rateLimit'] = {
|
|
77
|
+
points: env_1.default['RATE_LIMITER_POINTS'],
|
|
78
|
+
duration: env_1.default['RATE_LIMITER_DURATION'],
|
|
79
79
|
};
|
|
80
80
|
}
|
|
81
81
|
else {
|
|
82
|
-
info
|
|
82
|
+
info['rateLimit'] = false;
|
|
83
83
|
}
|
|
84
|
-
if (env_1.default
|
|
85
|
-
info
|
|
86
|
-
points: env_1.default
|
|
87
|
-
duration: env_1.default
|
|
84
|
+
if (env_1.default['RATE_LIMITER_GLOBAL_ENABLED']) {
|
|
85
|
+
info['rateLimitGlobal'] = {
|
|
86
|
+
points: env_1.default['RATE_LIMITER_GLOBAL_POINTS'],
|
|
87
|
+
duration: env_1.default['RATE_LIMITER_GLOBAL_DURATION'],
|
|
88
88
|
};
|
|
89
89
|
}
|
|
90
90
|
else {
|
|
91
|
-
info
|
|
91
|
+
info['rateLimitGlobal'] = false;
|
|
92
92
|
}
|
|
93
|
-
info
|
|
94
|
-
execAllowedModules: env_1.default
|
|
93
|
+
info['flows'] = {
|
|
94
|
+
execAllowedModules: env_1.default['FLOWS_EXEC_ALLOWED_MODULES'] ? (0, utils_1.toArray)(env_1.default['FLOWS_EXEC_ALLOWED_MODULES']) : [],
|
|
95
95
|
};
|
|
96
96
|
}
|
|
97
97
|
if (this.accountability?.admin === true) {
|
|
98
98
|
const { osType, osVersion } = (0, get_os_info_1.getOSInfo)();
|
|
99
|
-
info
|
|
99
|
+
info['directus'] = {
|
|
100
100
|
version: package_json_1.version,
|
|
101
101
|
};
|
|
102
|
-
info
|
|
102
|
+
info['node'] = {
|
|
103
103
|
version: process.versions.node,
|
|
104
104
|
uptime: Math.round(process.uptime()),
|
|
105
105
|
};
|
|
106
|
-
info
|
|
106
|
+
info['os'] = {
|
|
107
107
|
type: osType,
|
|
108
108
|
version: osVersion,
|
|
109
109
|
uptime: Math.round(os_1.default.uptime()),
|
|
@@ -118,7 +118,7 @@ class ServerService {
|
|
|
118
118
|
const data = {
|
|
119
119
|
status: 'ok',
|
|
120
120
|
releaseId: package_json_1.version,
|
|
121
|
-
serviceId: env_1.default
|
|
121
|
+
serviceId: env_1.default['KEY'],
|
|
122
122
|
checks: (0, lodash_1.merge)(...(await Promise.all([
|
|
123
123
|
testDatabase(),
|
|
124
124
|
testCache(),
|
|
@@ -153,7 +153,7 @@ class ServerService {
|
|
|
153
153
|
}
|
|
154
154
|
async function testDatabase() {
|
|
155
155
|
const database = (0, database_1.default)();
|
|
156
|
-
const client = env_1.default
|
|
156
|
+
const client = env_1.default['DB_CLIENT'];
|
|
157
157
|
const checks = {};
|
|
158
158
|
// Response time
|
|
159
159
|
// ----------------------------------------------------------------------------------------
|
|
@@ -163,7 +163,7 @@ class ServerService {
|
|
|
163
163
|
componentType: 'datastore',
|
|
164
164
|
observedUnit: 'ms',
|
|
165
165
|
observedValue: 0,
|
|
166
|
-
threshold: env_1.default
|
|
166
|
+
threshold: env_1.default['DB_HEALTHCHECK_THRESHOLD'] ? +env_1.default['DB_HEALTHCHECK_THRESHOLD'] : 150,
|
|
167
167
|
},
|
|
168
168
|
];
|
|
169
169
|
const startTime = perf_hooks_1.performance.now();
|
|
@@ -197,7 +197,7 @@ class ServerService {
|
|
|
197
197
|
return checks;
|
|
198
198
|
}
|
|
199
199
|
async function testCache() {
|
|
200
|
-
if (env_1.default
|
|
200
|
+
if (env_1.default['CACHE_ENABLED'] !== true) {
|
|
201
201
|
return {};
|
|
202
202
|
}
|
|
203
203
|
const { cache } = (0, cache_1.getCache)();
|
|
@@ -208,7 +208,7 @@ class ServerService {
|
|
|
208
208
|
componentType: 'cache',
|
|
209
209
|
observedValue: 0,
|
|
210
210
|
observedUnit: 'ms',
|
|
211
|
-
threshold: env_1.default
|
|
211
|
+
threshold: env_1.default['CACHE_HEALTHCHECK_THRESHOLD'] ? +env_1.default['CACHE_HEALTHCHECK_THRESHOLD'] : 150,
|
|
212
212
|
},
|
|
213
213
|
],
|
|
214
214
|
};
|
|
@@ -232,7 +232,7 @@ class ServerService {
|
|
|
232
232
|
return checks;
|
|
233
233
|
}
|
|
234
234
|
async function testRateLimiter() {
|
|
235
|
-
if (env_1.default
|
|
235
|
+
if (env_1.default['RATE_LIMITER_ENABLED'] !== true) {
|
|
236
236
|
return {};
|
|
237
237
|
}
|
|
238
238
|
const checks = {
|
|
@@ -242,7 +242,7 @@ class ServerService {
|
|
|
242
242
|
componentType: 'ratelimiter',
|
|
243
243
|
observedValue: 0,
|
|
244
244
|
observedUnit: 'ms',
|
|
245
|
-
threshold: env_1.default
|
|
245
|
+
threshold: env_1.default['RATE_LIMITER_HEALTHCHECK_THRESHOLD'] ? +env_1.default['RATE_LIMITER_HEALTHCHECK_THRESHOLD'] : 150,
|
|
246
246
|
},
|
|
247
247
|
],
|
|
248
248
|
};
|
|
@@ -266,7 +266,7 @@ class ServerService {
|
|
|
266
266
|
return checks;
|
|
267
267
|
}
|
|
268
268
|
async function testRateLimiterGlobal() {
|
|
269
|
-
if (env_1.default
|
|
269
|
+
if (env_1.default['RATE_LIMITER_GLOBAL_ENABLED'] !== true) {
|
|
270
270
|
return {};
|
|
271
271
|
}
|
|
272
272
|
const checks = {
|
|
@@ -276,8 +276,8 @@ class ServerService {
|
|
|
276
276
|
componentType: 'ratelimiter',
|
|
277
277
|
observedValue: 0,
|
|
278
278
|
observedUnit: 'ms',
|
|
279
|
-
threshold: env_1.default
|
|
280
|
-
? +env_1.default
|
|
279
|
+
threshold: env_1.default['RATE_LIMITER_GLOBAL_HEALTHCHECK_THRESHOLD']
|
|
280
|
+
? +env_1.default['RATE_LIMITER_GLOBAL_HEALTHCHECK_THRESHOLD']
|
|
281
281
|
: 150,
|
|
282
282
|
},
|
|
283
283
|
],
|
|
@@ -305,7 +305,7 @@ class ServerService {
|
|
|
305
305
|
async function testStorage() {
|
|
306
306
|
const storage = await (0, storage_1.getStorage)();
|
|
307
307
|
const checks = {};
|
|
308
|
-
for (const location of (0, utils_1.toArray)(env_1.default
|
|
308
|
+
for (const location of (0, utils_1.toArray)(env_1.default['STORAGE_LOCATIONS'])) {
|
|
309
309
|
const disk = storage.location(location);
|
|
310
310
|
const envThresholdKey = `STORAGE_${location}_HEALTHCHECK_THRESHOLD`.toUpperCase();
|
|
311
311
|
checks[`storage:${location}:responseTime`] = [
|
package/dist/services/shares.js
CHANGED
|
@@ -27,7 +27,7 @@ class SharesService extends items_1.ItemsService {
|
|
|
27
27
|
});
|
|
28
28
|
}
|
|
29
29
|
async createOne(data, opts) {
|
|
30
|
-
await this.authorizationService.checkAccess('share', data
|
|
30
|
+
await this.authorizationService.checkAccess('share', data['collection'], data['item']);
|
|
31
31
|
return super.createOne(data, opts);
|
|
32
32
|
}
|
|
33
33
|
async login(payload) {
|
|
@@ -45,7 +45,7 @@ class SharesService extends items_1.ItemsService {
|
|
|
45
45
|
share_password: 'password',
|
|
46
46
|
})
|
|
47
47
|
.from('directus_shares')
|
|
48
|
-
.where('id', payload
|
|
48
|
+
.where('id', payload['share'])
|
|
49
49
|
.andWhere((subQuery) => {
|
|
50
50
|
subQuery.whereNull('date_end').orWhere('date_end', '>=', new Date());
|
|
51
51
|
})
|
|
@@ -59,7 +59,7 @@ class SharesService extends items_1.ItemsService {
|
|
|
59
59
|
if (!record) {
|
|
60
60
|
throw new exceptions_1.InvalidCredentialsException();
|
|
61
61
|
}
|
|
62
|
-
if (record.share_password && !(await argon2_1.default.verify(record.share_password, payload
|
|
62
|
+
if (record.share_password && !(await argon2_1.default.verify(record.share_password, payload['password']))) {
|
|
63
63
|
throw new exceptions_1.InvalidCredentialsException();
|
|
64
64
|
}
|
|
65
65
|
await this.knex('directus_shares')
|
|
@@ -75,12 +75,12 @@ class SharesService extends items_1.ItemsService {
|
|
|
75
75
|
collection: record.share_collection,
|
|
76
76
|
},
|
|
77
77
|
};
|
|
78
|
-
const accessToken = jsonwebtoken_1.default.sign(tokenPayload, env_1.default
|
|
79
|
-
expiresIn: env_1.default
|
|
78
|
+
const accessToken = jsonwebtoken_1.default.sign(tokenPayload, env_1.default['SECRET'], {
|
|
79
|
+
expiresIn: env_1.default['ACCESS_TOKEN_TTL'],
|
|
80
80
|
issuer: 'directus',
|
|
81
81
|
});
|
|
82
82
|
const refreshToken = nanoid(64);
|
|
83
|
-
const refreshTokenExpiration = new Date(Date.now() + (0, get_milliseconds_1.getMilliseconds)(env_1.default
|
|
83
|
+
const refreshTokenExpiration = new Date(Date.now() + (0, get_milliseconds_1.getMilliseconds)(env_1.default['REFRESH_TOKEN_TTL'], 0));
|
|
84
84
|
await this.knex('directus_sessions').insert({
|
|
85
85
|
token: refreshToken,
|
|
86
86
|
expires: refreshTokenExpiration,
|
|
@@ -93,7 +93,7 @@ class SharesService extends items_1.ItemsService {
|
|
|
93
93
|
return {
|
|
94
94
|
accessToken,
|
|
95
95
|
refreshToken,
|
|
96
|
-
expires: (0, get_milliseconds_1.getMilliseconds)(env_1.default
|
|
96
|
+
expires: (0, get_milliseconds_1.getMilliseconds)(env_1.default['ACCESS_TOKEN_TTL']),
|
|
97
97
|
};
|
|
98
98
|
}
|
|
99
99
|
/**
|
|
@@ -115,9 +115,9 @@ class SharesService extends items_1.ItemsService {
|
|
|
115
115
|
const message = `
|
|
116
116
|
Hello!
|
|
117
117
|
|
|
118
|
-
${(0, user_name_1.userName)(userInfo)} has invited you to view an item in ${share
|
|
118
|
+
${(0, user_name_1.userName)(userInfo)} has invited you to view an item in ${share['collection']}.
|
|
119
119
|
|
|
120
|
-
[Open](${new url_1.Url(env_1.default
|
|
120
|
+
[Open](${new url_1.Url(env_1.default['PUBLIC_URL']).addPath('admin', 'shared', payload.share).toString()})
|
|
121
121
|
`;
|
|
122
122
|
for (const email of payload.emails) {
|
|
123
123
|
await mailService.send({
|
|
@@ -74,7 +74,7 @@ class OASSpecsService {
|
|
|
74
74
|
},
|
|
75
75
|
servers: [
|
|
76
76
|
{
|
|
77
|
-
url: env_1.default
|
|
77
|
+
url: env_1.default['PUBLIC_URL'],
|
|
78
78
|
description: 'Your current Directus instance.',
|
|
79
79
|
},
|
|
80
80
|
],
|
|
@@ -168,7 +168,7 @@ class OASSpecsService {
|
|
|
168
168
|
paths[`/items/${collection}`][method] = (0, lodash_1.mergeWith)((0, lodash_1.cloneDeep)(listBase[method]), {
|
|
169
169
|
description: listBase[method].description.replace('item', collection + ' item'),
|
|
170
170
|
tags: [tag.name],
|
|
171
|
-
parameters: 'parameters' in listBase ? this.filterCollectionFromParams(listBase
|
|
171
|
+
parameters: 'parameters' in listBase ? this.filterCollectionFromParams(listBase.parameters) : [],
|
|
172
172
|
operationId: `${this.getActionForMethod(method)}${tag.name}`,
|
|
173
173
|
requestBody: ['get', 'delete'].includes(method)
|
|
174
174
|
? undefined
|
|
@@ -213,6 +213,7 @@ class OASSpecsService {
|
|
|
213
213
|
}, (obj, src) => {
|
|
214
214
|
if (Array.isArray(obj))
|
|
215
215
|
return obj.concat(src);
|
|
216
|
+
return undefined;
|
|
216
217
|
});
|
|
217
218
|
}
|
|
218
219
|
if (detailBase[method]) {
|
|
@@ -220,7 +221,7 @@ class OASSpecsService {
|
|
|
220
221
|
description: detailBase[method].description.replace('item', collection + ' item'),
|
|
221
222
|
tags: [tag.name],
|
|
222
223
|
operationId: `${this.getActionForMethod(method)}Single${tag.name}`,
|
|
223
|
-
parameters: 'parameters' in detailBase ? this.filterCollectionFromParams(detailBase
|
|
224
|
+
parameters: 'parameters' in detailBase ? this.filterCollectionFromParams(detailBase.parameters) : [],
|
|
224
225
|
requestBody: ['get', 'delete'].includes(method)
|
|
225
226
|
? undefined
|
|
226
227
|
: {
|
|
@@ -252,6 +253,7 @@ class OASSpecsService {
|
|
|
252
253
|
}, (obj, src) => {
|
|
253
254
|
if (Array.isArray(obj))
|
|
254
255
|
return obj.concat(src);
|
|
256
|
+
return undefined;
|
|
255
257
|
});
|
|
256
258
|
}
|
|
257
259
|
}
|
package/dist/services/users.d.ts
CHANGED
|
@@ -1,11 +1,7 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type { Knex } from 'knex';
|
|
1
|
+
import type { Query } from '@directus/shared/types';
|
|
3
2
|
import type { AbstractServiceOptions, Item, MutationOptions, PrimaryKey } from '../types';
|
|
4
3
|
import { ItemsService } from './items';
|
|
5
4
|
export declare class UsersService extends ItemsService {
|
|
6
|
-
knex: Knex;
|
|
7
|
-
accountability: Accountability | null;
|
|
8
|
-
schema: SchemaOverview;
|
|
9
5
|
constructor(options: AbstractServiceOptions);
|
|
10
6
|
/**
|
|
11
7
|
* User email has to be unique case-insensitive. This is an additional check to make sure that
|