@directus/api 21.0.0 → 22.1.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 (299) hide show
  1. package/dist/app.js +4 -4
  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 +2 -4
  6. package/dist/cache.js +3 -0
  7. package/dist/cli/commands/bootstrap/index.js +8 -2
  8. package/dist/cli/commands/init/index.js +9 -10
  9. package/dist/cli/commands/init/questions.d.ts +7 -6
  10. package/dist/cli/commands/init/questions.js +2 -2
  11. package/dist/cli/utils/create-env/index.d.ts +2 -2
  12. package/dist/cli/utils/create-env/index.js +3 -1
  13. package/dist/cli/utils/defaults.d.ts +4 -11
  14. package/dist/cli/utils/defaults.js +7 -1
  15. package/dist/cli/utils/drivers.js +1 -1
  16. package/dist/constants.d.ts +1 -1
  17. package/dist/controllers/access.d.ts +2 -0
  18. package/dist/controllers/access.js +148 -0
  19. package/dist/controllers/auth.js +5 -16
  20. package/dist/controllers/permissions.js +14 -2
  21. package/dist/controllers/policies.d.ts +2 -0
  22. package/dist/controllers/policies.js +169 -0
  23. package/dist/controllers/roles.js +22 -1
  24. package/dist/controllers/tus.js +14 -26
  25. package/dist/controllers/users.js +0 -55
  26. package/dist/database/get-ast-from-query/get-ast-from-query.d.ts +16 -0
  27. package/dist/database/get-ast-from-query/get-ast-from-query.js +82 -0
  28. package/dist/database/get-ast-from-query/lib/convert-wildcards.d.ts +13 -0
  29. package/dist/database/get-ast-from-query/lib/convert-wildcards.js +69 -0
  30. package/dist/database/get-ast-from-query/lib/parse-fields.d.ts +15 -0
  31. package/dist/database/get-ast-from-query/lib/parse-fields.js +200 -0
  32. package/dist/database/get-ast-from-query/utils/get-deep-query.d.ts +14 -0
  33. package/dist/database/get-ast-from-query/utils/get-deep-query.js +17 -0
  34. package/dist/database/get-ast-from-query/utils/get-related-collection.d.ts +2 -0
  35. package/dist/database/get-ast-from-query/utils/get-related-collection.js +13 -0
  36. package/dist/database/get-ast-from-query/utils/get-relation.d.ts +2 -0
  37. package/dist/database/get-ast-from-query/utils/get-relation.js +7 -0
  38. package/dist/database/helpers/fn/types.d.ts +2 -1
  39. package/dist/database/helpers/fn/types.js +1 -1
  40. package/dist/database/helpers/geometry/dialects/mssql.d.ts +1 -1
  41. package/dist/database/helpers/geometry/dialects/mssql.js +4 -2
  42. package/dist/database/helpers/geometry/dialects/mysql.js +1 -1
  43. package/dist/database/helpers/geometry/dialects/oracle.d.ts +1 -1
  44. package/dist/database/helpers/geometry/dialects/oracle.js +5 -3
  45. package/dist/database/helpers/geometry/types.d.ts +1 -1
  46. package/dist/database/helpers/geometry/types.js +4 -2
  47. package/dist/database/helpers/index.d.ts +3 -3
  48. package/dist/database/helpers/schema/dialects/cockroachdb.d.ts +2 -1
  49. package/dist/database/helpers/schema/dialects/cockroachdb.js +4 -0
  50. package/dist/database/helpers/schema/dialects/mssql.d.ts +2 -1
  51. package/dist/database/helpers/schema/dialects/mssql.js +4 -0
  52. package/dist/database/helpers/schema/dialects/oracle.d.ts +2 -1
  53. package/dist/database/helpers/schema/dialects/oracle.js +4 -0
  54. package/dist/database/helpers/schema/dialects/postgres.d.ts +2 -1
  55. package/dist/database/helpers/schema/dialects/postgres.js +4 -0
  56. package/dist/database/helpers/schema/types.d.ts +5 -0
  57. package/dist/database/helpers/schema/types.js +3 -0
  58. package/dist/database/helpers/schema/utils/preprocess-bindings.d.ts +8 -0
  59. package/dist/database/helpers/schema/utils/preprocess-bindings.js +30 -0
  60. package/dist/database/index.js +6 -1
  61. package/dist/database/migrations/20210519A-add-system-fk-triggers.js +3 -2
  62. package/dist/database/migrations/20230721A-require-shares-fields.js +3 -5
  63. package/dist/database/migrations/20240716A-update-files-date-fields.js +3 -7
  64. package/dist/{utils/merge-permissions.d.ts → database/migrations/20240806A-permissions-policies.d.ts} +4 -1
  65. package/dist/database/migrations/20240806A-permissions-policies.js +352 -0
  66. package/dist/database/run-ast/lib/get-db-query.d.ts +4 -0
  67. package/dist/database/run-ast/lib/get-db-query.js +218 -0
  68. package/dist/database/run-ast/lib/parse-current-level.d.ts +7 -0
  69. package/dist/database/run-ast/lib/parse-current-level.js +41 -0
  70. package/dist/database/run-ast/run-ast.d.ts +7 -0
  71. package/dist/database/run-ast/run-ast.js +107 -0
  72. package/dist/database/{run-ast.d.ts → run-ast/types.d.ts} +3 -9
  73. package/dist/database/run-ast/types.js +1 -0
  74. package/dist/database/run-ast/utils/apply-case-when.d.ts +16 -0
  75. package/dist/database/run-ast/utils/apply-case-when.js +27 -0
  76. package/dist/database/run-ast/utils/apply-parent-filters.d.ts +3 -0
  77. package/dist/database/run-ast/utils/apply-parent-filters.js +55 -0
  78. package/dist/database/run-ast/utils/get-column-pre-processor.d.ts +10 -0
  79. package/dist/database/run-ast/utils/get-column-pre-processor.js +57 -0
  80. package/dist/database/run-ast/utils/get-field-alias.d.ts +2 -0
  81. package/dist/database/run-ast/utils/get-field-alias.js +4 -0
  82. package/dist/database/run-ast/utils/get-inner-query-column-pre-processor.d.ts +5 -0
  83. package/dist/database/run-ast/utils/get-inner-query-column-pre-processor.js +23 -0
  84. package/dist/database/run-ast/utils/merge-with-parent-items.d.ts +3 -0
  85. package/dist/database/run-ast/utils/merge-with-parent-items.js +87 -0
  86. package/dist/database/run-ast/utils/remove-temporary-fields.d.ts +3 -0
  87. package/dist/database/run-ast/utils/remove-temporary-fields.js +73 -0
  88. package/dist/database/run-ast/utils/with-preprocess-bindings.d.ts +2 -0
  89. package/dist/database/run-ast/utils/with-preprocess-bindings.js +14 -0
  90. package/dist/flows.js +3 -4
  91. package/dist/middleware/authenticate.js +2 -7
  92. package/dist/middleware/cache.js +1 -1
  93. package/dist/middleware/respond.js +1 -1
  94. package/dist/permissions/cache.d.ts +2 -0
  95. package/dist/permissions/cache.js +23 -0
  96. package/dist/permissions/lib/fetch-permissions.d.ts +11 -0
  97. package/dist/permissions/lib/fetch-permissions.js +56 -0
  98. package/dist/permissions/lib/fetch-policies.d.ts +14 -0
  99. package/dist/permissions/lib/fetch-policies.js +43 -0
  100. package/dist/permissions/lib/fetch-roles-tree.d.ts +3 -0
  101. package/dist/permissions/lib/fetch-roles-tree.js +28 -0
  102. package/dist/{services/permissions → permissions}/lib/with-app-minimal-permissions.d.ts +1 -1
  103. package/dist/permissions/lib/with-app-minimal-permissions.js +10 -0
  104. package/dist/permissions/modules/fetch-accountability-collection-access/fetch-accountability-collection-access.d.ts +7 -0
  105. package/dist/permissions/modules/fetch-accountability-collection-access/fetch-accountability-collection-access.js +56 -0
  106. package/dist/permissions/modules/fetch-accountability-policy-globals/fetch-accountability-policy-globals.d.ts +3 -0
  107. package/dist/permissions/modules/fetch-accountability-policy-globals/fetch-accountability-policy-globals.js +16 -0
  108. package/dist/permissions/modules/fetch-allowed-collections/fetch-allowed-collections.d.ts +8 -0
  109. package/dist/permissions/modules/fetch-allowed-collections/fetch-allowed-collections.js +24 -0
  110. package/dist/permissions/modules/fetch-allowed-field-map/fetch-allowed-field-map.d.ts +9 -0
  111. package/dist/permissions/modules/fetch-allowed-field-map/fetch-allowed-field-map.js +31 -0
  112. package/dist/permissions/modules/fetch-allowed-fields/fetch-allowed-fields.d.ts +16 -0
  113. package/dist/permissions/modules/fetch-allowed-fields/fetch-allowed-fields.js +27 -0
  114. package/dist/permissions/modules/fetch-global-access/fetch-global-access.d.ts +10 -0
  115. package/dist/permissions/modules/fetch-global-access/fetch-global-access.js +23 -0
  116. package/dist/permissions/modules/fetch-global-access/lib/fetch-global-access-for-roles.d.ts +5 -0
  117. package/dist/permissions/modules/fetch-global-access/lib/fetch-global-access-for-roles.js +7 -0
  118. package/dist/permissions/modules/fetch-global-access/lib/fetch-global-access-for-user.d.ts +5 -0
  119. package/dist/permissions/modules/fetch-global-access/lib/fetch-global-access-for-user.js +10 -0
  120. package/dist/permissions/modules/fetch-global-access/types.d.ts +4 -0
  121. package/dist/permissions/modules/fetch-global-access/types.js +1 -0
  122. package/dist/permissions/modules/fetch-global-access/utils/fetch-global-access-for-query.d.ts +4 -0
  123. package/dist/permissions/modules/fetch-global-access/utils/fetch-global-access-for-query.js +27 -0
  124. package/dist/permissions/modules/fetch-inconsistent-field-map/fetch-inconsistent-field-map.d.ts +12 -0
  125. package/dist/permissions/modules/fetch-inconsistent-field-map/fetch-inconsistent-field-map.js +32 -0
  126. package/dist/permissions/modules/fetch-policies-ip-access/fetch-policies-ip-access.d.ts +4 -0
  127. package/dist/permissions/modules/fetch-policies-ip-access/fetch-policies-ip-access.js +29 -0
  128. package/dist/permissions/modules/process-ast/lib/extract-fields-from-children.d.ts +4 -0
  129. package/dist/permissions/modules/process-ast/lib/extract-fields-from-children.js +49 -0
  130. package/dist/permissions/modules/process-ast/lib/extract-fields-from-query.d.ts +3 -0
  131. package/dist/permissions/modules/process-ast/lib/extract-fields-from-query.js +56 -0
  132. package/dist/permissions/modules/process-ast/lib/field-map-from-ast.d.ts +4 -0
  133. package/dist/permissions/modules/process-ast/lib/field-map-from-ast.js +8 -0
  134. package/dist/permissions/modules/process-ast/lib/inject-cases.d.ts +9 -0
  135. package/dist/permissions/modules/process-ast/lib/inject-cases.js +93 -0
  136. package/dist/permissions/modules/process-ast/process-ast.d.ts +9 -0
  137. package/dist/permissions/modules/process-ast/process-ast.js +39 -0
  138. package/dist/permissions/modules/process-ast/types.d.ts +18 -0
  139. package/dist/permissions/modules/process-ast/types.js +1 -0
  140. package/dist/permissions/modules/process-ast/utils/collections-in-field-map.d.ts +2 -0
  141. package/dist/permissions/modules/process-ast/utils/collections-in-field-map.js +7 -0
  142. package/dist/permissions/modules/process-ast/utils/dedupe-access.d.ts +12 -0
  143. package/dist/permissions/modules/process-ast/utils/dedupe-access.js +30 -0
  144. package/dist/permissions/modules/process-ast/utils/extract-paths-from-query.d.ts +15 -0
  145. package/dist/permissions/modules/process-ast/utils/extract-paths-from-query.js +60 -0
  146. package/dist/permissions/modules/process-ast/utils/find-related-collection.d.ts +3 -0
  147. package/dist/permissions/modules/process-ast/utils/find-related-collection.js +9 -0
  148. package/dist/permissions/modules/process-ast/utils/flatten-filter.d.ts +3 -0
  149. package/dist/permissions/modules/process-ast/utils/flatten-filter.js +34 -0
  150. package/dist/permissions/modules/process-ast/utils/format-a2o-key.d.ts +1 -0
  151. package/dist/permissions/modules/process-ast/utils/format-a2o-key.js +3 -0
  152. package/dist/permissions/modules/process-ast/utils/get-info-for-path.d.ts +5 -0
  153. package/dist/permissions/modules/process-ast/utils/get-info-for-path.js +7 -0
  154. package/dist/permissions/modules/process-ast/utils/has-item-permissions.d.ts +2 -0
  155. package/dist/permissions/modules/process-ast/utils/has-item-permissions.js +3 -0
  156. package/dist/permissions/modules/process-ast/utils/stringify-query-path.d.ts +2 -0
  157. package/dist/permissions/modules/process-ast/utils/stringify-query-path.js +3 -0
  158. package/dist/permissions/modules/process-ast/utils/validate-path/create-error.d.ts +3 -0
  159. package/dist/permissions/modules/process-ast/utils/validate-path/create-error.js +16 -0
  160. package/dist/permissions/modules/process-ast/utils/validate-path/validate-path-existence.d.ts +2 -0
  161. package/dist/permissions/modules/process-ast/utils/validate-path/validate-path-existence.js +12 -0
  162. package/dist/permissions/modules/process-ast/utils/validate-path/validate-path-permissions.d.ts +2 -0
  163. package/dist/permissions/modules/process-ast/utils/validate-path/validate-path-permissions.js +28 -0
  164. package/dist/permissions/modules/process-payload/lib/is-field-nullable.d.ts +5 -0
  165. package/dist/permissions/modules/process-payload/lib/is-field-nullable.js +12 -0
  166. package/dist/permissions/modules/process-payload/process-payload.d.ts +13 -0
  167. package/dist/permissions/modules/process-payload/process-payload.js +77 -0
  168. package/dist/permissions/modules/validate-access/lib/validate-collection-access.d.ts +12 -0
  169. package/dist/permissions/modules/validate-access/lib/validate-collection-access.js +11 -0
  170. package/dist/permissions/modules/validate-access/lib/validate-item-access.d.ts +9 -0
  171. package/dist/permissions/modules/validate-access/lib/validate-item-access.js +33 -0
  172. package/dist/permissions/modules/validate-access/validate-access.d.ts +14 -0
  173. package/dist/permissions/modules/validate-access/validate-access.js +28 -0
  174. package/dist/permissions/modules/validate-remaining-admin/validate-remaining-admin-count.d.ts +1 -0
  175. package/dist/permissions/modules/validate-remaining-admin/validate-remaining-admin-count.js +8 -0
  176. package/dist/permissions/modules/validate-remaining-admin/validate-remaining-admin-users.d.ts +5 -0
  177. package/dist/permissions/modules/validate-remaining-admin/validate-remaining-admin-users.js +10 -0
  178. package/dist/permissions/types.d.ts +6 -0
  179. package/dist/permissions/types.js +1 -0
  180. package/dist/permissions/utils/create-default-accountability.d.ts +2 -0
  181. package/dist/permissions/utils/create-default-accountability.js +11 -0
  182. package/dist/permissions/utils/extract-required-dynamic-variable-context.d.ts +8 -0
  183. package/dist/permissions/utils/extract-required-dynamic-variable-context.js +27 -0
  184. package/dist/permissions/utils/fetch-dynamic-variable-context.d.ts +9 -0
  185. package/dist/permissions/utils/fetch-dynamic-variable-context.js +43 -0
  186. package/dist/permissions/utils/filter-policies-by-ip.d.ts +2 -0
  187. package/dist/permissions/utils/filter-policies-by-ip.js +15 -0
  188. package/dist/permissions/utils/get-unaliased-field-key.d.ts +5 -0
  189. package/dist/permissions/utils/get-unaliased-field-key.js +17 -0
  190. package/dist/permissions/utils/process-permissions.d.ts +7 -0
  191. package/dist/permissions/utils/process-permissions.js +9 -0
  192. package/dist/permissions/utils/with-cache.d.ts +10 -0
  193. package/dist/permissions/utils/with-cache.js +25 -0
  194. package/dist/server.js +17 -4
  195. package/dist/services/access.d.ts +10 -0
  196. package/dist/services/access.js +43 -0
  197. package/dist/services/activity.js +22 -10
  198. package/dist/services/assets.d.ts +2 -3
  199. package/dist/services/assets.js +10 -5
  200. package/dist/services/authentication.js +18 -18
  201. package/dist/services/collections.js +18 -17
  202. package/dist/services/fields.d.ts +0 -1
  203. package/dist/services/fields.js +54 -25
  204. package/dist/services/files.js +10 -3
  205. package/dist/services/graphql/index.d.ts +3 -3
  206. package/dist/services/graphql/index.js +126 -22
  207. package/dist/services/graphql/subscription.js +2 -4
  208. package/dist/services/import-export.d.ts +3 -1
  209. package/dist/services/import-export.js +67 -9
  210. package/dist/services/index.d.ts +3 -2
  211. package/dist/services/index.js +3 -2
  212. package/dist/services/items.js +115 -44
  213. package/dist/services/meta.js +60 -23
  214. package/dist/services/notifications.js +14 -6
  215. package/dist/services/payload.d.ts +9 -10
  216. package/dist/services/payload.js +18 -3
  217. package/dist/services/{permissions/index.d.ts → permissions.d.ts} +5 -7
  218. package/dist/services/{permissions/index.js → permissions.js} +30 -54
  219. package/dist/services/policies.d.ts +12 -0
  220. package/dist/services/policies.js +87 -0
  221. package/dist/services/relations.d.ts +0 -6
  222. package/dist/services/relations.js +27 -30
  223. package/dist/services/roles.d.ts +4 -12
  224. package/dist/services/roles.js +57 -424
  225. package/dist/services/shares.d.ts +0 -2
  226. package/dist/services/shares.js +12 -8
  227. package/dist/services/specifications.d.ts +2 -2
  228. package/dist/services/specifications.js +39 -27
  229. package/dist/services/users.d.ts +1 -5
  230. package/dist/services/users.js +78 -161
  231. package/dist/services/utils.js +11 -7
  232. package/dist/services/versions.d.ts +0 -2
  233. package/dist/services/versions.js +34 -10
  234. package/dist/telemetry/lib/get-report.js +2 -2
  235. package/dist/telemetry/utils/check-user-limits.d.ts +5 -0
  236. package/dist/telemetry/utils/check-user-limits.js +19 -0
  237. package/dist/types/ast.d.ts +43 -1
  238. package/dist/types/database.d.ts +1 -1
  239. package/dist/types/items.d.ts +11 -0
  240. package/dist/utils/apply-query.d.ts +11 -7
  241. package/dist/utils/apply-query.js +69 -11
  242. package/dist/utils/fetch-user-count/fetch-access-lookup.d.ts +19 -0
  243. package/dist/utils/fetch-user-count/fetch-access-lookup.js +23 -0
  244. package/dist/utils/fetch-user-count/fetch-access-roles.d.ts +16 -0
  245. package/dist/utils/fetch-user-count/fetch-access-roles.js +37 -0
  246. package/dist/utils/fetch-user-count/fetch-active-users.d.ts +6 -0
  247. package/dist/utils/fetch-user-count/fetch-active-users.js +3 -0
  248. package/dist/utils/fetch-user-count/fetch-user-count.d.ts +12 -0
  249. package/dist/utils/fetch-user-count/fetch-user-count.js +64 -0
  250. package/dist/utils/fetch-user-count/get-user-count-query.d.ts +20 -0
  251. package/dist/utils/fetch-user-count/get-user-count-query.js +17 -0
  252. package/dist/utils/get-accountability-for-role.js +16 -25
  253. package/dist/utils/get-accountability-for-token.js +17 -16
  254. package/dist/utils/get-address.d.ts +5 -0
  255. package/dist/utils/get-address.js +13 -0
  256. package/dist/utils/get-cache-key.d.ts +1 -1
  257. package/dist/utils/get-cache-key.js +12 -1
  258. package/dist/utils/get-column.d.ts +2 -1
  259. package/dist/utils/get-column.js +1 -0
  260. package/dist/utils/get-service.js +5 -1
  261. package/dist/utils/reduce-schema.d.ts +4 -6
  262. package/dist/utils/reduce-schema.js +16 -32
  263. package/dist/utils/sanitize-schema.d.ts +1 -1
  264. package/dist/utils/transaction.js +28 -11
  265. package/dist/utils/validate-user-count-integrity.d.ts +13 -0
  266. package/dist/utils/validate-user-count-integrity.js +29 -0
  267. package/dist/websocket/authenticate.d.ts +0 -2
  268. package/dist/websocket/authenticate.js +0 -12
  269. package/dist/websocket/controllers/graphql.js +3 -7
  270. package/dist/websocket/controllers/hooks.js +4 -0
  271. package/dist/websocket/controllers/rest.js +2 -5
  272. package/dist/websocket/handlers/subscribe.js +0 -2
  273. package/dist/websocket/utils/items.d.ts +1 -1
  274. package/package.json +31 -30
  275. package/dist/database/run-ast.js +0 -458
  276. package/dist/middleware/check-ip.d.ts +0 -2
  277. package/dist/middleware/check-ip.js +0 -37
  278. package/dist/middleware/get-permissions.d.ts +0 -3
  279. package/dist/middleware/get-permissions.js +0 -10
  280. package/dist/services/authorization.d.ts +0 -17
  281. package/dist/services/authorization.js +0 -456
  282. package/dist/services/permissions/lib/with-app-minimal-permissions.js +0 -13
  283. package/dist/telemetry/utils/check-increased-user-limits.d.ts +0 -7
  284. package/dist/telemetry/utils/check-increased-user-limits.js +0 -25
  285. package/dist/telemetry/utils/get-role-counts-by-roles.d.ts +0 -6
  286. package/dist/telemetry/utils/get-role-counts-by-roles.js +0 -27
  287. package/dist/telemetry/utils/get-role-counts-by-users.d.ts +0 -11
  288. package/dist/telemetry/utils/get-role-counts-by-users.js +0 -34
  289. package/dist/telemetry/utils/get-user-count.d.ts +0 -8
  290. package/dist/telemetry/utils/get-user-count.js +0 -33
  291. package/dist/telemetry/utils/get-user-counts-by-roles.d.ts +0 -7
  292. package/dist/telemetry/utils/get-user-counts-by-roles.js +0 -35
  293. package/dist/utils/get-ast-from-query.d.ts +0 -13
  294. package/dist/utils/get-ast-from-query.js +0 -297
  295. package/dist/utils/get-permissions.d.ts +0 -2
  296. package/dist/utils/get-permissions.js +0 -150
  297. package/dist/utils/merge-permissions-for-share.d.ts +0 -4
  298. package/dist/utils/merge-permissions-for-share.js +0 -109
  299. package/dist/utils/merge-permissions.js +0 -95
package/dist/app.js CHANGED
@@ -10,6 +10,7 @@ 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';
13
14
  import assetsRouter from './controllers/assets.js';
14
15
  import authRouter from './controllers/auth.js';
15
16
  import collectionsRouter from './controllers/collections.js';
@@ -26,6 +27,7 @@ import notificationsRouter from './controllers/notifications.js';
26
27
  import operationsRouter from './controllers/operations.js';
27
28
  import panelsRouter from './controllers/panels.js';
28
29
  import permissionsRouter from './controllers/permissions.js';
30
+ import policiesRouter from './controllers/policies.js';
29
31
  import presetsRouter from './controllers/presets.js';
30
32
  import relationsRouter from './controllers/relations.js';
31
33
  import revisionsRouter from './controllers/revisions.js';
@@ -47,11 +49,9 @@ import { getFlowManager } from './flows.js';
47
49
  import { createExpressLogger, useLogger } from './logger/index.js';
48
50
  import authenticate from './middleware/authenticate.js';
49
51
  import cache from './middleware/cache.js';
50
- import { checkIP } from './middleware/check-ip.js';
51
52
  import cors from './middleware/cors.js';
52
53
  import { errorHandler } from './middleware/error-handler.js';
53
54
  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,16 +198,15 @@ 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);
202
201
  app.use(sanitizeQuery);
203
202
  app.use(cache);
204
203
  app.use(schema);
205
- app.use(getPermissions);
206
204
  await emitter.emitInit('middlewares.after', { app });
207
205
  await emitter.emitInit('routes.before', { app });
208
206
  app.use('/auth', authRouter);
209
207
  app.use('/graphql', graphqlRouter);
210
208
  app.use('/activity', activityRouter);
209
+ app.use('/access', accessRouter);
211
210
  app.use('/assets', assetsRouter);
212
211
  app.use('/collections', collectionsRouter);
213
212
  app.use('/dashboards', dashboardsRouter);
@@ -224,6 +223,7 @@ export default async function createApp() {
224
223
  app.use('/operations', operationsRouter);
225
224
  app.use('/panels', panelsRouter);
226
225
  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,16 +3,17 @@ 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';
6
7
  import getDatabase from '../../database/index.js';
7
8
  import emitter from '../../emitter.js';
8
9
  import { useLogger } from '../../logger/index.js';
9
10
  import { respond } from '../../middleware/respond.js';
11
+ import { createDefaultAccountability } from '../../permissions/utils/create-default-accountability.js';
10
12
  import { AuthenticationService } from '../../services/authentication.js';
11
13
  import { UsersService } from '../../services/users.js';
12
14
  import asyncHandler from '../../utils/async-handler.js';
13
15
  import { getIPFromReq } from '../../utils/get-ip-from-req.js';
14
16
  import { AuthDriver } from '../auth.js';
15
- import { REFRESH_COOKIE_OPTIONS, SESSION_COOKIE_OPTIONS } from '../../constants.js';
16
17
  // 0x2: ACCOUNTDISABLE
17
18
  // 0x10: LOCKOUT
18
19
  // 0x800000: PASSWORD_EXPIRED
@@ -295,10 +296,9 @@ export function createLDAPAuthRouter(provider) {
295
296
  }).unknown();
296
297
  router.post('/', asyncHandler(async (req, res, next) => {
297
298
  const env = useEnv();
298
- const accountability = {
299
+ const accountability = createDefaultAccountability({
299
300
  ip: getIPFromReq(req),
300
- role: null,
301
- };
301
+ });
302
302
  const userAgent = req.get('user-agent')?.substring(0, 1024);
303
303
  if (userAgent)
304
304
  accountability.userAgent = userAgent;
@@ -1,11 +1,12 @@
1
+ import { useEnv } from '@directus/env';
1
2
  import { InvalidCredentialsError, InvalidPayloadError } from '@directus/errors';
2
3
  import argon2 from 'argon2';
3
4
  import { Router } from 'express';
4
5
  import Joi from 'joi';
5
6
  import { performance } from 'perf_hooks';
6
7
  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';
9
10
  import { AuthenticationService } from '../../services/authentication.js';
10
11
  import asyncHandler from '../../utils/async-handler.js';
11
12
  import { getIPFromReq } from '../../utils/get-ip-from-req.js';
@@ -47,10 +48,9 @@ export function createLocalAuthRouter(provider) {
47
48
  router.post('/', asyncHandler(async (req, res, next) => {
48
49
  const STALL_TIME = env['LOGIN_STALL_TIME'];
49
50
  const timeStart = performance.now();
50
- const accountability = {
51
+ const accountability = createDefaultAccountability({
51
52
  ip: getIPFromReq(req),
52
- role: null,
53
- };
53
+ });
54
54
  const userAgent = req.get('user-agent')?.substring(0, 1024);
55
55
  if (userAgent)
56
56
  accountability.userAgent = userAgent;
@@ -11,15 +11,16 @@ 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';
14
15
  import { AuthenticationService } from '../../services/authentication.js';
15
16
  import { UsersService } from '../../services/users.js';
16
17
  import asyncHandler from '../../utils/async-handler.js';
17
18
  import { getConfigFromEnv } from '../../utils/get-config-from-env.js';
18
19
  import { getIPFromReq } from '../../utils/get-ip-from-req.js';
20
+ import { getSecret } from '../../utils/get-secret.js';
19
21
  import { isLoginRedirectAllowed } from '../../utils/is-login-redirect-allowed.js';
20
22
  import { Url } from '../../utils/url.js';
21
23
  import { LocalAuthDriver } from './local.js';
22
- import { getSecret } from '../../utils/get-secret.js';
23
24
  export class OAuth2AuthDriver extends LocalAuthDriver {
24
25
  client;
25
26
  redirectUrl;
@@ -251,10 +252,9 @@ export function createOAuth2AuthRouter(providerName) {
251
252
  throw new InvalidCredentialsError();
252
253
  }
253
254
  const { verifier, redirect, prompt } = tokenData;
254
- const accountability = {
255
+ const accountability = createDefaultAccountability({
255
256
  ip: getIPFromReq(req),
256
- role: null,
257
- };
257
+ });
258
258
  const userAgent = req.get('user-agent')?.substring(0, 1024);
259
259
  if (userAgent)
260
260
  accountability.userAgent = userAgent;
@@ -11,6 +11,7 @@ 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';
14
15
  import { AuthenticationService } from '../../services/authentication.js';
15
16
  import { UsersService } from '../../services/users.js';
16
17
  import asyncHandler from '../../utils/async-handler.js';
@@ -272,10 +273,7 @@ export function createOpenIDAuthRouter(providerName) {
272
273
  throw new InvalidCredentialsError();
273
274
  }
274
275
  const { verifier, redirect, prompt } = tokenData;
275
- const accountability = {
276
- ip: getIPFromReq(req),
277
- role: null,
278
- };
276
+ const accountability = createDefaultAccountability({ ip: getIPFromReq(req) });
279
277
  const userAgent = req.get('user-agent')?.substring(0, 1024);
280
278
  if (userAgent)
281
279
  accountability.userAgent = userAgent;
package/dist/cache.js CHANGED
@@ -7,6 +7,7 @@ import { compress, decompress } from './utils/compress.js';
7
7
  import { getConfigFromEnv } from './utils/get-config-from-env.js';
8
8
  import { getMilliseconds } from './utils/get-milliseconds.js';
9
9
  import { validateEnv } from './utils/validate-env.js';
10
+ import { clearCache as clearPermissionCache } from './permissions/cache.js';
10
11
  import { createRequire } from 'node:module';
11
12
  const logger = useLogger();
12
13
  const env = useEnv();
@@ -60,6 +61,8 @@ export async function clearSystemCache(opts) {
60
61
  await lockCache.delete('system-cache-lock');
61
62
  }
62
63
  await localSchemaCache.clear();
64
+ // Since a lot of cached permission function rely on the schema it needs to be cleared as well
65
+ await clearPermissionCache();
63
66
  messenger.publish('schemaChanged', { autoPurgeCache: opts?.autoPurgeCache });
64
67
  }
65
68
  export async function setSystemCache(key, value, ttl) {
@@ -3,11 +3,13 @@ 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';
6
8
  import { RolesService } from '../../../services/roles.js';
7
9
  import { SettingsService } from '../../../services/settings.js';
8
10
  import { UsersService } from '../../../services/users.js';
9
11
  import { getSchema } from '../../../utils/get-schema.js';
10
- import { defaultAdminRole, defaultAdminUser } from '../../utils/defaults.js';
12
+ import { defaultAdminPolicy, defaultAdminRole, defaultAdminUser } from '../../utils/defaults.js';
11
13
  export default async function bootstrap({ skipAdminInit }) {
12
14
  const logger = useLogger();
13
15
  logger.info('Initializing bootstrap...');
@@ -58,8 +60,12 @@ async function createDefaultAdmin(schema) {
58
60
  const env = useEnv();
59
61
  const { nanoid } = await import('nanoid');
60
62
  logger.info('Setting up first admin role...');
63
+ const accessService = new AccessService({ schema });
64
+ const policiesService = new PoliciesService({ schema });
61
65
  const rolesService = new RolesService({ schema });
62
66
  const role = await rolesService.createOne(defaultAdminRole);
67
+ const policy = await policiesService.createOne(defaultAdminPolicy);
68
+ await accessService.createOne({ policy, role });
63
69
  logger.info('Adding first admin user...');
64
70
  const usersService = new UsersService({ schema });
65
71
  let adminEmail = env['ADMIN_EMAIL'];
@@ -73,5 +79,5 @@ async function createDefaultAdmin(schema) {
73
79
  logger.info(`No admin password provided. Defaulting to "${adminPassword}"`);
74
80
  }
75
81
  const token = env['ADMIN_TOKEN'] ?? null;
76
- await usersService.createOne({ email: adminEmail, password: adminPassword, token, role, ...defaultAdminUser });
82
+ await usersService.createOne({ ...defaultAdminUser, email: adminEmail, password: adminPassword, token, role });
77
83
  }
@@ -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 { defaultAdminRole, defaultAdminUser } from '../../utils/defaults.js';
12
+ import { defaultAdminPolicy, 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,18 +79,17 @@ export default async function init() {
79
79
  },
80
80
  ]);
81
81
  firstUser.password = await generateHash(firstUser.password);
82
- const userID = randomUUID();
83
- const roleID = randomUUID();
84
- await db('directus_roles').insert({
85
- id: roleID,
86
- ...defaultAdminRole,
87
- });
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 });
88
87
  await db('directus_users').insert({
89
- id: userID,
88
+ ...defaultAdminUser,
89
+ id: randomUUID(),
90
90
  email: firstUser.email,
91
91
  password: firstUser.password,
92
- role: roleID,
93
- ...defaultAdminUser,
92
+ role,
94
93
  });
95
94
  await db.destroy();
96
95
  process.stdout.write(`\nYour project has been created at ${chalk.green(rootPath)}.\n`);
@@ -1,20 +1,21 @@
1
+ import type { Driver } from '../../../types/index.js';
1
2
  export declare const databaseQuestions: {
2
3
  sqlite3: (({ filepath }: {
3
4
  filepath: string;
4
5
  }) => Record<string, string>)[];
5
- mysql: (({ client }: {
6
- client: string;
6
+ mysql2: (({ client }: {
7
+ client: Exclude<Driver, 'sqlite3'>;
7
8
  }) => Record<string, any>)[];
8
9
  pg: (({ client }: {
9
- client: string;
10
+ client: Exclude<Driver, 'sqlite3'>;
10
11
  }) => Record<string, any>)[];
11
12
  cockroachdb: (({ client }: {
12
- client: string;
13
+ client: Exclude<Driver, 'sqlite3'>;
13
14
  }) => Record<string, any>)[];
14
15
  oracledb: (({ client }: {
15
- client: string;
16
+ client: Exclude<Driver, 'sqlite3'>;
16
17
  }) => Record<string, any>)[];
17
18
  mssql: (({ client }: {
18
- client: string;
19
+ client: Exclude<Driver, 'sqlite3'>;
19
20
  }) => Record<string, any>)[];
20
21
  };
@@ -19,7 +19,7 @@ const port = ({ client }) => ({
19
19
  const ports = {
20
20
  pg: 5432,
21
21
  cockroachdb: 26257,
22
- mysql: 3306,
22
+ mysql2: 3306,
23
23
  oracledb: 1521,
24
24
  mssql: 1433,
25
25
  };
@@ -57,7 +57,7 @@ const ssl = () => ({
57
57
  });
58
58
  export const databaseQuestions = {
59
59
  sqlite3: [filename],
60
- mysql: [host, port, database, user, password],
60
+ mysql2: [host, port, database, user, password],
61
61
  pg: [host, port, database, user, password, ssl],
62
62
  cockroachdb: [host, port, database, user, password, ssl],
63
63
  oracledb: [host, port, database, user, password],
@@ -1,3 +1,3 @@
1
+ import type { Driver } from '../../../types/index.js';
1
2
  import type { Credentials } from '../create-db-connection.js';
2
- import type { drivers } from '../drivers.js';
3
- export default function createEnv(client: keyof typeof drivers, credentials: Credentials, directory: string): Promise<void>;
3
+ export default function createEnv(client: Driver, credentials: Credentials, directory: string): Promise<void>;
@@ -14,12 +14,14 @@ const liquidEngine = new Liquid({
14
14
  });
15
15
  export default async function createEnv(client, credentials, directory) {
16
16
  const { nanoid } = await import('nanoid');
17
+ // For backwards-compatibility, DB_CLIENT is still 'mysql'
18
+ const dbClient = client === 'mysql2' ? 'mysql' : client;
17
19
  const config = {
18
20
  security: {
19
21
  SECRET: nanoid(32),
20
22
  },
21
23
  database: {
22
- DB_CLIENT: client,
24
+ DB_CLIENT: dbClient,
23
25
  },
24
26
  };
25
27
  for (const [key, value] of Object.entries(credentials)) {
@@ -1,11 +1,4 @@
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
+ 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,7 +1,6 @@
1
1
  export const defaultAdminRole = {
2
2
  name: 'Administrator',
3
3
  icon: 'verified',
4
- admin_access: true,
5
4
  description: '$t:admin_description',
6
5
  };
7
6
  export const defaultAdminUser = {
@@ -9,3 +8,10 @@ export const defaultAdminUser = {
9
8
  first_name: 'Admin',
10
9
  last_name: 'User',
11
10
  };
11
+ export const defaultAdminPolicy = {
12
+ name: 'Administrator',
13
+ icon: 'verified',
14
+ admin_access: true,
15
+ app_access: true,
16
+ description: '$t:admin_description',
17
+ };
@@ -1,7 +1,7 @@
1
1
  export const drivers = {
2
2
  pg: 'PostgreSQL / Redshift',
3
3
  cockroachdb: 'CockroachDB (Beta)',
4
- mysql: 'MySQL / MariaDB / Aurora',
4
+ mysql2: 'MySQL / MariaDB / Aurora',
5
5
  sqlite3: 'SQLite',
6
6
  mssql: 'Microsoft SQL Server',
7
7
  oracledb: 'Oracle Database',
@@ -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: string[];
9
+ export declare const GENERATE_SPECIAL: readonly ["uuid", "date-created", "role-created", "user-created"];
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;
@@ -0,0 +1,2 @@
1
+ declare const router: import("express-serve-static-core").Router;
2
+ export default router;
@@ -0,0 +1,148 @@
1
+ import { ErrorCode, isDirectusError } from '@directus/errors';
2
+ import express from 'express';
3
+ import { respond } from '../middleware/respond.js';
4
+ import useCollection from '../middleware/use-collection.js';
5
+ import { validateBatch } from '../middleware/validate-batch.js';
6
+ import { MetaService } from '../services/meta.js';
7
+ import { AccessService } from '../services/access.js';
8
+ import asyncHandler from '../utils/async-handler.js';
9
+ import { sanitizeQuery } from '../utils/sanitize-query.js';
10
+ const router = express.Router();
11
+ router.use(useCollection('directus_access'));
12
+ router.post('/', asyncHandler(async (req, res, next) => {
13
+ const service = new AccessService({
14
+ accountability: req.accountability,
15
+ schema: req.schema,
16
+ });
17
+ const savedKeys = [];
18
+ if (Array.isArray(req.body)) {
19
+ const keys = await service.createMany(req.body);
20
+ savedKeys.push(...keys);
21
+ }
22
+ else {
23
+ const key = await service.createOne(req.body);
24
+ savedKeys.push(key);
25
+ }
26
+ try {
27
+ if (Array.isArray(req.body)) {
28
+ const items = await service.readMany(savedKeys, req.sanitizedQuery);
29
+ res.locals['payload'] = { data: items };
30
+ }
31
+ else {
32
+ const item = await service.readOne(savedKeys[0], req.sanitizedQuery);
33
+ res.locals['payload'] = { data: item };
34
+ }
35
+ }
36
+ catch (error) {
37
+ if (isDirectusError(error, ErrorCode.Forbidden)) {
38
+ return next();
39
+ }
40
+ throw error;
41
+ }
42
+ return next();
43
+ }), respond);
44
+ const readHandler = asyncHandler(async (req, res, next) => {
45
+ const service = new AccessService({
46
+ accountability: req.accountability,
47
+ schema: req.schema,
48
+ });
49
+ const metaService = new MetaService({
50
+ accountability: req.accountability,
51
+ schema: req.schema,
52
+ });
53
+ let result;
54
+ if (req.body.keys) {
55
+ result = await service.readMany(req.body.keys, req.sanitizedQuery);
56
+ }
57
+ else {
58
+ result = await service.readByQuery(req.sanitizedQuery);
59
+ }
60
+ const meta = await metaService.getMetaForQuery('directus_access', req.sanitizedQuery);
61
+ res.locals['payload'] = { data: result, meta };
62
+ return next();
63
+ });
64
+ router.get('/', validateBatch('read'), readHandler, respond);
65
+ router.search('/', validateBatch('read'), readHandler, respond);
66
+ router.get('/:pk', asyncHandler(async (req, res, next) => {
67
+ if (req.path.endsWith('me'))
68
+ return next();
69
+ const service = new AccessService({
70
+ accountability: req.accountability,
71
+ schema: req.schema,
72
+ });
73
+ const record = await service.readOne(req.params['pk'], req.sanitizedQuery);
74
+ res.locals['payload'] = { data: record };
75
+ return next();
76
+ }), respond);
77
+ router.patch('/', validateBatch('update'), asyncHandler(async (req, res, next) => {
78
+ const service = new AccessService({
79
+ accountability: req.accountability,
80
+ schema: req.schema,
81
+ });
82
+ let keys = [];
83
+ if (Array.isArray(req.body)) {
84
+ keys = await service.updateBatch(req.body);
85
+ }
86
+ else if (req.body.keys) {
87
+ keys = await service.updateMany(req.body.keys, req.body.data);
88
+ }
89
+ else {
90
+ const sanitizedQuery = sanitizeQuery(req.body.query, req.accountability);
91
+ keys = await service.updateByQuery(sanitizedQuery, req.body.data);
92
+ }
93
+ try {
94
+ const result = await service.readMany(keys, req.sanitizedQuery);
95
+ res.locals['payload'] = { data: result };
96
+ }
97
+ catch (error) {
98
+ if (isDirectusError(error, ErrorCode.Forbidden)) {
99
+ return next();
100
+ }
101
+ throw error;
102
+ }
103
+ return next();
104
+ }), respond);
105
+ router.patch('/:pk', asyncHandler(async (req, res, next) => {
106
+ const service = new AccessService({
107
+ accountability: req.accountability,
108
+ schema: req.schema,
109
+ });
110
+ const primaryKey = await service.updateOne(req.params['pk'], req.body);
111
+ try {
112
+ const item = await service.readOne(primaryKey, req.sanitizedQuery);
113
+ res.locals['payload'] = { data: item || null };
114
+ }
115
+ catch (error) {
116
+ if (isDirectusError(error, ErrorCode.Forbidden)) {
117
+ return next();
118
+ }
119
+ throw error;
120
+ }
121
+ return next();
122
+ }), respond);
123
+ router.delete('/', validateBatch('delete'), asyncHandler(async (req, _res, next) => {
124
+ const service = new AccessService({
125
+ accountability: req.accountability,
126
+ schema: req.schema,
127
+ });
128
+ if (Array.isArray(req.body)) {
129
+ await service.deleteMany(req.body);
130
+ }
131
+ else if (req.body.keys) {
132
+ await service.deleteMany(req.body.keys);
133
+ }
134
+ else {
135
+ const sanitizedQuery = sanitizeQuery(req.body.query, req.accountability);
136
+ await service.deleteByQuery(sanitizedQuery);
137
+ }
138
+ return next();
139
+ }), respond);
140
+ router.delete('/:pk', asyncHandler(async (req, _res, next) => {
141
+ const service = new AccessService({
142
+ accountability: req.accountability,
143
+ schema: req.schema,
144
+ });
145
+ await service.deleteOne(req.params['pk']);
146
+ return next();
147
+ }), respond);
148
+ export default router;
@@ -5,6 +5,7 @@ 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';
8
9
  import { AuthenticationService } from '../services/authentication.js';
9
10
  import { UsersService } from '../services/users.js';
10
11
  import asyncHandler from '../utils/async-handler.js';
@@ -71,10 +72,7 @@ function getCurrentRefreshToken(req, mode) {
71
72
  return undefined;
72
73
  }
73
74
  router.post('/refresh', asyncHandler(async (req, res, next) => {
74
- const accountability = {
75
- ip: getIPFromReq(req),
76
- role: null,
77
- };
75
+ const accountability = createDefaultAccountability({ ip: getIPFromReq(req) });
78
76
  const userAgent = req.get('user-agent')?.substring(0, 1024);
79
77
  if (userAgent)
80
78
  accountability.userAgent = userAgent;
@@ -111,10 +109,7 @@ router.post('/refresh', asyncHandler(async (req, res, next) => {
111
109
  return next();
112
110
  }), respond);
113
111
  router.post('/logout', asyncHandler(async (req, res, next) => {
114
- const accountability = {
115
- ip: getIPFromReq(req),
116
- role: null,
117
- };
112
+ const accountability = createDefaultAccountability({ ip: getIPFromReq(req) });
118
113
  const userAgent = req.get('user-agent')?.substring(0, 1024);
119
114
  if (userAgent)
120
115
  accountability.userAgent = userAgent;
@@ -145,10 +140,7 @@ router.post('/password/request', asyncHandler(async (req, _res, next) => {
145
140
  if (typeof req.body.email !== 'string') {
146
141
  throw new InvalidPayloadError({ reason: `"email" field is required` });
147
142
  }
148
- const accountability = {
149
- ip: getIPFromReq(req),
150
- role: null,
151
- };
143
+ const accountability = createDefaultAccountability({ ip: getIPFromReq(req) });
152
144
  const userAgent = req.get('user-agent')?.substring(0, 1024);
153
145
  if (userAgent)
154
146
  accountability.userAgent = userAgent;
@@ -177,10 +169,7 @@ router.post('/password/reset', asyncHandler(async (req, _res, next) => {
177
169
  if (typeof req.body.password !== 'string') {
178
170
  throw new InvalidPayloadError({ reason: `"password" field is required` });
179
171
  }
180
- const accountability = {
181
- ip: getIPFromReq(req),
182
- role: null,
183
- };
172
+ const accountability = createDefaultAccountability({ ip: getIPFromReq(req) });
184
173
  const userAgent = req.get('user-agent')?.substring(0, 1024);
185
174
  if (userAgent)
186
175
  accountability.userAgent = userAgent;
@@ -1,10 +1,12 @@
1
- import { ErrorCode, isDirectusError } from '@directus/errors';
1
+ import { ErrorCode, ForbiddenError, isDirectusError } from '@directus/errors';
2
2
  import express from 'express';
3
+ import getDatabase from '../database/index.js';
3
4
  import { respond } from '../middleware/respond.js';
4
5
  import useCollection from '../middleware/use-collection.js';
5
6
  import { validateBatch } from '../middleware/validate-batch.js';
7
+ import { fetchAccountabilityCollectionAccess } from '../permissions/modules/fetch-accountability-collection-access/fetch-accountability-collection-access.js';
6
8
  import { MetaService } from '../services/meta.js';
7
- import { PermissionsService } from '../services/permissions/index.js';
9
+ import { PermissionsService } from '../services/permissions.js';
8
10
  import asyncHandler from '../utils/async-handler.js';
9
11
  import { sanitizeQuery } from '../utils/sanitize-query.js';
10
12
  const router = express.Router();
@@ -69,6 +71,16 @@ const readHandler = asyncHandler(async (req, res, next) => {
69
71
  });
70
72
  router.get('/', validateBatch('read'), readHandler, respond);
71
73
  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);
72
84
  router.get('/:pk', asyncHandler(async (req, res, next) => {
73
85
  if (req.path.endsWith('me'))
74
86
  return next();
@@ -0,0 +1,2 @@
1
+ declare const router: import("express-serve-static-core").Router;
2
+ export default router;