@directus/api 21.0.0-rc.0 → 21.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (285) hide show
  1. package/dist/app.js +5 -5
  2. package/dist/auth/drivers/ldap.js +4 -4
  3. package/dist/auth/drivers/local.js +4 -4
  4. package/dist/auth/drivers/oauth2.js +4 -4
  5. package/dist/auth/drivers/openid.js +4 -2
  6. package/dist/cache.d.ts +0 -1
  7. package/dist/cache.js +7 -25
  8. package/dist/cli/commands/bootstrap/index.js +2 -8
  9. package/dist/cli/commands/init/index.js +10 -9
  10. package/dist/cli/utils/defaults.d.ts +11 -4
  11. package/dist/cli/utils/defaults.js +1 -7
  12. package/dist/constants.d.ts +1 -1
  13. package/dist/controllers/auth.js +16 -5
  14. package/dist/controllers/permissions.js +2 -14
  15. package/dist/controllers/roles.js +1 -22
  16. package/dist/controllers/tus.js +27 -13
  17. package/dist/controllers/users.js +55 -0
  18. package/dist/database/helpers/fn/types.d.ts +1 -2
  19. package/dist/database/helpers/fn/types.js +1 -1
  20. package/dist/database/helpers/geometry/dialects/mssql.d.ts +1 -1
  21. package/dist/database/helpers/geometry/dialects/mssql.js +2 -4
  22. package/dist/database/helpers/geometry/dialects/mysql.js +1 -1
  23. package/dist/database/helpers/geometry/dialects/oracle.d.ts +1 -1
  24. package/dist/database/helpers/geometry/dialects/oracle.js +3 -5
  25. package/dist/database/helpers/geometry/types.d.ts +1 -1
  26. package/dist/database/helpers/geometry/types.js +2 -4
  27. package/dist/database/index.js +11 -8
  28. package/dist/database/migrations/20240305A-change-useragent-type.js +1 -1
  29. package/dist/database/migrations/20240716A-update-files-date-fields.js +33 -0
  30. package/dist/database/{run-ast/types.d.ts → run-ast.d.ts} +9 -3
  31. package/dist/database/run-ast.js +458 -0
  32. package/dist/flows.js +4 -3
  33. package/dist/logger/index.js +1 -1
  34. package/dist/middleware/authenticate.js +7 -2
  35. package/dist/middleware/cache.js +1 -1
  36. package/dist/middleware/check-ip.d.ts +2 -0
  37. package/dist/middleware/check-ip.js +37 -0
  38. package/dist/middleware/error-handler.d.ts +2 -2
  39. package/dist/middleware/error-handler.js +54 -51
  40. package/dist/middleware/get-permissions.d.ts +3 -0
  41. package/dist/middleware/get-permissions.js +10 -0
  42. package/dist/middleware/respond.js +1 -1
  43. package/dist/services/activity.js +10 -22
  44. package/dist/services/assets.d.ts +3 -2
  45. package/dist/services/assets.js +7 -15
  46. package/dist/services/authentication.js +18 -18
  47. package/dist/services/authorization.d.ts +17 -0
  48. package/dist/services/authorization.js +456 -0
  49. package/dist/services/collections.js +17 -18
  50. package/dist/services/fields.d.ts +4 -0
  51. package/dist/services/fields.js +53 -58
  52. package/dist/services/files/lib/get-sharp-instance.d.ts +2 -0
  53. package/dist/services/files/lib/get-sharp-instance.js +10 -0
  54. package/dist/services/files/utils/get-metadata.js +7 -6
  55. package/dist/services/files.js +8 -10
  56. package/dist/services/graphql/index.d.ts +3 -3
  57. package/dist/services/graphql/index.js +22 -126
  58. package/dist/services/graphql/subscription.js +4 -2
  59. package/dist/services/import-export.js +4 -18
  60. package/dist/services/index.d.ts +2 -3
  61. package/dist/services/index.js +2 -3
  62. package/dist/services/items.js +44 -115
  63. package/dist/services/mail/index.d.ts +1 -1
  64. package/dist/services/mail/index.js +9 -1
  65. package/dist/services/meta.js +23 -60
  66. package/dist/services/notifications.js +6 -14
  67. package/dist/services/payload.d.ts +10 -9
  68. package/dist/services/payload.js +3 -18
  69. package/dist/services/{permissions.d.ts → permissions/index.d.ts} +7 -5
  70. package/dist/services/{permissions.js → permissions/index.js} +54 -30
  71. package/dist/{permissions → services/permissions}/lib/with-app-minimal-permissions.d.ts +1 -1
  72. package/dist/services/permissions/lib/with-app-minimal-permissions.js +13 -0
  73. package/dist/services/relations.d.ts +9 -1
  74. package/dist/services/relations.js +56 -31
  75. package/dist/services/roles.d.ts +12 -4
  76. package/dist/services/roles.js +424 -57
  77. package/dist/services/shares.d.ts +2 -0
  78. package/dist/services/shares.js +8 -12
  79. package/dist/services/specifications.d.ts +2 -2
  80. package/dist/services/specifications.js +27 -39
  81. package/dist/services/tus/data-store.js +4 -5
  82. package/dist/services/tus/server.d.ts +1 -1
  83. package/dist/services/tus/server.js +9 -2
  84. package/dist/services/users.d.ts +5 -1
  85. package/dist/services/users.js +161 -78
  86. package/dist/services/utils.js +7 -11
  87. package/dist/services/versions.d.ts +2 -0
  88. package/dist/services/versions.js +10 -34
  89. package/dist/telemetry/lib/get-report.js +2 -2
  90. package/dist/telemetry/utils/check-increased-user-limits.d.ts +7 -0
  91. package/dist/telemetry/utils/check-increased-user-limits.js +25 -0
  92. package/dist/telemetry/utils/get-role-counts-by-roles.d.ts +6 -0
  93. package/dist/telemetry/utils/get-role-counts-by-roles.js +27 -0
  94. package/dist/telemetry/utils/get-role-counts-by-users.d.ts +11 -0
  95. package/dist/telemetry/utils/get-role-counts-by-users.js +34 -0
  96. package/dist/telemetry/utils/get-user-count.d.ts +8 -0
  97. package/dist/telemetry/utils/get-user-count.js +33 -0
  98. package/dist/telemetry/utils/get-user-counts-by-roles.d.ts +7 -0
  99. package/dist/telemetry/utils/get-user-counts-by-roles.js +35 -0
  100. package/dist/types/ast.d.ts +1 -43
  101. package/dist/types/items.d.ts +0 -11
  102. package/dist/utils/apply-query.d.ts +3 -4
  103. package/dist/utils/apply-query.js +16 -39
  104. package/dist/utils/get-accountability-for-role.js +25 -16
  105. package/dist/utils/get-accountability-for-token.js +16 -17
  106. package/dist/utils/get-ast-from-query.d.ts +13 -0
  107. package/dist/utils/get-ast-from-query.js +297 -0
  108. package/dist/utils/get-cache-key.d.ts +1 -1
  109. package/dist/utils/get-cache-key.js +1 -12
  110. package/dist/utils/get-column.d.ts +1 -2
  111. package/dist/utils/get-column.js +0 -1
  112. package/dist/utils/get-permissions.d.ts +2 -0
  113. package/dist/utils/get-permissions.js +150 -0
  114. package/dist/utils/get-schema.js +3 -3
  115. package/dist/utils/get-service.js +1 -5
  116. package/dist/utils/merge-permissions-for-share.d.ts +4 -0
  117. package/dist/utils/merge-permissions-for-share.js +109 -0
  118. package/dist/utils/merge-permissions.d.ts +3 -0
  119. package/dist/utils/merge-permissions.js +95 -0
  120. package/dist/utils/reduce-schema.d.ts +6 -4
  121. package/dist/utils/reduce-schema.js +32 -16
  122. package/dist/websocket/authenticate.d.ts +2 -0
  123. package/dist/websocket/authenticate.js +12 -0
  124. package/dist/websocket/controllers/graphql.js +4 -1
  125. package/dist/websocket/controllers/hooks.js +0 -4
  126. package/dist/websocket/controllers/rest.js +2 -0
  127. package/dist/websocket/handlers/subscribe.js +2 -0
  128. package/dist/websocket/utils/items.d.ts +1 -1
  129. package/package.json +36 -37
  130. package/dist/controllers/access.d.ts +0 -2
  131. package/dist/controllers/access.js +0 -148
  132. package/dist/controllers/policies.d.ts +0 -2
  133. package/dist/controllers/policies.js +0 -169
  134. package/dist/database/get-ast-from-query/get-ast-from-query.d.ts +0 -16
  135. package/dist/database/get-ast-from-query/get-ast-from-query.js +0 -82
  136. package/dist/database/get-ast-from-query/lib/convert-wildcards.d.ts +0 -13
  137. package/dist/database/get-ast-from-query/lib/convert-wildcards.js +0 -69
  138. package/dist/database/get-ast-from-query/lib/parse-fields.d.ts +0 -15
  139. package/dist/database/get-ast-from-query/lib/parse-fields.js +0 -190
  140. package/dist/database/get-ast-from-query/utils/get-deep-query.d.ts +0 -14
  141. package/dist/database/get-ast-from-query/utils/get-deep-query.js +0 -17
  142. package/dist/database/get-ast-from-query/utils/get-related-collection.d.ts +0 -2
  143. package/dist/database/get-ast-from-query/utils/get-related-collection.js +0 -13
  144. package/dist/database/get-ast-from-query/utils/get-relation.d.ts +0 -2
  145. package/dist/database/get-ast-from-query/utils/get-relation.js +0 -7
  146. package/dist/database/migrations/20240710A-permissions-policies.js +0 -169
  147. package/dist/database/run-ast/lib/get-db-query.d.ts +0 -4
  148. package/dist/database/run-ast/lib/get-db-query.js +0 -208
  149. package/dist/database/run-ast/lib/parse-current-level.d.ts +0 -7
  150. package/dist/database/run-ast/lib/parse-current-level.js +0 -41
  151. package/dist/database/run-ast/run-ast.d.ts +0 -7
  152. package/dist/database/run-ast/run-ast.js +0 -107
  153. package/dist/database/run-ast/types.js +0 -1
  154. package/dist/database/run-ast/utils/apply-case-when.d.ts +0 -16
  155. package/dist/database/run-ast/utils/apply-case-when.js +0 -26
  156. package/dist/database/run-ast/utils/apply-parent-filters.d.ts +0 -3
  157. package/dist/database/run-ast/utils/apply-parent-filters.js +0 -55
  158. package/dist/database/run-ast/utils/get-column-pre-processor.d.ts +0 -10
  159. package/dist/database/run-ast/utils/get-column-pre-processor.js +0 -57
  160. package/dist/database/run-ast/utils/get-field-alias.d.ts +0 -2
  161. package/dist/database/run-ast/utils/get-field-alias.js +0 -4
  162. package/dist/database/run-ast/utils/get-inner-query-column-pre-processor.d.ts +0 -5
  163. package/dist/database/run-ast/utils/get-inner-query-column-pre-processor.js +0 -23
  164. package/dist/database/run-ast/utils/merge-with-parent-items.d.ts +0 -3
  165. package/dist/database/run-ast/utils/merge-with-parent-items.js +0 -87
  166. package/dist/database/run-ast/utils/remove-temporary-fields.d.ts +0 -3
  167. package/dist/database/run-ast/utils/remove-temporary-fields.js +0 -73
  168. package/dist/permissions/cache.d.ts +0 -2
  169. package/dist/permissions/cache.js +0 -23
  170. package/dist/permissions/lib/fetch-permissions.d.ts +0 -10
  171. package/dist/permissions/lib/fetch-permissions.js +0 -55
  172. package/dist/permissions/lib/fetch-policies.d.ts +0 -7
  173. package/dist/permissions/lib/fetch-policies.js +0 -28
  174. package/dist/permissions/lib/fetch-roles-tree.d.ts +0 -3
  175. package/dist/permissions/lib/fetch-roles-tree.js +0 -28
  176. package/dist/permissions/lib/with-app-minimal-permissions.js +0 -10
  177. package/dist/permissions/modules/fetch-accountability-collection-access/fetch-accountability-collection-access.d.ts +0 -7
  178. package/dist/permissions/modules/fetch-accountability-collection-access/fetch-accountability-collection-access.js +0 -56
  179. package/dist/permissions/modules/fetch-accountability-policy-globals/fetch-accountability-policy-globals.d.ts +0 -3
  180. package/dist/permissions/modules/fetch-accountability-policy-globals/fetch-accountability-policy-globals.js +0 -16
  181. package/dist/permissions/modules/fetch-allowed-collections/fetch-allowed-collections.d.ts +0 -8
  182. package/dist/permissions/modules/fetch-allowed-collections/fetch-allowed-collections.js +0 -24
  183. package/dist/permissions/modules/fetch-allowed-field-map/fetch-allowed-field-map.d.ts +0 -9
  184. package/dist/permissions/modules/fetch-allowed-field-map/fetch-allowed-field-map.js +0 -31
  185. package/dist/permissions/modules/fetch-allowed-fields/fetch-allowed-fields.d.ts +0 -16
  186. package/dist/permissions/modules/fetch-allowed-fields/fetch-allowed-fields.js +0 -27
  187. package/dist/permissions/modules/fetch-global-access/fetch-global-access.d.ts +0 -10
  188. package/dist/permissions/modules/fetch-global-access/fetch-global-access.js +0 -23
  189. package/dist/permissions/modules/fetch-global-access/lib/fetch-global-access-for-roles.d.ts +0 -5
  190. package/dist/permissions/modules/fetch-global-access/lib/fetch-global-access-for-roles.js +0 -7
  191. package/dist/permissions/modules/fetch-global-access/lib/fetch-global-access-for-user.d.ts +0 -5
  192. package/dist/permissions/modules/fetch-global-access/lib/fetch-global-access-for-user.js +0 -10
  193. package/dist/permissions/modules/fetch-global-access/types.d.ts +0 -4
  194. package/dist/permissions/modules/fetch-global-access/types.js +0 -1
  195. package/dist/permissions/modules/fetch-global-access/utils/fetch-global-access-for-query.d.ts +0 -4
  196. package/dist/permissions/modules/fetch-global-access/utils/fetch-global-access-for-query.js +0 -27
  197. package/dist/permissions/modules/fetch-inconsistent-field-map/fetch-inconsistent-field-map.d.ts +0 -12
  198. package/dist/permissions/modules/fetch-inconsistent-field-map/fetch-inconsistent-field-map.js +0 -32
  199. package/dist/permissions/modules/fetch-policies-ip-access/fetch-policies-ip-access.d.ts +0 -4
  200. package/dist/permissions/modules/fetch-policies-ip-access/fetch-policies-ip-access.js +0 -29
  201. package/dist/permissions/modules/process-ast/lib/extract-fields-from-children.d.ts +0 -4
  202. package/dist/permissions/modules/process-ast/lib/extract-fields-from-children.js +0 -49
  203. package/dist/permissions/modules/process-ast/lib/extract-fields-from-query.d.ts +0 -3
  204. package/dist/permissions/modules/process-ast/lib/extract-fields-from-query.js +0 -56
  205. package/dist/permissions/modules/process-ast/lib/field-map-from-ast.d.ts +0 -4
  206. package/dist/permissions/modules/process-ast/lib/field-map-from-ast.js +0 -8
  207. package/dist/permissions/modules/process-ast/lib/inject-cases.d.ts +0 -9
  208. package/dist/permissions/modules/process-ast/lib/inject-cases.js +0 -93
  209. package/dist/permissions/modules/process-ast/process-ast.d.ts +0 -9
  210. package/dist/permissions/modules/process-ast/process-ast.js +0 -39
  211. package/dist/permissions/modules/process-ast/types.d.ts +0 -24
  212. package/dist/permissions/modules/process-ast/types.js +0 -1
  213. package/dist/permissions/modules/process-ast/utils/collections-in-field-map.d.ts +0 -2
  214. package/dist/permissions/modules/process-ast/utils/collections-in-field-map.js +0 -7
  215. package/dist/permissions/modules/process-ast/utils/dedupe-access.d.ts +0 -12
  216. package/dist/permissions/modules/process-ast/utils/dedupe-access.js +0 -30
  217. package/dist/permissions/modules/process-ast/utils/extract-paths-from-query.d.ts +0 -15
  218. package/dist/permissions/modules/process-ast/utils/extract-paths-from-query.js +0 -50
  219. package/dist/permissions/modules/process-ast/utils/find-related-collection.d.ts +0 -3
  220. package/dist/permissions/modules/process-ast/utils/find-related-collection.js +0 -9
  221. package/dist/permissions/modules/process-ast/utils/flatten-filter.d.ts +0 -3
  222. package/dist/permissions/modules/process-ast/utils/flatten-filter.js +0 -34
  223. package/dist/permissions/modules/process-ast/utils/format-a2o-key.d.ts +0 -1
  224. package/dist/permissions/modules/process-ast/utils/format-a2o-key.js +0 -3
  225. package/dist/permissions/modules/process-ast/utils/get-info-for-path.d.ts +0 -5
  226. package/dist/permissions/modules/process-ast/utils/get-info-for-path.js +0 -7
  227. package/dist/permissions/modules/process-ast/utils/has-item-permissions.d.ts +0 -2
  228. package/dist/permissions/modules/process-ast/utils/has-item-permissions.js +0 -3
  229. package/dist/permissions/modules/process-ast/utils/stringify-query-path.d.ts +0 -2
  230. package/dist/permissions/modules/process-ast/utils/stringify-query-path.js +0 -3
  231. package/dist/permissions/modules/process-ast/utils/validate-path/create-error.d.ts +0 -3
  232. package/dist/permissions/modules/process-ast/utils/validate-path/create-error.js +0 -16
  233. package/dist/permissions/modules/process-ast/utils/validate-path/validate-path-existence.d.ts +0 -2
  234. package/dist/permissions/modules/process-ast/utils/validate-path/validate-path-existence.js +0 -12
  235. package/dist/permissions/modules/process-ast/utils/validate-path/validate-path-permissions.d.ts +0 -2
  236. package/dist/permissions/modules/process-ast/utils/validate-path/validate-path-permissions.js +0 -28
  237. package/dist/permissions/modules/process-payload/lib/is-field-nullable.d.ts +0 -5
  238. package/dist/permissions/modules/process-payload/lib/is-field-nullable.js +0 -12
  239. package/dist/permissions/modules/process-payload/process-payload.d.ts +0 -13
  240. package/dist/permissions/modules/process-payload/process-payload.js +0 -77
  241. package/dist/permissions/modules/validate-access/lib/validate-collection-access.d.ts +0 -12
  242. package/dist/permissions/modules/validate-access/lib/validate-collection-access.js +0 -11
  243. package/dist/permissions/modules/validate-access/lib/validate-item-access.d.ts +0 -9
  244. package/dist/permissions/modules/validate-access/lib/validate-item-access.js +0 -33
  245. package/dist/permissions/modules/validate-access/validate-access.d.ts +0 -14
  246. package/dist/permissions/modules/validate-access/validate-access.js +0 -28
  247. package/dist/permissions/modules/validate-remaining-admin/validate-remaining-admin-count.d.ts +0 -1
  248. package/dist/permissions/modules/validate-remaining-admin/validate-remaining-admin-count.js +0 -8
  249. package/dist/permissions/modules/validate-remaining-admin/validate-remaining-admin-users.d.ts +0 -5
  250. package/dist/permissions/modules/validate-remaining-admin/validate-remaining-admin-users.js +0 -10
  251. package/dist/permissions/types.d.ts +0 -6
  252. package/dist/permissions/types.js +0 -1
  253. package/dist/permissions/utils/create-default-accountability.d.ts +0 -2
  254. package/dist/permissions/utils/create-default-accountability.js +0 -11
  255. package/dist/permissions/utils/extract-required-dynamic-variable-context.d.ts +0 -8
  256. package/dist/permissions/utils/extract-required-dynamic-variable-context.js +0 -27
  257. package/dist/permissions/utils/fetch-dynamic-variable-context.d.ts +0 -9
  258. package/dist/permissions/utils/fetch-dynamic-variable-context.js +0 -43
  259. package/dist/permissions/utils/filter-policies-by-ip.d.ts +0 -2
  260. package/dist/permissions/utils/filter-policies-by-ip.js +0 -15
  261. package/dist/permissions/utils/get-unaliased-field-key.d.ts +0 -5
  262. package/dist/permissions/utils/get-unaliased-field-key.js +0 -17
  263. package/dist/permissions/utils/process-permissions.d.ts +0 -7
  264. package/dist/permissions/utils/process-permissions.js +0 -9
  265. package/dist/permissions/utils/with-cache.d.ts +0 -10
  266. package/dist/permissions/utils/with-cache.js +0 -25
  267. package/dist/services/access.d.ts +0 -10
  268. package/dist/services/access.js +0 -43
  269. package/dist/services/policies.d.ts +0 -12
  270. package/dist/services/policies.js +0 -87
  271. package/dist/telemetry/utils/check-user-limits.d.ts +0 -5
  272. package/dist/telemetry/utils/check-user-limits.js +0 -19
  273. package/dist/utils/fetch-user-count/fetch-access-lookup.d.ts +0 -17
  274. package/dist/utils/fetch-user-count/fetch-access-lookup.js +0 -22
  275. package/dist/utils/fetch-user-count/fetch-access-roles.d.ts +0 -16
  276. package/dist/utils/fetch-user-count/fetch-access-roles.js +0 -37
  277. package/dist/utils/fetch-user-count/fetch-active-users.d.ts +0 -6
  278. package/dist/utils/fetch-user-count/fetch-active-users.js +0 -3
  279. package/dist/utils/fetch-user-count/fetch-user-count.d.ts +0 -12
  280. package/dist/utils/fetch-user-count/fetch-user-count.js +0 -57
  281. package/dist/utils/fetch-user-count/get-user-count-query.d.ts +0 -20
  282. package/dist/utils/fetch-user-count/get-user-count-query.js +0 -17
  283. package/dist/utils/validate-user-count-integrity.d.ts +0 -13
  284. package/dist/utils/validate-user-count-integrity.js +0 -29
  285. /package/dist/database/migrations/{20240710A-permissions-policies.d.ts → 20240716A-update-files-date-fields.d.ts} +0 -0
package/dist/app.js CHANGED
@@ -10,7 +10,6 @@ import path from 'path';
10
10
  import qs from 'qs';
11
11
  import { registerAuthProviders } from './auth.js';
12
12
  import activityRouter from './controllers/activity.js';
13
- import accessRouter from './controllers/access.js';
14
13
  import assetsRouter from './controllers/assets.js';
15
14
  import authRouter from './controllers/auth.js';
16
15
  import collectionsRouter from './controllers/collections.js';
@@ -27,7 +26,6 @@ import notificationsRouter from './controllers/notifications.js';
27
26
  import operationsRouter from './controllers/operations.js';
28
27
  import panelsRouter from './controllers/panels.js';
29
28
  import permissionsRouter from './controllers/permissions.js';
30
- import policiesRouter from './controllers/policies.js';
31
29
  import presetsRouter from './controllers/presets.js';
32
30
  import relationsRouter from './controllers/relations.js';
33
31
  import revisionsRouter from './controllers/revisions.js';
@@ -49,9 +47,11 @@ import { getFlowManager } from './flows.js';
49
47
  import { createExpressLogger, useLogger } from './logger/index.js';
50
48
  import authenticate from './middleware/authenticate.js';
51
49
  import cache from './middleware/cache.js';
50
+ import { checkIP } from './middleware/check-ip.js';
52
51
  import cors from './middleware/cors.js';
53
- import errorHandler from './middleware/error-handler.js';
52
+ import { errorHandler } from './middleware/error-handler.js';
54
53
  import extractToken from './middleware/extract-token.js';
54
+ import getPermissions from './middleware/get-permissions.js';
55
55
  import rateLimiterGlobal from './middleware/rate-limiter-global.js';
56
56
  import rateLimiter from './middleware/rate-limiter-ip.js';
57
57
  import sanitizeQuery from './middleware/sanitize-query.js';
@@ -198,15 +198,16 @@ export default async function createApp() {
198
198
  }
199
199
  app.get('/server/ping', (_req, res) => res.send('pong'));
200
200
  app.use(authenticate);
201
+ app.use(checkIP);
201
202
  app.use(sanitizeQuery);
202
203
  app.use(cache);
203
204
  app.use(schema);
205
+ app.use(getPermissions);
204
206
  await emitter.emitInit('middlewares.after', { app });
205
207
  await emitter.emitInit('routes.before', { app });
206
208
  app.use('/auth', authRouter);
207
209
  app.use('/graphql', graphqlRouter);
208
210
  app.use('/activity', activityRouter);
209
- app.use('/access', accessRouter);
210
211
  app.use('/assets', assetsRouter);
211
212
  app.use('/collections', collectionsRouter);
212
213
  app.use('/dashboards', dashboardsRouter);
@@ -223,7 +224,6 @@ export default async function createApp() {
223
224
  app.use('/operations', operationsRouter);
224
225
  app.use('/panels', panelsRouter);
225
226
  app.use('/permissions', permissionsRouter);
226
- app.use('/policies', policiesRouter);
227
227
  app.use('/presets', presetsRouter);
228
228
  app.use('/translations', translationsRouter);
229
229
  app.use('/relations', relationsRouter);
@@ -3,17 +3,16 @@ import { ErrorCode, InvalidCredentialsError, InvalidPayloadError, InvalidProvide
3
3
  import { Router } from 'express';
4
4
  import Joi from 'joi';
5
5
  import ldap from 'ldapjs';
6
- import { REFRESH_COOKIE_OPTIONS, SESSION_COOKIE_OPTIONS } from '../../constants.js';
7
6
  import getDatabase from '../../database/index.js';
8
7
  import emitter from '../../emitter.js';
9
8
  import { useLogger } from '../../logger/index.js';
10
9
  import { respond } from '../../middleware/respond.js';
11
- import { createDefaultAccountability } from '../../permissions/utils/create-default-accountability.js';
12
10
  import { AuthenticationService } from '../../services/authentication.js';
13
11
  import { UsersService } from '../../services/users.js';
14
12
  import asyncHandler from '../../utils/async-handler.js';
15
13
  import { getIPFromReq } from '../../utils/get-ip-from-req.js';
16
14
  import { AuthDriver } from '../auth.js';
15
+ import { REFRESH_COOKIE_OPTIONS, SESSION_COOKIE_OPTIONS } from '../../constants.js';
17
16
  // 0x2: ACCOUNTDISABLE
18
17
  // 0x10: LOCKOUT
19
18
  // 0x800000: PASSWORD_EXPIRED
@@ -296,9 +295,10 @@ export function createLDAPAuthRouter(provider) {
296
295
  }).unknown();
297
296
  router.post('/', asyncHandler(async (req, res, next) => {
298
297
  const env = useEnv();
299
- const accountability = createDefaultAccountability({
298
+ const accountability = {
300
299
  ip: getIPFromReq(req),
301
- });
300
+ role: null,
301
+ };
302
302
  const userAgent = req.get('user-agent')?.substring(0, 1024);
303
303
  if (userAgent)
304
304
  accountability.userAgent = userAgent;
@@ -1,12 +1,11 @@
1
- import { useEnv } from '@directus/env';
2
1
  import { InvalidCredentialsError, InvalidPayloadError } from '@directus/errors';
3
2
  import argon2 from 'argon2';
4
3
  import { Router } from 'express';
5
4
  import Joi from 'joi';
6
5
  import { performance } from 'perf_hooks';
7
6
  import { REFRESH_COOKIE_OPTIONS, SESSION_COOKIE_OPTIONS } from '../../constants.js';
7
+ import { useEnv } from '@directus/env';
8
8
  import { respond } from '../../middleware/respond.js';
9
- import { createDefaultAccountability } from '../../permissions/utils/create-default-accountability.js';
10
9
  import { AuthenticationService } from '../../services/authentication.js';
11
10
  import asyncHandler from '../../utils/async-handler.js';
12
11
  import { getIPFromReq } from '../../utils/get-ip-from-req.js';
@@ -48,9 +47,10 @@ export function createLocalAuthRouter(provider) {
48
47
  router.post('/', asyncHandler(async (req, res, next) => {
49
48
  const STALL_TIME = env['LOGIN_STALL_TIME'];
50
49
  const timeStart = performance.now();
51
- const accountability = createDefaultAccountability({
50
+ const accountability = {
52
51
  ip: getIPFromReq(req),
53
- });
52
+ role: null,
53
+ };
54
54
  const userAgent = req.get('user-agent')?.substring(0, 1024);
55
55
  if (userAgent)
56
56
  accountability.userAgent = userAgent;
@@ -11,16 +11,15 @@ import getDatabase from '../../database/index.js';
11
11
  import emitter from '../../emitter.js';
12
12
  import { useLogger } from '../../logger/index.js';
13
13
  import { respond } from '../../middleware/respond.js';
14
- import { createDefaultAccountability } from '../../permissions/utils/create-default-accountability.js';
15
14
  import { AuthenticationService } from '../../services/authentication.js';
16
15
  import { UsersService } from '../../services/users.js';
17
16
  import asyncHandler from '../../utils/async-handler.js';
18
17
  import { getConfigFromEnv } from '../../utils/get-config-from-env.js';
19
18
  import { getIPFromReq } from '../../utils/get-ip-from-req.js';
20
- import { getSecret } from '../../utils/get-secret.js';
21
19
  import { isLoginRedirectAllowed } from '../../utils/is-login-redirect-allowed.js';
22
20
  import { Url } from '../../utils/url.js';
23
21
  import { LocalAuthDriver } from './local.js';
22
+ import { getSecret } from '../../utils/get-secret.js';
24
23
  export class OAuth2AuthDriver extends LocalAuthDriver {
25
24
  client;
26
25
  redirectUrl;
@@ -252,9 +251,10 @@ export function createOAuth2AuthRouter(providerName) {
252
251
  throw new InvalidCredentialsError();
253
252
  }
254
253
  const { verifier, redirect, prompt } = tokenData;
255
- const accountability = createDefaultAccountability({
254
+ const accountability = {
256
255
  ip: getIPFromReq(req),
257
- });
256
+ role: null,
257
+ };
258
258
  const userAgent = req.get('user-agent')?.substring(0, 1024);
259
259
  if (userAgent)
260
260
  accountability.userAgent = userAgent;
@@ -11,7 +11,6 @@ import getDatabase from '../../database/index.js';
11
11
  import emitter from '../../emitter.js';
12
12
  import { useLogger } from '../../logger/index.js';
13
13
  import { respond } from '../../middleware/respond.js';
14
- import { createDefaultAccountability } from '../../permissions/utils/create-default-accountability.js';
15
14
  import { AuthenticationService } from '../../services/authentication.js';
16
15
  import { UsersService } from '../../services/users.js';
17
16
  import asyncHandler from '../../utils/async-handler.js';
@@ -273,7 +272,10 @@ export function createOpenIDAuthRouter(providerName) {
273
272
  throw new InvalidCredentialsError();
274
273
  }
275
274
  const { verifier, redirect, prompt } = tokenData;
276
- const accountability = createDefaultAccountability({ ip: getIPFromReq(req) });
275
+ const accountability = {
276
+ ip: getIPFromReq(req),
277
+ role: null,
278
+ };
277
279
  const userAgent = req.get('user-agent')?.substring(0, 1024);
278
280
  if (userAgent)
279
281
  accountability.userAgent = userAgent;
package/dist/cache.d.ts CHANGED
@@ -3,7 +3,6 @@ import Keyv from 'keyv';
3
3
  export declare function getCache(): {
4
4
  cache: Keyv | null;
5
5
  systemCache: Keyv;
6
- sharedSchemaCache: Keyv;
7
6
  localSchemaCache: Keyv;
8
7
  lockCache: Keyv;
9
8
  };
package/dist/cache.js CHANGED
@@ -1,5 +1,4 @@
1
1
  import { useEnv } from '@directus/env';
2
- import { getSimpleHash } from '@directus/utils';
3
2
  import Keyv from 'keyv';
4
3
  import { useBus } from './bus/index.js';
5
4
  import { useLogger } from './logger/index.js';
@@ -8,7 +7,6 @@ import { compress, decompress } from './utils/compress.js';
8
7
  import { getConfigFromEnv } from './utils/get-config-from-env.js';
9
8
  import { getMilliseconds } from './utils/get-milliseconds.js';
10
9
  import { validateEnv } from './utils/validate-env.js';
11
- import { clearCache as clearPermissionCache } from './permissions/cache.js';
12
10
  import { createRequire } from 'node:module';
13
11
  const logger = useLogger();
14
12
  const env = useEnv();
@@ -16,16 +14,16 @@ const require = createRequire(import.meta.url);
16
14
  let cache = null;
17
15
  let systemCache = null;
18
16
  let localSchemaCache = null;
19
- let sharedSchemaCache = null;
20
17
  let lockCache = null;
21
18
  let messengerSubscribed = false;
22
19
  const messenger = useBus();
23
- if (redisConfigAvailable() && env['CACHE_STORE'] === 'memory' && env['CACHE_AUTO_PURGE'] && !messengerSubscribed) {
20
+ if (redisConfigAvailable() && !messengerSubscribed) {
24
21
  messengerSubscribed = true;
25
22
  messenger.subscribe('schemaChanged', async (opts) => {
26
- if (cache && opts?.['autoPurgeCache'] !== false) {
23
+ if (env['CACHE_STORE'] === 'memory' && env['CACHE_AUTO_PURGE'] && cache && opts?.['autoPurgeCache'] !== false) {
27
24
  await cache.clear();
28
25
  }
26
+ await localSchemaCache?.clear();
29
27
  });
30
28
  }
31
29
  export function getCache() {
@@ -38,10 +36,6 @@ export function getCache() {
38
36
  systemCache = getKeyvInstance(env['CACHE_STORE'], getMilliseconds(env['CACHE_SYSTEM_TTL']), '_system');
39
37
  systemCache.on('error', (err) => logger.warn(err, `[system-cache] ${err}`));
40
38
  }
41
- if (sharedSchemaCache === null) {
42
- sharedSchemaCache = getKeyvInstance(env['CACHE_STORE'], getMilliseconds(env['CACHE_SYSTEM_TTL']), '_schema_shared');
43
- sharedSchemaCache.on('error', (err) => logger.warn(err, `[shared-schema-cache] ${err}`));
44
- }
45
39
  if (localSchemaCache === null) {
46
40
  localSchemaCache = getKeyvInstance('memory', getMilliseconds(env['CACHE_SYSTEM_TTL']), '_schema');
47
41
  localSchemaCache.on('error', (err) => logger.warn(err, `[schema-cache] ${err}`));
@@ -50,7 +44,7 @@ export function getCache() {
50
44
  lockCache = getKeyvInstance(env['CACHE_STORE'], undefined, '_lock');
51
45
  lockCache.on('error', (err) => logger.warn(err, `[lock-cache] ${err}`));
52
46
  }
53
- return { cache, systemCache, sharedSchemaCache, localSchemaCache, lockCache };
47
+ return { cache, systemCache, localSchemaCache, lockCache };
54
48
  }
55
49
  export async function flushCaches(forced) {
56
50
  const { cache } = getCache();
@@ -58,17 +52,14 @@ export async function flushCaches(forced) {
58
52
  await cache?.clear();
59
53
  }
60
54
  export async function clearSystemCache(opts) {
61
- const { systemCache, localSchemaCache, lockCache, sharedSchemaCache } = getCache();
55
+ const { systemCache, localSchemaCache, lockCache } = getCache();
62
56
  // Flush system cache when forced or when system cache lock not set
63
57
  if (opts?.forced || !(await lockCache.get('system-cache-lock'))) {
64
58
  await lockCache.set('system-cache-lock', true, 10000);
65
59
  await systemCache.clear();
66
60
  await lockCache.delete('system-cache-lock');
67
61
  }
68
- await sharedSchemaCache.clear();
69
62
  await localSchemaCache.clear();
70
- // Since a lot of cached permission function rely on the schema it needs to be cleared as well
71
- await clearPermissionCache();
72
63
  messenger.publish('schemaChanged', { autoPurgeCache: opts?.autoPurgeCache });
73
64
  }
74
65
  export async function setSystemCache(key, value, ttl) {
@@ -82,20 +73,11 @@ export async function getSystemCache(key) {
82
73
  return await getCacheValue(systemCache, key);
83
74
  }
84
75
  export async function setSchemaCache(schema) {
85
- const { localSchemaCache, sharedSchemaCache } = getCache();
86
- const schemaHash = getSimpleHash(JSON.stringify(schema));
87
- await sharedSchemaCache.set('hash', schemaHash);
76
+ const { localSchemaCache } = getCache();
88
77
  await localSchemaCache.set('schema', schema);
89
- await localSchemaCache.set('hash', schemaHash);
90
78
  }
91
79
  export async function getSchemaCache() {
92
- const { localSchemaCache, sharedSchemaCache } = getCache();
93
- const sharedSchemaHash = await sharedSchemaCache.get('hash');
94
- if (!sharedSchemaHash)
95
- return;
96
- const localSchemaHash = await localSchemaCache.get('hash');
97
- if (!localSchemaHash || localSchemaHash !== sharedSchemaHash)
98
- return;
80
+ const { localSchemaCache } = getCache();
99
81
  return await localSchemaCache.get('schema');
100
82
  }
101
83
  export async function setCacheValue(cache, key, value, ttl) {
@@ -3,13 +3,11 @@ import getDatabase, { hasDatabaseConnection, isInstalled, validateDatabaseConnec
3
3
  import runMigrations from '../../../database/migrations/run.js';
4
4
  import installDatabase from '../../../database/seeds/run.js';
5
5
  import { useLogger } from '../../../logger/index.js';
6
- import { AccessService } from '../../../services/access.js';
7
- import { PoliciesService } from '../../../services/policies.js';
8
6
  import { RolesService } from '../../../services/roles.js';
9
7
  import { SettingsService } from '../../../services/settings.js';
10
8
  import { UsersService } from '../../../services/users.js';
11
9
  import { getSchema } from '../../../utils/get-schema.js';
12
- import { defaultAdminPolicy, defaultAdminRole, defaultAdminUser } from '../../utils/defaults.js';
10
+ import { defaultAdminRole, defaultAdminUser } from '../../utils/defaults.js';
13
11
  export default async function bootstrap({ skipAdminInit }) {
14
12
  const logger = useLogger();
15
13
  logger.info('Initializing bootstrap...');
@@ -60,12 +58,8 @@ async function createDefaultAdmin(schema) {
60
58
  const env = useEnv();
61
59
  const { nanoid } = await import('nanoid');
62
60
  logger.info('Setting up first admin role...');
63
- const accessService = new AccessService({ schema });
64
- const policiesService = new PoliciesService({ schema });
65
61
  const rolesService = new RolesService({ schema });
66
62
  const role = await rolesService.createOne(defaultAdminRole);
67
- const policy = await policiesService.createOne(defaultAdminPolicy);
68
- await accessService.createOne({ policy, role });
69
63
  logger.info('Adding first admin user...');
70
64
  const usersService = new UsersService({ schema });
71
65
  let adminEmail = env['ADMIN_EMAIL'];
@@ -79,5 +73,5 @@ async function createDefaultAdmin(schema) {
79
73
  logger.info(`No admin password provided. Defaulting to "${adminPassword}"`);
80
74
  }
81
75
  const token = env['ADMIN_TOKEN'] ?? null;
82
- await usersService.createOne({ ...defaultAdminUser, email: adminEmail, password: adminPassword, token, role });
76
+ await usersService.createOne({ email: adminEmail, password: adminPassword, token, role, ...defaultAdminUser });
83
77
  }
@@ -9,7 +9,7 @@ import runSeed from '../../../database/seeds/run.js';
9
9
  import { generateHash } from '../../../utils/generate-hash.js';
10
10
  import createDBConnection from '../../utils/create-db-connection.js';
11
11
  import createEnv from '../../utils/create-env/index.js';
12
- import { defaultAdminPolicy, defaultAdminRole, defaultAdminUser } from '../../utils/defaults.js';
12
+ import { defaultAdminRole, defaultAdminUser } from '../../utils/defaults.js';
13
13
  import { drivers, getDriverForClient } from '../../utils/drivers.js';
14
14
  import { databaseQuestions } from './questions.js';
15
15
  export default async function init() {
@@ -79,17 +79,18 @@ export default async function init() {
79
79
  },
80
80
  ]);
81
81
  firstUser.password = await generateHash(firstUser.password);
82
- const role = randomUUID();
83
- const policy = randomUUID();
84
- await db('directus_roles').insert({ ...defaultAdminRole, id: role });
85
- await db('directus_policies').insert({ ...defaultAdminPolicy, id: policy });
86
- await db('directus_access').insert({ id: randomUUID(), role, policy });
82
+ const userID = randomUUID();
83
+ const roleID = randomUUID();
84
+ await db('directus_roles').insert({
85
+ id: roleID,
86
+ ...defaultAdminRole,
87
+ });
87
88
  await db('directus_users').insert({
88
- ...defaultAdminUser,
89
- id: randomUUID(),
89
+ id: userID,
90
90
  email: firstUser.email,
91
91
  password: firstUser.password,
92
- role,
92
+ role: roleID,
93
+ ...defaultAdminUser,
93
94
  });
94
95
  await db.destroy();
95
96
  process.stdout.write(`\nYour project has been created at ${chalk.green(rootPath)}.\n`);
@@ -1,4 +1,11 @@
1
- import type { Policy, Role, User } from '@directus/types';
2
- export declare const defaultAdminRole: Partial<Role>;
3
- export declare const defaultAdminUser: Partial<User>;
4
- export declare const defaultAdminPolicy: Partial<Policy>;
1
+ export declare const defaultAdminRole: {
2
+ name: string;
3
+ icon: string;
4
+ admin_access: boolean;
5
+ description: string;
6
+ };
7
+ export declare const defaultAdminUser: {
8
+ status: string;
9
+ first_name: string;
10
+ last_name: string;
11
+ };
@@ -1,6 +1,7 @@
1
1
  export const defaultAdminRole = {
2
2
  name: 'Administrator',
3
3
  icon: 'verified',
4
+ admin_access: true,
4
5
  description: '$t:admin_description',
5
6
  };
6
7
  export const defaultAdminUser = {
@@ -8,10 +9,3 @@ export const defaultAdminUser = {
8
9
  first_name: 'Admin',
9
10
  last_name: 'User',
10
11
  };
11
- export const defaultAdminPolicy = {
12
- name: 'Administrator',
13
- icon: 'verified',
14
- admin_access: true,
15
- app_access: true,
16
- description: '$t:admin_description',
17
- };
@@ -6,7 +6,7 @@ export declare const FILTER_VARIABLES: string[];
6
6
  export declare const ALIAS_TYPES: string[];
7
7
  export declare const DEFAULT_AUTH_PROVIDER = "default";
8
8
  export declare const COLUMN_TRANSFORMS: string[];
9
- export declare const GENERATE_SPECIAL: readonly ["uuid", "date-created", "role-created", "user-created"];
9
+ 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 REFRESH_COOKIE_OPTIONS: CookieOptions;
12
12
  export declare const SESSION_COOKIE_OPTIONS: CookieOptions;
@@ -5,7 +5,6 @@ import { createLDAPAuthRouter, createLocalAuthRouter, createOAuth2AuthRouter, cr
5
5
  import { DEFAULT_AUTH_PROVIDER, REFRESH_COOKIE_OPTIONS, SESSION_COOKIE_OPTIONS } from '../constants.js';
6
6
  import { useLogger } from '../logger/index.js';
7
7
  import { respond } from '../middleware/respond.js';
8
- import { createDefaultAccountability } from '../permissions/utils/create-default-accountability.js';
9
8
  import { AuthenticationService } from '../services/authentication.js';
10
9
  import { UsersService } from '../services/users.js';
11
10
  import asyncHandler from '../utils/async-handler.js';
@@ -72,7 +71,10 @@ function getCurrentRefreshToken(req, mode) {
72
71
  return undefined;
73
72
  }
74
73
  router.post('/refresh', asyncHandler(async (req, res, next) => {
75
- const accountability = createDefaultAccountability({ ip: getIPFromReq(req) });
74
+ const accountability = {
75
+ ip: getIPFromReq(req),
76
+ role: null,
77
+ };
76
78
  const userAgent = req.get('user-agent')?.substring(0, 1024);
77
79
  if (userAgent)
78
80
  accountability.userAgent = userAgent;
@@ -109,7 +111,10 @@ router.post('/refresh', asyncHandler(async (req, res, next) => {
109
111
  return next();
110
112
  }), respond);
111
113
  router.post('/logout', asyncHandler(async (req, res, next) => {
112
- const accountability = createDefaultAccountability({ ip: getIPFromReq(req) });
114
+ const accountability = {
115
+ ip: getIPFromReq(req),
116
+ role: null,
117
+ };
113
118
  const userAgent = req.get('user-agent')?.substring(0, 1024);
114
119
  if (userAgent)
115
120
  accountability.userAgent = userAgent;
@@ -140,7 +145,10 @@ router.post('/password/request', asyncHandler(async (req, _res, next) => {
140
145
  if (typeof req.body.email !== 'string') {
141
146
  throw new InvalidPayloadError({ reason: `"email" field is required` });
142
147
  }
143
- const accountability = createDefaultAccountability({ ip: getIPFromReq(req) });
148
+ const accountability = {
149
+ ip: getIPFromReq(req),
150
+ role: null,
151
+ };
144
152
  const userAgent = req.get('user-agent')?.substring(0, 1024);
145
153
  if (userAgent)
146
154
  accountability.userAgent = userAgent;
@@ -169,7 +177,10 @@ router.post('/password/reset', asyncHandler(async (req, _res, next) => {
169
177
  if (typeof req.body.password !== 'string') {
170
178
  throw new InvalidPayloadError({ reason: `"password" field is required` });
171
179
  }
172
- const accountability = createDefaultAccountability({ ip: getIPFromReq(req) });
180
+ const accountability = {
181
+ ip: getIPFromReq(req),
182
+ role: null,
183
+ };
173
184
  const userAgent = req.get('user-agent')?.substring(0, 1024);
174
185
  if (userAgent)
175
186
  accountability.userAgent = userAgent;
@@ -1,12 +1,10 @@
1
- import { ErrorCode, ForbiddenError, isDirectusError } from '@directus/errors';
1
+ import { ErrorCode, isDirectusError } from '@directus/errors';
2
2
  import express from 'express';
3
- import getDatabase from '../database/index.js';
4
3
  import { respond } from '../middleware/respond.js';
5
4
  import useCollection from '../middleware/use-collection.js';
6
5
  import { validateBatch } from '../middleware/validate-batch.js';
7
- import { fetchAccountabilityCollectionAccess } from '../permissions/modules/fetch-accountability-collection-access/fetch-accountability-collection-access.js';
8
6
  import { MetaService } from '../services/meta.js';
9
- import { PermissionsService } from '../services/permissions.js';
7
+ import { PermissionsService } from '../services/permissions/index.js';
10
8
  import asyncHandler from '../utils/async-handler.js';
11
9
  import { sanitizeQuery } from '../utils/sanitize-query.js';
12
10
  const router = express.Router();
@@ -71,16 +69,6 @@ const readHandler = asyncHandler(async (req, res, next) => {
71
69
  });
72
70
  router.get('/', validateBatch('read'), readHandler, respond);
73
71
  router.search('/', validateBatch('read'), readHandler, respond);
74
- router.get('/me', asyncHandler(async (req, res, next) => {
75
- if (!req.accountability?.user && !req.accountability?.role)
76
- throw new ForbiddenError();
77
- const result = await fetchAccountabilityCollectionAccess(req.accountability, {
78
- schema: req.schema,
79
- knex: getDatabase(),
80
- });
81
- res.locals['payload'] = { data: result };
82
- return next();
83
- }), respond);
84
72
  router.get('/:pk', asyncHandler(async (req, res, next) => {
85
73
  if (req.path.endsWith('me'))
86
74
  return next();
@@ -1,4 +1,4 @@
1
- import { ErrorCode, ForbiddenError, isDirectusError } from '@directus/errors';
1
+ import { ErrorCode, isDirectusError } from '@directus/errors';
2
2
  import express from 'express';
3
3
  import { respond } from '../middleware/respond.js';
4
4
  import useCollection from '../middleware/use-collection.js';
@@ -57,27 +57,6 @@ const readHandler = asyncHandler(async (req, res, next) => {
57
57
  });
58
58
  router.get('/', validateBatch('read'), readHandler, respond);
59
59
  router.search('/', validateBatch('read'), readHandler, respond);
60
- router.get('/me', asyncHandler(async (req, res, next) => {
61
- if (!req.accountability?.user && !req.accountability?.role)
62
- throw new ForbiddenError();
63
- const service = new RolesService({
64
- accountability: req.accountability,
65
- schema: req.schema,
66
- });
67
- const query = { ...req.sanitizedQuery, limit: -1 };
68
- try {
69
- const roles = await service.readMany(req.accountability.roles, query);
70
- res.locals['payload'] = { data: roles || null };
71
- }
72
- catch (error) {
73
- if (isDirectusError(error, ErrorCode.Forbidden)) {
74
- res.locals['payload'] = { data: req.accountability.roles.map((id) => ({ id })) };
75
- return next();
76
- }
77
- throw error;
78
- }
79
- return next();
80
- }), respond);
81
60
  router.get('/:pk', asyncHandler(async (req, res, next) => {
82
61
  const service = new RolesService({
83
62
  accountability: req.accountability,
@@ -1,10 +1,10 @@
1
1
  import { Router } from 'express';
2
- import getDatabase from '../database/index.js';
3
- import { validateAccess } from '../permissions/modules/validate-access/validate-access.js';
4
2
  import { getSchema } from '../utils/get-schema.js';
5
3
  import { scheduleSynchronizedJob, validateCron } from '../utils/schedule.js';
6
4
  import { createTusServer } from '../services/tus/index.js';
5
+ import { AuthorizationService } from '../services/authorization.js';
7
6
  import asyncHandler from '../utils/async-handler.js';
7
+ import { ForbiddenError } from '@directus/errors';
8
8
  import { RESUMABLE_UPLOADS } from '../constants.js';
9
9
  const mapAction = (method) => {
10
10
  switch (method) {
@@ -19,35 +19,49 @@ const mapAction = (method) => {
19
19
  }
20
20
  };
21
21
  const checkFileAccess = asyncHandler(async (req, _res, next) => {
22
- if (req.accountability) {
22
+ const auth = new AuthorizationService({
23
+ accountability: req.accountability,
24
+ schema: req.schema,
25
+ });
26
+ if (!req.accountability?.admin) {
23
27
  const action = mapAction(req.method);
24
- await validateAccess({
25
- action,
26
- collection: 'directus_files',
27
- accountability: req.accountability,
28
- }, {
29
- schema: req.schema,
30
- knex: getDatabase(),
31
- });
28
+ if (action === 'create') {
29
+ // checkAccess doesn't seem to work as expected for "create" actions
30
+ const hasPermission = Boolean(req.accountability?.permissions?.find((permission) => {
31
+ return permission.collection === 'directus_files' && permission.action === action;
32
+ }));
33
+ if (!hasPermission)
34
+ throw new ForbiddenError();
35
+ }
36
+ else {
37
+ try {
38
+ await auth.checkAccess(action, 'directus_files');
39
+ }
40
+ catch (e) {
41
+ throw new ForbiddenError();
42
+ }
43
+ }
32
44
  }
33
45
  return next();
34
46
  });
35
47
  const handler = asyncHandler(async (req, res) => {
36
- const tusServer = await createTusServer({
48
+ const [tusServer, cleanupServer] = await createTusServer({
37
49
  schema: req.schema,
38
50
  accountability: req.accountability,
39
51
  });
40
52
  await tusServer.handle(req, res);
53
+ cleanupServer();
41
54
  });
42
55
  export function scheduleTusCleanup() {
43
56
  if (!RESUMABLE_UPLOADS.ENABLED)
44
57
  return;
45
58
  if (validateCron(RESUMABLE_UPLOADS.SCHEDULE)) {
46
59
  scheduleSynchronizedJob('tus-cleanup', RESUMABLE_UPLOADS.SCHEDULE, async () => {
47
- const tusServer = await createTusServer({
60
+ const [tusServer, cleanupServer] = await createTusServer({
48
61
  schema: await getSchema(),
49
62
  });
50
63
  await tusServer.cleanUpExpiredUploads();
64
+ cleanupServer();
51
65
  });
52
66
  }
53
67
  }