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.
Files changed (113) hide show
  1. package/dist/app.js +12 -12
  2. package/dist/auth/drivers/ldap.js +22 -22
  3. package/dist/auth/drivers/local.js +7 -7
  4. package/dist/auth/drivers/oauth2.js +27 -25
  5. package/dist/auth/drivers/openid.js +32 -30
  6. package/dist/auth/drivers/saml.js +10 -10
  7. package/dist/auth.js +4 -3
  8. package/dist/cache.js +16 -11
  9. package/dist/cli/commands/bootstrap/index.js +5 -4
  10. package/dist/cli/utils/create-db-connection.js +1 -1
  11. package/dist/cli/utils/create-env/index.js +1 -1
  12. package/dist/constants.d.ts +1 -0
  13. package/dist/constants.js +6 -5
  14. package/dist/controllers/activity.js +9 -9
  15. package/dist/controllers/assets.js +19 -18
  16. package/dist/controllers/auth.js +13 -13
  17. package/dist/controllers/collections.js +10 -10
  18. package/dist/controllers/dashboards.js +9 -9
  19. package/dist/controllers/extensions.js +3 -3
  20. package/dist/controllers/fields.js +16 -16
  21. package/dist/controllers/files.js +16 -15
  22. package/dist/controllers/flows.js +11 -11
  23. package/dist/controllers/folders.js +9 -9
  24. package/dist/controllers/graphql.js +6 -6
  25. package/dist/controllers/items.js +17 -17
  26. package/dist/controllers/notifications.js +9 -9
  27. package/dist/controllers/operations.js +9 -9
  28. package/dist/controllers/panels.js +9 -9
  29. package/dist/controllers/permissions.js +9 -9
  30. package/dist/controllers/presets.js +9 -9
  31. package/dist/controllers/relations.js +10 -10
  32. package/dist/controllers/revisions.js +3 -3
  33. package/dist/controllers/roles.js +9 -9
  34. package/dist/controllers/schema.js +5 -5
  35. package/dist/controllers/server.js +7 -7
  36. package/dist/controllers/settings.js +2 -2
  37. package/dist/controllers/shares.js +13 -13
  38. package/dist/controllers/users.js +16 -16
  39. package/dist/controllers/utils.js +5 -5
  40. package/dist/controllers/webhooks.js +9 -9
  41. package/dist/database/helpers/fn/types.d.ts +0 -1
  42. package/dist/database/helpers/fn/types.js +0 -2
  43. package/dist/database/helpers/index.d.ts +3 -3
  44. package/dist/database/index.js +5 -5
  45. package/dist/database/migrations/20210805B-change-image-metadata-structure.js +15 -15
  46. package/dist/database/migrations/run.js +1 -1
  47. package/dist/database/run-ast.js +4 -4
  48. package/dist/database/system-data/collections/index.js +2 -2
  49. package/dist/database/system-data/fields/index.js +3 -3
  50. package/dist/env.js +1 -1
  51. package/dist/extensions.js +10 -10
  52. package/dist/flows.js +33 -31
  53. package/dist/logger.d.ts +1 -0
  54. package/dist/logger.js +32 -32
  55. package/dist/mailer.js +16 -16
  56. package/dist/messenger.js +4 -4
  57. package/dist/middleware/authenticate.js +1 -1
  58. package/dist/middleware/cache.js +11 -11
  59. package/dist/middleware/collection-exists.js +3 -3
  60. package/dist/middleware/cors.js +7 -7
  61. package/dist/middleware/error-handler.js +2 -2
  62. package/dist/middleware/extract-token.js +2 -2
  63. package/dist/middleware/graphql.js +12 -6
  64. package/dist/middleware/rate-limiter-global.js +5 -5
  65. package/dist/middleware/rate-limiter-ip.js +2 -2
  66. package/dist/middleware/respond.js +16 -16
  67. package/dist/middleware/sanitize-query.js +1 -1
  68. package/dist/operations/exec/index.js +2 -2
  69. package/dist/rate-limiter.js +1 -1
  70. package/dist/request/validate-ip.js +2 -2
  71. package/dist/server.js +4 -4
  72. package/dist/services/activity.js +14 -14
  73. package/dist/services/assets.js +6 -6
  74. package/dist/services/authentication.js +9 -9
  75. package/dist/services/collections.js +9 -9
  76. package/dist/services/fields.js +5 -5
  77. package/dist/services/files.js +12 -12
  78. package/dist/services/graphql/index.js +100 -98
  79. package/dist/services/import-export.js +6 -6
  80. package/dist/services/items.js +6 -6
  81. package/dist/services/mail/index.js +5 -5
  82. package/dist/services/meta.js +1 -0
  83. package/dist/services/notifications.js +4 -4
  84. package/dist/services/revisions.js +3 -3
  85. package/dist/services/roles.js +5 -5
  86. package/dist/services/server.js +27 -27
  87. package/dist/services/shares.js +9 -9
  88. package/dist/services/specifications.js +5 -3
  89. package/dist/services/users.d.ts +1 -5
  90. package/dist/services/users.js +24 -27
  91. package/dist/storage/register-locations.js +1 -1
  92. package/dist/utils/apply-query.js +2 -1
  93. package/dist/utils/dynamic-import.js +1 -1
  94. package/dist/utils/generate-hash.js +1 -1
  95. package/dist/utils/get-ast-from-query.js +1 -1
  96. package/dist/utils/get-auth-providers.js +1 -1
  97. package/dist/utils/get-cache-headers.js +3 -3
  98. package/dist/utils/get-collection-from-alias.js +1 -0
  99. package/dist/utils/get-default-value.js +1 -1
  100. package/dist/utils/get-ip-from-req.js +2 -2
  101. package/dist/utils/get-permissions.js +11 -11
  102. package/dist/utils/get-schema.js +2 -2
  103. package/dist/utils/is-url-allowed.js +5 -2
  104. package/dist/utils/sanitize-query.js +26 -26
  105. package/dist/utils/should-skip-cache.js +2 -2
  106. package/dist/utils/track.js +16 -16
  107. package/dist/utils/validate-query.js +1 -1
  108. package/dist/utils/validate-storage.js +8 -8
  109. package/dist/webhooks.js +2 -2
  110. package/package.json +13 -13
  111. package/dist/utils/redact-header-cookies.d.ts +0 -1
  112. package/dist/utils/redact-header-cookies.js +0 -11
  113. /package/dist/{utils/redact-header-cookies.test.d.ts → logger.test.d.ts} +0 -0
package/dist/mailer.js CHANGED
@@ -11,12 +11,12 @@ let transporter;
11
11
  function getMailer() {
12
12
  if (transporter)
13
13
  return transporter;
14
- const transportName = env_1.default.EMAIL_TRANSPORT.toLowerCase();
14
+ const transportName = env_1.default['EMAIL_TRANSPORT'].toLowerCase();
15
15
  if (transportName === 'sendmail') {
16
16
  transporter = nodemailer_1.default.createTransport({
17
17
  sendmail: true,
18
- newline: env_1.default.EMAIL_SENDMAIL_NEW_LINE || 'unix',
19
- path: env_1.default.EMAIL_SENDMAIL_PATH || '/usr/sbin/sendmail',
18
+ newline: env_1.default['EMAIL_SENDMAIL_NEW_LINE'] || 'unix',
19
+ path: env_1.default['EMAIL_SENDMAIL_PATH'] || '/usr/sbin/sendmail',
20
20
  });
21
21
  }
22
22
  else if (transportName === 'ses') {
@@ -29,20 +29,20 @@ function getMailer() {
29
29
  }
30
30
  else if (transportName === 'smtp') {
31
31
  let auth = false;
32
- if (env_1.default.EMAIL_SMTP_USER || env_1.default.EMAIL_SMTP_PASSWORD) {
32
+ if (env_1.default['EMAIL_SMTP_USER'] || env_1.default['EMAIL_SMTP_PASSWORD']) {
33
33
  auth = {
34
- user: env_1.default.EMAIL_SMTP_USER,
35
- pass: env_1.default.EMAIL_SMTP_PASSWORD,
34
+ user: env_1.default['EMAIL_SMTP_USER'],
35
+ pass: env_1.default['EMAIL_SMTP_PASSWORD'],
36
36
  };
37
37
  }
38
38
  const tls = (0, get_config_from_env_1.getConfigFromEnv)('EMAIL_SMTP_TLS_');
39
39
  transporter = nodemailer_1.default.createTransport({
40
- name: env_1.default.EMAIL_SMTP_NAME,
41
- pool: env_1.default.EMAIL_SMTP_POOL,
42
- host: env_1.default.EMAIL_SMTP_HOST,
43
- port: env_1.default.EMAIL_SMTP_PORT,
44
- secure: env_1.default.EMAIL_SMTP_SECURE,
45
- ignoreTLS: env_1.default.EMAIL_SMTP_IGNORE_TLS,
40
+ name: env_1.default['EMAIL_SMTP_NAME'],
41
+ pool: env_1.default['EMAIL_SMTP_POOL'],
42
+ host: env_1.default['EMAIL_SMTP_HOST'],
43
+ port: env_1.default['EMAIL_SMTP_PORT'],
44
+ secure: env_1.default['EMAIL_SMTP_SECURE'],
45
+ ignoreTLS: env_1.default['EMAIL_SMTP_IGNORE_TLS'],
46
46
  auth,
47
47
  tls,
48
48
  });
@@ -51,16 +51,16 @@ function getMailer() {
51
51
  const mg = require('nodemailer-mailgun-transport');
52
52
  transporter = nodemailer_1.default.createTransport(mg({
53
53
  auth: {
54
- api_key: env_1.default.EMAIL_MAILGUN_API_KEY,
55
- domain: env_1.default.EMAIL_MAILGUN_DOMAIN,
54
+ api_key: env_1.default['EMAIL_MAILGUN_API_KEY'],
55
+ domain: env_1.default['EMAIL_MAILGUN_DOMAIN'],
56
56
  },
57
- host: env_1.default.EMAIL_MAILGUN_HOST || 'api.mailgun.net',
57
+ host: env_1.default['EMAIL_MAILGUN_HOST'] || 'api.mailgun.net',
58
58
  }));
59
59
  }
60
60
  else if (transportName === 'sendgrid') {
61
61
  const sg = require('nodemailer-sendgrid');
62
62
  transporter = nodemailer_1.default.createTransport(sg({
63
- apiKey: env_1.default.EMAIL_SENDGRID_API_KEY,
63
+ apiKey: env_1.default['EMAIL_SENDGRID_API_KEY'],
64
64
  }));
65
65
  }
66
66
  else {
package/dist/messenger.js CHANGED
@@ -30,9 +30,9 @@ class MessengerRedis {
30
30
  sub;
31
31
  constructor() {
32
32
  const config = (0, get_config_from_env_1.getConfigFromEnv)('MESSENGER_REDIS');
33
- this.pub = new ioredis_1.default(env_1.default.MESSENGER_REDIS ?? config);
34
- this.sub = new ioredis_1.default(env_1.default.MESSENGER_REDIS ?? config);
35
- this.namespace = env_1.default.MESSENGER_NAMESPACE ?? 'directus';
33
+ this.pub = new ioredis_1.default(env_1.default['MESSENGER_REDIS'] ?? config);
34
+ this.sub = new ioredis_1.default(env_1.default['MESSENGER_REDIS'] ?? config);
35
+ this.namespace = env_1.default['MESSENGER_NAMESPACE'] ?? 'directus';
36
36
  }
37
37
  publish(channel, payload) {
38
38
  this.pub.publish(`${this.namespace}:${channel}`, JSON.stringify(payload));
@@ -55,7 +55,7 @@ let messenger;
55
55
  function getMessenger() {
56
56
  if (messenger)
57
57
  return messenger;
58
- if (env_1.default.MESSENGER_STORE === 'redis') {
58
+ if (env_1.default['MESSENGER_STORE'] === 'redis') {
59
59
  messenger = new MessengerRedis();
60
60
  }
61
61
  else {
@@ -45,7 +45,7 @@ const handler = async (req, res, next) => {
45
45
  req.accountability = defaultAccountability;
46
46
  if (req.token) {
47
47
  if ((0, is_directus_jwt_1.default)(req.token)) {
48
- const payload = (0, jwt_1.verifyAccessJWT)(req.token, env_1.default.SECRET);
48
+ const payload = (0, jwt_1.verifyAccessJWT)(req.token, env_1.default['SECRET']);
49
49
  req.accountability.role = payload.role;
50
50
  req.accountability.admin = payload.admin_access === true || payload.admin_access == 1;
51
51
  req.accountability.app = payload.app_access === true || payload.app_access == 1;
@@ -14,13 +14,13 @@ const checkCacheMiddleware = (0, async_handler_1.default)(async (req, res, next)
14
14
  const { cache } = (0, cache_1.getCache)();
15
15
  if (req.method.toLowerCase() !== 'get' && req.originalUrl?.startsWith('/graphql') === false)
16
16
  return next();
17
- if (env_1.default.CACHE_ENABLED !== true)
17
+ if (env_1.default['CACHE_ENABLED'] !== true)
18
18
  return next();
19
19
  if (!cache)
20
20
  return next();
21
21
  if ((0, should_skip_cache_1.shouldSkipCache)(req)) {
22
- if (env_1.default.CACHE_STATUS_HEADER)
23
- res.setHeader(`${env_1.default.CACHE_STATUS_HEADER}`, 'MISS');
22
+ if (env_1.default['CACHE_STATUS_HEADER'])
23
+ res.setHeader(`${env_1.default['CACHE_STATUS_HEADER']}`, 'MISS');
24
24
  return next();
25
25
  }
26
26
  const key = (0, get_cache_key_1.getCacheKey)(req);
@@ -30,8 +30,8 @@ const checkCacheMiddleware = (0, async_handler_1.default)(async (req, res, next)
30
30
  }
31
31
  catch (err) {
32
32
  logger_1.default.warn(err, `[cache] Couldn't read key ${key}. ${err.message}`);
33
- if (env_1.default.CACHE_STATUS_HEADER)
34
- res.setHeader(`${env_1.default.CACHE_STATUS_HEADER}`, 'MISS');
33
+ if (env_1.default['CACHE_STATUS_HEADER'])
34
+ res.setHeader(`${env_1.default['CACHE_STATUS_HEADER']}`, 'MISS');
35
35
  return next();
36
36
  }
37
37
  if (cachedData) {
@@ -41,20 +41,20 @@ const checkCacheMiddleware = (0, async_handler_1.default)(async (req, res, next)
41
41
  }
42
42
  catch (err) {
43
43
  logger_1.default.warn(err, `[cache] Couldn't read key ${`${key}__expires_at`}. ${err.message}`);
44
- if (env_1.default.CACHE_STATUS_HEADER)
45
- res.setHeader(`${env_1.default.CACHE_STATUS_HEADER}`, 'MISS');
44
+ if (env_1.default['CACHE_STATUS_HEADER'])
45
+ res.setHeader(`${env_1.default['CACHE_STATUS_HEADER']}`, 'MISS');
46
46
  return next();
47
47
  }
48
48
  const cacheTTL = cacheExpiryDate ? cacheExpiryDate - Date.now() : undefined;
49
49
  res.setHeader('Cache-Control', (0, get_cache_headers_1.getCacheControlHeader)(req, cacheTTL, true, true));
50
50
  res.setHeader('Vary', 'Origin, Cache-Control');
51
- if (env_1.default.CACHE_STATUS_HEADER)
52
- res.setHeader(`${env_1.default.CACHE_STATUS_HEADER}`, 'HIT');
51
+ if (env_1.default['CACHE_STATUS_HEADER'])
52
+ res.setHeader(`${env_1.default['CACHE_STATUS_HEADER']}`, 'HIT');
53
53
  return res.json(cachedData);
54
54
  }
55
55
  else {
56
- if (env_1.default.CACHE_STATUS_HEADER)
57
- res.setHeader(`${env_1.default.CACHE_STATUS_HEADER}`, 'MISS');
56
+ if (env_1.default['CACHE_STATUS_HEADER'])
57
+ res.setHeader(`${env_1.default['CACHE_STATUS_HEADER']}`, 'MISS');
58
58
  return next();
59
59
  }
60
60
  });
@@ -10,12 +10,12 @@ 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
12
  const collectionExists = (0, async_handler_1.default)(async (req, res, next) => {
13
- if (!req.params.collection)
13
+ if (!req.params['collection'])
14
14
  return next();
15
- if (req.params.collection in req.schema.collections === false) {
15
+ if (req.params['collection'] in req.schema.collections === false) {
16
16
  throw new exceptions_1.ForbiddenException();
17
17
  }
18
- req.collection = req.params.collection;
18
+ req.collection = req.params['collection'];
19
19
  if (req.collection.startsWith('directus_')) {
20
20
  const systemRow = collections_1.systemCollectionRows.find((collection) => {
21
21
  return collection?.collection === req.collection;
@@ -6,14 +6,14 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  const cors_1 = __importDefault(require("cors"));
7
7
  const env_1 = __importDefault(require("../env"));
8
8
  let corsMiddleware = (req, res, next) => next();
9
- if (env_1.default.CORS_ENABLED === true) {
9
+ if (env_1.default['CORS_ENABLED'] === true) {
10
10
  corsMiddleware = (0, cors_1.default)({
11
- origin: env_1.default.CORS_ORIGIN || true,
12
- methods: env_1.default.CORS_METHODS || 'GET,POST,PATCH,DELETE',
13
- allowedHeaders: env_1.default.CORS_ALLOWED_HEADERS,
14
- exposedHeaders: env_1.default.CORS_EXPOSED_HEADERS,
15
- credentials: env_1.default.CORS_CREDENTIALS || undefined,
16
- maxAge: env_1.default.CORS_MAX_AGE || undefined,
11
+ origin: env_1.default['CORS_ORIGIN'] || true,
12
+ methods: env_1.default['CORS_METHODS'] || 'GET,POST,PATCH,DELETE',
13
+ allowedHeaders: env_1.default['CORS_ALLOWED_HEADERS'],
14
+ exposedHeaders: env_1.default['CORS_EXPOSED_HEADERS'],
15
+ credentials: env_1.default['CORS_CREDENTIALS'] || undefined,
16
+ maxAge: env_1.default['CORS_MAX_AGE'] || undefined,
17
17
  });
18
18
  }
19
19
  exports.default = corsMiddleware;
@@ -32,7 +32,7 @@ const errorHandler = (err, req, res, _next) => {
32
32
  res.status(status);
33
33
  }
34
34
  for (const err of errors) {
35
- if (env_1.default.NODE_ENV === 'development') {
35
+ if (env_1.default['NODE_ENV'] === 'development') {
36
36
  err.extensions = {
37
37
  ...(err.extensions || {}),
38
38
  stack: err.stack,
@@ -49,7 +49,7 @@ const errorHandler = (err, req, res, _next) => {
49
49
  },
50
50
  });
51
51
  if (err instanceof exceptions_2.MethodNotAllowedException) {
52
- res.header('Allow', err.extensions.allow.join(', '));
52
+ res.header('Allow', err.extensions['allow'].join(', '));
53
53
  }
54
54
  }
55
55
  else {
@@ -10,8 +10,8 @@
10
10
  Object.defineProperty(exports, "__esModule", { value: true });
11
11
  const extractToken = (req, res, next) => {
12
12
  let token = null;
13
- if (req.query && req.query.access_token) {
14
- token = req.query.access_token;
13
+ if (req.query && req.query['access_token']) {
14
+ token = req.query['access_token'];
15
15
  }
16
16
  if (req.headers && req.headers.authorization) {
17
17
  const parts = req.headers.authorization.split(' ');
@@ -17,10 +17,10 @@ exports.parseGraphQL = (0, async_handler_1.default)(async (req, res, next) => {
17
17
  let operationName = null;
18
18
  let document;
19
19
  if (req.method === 'GET') {
20
- query = req.query.query || null;
21
- if (req.query.variables) {
20
+ query = req.query['query'] || null;
21
+ if (req.query['variables']) {
22
22
  try {
23
- variables = (0, utils_1.parseJSON)(req.query.variables);
23
+ variables = (0, utils_1.parseJSON)(req.query['variables']);
24
24
  }
25
25
  catch {
26
26
  throw new exceptions_1.InvalidQueryException(`Variables are invalid JSON.`);
@@ -29,7 +29,7 @@ exports.parseGraphQL = (0, async_handler_1.default)(async (req, res, next) => {
29
29
  else {
30
30
  variables = {};
31
31
  }
32
- operationName = req.query.operationName || null;
32
+ operationName = req.query['operationName'] || null;
33
33
  }
34
34
  else {
35
35
  query = req.body.query || null;
@@ -56,8 +56,14 @@ exports.parseGraphQL = (0, async_handler_1.default)(async (req, res, next) => {
56
56
  }
57
57
  // Prevent caching responses when mutations are made
58
58
  if (operationAST?.operation === 'mutation') {
59
- res.locals.cache = false;
59
+ res.locals['cache'] = false;
60
60
  }
61
- res.locals.graphqlParams = { document, query, variables, operationName, contextValue: { req, res } };
61
+ res.locals['graphqlParams'] = {
62
+ document,
63
+ query,
64
+ variables,
65
+ operationName,
66
+ contextValue: { req, res },
67
+ };
62
68
  return next();
63
69
  });
@@ -13,7 +13,7 @@ const async_handler_1 = __importDefault(require("../utils/async-handler"));
13
13
  const validate_env_1 = require("../utils/validate-env");
14
14
  const RATE_LIMITER_GLOBAL_KEY = 'global-rate-limit';
15
15
  let checkRateLimit = (_req, _res, next) => next();
16
- if (env_1.default.RATE_LIMITER_GLOBAL_ENABLED === true) {
16
+ if (env_1.default['RATE_LIMITER_GLOBAL_ENABLED'] === true) {
17
17
  (0, validate_env_1.validateEnv)(['RATE_LIMITER_GLOBAL_STORE', 'RATE_LIMITER_GLOBAL_DURATION', 'RATE_LIMITER_GLOBAL_POINTS']);
18
18
  validateConfiguration();
19
19
  exports.rateLimiterGlobal = (0, rate_limiter_1.createRateLimiter)('RATE_LIMITER_GLOBAL');
@@ -26,7 +26,7 @@ if (env_1.default.RATE_LIMITER_GLOBAL_ENABLED === true) {
26
26
  throw rateLimiterRes;
27
27
  res.set('Retry-After', String(Math.round(rateLimiterRes.msBeforeNext / 1000)));
28
28
  throw new index_1.HitRateLimitException(`Too many requests, retry after ${(0, ms_1.default)(rateLimiterRes.msBeforeNext)}.`, {
29
- limit: +env_1.default.RATE_LIMITER_GLOBAL_POINTS,
29
+ limit: +env_1.default['RATE_LIMITER_GLOBAL_POINTS'],
30
30
  reset: new Date(Date.now() + rateLimiterRes.msBeforeNext),
31
31
  });
32
32
  }
@@ -35,12 +35,12 @@ if (env_1.default.RATE_LIMITER_GLOBAL_ENABLED === true) {
35
35
  }
36
36
  exports.default = checkRateLimit;
37
37
  function validateConfiguration() {
38
- if (env_1.default.RATE_LIMITER_ENABLED !== true) {
38
+ if (env_1.default['RATE_LIMITER_ENABLED'] !== true) {
39
39
  logger_1.default.error(`The IP based rate limiter needs to be enabled when using the global rate limiter.`);
40
40
  process.exit(1);
41
41
  }
42
- const globalPointsPerSec = Number(env_1.default.RATE_LIMITER_GLOBAL_POINTS) / Math.max(Number(env_1.default.RATE_LIMITER_GLOBAL_DURATION), 1);
43
- const regularPointsPerSec = Number(env_1.default.RATE_LIMITER_POINTS) / Math.max(Number(env_1.default.RATE_LIMITER_DURATION), 1);
42
+ const globalPointsPerSec = Number(env_1.default['RATE_LIMITER_GLOBAL_POINTS']) / Math.max(Number(env_1.default['RATE_LIMITER_GLOBAL_DURATION']), 1);
43
+ const regularPointsPerSec = Number(env_1.default['RATE_LIMITER_POINTS']) / Math.max(Number(env_1.default['RATE_LIMITER_DURATION']), 1);
44
44
  if (globalPointsPerSec <= regularPointsPerSec) {
45
45
  logger_1.default.error(`The global rate limiter needs to allow more requests per second than the IP based rate limiter.`);
46
46
  process.exit(1);
@@ -12,7 +12,7 @@ const async_handler_1 = __importDefault(require("../utils/async-handler"));
12
12
  const get_ip_from_req_1 = require("../utils/get-ip-from-req");
13
13
  const validate_env_1 = require("../utils/validate-env");
14
14
  let checkRateLimit = (_req, _res, next) => next();
15
- if (env_1.default.RATE_LIMITER_ENABLED === true) {
15
+ if (env_1.default['RATE_LIMITER_ENABLED'] === true) {
16
16
  (0, validate_env_1.validateEnv)(['RATE_LIMITER_STORE', 'RATE_LIMITER_DURATION', 'RATE_LIMITER_POINTS']);
17
17
  exports.rateLimiter = (0, rate_limiter_1.createRateLimiter)('RATE_LIMITER');
18
18
  checkRateLimit = (0, async_handler_1.default)(async (req, res, next) => {
@@ -24,7 +24,7 @@ if (env_1.default.RATE_LIMITER_ENABLED === true) {
24
24
  throw rateLimiterRes;
25
25
  res.set('Retry-After', String(Math.round(rateLimiterRes.msBeforeNext / 1000)));
26
26
  throw new exceptions_1.HitRateLimitException(`Too many requests, retry after ${(0, ms_1.default)(rateLimiterRes.msBeforeNext)}.`, {
27
- limit: +env_1.default.RATE_LIMITER_POINTS,
27
+ limit: +env_1.default['RATE_LIMITER_POINTS'],
28
28
  reset: new Date(Date.now() + rateLimiterRes.msBeforeNext),
29
29
  });
30
30
  }
@@ -18,26 +18,26 @@ const get_string_byte_size_1 = require("../utils/get-string-byte-size");
18
18
  exports.respond = (0, async_handler_1.default)(async (req, res) => {
19
19
  const { cache } = (0, cache_1.getCache)();
20
20
  let exceedsMaxSize = false;
21
- if (env_1.default.CACHE_VALUE_MAX_SIZE !== false) {
22
- const valueSize = res.locals.payload ? (0, get_string_byte_size_1.stringByteSize)(JSON.stringify(res.locals.payload)) : 0;
23
- const maxSize = (0, bytes_1.parse)(env_1.default.CACHE_VALUE_MAX_SIZE);
21
+ if (env_1.default['CACHE_VALUE_MAX_SIZE'] !== false) {
22
+ const valueSize = res.locals['payload'] ? (0, get_string_byte_size_1.stringByteSize)(JSON.stringify(res.locals['payload'])) : 0;
23
+ const maxSize = (0, bytes_1.parse)(env_1.default['CACHE_VALUE_MAX_SIZE']);
24
24
  exceedsMaxSize = valueSize > maxSize;
25
25
  }
26
26
  if ((req.method.toLowerCase() === 'get' || req.originalUrl?.startsWith('/graphql')) &&
27
- env_1.default.CACHE_ENABLED === true &&
27
+ env_1.default['CACHE_ENABLED'] === true &&
28
28
  cache &&
29
29
  !req.sanitizedQuery.export &&
30
- res.locals.cache !== false &&
30
+ res.locals['cache'] !== false &&
31
31
  exceedsMaxSize === false) {
32
32
  const key = (0, get_cache_key_1.getCacheKey)(req);
33
33
  try {
34
- await (0, cache_1.setCacheValue)(cache, key, res.locals.payload, (0, get_milliseconds_1.getMilliseconds)(env_1.default.CACHE_TTL));
35
- await (0, cache_1.setCacheValue)(cache, `${key}__expires_at`, { exp: Date.now() + (0, get_milliseconds_1.getMilliseconds)(env_1.default.CACHE_TTL, 0) });
34
+ await (0, cache_1.setCacheValue)(cache, key, res.locals['payload'], (0, get_milliseconds_1.getMilliseconds)(env_1.default['CACHE_TTL']));
35
+ await (0, cache_1.setCacheValue)(cache, `${key}__expires_at`, { exp: Date.now() + (0, get_milliseconds_1.getMilliseconds)(env_1.default['CACHE_TTL'], 0) });
36
36
  }
37
37
  catch (err) {
38
38
  logger_1.default.warn(err, `[cache] Couldn't set key ${key}. ${err}`);
39
39
  }
40
- res.setHeader('Cache-Control', (0, get_cache_headers_1.getCacheControlHeader)(req, (0, get_milliseconds_1.getMilliseconds)(env_1.default.CACHE_TTL), true, true));
40
+ res.setHeader('Cache-Control', (0, get_cache_headers_1.getCacheControlHeader)(req, (0, get_milliseconds_1.getMilliseconds)(env_1.default['CACHE_TTL']), true, true));
41
41
  res.setHeader('Vary', 'Origin, Cache-Control');
42
42
  }
43
43
  else {
@@ -58,29 +58,29 @@ exports.respond = (0, async_handler_1.default)(async (req, res) => {
58
58
  if (req.sanitizedQuery.export === 'json') {
59
59
  res.attachment(`${filename}.json`);
60
60
  res.set('Content-Type', 'application/json');
61
- return res.status(200).send(exportService.transform(res.locals.payload?.data, 'json'));
61
+ return res.status(200).send(exportService.transform(res.locals['payload']?.data, 'json'));
62
62
  }
63
63
  if (req.sanitizedQuery.export === 'xml') {
64
64
  res.attachment(`${filename}.xml`);
65
65
  res.set('Content-Type', 'text/xml');
66
- return res.status(200).send(exportService.transform(res.locals.payload?.data, 'xml'));
66
+ return res.status(200).send(exportService.transform(res.locals['payload']?.data, 'xml'));
67
67
  }
68
68
  if (req.sanitizedQuery.export === 'csv') {
69
69
  res.attachment(`${filename}.csv`);
70
70
  res.set('Content-Type', 'text/csv');
71
- return res.status(200).send(exportService.transform(res.locals.payload?.data, 'csv'));
71
+ return res.status(200).send(exportService.transform(res.locals['payload']?.data, 'csv'));
72
72
  }
73
73
  if (req.sanitizedQuery.export === 'yaml') {
74
74
  res.attachment(`${filename}.yaml`);
75
75
  res.set('Content-Type', 'text/yaml');
76
- return res.status(200).send(exportService.transform(res.locals.payload?.data, 'yaml'));
76
+ return res.status(200).send(exportService.transform(res.locals['payload']?.data, 'yaml'));
77
77
  }
78
78
  }
79
- if (Buffer.isBuffer(res.locals.payload)) {
80
- return res.end(res.locals.payload);
79
+ if (Buffer.isBuffer(res.locals['payload'])) {
80
+ return res.end(res.locals['payload']);
81
81
  }
82
- else if (res.locals.payload) {
83
- return res.json(res.locals.payload);
82
+ else if (res.locals['payload']) {
83
+ return res.json(res.locals['payload']);
84
84
  }
85
85
  else {
86
86
  return res.status(204).end();
@@ -11,7 +11,7 @@ const sanitizeQueryMiddleware = (req, _res, next) => {
11
11
  if (!req.query)
12
12
  return;
13
13
  req.sanitizedQuery = (0, sanitize_query_1.sanitizeQuery)({
14
- fields: req.query.fields || '*',
14
+ fields: req.query['fields'] || '*',
15
15
  ...req.query,
16
16
  }, req.accountability || null);
17
17
  Object.freeze(req.sanitizedQuery);
@@ -6,10 +6,10 @@ const node_module_1 = require("node:module");
6
6
  exports.default = (0, utils_1.defineOperationApi)({
7
7
  id: 'exec',
8
8
  handler: async ({ code }, { data, env }) => {
9
- const allowedModules = env.FLOWS_EXEC_ALLOWED_MODULES ? (0, utils_1.toArray)(env.FLOWS_EXEC_ALLOWED_MODULES) : [];
9
+ const allowedModules = env['FLOWS_EXEC_ALLOWED_MODULES'] ? (0, utils_1.toArray)(env['FLOWS_EXEC_ALLOWED_MODULES']) : [];
10
10
  const allowedModulesBuiltIn = [];
11
11
  const allowedModulesExternal = [];
12
- const allowedEnv = data.$env ?? {};
12
+ const allowedEnv = data['$env'] ?? {};
13
13
  const opts = {
14
14
  eval: false,
15
15
  wasm: false,
@@ -9,7 +9,7 @@ const rate_limiter_flexible_1 = require("rate-limiter-flexible");
9
9
  const env_1 = __importDefault(require("./env"));
10
10
  const get_config_from_env_1 = require("./utils/get-config-from-env");
11
11
  function createRateLimiter(configPrefix = 'RATE_LIMITER', configOverrides) {
12
- switch (env_1.default.RATE_LIMITER_STORE) {
12
+ switch (env_1.default['RATE_LIMITER_STORE']) {
13
13
  case 'redis':
14
14
  return new rate_limiter_flexible_1.RateLimiterRedis(getConfig('redis', configPrefix, configOverrides));
15
15
  case 'memcache':
@@ -8,10 +8,10 @@ const node_os_1 = __importDefault(require("node:os"));
8
8
  const env_1 = require("../env");
9
9
  const validateIP = async (ip, url) => {
10
10
  const env = (0, env_1.getEnv)();
11
- if (env.IMPORT_IP_DENY_LIST.includes(ip)) {
11
+ if (env['IMPORT_IP_DENY_LIST'].includes(ip)) {
12
12
  throw new Error(`Requested URL "${url}" resolves to a denied IP address`);
13
13
  }
14
- if (env.IMPORT_IP_DENY_LIST.includes('0.0.0.0')) {
14
+ if (env['IMPORT_IP_DENY_LIST'].includes('0.0.0.0')) {
15
15
  const networkInterfaces = node_os_1.default.networkInterfaces();
16
16
  for (const networkInfo of Object.values(networkInterfaces)) {
17
17
  if (!networkInfo)
package/dist/server.js CHANGED
@@ -106,7 +106,7 @@ async function createServer() {
106
106
  (0, terminus_1.createTerminus)(server, terminusOptions);
107
107
  return server;
108
108
  async function beforeShutdown() {
109
- if (env_1.default.NODE_ENV !== 'development') {
109
+ if (env_1.default['NODE_ENV'] !== 'development') {
110
110
  logger_1.default.info('Shutting down...');
111
111
  }
112
112
  }
@@ -121,7 +121,7 @@ async function createServer() {
121
121
  schema: null,
122
122
  accountability: null,
123
123
  });
124
- if (env_1.default.NODE_ENV !== 'development') {
124
+ if (env_1.default['NODE_ENV'] !== 'development') {
125
125
  logger_1.default.info('Directus shut down OK. Bye bye!');
126
126
  }
127
127
  }
@@ -129,8 +129,8 @@ async function createServer() {
129
129
  exports.createServer = createServer;
130
130
  async function startServer() {
131
131
  const server = await createServer();
132
- const host = env_1.default.HOST;
133
- const port = env_1.default.PORT;
132
+ const host = env_1.default['HOST'];
133
+ const port = env_1.default['PORT'];
134
134
  server
135
135
  .listen(port, host, () => {
136
136
  (0, update_check_1.default)(package_json_1.default)
@@ -26,9 +26,9 @@ class ActivityService extends items_1.ItemsService {
26
26
  this.usersService = new users_1.UsersService({ schema: this.schema });
27
27
  }
28
28
  async createOne(data, opts) {
29
- if (data.action === types_1.Action.COMMENT && typeof data.comment === 'string') {
29
+ if (data['action'] === types_1.Action.COMMENT && typeof data['comment'] === 'string') {
30
30
  const usersRegExp = new RegExp(/@[0-9A-F]{8}-[0-9A-F]{4}-4[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}/gi);
31
- const mentions = (0, lodash_1.uniq)(data.comment.match(usersRegExp) ?? []);
31
+ const mentions = (0, lodash_1.uniq)(data['comment'].match(usersRegExp) ?? []);
32
32
  const sender = await this.usersService.readOne(this.accountability.user, {
33
33
  fields: ['id', 'first_name', 'last_name', 'email'],
34
34
  });
@@ -39,24 +39,24 @@ class ActivityService extends items_1.ItemsService {
39
39
  });
40
40
  const accountability = {
41
41
  user: userID,
42
- role: user.role?.id ?? null,
43
- admin: user.role?.admin_access ?? null,
44
- app: user.role?.app_access ?? null,
42
+ role: user['role']?.id ?? null,
43
+ admin: user['role']?.admin_access ?? null,
44
+ app: user['role']?.app_access ?? null,
45
45
  };
46
46
  accountability.permissions = await (0, get_permissions_1.getPermissions)(accountability, this.schema);
47
47
  const authorizationService = new authorization_1.AuthorizationService({ schema: this.schema, accountability });
48
48
  const usersService = new users_1.UsersService({ schema: this.schema, accountability });
49
49
  try {
50
- await authorizationService.checkAccess('read', data.collection, data.item);
50
+ await authorizationService.checkAccess('read', data['collection'], data['item']);
51
51
  const templateData = await usersService.readByQuery({
52
52
  fields: ['id', 'first_name', 'last_name', 'email'],
53
53
  filter: { id: { _in: mentions.map((mention) => mention.substring(1)) } },
54
54
  });
55
55
  const userPreviews = templateData.reduce((acc, user) => {
56
- acc[user.id] = `<em>${(0, user_name_1.userName)(user)}</em>`;
56
+ acc[user['id']] = `<em>${(0, user_name_1.userName)(user)}</em>`;
57
57
  return acc;
58
58
  }, {});
59
- let comment = data.comment;
59
+ let comment = data['comment'];
60
60
  for (const mention of mentions) {
61
61
  const uuid = mention.substring(1);
62
62
  // We only match on UUIDs in the first place. This is just an extra sanity check
@@ -72,17 +72,17 @@ ${(0, user_name_1.userName)(sender)} has mentioned you in a comment:
72
72
 
73
73
  ${comment}
74
74
 
75
- <a href="${new url_1.Url(env_1.default.PUBLIC_URL)
76
- .addPath('admin', 'content', data.collection, data.item)
75
+ <a href="${new url_1.Url(env_1.default['PUBLIC_URL'])
76
+ .addPath('admin', 'content', data['collection'], data['item'])
77
77
  .toString()}">Click here to view.</a>
78
78
  `;
79
79
  await this.notificationsService.createOne({
80
80
  recipient: userID,
81
- sender: sender.id,
82
- subject: `You were mentioned in ${data.collection}`,
81
+ sender: sender['id'],
82
+ subject: `You were mentioned in ${data['collection']}`,
83
83
  message,
84
- collection: data.collection,
85
- item: data.item,
84
+ collection: data['collection'],
85
+ item: data['item'],
86
86
  });
87
87
  }
88
88
  catch (err) {
@@ -131,24 +131,24 @@ class AssetsService {
131
131
  const { width, height } = file;
132
132
  if (!width ||
133
133
  !height ||
134
- width > env_1.default.ASSETS_TRANSFORM_IMAGE_MAX_DIMENSION ||
135
- height > env_1.default.ASSETS_TRANSFORM_IMAGE_MAX_DIMENSION) {
134
+ width > env_1.default['ASSETS_TRANSFORM_IMAGE_MAX_DIMENSION'] ||
135
+ height > env_1.default['ASSETS_TRANSFORM_IMAGE_MAX_DIMENSION']) {
136
136
  throw new exceptions_1.IllegalAssetTransformation(`Image is too large to be transformed, or image size couldn't be determined.`);
137
137
  }
138
138
  const { queue, process } = sharp_1.default.counters();
139
- if (queue + process > env_1.default.ASSETS_TRANSFORM_MAX_CONCURRENT) {
139
+ if (queue + process > env_1.default['ASSETS_TRANSFORM_MAX_CONCURRENT']) {
140
140
  throw new service_unavailable_1.ServiceUnavailableException('Server too busy', {
141
141
  service: 'files',
142
142
  });
143
143
  }
144
144
  const readStream = await storage.location(file.storage).read(file.filename_disk, range);
145
145
  const transformer = (0, sharp_1.default)({
146
- limitInputPixels: Math.pow(env_1.default.ASSETS_TRANSFORM_IMAGE_MAX_DIMENSION, 2),
146
+ limitInputPixels: Math.pow(env_1.default['ASSETS_TRANSFORM_IMAGE_MAX_DIMENSION'], 2),
147
147
  sequentialRead: true,
148
- failOn: env_1.default.ASSETS_INVALID_IMAGE_SENSITIVITY_LEVEL,
148
+ failOn: env_1.default['ASSETS_INVALID_IMAGE_SENSITIVITY_LEVEL'],
149
149
  });
150
150
  transformer.timeout({
151
- seconds: (0, lodash_1.clamp)(Math.round((0, get_milliseconds_1.getMilliseconds)(env_1.default.ASSETS_TRANSFORM_TIMEOUT, 0) / 1000), 1, 3600),
151
+ seconds: (0, lodash_1.clamp)(Math.round((0, get_milliseconds_1.getMilliseconds)(env_1.default['ASSETS_TRANSFORM_TIMEOUT'], 0) / 1000), 1, 3600),
152
152
  });
153
153
  if (transforms.find((transform) => transform[0] === 'rotate') === undefined)
154
154
  transformer.rotate();
@@ -40,7 +40,7 @@ class AuthenticationService {
40
40
  */
41
41
  async login(providerName = constants_1.DEFAULT_AUTH_PROVIDER, payload, otp) {
42
42
  const { nanoid } = await import('nanoid');
43
- const STALL_TIME = env_1.default.LOGIN_STALL_TIME;
43
+ const STALL_TIME = env_1.default['LOGIN_STALL_TIME'];
44
44
  const timeStart = perf_hooks_1.performance.now();
45
45
  const provider = (0, auth_1.getAuthProvider)(providerName);
46
46
  let userId;
@@ -150,12 +150,12 @@ class AuthenticationService {
150
150
  schema: this.schema,
151
151
  accountability: this.accountability,
152
152
  });
153
- const accessToken = jsonwebtoken_1.default.sign(customClaims, env_1.default.SECRET, {
154
- expiresIn: env_1.default.ACCESS_TOKEN_TTL,
153
+ const accessToken = jsonwebtoken_1.default.sign(customClaims, env_1.default['SECRET'], {
154
+ expiresIn: env_1.default['ACCESS_TOKEN_TTL'],
155
155
  issuer: 'directus',
156
156
  });
157
157
  const refreshToken = nanoid(64);
158
- const refreshTokenExpiration = new Date(Date.now() + (0, get_milliseconds_1.getMilliseconds)(env_1.default.REFRESH_TOKEN_TTL, 0));
158
+ const refreshTokenExpiration = new Date(Date.now() + (0, get_milliseconds_1.getMilliseconds)(env_1.default['REFRESH_TOKEN_TTL'], 0));
159
159
  await this.knex('directus_sessions').insert({
160
160
  token: refreshToken,
161
161
  user: user.id,
@@ -185,7 +185,7 @@ class AuthenticationService {
185
185
  return {
186
186
  accessToken,
187
187
  refreshToken,
188
- expires: (0, get_milliseconds_1.getMilliseconds)(env_1.default.ACCESS_TOKEN_TTL),
188
+ expires: (0, get_milliseconds_1.getMilliseconds)(env_1.default['ACCESS_TOKEN_TTL']),
189
189
  id: user.id,
190
190
  };
191
191
  }
@@ -280,12 +280,12 @@ class AuthenticationService {
280
280
  schema: this.schema,
281
281
  accountability: this.accountability,
282
282
  });
283
- const accessToken = jsonwebtoken_1.default.sign(customClaims, env_1.default.SECRET, {
284
- expiresIn: env_1.default.ACCESS_TOKEN_TTL,
283
+ const accessToken = jsonwebtoken_1.default.sign(customClaims, env_1.default['SECRET'], {
284
+ expiresIn: env_1.default['ACCESS_TOKEN_TTL'],
285
285
  issuer: 'directus',
286
286
  });
287
287
  const newRefreshToken = nanoid(64);
288
- const refreshTokenExpiration = new Date(Date.now() + (0, get_milliseconds_1.getMilliseconds)(env_1.default.REFRESH_TOKEN_TTL, 0));
288
+ const refreshTokenExpiration = new Date(Date.now() + (0, get_milliseconds_1.getMilliseconds)(env_1.default['REFRESH_TOKEN_TTL'], 0));
289
289
  await this.knex('directus_sessions')
290
290
  .update({
291
291
  token: newRefreshToken,
@@ -298,7 +298,7 @@ class AuthenticationService {
298
298
  return {
299
299
  accessToken,
300
300
  refreshToken: newRefreshToken,
301
- expires: (0, get_milliseconds_1.getMilliseconds)(env_1.default.ACCESS_TOKEN_TTL),
301
+ expires: (0, get_milliseconds_1.getMilliseconds)(env_1.default['ACCESS_TOKEN_TTL']),
302
302
  id: record.user_id,
303
303
  };
304
304
  }