@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
@@ -6,15 +6,21 @@ import objectHash from 'object-hash';
6
6
  import { getCache } from '../cache.js';
7
7
  import getDatabase from '../database/index.js';
8
8
  import emitter from '../emitter.js';
9
- import { validateAccess } from '../permissions/modules/validate-access/validate-access.js';
10
9
  import { shouldClearCache } from '../utils/should-clear-cache.js';
11
10
  import { ActivityService } from './activity.js';
11
+ import { AuthorizationService } from './authorization.js';
12
12
  import { ItemsService } from './items.js';
13
13
  import { PayloadService } from './payload.js';
14
14
  import { RevisionsService } from './revisions.js';
15
15
  export class VersionsService extends ItemsService {
16
+ authorizationService;
16
17
  constructor(options) {
17
18
  super('directus_versions', options);
19
+ this.authorizationService = new AuthorizationService({
20
+ accountability: this.accountability,
21
+ knex: this.knex,
22
+ schema: this.schema,
23
+ });
18
24
  }
19
25
  async validateCreateData(data) {
20
26
  if (!data['key'])
@@ -49,31 +55,11 @@ export class VersionsService extends ItemsService {
49
55
  });
50
56
  }
51
57
  // will throw an error if the accountability does not have permission to read the item
52
- if (this.accountability) {
53
- await validateAccess({
54
- accountability: this.accountability,
55
- action: 'read',
56
- collection: data['collection'],
57
- primaryKeys: [data['item']],
58
- }, {
59
- schema: this.schema,
60
- knex: this.knex,
61
- });
62
- }
58
+ await this.authorizationService.checkAccess('read', data['collection'], data['item']);
63
59
  }
64
60
  async getMainItem(collection, item, query) {
65
61
  // will throw an error if the accountability does not have permission to read the item
66
- if (this.accountability) {
67
- await validateAccess({
68
- accountability: this.accountability,
69
- action: 'read',
70
- collection,
71
- primaryKeys: [item],
72
- }, {
73
- schema: this.schema,
74
- knex: this.knex,
75
- });
76
- }
62
+ await this.authorizationService.checkAccess('read', collection, item);
77
63
  const itemsService = new ItemsService(collection, {
78
64
  knex: this.knex,
79
65
  accountability: this.accountability,
@@ -214,17 +200,7 @@ export class VersionsService extends ItemsService {
214
200
  async promote(version, mainHash, fields) {
215
201
  const { id, collection, item } = (await this.readOne(version));
216
202
  // will throw an error if the accountability does not have permission to update the item
217
- if (this.accountability) {
218
- await validateAccess({
219
- accountability: this.accountability,
220
- action: 'update',
221
- collection,
222
- primaryKeys: [item],
223
- }, {
224
- schema: this.schema,
225
- knex: this.knex,
226
- });
227
- }
203
+ await this.authorizationService.checkAccess('update', collection, item);
228
204
  const { outdated } = await this.verifyHash(collection, item, mainHash);
229
205
  if (outdated) {
230
206
  throw new UnprocessableContentError({
@@ -2,11 +2,11 @@ import { useEnv } from '@directus/env';
2
2
  import { version } from 'directus/version';
3
3
  import { getHelpers } from '../../database/helpers/index.js';
4
4
  import { getDatabase, getDatabaseClient } from '../../database/index.js';
5
- import { fetchUserCount } from '../../utils/fetch-user-count/fetch-user-count.js';
6
5
  import { getExtensionCount } from '../utils/get-extension-count.js';
7
6
  import { getFieldCount } from '../utils/get-field-count.js';
8
7
  import { getFilesizeSum } from '../utils/get-filesize-sum.js';
9
8
  import { getItemCount } from '../utils/get-item-count.js';
9
+ import { getUserCount } from '../utils/get-user-count.js';
10
10
  import { getUserItemCount } from '../utils/get-user-item-count.js';
11
11
  const basicCountTasks = [
12
12
  { collection: 'directus_dashboards' },
@@ -27,7 +27,7 @@ export const getReport = async () => {
27
27
  const helpers = getHelpers(db);
28
28
  const [basicCounts, userCounts, userItemCount, fieldsCounts, extensionsCounts, databaseSize, filesizes] = await Promise.all([
29
29
  getItemCount(db, basicCountTasks),
30
- fetchUserCount({ knex: db }),
30
+ getUserCount(db),
31
31
  getUserItemCount(db),
32
32
  getFieldCount(db),
33
33
  getExtensionCount(db),
@@ -0,0 +1,7 @@
1
+ import type { PrimaryKey } from '@directus/types';
2
+ import type { Knex } from 'knex';
3
+ import { type AccessTypeCount } from './get-user-count.js';
4
+ /**
5
+ * Ensure that user limits are not reached
6
+ */
7
+ export declare function checkIncreasedUserLimits(db: Knex, increasedUserCounts: AccessTypeCount, ignoreIds?: PrimaryKey[]): Promise<void>;
@@ -0,0 +1,25 @@
1
+ import { useEnv } from '@directus/env';
2
+ import { LimitExceededError } from '@directus/errors';
3
+ import { getUserCount } from './get-user-count.js';
4
+ const env = useEnv();
5
+ /**
6
+ * Ensure that user limits are not reached
7
+ */
8
+ export async function checkIncreasedUserLimits(db, increasedUserCounts, ignoreIds = []) {
9
+ if (!increasedUserCounts.admin && !increasedUserCounts.app && !increasedUserCounts.api)
10
+ return;
11
+ const userCounts = await getUserCount(db, ignoreIds);
12
+ // Admins have full permissions, therefore should count under app access limit
13
+ const existingAppUsersCount = userCounts.admin + userCounts.app;
14
+ const newAppUsersCount = increasedUserCounts.admin + increasedUserCounts.app;
15
+ if (increasedUserCounts.admin > 0 &&
16
+ increasedUserCounts.admin + userCounts.admin > Number(env['USERS_ADMIN_ACCESS_LIMIT'])) {
17
+ throw new LimitExceededError({ category: 'Active Admin users' });
18
+ }
19
+ if (newAppUsersCount > 0 && newAppUsersCount + existingAppUsersCount > Number(env['USERS_APP_ACCESS_LIMIT'])) {
20
+ throw new LimitExceededError({ category: 'Active App users' });
21
+ }
22
+ if (increasedUserCounts.api > 0 && increasedUserCounts.api + userCounts.api > Number(env['USERS_API_ACCESS_LIMIT'])) {
23
+ throw new LimitExceededError({ category: 'Active API users' });
24
+ }
25
+ }
@@ -0,0 +1,6 @@
1
+ import type { Knex } from 'knex';
2
+ import { type AccessTypeCount } from './get-user-count.js';
3
+ /**
4
+ * Get the role type counts by role IDs
5
+ */
6
+ export declare function getRoleCountsByRoles(db: Knex, roles: string[]): Promise<AccessTypeCount>;
@@ -0,0 +1,27 @@
1
+ import { toBoolean } from '@directus/utils';
2
+ import {} from './get-user-count.js';
3
+ /**
4
+ * Get the role type counts by role IDs
5
+ */
6
+ export async function getRoleCountsByRoles(db, roles) {
7
+ const counts = {
8
+ admin: 0,
9
+ app: 0,
10
+ api: 0,
11
+ };
12
+ const result = (await db.select('id', 'admin_access', 'app_access').from('directus_roles').whereIn('id', roles));
13
+ for (const role of result) {
14
+ const adminAccess = toBoolean(role.admin_access);
15
+ const appAccess = toBoolean(role.app_access);
16
+ if (adminAccess) {
17
+ counts.admin++;
18
+ }
19
+ else if (appAccess) {
20
+ counts.app++;
21
+ }
22
+ else {
23
+ counts.api++;
24
+ }
25
+ }
26
+ return counts;
27
+ }
@@ -0,0 +1,11 @@
1
+ import type { PrimaryKey } from '@directus/types';
2
+ import type { Knex } from 'knex';
3
+ import type { AccessTypeCount } from './get-user-count.js';
4
+ type CountOptions = {
5
+ inactiveUsers?: boolean;
6
+ };
7
+ /**
8
+ * Get the role type counts by user IDs
9
+ */
10
+ export declare function getRoleCountsByUsers(db: Knex, userIds: PrimaryKey[], options?: CountOptions): Promise<AccessTypeCount>;
11
+ export {};
@@ -0,0 +1,34 @@
1
+ import { toBoolean } from '@directus/utils';
2
+ /**
3
+ * Get the role type counts by user IDs
4
+ */
5
+ export async function getRoleCountsByUsers(db, userIds, options = {}) {
6
+ const counts = {
7
+ admin: 0,
8
+ app: 0,
9
+ api: 0,
10
+ };
11
+ const result = await db
12
+ .count('directus_users.id', { as: 'count' })
13
+ .select('directus_roles.admin_access', 'directus_roles.app_access')
14
+ .from('directus_users')
15
+ .whereIn('directus_users.id', userIds)
16
+ .andWhere('directus_users.status', options.inactiveUsers ? '!=' : '=', 'active')
17
+ .leftJoin('directus_roles', 'directus_users.role', '=', 'directus_roles.id')
18
+ .groupBy('directus_roles.admin_access', 'directus_roles.app_access');
19
+ for (const record of result) {
20
+ const adminAccess = toBoolean(record.admin_access);
21
+ const appAccess = toBoolean(record.app_access);
22
+ const count = Number(record.count);
23
+ if (adminAccess) {
24
+ counts.admin += count;
25
+ }
26
+ else if (appAccess) {
27
+ counts.app += count;
28
+ }
29
+ else {
30
+ counts.api += count;
31
+ }
32
+ }
33
+ return counts;
34
+ }
@@ -0,0 +1,8 @@
1
+ import type { PrimaryKey } from '@directus/types';
2
+ import { type Knex } from 'knex';
3
+ export interface AccessTypeCount {
4
+ admin: number;
5
+ app: number;
6
+ api: number;
7
+ }
8
+ export declare const getUserCount: (db: Knex, ignoreIds?: PrimaryKey[]) => Promise<AccessTypeCount>;
@@ -0,0 +1,33 @@
1
+ import { toBoolean } from '@directus/utils';
2
+ import {} from 'knex';
3
+ export const getUserCount = async (db, ignoreIds = []) => {
4
+ const counts = {
5
+ admin: 0,
6
+ app: 0,
7
+ api: 0,
8
+ };
9
+ const result = (await db
10
+ .count('directus_users.id', { as: 'count' })
11
+ .select('directus_roles.admin_access', 'directus_roles.app_access')
12
+ .from('directus_users')
13
+ .whereNotIn('directus_users.id', ignoreIds)
14
+ .andWhere('directus_users.status', 'active')
15
+ .leftJoin('directus_roles', 'directus_users.role', '=', 'directus_roles.id')
16
+ .where('directus_users.status', '=', 'active')
17
+ .groupBy('directus_roles.admin_access', 'directus_roles.app_access'));
18
+ for (const record of result) {
19
+ const adminAccess = toBoolean(record.admin_access);
20
+ const appAccess = toBoolean(record.app_access);
21
+ const count = Number(record.count);
22
+ if (adminAccess) {
23
+ counts.admin += count;
24
+ }
25
+ else if (appAccess) {
26
+ counts.app += count;
27
+ }
28
+ else {
29
+ counts.api += count;
30
+ }
31
+ }
32
+ return counts;
33
+ };
@@ -0,0 +1,7 @@
1
+ import type { PrimaryKey } from '@directus/types';
2
+ import type { Knex } from 'knex';
3
+ import { type AccessTypeCount } from './get-user-count.js';
4
+ /**
5
+ * Get the user type counts by role IDs
6
+ */
7
+ export declare function getUserCountsByRoles(db: Knex, roleIds: PrimaryKey[]): Promise<AccessTypeCount>;
@@ -0,0 +1,35 @@
1
+ import { toBoolean } from '@directus/utils';
2
+ import {} from './get-user-count.js';
3
+ /**
4
+ * Get the user type counts by role IDs
5
+ */
6
+ export async function getUserCountsByRoles(db, roleIds) {
7
+ const counts = {
8
+ admin: 0,
9
+ app: 0,
10
+ api: 0,
11
+ };
12
+ const result = (await db
13
+ .count('directus_users.id', { as: 'count' })
14
+ .select('directus_roles.admin_access', 'directus_roles.app_access')
15
+ .from('directus_users')
16
+ .whereIn('directus_roles.id', roleIds)
17
+ .andWhere('directus_users.status', '=', 'active')
18
+ .leftJoin('directus_roles', 'directus_users.role', '=', 'directus_roles.id')
19
+ .groupBy('directus_roles.admin_access', 'directus_roles.app_access'));
20
+ for (const record of result) {
21
+ const adminAccess = toBoolean(record.admin_access);
22
+ const appAccess = toBoolean(record.app_access);
23
+ const count = Number(record.count);
24
+ if (adminAccess) {
25
+ counts.admin += count;
26
+ }
27
+ else if (appAccess) {
28
+ counts.app += count;
29
+ }
30
+ else {
31
+ counts.api += count;
32
+ }
33
+ }
34
+ return counts;
35
+ }
@@ -1,4 +1,4 @@
1
- import type { Filter, Query, Relation } from '@directus/types';
1
+ import type { Query, Relation } from '@directus/types';
2
2
  export type M2ONode = {
3
3
  type: 'm2o';
4
4
  name: string;
@@ -8,14 +8,6 @@ export type M2ONode = {
8
8
  relation: Relation;
9
9
  parentKey: string;
10
10
  relatedKey: string;
11
- /**
12
- * Which permission cases have to be met on the current item for this field to return a value
13
- */
14
- whenCase: number[];
15
- /**
16
- * Permissions rules for the item access of the children of this item.
17
- */
18
- cases: Filter[];
19
11
  };
20
12
  export type A2MNode = {
21
13
  type: 'a2o';
@@ -32,16 +24,6 @@ export type A2MNode = {
32
24
  fieldKey: string;
33
25
  relation: Relation;
34
26
  parentKey: string;
35
- /**
36
- * Which permission cases have to be met on the current item for this field to return a value
37
- */
38
- whenCase: number[];
39
- /**
40
- * Permissions rules for the item access of the children of this item.
41
- */
42
- cases: {
43
- [collection: string]: Filter[];
44
- };
45
27
  };
46
28
  export type O2MNode = {
47
29
  type: 'o2m';
@@ -52,24 +34,12 @@ export type O2MNode = {
52
34
  relation: Relation;
53
35
  parentKey: string;
54
36
  relatedKey: string;
55
- /**
56
- * Which permission cases have to be met on the current item for this field to return a value
57
- */
58
- whenCase: number[];
59
- /**
60
- * Permissions rules for the item access of the children of this item.
61
- */
62
- cases: Filter[];
63
37
  };
64
38
  export type NestedCollectionNode = M2ONode | O2MNode | A2MNode;
65
39
  export type FieldNode = {
66
40
  type: 'field';
67
41
  name: string;
68
42
  fieldKey: string;
69
- /**
70
- * Which permission cases have to be met on the current item for this field to return a value
71
- */
72
- whenCase: number[];
73
43
  };
74
44
  export type FunctionFieldNode = {
75
45
  type: 'functionField';
@@ -77,22 +47,10 @@ export type FunctionFieldNode = {
77
47
  fieldKey: string;
78
48
  query: Query;
79
49
  relatedCollection: string;
80
- /**
81
- * Which permission cases have to be met on the current item for this field to return a value
82
- */
83
- whenCase: number[];
84
- /**
85
- * Permissions rules for the item access of the related collection of this item.
86
- */
87
- cases: Filter[];
88
50
  };
89
51
  export type AST = {
90
52
  type: 'root';
91
53
  name: string;
92
54
  children: (NestedCollectionNode | FieldNode | FunctionFieldNode)[];
93
55
  query: Query;
94
- /**
95
- * Permissions rules for the item access of the children of this item.
96
- */
97
- cases: Filter[];
98
56
  };
@@ -1,7 +1,6 @@
1
1
  import type { DirectusError } from '@directus/errors';
2
2
  import type { EventContext, PrimaryKey } from '@directus/types';
3
3
  import type { MutationTracker } from '../services/items.js';
4
- import type { UserIntegrityCheckFlag } from '../utils/validate-user-count-integrity.js';
5
4
  export type MutationOptions = {
6
5
  /**
7
6
  * Callback function that's fired whenever a revision is made in the mutation
@@ -34,16 +33,6 @@ export type MutationOptions = {
34
33
  mutationTracker?: MutationTracker | undefined;
35
34
  preMutationError?: DirectusError | undefined;
36
35
  bypassAutoIncrementSequenceReset?: boolean;
37
- /**
38
- * Indicate that the top level mutation needs to perform a user integrity check before commiting the transaction
39
- * This is a combination of flags
40
- * @see UserIntegrityCheckFlag
41
- */
42
- userIntegrityCheckFlags?: UserIntegrityCheckFlag;
43
- /**
44
- * Callback function that is called whenever a mutation requires a user integrity check to be made
45
- */
46
- onRequireUserIntegrityCheck?: ((flags: UserIntegrityCheckFlag) => void) | undefined;
47
36
  };
48
37
  export type ActionEventParams = {
49
38
  event: string | string[];
@@ -5,7 +5,7 @@ export declare const generateAlias: (size?: number | undefined) => string;
5
5
  /**
6
6
  * Apply the Query to a given Knex query builder instance
7
7
  */
8
- export default function applyQuery(knex: Knex, collection: string, dbQuery: Knex.QueryBuilder, query: Query, schema: SchemaOverview, cases: Filter[], options?: {
8
+ export default function applyQuery(knex: Knex, collection: string, dbQuery: Knex.QueryBuilder, query: Query, schema: SchemaOverview, options?: {
9
9
  aliasMap?: AliasMap;
10
10
  isInnerQuery?: boolean;
11
11
  hasMultiRelationalSort?: boolean | undefined;
@@ -32,11 +32,10 @@ export declare function applySort(knex: Knex, schema: SchemaOverview, rootQuery:
32
32
  };
33
33
  export declare function applyLimit(knex: Knex, rootQuery: Knex.QueryBuilder, limit: any): void;
34
34
  export declare function applyOffset(knex: Knex, rootQuery: Knex.QueryBuilder, offset: any): void;
35
- export declare function applyFilter(knex: Knex, schema: SchemaOverview, rootQuery: Knex.QueryBuilder, rootFilter: Filter, collection: string, aliasMap: AliasMap, cases: Filter[]): {
35
+ export declare function applyFilter(knex: Knex, schema: SchemaOverview, rootQuery: Knex.QueryBuilder, rootFilter: Filter, collection: string, aliasMap: AliasMap): {
36
36
  query: Knex.QueryBuilder<any, any>;
37
37
  hasJoins: boolean;
38
38
  hasMultiRelationalFilter: boolean;
39
39
  };
40
- export declare function applySearch(knex: Knex, schema: SchemaOverview, dbQuery: Knex.QueryBuilder, searchQuery: string, collection: string): void;
40
+ export declare function applySearch(knex: Knex, schema: SchemaOverview, dbQuery: Knex.QueryBuilder, searchQuery: string, collection: string): Promise<void>;
41
41
  export declare function applyAggregate(schema: SchemaOverview, dbQuery: Knex.QueryBuilder, aggregate: Aggregate, collection: string, hasJoins: boolean): void;
42
- export declare function joinFilterWithCases(filter: Filter | null | undefined, cases: Filter[]): Filter | null;
@@ -14,7 +14,7 @@ export const generateAlias = customAlphabet('abcdefghijklmnopqrstuvwxyz', 5);
14
14
  /**
15
15
  * Apply the Query to a given Knex query builder instance
16
16
  */
17
- export default function applyQuery(knex, collection, dbQuery, query, schema, cases, options) {
17
+ export default function applyQuery(knex, collection, dbQuery, query, schema, options) {
18
18
  const aliasMap = options?.aliasMap ?? Object.create(null);
19
19
  let hasJoins = false;
20
20
  let hasMultiRelationalFilter = false;
@@ -37,14 +37,8 @@ export default function applyQuery(knex, collection, dbQuery, query, schema, cas
37
37
  if (query.group) {
38
38
  dbQuery.groupBy(query.group.map((column) => getColumn(knex, collection, column, false, schema)));
39
39
  }
40
- // `cases` are the permissions cases that are required for the current data set. We're
41
- // dynamically adding those into the filters that the user provided to enforce the permission
42
- // rules. You should be able to read an item if one or more of the cases matches. The actual case
43
- // is reused in the column selection case/when to dynamically return or nullify the field values
44
- // you're actually allowed to read
45
- const filter = joinFilterWithCases(query.filter, cases);
46
- if (filter) {
47
- const filterResult = applyFilter(knex, schema, dbQuery, filter, collection, aliasMap, cases);
40
+ if (query.filter) {
41
+ const filterResult = applyFilter(knex, schema, dbQuery, query.filter, collection, aliasMap);
48
42
  if (!hasJoins) {
49
43
  hasJoins = filterResult.hasJoins;
50
44
  }
@@ -232,7 +226,7 @@ export function applyOffset(knex, rootQuery, offset) {
232
226
  getHelpers(knex).schema.applyOffset(rootQuery, offset);
233
227
  }
234
228
  }
235
- export function applyFilter(knex, schema, rootQuery, rootFilter, collection, aliasMap, cases) {
229
+ export function applyFilter(knex, schema, rootQuery, rootFilter, collection, aliasMap) {
236
230
  const helpers = getHelpers(knex);
237
231
  const relations = schema.relations;
238
232
  let hasJoins = false;
@@ -241,23 +235,12 @@ export function applyFilter(knex, schema, rootQuery, rootFilter, collection, ali
241
235
  addWhereClauses(knex, rootQuery, rootFilter, collection);
242
236
  return { query: rootQuery, hasJoins, hasMultiRelationalFilter };
243
237
  function addJoins(dbQuery, filter, collection) {
244
- // eslint-disable-next-line prefer-const
245
- for (let [key, value] of Object.entries(filter)) {
238
+ for (const [key, value] of Object.entries(filter)) {
246
239
  if (key === '_or' || key === '_and') {
247
240
  // If the _or array contains an empty object (full permissions), we should short-circuit and ignore all other
248
241
  // permission checks, as {} already matches full permissions.
249
242
  if (key === '_or' && value.some((subFilter) => Object.keys(subFilter).length === 0)) {
250
- // But only do so, if the value is not equal to `cases` (since then this is not permission related at all)
251
- // or the length of value is 1, ie. only the empty filter.
252
- // If the length is more than one it means that some items (and fields) might now be available, so
253
- // the joins are required for the case/when construction.
254
- if (value !== cases || value.length === 1) {
255
- continue;
256
- }
257
- else {
258
- // Otherwise we can at least filter out all empty filters that would not add joins anyway
259
- value = value.filter((subFilter) => Object.keys(subFilter).length > 0);
260
- }
243
+ continue;
261
244
  }
262
245
  value.forEach((subFilter) => {
263
246
  addJoins(dbQuery, subFilter, collection);
@@ -328,7 +311,7 @@ export function applyFilter(knex, schema, rootQuery, rootFilter, collection, ali
328
311
  .select({ [field]: column })
329
312
  .from(collection)
330
313
  .whereNotNull(column);
331
- applyQuery(knex, relation.collection, subQueryKnex, { filter }, schema, cases);
314
+ applyQuery(knex, relation.collection, subQueryKnex, { filter }, schema);
332
315
  };
333
316
  const childKey = Object.keys(value)?.[0];
334
317
  if (childKey === '_none') {
@@ -408,11 +391,17 @@ export function applyFilter(knex, schema, rootQuery, rootFilter, collection, ali
408
391
  // Knex supports "raw" in the columnName parameter, but isn't typed as such. Too bad..
409
392
  // See https://github.com/knex/knex/issues/4518 @TODO remove as any once knex is updated
410
393
  // These operators don't rely on a value, and can thus be used without one (eg `?filter[field][_null]`)
411
- if ((operator === '_null' && compareValue !== false) || (operator === '_nnull' && compareValue === false)) {
394
+ if ((operator === '_null' && compareValue !== false) ||
395
+ (operator === '_nnull' && compareValue === false) ||
396
+ (operator === '_eq' && compareValue === null)) {
412
397
  dbQuery[logical].whereNull(selectionRaw);
398
+ return;
413
399
  }
414
- if ((operator === '_nnull' && compareValue !== false) || (operator === '_null' && compareValue === false)) {
400
+ if ((operator === '_nnull' && compareValue !== false) ||
401
+ (operator === '_null' && compareValue === false) ||
402
+ (operator === '_neq' && compareValue === null)) {
415
403
  dbQuery[logical].whereNotNull(selectionRaw);
404
+ return;
416
405
  }
417
406
  if ((operator === '_empty' && compareValue !== false) || (operator === '_nempty' && compareValue === false)) {
418
407
  dbQuery[logical].andWhere((query) => {
@@ -568,7 +557,7 @@ export function applyFilter(knex, schema, rootQuery, rootFilter, collection, ali
568
557
  }
569
558
  }
570
559
  }
571
- export function applySearch(knex, schema, dbQuery, searchQuery, collection) {
560
+ export async function applySearch(knex, schema, dbQuery, searchQuery, collection) {
572
561
  const { number: numberHelper } = getHelpers(knex);
573
562
  const fields = Object.entries(schema.collections[collection].fields);
574
563
  dbQuery.andWhere(function () {
@@ -644,18 +633,6 @@ export function applyAggregate(schema, dbQuery, aggregate, collection, hasJoins)
644
633
  }
645
634
  }
646
635
  }
647
- export function joinFilterWithCases(filter, cases) {
648
- if (cases.length > 0 && !filter) {
649
- return { _or: cases };
650
- }
651
- else if (filter && cases.length === 0) {
652
- return filter ?? null;
653
- }
654
- else if (filter && cases.length > 0) {
655
- return { _and: [filter, { _or: cases }] };
656
- }
657
- return null;
658
- }
659
636
  function getFilterPath(key, value) {
660
637
  const path = [key];
661
638
  const childKey = Object.keys(value)[0];
@@ -1,31 +1,40 @@
1
- import { fetchRolesTree } from '../permissions/lib/fetch-roles-tree.js';
2
- import { fetchGlobalAccess } from '../permissions/modules/fetch-global-access/fetch-global-access.js';
3
- import { createDefaultAccountability } from '../permissions/utils/create-default-accountability.js';
1
+ import { getPermissions } from './get-permissions.js';
4
2
  export async function getAccountabilityForRole(role, context) {
5
- let generatedAccountability;
3
+ let generatedAccountability = context.accountability;
6
4
  if (role === null) {
7
- generatedAccountability = createDefaultAccountability();
5
+ generatedAccountability = {
6
+ role: null,
7
+ user: null,
8
+ admin: false,
9
+ app: false,
10
+ };
11
+ generatedAccountability.permissions = await getPermissions(generatedAccountability, context.schema);
8
12
  }
9
13
  else if (role === 'system') {
10
- generatedAccountability = createDefaultAccountability({
14
+ generatedAccountability = {
15
+ user: null,
16
+ role: null,
11
17
  admin: true,
12
18
  app: true,
13
- });
19
+ permissions: [],
20
+ };
14
21
  }
15
22
  else {
16
- const roles = await fetchRolesTree(role, context.database);
17
- // The roles tree should always include the passed role. If it doesn't, it's because it
18
- // couldn't be read from the database and therefore doesn't exist
19
- if (roles.length === 0) {
23
+ const roleInfo = await context.database
24
+ .select(['app_access', 'admin_access'])
25
+ .from('directus_roles')
26
+ .where({ id: role })
27
+ .first();
28
+ if (!roleInfo) {
20
29
  throw new Error(`Configured role "${role}" isn't a valid role ID or doesn't exist.`);
21
30
  }
22
- const globalAccess = await fetchGlobalAccess({ user: null, roles, ip: context.accountability?.ip ?? null }, context.database);
23
- generatedAccountability = createDefaultAccountability({
31
+ generatedAccountability = {
24
32
  role,
25
- roles,
26
33
  user: null,
27
- ...globalAccess,
28
- });
34
+ admin: roleInfo.admin_access === 1 || roleInfo.admin_access === '1' || roleInfo.admin_access === true,
35
+ app: roleInfo.app_access === 1 || roleInfo.app_access === '1' || roleInfo.app_access === true,
36
+ };
37
+ generatedAccountability.permissions = await getPermissions(generatedAccountability, context.schema);
29
38
  }
30
39
  return generatedAccountability;
31
40
  }