@directus/api 20.0.0-rc.0 → 20.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 (291) hide show
  1. package/dist/app.js +9 -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 +4 -2
  6. package/dist/cache.js +0 -3
  7. package/dist/cli/commands/bootstrap/index.js +2 -8
  8. package/dist/cli/commands/init/index.js +10 -9
  9. package/dist/cli/utils/defaults.d.ts +11 -4
  10. package/dist/cli/utils/defaults.js +1 -7
  11. package/dist/constants.d.ts +9 -1
  12. package/dist/constants.js +10 -0
  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/{access.d.ts → tus.d.ts} +1 -0
  17. package/dist/controllers/tus.js +72 -0
  18. package/dist/controllers/users.js +55 -0
  19. package/dist/database/helpers/fn/types.d.ts +1 -2
  20. package/dist/database/helpers/fn/types.js +1 -1
  21. package/dist/database/helpers/geometry/dialects/mssql.d.ts +1 -1
  22. package/dist/database/helpers/geometry/dialects/mssql.js +2 -4
  23. package/dist/database/helpers/geometry/dialects/mysql.js +1 -1
  24. package/dist/database/helpers/geometry/dialects/oracle.d.ts +1 -1
  25. package/dist/database/helpers/geometry/dialects/oracle.js +3 -5
  26. package/dist/database/helpers/geometry/types.d.ts +1 -1
  27. package/dist/database/helpers/geometry/types.js +2 -4
  28. package/dist/database/index.js +1 -2
  29. package/dist/database/migrations/20240701A-add-tus-data.js +12 -0
  30. package/dist/database/{run-ast/types.d.ts → run-ast.d.ts} +9 -3
  31. package/dist/database/run-ast.js +450 -0
  32. package/dist/flows.js +4 -3
  33. package/dist/middleware/authenticate.js +7 -2
  34. package/dist/middleware/cache.js +1 -1
  35. package/dist/middleware/check-ip.d.ts +2 -0
  36. package/dist/middleware/check-ip.js +37 -0
  37. package/dist/middleware/get-permissions.d.ts +3 -0
  38. package/dist/middleware/get-permissions.js +10 -0
  39. package/dist/middleware/respond.js +1 -1
  40. package/dist/services/activity.js +10 -22
  41. package/dist/services/assets.d.ts +3 -2
  42. package/dist/services/assets.js +5 -10
  43. package/dist/services/authentication.js +26 -32
  44. package/dist/services/authorization.d.ts +17 -0
  45. package/dist/services/authorization.js +456 -0
  46. package/dist/services/collections.js +17 -18
  47. package/dist/services/fields.d.ts +1 -0
  48. package/dist/services/fields.js +24 -53
  49. package/dist/services/files/lib/extract-metadata.d.ts +3 -0
  50. package/dist/services/files/lib/extract-metadata.js +32 -0
  51. package/dist/services/files/utils/get-metadata.d.ts +5 -0
  52. package/dist/services/files/utils/get-metadata.js +107 -0
  53. package/dist/services/files.d.ts +4 -6
  54. package/dist/services/files.js +24 -140
  55. package/dist/services/graphql/index.d.ts +3 -3
  56. package/dist/services/graphql/index.js +22 -126
  57. package/dist/services/graphql/subscription.js +4 -2
  58. package/dist/services/import-export.js +4 -18
  59. package/dist/services/index.d.ts +2 -3
  60. package/dist/services/index.js +2 -3
  61. package/dist/services/items.js +44 -115
  62. package/dist/services/meta.js +23 -60
  63. package/dist/services/payload.d.ts +10 -9
  64. package/dist/services/payload.js +3 -18
  65. package/dist/services/{permissions.d.ts → permissions/index.d.ts} +7 -5
  66. package/dist/services/{permissions.js → permissions/index.js} +54 -30
  67. package/dist/{permissions → services/permissions}/lib/with-app-minimal-permissions.d.ts +1 -1
  68. package/dist/services/permissions/lib/with-app-minimal-permissions.js +13 -0
  69. package/dist/services/relations.d.ts +6 -0
  70. package/dist/services/relations.js +29 -26
  71. package/dist/services/roles.d.ts +12 -4
  72. package/dist/services/roles.js +424 -57
  73. package/dist/services/server.js +6 -0
  74. package/dist/services/shares.d.ts +2 -0
  75. package/dist/services/shares.js +8 -12
  76. package/dist/services/specifications.d.ts +2 -2
  77. package/dist/services/specifications.js +27 -39
  78. package/dist/services/tus/data-store.d.ts +36 -0
  79. package/dist/services/tus/data-store.js +214 -0
  80. package/dist/services/tus/index.d.ts +2 -0
  81. package/dist/services/tus/index.js +2 -0
  82. package/dist/services/tus/lockers.d.ts +36 -0
  83. package/dist/services/tus/lockers.js +83 -0
  84. package/dist/services/tus/server.d.ts +8 -0
  85. package/dist/services/tus/server.js +80 -0
  86. package/dist/services/tus/utils/wait-timeout.d.ts +1 -0
  87. package/dist/services/tus/utils/wait-timeout.js +13 -0
  88. package/dist/services/users.d.ts +5 -1
  89. package/dist/services/users.js +161 -78
  90. package/dist/services/utils.js +7 -11
  91. package/dist/services/versions.d.ts +2 -0
  92. package/dist/services/versions.js +10 -34
  93. package/dist/storage/register-locations.js +5 -1
  94. package/dist/telemetry/lib/get-report.js +2 -2
  95. package/dist/telemetry/utils/check-increased-user-limits.d.ts +7 -0
  96. package/dist/telemetry/utils/check-increased-user-limits.js +25 -0
  97. package/dist/telemetry/utils/get-role-counts-by-roles.d.ts +6 -0
  98. package/dist/telemetry/utils/get-role-counts-by-roles.js +27 -0
  99. package/dist/telemetry/utils/get-role-counts-by-users.d.ts +11 -0
  100. package/dist/telemetry/utils/get-role-counts-by-users.js +34 -0
  101. package/dist/telemetry/utils/get-user-count.d.ts +8 -0
  102. package/dist/telemetry/utils/get-user-count.js +33 -0
  103. package/dist/telemetry/utils/get-user-counts-by-roles.d.ts +7 -0
  104. package/dist/telemetry/utils/get-user-counts-by-roles.js +35 -0
  105. package/dist/types/ast.d.ts +1 -43
  106. package/dist/types/items.d.ts +0 -11
  107. package/dist/utils/apply-query.d.ts +3 -4
  108. package/dist/utils/apply-query.js +8 -37
  109. package/dist/utils/get-accountability-for-role.js +25 -16
  110. package/dist/utils/get-accountability-for-token.js +16 -17
  111. package/dist/utils/get-ast-from-query.d.ts +13 -0
  112. package/dist/utils/get-ast-from-query.js +297 -0
  113. package/dist/utils/get-cache-key.d.ts +1 -1
  114. package/dist/utils/get-cache-key.js +1 -12
  115. package/dist/utils/get-column.d.ts +1 -2
  116. package/dist/utils/get-column.js +0 -1
  117. package/dist/utils/get-permissions.d.ts +2 -0
  118. package/dist/utils/get-permissions.js +150 -0
  119. package/dist/utils/get-service.js +1 -5
  120. package/dist/utils/merge-permissions-for-share.d.ts +4 -0
  121. package/dist/utils/merge-permissions-for-share.js +109 -0
  122. package/dist/utils/merge-permissions.d.ts +3 -0
  123. package/dist/utils/merge-permissions.js +95 -0
  124. package/dist/utils/reduce-schema.d.ts +6 -4
  125. package/dist/utils/reduce-schema.js +34 -14
  126. package/dist/utils/verify-session-jwt.js +2 -1
  127. package/dist/websocket/authenticate.d.ts +2 -0
  128. package/dist/websocket/authenticate.js +12 -0
  129. package/dist/websocket/controllers/graphql.js +4 -1
  130. package/dist/websocket/controllers/hooks.js +0 -4
  131. package/dist/websocket/controllers/rest.js +2 -0
  132. package/dist/websocket/handlers/subscribe.js +2 -0
  133. package/dist/websocket/utils/items.d.ts +1 -1
  134. package/package.json +35 -33
  135. package/dist/controllers/access.js +0 -148
  136. package/dist/controllers/policies.d.ts +0 -2
  137. package/dist/controllers/policies.js +0 -169
  138. package/dist/database/get-ast-from-query/get-ast-from-query.d.ts +0 -16
  139. package/dist/database/get-ast-from-query/get-ast-from-query.js +0 -82
  140. package/dist/database/get-ast-from-query/lib/convert-wildcards.d.ts +0 -13
  141. package/dist/database/get-ast-from-query/lib/convert-wildcards.js +0 -69
  142. package/dist/database/get-ast-from-query/lib/parse-fields.d.ts +0 -15
  143. package/dist/database/get-ast-from-query/lib/parse-fields.js +0 -190
  144. package/dist/database/get-ast-from-query/utils/get-deep-query.d.ts +0 -14
  145. package/dist/database/get-ast-from-query/utils/get-deep-query.js +0 -17
  146. package/dist/database/get-ast-from-query/utils/get-related-collection.d.ts +0 -2
  147. package/dist/database/get-ast-from-query/utils/get-related-collection.js +0 -13
  148. package/dist/database/get-ast-from-query/utils/get-relation.d.ts +0 -2
  149. package/dist/database/get-ast-from-query/utils/get-relation.js +0 -7
  150. package/dist/database/migrations/20240619A-permissions-policies.js +0 -163
  151. package/dist/database/run-ast/lib/get-db-query.d.ts +0 -4
  152. package/dist/database/run-ast/lib/get-db-query.js +0 -194
  153. package/dist/database/run-ast/lib/parse-current-level.d.ts +0 -7
  154. package/dist/database/run-ast/lib/parse-current-level.js +0 -41
  155. package/dist/database/run-ast/run-ast.d.ts +0 -7
  156. package/dist/database/run-ast/run-ast.js +0 -107
  157. package/dist/database/run-ast/types.js +0 -1
  158. package/dist/database/run-ast/utils/apply-case-when.d.ts +0 -16
  159. package/dist/database/run-ast/utils/apply-case-when.js +0 -26
  160. package/dist/database/run-ast/utils/apply-parent-filters.d.ts +0 -3
  161. package/dist/database/run-ast/utils/apply-parent-filters.js +0 -55
  162. package/dist/database/run-ast/utils/get-column-pre-processor.d.ts +0 -10
  163. package/dist/database/run-ast/utils/get-column-pre-processor.js +0 -57
  164. package/dist/database/run-ast/utils/get-field-alias.d.ts +0 -2
  165. package/dist/database/run-ast/utils/get-field-alias.js +0 -4
  166. package/dist/database/run-ast/utils/get-inner-query-column-pre-processor.d.ts +0 -5
  167. package/dist/database/run-ast/utils/get-inner-query-column-pre-processor.js +0 -23
  168. package/dist/database/run-ast/utils/merge-with-parent-items.d.ts +0 -3
  169. package/dist/database/run-ast/utils/merge-with-parent-items.js +0 -87
  170. package/dist/database/run-ast/utils/remove-temporary-fields.d.ts +0 -3
  171. package/dist/database/run-ast/utils/remove-temporary-fields.js +0 -73
  172. package/dist/permissions/cache.d.ts +0 -2
  173. package/dist/permissions/cache.js +0 -23
  174. package/dist/permissions/lib/fetch-permissions.d.ts +0 -10
  175. package/dist/permissions/lib/fetch-permissions.js +0 -55
  176. package/dist/permissions/lib/fetch-policies.d.ts +0 -7
  177. package/dist/permissions/lib/fetch-policies.js +0 -28
  178. package/dist/permissions/lib/fetch-roles-tree.d.ts +0 -3
  179. package/dist/permissions/lib/fetch-roles-tree.js +0 -28
  180. package/dist/permissions/lib/with-app-minimal-permissions.js +0 -10
  181. package/dist/permissions/modules/fetch-accountability-collection-access/fetch-accountability-collection-access.d.ts +0 -7
  182. package/dist/permissions/modules/fetch-accountability-collection-access/fetch-accountability-collection-access.js +0 -56
  183. package/dist/permissions/modules/fetch-accountability-policy-globals/fetch-accountability-policy-globals.d.ts +0 -3
  184. package/dist/permissions/modules/fetch-accountability-policy-globals/fetch-accountability-policy-globals.js +0 -16
  185. package/dist/permissions/modules/fetch-allowed-collections/fetch-allowed-collections.d.ts +0 -8
  186. package/dist/permissions/modules/fetch-allowed-collections/fetch-allowed-collections.js +0 -24
  187. package/dist/permissions/modules/fetch-allowed-field-map/fetch-allowed-field-map.d.ts +0 -9
  188. package/dist/permissions/modules/fetch-allowed-field-map/fetch-allowed-field-map.js +0 -31
  189. package/dist/permissions/modules/fetch-allowed-fields/fetch-allowed-fields.d.ts +0 -16
  190. package/dist/permissions/modules/fetch-allowed-fields/fetch-allowed-fields.js +0 -27
  191. package/dist/permissions/modules/fetch-global-access/fetch-global-access.d.ts +0 -10
  192. package/dist/permissions/modules/fetch-global-access/fetch-global-access.js +0 -23
  193. package/dist/permissions/modules/fetch-global-access/lib/fetch-global-access-for-roles.d.ts +0 -5
  194. package/dist/permissions/modules/fetch-global-access/lib/fetch-global-access-for-roles.js +0 -7
  195. package/dist/permissions/modules/fetch-global-access/lib/fetch-global-access-for-user.d.ts +0 -5
  196. package/dist/permissions/modules/fetch-global-access/lib/fetch-global-access-for-user.js +0 -10
  197. package/dist/permissions/modules/fetch-global-access/types.d.ts +0 -4
  198. package/dist/permissions/modules/fetch-global-access/types.js +0 -1
  199. package/dist/permissions/modules/fetch-global-access/utils/fetch-global-access-for-query.d.ts +0 -4
  200. package/dist/permissions/modules/fetch-global-access/utils/fetch-global-access-for-query.js +0 -27
  201. package/dist/permissions/modules/fetch-inconsistent-field-map/fetch-inconsistent-field-map.d.ts +0 -12
  202. package/dist/permissions/modules/fetch-inconsistent-field-map/fetch-inconsistent-field-map.js +0 -32
  203. package/dist/permissions/modules/fetch-policies-ip-access/fetch-policies-ip-access.d.ts +0 -4
  204. package/dist/permissions/modules/fetch-policies-ip-access/fetch-policies-ip-access.js +0 -29
  205. package/dist/permissions/modules/process-ast/lib/extract-fields-from-children.d.ts +0 -4
  206. package/dist/permissions/modules/process-ast/lib/extract-fields-from-children.js +0 -49
  207. package/dist/permissions/modules/process-ast/lib/extract-fields-from-query.d.ts +0 -3
  208. package/dist/permissions/modules/process-ast/lib/extract-fields-from-query.js +0 -56
  209. package/dist/permissions/modules/process-ast/lib/field-map-from-ast.d.ts +0 -4
  210. package/dist/permissions/modules/process-ast/lib/field-map-from-ast.js +0 -8
  211. package/dist/permissions/modules/process-ast/lib/inject-cases.d.ts +0 -9
  212. package/dist/permissions/modules/process-ast/lib/inject-cases.js +0 -93
  213. package/dist/permissions/modules/process-ast/process-ast.d.ts +0 -9
  214. package/dist/permissions/modules/process-ast/process-ast.js +0 -39
  215. package/dist/permissions/modules/process-ast/types.d.ts +0 -24
  216. package/dist/permissions/modules/process-ast/types.js +0 -1
  217. package/dist/permissions/modules/process-ast/utils/collections-in-field-map.d.ts +0 -2
  218. package/dist/permissions/modules/process-ast/utils/collections-in-field-map.js +0 -7
  219. package/dist/permissions/modules/process-ast/utils/dedupe-access.d.ts +0 -12
  220. package/dist/permissions/modules/process-ast/utils/dedupe-access.js +0 -30
  221. package/dist/permissions/modules/process-ast/utils/extract-paths-from-query.d.ts +0 -15
  222. package/dist/permissions/modules/process-ast/utils/extract-paths-from-query.js +0 -50
  223. package/dist/permissions/modules/process-ast/utils/find-related-collection.d.ts +0 -3
  224. package/dist/permissions/modules/process-ast/utils/find-related-collection.js +0 -9
  225. package/dist/permissions/modules/process-ast/utils/flatten-filter.d.ts +0 -3
  226. package/dist/permissions/modules/process-ast/utils/flatten-filter.js +0 -24
  227. package/dist/permissions/modules/process-ast/utils/format-a2o-key.d.ts +0 -1
  228. package/dist/permissions/modules/process-ast/utils/format-a2o-key.js +0 -3
  229. package/dist/permissions/modules/process-ast/utils/get-info-for-path.d.ts +0 -5
  230. package/dist/permissions/modules/process-ast/utils/get-info-for-path.js +0 -7
  231. package/dist/permissions/modules/process-ast/utils/has-item-permissions.d.ts +0 -2
  232. package/dist/permissions/modules/process-ast/utils/has-item-permissions.js +0 -3
  233. package/dist/permissions/modules/process-ast/utils/stringify-query-path.d.ts +0 -2
  234. package/dist/permissions/modules/process-ast/utils/stringify-query-path.js +0 -3
  235. package/dist/permissions/modules/process-ast/utils/validate-path/create-error.d.ts +0 -3
  236. package/dist/permissions/modules/process-ast/utils/validate-path/create-error.js +0 -16
  237. package/dist/permissions/modules/process-ast/utils/validate-path/validate-path-existence.d.ts +0 -2
  238. package/dist/permissions/modules/process-ast/utils/validate-path/validate-path-existence.js +0 -12
  239. package/dist/permissions/modules/process-ast/utils/validate-path/validate-path-permissions.d.ts +0 -2
  240. package/dist/permissions/modules/process-ast/utils/validate-path/validate-path-permissions.js +0 -28
  241. package/dist/permissions/modules/process-payload/lib/is-field-nullable.d.ts +0 -5
  242. package/dist/permissions/modules/process-payload/lib/is-field-nullable.js +0 -12
  243. package/dist/permissions/modules/process-payload/process-payload.d.ts +0 -13
  244. package/dist/permissions/modules/process-payload/process-payload.js +0 -77
  245. package/dist/permissions/modules/validate-access/lib/validate-collection-access.d.ts +0 -12
  246. package/dist/permissions/modules/validate-access/lib/validate-collection-access.js +0 -11
  247. package/dist/permissions/modules/validate-access/lib/validate-item-access.d.ts +0 -9
  248. package/dist/permissions/modules/validate-access/lib/validate-item-access.js +0 -33
  249. package/dist/permissions/modules/validate-access/validate-access.d.ts +0 -14
  250. package/dist/permissions/modules/validate-access/validate-access.js +0 -28
  251. package/dist/permissions/modules/validate-remaining-admin/validate-remaining-admin-count.d.ts +0 -1
  252. package/dist/permissions/modules/validate-remaining-admin/validate-remaining-admin-count.js +0 -8
  253. package/dist/permissions/modules/validate-remaining-admin/validate-remaining-admin-users.d.ts +0 -5
  254. package/dist/permissions/modules/validate-remaining-admin/validate-remaining-admin-users.js +0 -10
  255. package/dist/permissions/types.d.ts +0 -6
  256. package/dist/permissions/types.js +0 -1
  257. package/dist/permissions/utils/create-default-accountability.d.ts +0 -2
  258. package/dist/permissions/utils/create-default-accountability.js +0 -11
  259. package/dist/permissions/utils/extract-required-dynamic-variable-context.d.ts +0 -8
  260. package/dist/permissions/utils/extract-required-dynamic-variable-context.js +0 -27
  261. package/dist/permissions/utils/fetch-dynamic-variable-context.d.ts +0 -9
  262. package/dist/permissions/utils/fetch-dynamic-variable-context.js +0 -43
  263. package/dist/permissions/utils/filter-policies-by-ip.d.ts +0 -2
  264. package/dist/permissions/utils/filter-policies-by-ip.js +0 -15
  265. package/dist/permissions/utils/get-unaliased-field-key.d.ts +0 -5
  266. package/dist/permissions/utils/get-unaliased-field-key.js +0 -17
  267. package/dist/permissions/utils/process-permissions.d.ts +0 -7
  268. package/dist/permissions/utils/process-permissions.js +0 -9
  269. package/dist/permissions/utils/with-cache.d.ts +0 -10
  270. package/dist/permissions/utils/with-cache.js +0 -25
  271. package/dist/services/access.d.ts +0 -10
  272. package/dist/services/access.js +0 -43
  273. package/dist/services/policies.d.ts +0 -12
  274. package/dist/services/policies.js +0 -87
  275. package/dist/telemetry/utils/check-user-limits.d.ts +0 -5
  276. package/dist/telemetry/utils/check-user-limits.js +0 -19
  277. package/dist/utils/fetch-user-count/fetch-access-lookup.d.ts +0 -17
  278. package/dist/utils/fetch-user-count/fetch-access-lookup.js +0 -22
  279. package/dist/utils/fetch-user-count/fetch-access-roles.d.ts +0 -16
  280. package/dist/utils/fetch-user-count/fetch-access-roles.js +0 -37
  281. package/dist/utils/fetch-user-count/fetch-active-users.d.ts +0 -6
  282. package/dist/utils/fetch-user-count/fetch-active-users.js +0 -3
  283. package/dist/utils/fetch-user-count/fetch-user-count.d.ts +0 -12
  284. package/dist/utils/fetch-user-count/fetch-user-count.js +0 -57
  285. package/dist/utils/fetch-user-count/get-user-count-query.d.ts +0 -20
  286. package/dist/utils/fetch-user-count/get-user-count-query.js +0 -17
  287. package/dist/utils/validate-user-count-integrity.d.ts +0 -13
  288. package/dist/utils/validate-user-count-integrity.js +0 -29
  289. /package/dist/database/migrations/{20240619A-permissions-policies.d.ts → 20240701A-add-tus-data.d.ts} +0 -0
  290. /package/dist/{utils → services/files/utils}/parse-image-metadata.d.ts +0 -0
  291. /package/dist/{utils → services/files/utils}/parse-image-metadata.js +0 -0
@@ -1,10 +0,0 @@
1
- import type { Filter, SchemaOverview } from '@directus/types';
2
- import type { Knex } from 'knex';
3
- import type { FieldNode, FunctionFieldNode, M2ONode } from '../../../types/ast.js';
4
- import type { AliasMap } from '../../../utils/get-column-path.js';
5
- interface NodePreProcessOptions {
6
- /** Don't assign an alias to the column but instead return the column as is */
7
- noAlias?: boolean;
8
- }
9
- export declare function getColumnPreprocessor(knex: Knex, schema: SchemaOverview, table: string, cases: Filter[], aliasMap: AliasMap): (fieldNode: FieldNode | FunctionFieldNode | M2ONode, options?: NodePreProcessOptions) => Knex.Raw<string>;
10
- export {};
@@ -1,57 +0,0 @@
1
- import { joinFilterWithCases } from '../../../utils/apply-query.js';
2
- import { getColumn } from '../../../utils/get-column.js';
3
- import { parseFilterKey } from '../../../utils/parse-filter-key.js';
4
- import { getHelpers } from '../../helpers/index.js';
5
- import { applyCaseWhen } from './apply-case-when.js';
6
- import { getNodeAlias } from './get-field-alias.js';
7
- export function getColumnPreprocessor(knex, schema, table, cases, aliasMap) {
8
- const helpers = getHelpers(knex);
9
- return function (fieldNode, options) {
10
- // Don't assign an alias to the column expression if the field has a whenCase
11
- // (since the alias will be assigned in applyCaseWhen) or if the noAlias option is set
12
- const hasWhenCase = fieldNode.whenCase && fieldNode.whenCase.length > 0;
13
- const noAlias = options?.noAlias || hasWhenCase;
14
- const alias = getNodeAlias(fieldNode);
15
- const rawColumnAlias = noAlias ? false : alias;
16
- let field;
17
- if (fieldNode.type === 'field' || fieldNode.type === 'functionField') {
18
- const { fieldName } = parseFilterKey(fieldNode.name);
19
- field = schema.collections[table].fields[fieldName];
20
- }
21
- else {
22
- field = schema.collections[fieldNode.relation.collection].fields[fieldNode.relation.field];
23
- }
24
- let column;
25
- if (field?.type?.startsWith('geometry')) {
26
- column = helpers.st.asText(table, field.field, rawColumnAlias);
27
- }
28
- else if (fieldNode.type === 'functionField') {
29
- // Include the field cases in the functionField query filter
30
- column = getColumn(knex, table, fieldNode.name, rawColumnAlias, schema, {
31
- query: {
32
- ...fieldNode.query,
33
- filter: joinFilterWithCases(fieldNode.query.filter, fieldNode.cases),
34
- },
35
- cases: fieldNode.cases,
36
- });
37
- }
38
- else {
39
- column = getColumn(knex, table, fieldNode.name, rawColumnAlias, schema);
40
- }
41
- if (hasWhenCase) {
42
- const columnCases = [];
43
- for (const index of fieldNode.whenCase) {
44
- columnCases.push(cases[index]);
45
- }
46
- column = applyCaseWhen({
47
- column,
48
- columnCases,
49
- aliasMap,
50
- cases,
51
- table,
52
- alias,
53
- }, { knex, schema });
54
- }
55
- return column;
56
- };
57
- }
@@ -1,2 +0,0 @@
1
- import type { FieldNode, FunctionFieldNode, M2ONode, O2MNode } from '../../../types/index.js';
2
- export declare function getNodeAlias(node: FieldNode | FunctionFieldNode | M2ONode | O2MNode): string;
@@ -1,4 +0,0 @@
1
- import { applyFunctionToColumnName } from '../../../utils/apply-function-to-column-name.js';
2
- export function getNodeAlias(node) {
3
- return applyFunctionToColumnName(node.fieldKey);
4
- }
@@ -1,5 +0,0 @@
1
- import type { Filter, SchemaOverview } from '@directus/types';
2
- import type { Knex } from 'knex';
3
- import type { FieldNode, FunctionFieldNode, M2ONode, O2MNode } from '../../../types/index.js';
4
- import type { AliasMap } from '../../../utils/get-column-path.js';
5
- export declare function getInnerQueryColumnPreProcessor(knex: Knex, schema: SchemaOverview, table: string, cases: Filter[], aliasMap: AliasMap, aliasPrefix: string): (fieldNode: FieldNode | FunctionFieldNode | M2ONode | O2MNode) => Knex.Raw<string> | null;
@@ -1,23 +0,0 @@
1
- import { applyCaseWhen } from './apply-case-when.js';
2
- import { getNodeAlias } from './get-field-alias.js';
3
- export function getInnerQueryColumnPreProcessor(knex, schema, table, cases, aliasMap, aliasPrefix) {
4
- return function (fieldNode) {
5
- const alias = getNodeAlias(fieldNode);
6
- if (fieldNode.whenCase && fieldNode.whenCase.length > 0) {
7
- const columnCases = [];
8
- for (const index of fieldNode.whenCase) {
9
- columnCases.push(cases[index]);
10
- }
11
- // Don't pass in the alias as we need to wrap the whole case/when in a count() an alias that
12
- const caseWhen = applyCaseWhen({
13
- column: knex.raw(1),
14
- columnCases,
15
- aliasMap,
16
- cases,
17
- table,
18
- }, { knex, schema });
19
- return knex.raw('COUNT(??) AS ??', [caseWhen, `${aliasPrefix}_${alias}`]);
20
- }
21
- return null;
22
- };
23
- }
@@ -1,3 +0,0 @@
1
- import type { Item, SchemaOverview } from '@directus/types';
2
- import type { NestedCollectionNode } from '../../../types/ast.js';
3
- export declare function mergeWithParentItems(schema: SchemaOverview, nestedItem: Item | Item[], parentItem: Item | Item[], nestedNode: NestedCollectionNode, fieldAllowed: boolean | boolean[]): Item | Item[] | undefined;
@@ -1,87 +0,0 @@
1
- import { useEnv } from '@directus/env';
2
- import { toArray } from '@directus/utils';
3
- import { clone, isArray } from 'lodash-es';
4
- export function mergeWithParentItems(schema, nestedItem, parentItem, nestedNode, fieldAllowed) {
5
- const env = useEnv();
6
- const nestedItems = toArray(nestedItem);
7
- const parentItems = clone(toArray(parentItem));
8
- if (nestedNode.type === 'm2o') {
9
- for (const parentItem of parentItems) {
10
- const itemChild = nestedItems.find((nestedItem) => {
11
- return (nestedItem[schema.collections[nestedNode.relation.related_collection].primary] ==
12
- parentItem[nestedNode.relation.field]);
13
- });
14
- parentItem[nestedNode.fieldKey] = itemChild || null;
15
- }
16
- }
17
- else if (nestedNode.type === 'o2m') {
18
- for (const [index, parentItem] of parentItems.entries()) {
19
- if (fieldAllowed === false || (isArray(fieldAllowed) && !fieldAllowed[index])) {
20
- parentItem[nestedNode.fieldKey] = null;
21
- continue;
22
- }
23
- if (!parentItem[nestedNode.fieldKey])
24
- parentItem[nestedNode.fieldKey] = [];
25
- const itemChildren = nestedItems.filter((nestedItem) => {
26
- if (nestedItem === null)
27
- return false;
28
- if (Array.isArray(nestedItem[nestedNode.relation.field]))
29
- return true;
30
- return (nestedItem[nestedNode.relation.field] ==
31
- parentItem[schema.collections[nestedNode.relation.related_collection].primary] ||
32
- nestedItem[nestedNode.relation.field]?.[schema.collections[nestedNode.relation.related_collection].primary] == parentItem[schema.collections[nestedNode.relation.related_collection].primary]);
33
- });
34
- parentItem[nestedNode.fieldKey].push(...itemChildren);
35
- const limit = nestedNode.query.limit ?? Number(env['QUERY_LIMIT_DEFAULT']);
36
- if (nestedNode.query.page && nestedNode.query.page > 1) {
37
- parentItem[nestedNode.fieldKey] = parentItem[nestedNode.fieldKey].slice(limit * (nestedNode.query.page - 1));
38
- }
39
- if (nestedNode.query.offset && nestedNode.query.offset >= 0) {
40
- parentItem[nestedNode.fieldKey] = parentItem[nestedNode.fieldKey].slice(nestedNode.query.offset);
41
- }
42
- if (limit !== -1) {
43
- parentItem[nestedNode.fieldKey] = parentItem[nestedNode.fieldKey].slice(0, limit);
44
- }
45
- parentItem[nestedNode.fieldKey] = parentItem[nestedNode.fieldKey].sort((a, b) => {
46
- // This is pre-filled in get-ast-from-query
47
- const sortField = nestedNode.query.sort[0];
48
- let column = sortField;
49
- let order = 'asc';
50
- if (sortField.startsWith('-')) {
51
- column = sortField.substring(1);
52
- order = 'desc';
53
- }
54
- if (a[column] === b[column])
55
- return 0;
56
- if (a[column] === null)
57
- return 1;
58
- if (b[column] === null)
59
- return -1;
60
- if (order === 'asc') {
61
- return a[column] < b[column] ? -1 : 1;
62
- }
63
- else {
64
- return a[column] < b[column] ? 1 : -1;
65
- }
66
- });
67
- }
68
- }
69
- else if (nestedNode.type === 'a2o') {
70
- for (const parentItem of parentItems) {
71
- if (!nestedNode.relation.meta?.one_collection_field) {
72
- parentItem[nestedNode.fieldKey] = null;
73
- continue;
74
- }
75
- const relatedCollection = parentItem[nestedNode.relation.meta.one_collection_field];
76
- if (!nestedItem[relatedCollection]) {
77
- parentItem[nestedNode.fieldKey] = null;
78
- continue;
79
- }
80
- const itemChild = nestedItem[relatedCollection].find((nestedItem) => {
81
- return nestedItem[nestedNode.relatedKey[relatedCollection]] == parentItem[nestedNode.fieldKey];
82
- });
83
- parentItem[nestedNode.fieldKey] = itemChild || null;
84
- }
85
- }
86
- return Array.isArray(parentItem) ? parentItems : parentItems[0];
87
- }
@@ -1,3 +0,0 @@
1
- import type { Item, SchemaOverview } from '@directus/types';
2
- import type { AST, NestedCollectionNode } from '../../../types/ast.js';
3
- export declare function removeTemporaryFields(schema: SchemaOverview, rawItem: Item | Item[], ast: AST | NestedCollectionNode, primaryKeyField: string, parentItem?: Item): null | Item | Item[];
@@ -1,73 +0,0 @@
1
- import { toArray } from '@directus/utils';
2
- import { cloneDeep, pick } from 'lodash-es';
3
- import { applyFunctionToColumnName } from '../../../utils/apply-function-to-column-name.js';
4
- export function removeTemporaryFields(schema, rawItem, ast, primaryKeyField, parentItem) {
5
- const rawItems = cloneDeep(toArray(rawItem));
6
- const items = [];
7
- if (ast.type === 'a2o') {
8
- const fields = {};
9
- const nestedCollectionNodes = {};
10
- for (const relatedCollection of ast.names) {
11
- if (!fields[relatedCollection])
12
- fields[relatedCollection] = [];
13
- if (!nestedCollectionNodes[relatedCollection])
14
- nestedCollectionNodes[relatedCollection] = [];
15
- for (const child of ast.children[relatedCollection]) {
16
- if (child.type === 'field' || child.type === 'functionField') {
17
- fields[relatedCollection].push(child.name);
18
- }
19
- else {
20
- fields[relatedCollection].push(child.fieldKey);
21
- nestedCollectionNodes[relatedCollection].push(child);
22
- }
23
- }
24
- }
25
- for (const rawItem of rawItems) {
26
- const relatedCollection = parentItem?.[ast.relation.meta.one_collection_field];
27
- if (rawItem === null || rawItem === undefined)
28
- return rawItem;
29
- let item = rawItem;
30
- for (const nestedNode of nestedCollectionNodes[relatedCollection]) {
31
- item[nestedNode.fieldKey] = removeTemporaryFields(schema, item[nestedNode.fieldKey], nestedNode, schema.collections[nestedNode.relation.collection].primary, item);
32
- }
33
- const fieldsWithFunctionsApplied = fields[relatedCollection].map((field) => applyFunctionToColumnName(field));
34
- item =
35
- fields[relatedCollection].length > 0 ? pick(rawItem, fieldsWithFunctionsApplied) : rawItem[primaryKeyField];
36
- items.push(item);
37
- }
38
- }
39
- else {
40
- const fields = [];
41
- const nestedCollectionNodes = [];
42
- for (const child of ast.children) {
43
- fields.push(child.fieldKey);
44
- if (child.type !== 'field' && child.type !== 'functionField') {
45
- nestedCollectionNodes.push(child);
46
- }
47
- }
48
- // Make sure any requested aggregate fields are included
49
- if (ast.query?.aggregate) {
50
- for (const [operation, aggregateFields] of Object.entries(ast.query.aggregate)) {
51
- if (!fields)
52
- continue;
53
- if (operation === 'count' && aggregateFields.includes('*'))
54
- fields.push('count');
55
- fields.push(...aggregateFields.map((field) => `${operation}.${field}`));
56
- }
57
- }
58
- for (const rawItem of rawItems) {
59
- if (rawItem === null || rawItem === undefined)
60
- return rawItem;
61
- let item = rawItem;
62
- for (const nestedNode of nestedCollectionNodes) {
63
- item[nestedNode.fieldKey] = removeTemporaryFields(schema, item[nestedNode.fieldKey], nestedNode, nestedNode.type === 'm2o'
64
- ? schema.collections[nestedNode.relation.related_collection].primary
65
- : schema.collections[nestedNode.relation.collection].primary, item);
66
- }
67
- const fieldsWithFunctionsApplied = fields.map((field) => applyFunctionToColumnName(field));
68
- item = fields.length > 0 ? pick(rawItem, fieldsWithFunctionsApplied) : rawItem[primaryKeyField];
69
- items.push(item);
70
- }
71
- }
72
- return Array.isArray(rawItem) ? items : items[0];
73
- }
@@ -1,2 +0,0 @@
1
- export declare const useCache: () => import("@directus/memory").Cache;
2
- export declare function clearCache(): Promise<void>;
@@ -1,23 +0,0 @@
1
- import { defineCache } from '@directus/memory';
2
- import { redisConfigAvailable, useRedis } from '../redis/index.js';
3
- const localOnly = redisConfigAvailable() === false;
4
- const config = localOnly
5
- ? {
6
- type: 'local',
7
- maxKeys: 500,
8
- }
9
- : {
10
- type: 'multi',
11
- redis: {
12
- namespace: 'permissions',
13
- redis: useRedis(),
14
- },
15
- local: {
16
- maxKeys: 100,
17
- },
18
- };
19
- export const useCache = defineCache(config);
20
- export function clearCache() {
21
- const cache = useCache();
22
- return cache.clear();
23
- }
@@ -1,10 +0,0 @@
1
- import type { Accountability, Permission, PermissionsAction } from '@directus/types';
2
- import type { Context } from '../types.js';
3
- export declare const fetchPermissions: typeof _fetchPermissions;
4
- export interface FetchPermissionsOptions {
5
- action?: PermissionsAction;
6
- policies: string[];
7
- collections?: string[];
8
- accountability?: Pick<Accountability, 'user' | 'role' | 'roles' | 'app'>;
9
- }
10
- export declare function _fetchPermissions(options: FetchPermissionsOptions, context: Context): Promise<Permission[]>;
@@ -1,55 +0,0 @@
1
- import { pick, sortBy } from 'lodash-es';
2
- import { fetchDynamicVariableContext } from '../utils/fetch-dynamic-variable-context.js';
3
- import { processPermissions } from '../utils/process-permissions.js';
4
- import { withCache } from '../utils/with-cache.js';
5
- import { withAppMinimalPermissions } from './with-app-minimal-permissions.js';
6
- export const fetchPermissions = withCache('permissions', _fetchPermissions, ({ action, policies, collections, accountability }) => ({
7
- policies, // we assume that policies always come from the same source, so they should be in the same order
8
- ...(action && { action }),
9
- ...(collections && { collections: sortBy(collections) }),
10
- ...(accountability && { accountability: pick(accountability, ['user', 'role', 'roles', 'app']) }),
11
- }));
12
- export async function _fetchPermissions(options, context) {
13
- const { PermissionsService } = await import('../../services/permissions.js');
14
- const permissionsService = new PermissionsService(context);
15
- const filter = {
16
- _and: [{ policy: { _in: options.policies } }],
17
- };
18
- if (options.action) {
19
- filter._and.push({ action: { _eq: options.action } });
20
- }
21
- if (options.collections) {
22
- filter._and.push({ collection: { _in: options.collections } });
23
- }
24
- let permissions = (await permissionsService.readByQuery({
25
- filter,
26
- limit: -1,
27
- }));
28
- // Sort permissions by their order in the policies array
29
- // This ensures that if a sorted array of policies is passed in the permissions are returned in the same order
30
- // which is necessary for correctly applying the presets in order
31
- permissions = sortBy(permissions, (permission) => options.policies.indexOf(permission.policy));
32
- if (options.accountability) {
33
- // Add app minimal permissions for the request accountability, if applicable.
34
- // Normally this is done in the permissions service readByQuery, but it also needs to do it here
35
- // since the permissions service is created without accountability.
36
- // We call it without the policies filter, since the static minimal app permissions don't have a policy attached.
37
- const permissionsWithAppPermissions = withAppMinimalPermissions(options.accountability ?? null, permissions, {
38
- _and: filter._and.slice(1),
39
- });
40
- const permissionsContext = await fetchDynamicVariableContext({
41
- accountability: options.accountability,
42
- policies: options.policies,
43
- permissions: permissionsWithAppPermissions,
44
- }, context);
45
- // Replace dynamic variables with their actual values
46
- const processedPermissions = processPermissions({
47
- permissions: permissionsWithAppPermissions,
48
- accountability: options.accountability,
49
- permissionsContext,
50
- });
51
- // TODO merge in permissions coming from the share scope
52
- return processedPermissions;
53
- }
54
- return permissions;
55
- }
@@ -1,7 +0,0 @@
1
- import type { Accountability } from '@directus/types';
2
- import type { Context } from '../types.js';
3
- export declare const fetchPolicies: typeof _fetchPolicies;
4
- /**
5
- * Fetch the policies associated with the current user accountability
6
- */
7
- export declare function _fetchPolicies({ roles, user, ip }: Pick<Accountability, 'user' | 'roles' | 'ip'>, context: Context): Promise<string[]>;
@@ -1,28 +0,0 @@
1
- import { filterPoliciesByIp } from '../utils/filter-policies-by-ip.js';
2
- import { withCache } from '../utils/with-cache.js';
3
- export const fetchPolicies = withCache('policies', _fetchPolicies, ({ roles, user, ip }) => ({ roles, user, ip }));
4
- /**
5
- * Fetch the policies associated with the current user accountability
6
- */
7
- export async function _fetchPolicies({ roles, user, ip }, context) {
8
- const { AccessService } = await import('../../services/access.js');
9
- const accessService = new AccessService(context);
10
- let roleFilter;
11
- if (roles.length === 0) {
12
- // Users without role assumes the Public role permissions along with their attached policies
13
- roleFilter = { role: { _null: true }, user: { _null: true } };
14
- }
15
- else {
16
- roleFilter = { role: { _in: roles } };
17
- }
18
- // If the user is not null, we also want to include the policies attached to the user
19
- const filter = user ? { _or: [{ user: { _eq: user } }, roleFilter] } : roleFilter;
20
- const accessRows = (await accessService.readByQuery({
21
- filter,
22
- fields: ['policy.id', 'policy.ip_access'],
23
- limit: -1,
24
- }));
25
- const filteredAccessRows = filterPoliciesByIp(accessRows, ip);
26
- const ids = filteredAccessRows.map(({ policy }) => policy.id);
27
- return ids;
28
- }
@@ -1,3 +0,0 @@
1
- import type { Knex } from 'knex';
2
- export declare const fetchRolesTree: typeof _fetchRolesTree;
3
- export declare function _fetchRolesTree(start: string | null, knex: Knex): Promise<string[]>;
@@ -1,28 +0,0 @@
1
- import { withCache } from '../utils/with-cache.js';
2
- export const fetchRolesTree = withCache('roles-tree', _fetchRolesTree);
3
- export async function _fetchRolesTree(start, knex) {
4
- if (!start)
5
- return [];
6
- let parent = start;
7
- const roles = [];
8
- while (parent) {
9
- const role = await knex
10
- .select('id', 'parent')
11
- .from('directus_roles')
12
- .where({ id: parent })
13
- .first();
14
- if (!role) {
15
- break;
16
- }
17
- roles.push(role.id);
18
- // Prevent infinite recursion loops
19
- if (role.parent && roles.includes(role.parent) === true) {
20
- roles.reverse();
21
- const rolesStr = roles.map((role) => `"${role}"`).join('->');
22
- throw new Error(`Recursion encountered: role "${role.id}" already exists in tree path ${rolesStr}`);
23
- }
24
- parent = role.parent;
25
- }
26
- roles.reverse();
27
- return roles;
28
- }
@@ -1,10 +0,0 @@
1
- import { appAccessMinimalPermissions } from '@directus/system-data';
2
- import { cloneDeep } from 'lodash-es';
3
- import { filterItems } from '../../utils/filter-items.js';
4
- export function withAppMinimalPermissions(accountability, permissions, filter) {
5
- if (accountability?.app === true) {
6
- const filteredAppMinimalPermissions = cloneDeep(filterItems(appAccessMinimalPermissions, filter));
7
- return [...permissions, ...filteredAppMinimalPermissions];
8
- }
9
- return permissions;
10
- }
@@ -1,7 +0,0 @@
1
- import type { Accountability, CollectionAccess } from '@directus/types';
2
- import type { Context } from '../../types.js';
3
- /**
4
- * Get all permissions + minimal app permissions (if applicable) for the user + role in the current accountability.
5
- * The permissions will be filtered by IP access.
6
- */
7
- export declare function fetchAccountabilityCollectionAccess(accountability: Pick<Accountability, 'user' | 'roles' | 'role' | 'ip' | 'admin' | 'app'>, context: Context): Promise<CollectionAccess>;
@@ -1,56 +0,0 @@
1
- import { PERMISSION_ACTIONS } from '@directus/constants';
2
- import { mapValues, uniq } from 'lodash-es';
3
- import { fetchPermissions } from '../../lib/fetch-permissions.js';
4
- import { fetchPolicies } from '../../lib/fetch-policies.js';
5
- /**
6
- * Get all permissions + minimal app permissions (if applicable) for the user + role in the current accountability.
7
- * The permissions will be filtered by IP access.
8
- */
9
- export async function fetchAccountabilityCollectionAccess(accountability, context) {
10
- if (accountability.admin) {
11
- return mapValues(context.schema.collections, () => Object.fromEntries(PERMISSION_ACTIONS.map((action) => [
12
- action,
13
- {
14
- access: 'full',
15
- fields: ['*'],
16
- },
17
- ])));
18
- }
19
- const policies = await fetchPolicies(accountability, context);
20
- const permissions = await fetchPermissions({ policies, accountability }, context);
21
- const infos = {};
22
- for (const perm of permissions) {
23
- // Ensure that collection is in infos
24
- if (!infos[perm.collection]) {
25
- infos[perm.collection] = {
26
- read: { access: 'none' },
27
- create: { access: 'none' },
28
- update: { access: 'none' },
29
- delete: { access: 'none' },
30
- share: { access: 'none' },
31
- };
32
- }
33
- // Ensure that action with default values is in collection infos
34
- if (infos[perm.collection][perm.action]?.access === 'none') {
35
- // If a permissions is iterated over it means that the user has access to it, so set access to 'full'
36
- // Set access to 'full' initially and refine that whenever a permission with filters is encountered
37
- infos[perm.collection][perm.action].access = 'full';
38
- }
39
- const info = infos[perm.collection][perm.action];
40
- // Set access to 'partial' if the permission has filters, which means that the user has conditional access
41
- if (info.access === 'full' && perm.permissions && Object.keys(perm.permissions).length > 0) {
42
- info.access = 'partial';
43
- }
44
- if (perm.fields && info.fields?.[0] !== '*') {
45
- info.fields = uniq([...(info.fields || []), ...(perm.fields || [])]);
46
- if (info.fields.includes('*')) {
47
- info.fields = ['*'];
48
- }
49
- }
50
- if (perm.presets) {
51
- info.presets = { ...(info.presets ?? {}), ...perm.presets };
52
- }
53
- }
54
- // TODO Should fields by null, undefined or and empty array if no access?
55
- return infos;
56
- }
@@ -1,3 +0,0 @@
1
- import type { Accountability, Globals } from '@directus/types';
2
- import type { Context } from '../../types.js';
3
- export declare function fetchAccountabilityPolicyGlobals(accountability: Pick<Accountability, 'user' | 'roles' | 'ip' | 'admin' | 'app'>, context: Context): Promise<Globals>;
@@ -1,16 +0,0 @@
1
- import { fetchPolicies } from '../../lib/fetch-policies.js';
2
- export async function fetchAccountabilityPolicyGlobals(accountability, context) {
3
- const policies = await fetchPolicies(accountability, context);
4
- // Policies are already filtered down by the accountability IP, so we don't need to check it again
5
- const result = await context.knex
6
- .select(1)
7
- .from('directus_policies')
8
- .whereIn('id', policies)
9
- .where('enforce_tfa', true)
10
- .first();
11
- return {
12
- app_access: accountability.app,
13
- admin_access: accountability.admin,
14
- enforce_tfa: !!result,
15
- };
16
- }
@@ -1,8 +0,0 @@
1
- import type { Accountability, PermissionsAction } from '@directus/types';
2
- import type { Context } from '../../types.js';
3
- export interface FetchAllowedCollectionsOptions {
4
- action: PermissionsAction;
5
- accountability: Pick<Accountability, 'user' | 'role' | 'roles' | 'ip' | 'admin' | 'app'>;
6
- }
7
- export declare const fetchAllowedCollections: typeof _fetchAllowedCollections;
8
- export declare function _fetchAllowedCollections({ action, accountability }: FetchAllowedCollectionsOptions, { knex, schema }: Context): Promise<string[]>;
@@ -1,24 +0,0 @@
1
- import { uniq } from 'lodash-es';
2
- import { fetchPolicies } from '../../lib/fetch-policies.js';
3
- import { withCache } from '../../utils/with-cache.js';
4
- import { fetchPermissions } from '../../lib/fetch-permissions.js';
5
- export const fetchAllowedCollections = withCache('allowed-collections', _fetchAllowedCollections, ({ action, accountability: { user, role, roles, ip, admin, app } }) => ({
6
- action,
7
- accountability: {
8
- user,
9
- role,
10
- roles,
11
- ip,
12
- admin,
13
- app,
14
- },
15
- }));
16
- export async function _fetchAllowedCollections({ action, accountability }, { knex, schema }) {
17
- if (accountability.admin) {
18
- return Object.keys(schema.collections);
19
- }
20
- const policies = await fetchPolicies(accountability, { knex, schema });
21
- const permissions = await fetchPermissions({ action, policies, accountability }, { knex, schema });
22
- const collections = permissions.map(({ collection }) => collection);
23
- return uniq(collections);
24
- }
@@ -1,9 +0,0 @@
1
- import type { Accountability, PermissionsAction } from '@directus/types';
2
- import type { Context } from '../../types.js';
3
- export type FieldMap = Record<string, string[]>;
4
- export interface FetchAllowedFieldMapOptions {
5
- accountability: Pick<Accountability, 'user' | 'role' | 'roles' | 'ip' | 'admin' | 'app'>;
6
- action: PermissionsAction;
7
- }
8
- export declare const fetchAllowedFieldMap: typeof _fetchAllowedFieldMap;
9
- export declare function _fetchAllowedFieldMap({ accountability, action }: FetchAllowedFieldMapOptions, { knex, schema }: Context): Promise<FieldMap>;
@@ -1,31 +0,0 @@
1
- import { uniq } from 'lodash-es';
2
- import { fetchPolicies } from '../../lib/fetch-policies.js';
3
- import { withCache } from '../../utils/with-cache.js';
4
- import { fetchPermissions } from '../../lib/fetch-permissions.js';
5
- export const fetchAllowedFieldMap = withCache('allowed-field-map', _fetchAllowedFieldMap, ({ action, accountability: { user, role, roles, ip, admin, app } }) => ({
6
- action,
7
- accountability: { user, role, roles, ip, admin, app },
8
- }));
9
- export async function _fetchAllowedFieldMap({ accountability, action }, { knex, schema }) {
10
- const fieldMap = {};
11
- if (accountability.admin) {
12
- for (const [collection, { fields }] of Object.entries(schema.collections)) {
13
- fieldMap[collection] = Object.keys(fields);
14
- }
15
- return fieldMap;
16
- }
17
- const policies = await fetchPolicies(accountability, { knex, schema });
18
- const permissions = await fetchPermissions({ action, policies, accountability }, { knex, schema });
19
- for (const { collection, fields } of permissions) {
20
- if (!fieldMap[collection]) {
21
- fieldMap[collection] = [];
22
- }
23
- if (fields) {
24
- fieldMap[collection].push(...fields);
25
- }
26
- }
27
- for (const [collection, fields] of Object.entries(fieldMap)) {
28
- fieldMap[collection] = uniq(fields);
29
- }
30
- return fieldMap;
31
- }
@@ -1,16 +0,0 @@
1
- import type { Accountability, PermissionsAction } from '@directus/types';
2
- import type { Context } from '../../types.js';
3
- export interface FetchAllowedFieldsOptions {
4
- collection: string;
5
- action: PermissionsAction;
6
- accountability: Pick<Accountability, 'user' | 'role' | 'roles' | 'ip' | 'app'>;
7
- }
8
- export declare const fetchAllowedFields: typeof _fetchAllowedFields;
9
- /**
10
- * Look up all fields that are allowed to be used for the given collection and action for the given
11
- * accountability object
12
- *
13
- * Done by looking up all available policies for the current accountability object, and reading all
14
- * permissions that exist for the collection+action+policy combination
15
- */
16
- export declare function _fetchAllowedFields({ accountability, action, collection }: FetchAllowedFieldsOptions, { knex, schema }: Context): Promise<string[]>;