directus 9.3.0 → 9.4.3

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 (92) hide show
  1. package/dist/app.js +25 -4
  2. package/dist/auth/auth.d.ts +4 -6
  3. package/dist/auth/auth.js +5 -9
  4. package/dist/auth/drivers/ldap.d.ts +3 -3
  5. package/dist/auth/drivers/ldap.js +2 -3
  6. package/dist/auth/drivers/local.d.ts +2 -2
  7. package/dist/auth/drivers/local.js +7 -13
  8. package/dist/auth/drivers/oauth2.d.ts +3 -3
  9. package/dist/auth/drivers/oauth2.js +4 -4
  10. package/dist/auth/drivers/openid.d.ts +3 -3
  11. package/dist/auth/drivers/openid.js +4 -4
  12. package/dist/cache.js +1 -3
  13. package/dist/cli/commands/schema/apply.js +1 -1
  14. package/dist/cli/index.js +1 -1
  15. package/dist/constants.d.ts +8 -0
  16. package/dist/constants.js +16 -2
  17. package/dist/controllers/activity.js +2 -1
  18. package/dist/controllers/auth.js +5 -4
  19. package/dist/controllers/extensions.js +1 -1
  20. package/dist/controllers/shares.d.ts +2 -0
  21. package/dist/controllers/shares.js +212 -0
  22. package/dist/controllers/users.js +21 -9
  23. package/dist/database/index.js +3 -0
  24. package/dist/database/migrations/20211211A-add-shares.d.ts +3 -0
  25. package/dist/database/migrations/20211211A-add-shares.js +38 -0
  26. package/dist/database/migrations/20211230A-add-project-descriptor.d.ts +3 -0
  27. package/dist/database/migrations/20211230A-add-project-descriptor.js +15 -0
  28. package/dist/database/migrations/run.js +1 -1
  29. package/dist/database/run-ast.js +5 -5
  30. package/dist/database/system-data/app-access-permissions/app-access-permissions.yaml +0 -15
  31. package/dist/database/system-data/app-access-permissions/index.d.ts +1 -0
  32. package/dist/database/system-data/app-access-permissions/index.js +4 -2
  33. package/dist/database/system-data/app-access-permissions/schema-access-permissions.yaml +17 -0
  34. package/dist/database/system-data/collections/collections.yaml +3 -0
  35. package/dist/database/system-data/fields/_defaults.yaml +2 -0
  36. package/dist/database/system-data/fields/sessions.yaml +1 -1
  37. package/dist/database/system-data/fields/settings.yaml +20 -1
  38. package/dist/database/system-data/fields/shares.yaml +77 -0
  39. package/dist/database/system-data/fields/users.yaml +1 -1
  40. package/dist/database/system-data/relations/relations.yaml +15 -0
  41. package/dist/env.js +4 -1
  42. package/dist/extensions.d.ts +11 -6
  43. package/dist/extensions.js +97 -42
  44. package/dist/middleware/authenticate.js +7 -16
  45. package/dist/middleware/check-ip.js +9 -6
  46. package/dist/middleware/rate-limiter.js +2 -1
  47. package/dist/middleware/respond.js +4 -1
  48. package/dist/services/activity.d.ts +2 -1
  49. package/dist/services/activity.js +2 -2
  50. package/dist/services/assets.js +3 -3
  51. package/dist/services/authentication.d.ts +2 -7
  52. package/dist/services/authentication.js +84 -41
  53. package/dist/services/authorization.js +3 -3
  54. package/dist/services/collections.d.ts +1 -2
  55. package/dist/services/collections.js +2 -2
  56. package/dist/services/files.d.ts +2 -2
  57. package/dist/services/graphql.d.ts +1 -1
  58. package/dist/services/graphql.js +51 -10
  59. package/dist/services/index.d.ts +1 -0
  60. package/dist/services/index.js +1 -0
  61. package/dist/services/items.d.ts +1 -15
  62. package/dist/services/notifications.d.ts +2 -2
  63. package/dist/services/permissions.d.ts +2 -2
  64. package/dist/services/roles.d.ts +2 -2
  65. package/dist/services/server.js +1 -0
  66. package/dist/services/shares.d.ts +17 -0
  67. package/dist/services/shares.js +135 -0
  68. package/dist/services/specifications.js +1 -1
  69. package/dist/services/users.d.ts +2 -2
  70. package/dist/services/webhooks.d.ts +2 -2
  71. package/dist/types/ast.d.ts +3 -3
  72. package/dist/types/auth.d.ts +31 -0
  73. package/dist/types/items.d.ts +14 -0
  74. package/dist/utils/apply-query.d.ts +0 -38
  75. package/dist/utils/apply-query.js +66 -67
  76. package/dist/utils/get-ast-from-query.js +3 -3
  77. package/dist/utils/get-default-value.js +3 -1
  78. package/dist/utils/get-ip-from-req.d.ts +2 -0
  79. package/dist/utils/get-ip-from-req.js +24 -0
  80. package/dist/utils/get-local-type.js +1 -1
  81. package/dist/utils/get-permissions.js +15 -7
  82. package/dist/utils/get-relation-type.d.ts +1 -1
  83. package/dist/utils/get-relation-type.js +1 -1
  84. package/dist/utils/merge-permissions-for-share.d.ts +5 -0
  85. package/dist/utils/merge-permissions-for-share.js +116 -0
  86. package/dist/utils/merge-permissions.d.ts +13 -1
  87. package/dist/utils/merge-permissions.js +27 -19
  88. package/dist/utils/reduce-schema.d.ts +2 -2
  89. package/dist/utils/reduce-schema.js +7 -7
  90. package/dist/utils/user-name.js +3 -0
  91. package/example.env +1 -1
  92. package/package.json +15 -13
@@ -12,6 +12,9 @@ defaults:
12
12
  sort_field: null
13
13
 
14
14
  data:
15
+ - many_collection: directus_collections
16
+ many_field: group
17
+ one_collection: directus_collections
15
18
  - many_collection: directus_users
16
19
  many_field: role
17
20
  one_collection: directus_roles
@@ -73,6 +76,9 @@ data:
73
76
  - many_collection: directus_sessions
74
77
  many_field: user
75
78
  one_collection: directus_users
79
+ - many_collection: directus_sessions
80
+ many_field: share
81
+ one_collection: directus_shares
76
82
  - many_collection: directus_settings
77
83
  many_field: storage_default_folder
78
84
  one_collection: directus_folders
@@ -88,3 +94,12 @@ data:
88
94
  - many_collection: directus_notifications
89
95
  many_field: sender
90
96
  one_collection: directus_users
97
+ - many_collection: directus_shares
98
+ many_field: role
99
+ one_collection: directus_roles
100
+ - many_collection: directus_shares
101
+ many_field: collection
102
+ one_collection: directus_collections
103
+ - many_collection: directus_shares
104
+ many_field: user_created
105
+ one_collection: directus_users
package/dist/env.js CHANGED
@@ -20,7 +20,7 @@ const defaults = {
20
20
  PORT: 8055,
21
21
  PUBLIC_URL: '/',
22
22
  MAX_PAYLOAD_SIZE: '100kb',
23
- DB_EXCLUDE_TABLES: 'spatial_ref_sys',
23
+ DB_EXCLUDE_TABLES: 'spatial_ref_sys,sysdiagrams',
24
24
  STORAGE_LOCATIONS: 'local',
25
25
  STORAGE_LOCAL_DRIVER: 'local',
26
26
  STORAGE_LOCAL_ROOT: './uploads',
@@ -52,6 +52,7 @@ const defaults = {
52
52
  AUTH_PROVIDERS: '',
53
53
  AUTH_DISABLE_DEFAULT: false,
54
54
  EXTENSIONS_PATH: './extensions',
55
+ EXTENSIONS_AUTO_RELOAD: false,
55
56
  EMAIL_FROM: 'no-reply@directus.io',
56
57
  EMAIL_TRANSPORT: 'sendmail',
57
58
  EMAIL_SENDMAIL_NEW_LINE: 'unix',
@@ -61,6 +62,8 @@ const defaults = {
61
62
  ASSETS_TRANSFORM_MAX_CONCURRENT: 1,
62
63
  ASSETS_TRANSFORM_IMAGE_MAX_DIMENSION: 6000,
63
64
  ASSETS_TRANSFORM_MAX_OPERATIONS: 5,
65
+ IP_TRUST_PROXY: true,
66
+ IP_CUSTOM_HEADER: false,
64
67
  SERVE_APP: true,
65
68
  };
66
69
  // Allows us to force certain environment variable into a type, instead of relying
@@ -2,22 +2,27 @@ import { Router } from 'express';
2
2
  import { AppExtensionType, ExtensionType } from '@directus/shared/types';
3
3
  export declare function getExtensionManager(): ExtensionManager;
4
4
  declare class ExtensionManager {
5
- private isInitialized;
5
+ private isLoaded;
6
+ private isScheduleHookEnabled;
6
7
  private extensions;
7
8
  private appExtensions;
8
- private apiHooks;
9
- private apiEndpoints;
9
+ private apiExtensions;
10
10
  private apiEmitter;
11
11
  private endpointRouter;
12
- private isScheduleHookEnabled;
12
+ private watcher;
13
13
  constructor();
14
- initialize({ schedule }?: {
14
+ initialize({ schedule, watch }?: {
15
15
  schedule: boolean;
16
+ watch: boolean;
16
17
  }): Promise<void>;
17
18
  reload(): Promise<void>;
18
- listExtensions(type?: ExtensionType): string[];
19
+ getExtensionsList(type?: ExtensionType): string[];
19
20
  getAppExtensions(type: AppExtensionType): string | undefined;
20
21
  getEndpointRouter(): Router;
22
+ private load;
23
+ private unload;
24
+ private initializeWatcher;
25
+ private updateWatchedExtensions;
21
26
  private getExtensions;
22
27
  private generateExtensionBundles;
23
28
  private getSharedDepsMapping;
@@ -44,6 +44,9 @@ const plugin_virtual_1 = __importDefault(require("@rollup/plugin-virtual"));
44
44
  const plugin_alias_1 = __importDefault(require("@rollup/plugin-alias"));
45
45
  const url_1 = require("./utils/url");
46
46
  const get_module_default_1 = __importDefault(require("./utils/get-module-default"));
47
+ const lodash_1 = require("lodash");
48
+ const chokidar_1 = __importDefault(require("chokidar"));
49
+ const utils_1 = require("@directus/shared/utils");
47
50
  let extensionManager;
48
51
  function getExtensionManager() {
49
52
  if (extensionManager) {
@@ -55,19 +58,66 @@ function getExtensionManager() {
55
58
  exports.getExtensionManager = getExtensionManager;
56
59
  class ExtensionManager {
57
60
  constructor() {
58
- this.isInitialized = false;
61
+ this.isLoaded = false;
62
+ this.isScheduleHookEnabled = true;
59
63
  this.extensions = [];
60
64
  this.appExtensions = {};
61
- this.apiHooks = [];
62
- this.apiEndpoints = [];
63
- this.isScheduleHookEnabled = true;
65
+ this.apiExtensions = { hooks: [], endpoints: [] };
66
+ this.watcher = null;
64
67
  this.apiEmitter = new emitter_1.Emitter();
65
68
  this.endpointRouter = (0, express_1.Router)();
66
69
  }
67
- async initialize({ schedule } = { schedule: true }) {
70
+ async initialize({ schedule, watch } = { schedule: true, watch: true }) {
68
71
  this.isScheduleHookEnabled = schedule;
69
- if (this.isInitialized)
70
- return;
72
+ if (watch) {
73
+ this.initializeWatcher();
74
+ }
75
+ if (!this.isLoaded) {
76
+ await this.load();
77
+ this.updateWatchedExtensions(this.extensions);
78
+ const loadedExtensions = this.getExtensionsList();
79
+ if (loadedExtensions.length > 0) {
80
+ logger_1.default.info(`Loaded extensions: ${loadedExtensions.join(', ')}`);
81
+ }
82
+ }
83
+ }
84
+ async reload() {
85
+ if (this.isLoaded) {
86
+ logger_1.default.info('Reloading extensions');
87
+ const prevExtensions = (0, lodash_1.clone)(this.extensions);
88
+ await this.unload();
89
+ await this.load();
90
+ const added = this.extensions.filter((extension) => !prevExtensions.some((prevExtension) => extension.path === prevExtension.path));
91
+ const removed = prevExtensions.filter((prevExtension) => !this.extensions.some((extension) => prevExtension.path === extension.path));
92
+ this.updateWatchedExtensions(added, removed);
93
+ const addedExtensions = added.map((extension) => extension.name);
94
+ const removedExtensions = removed.map((extension) => extension.name);
95
+ if (addedExtensions.length > 0) {
96
+ logger_1.default.info(`Added extensions: ${addedExtensions.join(', ')}`);
97
+ }
98
+ if (removedExtensions.length > 0) {
99
+ logger_1.default.info(`Removed extensions: ${removedExtensions.join(', ')}`);
100
+ }
101
+ }
102
+ else {
103
+ logger_1.default.warn('Extensions have to be loaded before they can be reloaded');
104
+ }
105
+ }
106
+ getExtensionsList(type) {
107
+ if (type === undefined) {
108
+ return this.extensions.map((extension) => extension.name);
109
+ }
110
+ else {
111
+ return this.extensions.filter((extension) => extension.type === type).map((extension) => extension.name);
112
+ }
113
+ }
114
+ getAppExtensions(type) {
115
+ return this.appExtensions[type];
116
+ }
117
+ getEndpointRouter() {
118
+ return this.endpointRouter;
119
+ }
120
+ async load() {
71
121
  try {
72
122
  await (0, node_1.ensureExtensionDirs)(env_1.default.EXTENSIONS_PATH, env_1.default.SERVE_APP ? constants_1.EXTENSION_TYPES : constants_1.API_EXTENSION_TYPES);
73
123
  this.extensions = await this.getExtensions();
@@ -81,38 +131,42 @@ class ExtensionManager {
81
131
  if (env_1.default.SERVE_APP) {
82
132
  this.appExtensions = await this.generateExtensionBundles();
83
133
  }
84
- const loadedExtensions = this.listExtensions();
85
- if (loadedExtensions.length > 0) {
86
- logger_1.default.info(`Loaded extensions: ${loadedExtensions.join(', ')}`);
87
- }
88
- this.isInitialized = true;
134
+ this.isLoaded = true;
89
135
  }
90
- async reload() {
91
- if (!this.isInitialized)
92
- return;
93
- logger_1.default.info('Reloading extensions');
136
+ async unload() {
94
137
  this.unregisterHooks();
95
138
  this.unregisterEndpoints();
96
139
  this.apiEmitter.offAll();
97
140
  if (env_1.default.SERVE_APP) {
98
141
  this.appExtensions = {};
99
142
  }
100
- this.isInitialized = false;
101
- await this.initialize();
143
+ this.isLoaded = false;
102
144
  }
103
- listExtensions(type) {
104
- if (type === undefined) {
105
- return this.extensions.map((extension) => extension.name);
106
- }
107
- else {
108
- return this.extensions.filter((extension) => extension.type === type).map((extension) => extension.name);
145
+ initializeWatcher() {
146
+ if (env_1.default.EXTENSIONS_AUTO_RELOAD && env_1.default.NODE_ENV !== 'development' && !this.watcher) {
147
+ logger_1.default.info('Watching extensions for changes...');
148
+ const localExtensionPaths = (env_1.default.SERVE_APP ? constants_1.EXTENSION_TYPES : constants_1.API_EXTENSION_TYPES).map((type) => path_1.default.resolve(env_1.default.EXTENSIONS_PATH, (0, utils_1.pluralize)(type)));
149
+ this.watcher = chokidar_1.default.watch([path_1.default.resolve('.', 'package.json'), ...localExtensionPaths], {
150
+ ignoreInitial: true,
151
+ });
152
+ this.watcher
153
+ .on('add', () => this.reload())
154
+ .on('change', () => this.reload())
155
+ .on('unlink', () => this.reload());
109
156
  }
110
157
  }
111
- getAppExtensions(type) {
112
- return this.appExtensions[type];
113
- }
114
- getEndpointRouter() {
115
- return this.endpointRouter;
158
+ updateWatchedExtensions(added, removed = []) {
159
+ if (this.watcher) {
160
+ const toPackageExtensionPaths = (extensions) => extensions
161
+ .filter((extension) => !extension.local)
162
+ .map((extension) => extension.type !== 'pack'
163
+ ? path_1.default.resolve(extension.path, extension.entrypoint || '')
164
+ : path_1.default.resolve(extension.path, 'package.json'));
165
+ const addedPackageExtensionPaths = toPackageExtensionPaths(added);
166
+ const removedPackageExtensionPaths = toPackageExtensionPaths(removed);
167
+ this.watcher.add(addedPackageExtensionPaths);
168
+ this.watcher.unwatch(removedPackageExtensionPaths);
169
+ }
116
170
  }
117
171
  async getExtensions() {
118
172
  const packageExtensions = await (0, node_1.getPackageExtensions)('.', env_1.default.SERVE_APP ? constants_1.EXTENSION_PACKAGE_TYPES : constants_1.API_EXTENSION_PACKAGE_TYPES);
@@ -141,12 +195,13 @@ class ExtensionManager {
141
195
  return bundles;
142
196
  }
143
197
  async getSharedDepsMapping(deps) {
144
- const appDir = await fs_extra_1.default.readdir(path_1.default.join((0, node_1.resolvePackage)('@directus/app'), 'dist'));
198
+ const appDir = await fs_extra_1.default.readdir(path_1.default.join((0, node_1.resolvePackage)('@directus/app'), 'dist', 'assets'));
145
199
  const depsMapping = {};
146
200
  for (const dep of deps) {
147
- const depName = appDir.find((file) => dep.replace(/\//g, '_') === file.substring(0, file.indexOf('.')));
201
+ const depRegex = new RegExp(`${(0, lodash_1.escapeRegExp)(dep.replace(/\//g, '_'))}\\.[0-9a-f]{8}\\.entry\\.js`);
202
+ const depName = appDir.find((file) => depRegex.test(file));
148
203
  if (depName) {
149
- const depUrl = new url_1.Url(env_1.default.PUBLIC_URL).addPath('admin', depName);
204
+ const depUrl = new url_1.Url(env_1.default.PUBLIC_URL).addPath('admin', 'assets', depName);
150
205
  depsMapping[dep] = depUrl.toString({ rootRelative: true });
151
206
  }
152
207
  else {
@@ -186,7 +241,7 @@ class ExtensionManager {
186
241
  const registerFunctions = {
187
242
  filter: (event, handler) => {
188
243
  emitter_1.default.onFilter(event, handler);
189
- this.apiHooks.push({
244
+ this.apiExtensions.hooks.push({
190
245
  type: 'filter',
191
246
  path: hookPath,
192
247
  event,
@@ -195,7 +250,7 @@ class ExtensionManager {
195
250
  },
196
251
  action: (event, handler) => {
197
252
  emitter_1.default.onAction(event, handler);
198
- this.apiHooks.push({
253
+ this.apiExtensions.hooks.push({
199
254
  type: 'action',
200
255
  path: hookPath,
201
256
  event,
@@ -204,7 +259,7 @@ class ExtensionManager {
204
259
  },
205
260
  init: (event, handler) => {
206
261
  emitter_1.default.onInit(event, handler);
207
- this.apiHooks.push({
262
+ this.apiExtensions.hooks.push({
208
263
  type: 'init',
209
264
  path: hookPath,
210
265
  event,
@@ -223,7 +278,7 @@ class ExtensionManager {
223
278
  }
224
279
  }
225
280
  });
226
- this.apiHooks.push({
281
+ this.apiExtensions.hooks.push({
227
282
  type: 'schedule',
228
283
  path: hookPath,
229
284
  task,
@@ -261,12 +316,12 @@ class ExtensionManager {
261
316
  logger: logger_1.default,
262
317
  getSchema: get_schema_1.getSchema,
263
318
  });
264
- this.apiEndpoints.push({
319
+ this.apiExtensions.endpoints.push({
265
320
  path: endpointPath,
266
321
  });
267
322
  }
268
323
  unregisterHooks() {
269
- for (const hook of this.apiHooks) {
324
+ for (const hook of this.apiExtensions.hooks) {
270
325
  switch (hook.type) {
271
326
  case 'filter':
272
327
  emitter_1.default.offFilter(hook.event, hook.handler);
@@ -278,18 +333,18 @@ class ExtensionManager {
278
333
  emitter_1.default.offInit(hook.event, hook.handler);
279
334
  break;
280
335
  case 'schedule':
281
- hook.task.destroy();
336
+ hook.task.stop();
282
337
  break;
283
338
  }
284
339
  delete require.cache[require.resolve(hook.path)];
285
340
  }
286
- this.apiHooks = [];
341
+ this.apiExtensions.hooks = [];
287
342
  }
288
343
  unregisterEndpoints() {
289
- for (const endpoint of this.apiEndpoints) {
344
+ for (const endpoint of this.apiExtensions.endpoints) {
290
345
  delete require.cache[require.resolve(endpoint.path)];
291
346
  }
292
347
  this.endpointRouter.stack = [];
293
- this.apiEndpoints = [];
348
+ this.apiExtensions.endpoints = [];
294
349
  }
295
350
  }
@@ -27,6 +27,7 @@ const database_1 = __importDefault(require("../database"));
27
27
  const env_1 = __importDefault(require("../env"));
28
28
  const exceptions_1 = require("../exceptions");
29
29
  const async_handler_1 = __importDefault(require("../utils/async-handler"));
30
+ const get_ip_from_req_1 = require("../utils/get-ip-from-req");
30
31
  const is_directus_jwt_1 = __importDefault(require("../utils/is-directus-jwt"));
31
32
  /**
32
33
  * Verify the passed JWT and assign the user ID and role to `req`
@@ -37,7 +38,7 @@ const authenticate = (0, async_handler_1.default)(async (req, res, next) => {
37
38
  role: null,
38
39
  admin: false,
39
40
  app: false,
40
- ip: req.ip.startsWith('::ffff:') ? req.ip.substring(7) : req.ip,
41
+ ip: (0, get_ip_from_req_1.getIPFromReq)(req),
41
42
  userAgent: req.get('user-agent'),
42
43
  };
43
44
  const database = (0, database_1.default)();
@@ -58,22 +59,12 @@ const authenticate = (0, async_handler_1.default)(async (req, res, next) => {
58
59
  throw err;
59
60
  }
60
61
  }
61
- const user = await database
62
- .select('directus_users.role', 'directus_roles.admin_access', 'directus_roles.app_access')
63
- .from('directus_users')
64
- .leftJoin('directus_roles', 'directus_users.role', 'directus_roles.id')
65
- .where({
66
- 'directus_users.id': payload.id,
67
- status: 'active',
68
- })
69
- .first();
70
- if (!user) {
71
- throw new exceptions_1.InvalidCredentialsException();
72
- }
62
+ req.accountability.share = payload.share;
63
+ req.accountability.share_scope = payload.share_scope;
73
64
  req.accountability.user = payload.id;
74
- req.accountability.role = user.role;
75
- req.accountability.admin = user.admin_access === true || user.admin_access == 1;
76
- req.accountability.app = user.app_access === true || user.app_access == 1;
65
+ req.accountability.role = payload.role;
66
+ req.accountability.admin = payload.admin_access === true || payload.admin_access == 1;
67
+ req.accountability.app = payload.app_access === true || payload.app_access == 1;
77
68
  }
78
69
  else {
79
70
  // Try finding the user with the provided token
@@ -7,13 +7,16 @@ exports.checkIP = void 0;
7
7
  const database_1 = __importDefault(require("../database"));
8
8
  const exceptions_1 = require("../exceptions");
9
9
  const async_handler_1 = __importDefault(require("../utils/async-handler"));
10
- exports.checkIP = (0, async_handler_1.default)(async (req, res, next) => {
10
+ exports.checkIP = (0, async_handler_1.default)(async (req, _res, next) => {
11
11
  const database = (0, database_1.default)();
12
- const role = await database
13
- .select('ip_access')
14
- .from('directus_roles')
15
- .where({ id: req.accountability.role })
16
- .first();
12
+ const query = database.select('ip_access').from('directus_roles');
13
+ if (req.accountability.role) {
14
+ query.where({ id: req.accountability.role });
15
+ }
16
+ else {
17
+ query.whereNull('id');
18
+ }
19
+ const role = await query.first();
17
20
  const ipAllowlist = ((role === null || role === void 0 ? void 0 : role.ip_access) || '').split(',').filter((ip) => ip);
18
21
  if (ipAllowlist.length > 0 && ipAllowlist.includes(req.accountability.ip) === false)
19
22
  throw new exceptions_1.InvalidIPException();
@@ -9,6 +9,7 @@ const env_1 = __importDefault(require("../env"));
9
9
  const exceptions_1 = require("../exceptions");
10
10
  const rate_limiter_1 = require("../rate-limiter");
11
11
  const async_handler_1 = __importDefault(require("../utils/async-handler"));
12
+ const get_ip_from_req_1 = require("../utils/get-ip-from-req");
12
13
  const validate_env_1 = require("../utils/validate-env");
13
14
  let checkRateLimit = (req, res, next) => next();
14
15
  if (env_1.default.RATE_LIMITER_ENABLED === true) {
@@ -16,7 +17,7 @@ if (env_1.default.RATE_LIMITER_ENABLED === true) {
16
17
  exports.rateLimiter = (0, rate_limiter_1.createRateLimiter)();
17
18
  checkRateLimit = (0, async_handler_1.default)(async (req, res, next) => {
18
19
  try {
19
- await exports.rateLimiter.consume(req.ip, 1);
20
+ await exports.rateLimiter.consume((0, get_ip_from_req_1.getIPFromReq)(req), 1);
20
21
  }
21
22
  catch (rateLimiterRes) {
22
23
  if (rateLimiterRes instanceof Error)
@@ -77,9 +77,12 @@ exports.respond = (0, async_handler_1.default)(async (req, res) => {
77
77
  if (Buffer.isBuffer(res.locals.payload)) {
78
78
  return res.end(res.locals.payload);
79
79
  }
80
- else {
80
+ else if (res.locals.payload) {
81
81
  return res.json(res.locals.payload);
82
82
  }
83
+ else {
84
+ return res.status(204).end();
85
+ }
83
86
  });
84
87
  function getDateFormatted() {
85
88
  const date = new Date();
@@ -1,5 +1,6 @@
1
1
  import { AbstractServiceOptions, PrimaryKey, Item } from '../types';
2
- import { ItemsService, MutationOptions } from './index';
2
+ import { ItemsService } from './items';
3
+ import { MutationOptions } from '../types';
3
4
  import { NotificationsService } from './notifications';
4
5
  import { UsersService } from './users';
5
6
  export declare class ActivityService extends ItemsService {
@@ -5,7 +5,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.ActivityService = void 0;
7
7
  const types_1 = require("../types");
8
- const index_1 = require("./index");
8
+ const items_1 = require("./items");
9
9
  const notifications_1 = require("./notifications");
10
10
  const users_1 = require("./users");
11
11
  const authorization_1 = require("./authorization");
@@ -16,7 +16,7 @@ const user_name_1 = require("../utils/user-name");
16
16
  const lodash_1 = require("lodash");
17
17
  const env_1 = __importDefault(require("../env"));
18
18
  const uuid_validate_1 = __importDefault(require("uuid-validate"));
19
- class ActivityService extends index_1.ItemsService {
19
+ class ActivityService extends items_1.ItemsService {
20
20
  constructor(options) {
21
21
  super('directus_activity', options);
22
22
  this.notificationsService = new notifications_1.NotificationsService({ schema: this.schema });
@@ -52,9 +52,6 @@ class AssetsService {
52
52
  .from('directus_settings')
53
53
  .first();
54
54
  const systemPublicKeys = Object.values(publicSettings || {});
55
- if (systemPublicKeys.includes(id) === false && ((_a = this.accountability) === null || _a === void 0 ? void 0 : _a.admin) !== true) {
56
- await this.authorizationService.checkAccess('read', 'directus_files', id);
57
- }
58
55
  /**
59
56
  * This is a little annoying. Postgres will error out if you're trying to search in `where`
60
57
  * with a wrong type. In case of directus_files where id is a uuid, we'll have to verify the
@@ -63,6 +60,9 @@ class AssetsService {
63
60
  const isValidUUID = (0, uuid_validate_1.default)(id, 4);
64
61
  if (isValidUUID === false)
65
62
  throw new exceptions_1.ForbiddenException();
63
+ if (systemPublicKeys.includes(id) === false && ((_a = this.accountability) === null || _a === void 0 ? void 0 : _a.admin) !== true) {
64
+ await this.authorizationService.checkAccess('read', 'directus_files', id);
65
+ }
66
66
  const file = (await this.knex.select('*').from('directus_files').where({ id }).first());
67
67
  if (!file)
68
68
  throw new exceptions_1.ForbiddenException();
@@ -1,6 +1,6 @@
1
1
  import { Knex } from 'knex';
2
2
  import { ActivityService } from './activity';
3
- import { AbstractServiceOptions, SchemaOverview } from '../types';
3
+ import { AbstractServiceOptions, SchemaOverview, LoginResult } from '../types';
4
4
  import { Accountability } from '@directus/shared/types';
5
5
  export declare class AuthenticationService {
6
6
  knex: Knex;
@@ -14,12 +14,7 @@ export declare class AuthenticationService {
14
14
  * Password is optional to allow usage of this function within the SSO flow and extensions. Make sure
15
15
  * to handle password existence checks elsewhere
16
16
  */
17
- login(providerName: string | undefined, payload: Record<string, any>, otp?: string): Promise<{
18
- accessToken: any;
19
- refreshToken: any;
20
- expires: any;
21
- id?: any;
22
- }>;
17
+ login(providerName: string | undefined, payload: Record<string, any>, otp?: string): Promise<LoginResult>;
23
18
  refresh(refreshToken: string): Promise<Record<string, any>>;
24
19
  logout(refreshToken: string): Promise<void>;
25
20
  verifyPassword(userID: string, password: string): Promise<void>;