directus 9.23.3 → 9.23.4
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 +12 -12
- 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 +9 -9
- package/dist/controllers/assets.js +19 -18
- package/dist/controllers/auth.js +13 -13
- package/dist/controllers/collections.js +10 -10
- package/dist/controllers/dashboards.js +9 -9
- package/dist/controllers/extensions.js +3 -3
- package/dist/controllers/fields.js +16 -16
- package/dist/controllers/files.js +16 -15
- package/dist/controllers/flows.js +11 -11
- package/dist/controllers/folders.js +9 -9
- package/dist/controllers/graphql.js +6 -6
- package/dist/controllers/items.js +17 -17
- package/dist/controllers/notifications.js +9 -9
- package/dist/controllers/operations.js +9 -9
- package/dist/controllers/panels.js +9 -9
- package/dist/controllers/permissions.js +9 -9
- package/dist/controllers/presets.js +9 -9
- package/dist/controllers/relations.js +10 -10
- package/dist/controllers/revisions.js +3 -3
- package/dist/controllers/roles.js +9 -9
- 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 +13 -13
- package/dist/controllers/users.js +16 -16
- package/dist/controllers/utils.js +5 -5
- package/dist/controllers/webhooks.js +9 -9
- 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 +4 -4
- 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/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.js +1 -1
- package/dist/middleware/cache.js +11 -11
- package/dist/middleware/collection-exists.js +3 -3
- package/dist/middleware/cors.js +7 -7
- package/dist/middleware/error-handler.js +2 -2
- package/dist/middleware/extract-token.js +2 -2
- 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/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 +12 -12
- package/dist/services/graphql/index.js +100 -98
- 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/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-query.js +2 -1
- package/dist/utils/dynamic-import.js +1 -1
- package/dist/utils/generate-hash.js +1 -1
- package/dist/utils/get-ast-from-query.js +1 -1
- 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-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 +2 -2
- package/dist/utils/is-url-allowed.js +5 -2
- package/dist/utils/sanitize-query.js +26 -26
- package/dist/utils/should-skip-cache.js +2 -2
- package/dist/utils/track.js +16 -16
- 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/redact-header-cookies.test.d.ts → logger.test.d.ts} +0 -0
package/dist/cache.js
CHANGED
|
@@ -20,34 +20,37 @@ let sharedSchemaCache = null;
|
|
|
20
20
|
let lockCache = null;
|
|
21
21
|
let messengerSubscribed = false;
|
|
22
22
|
const messenger = (0, messenger_1.getMessenger)();
|
|
23
|
-
if (env_1.default
|
|
23
|
+
if (env_1.default['MESSENGER_STORE'] === 'redis' &&
|
|
24
|
+
env_1.default['CACHE_STORE'] === 'memory' &&
|
|
25
|
+
env_1.default['CACHE_AUTO_PURGE'] &&
|
|
26
|
+
!messengerSubscribed) {
|
|
24
27
|
messengerSubscribed = true;
|
|
25
28
|
messenger.subscribe('schemaChanged', async (opts) => {
|
|
26
|
-
if (cache && opts?.autoPurgeCache !== false) {
|
|
29
|
+
if (cache && opts?.['autoPurgeCache'] !== false) {
|
|
27
30
|
await cache.clear();
|
|
28
31
|
}
|
|
29
32
|
});
|
|
30
33
|
}
|
|
31
34
|
function getCache() {
|
|
32
|
-
if (env_1.default
|
|
35
|
+
if (env_1.default['CACHE_ENABLED'] === true && cache === null) {
|
|
33
36
|
(0, validate_env_1.validateEnv)(['CACHE_NAMESPACE', 'CACHE_TTL', 'CACHE_STORE']);
|
|
34
|
-
cache = getKeyvInstance(env_1.default
|
|
37
|
+
cache = getKeyvInstance(env_1.default['CACHE_STORE'], (0, get_milliseconds_1.getMilliseconds)(env_1.default['CACHE_TTL']));
|
|
35
38
|
cache.on('error', (err) => logger_1.default.warn(err, `[cache] ${err}`));
|
|
36
39
|
}
|
|
37
40
|
if (systemCache === null) {
|
|
38
|
-
systemCache = getKeyvInstance(env_1.default
|
|
41
|
+
systemCache = getKeyvInstance(env_1.default['CACHE_STORE'], (0, get_milliseconds_1.getMilliseconds)(env_1.default['CACHE_SYSTEM_TTL']), '_system');
|
|
39
42
|
systemCache.on('error', (err) => logger_1.default.warn(err, `[system-cache] ${err}`));
|
|
40
43
|
}
|
|
41
44
|
if (sharedSchemaCache === null) {
|
|
42
|
-
sharedSchemaCache = getKeyvInstance(env_1.default
|
|
45
|
+
sharedSchemaCache = getKeyvInstance(env_1.default['CACHE_STORE'], (0, get_milliseconds_1.getMilliseconds)(env_1.default['CACHE_SYSTEM_TTL']), '_schema_shared');
|
|
43
46
|
sharedSchemaCache.on('error', (err) => logger_1.default.warn(err, `[shared-schema-cache] ${err}`));
|
|
44
47
|
}
|
|
45
48
|
if (localSchemaCache === null) {
|
|
46
|
-
localSchemaCache = getKeyvInstance('memory', (0, get_milliseconds_1.getMilliseconds)(env_1.default
|
|
49
|
+
localSchemaCache = getKeyvInstance('memory', (0, get_milliseconds_1.getMilliseconds)(env_1.default['CACHE_SYSTEM_TTL']), '_schema');
|
|
47
50
|
localSchemaCache.on('error', (err) => logger_1.default.warn(err, `[schema-cache] ${err}`));
|
|
48
51
|
}
|
|
49
52
|
if (lockCache === null) {
|
|
50
|
-
lockCache = getKeyvInstance(env_1.default
|
|
53
|
+
lockCache = getKeyvInstance(env_1.default['CACHE_STORE'], undefined, '_lock');
|
|
51
54
|
lockCache.on('error', (err) => logger_1.default.warn(err, `[lock-cache] ${err}`));
|
|
52
55
|
}
|
|
53
56
|
return { cache, systemCache, sharedSchemaCache, localSchemaCache, lockCache };
|
|
@@ -128,18 +131,20 @@ function getKeyvInstance(store, ttl, namespaceSuffix) {
|
|
|
128
131
|
}
|
|
129
132
|
function getConfig(store = 'memory', ttl, namespaceSuffix = '') {
|
|
130
133
|
const config = {
|
|
131
|
-
namespace: `${env_1.default
|
|
134
|
+
namespace: `${env_1.default['CACHE_NAMESPACE']}${namespaceSuffix}`,
|
|
132
135
|
ttl,
|
|
133
136
|
};
|
|
134
137
|
if (store === 'redis') {
|
|
135
138
|
const KeyvRedis = require('@keyv/redis');
|
|
136
|
-
config.store = new KeyvRedis(env_1.default
|
|
139
|
+
config.store = new KeyvRedis(env_1.default['CACHE_REDIS'] || (0, get_config_from_env_1.getConfigFromEnv)('CACHE_REDIS_'));
|
|
137
140
|
}
|
|
138
141
|
if (store === 'memcache') {
|
|
139
142
|
const KeyvMemcache = require('keyv-memcache');
|
|
140
143
|
// keyv-memcache uses memjs which only accepts a comma separated string instead of an array,
|
|
141
144
|
// so we need to join array into a string when applicable. See #7986
|
|
142
|
-
const cacheMemcache = Array.isArray(env_1.default
|
|
145
|
+
const cacheMemcache = Array.isArray(env_1.default['CACHE_MEMCACHE'])
|
|
146
|
+
? env_1.default['CACHE_MEMCACHE'].join(',')
|
|
147
|
+
: env_1.default['CACHE_MEMCACHE'];
|
|
143
148
|
config.store = new KeyvMemcache(cacheMemcache);
|
|
144
149
|
}
|
|
145
150
|
return config;
|
|
@@ -50,9 +50,9 @@ async function bootstrap({ skipAdminInit }) {
|
|
|
50
50
|
else {
|
|
51
51
|
logger_1.default.info('Skipping creation of default Admin user and role...');
|
|
52
52
|
}
|
|
53
|
-
if (env_1.default
|
|
53
|
+
if (env_1.default['PROJECT_NAME'] && typeof env_1.default['PROJECT_NAME'] === 'string' && env_1.default['PROJECT_NAME'].length > 0) {
|
|
54
54
|
const settingsService = new services_1.SettingsService({ schema });
|
|
55
|
-
await settingsService.upsertSingleton({ project_name: env_1.default
|
|
55
|
+
await settingsService.upsertSingleton({ project_name: env_1.default['PROJECT_NAME'] });
|
|
56
56
|
}
|
|
57
57
|
}
|
|
58
58
|
else {
|
|
@@ -75,6 +75,7 @@ async function waitForDatabase(database) {
|
|
|
75
75
|
}
|
|
76
76
|
// This will throw and exit the process if the database is not available
|
|
77
77
|
await (0, database_1.validateDatabaseConnection)(database);
|
|
78
|
+
return database;
|
|
78
79
|
}
|
|
79
80
|
async function createDefaultAdmin(schema) {
|
|
80
81
|
const { nanoid } = await import('nanoid');
|
|
@@ -83,12 +84,12 @@ async function createDefaultAdmin(schema) {
|
|
|
83
84
|
const role = await rolesService.createOne(defaults_1.defaultAdminRole);
|
|
84
85
|
logger_1.default.info('Adding first admin user...');
|
|
85
86
|
const usersService = new services_1.UsersService({ schema });
|
|
86
|
-
let adminEmail = env_1.default
|
|
87
|
+
let adminEmail = env_1.default['ADMIN_EMAIL'];
|
|
87
88
|
if (!adminEmail) {
|
|
88
89
|
logger_1.default.info('No admin email provided. Defaulting to "admin@example.com"');
|
|
89
90
|
adminEmail = 'admin@example.com';
|
|
90
91
|
}
|
|
91
|
-
let adminPassword = env_1.default
|
|
92
|
+
let adminPassword = env_1.default['ADMIN_PASSWORD'];
|
|
92
93
|
if (!adminPassword) {
|
|
93
94
|
adminPassword = nanoid(12);
|
|
94
95
|
logger_1.default.info(`No admin password provided. Defaulting to "${adminPassword}"`);
|
|
@@ -25,7 +25,7 @@ function createDBConnection(client, credentials) {
|
|
|
25
25
|
};
|
|
26
26
|
if (client === 'pg' || client === 'cockroachdb') {
|
|
27
27
|
const { ssl } = credentials;
|
|
28
|
-
connection
|
|
28
|
+
connection.ssl = ssl;
|
|
29
29
|
}
|
|
30
30
|
if (client === 'mssql') {
|
|
31
31
|
const { options__encrypt } = credentials;
|
|
@@ -27,7 +27,7 @@ async function createEnv(client, credentials, directory) {
|
|
|
27
27
|
},
|
|
28
28
|
};
|
|
29
29
|
for (const [key, value] of Object.entries(credentials)) {
|
|
30
|
-
config
|
|
30
|
+
config['database'][`DB_${key.toUpperCase()}`] = value;
|
|
31
31
|
}
|
|
32
32
|
const configAsStrings = {};
|
|
33
33
|
for (const [key, value] of Object.entries(config)) {
|
package/dist/constants.d.ts
CHANGED
|
@@ -10,3 +10,4 @@ export declare const GENERATE_SPECIAL: string[];
|
|
|
10
10
|
export declare const UUID_REGEX = "[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}";
|
|
11
11
|
export declare const COOKIE_OPTIONS: CookieOptions;
|
|
12
12
|
export declare const OAS_REQUIRED_SCHEMAS: string[];
|
|
13
|
+
export declare const REDACT_TEXT = "--redact--";
|
package/dist/constants.js
CHANGED
|
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.OAS_REQUIRED_SCHEMAS = exports.COOKIE_OPTIONS = exports.UUID_REGEX = exports.GENERATE_SPECIAL = exports.COLUMN_TRANSFORMS = exports.DEFAULT_AUTH_PROVIDER = exports.ALIAS_TYPES = exports.FILTER_VARIABLES = exports.ASSET_TRANSFORM_QUERY_KEYS = exports.SYSTEM_ASSET_ALLOW_LIST = void 0;
|
|
6
|
+
exports.REDACT_TEXT = exports.OAS_REQUIRED_SCHEMAS = exports.COOKIE_OPTIONS = exports.UUID_REGEX = exports.GENERATE_SPECIAL = exports.COLUMN_TRANSFORMS = exports.DEFAULT_AUTH_PROVIDER = exports.ALIAS_TYPES = exports.FILTER_VARIABLES = exports.ASSET_TRANSFORM_QUERY_KEYS = exports.SYSTEM_ASSET_ALLOW_LIST = void 0;
|
|
7
7
|
const env_1 = __importDefault(require("./env"));
|
|
8
8
|
const get_milliseconds_1 = require("./utils/get-milliseconds");
|
|
9
9
|
exports.SYSTEM_ASSET_ALLOW_LIST = [
|
|
@@ -50,9 +50,10 @@ exports.GENERATE_SPECIAL = ['uuid', 'date-created', 'role-created', 'user-create
|
|
|
50
50
|
exports.UUID_REGEX = '[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}';
|
|
51
51
|
exports.COOKIE_OPTIONS = {
|
|
52
52
|
httpOnly: true,
|
|
53
|
-
domain: env_1.default
|
|
54
|
-
maxAge: (0, get_milliseconds_1.getMilliseconds)(env_1.default
|
|
55
|
-
secure: env_1.default
|
|
56
|
-
sameSite: env_1.default
|
|
53
|
+
domain: env_1.default['REFRESH_TOKEN_COOKIE_DOMAIN'],
|
|
54
|
+
maxAge: (0, get_milliseconds_1.getMilliseconds)(env_1.default['REFRESH_TOKEN_TTL']),
|
|
55
|
+
secure: env_1.default['REFRESH_TOKEN_COOKIE_SECURE'] ?? false,
|
|
56
|
+
sameSite: env_1.default['REFRESH_TOKEN_COOKIE_SAME_SITE'] || 'strict',
|
|
57
57
|
};
|
|
58
58
|
exports.OAS_REQUIRED_SCHEMAS = ['Diff', 'Schema', 'Query', 'x-metadata'];
|
|
59
|
+
exports.REDACT_TEXT = '--redact--';
|
|
@@ -35,7 +35,7 @@ const readHandler = (0, async_handler_1.default)(async (req, res, next) => {
|
|
|
35
35
|
result = await service.readByQuery(req.sanitizedQuery);
|
|
36
36
|
}
|
|
37
37
|
const meta = await metaService.getMetaForQuery('directus_activity', req.sanitizedQuery);
|
|
38
|
-
res.locals
|
|
38
|
+
res.locals['payload'] = {
|
|
39
39
|
data: result,
|
|
40
40
|
meta,
|
|
41
41
|
};
|
|
@@ -48,8 +48,8 @@ router.get('/:pk', (0, async_handler_1.default)(async (req, res, next) => {
|
|
|
48
48
|
accountability: req.accountability,
|
|
49
49
|
schema: req.schema,
|
|
50
50
|
});
|
|
51
|
-
const record = await service.readOne(req.params
|
|
52
|
-
res.locals
|
|
51
|
+
const record = await service.readOne(req.params['pk'], req.sanitizedQuery);
|
|
52
|
+
res.locals['payload'] = {
|
|
53
53
|
data: record || null,
|
|
54
54
|
};
|
|
55
55
|
return next();
|
|
@@ -78,7 +78,7 @@ router.post('/comment', (0, async_handler_1.default)(async (req, res, next) => {
|
|
|
78
78
|
});
|
|
79
79
|
try {
|
|
80
80
|
const record = await service.readOne(primaryKey, req.sanitizedQuery);
|
|
81
|
-
res.locals
|
|
81
|
+
res.locals['payload'] = {
|
|
82
82
|
data: record || null,
|
|
83
83
|
};
|
|
84
84
|
}
|
|
@@ -102,10 +102,10 @@ router.patch('/comment/:pk', (0, async_handler_1.default)(async (req, res, next)
|
|
|
102
102
|
if (error) {
|
|
103
103
|
throw new exceptions_1.InvalidPayloadException(error.message);
|
|
104
104
|
}
|
|
105
|
-
const primaryKey = await service.updateOne(req.params
|
|
105
|
+
const primaryKey = await service.updateOne(req.params['pk'], req.body);
|
|
106
106
|
try {
|
|
107
107
|
const record = await service.readOne(primaryKey, req.sanitizedQuery);
|
|
108
|
-
res.locals
|
|
108
|
+
res.locals['payload'] = {
|
|
109
109
|
data: record || null,
|
|
110
110
|
};
|
|
111
111
|
}
|
|
@@ -125,11 +125,11 @@ router.delete('/comment/:pk', (0, async_handler_1.default)(async (req, res, next
|
|
|
125
125
|
const adminService = new services_1.ActivityService({
|
|
126
126
|
schema: req.schema,
|
|
127
127
|
});
|
|
128
|
-
const item = await adminService.readOne(req.params
|
|
129
|
-
if (!item || item
|
|
128
|
+
const item = await adminService.readOne(req.params['pk'], { fields: ['action'] });
|
|
129
|
+
if (!item || item['action'] !== 'comment') {
|
|
130
130
|
throw new exceptions_1.ForbiddenException();
|
|
131
131
|
}
|
|
132
|
-
await service.deleteOne(req.params
|
|
132
|
+
await service.deleteOne(req.params['pk']);
|
|
133
133
|
return next();
|
|
134
134
|
}), respond_1.respond);
|
|
135
135
|
exports.default = router;
|
|
@@ -52,8 +52,8 @@ router.get('/:pk/:filename?',
|
|
|
52
52
|
throw new exceptions_1.InvalidQueryException(`"transforms" Parameter needs to be a JSON array of allowed transformations.`);
|
|
53
53
|
}
|
|
54
54
|
// Check against ASSETS_TRANSFORM_MAX_OPERATIONS
|
|
55
|
-
if (transforms.length > Number(env_1.default
|
|
56
|
-
throw new exceptions_1.InvalidQueryException(`"transforms" Parameter is only allowed ${env_1.default
|
|
55
|
+
if (transforms.length > Number(env_1.default['ASSETS_TRANSFORM_MAX_OPERATIONS'])) {
|
|
56
|
+
throw new exceptions_1.InvalidQueryException(`"transforms" Parameter is only allowed ${env_1.default['ASSETS_TRANSFORM_MAX_OPERATIONS']} transformations.`);
|
|
57
57
|
}
|
|
58
58
|
// Check the transformations are valid
|
|
59
59
|
transforms.forEach((transform) => {
|
|
@@ -62,33 +62,33 @@ router.get('/:pk/:filename?',
|
|
|
62
62
|
throw new exceptions_1.InvalidQueryException(`"transforms" Parameter does not allow "${name}" as a transformation.`);
|
|
63
63
|
}
|
|
64
64
|
});
|
|
65
|
-
transformation
|
|
65
|
+
transformation['transforms'] = transforms;
|
|
66
66
|
}
|
|
67
|
-
const systemKeys = constants_1.SYSTEM_ASSET_ALLOW_LIST.map((transformation) => transformation
|
|
67
|
+
const systemKeys = constants_1.SYSTEM_ASSET_ALLOW_LIST.map((transformation) => transformation['key']);
|
|
68
68
|
const allKeys = [
|
|
69
69
|
...systemKeys,
|
|
70
|
-
...(assetSettings.storage_asset_presets || []).map((transformation) => transformation
|
|
70
|
+
...(assetSettings.storage_asset_presets || []).map((transformation) => transformation['key']),
|
|
71
71
|
];
|
|
72
72
|
// For use in the next request handler
|
|
73
|
-
res.locals
|
|
74
|
-
res.locals
|
|
73
|
+
res.locals['shortcuts'] = [...constants_1.SYSTEM_ASSET_ALLOW_LIST, ...(assetSettings.storage_asset_presets || [])];
|
|
74
|
+
res.locals['transformation'] = transformation;
|
|
75
75
|
if (Object.keys(transformation).length === 0 ||
|
|
76
|
-
('transforms' in transformation && transformation
|
|
76
|
+
('transforms' in transformation && transformation['transforms'].length === 0)) {
|
|
77
77
|
return next();
|
|
78
78
|
}
|
|
79
79
|
if (assetSettings.storage_asset_transform === 'all') {
|
|
80
|
-
if (transformation
|
|
81
|
-
throw new exceptions_1.InvalidQueryException(`Key "${transformation
|
|
80
|
+
if (transformation['key'] && allKeys.includes(transformation['key']) === false) {
|
|
81
|
+
throw new exceptions_1.InvalidQueryException(`Key "${transformation['key']}" isn't configured.`);
|
|
82
82
|
}
|
|
83
83
|
return next();
|
|
84
84
|
}
|
|
85
85
|
else if (assetSettings.storage_asset_transform === 'presets') {
|
|
86
|
-
if (allKeys.includes(transformation
|
|
86
|
+
if (allKeys.includes(transformation['key']))
|
|
87
87
|
return next();
|
|
88
88
|
throw new exceptions_1.InvalidQueryException(`Only configured presets can be used in asset generation.`);
|
|
89
89
|
}
|
|
90
90
|
else {
|
|
91
|
-
if (transformation
|
|
91
|
+
if (transformation['key'] && systemKeys.includes(transformation['key']))
|
|
92
92
|
return next();
|
|
93
93
|
throw new exceptions_1.InvalidQueryException(`Dynamic asset generation has been disabled for this project.`);
|
|
94
94
|
}
|
|
@@ -103,14 +103,14 @@ 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
|
|
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,
|
|
110
110
|
});
|
|
111
|
-
const transformation = res.locals
|
|
112
|
-
? res.locals
|
|
113
|
-
: res.locals
|
|
111
|
+
const transformation = res.locals['transformation'].key
|
|
112
|
+
? res.locals['shortcuts'].find((transformation) => transformation['key'] === res.locals['transformation'].key)
|
|
113
|
+
: res.locals['transformation'];
|
|
114
114
|
let range = undefined;
|
|
115
115
|
if (req.headers.range) {
|
|
116
116
|
const rangeParts = /bytes=([0-9]*)-([0-9]*)/.exec(req.headers.range);
|
|
@@ -129,10 +129,10 @@ router.get('/:pk/:filename?',
|
|
|
129
129
|
}
|
|
130
130
|
}
|
|
131
131
|
const { stream, file, stat } = await service.getAsset(id, transformation, range);
|
|
132
|
-
res.attachment(req.params
|
|
132
|
+
res.attachment(req.params['filename'] ?? file.filename_download);
|
|
133
133
|
res.setHeader('Content-Type', file.type);
|
|
134
134
|
res.setHeader('Accept-Ranges', 'bytes');
|
|
135
|
-
res.setHeader('Cache-Control', (0, get_cache_headers_1.getCacheControlHeader)(req, (0, get_milliseconds_1.getMilliseconds)(env_1.default
|
|
135
|
+
res.setHeader('Cache-Control', (0, get_cache_headers_1.getCacheControlHeader)(req, (0, get_milliseconds_1.getMilliseconds)(env_1.default['ASSETS_CACHE_TTL']), false, true));
|
|
136
136
|
const unixTime = Date.parse(file.modified_on);
|
|
137
137
|
if (!Number.isNaN(unixTime)) {
|
|
138
138
|
const lastModifiedDate = new Date(unixTime);
|
|
@@ -181,5 +181,6 @@ router.get('/:pk/:filename?',
|
|
|
181
181
|
});
|
|
182
182
|
}
|
|
183
183
|
});
|
|
184
|
+
return undefined;
|
|
184
185
|
}));
|
|
185
186
|
exports.default = router;
|
package/dist/controllers/auth.js
CHANGED
|
@@ -41,7 +41,7 @@ for (const authProvider of authProviders) {
|
|
|
41
41
|
}
|
|
42
42
|
router.use(`/login/${authProvider.name}`, authRouter);
|
|
43
43
|
}
|
|
44
|
-
if (!env_1.default
|
|
44
|
+
if (!env_1.default['AUTH_DISABLE_DEFAULT']) {
|
|
45
45
|
router.use('/login', (0, drivers_1.createLocalAuthRouter)(constants_1.DEFAULT_AUTH_PROVIDER));
|
|
46
46
|
}
|
|
47
47
|
router.post('/refresh', (0, async_handler_1.default)(async (req, res, next) => {
|
|
@@ -59,7 +59,7 @@ router.post('/refresh', (0, async_handler_1.default)(async (req, res, next) => {
|
|
|
59
59
|
accountability: accountability,
|
|
60
60
|
schema: req.schema,
|
|
61
61
|
});
|
|
62
|
-
const currentRefreshToken = req.body.refresh_token || req.cookies[env_1.default
|
|
62
|
+
const currentRefreshToken = req.body.refresh_token || req.cookies[env_1.default['REFRESH_TOKEN_COOKIE_NAME']];
|
|
63
63
|
if (!currentRefreshToken) {
|
|
64
64
|
throw new exceptions_1.InvalidPayloadException(`"refresh_token" is required in either the JSON payload or Cookie`);
|
|
65
65
|
}
|
|
@@ -69,12 +69,12 @@ router.post('/refresh', (0, async_handler_1.default)(async (req, res, next) => {
|
|
|
69
69
|
data: { access_token: accessToken, expires },
|
|
70
70
|
};
|
|
71
71
|
if (mode === 'json') {
|
|
72
|
-
payload
|
|
72
|
+
payload['data']['refresh_token'] = refreshToken;
|
|
73
73
|
}
|
|
74
74
|
if (mode === 'cookie') {
|
|
75
|
-
res.cookie(env_1.default
|
|
75
|
+
res.cookie(env_1.default['REFRESH_TOKEN_COOKIE_NAME'], refreshToken, constants_1.COOKIE_OPTIONS);
|
|
76
76
|
}
|
|
77
|
-
res.locals
|
|
77
|
+
res.locals['payload'] = payload;
|
|
78
78
|
return next();
|
|
79
79
|
}), respond_1.respond);
|
|
80
80
|
router.post('/logout', (0, async_handler_1.default)(async (req, res, next) => {
|
|
@@ -92,17 +92,17 @@ router.post('/logout', (0, async_handler_1.default)(async (req, res, next) => {
|
|
|
92
92
|
accountability: accountability,
|
|
93
93
|
schema: req.schema,
|
|
94
94
|
});
|
|
95
|
-
const currentRefreshToken = req.body.refresh_token || req.cookies[env_1.default
|
|
95
|
+
const currentRefreshToken = req.body.refresh_token || req.cookies[env_1.default['REFRESH_TOKEN_COOKIE_NAME']];
|
|
96
96
|
if (!currentRefreshToken) {
|
|
97
97
|
throw new exceptions_1.InvalidPayloadException(`"refresh_token" is required in either the JSON payload or Cookie`);
|
|
98
98
|
}
|
|
99
99
|
await authenticationService.logout(currentRefreshToken);
|
|
100
|
-
if (req.cookies[env_1.default
|
|
101
|
-
res.clearCookie(env_1.default
|
|
100
|
+
if (req.cookies[env_1.default['REFRESH_TOKEN_COOKIE_NAME']]) {
|
|
101
|
+
res.clearCookie(env_1.default['REFRESH_TOKEN_COOKIE_NAME'], {
|
|
102
102
|
httpOnly: true,
|
|
103
|
-
domain: env_1.default
|
|
104
|
-
secure: env_1.default
|
|
105
|
-
sameSite: env_1.default
|
|
103
|
+
domain: env_1.default['REFRESH_TOKEN_COOKIE_DOMAIN'],
|
|
104
|
+
secure: env_1.default['REFRESH_TOKEN_COOKIE_SECURE'] ?? false,
|
|
105
|
+
sameSite: env_1.default['REFRESH_TOKEN_COOKIE_SAME_SITE'] || 'strict',
|
|
106
106
|
});
|
|
107
107
|
}
|
|
108
108
|
return next();
|
|
@@ -158,9 +158,9 @@ router.post('/password/reset', (0, async_handler_1.default)(async (req, res, nex
|
|
|
158
158
|
return next();
|
|
159
159
|
}), respond_1.respond);
|
|
160
160
|
router.get('/', (0, async_handler_1.default)(async (req, res, next) => {
|
|
161
|
-
res.locals
|
|
161
|
+
res.locals['payload'] = {
|
|
162
162
|
data: (0, get_auth_providers_1.getAuthProviders)(),
|
|
163
|
-
disableDefault: env_1.default
|
|
163
|
+
disableDefault: env_1.default['AUTH_DISABLE_DEFAULT'],
|
|
164
164
|
};
|
|
165
165
|
return next();
|
|
166
166
|
}), respond_1.respond);
|
|
@@ -18,12 +18,12 @@ router.post('/', (0, async_handler_1.default)(async (req, res, next) => {
|
|
|
18
18
|
if (Array.isArray(req.body)) {
|
|
19
19
|
const collectionKey = await collectionsService.createMany(req.body);
|
|
20
20
|
const records = await collectionsService.readMany(collectionKey);
|
|
21
|
-
res.locals
|
|
21
|
+
res.locals['payload'] = { data: records || null };
|
|
22
22
|
}
|
|
23
23
|
else {
|
|
24
24
|
const collectionKey = await collectionsService.createOne(req.body);
|
|
25
25
|
const record = await collectionsService.readOne(collectionKey);
|
|
26
|
-
res.locals
|
|
26
|
+
res.locals['payload'] = { data: record || null };
|
|
27
27
|
}
|
|
28
28
|
return next();
|
|
29
29
|
}), respond_1.respond);
|
|
@@ -44,7 +44,7 @@ const readHandler = (0, async_handler_1.default)(async (req, res, next) => {
|
|
|
44
44
|
result = await collectionsService.readByQuery();
|
|
45
45
|
}
|
|
46
46
|
const meta = await metaService.getMetaForQuery('directus_collections', {});
|
|
47
|
-
res.locals
|
|
47
|
+
res.locals['payload'] = { data: result, meta };
|
|
48
48
|
return next();
|
|
49
49
|
});
|
|
50
50
|
router.get('/', (0, validate_batch_1.validateBatch)('read'), readHandler, respond_1.respond);
|
|
@@ -54,8 +54,8 @@ router.get('/:collection', (0, async_handler_1.default)(async (req, res, next) =
|
|
|
54
54
|
accountability: req.accountability,
|
|
55
55
|
schema: req.schema,
|
|
56
56
|
});
|
|
57
|
-
const collection = await collectionsService.readOne(req.params
|
|
58
|
-
res.locals
|
|
57
|
+
const collection = await collectionsService.readOne(req.params['collection']);
|
|
58
|
+
res.locals['payload'] = { data: collection || null };
|
|
59
59
|
return next();
|
|
60
60
|
}), respond_1.respond);
|
|
61
61
|
router.patch('/', (0, async_handler_1.default)(async (req, res, next) => {
|
|
@@ -66,7 +66,7 @@ router.patch('/', (0, async_handler_1.default)(async (req, res, next) => {
|
|
|
66
66
|
const collectionKeys = await collectionsService.updateBatch(req.body);
|
|
67
67
|
try {
|
|
68
68
|
const collections = await collectionsService.readMany(collectionKeys);
|
|
69
|
-
res.locals
|
|
69
|
+
res.locals['payload'] = { data: collections || null };
|
|
70
70
|
}
|
|
71
71
|
catch (error) {
|
|
72
72
|
if (error instanceof exceptions_1.ForbiddenException) {
|
|
@@ -81,10 +81,10 @@ router.patch('/:collection', (0, async_handler_1.default)(async (req, res, next)
|
|
|
81
81
|
accountability: req.accountability,
|
|
82
82
|
schema: req.schema,
|
|
83
83
|
});
|
|
84
|
-
await collectionsService.updateOne(req.params
|
|
84
|
+
await collectionsService.updateOne(req.params['collection'], req.body);
|
|
85
85
|
try {
|
|
86
|
-
const collection = await collectionsService.readOne(req.params
|
|
87
|
-
res.locals
|
|
86
|
+
const collection = await collectionsService.readOne(req.params['collection']);
|
|
87
|
+
res.locals['payload'] = { data: collection || null };
|
|
88
88
|
}
|
|
89
89
|
catch (error) {
|
|
90
90
|
if (error instanceof exceptions_1.ForbiddenException) {
|
|
@@ -99,7 +99,7 @@ router.delete('/:collection', (0, async_handler_1.default)(async (req, res, next
|
|
|
99
99
|
accountability: req.accountability,
|
|
100
100
|
schema: req.schema,
|
|
101
101
|
});
|
|
102
|
-
await collectionsService.deleteOne(req.params
|
|
102
|
+
await collectionsService.deleteOne(req.params['collection']);
|
|
103
103
|
return next();
|
|
104
104
|
}), respond_1.respond);
|
|
105
105
|
exports.default = router;
|
|
@@ -30,11 +30,11 @@ router.post('/', (0, async_handler_1.default)(async (req, res, next) => {
|
|
|
30
30
|
try {
|
|
31
31
|
if (Array.isArray(req.body)) {
|
|
32
32
|
const items = await service.readMany(savedKeys, req.sanitizedQuery);
|
|
33
|
-
res.locals
|
|
33
|
+
res.locals['payload'] = { data: items };
|
|
34
34
|
}
|
|
35
35
|
else {
|
|
36
36
|
const item = await service.readOne(savedKeys[0], req.sanitizedQuery);
|
|
37
|
-
res.locals
|
|
37
|
+
res.locals['payload'] = { data: item };
|
|
38
38
|
}
|
|
39
39
|
}
|
|
40
40
|
catch (error) {
|
|
@@ -56,7 +56,7 @@ const readHandler = (0, async_handler_1.default)(async (req, res, next) => {
|
|
|
56
56
|
});
|
|
57
57
|
const records = await service.readByQuery(req.sanitizedQuery);
|
|
58
58
|
const meta = await metaService.getMetaForQuery(req.collection, req.sanitizedQuery);
|
|
59
|
-
res.locals
|
|
59
|
+
res.locals['payload'] = { data: records || null, meta };
|
|
60
60
|
return next();
|
|
61
61
|
});
|
|
62
62
|
router.get('/', (0, validate_batch_1.validateBatch)('read'), readHandler, respond_1.respond);
|
|
@@ -66,8 +66,8 @@ router.get('/:pk', (0, async_handler_1.default)(async (req, res, next) => {
|
|
|
66
66
|
accountability: req.accountability,
|
|
67
67
|
schema: req.schema,
|
|
68
68
|
});
|
|
69
|
-
const record = await service.readOne(req.params
|
|
70
|
-
res.locals
|
|
69
|
+
const record = await service.readOne(req.params['pk'], req.sanitizedQuery);
|
|
70
|
+
res.locals['payload'] = { data: record || null };
|
|
71
71
|
return next();
|
|
72
72
|
}), respond_1.respond);
|
|
73
73
|
router.patch('/', (0, validate_batch_1.validateBatch)('update'), (0, async_handler_1.default)(async (req, res, next) => {
|
|
@@ -88,7 +88,7 @@ router.patch('/', (0, validate_batch_1.validateBatch)('update'), (0, async_handl
|
|
|
88
88
|
}
|
|
89
89
|
try {
|
|
90
90
|
const result = await service.readMany(keys, req.sanitizedQuery);
|
|
91
|
-
res.locals
|
|
91
|
+
res.locals['payload'] = { data: result };
|
|
92
92
|
}
|
|
93
93
|
catch (error) {
|
|
94
94
|
if (error instanceof exceptions_1.ForbiddenException) {
|
|
@@ -103,10 +103,10 @@ router.patch('/:pk', (0, async_handler_1.default)(async (req, res, next) => {
|
|
|
103
103
|
accountability: req.accountability,
|
|
104
104
|
schema: req.schema,
|
|
105
105
|
});
|
|
106
|
-
const primaryKey = await service.updateOne(req.params
|
|
106
|
+
const primaryKey = await service.updateOne(req.params['pk'], req.body);
|
|
107
107
|
try {
|
|
108
108
|
const item = await service.readOne(primaryKey, req.sanitizedQuery);
|
|
109
|
-
res.locals
|
|
109
|
+
res.locals['payload'] = { data: item || null };
|
|
110
110
|
}
|
|
111
111
|
catch (error) {
|
|
112
112
|
if (error instanceof exceptions_1.ForbiddenException) {
|
|
@@ -138,7 +138,7 @@ router.delete('/:pk', (0, async_handler_1.default)(async (req, res, next) => {
|
|
|
138
138
|
accountability: req.accountability,
|
|
139
139
|
schema: req.schema,
|
|
140
140
|
});
|
|
141
|
-
await service.deleteOne(req.params
|
|
141
|
+
await service.deleteOne(req.params['pk']);
|
|
142
142
|
return next();
|
|
143
143
|
}), respond_1.respond);
|
|
144
144
|
exports.default = router;
|
|
@@ -15,13 +15,13 @@ const get_cache_headers_1 = require("../utils/get-cache-headers");
|
|
|
15
15
|
const get_milliseconds_1 = require("../utils/get-milliseconds");
|
|
16
16
|
const router = (0, express_1.Router)();
|
|
17
17
|
router.get('/:type', (0, async_handler_1.default)(async (req, res, next) => {
|
|
18
|
-
const type = (0, utils_1.depluralize)(req.params
|
|
18
|
+
const type = (0, utils_1.depluralize)(req.params['type']);
|
|
19
19
|
if (!(0, utils_1.isIn)(type, constants_1.EXTENSION_TYPES)) {
|
|
20
20
|
throw new exceptions_1.RouteNotFoundException(req.path);
|
|
21
21
|
}
|
|
22
22
|
const extensionManager = (0, extensions_1.getExtensionManager)();
|
|
23
23
|
const extensions = extensionManager.getExtensionsList(type);
|
|
24
|
-
res.locals
|
|
24
|
+
res.locals['payload'] = {
|
|
25
25
|
data: extensions,
|
|
26
26
|
};
|
|
27
27
|
return next();
|
|
@@ -33,7 +33,7 @@ router.get('/sources/index.js', (0, async_handler_1.default)(async (req, res) =>
|
|
|
33
33
|
throw new exceptions_1.RouteNotFoundException(req.path);
|
|
34
34
|
}
|
|
35
35
|
res.setHeader('Content-Type', 'application/javascript; charset=UTF-8');
|
|
36
|
-
res.setHeader('Cache-Control', (0, get_cache_headers_1.getCacheControlHeader)(req, (0, get_milliseconds_1.getMilliseconds)(env_1.default
|
|
36
|
+
res.setHeader('Cache-Control', (0, get_cache_headers_1.getCacheControlHeader)(req, (0, get_milliseconds_1.getMilliseconds)(env_1.default['EXTENSIONS_CACHE_TTL']), false, false));
|
|
37
37
|
res.setHeader('Vary', 'Origin, Cache-Control');
|
|
38
38
|
res.end(extensionSource);
|
|
39
39
|
}));
|
|
@@ -21,7 +21,7 @@ router.get('/', (0, async_handler_1.default)(async (req, res, next) => {
|
|
|
21
21
|
schema: req.schema,
|
|
22
22
|
});
|
|
23
23
|
const fields = await service.readAll();
|
|
24
|
-
res.locals
|
|
24
|
+
res.locals['payload'] = { data: fields || null };
|
|
25
25
|
return next();
|
|
26
26
|
}), respond_1.respond);
|
|
27
27
|
router.get('/:collection', collection_exists_1.default, (0, async_handler_1.default)(async (req, res, next) => {
|
|
@@ -29,8 +29,8 @@ router.get('/:collection', collection_exists_1.default, (0, async_handler_1.defa
|
|
|
29
29
|
accountability: req.accountability,
|
|
30
30
|
schema: req.schema,
|
|
31
31
|
});
|
|
32
|
-
const fields = await service.readAll(req.params
|
|
33
|
-
res.locals
|
|
32
|
+
const fields = await service.readAll(req.params['collection']);
|
|
33
|
+
res.locals['payload'] = { data: fields || null };
|
|
34
34
|
return next();
|
|
35
35
|
}), respond_1.respond);
|
|
36
36
|
router.get('/:collection/:field', collection_exists_1.default, (0, async_handler_1.default)(async (req, res, next) => {
|
|
@@ -38,8 +38,8 @@ router.get('/:collection/:field', collection_exists_1.default, (0, async_handler
|
|
|
38
38
|
accountability: req.accountability,
|
|
39
39
|
schema: req.schema,
|
|
40
40
|
});
|
|
41
|
-
const field = await service.readOne(req.params
|
|
42
|
-
res.locals
|
|
41
|
+
const field = await service.readOne(req.params['collection'], req.params['field']);
|
|
42
|
+
res.locals['payload'] = { data: field || null };
|
|
43
43
|
return next();
|
|
44
44
|
}), respond_1.respond);
|
|
45
45
|
const newFieldSchema = joi_1.default.object({
|
|
@@ -68,10 +68,10 @@ router.post('/:collection', collection_exists_1.default, (0, async_handler_1.def
|
|
|
68
68
|
throw new exceptions_1.InvalidPayloadException(error.message);
|
|
69
69
|
}
|
|
70
70
|
const field = req.body;
|
|
71
|
-
await service.createField(req.params
|
|
71
|
+
await service.createField(req.params['collection'], field);
|
|
72
72
|
try {
|
|
73
|
-
const createdField = await service.readOne(req.params
|
|
74
|
-
res.locals
|
|
73
|
+
const createdField = await service.readOne(req.params['collection'], field.field);
|
|
74
|
+
res.locals['payload'] = { data: createdField || null };
|
|
75
75
|
}
|
|
76
76
|
catch (error) {
|
|
77
77
|
if (error instanceof exceptions_1.ForbiddenException) {
|
|
@@ -90,14 +90,14 @@ router.patch('/:collection', collection_exists_1.default, (0, async_handler_1.de
|
|
|
90
90
|
throw new exceptions_1.InvalidPayloadException('Submitted body has to be an array.');
|
|
91
91
|
}
|
|
92
92
|
for (const field of req.body) {
|
|
93
|
-
await service.updateField(req.params
|
|
93
|
+
await service.updateField(req.params['collection'], field);
|
|
94
94
|
}
|
|
95
95
|
try {
|
|
96
96
|
const results = [];
|
|
97
97
|
for (const field of req.body) {
|
|
98
|
-
const updatedField = await service.readOne(req.params
|
|
98
|
+
const updatedField = await service.readOne(req.params['collection'], field.field);
|
|
99
99
|
results.push(updatedField);
|
|
100
|
-
res.locals
|
|
100
|
+
res.locals['payload'] = { data: results || null };
|
|
101
101
|
}
|
|
102
102
|
}
|
|
103
103
|
catch (error) {
|
|
@@ -135,11 +135,11 @@ router.patch('/:collection/:field', collection_exists_1.default, (0, async_handl
|
|
|
135
135
|
}
|
|
136
136
|
const fieldData = req.body;
|
|
137
137
|
if (!fieldData.field)
|
|
138
|
-
fieldData.field = req.params
|
|
139
|
-
await service.updateField(req.params
|
|
138
|
+
fieldData.field = req.params['field'];
|
|
139
|
+
await service.updateField(req.params['collection'], fieldData);
|
|
140
140
|
try {
|
|
141
|
-
const updatedField = await service.readOne(req.params
|
|
142
|
-
res.locals
|
|
141
|
+
const updatedField = await service.readOne(req.params['collection'], req.params['field']);
|
|
142
|
+
res.locals['payload'] = { data: updatedField || null };
|
|
143
143
|
}
|
|
144
144
|
catch (error) {
|
|
145
145
|
if (error instanceof exceptions_1.ForbiddenException) {
|
|
@@ -154,7 +154,7 @@ router.delete('/:collection/:field', collection_exists_1.default, (0, async_hand
|
|
|
154
154
|
accountability: req.accountability,
|
|
155
155
|
schema: req.schema,
|
|
156
156
|
});
|
|
157
|
-
await service.deleteField(req.params
|
|
157
|
+
await service.deleteField(req.params['collection'], req.params['field']);
|
|
158
158
|
return next();
|
|
159
159
|
}), respond_1.respond);
|
|
160
160
|
exports.default = router;
|