@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.
- package/dist/app.js +9 -4
- package/dist/auth/drivers/ldap.js +4 -4
- package/dist/auth/drivers/local.js +4 -4
- package/dist/auth/drivers/oauth2.js +4 -4
- package/dist/auth/drivers/openid.js +4 -2
- package/dist/cache.js +0 -3
- package/dist/cli/commands/bootstrap/index.js +2 -8
- package/dist/cli/commands/init/index.js +10 -9
- package/dist/cli/utils/defaults.d.ts +11 -4
- package/dist/cli/utils/defaults.js +1 -7
- package/dist/constants.d.ts +9 -1
- package/dist/constants.js +10 -0
- package/dist/controllers/auth.js +16 -5
- package/dist/controllers/permissions.js +2 -14
- package/dist/controllers/roles.js +1 -22
- package/dist/controllers/{access.d.ts → tus.d.ts} +1 -0
- package/dist/controllers/tus.js +72 -0
- package/dist/controllers/users.js +55 -0
- package/dist/database/helpers/fn/types.d.ts +1 -2
- package/dist/database/helpers/fn/types.js +1 -1
- package/dist/database/helpers/geometry/dialects/mssql.d.ts +1 -1
- package/dist/database/helpers/geometry/dialects/mssql.js +2 -4
- package/dist/database/helpers/geometry/dialects/mysql.js +1 -1
- package/dist/database/helpers/geometry/dialects/oracle.d.ts +1 -1
- package/dist/database/helpers/geometry/dialects/oracle.js +3 -5
- package/dist/database/helpers/geometry/types.d.ts +1 -1
- package/dist/database/helpers/geometry/types.js +2 -4
- package/dist/database/index.js +1 -2
- package/dist/database/migrations/20240701A-add-tus-data.js +12 -0
- package/dist/database/{run-ast/types.d.ts → run-ast.d.ts} +9 -3
- package/dist/database/run-ast.js +450 -0
- package/dist/flows.js +4 -3
- package/dist/middleware/authenticate.js +7 -2
- package/dist/middleware/cache.js +1 -1
- package/dist/middleware/check-ip.d.ts +2 -0
- package/dist/middleware/check-ip.js +37 -0
- package/dist/middleware/get-permissions.d.ts +3 -0
- package/dist/middleware/get-permissions.js +10 -0
- package/dist/middleware/respond.js +1 -1
- package/dist/services/activity.js +10 -22
- package/dist/services/assets.d.ts +3 -2
- package/dist/services/assets.js +5 -10
- package/dist/services/authentication.js +26 -32
- package/dist/services/authorization.d.ts +17 -0
- package/dist/services/authorization.js +456 -0
- package/dist/services/collections.js +17 -18
- package/dist/services/fields.d.ts +1 -0
- package/dist/services/fields.js +24 -53
- package/dist/services/files/lib/extract-metadata.d.ts +3 -0
- package/dist/services/files/lib/extract-metadata.js +32 -0
- package/dist/services/files/utils/get-metadata.d.ts +5 -0
- package/dist/services/files/utils/get-metadata.js +107 -0
- package/dist/services/files.d.ts +4 -6
- package/dist/services/files.js +24 -140
- package/dist/services/graphql/index.d.ts +3 -3
- package/dist/services/graphql/index.js +22 -126
- package/dist/services/graphql/subscription.js +4 -2
- package/dist/services/import-export.js +4 -18
- package/dist/services/index.d.ts +2 -3
- package/dist/services/index.js +2 -3
- package/dist/services/items.js +44 -115
- package/dist/services/meta.js +23 -60
- package/dist/services/payload.d.ts +10 -9
- package/dist/services/payload.js +3 -18
- package/dist/services/{permissions.d.ts → permissions/index.d.ts} +7 -5
- package/dist/services/{permissions.js → permissions/index.js} +54 -30
- package/dist/{permissions → services/permissions}/lib/with-app-minimal-permissions.d.ts +1 -1
- package/dist/services/permissions/lib/with-app-minimal-permissions.js +13 -0
- package/dist/services/relations.d.ts +6 -0
- package/dist/services/relations.js +29 -26
- package/dist/services/roles.d.ts +12 -4
- package/dist/services/roles.js +424 -57
- package/dist/services/server.js +6 -0
- package/dist/services/shares.d.ts +2 -0
- package/dist/services/shares.js +8 -12
- package/dist/services/specifications.d.ts +2 -2
- package/dist/services/specifications.js +27 -39
- package/dist/services/tus/data-store.d.ts +36 -0
- package/dist/services/tus/data-store.js +214 -0
- package/dist/services/tus/index.d.ts +2 -0
- package/dist/services/tus/index.js +2 -0
- package/dist/services/tus/lockers.d.ts +36 -0
- package/dist/services/tus/lockers.js +83 -0
- package/dist/services/tus/server.d.ts +8 -0
- package/dist/services/tus/server.js +80 -0
- package/dist/services/tus/utils/wait-timeout.d.ts +1 -0
- package/dist/services/tus/utils/wait-timeout.js +13 -0
- package/dist/services/users.d.ts +5 -1
- package/dist/services/users.js +161 -78
- package/dist/services/utils.js +7 -11
- package/dist/services/versions.d.ts +2 -0
- package/dist/services/versions.js +10 -34
- package/dist/storage/register-locations.js +5 -1
- package/dist/telemetry/lib/get-report.js +2 -2
- package/dist/telemetry/utils/check-increased-user-limits.d.ts +7 -0
- package/dist/telemetry/utils/check-increased-user-limits.js +25 -0
- package/dist/telemetry/utils/get-role-counts-by-roles.d.ts +6 -0
- package/dist/telemetry/utils/get-role-counts-by-roles.js +27 -0
- package/dist/telemetry/utils/get-role-counts-by-users.d.ts +11 -0
- package/dist/telemetry/utils/get-role-counts-by-users.js +34 -0
- package/dist/telemetry/utils/get-user-count.d.ts +8 -0
- package/dist/telemetry/utils/get-user-count.js +33 -0
- package/dist/telemetry/utils/get-user-counts-by-roles.d.ts +7 -0
- package/dist/telemetry/utils/get-user-counts-by-roles.js +35 -0
- package/dist/types/ast.d.ts +1 -43
- package/dist/types/items.d.ts +0 -11
- package/dist/utils/apply-query.d.ts +3 -4
- package/dist/utils/apply-query.js +8 -37
- package/dist/utils/get-accountability-for-role.js +25 -16
- package/dist/utils/get-accountability-for-token.js +16 -17
- package/dist/utils/get-ast-from-query.d.ts +13 -0
- package/dist/utils/get-ast-from-query.js +297 -0
- package/dist/utils/get-cache-key.d.ts +1 -1
- package/dist/utils/get-cache-key.js +1 -12
- package/dist/utils/get-column.d.ts +1 -2
- package/dist/utils/get-column.js +0 -1
- package/dist/utils/get-permissions.d.ts +2 -0
- package/dist/utils/get-permissions.js +150 -0
- package/dist/utils/get-service.js +1 -5
- package/dist/utils/merge-permissions-for-share.d.ts +4 -0
- package/dist/utils/merge-permissions-for-share.js +109 -0
- package/dist/utils/merge-permissions.d.ts +3 -0
- package/dist/utils/merge-permissions.js +95 -0
- package/dist/utils/reduce-schema.d.ts +6 -4
- package/dist/utils/reduce-schema.js +34 -14
- package/dist/utils/verify-session-jwt.js +2 -1
- package/dist/websocket/authenticate.d.ts +2 -0
- package/dist/websocket/authenticate.js +12 -0
- package/dist/websocket/controllers/graphql.js +4 -1
- package/dist/websocket/controllers/hooks.js +0 -4
- package/dist/websocket/controllers/rest.js +2 -0
- package/dist/websocket/handlers/subscribe.js +2 -0
- package/dist/websocket/utils/items.d.ts +1 -1
- package/package.json +35 -33
- package/dist/controllers/access.js +0 -148
- package/dist/controllers/policies.d.ts +0 -2
- package/dist/controllers/policies.js +0 -169
- package/dist/database/get-ast-from-query/get-ast-from-query.d.ts +0 -16
- package/dist/database/get-ast-from-query/get-ast-from-query.js +0 -82
- package/dist/database/get-ast-from-query/lib/convert-wildcards.d.ts +0 -13
- package/dist/database/get-ast-from-query/lib/convert-wildcards.js +0 -69
- package/dist/database/get-ast-from-query/lib/parse-fields.d.ts +0 -15
- package/dist/database/get-ast-from-query/lib/parse-fields.js +0 -190
- package/dist/database/get-ast-from-query/utils/get-deep-query.d.ts +0 -14
- package/dist/database/get-ast-from-query/utils/get-deep-query.js +0 -17
- package/dist/database/get-ast-from-query/utils/get-related-collection.d.ts +0 -2
- package/dist/database/get-ast-from-query/utils/get-related-collection.js +0 -13
- package/dist/database/get-ast-from-query/utils/get-relation.d.ts +0 -2
- package/dist/database/get-ast-from-query/utils/get-relation.js +0 -7
- package/dist/database/migrations/20240619A-permissions-policies.js +0 -163
- package/dist/database/run-ast/lib/get-db-query.d.ts +0 -4
- package/dist/database/run-ast/lib/get-db-query.js +0 -194
- package/dist/database/run-ast/lib/parse-current-level.d.ts +0 -7
- package/dist/database/run-ast/lib/parse-current-level.js +0 -41
- package/dist/database/run-ast/run-ast.d.ts +0 -7
- package/dist/database/run-ast/run-ast.js +0 -107
- package/dist/database/run-ast/types.js +0 -1
- package/dist/database/run-ast/utils/apply-case-when.d.ts +0 -16
- package/dist/database/run-ast/utils/apply-case-when.js +0 -26
- package/dist/database/run-ast/utils/apply-parent-filters.d.ts +0 -3
- package/dist/database/run-ast/utils/apply-parent-filters.js +0 -55
- package/dist/database/run-ast/utils/get-column-pre-processor.d.ts +0 -10
- package/dist/database/run-ast/utils/get-column-pre-processor.js +0 -57
- package/dist/database/run-ast/utils/get-field-alias.d.ts +0 -2
- package/dist/database/run-ast/utils/get-field-alias.js +0 -4
- package/dist/database/run-ast/utils/get-inner-query-column-pre-processor.d.ts +0 -5
- package/dist/database/run-ast/utils/get-inner-query-column-pre-processor.js +0 -23
- package/dist/database/run-ast/utils/merge-with-parent-items.d.ts +0 -3
- package/dist/database/run-ast/utils/merge-with-parent-items.js +0 -87
- package/dist/database/run-ast/utils/remove-temporary-fields.d.ts +0 -3
- package/dist/database/run-ast/utils/remove-temporary-fields.js +0 -73
- package/dist/permissions/cache.d.ts +0 -2
- package/dist/permissions/cache.js +0 -23
- package/dist/permissions/lib/fetch-permissions.d.ts +0 -10
- package/dist/permissions/lib/fetch-permissions.js +0 -55
- package/dist/permissions/lib/fetch-policies.d.ts +0 -7
- package/dist/permissions/lib/fetch-policies.js +0 -28
- package/dist/permissions/lib/fetch-roles-tree.d.ts +0 -3
- package/dist/permissions/lib/fetch-roles-tree.js +0 -28
- package/dist/permissions/lib/with-app-minimal-permissions.js +0 -10
- package/dist/permissions/modules/fetch-accountability-collection-access/fetch-accountability-collection-access.d.ts +0 -7
- package/dist/permissions/modules/fetch-accountability-collection-access/fetch-accountability-collection-access.js +0 -56
- package/dist/permissions/modules/fetch-accountability-policy-globals/fetch-accountability-policy-globals.d.ts +0 -3
- package/dist/permissions/modules/fetch-accountability-policy-globals/fetch-accountability-policy-globals.js +0 -16
- package/dist/permissions/modules/fetch-allowed-collections/fetch-allowed-collections.d.ts +0 -8
- package/dist/permissions/modules/fetch-allowed-collections/fetch-allowed-collections.js +0 -24
- package/dist/permissions/modules/fetch-allowed-field-map/fetch-allowed-field-map.d.ts +0 -9
- package/dist/permissions/modules/fetch-allowed-field-map/fetch-allowed-field-map.js +0 -31
- package/dist/permissions/modules/fetch-allowed-fields/fetch-allowed-fields.d.ts +0 -16
- package/dist/permissions/modules/fetch-allowed-fields/fetch-allowed-fields.js +0 -27
- package/dist/permissions/modules/fetch-global-access/fetch-global-access.d.ts +0 -10
- package/dist/permissions/modules/fetch-global-access/fetch-global-access.js +0 -23
- package/dist/permissions/modules/fetch-global-access/lib/fetch-global-access-for-roles.d.ts +0 -5
- package/dist/permissions/modules/fetch-global-access/lib/fetch-global-access-for-roles.js +0 -7
- package/dist/permissions/modules/fetch-global-access/lib/fetch-global-access-for-user.d.ts +0 -5
- package/dist/permissions/modules/fetch-global-access/lib/fetch-global-access-for-user.js +0 -10
- package/dist/permissions/modules/fetch-global-access/types.d.ts +0 -4
- package/dist/permissions/modules/fetch-global-access/types.js +0 -1
- package/dist/permissions/modules/fetch-global-access/utils/fetch-global-access-for-query.d.ts +0 -4
- package/dist/permissions/modules/fetch-global-access/utils/fetch-global-access-for-query.js +0 -27
- package/dist/permissions/modules/fetch-inconsistent-field-map/fetch-inconsistent-field-map.d.ts +0 -12
- package/dist/permissions/modules/fetch-inconsistent-field-map/fetch-inconsistent-field-map.js +0 -32
- package/dist/permissions/modules/fetch-policies-ip-access/fetch-policies-ip-access.d.ts +0 -4
- package/dist/permissions/modules/fetch-policies-ip-access/fetch-policies-ip-access.js +0 -29
- package/dist/permissions/modules/process-ast/lib/extract-fields-from-children.d.ts +0 -4
- package/dist/permissions/modules/process-ast/lib/extract-fields-from-children.js +0 -49
- package/dist/permissions/modules/process-ast/lib/extract-fields-from-query.d.ts +0 -3
- package/dist/permissions/modules/process-ast/lib/extract-fields-from-query.js +0 -56
- package/dist/permissions/modules/process-ast/lib/field-map-from-ast.d.ts +0 -4
- package/dist/permissions/modules/process-ast/lib/field-map-from-ast.js +0 -8
- package/dist/permissions/modules/process-ast/lib/inject-cases.d.ts +0 -9
- package/dist/permissions/modules/process-ast/lib/inject-cases.js +0 -93
- package/dist/permissions/modules/process-ast/process-ast.d.ts +0 -9
- package/dist/permissions/modules/process-ast/process-ast.js +0 -39
- package/dist/permissions/modules/process-ast/types.d.ts +0 -24
- package/dist/permissions/modules/process-ast/types.js +0 -1
- package/dist/permissions/modules/process-ast/utils/collections-in-field-map.d.ts +0 -2
- package/dist/permissions/modules/process-ast/utils/collections-in-field-map.js +0 -7
- package/dist/permissions/modules/process-ast/utils/dedupe-access.d.ts +0 -12
- package/dist/permissions/modules/process-ast/utils/dedupe-access.js +0 -30
- package/dist/permissions/modules/process-ast/utils/extract-paths-from-query.d.ts +0 -15
- package/dist/permissions/modules/process-ast/utils/extract-paths-from-query.js +0 -50
- package/dist/permissions/modules/process-ast/utils/find-related-collection.d.ts +0 -3
- package/dist/permissions/modules/process-ast/utils/find-related-collection.js +0 -9
- package/dist/permissions/modules/process-ast/utils/flatten-filter.d.ts +0 -3
- package/dist/permissions/modules/process-ast/utils/flatten-filter.js +0 -24
- package/dist/permissions/modules/process-ast/utils/format-a2o-key.d.ts +0 -1
- package/dist/permissions/modules/process-ast/utils/format-a2o-key.js +0 -3
- package/dist/permissions/modules/process-ast/utils/get-info-for-path.d.ts +0 -5
- package/dist/permissions/modules/process-ast/utils/get-info-for-path.js +0 -7
- package/dist/permissions/modules/process-ast/utils/has-item-permissions.d.ts +0 -2
- package/dist/permissions/modules/process-ast/utils/has-item-permissions.js +0 -3
- package/dist/permissions/modules/process-ast/utils/stringify-query-path.d.ts +0 -2
- package/dist/permissions/modules/process-ast/utils/stringify-query-path.js +0 -3
- package/dist/permissions/modules/process-ast/utils/validate-path/create-error.d.ts +0 -3
- package/dist/permissions/modules/process-ast/utils/validate-path/create-error.js +0 -16
- package/dist/permissions/modules/process-ast/utils/validate-path/validate-path-existence.d.ts +0 -2
- package/dist/permissions/modules/process-ast/utils/validate-path/validate-path-existence.js +0 -12
- package/dist/permissions/modules/process-ast/utils/validate-path/validate-path-permissions.d.ts +0 -2
- package/dist/permissions/modules/process-ast/utils/validate-path/validate-path-permissions.js +0 -28
- package/dist/permissions/modules/process-payload/lib/is-field-nullable.d.ts +0 -5
- package/dist/permissions/modules/process-payload/lib/is-field-nullable.js +0 -12
- package/dist/permissions/modules/process-payload/process-payload.d.ts +0 -13
- package/dist/permissions/modules/process-payload/process-payload.js +0 -77
- package/dist/permissions/modules/validate-access/lib/validate-collection-access.d.ts +0 -12
- package/dist/permissions/modules/validate-access/lib/validate-collection-access.js +0 -11
- package/dist/permissions/modules/validate-access/lib/validate-item-access.d.ts +0 -9
- package/dist/permissions/modules/validate-access/lib/validate-item-access.js +0 -33
- package/dist/permissions/modules/validate-access/validate-access.d.ts +0 -14
- package/dist/permissions/modules/validate-access/validate-access.js +0 -28
- package/dist/permissions/modules/validate-remaining-admin/validate-remaining-admin-count.d.ts +0 -1
- package/dist/permissions/modules/validate-remaining-admin/validate-remaining-admin-count.js +0 -8
- package/dist/permissions/modules/validate-remaining-admin/validate-remaining-admin-users.d.ts +0 -5
- package/dist/permissions/modules/validate-remaining-admin/validate-remaining-admin-users.js +0 -10
- package/dist/permissions/types.d.ts +0 -6
- package/dist/permissions/types.js +0 -1
- package/dist/permissions/utils/create-default-accountability.d.ts +0 -2
- package/dist/permissions/utils/create-default-accountability.js +0 -11
- package/dist/permissions/utils/extract-required-dynamic-variable-context.d.ts +0 -8
- package/dist/permissions/utils/extract-required-dynamic-variable-context.js +0 -27
- package/dist/permissions/utils/fetch-dynamic-variable-context.d.ts +0 -9
- package/dist/permissions/utils/fetch-dynamic-variable-context.js +0 -43
- package/dist/permissions/utils/filter-policies-by-ip.d.ts +0 -2
- package/dist/permissions/utils/filter-policies-by-ip.js +0 -15
- package/dist/permissions/utils/get-unaliased-field-key.d.ts +0 -5
- package/dist/permissions/utils/get-unaliased-field-key.js +0 -17
- package/dist/permissions/utils/process-permissions.d.ts +0 -7
- package/dist/permissions/utils/process-permissions.js +0 -9
- package/dist/permissions/utils/with-cache.d.ts +0 -10
- package/dist/permissions/utils/with-cache.js +0 -25
- package/dist/services/access.d.ts +0 -10
- package/dist/services/access.js +0 -43
- package/dist/services/policies.d.ts +0 -12
- package/dist/services/policies.js +0 -87
- package/dist/telemetry/utils/check-user-limits.d.ts +0 -5
- package/dist/telemetry/utils/check-user-limits.js +0 -19
- package/dist/utils/fetch-user-count/fetch-access-lookup.d.ts +0 -17
- package/dist/utils/fetch-user-count/fetch-access-lookup.js +0 -22
- package/dist/utils/fetch-user-count/fetch-access-roles.d.ts +0 -16
- package/dist/utils/fetch-user-count/fetch-access-roles.js +0 -37
- package/dist/utils/fetch-user-count/fetch-active-users.d.ts +0 -6
- package/dist/utils/fetch-user-count/fetch-active-users.js +0 -3
- package/dist/utils/fetch-user-count/fetch-user-count.d.ts +0 -12
- package/dist/utils/fetch-user-count/fetch-user-count.js +0 -57
- package/dist/utils/fetch-user-count/get-user-count-query.d.ts +0 -20
- package/dist/utils/fetch-user-count/get-user-count-query.js +0 -17
- package/dist/utils/validate-user-count-integrity.d.ts +0 -13
- package/dist/utils/validate-user-count-integrity.js +0 -29
- /package/dist/database/migrations/{20240619A-permissions-policies.d.ts → 20240701A-add-tus-data.d.ts} +0 -0
- /package/dist/{utils → services/files/utils}/parse-image-metadata.d.ts +0 -0
- /package/dist/{utils → services/files/utils}/parse-image-metadata.js +0 -0
|
@@ -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
|
+
}
|
package/dist/types/ast.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
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
|
};
|
package/dist/types/items.d.ts
CHANGED
|
@@ -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,
|
|
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
|
|
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,
|
|
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
|
-
|
|
41
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
314
|
+
applyQuery(knex, relation.collection, subQueryKnex, { filter }, schema);
|
|
332
315
|
};
|
|
333
316
|
const childKey = Object.keys(value)?.[0];
|
|
334
317
|
if (childKey === '_none') {
|
|
@@ -568,7 +551,7 @@ export function applyFilter(knex, schema, rootQuery, rootFilter, collection, ali
|
|
|
568
551
|
}
|
|
569
552
|
}
|
|
570
553
|
}
|
|
571
|
-
export function applySearch(knex, schema, dbQuery, searchQuery, collection) {
|
|
554
|
+
export async function applySearch(knex, schema, dbQuery, searchQuery, collection) {
|
|
572
555
|
const { number: numberHelper } = getHelpers(knex);
|
|
573
556
|
const fields = Object.entries(schema.collections[collection].fields);
|
|
574
557
|
dbQuery.andWhere(function () {
|
|
@@ -644,18 +627,6 @@ export function applyAggregate(schema, dbQuery, aggregate, collection, hasJoins)
|
|
|
644
627
|
}
|
|
645
628
|
}
|
|
646
629
|
}
|
|
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
630
|
function getFilterPath(key, value) {
|
|
660
631
|
const path = [key];
|
|
661
632
|
const childKey = Object.keys(value)[0];
|
|
@@ -1,31 +1,40 @@
|
|
|
1
|
-
import {
|
|
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 =
|
|
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 =
|
|
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
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
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
|
-
|
|
23
|
-
generatedAccountability = createDefaultAccountability({
|
|
31
|
+
generatedAccountability = {
|
|
24
32
|
role,
|
|
25
|
-
roles,
|
|
26
33
|
user: null,
|
|
27
|
-
|
|
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
|
}
|
|
@@ -1,40 +1,41 @@
|
|
|
1
1
|
import { InvalidCredentialsError } from '@directus/errors';
|
|
2
2
|
import getDatabase from '../database/index.js';
|
|
3
|
-
import { fetchRolesTree } from '../permissions/lib/fetch-roles-tree.js';
|
|
4
|
-
import { fetchGlobalAccess } from '../permissions/modules/fetch-global-access/fetch-global-access.js';
|
|
5
|
-
import { createDefaultAccountability } from '../permissions/utils/create-default-accountability.js';
|
|
6
3
|
import { getSecret } from './get-secret.js';
|
|
7
4
|
import isDirectusJWT from './is-directus-jwt.js';
|
|
8
|
-
import { verifyAccessJWT } from './jwt.js';
|
|
9
5
|
import { verifySessionJWT } from './verify-session-jwt.js';
|
|
6
|
+
import { verifyAccessJWT } from './jwt.js';
|
|
10
7
|
export async function getAccountabilityForToken(token, accountability) {
|
|
11
8
|
if (!accountability) {
|
|
12
|
-
accountability =
|
|
9
|
+
accountability = {
|
|
10
|
+
user: null,
|
|
11
|
+
role: null,
|
|
12
|
+
admin: false,
|
|
13
|
+
app: false,
|
|
14
|
+
};
|
|
13
15
|
}
|
|
14
|
-
// Try finding the user with the provided token
|
|
15
|
-
const database = getDatabase();
|
|
16
16
|
if (token) {
|
|
17
17
|
if (isDirectusJWT(token)) {
|
|
18
18
|
const payload = verifyAccessJWT(token, getSecret());
|
|
19
19
|
if ('session' in payload) {
|
|
20
20
|
await verifySessionJWT(payload);
|
|
21
21
|
}
|
|
22
|
+
accountability.role = payload.role;
|
|
23
|
+
accountability.admin = payload.admin_access === true || payload.admin_access == 1;
|
|
24
|
+
accountability.app = payload.app_access === true || payload.app_access == 1;
|
|
22
25
|
if (payload.share)
|
|
23
26
|
accountability.share = payload.share;
|
|
24
27
|
if (payload.share_scope)
|
|
25
28
|
accountability.share_scope = payload.share_scope;
|
|
26
29
|
if (payload.id)
|
|
27
30
|
accountability.user = payload.id;
|
|
28
|
-
accountability.role = payload.role;
|
|
29
|
-
accountability.roles = await fetchRolesTree(payload.role, database);
|
|
30
|
-
const { admin, app } = await fetchGlobalAccess(accountability, database);
|
|
31
|
-
accountability.admin = admin;
|
|
32
|
-
accountability.app = app;
|
|
33
31
|
}
|
|
34
32
|
else {
|
|
33
|
+
// Try finding the user with the provided token
|
|
34
|
+
const database = getDatabase();
|
|
35
35
|
const user = await database
|
|
36
|
-
.select('directus_users.id', 'directus_users.role')
|
|
36
|
+
.select('directus_users.id', 'directus_users.role', 'directus_roles.admin_access', 'directus_roles.app_access')
|
|
37
37
|
.from('directus_users')
|
|
38
|
+
.leftJoin('directus_roles', 'directus_users.role', 'directus_roles.id')
|
|
38
39
|
.where({
|
|
39
40
|
'directus_users.token': token,
|
|
40
41
|
status: 'active',
|
|
@@ -45,10 +46,8 @@ export async function getAccountabilityForToken(token, accountability) {
|
|
|
45
46
|
}
|
|
46
47
|
accountability.user = user.id;
|
|
47
48
|
accountability.role = user.role;
|
|
48
|
-
accountability.
|
|
49
|
-
|
|
50
|
-
accountability.admin = admin;
|
|
51
|
-
accountability.app = app;
|
|
49
|
+
accountability.admin = user.admin_access === true || user.admin_access == 1;
|
|
50
|
+
accountability.app = user.app_access === true || user.app_access == 1;
|
|
52
51
|
}
|
|
53
52
|
}
|
|
54
53
|
return accountability;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generate an AST based on a given collection and query
|
|
3
|
+
*/
|
|
4
|
+
import type { Accountability, PermissionsAction, Query, SchemaOverview } from '@directus/types';
|
|
5
|
+
import type { Knex } from 'knex';
|
|
6
|
+
import type { AST } from '../types/index.js';
|
|
7
|
+
type GetASTOptions = {
|
|
8
|
+
accountability?: Accountability | null;
|
|
9
|
+
action?: PermissionsAction;
|
|
10
|
+
knex?: Knex;
|
|
11
|
+
};
|
|
12
|
+
export default function getASTFromQuery(collection: string, query: Query, schema: SchemaOverview, options?: GetASTOptions): Promise<AST>;
|
|
13
|
+
export {};
|