@directus/api 21.0.0-rc.0 → 21.0.1
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 +5 -5
- 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.d.ts +2 -3
- package/dist/cache.js +9 -27
- 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 +1 -1
- package/dist/controllers/auth.js +16 -5
- package/dist/controllers/permissions.js +2 -14
- package/dist/controllers/roles.js +1 -22
- package/dist/controllers/tus.js +27 -13
- 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 +11 -8
- package/dist/database/migrations/20240305A-change-useragent-type.js +1 -1
- package/dist/database/migrations/20240716A-update-files-date-fields.js +33 -0
- package/dist/database/{run-ast/types.d.ts → run-ast.d.ts} +9 -3
- package/dist/database/run-ast.js +458 -0
- package/dist/flows.js +4 -3
- package/dist/logger/index.js +1 -1
- 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/error-handler.d.ts +2 -2
- package/dist/middleware/error-handler.js +54 -51
- package/dist/middleware/get-permissions.d.ts +3 -0
- package/dist/middleware/get-permissions.js +10 -0
- package/dist/middleware/respond.js +2 -1
- package/dist/request/is-denied-ip.js +7 -1
- package/dist/services/activity.js +10 -22
- package/dist/services/assets.d.ts +3 -2
- package/dist/services/assets.js +7 -15
- package/dist/services/authentication.js +18 -18
- 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 +4 -0
- package/dist/services/fields.js +53 -58
- package/dist/services/files/lib/get-sharp-instance.d.ts +2 -0
- package/dist/services/files/lib/get-sharp-instance.js +10 -0
- package/dist/services/files/utils/get-metadata.js +7 -6
- package/dist/services/files.js +8 -10
- 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/mail/index.d.ts +1 -1
- package/dist/services/mail/index.js +9 -1
- package/dist/services/meta.js +23 -60
- package/dist/services/notifications.js +6 -14
- 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 +9 -1
- package/dist/services/relations.js +56 -31
- package/dist/services/roles.d.ts +12 -4
- package/dist/services/roles.js +424 -57
- 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.js +4 -5
- package/dist/services/tus/server.d.ts +1 -1
- package/dist/services/tus/server.js +9 -2
- 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/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 +16 -39
- 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-schema.js +22 -27
- 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 +32 -16
- 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 -36
- package/dist/controllers/access.d.ts +0 -2
- 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/20240710A-permissions-policies.js +0 -169
- package/dist/database/run-ast/lib/get-db-query.d.ts +0 -4
- package/dist/database/run-ast/lib/get-db-query.js +0 -208
- 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 -34
- 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/{20240710A-permissions-policies.d.ts → 20240716A-update-files-date-fields.d.ts} +0 -0
package/dist/utils/get-schema.js
CHANGED
|
@@ -4,7 +4,7 @@ import { systemCollectionRows } from '@directus/system-data';
|
|
|
4
4
|
import { parseJSON, toArray } from '@directus/utils';
|
|
5
5
|
import { mapValues } from 'lodash-es';
|
|
6
6
|
import { useBus } from '../bus/index.js';
|
|
7
|
-
import {
|
|
7
|
+
import { getLocalSchemaCache, setLocalSchemaCache } from '../cache.js';
|
|
8
8
|
import { ALIAS_TYPES } from '../constants.js';
|
|
9
9
|
import getDatabase from '../database/index.js';
|
|
10
10
|
import { useLock } from '../lock/index.js';
|
|
@@ -17,18 +17,18 @@ const logger = useLogger();
|
|
|
17
17
|
export async function getSchema(options, attempt = 0) {
|
|
18
18
|
const MAX_ATTEMPTS = 3;
|
|
19
19
|
const env = useEnv();
|
|
20
|
-
if (attempt >= MAX_ATTEMPTS) {
|
|
21
|
-
throw new Error(`Failed to get Schema information: hit infinite loop`);
|
|
22
|
-
}
|
|
23
20
|
if (options?.bypassCache || env['CACHE_SCHEMA'] === false) {
|
|
24
21
|
const database = options?.database || getDatabase();
|
|
25
22
|
const schemaInspector = createInspector(database);
|
|
26
23
|
return await getDatabaseSchema(database, schemaInspector);
|
|
27
24
|
}
|
|
28
|
-
const cached = await
|
|
25
|
+
const cached = await getLocalSchemaCache();
|
|
29
26
|
if (cached) {
|
|
30
27
|
return cached;
|
|
31
28
|
}
|
|
29
|
+
if (attempt >= MAX_ATTEMPTS) {
|
|
30
|
+
throw new Error(`Failed to get Schema information: hit infinite loop`);
|
|
31
|
+
}
|
|
32
32
|
const lock = useLock();
|
|
33
33
|
const bus = useBus();
|
|
34
34
|
const lockKey = 'schemaCache--preparing';
|
|
@@ -40,39 +40,34 @@ export async function getSchema(options, attempt = 0) {
|
|
|
40
40
|
const currentProcessShouldHandleOperation = processId === 1;
|
|
41
41
|
if (currentProcessShouldHandleOperation === false) {
|
|
42
42
|
logger.trace('Schema cache is prepared in another process, waiting for result.');
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
bus.subscribe(messageKey, callback);
|
|
50
|
-
async function callback() {
|
|
51
|
-
try {
|
|
52
|
-
if (timeout)
|
|
53
|
-
clearTimeout(timeout);
|
|
54
|
-
const schema = await getSchema(options, attempt + 1);
|
|
55
|
-
resolve(schema);
|
|
56
|
-
}
|
|
57
|
-
catch (error) {
|
|
58
|
-
reject(error);
|
|
59
|
-
}
|
|
60
|
-
finally {
|
|
61
|
-
bus.unsubscribe(messageKey, callback);
|
|
43
|
+
const timeout = new Promise((_, reject) => setTimeout(reject, env['CACHE_SCHEMA_SYNC_TIMEOUT']));
|
|
44
|
+
const subscription = new Promise((resolve, reject) => {
|
|
45
|
+
bus.subscribe(messageKey, busListener).catch(reject);
|
|
46
|
+
function busListener(options) {
|
|
47
|
+
if (options.schema === null) {
|
|
48
|
+
return reject();
|
|
62
49
|
}
|
|
50
|
+
cleanup();
|
|
51
|
+
setLocalSchemaCache(options.schema).catch(reject);
|
|
52
|
+
resolve(options.schema);
|
|
53
|
+
}
|
|
54
|
+
function cleanup() {
|
|
55
|
+
bus.unsubscribe(messageKey, busListener).catch(reject);
|
|
63
56
|
}
|
|
64
57
|
});
|
|
58
|
+
return Promise.race([timeout, subscription]).catch(() => getSchema(options, attempt + 1));
|
|
65
59
|
}
|
|
60
|
+
let schema = null;
|
|
66
61
|
try {
|
|
67
62
|
const database = options?.database || getDatabase();
|
|
68
63
|
const schemaInspector = createInspector(database);
|
|
69
|
-
|
|
70
|
-
await
|
|
64
|
+
schema = await getDatabaseSchema(database, schemaInspector);
|
|
65
|
+
await setLocalSchemaCache(schema);
|
|
71
66
|
return schema;
|
|
72
67
|
}
|
|
73
68
|
finally {
|
|
69
|
+
await bus.publish(messageKey, { schema });
|
|
74
70
|
await lock.delete(lockKey);
|
|
75
|
-
bus.publish(messageKey, { ready: true });
|
|
76
71
|
}
|
|
77
72
|
}
|
|
78
73
|
async function getDatabaseSchema(database, schemaInspector) {
|
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
import { ForbiddenError } from '@directus/errors';
|
|
2
|
-
import {
|
|
2
|
+
import { ActivityService, DashboardsService, FilesService, FlowsService, FoldersService, ItemsService, NotificationsService, OperationsService, PanelsService, PermissionsService, PresetsService, RevisionsService, RolesService, SettingsService, SharesService, TranslationsService, UsersService, VersionsService, WebhooksService, } from '../services/index.js';
|
|
3
3
|
/**
|
|
4
4
|
* Select the correct service for the given collection. This allows the individual services to run
|
|
5
5
|
* their custom checks (f.e. it allows `UsersService` to prevent updating TFA secret from outside).
|
|
6
6
|
*/
|
|
7
7
|
export function getService(collection, opts) {
|
|
8
8
|
switch (collection) {
|
|
9
|
-
case 'directus_access':
|
|
10
|
-
return new AccessService(opts);
|
|
11
9
|
case 'directus_activity':
|
|
12
10
|
return new ActivityService(opts);
|
|
13
11
|
case 'directus_dashboards':
|
|
@@ -28,8 +26,6 @@ export function getService(collection, opts) {
|
|
|
28
26
|
return new PermissionsService(opts);
|
|
29
27
|
case 'directus_presets':
|
|
30
28
|
return new PresetsService(opts);
|
|
31
|
-
case 'directus_policies':
|
|
32
|
-
return new PoliciesService(opts);
|
|
33
29
|
case 'directus_revisions':
|
|
34
30
|
return new RevisionsService(opts);
|
|
35
31
|
case 'directus_roles':
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { Accountability, Filter, Permission, SchemaOverview } from '@directus/types';
|
|
2
|
+
export declare function mergePermissionsForShare(currentPermissions: Permission[], accountability: Accountability, schema: SchemaOverview): Permission[];
|
|
3
|
+
export declare function traverse(schema: SchemaOverview, rootItemPrimaryKeyField: string, rootItemPrimaryKey: string, currentCollection: string, parentCollections?: string[], path?: string[]): Partial<Permission>[];
|
|
4
|
+
export declare function getFilterForPath(type: 'o2m' | 'm2o' | 'a2o', path: string[], rootPrimaryKeyField: string, rootPrimaryKey: string): Filter;
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { assign, set, uniq } from 'lodash-es';
|
|
2
|
+
import { schemaPermissions } from '@directus/system-data';
|
|
3
|
+
import { mergePermissions } from './merge-permissions.js';
|
|
4
|
+
import { reduceSchema } from './reduce-schema.js';
|
|
5
|
+
export function mergePermissionsForShare(currentPermissions, accountability, schema) {
|
|
6
|
+
const defaults = {
|
|
7
|
+
action: 'read',
|
|
8
|
+
role: accountability.role,
|
|
9
|
+
collection: '',
|
|
10
|
+
permissions: {},
|
|
11
|
+
validation: null,
|
|
12
|
+
presets: null,
|
|
13
|
+
fields: null,
|
|
14
|
+
};
|
|
15
|
+
const { collection, item } = accountability.share_scope;
|
|
16
|
+
const parentPrimaryKeyField = schema.collections[collection].primary;
|
|
17
|
+
const reducedSchema = reduceSchema(schema, currentPermissions, ['read']);
|
|
18
|
+
const relationalPermissions = traverse(reducedSchema, parentPrimaryKeyField, item, collection);
|
|
19
|
+
const parentCollectionPermission = assign({}, defaults, {
|
|
20
|
+
collection,
|
|
21
|
+
permissions: {
|
|
22
|
+
[parentPrimaryKeyField]: {
|
|
23
|
+
_eq: item,
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
});
|
|
27
|
+
// All permissions that will be merged into the original permissions set
|
|
28
|
+
const allGeneratedPermissions = [
|
|
29
|
+
parentCollectionPermission,
|
|
30
|
+
...relationalPermissions.map((generated) => assign({}, defaults, generated)),
|
|
31
|
+
...schemaPermissions,
|
|
32
|
+
];
|
|
33
|
+
// All the collections that are touched through the relational tree from the current root collection, and the schema collections
|
|
34
|
+
const allowedCollections = uniq(allGeneratedPermissions.map(({ collection }) => collection));
|
|
35
|
+
const generatedPermissions = [];
|
|
36
|
+
// Merge all the permissions that relate to the same collection with an _or (this allows you to properly retrieve)
|
|
37
|
+
// the items of a collection if you entered that collection from multiple angles
|
|
38
|
+
for (const collection of allowedCollections) {
|
|
39
|
+
const permissionsForCollection = allGeneratedPermissions.filter((permission) => permission.collection === collection);
|
|
40
|
+
if (permissionsForCollection.length > 0) {
|
|
41
|
+
generatedPermissions.push(...mergePermissions('or', permissionsForCollection));
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
generatedPermissions.push(...permissionsForCollection);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
// Explicitly filter out permissions to collections unrelated to the root parent item.
|
|
48
|
+
const limitedPermissions = currentPermissions.filter(({ action, collection }) => allowedCollections.includes(collection) && action === 'read');
|
|
49
|
+
return mergePermissions('and', limitedPermissions, generatedPermissions);
|
|
50
|
+
}
|
|
51
|
+
export function traverse(schema, rootItemPrimaryKeyField, rootItemPrimaryKey, currentCollection, parentCollections = [], path = []) {
|
|
52
|
+
const permissions = [];
|
|
53
|
+
// If there's already a permissions rule for the collection we're currently checking, we'll shortcircuit.
|
|
54
|
+
// This prevents infinite loop in recursive relationships, like articles->related_articles->articles, or
|
|
55
|
+
// articles.author->users.avatar->files.created_by->users.avatar->files.created_by->🔁
|
|
56
|
+
if (parentCollections.includes(currentCollection)) {
|
|
57
|
+
return permissions;
|
|
58
|
+
}
|
|
59
|
+
const relationsInCollection = schema.relations.filter((relation) => {
|
|
60
|
+
return relation.collection === currentCollection || relation.related_collection === currentCollection;
|
|
61
|
+
});
|
|
62
|
+
for (const relation of relationsInCollection) {
|
|
63
|
+
let type;
|
|
64
|
+
if (relation.related_collection === currentCollection) {
|
|
65
|
+
type = 'o2m';
|
|
66
|
+
}
|
|
67
|
+
else if (!relation.related_collection) {
|
|
68
|
+
type = 'a2o';
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
type = 'm2o';
|
|
72
|
+
}
|
|
73
|
+
if (type === 'o2m') {
|
|
74
|
+
permissions.push({
|
|
75
|
+
collection: relation.collection,
|
|
76
|
+
permissions: getFilterForPath(type, [...path, relation.field], rootItemPrimaryKeyField, rootItemPrimaryKey),
|
|
77
|
+
});
|
|
78
|
+
permissions.push(...traverse(schema, rootItemPrimaryKeyField, rootItemPrimaryKey, relation.collection, [...parentCollections, currentCollection], [...path, relation.field]));
|
|
79
|
+
}
|
|
80
|
+
if (type === 'a2o' && relation.meta?.one_allowed_collections) {
|
|
81
|
+
for (const collection of relation.meta.one_allowed_collections) {
|
|
82
|
+
permissions.push({
|
|
83
|
+
collection,
|
|
84
|
+
permissions: getFilterForPath(type, [...path, `$FOLLOW(${relation.collection},${relation.field},${relation.meta.one_collection_field})`], rootItemPrimaryKeyField, rootItemPrimaryKey),
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
if (type === 'm2o') {
|
|
89
|
+
permissions.push({
|
|
90
|
+
collection: relation.related_collection,
|
|
91
|
+
permissions: getFilterForPath(type, [...path, `$FOLLOW(${relation.collection},${relation.field})`], rootItemPrimaryKeyField, rootItemPrimaryKey),
|
|
92
|
+
});
|
|
93
|
+
if (relation.meta?.one_field) {
|
|
94
|
+
permissions.push(...traverse(schema, rootItemPrimaryKeyField, rootItemPrimaryKey, relation.related_collection, [...parentCollections, currentCollection], [...path, relation.meta?.one_field]));
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
return permissions;
|
|
99
|
+
}
|
|
100
|
+
export function getFilterForPath(type, path, rootPrimaryKeyField, rootPrimaryKey) {
|
|
101
|
+
const filter = {};
|
|
102
|
+
if (type === 'm2o' || type === 'a2o') {
|
|
103
|
+
set(filter, path.reverse(), { [rootPrimaryKeyField]: { _eq: rootPrimaryKey } });
|
|
104
|
+
}
|
|
105
|
+
else {
|
|
106
|
+
set(filter, path.reverse(), { _eq: rootPrimaryKey });
|
|
107
|
+
}
|
|
108
|
+
return filter;
|
|
109
|
+
}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { Permission } from '@directus/types';
|
|
2
|
+
export declare function mergePermissions(strategy: 'and' | 'or', ...permissions: Permission[][]): Permission[];
|
|
3
|
+
export declare function mergePermission(strategy: 'and' | 'or', currentPerm: Permission, newPerm: Permission): Omit<Permission, 'id' | 'system'>;
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { flatten, intersection, isEqual, merge, omit } from 'lodash-es';
|
|
2
|
+
export function mergePermissions(strategy, ...permissions) {
|
|
3
|
+
const allPermissions = flatten(permissions);
|
|
4
|
+
const mergedPermissions = allPermissions
|
|
5
|
+
.reduce((acc, val) => {
|
|
6
|
+
const key = `${val.collection}__${val.action}__${val.role || '$PUBLIC'}`;
|
|
7
|
+
const current = acc.get(key);
|
|
8
|
+
acc.set(key, current ? mergePermission(strategy, current, val) : val);
|
|
9
|
+
return acc;
|
|
10
|
+
}, new Map())
|
|
11
|
+
.values();
|
|
12
|
+
return Array.from(mergedPermissions);
|
|
13
|
+
}
|
|
14
|
+
export function mergePermission(strategy, currentPerm, newPerm) {
|
|
15
|
+
const logicalKey = `_${strategy}`;
|
|
16
|
+
let permissions = currentPerm.permissions;
|
|
17
|
+
let validation = currentPerm.validation;
|
|
18
|
+
let fields = currentPerm.fields;
|
|
19
|
+
let presets = currentPerm.presets;
|
|
20
|
+
if (newPerm.permissions) {
|
|
21
|
+
if (currentPerm.permissions && Object.keys(currentPerm.permissions)[0] === logicalKey) {
|
|
22
|
+
permissions = {
|
|
23
|
+
[logicalKey]: [
|
|
24
|
+
...currentPerm.permissions[logicalKey],
|
|
25
|
+
newPerm.permissions,
|
|
26
|
+
],
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
else if (currentPerm.permissions) {
|
|
30
|
+
// Empty {} supersedes other permissions in _OR merge
|
|
31
|
+
if (strategy === 'or' && (isEqual(currentPerm.permissions, {}) || isEqual(newPerm.permissions, {}))) {
|
|
32
|
+
permissions = {};
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
permissions = {
|
|
36
|
+
[logicalKey]: [currentPerm.permissions, newPerm.permissions],
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
permissions = {
|
|
42
|
+
[logicalKey]: [newPerm.permissions],
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
if (newPerm.validation) {
|
|
47
|
+
if (currentPerm.validation && Object.keys(currentPerm.validation)[0] === logicalKey) {
|
|
48
|
+
validation = {
|
|
49
|
+
[logicalKey]: [
|
|
50
|
+
...currentPerm.validation[logicalKey],
|
|
51
|
+
newPerm.validation,
|
|
52
|
+
],
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
else if (currentPerm.validation) {
|
|
56
|
+
// Empty {} supersedes other validations in _OR merge
|
|
57
|
+
if (strategy === 'or' && (isEqual(currentPerm.validation, {}) || isEqual(newPerm.validation, {}))) {
|
|
58
|
+
validation = {};
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
validation = {
|
|
62
|
+
[logicalKey]: [currentPerm.validation, newPerm.validation],
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
validation = {
|
|
68
|
+
[logicalKey]: [newPerm.validation],
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
if (newPerm.fields) {
|
|
73
|
+
if (Array.isArray(currentPerm.fields) && strategy === 'or') {
|
|
74
|
+
fields = [...new Set([...currentPerm.fields, ...newPerm.fields])];
|
|
75
|
+
}
|
|
76
|
+
else if (Array.isArray(currentPerm.fields) && strategy === 'and') {
|
|
77
|
+
fields = intersection(currentPerm.fields, newPerm.fields);
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
fields = newPerm.fields;
|
|
81
|
+
}
|
|
82
|
+
if (fields.includes('*'))
|
|
83
|
+
fields = ['*'];
|
|
84
|
+
}
|
|
85
|
+
if (newPerm.presets) {
|
|
86
|
+
presets = merge({}, presets, newPerm.presets);
|
|
87
|
+
}
|
|
88
|
+
return omit({
|
|
89
|
+
...currentPerm,
|
|
90
|
+
permissions,
|
|
91
|
+
validation,
|
|
92
|
+
fields,
|
|
93
|
+
presets,
|
|
94
|
+
}, ['id', 'system']);
|
|
95
|
+
}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
import type { SchemaOverview } from '@directus/types';
|
|
2
|
-
import type { FieldMap } from '../permissions/modules/fetch-allowed-field-map/fetch-allowed-field-map.js';
|
|
1
|
+
import type { Permission, PermissionsAction, SchemaOverview } from '@directus/types';
|
|
3
2
|
/**
|
|
4
3
|
* Reduces the schema based on the included permissions. The resulting object is the schema structure, but with only
|
|
5
|
-
* the allowed collections/fields/relations included based on the
|
|
4
|
+
* the allowed collections/fields/relations included based on the permissions.
|
|
5
|
+
* @param schema The full project schema
|
|
6
|
+
* @param actions Array of permissions actions (crud)
|
|
7
|
+
* @returns Reduced schema
|
|
6
8
|
*/
|
|
7
|
-
export declare function reduceSchema(schema: SchemaOverview,
|
|
9
|
+
export declare function reduceSchema(schema: SchemaOverview, permissions: Permission[] | null, actions?: PermissionsAction[]): SchemaOverview;
|
|
@@ -1,24 +1,40 @@
|
|
|
1
|
+
import { uniq } from 'lodash-es';
|
|
1
2
|
/**
|
|
2
3
|
* Reduces the schema based on the included permissions. The resulting object is the schema structure, but with only
|
|
3
|
-
* the allowed collections/fields/relations included based on the
|
|
4
|
+
* the allowed collections/fields/relations included based on the permissions.
|
|
5
|
+
* @param schema The full project schema
|
|
6
|
+
* @param actions Array of permissions actions (crud)
|
|
7
|
+
* @returns Reduced schema
|
|
4
8
|
*/
|
|
5
|
-
export function reduceSchema(schema,
|
|
9
|
+
export function reduceSchema(schema, permissions, actions = ['create', 'read', 'update', 'delete']) {
|
|
6
10
|
const reduced = {
|
|
7
11
|
collections: {},
|
|
8
12
|
relations: [],
|
|
9
13
|
};
|
|
14
|
+
const allowedFieldsInCollection = permissions
|
|
15
|
+
?.filter((permission) => actions.includes(permission.action))
|
|
16
|
+
.reduce((acc, permission) => {
|
|
17
|
+
if (!acc[permission.collection]) {
|
|
18
|
+
acc[permission.collection] = [];
|
|
19
|
+
}
|
|
20
|
+
if (permission.fields) {
|
|
21
|
+
acc[permission.collection] = uniq([...acc[permission.collection], ...permission.fields]);
|
|
22
|
+
}
|
|
23
|
+
return acc;
|
|
24
|
+
}, {}) ?? {};
|
|
10
25
|
for (const [collectionName, collection] of Object.entries(schema.collections)) {
|
|
11
|
-
if (!
|
|
12
|
-
// Collection is not allowed at all
|
|
26
|
+
if (!permissions?.some((permission) => permission.collection === collectionName && actions.includes(permission.action))) {
|
|
13
27
|
continue;
|
|
14
28
|
}
|
|
15
29
|
const fields = {};
|
|
16
30
|
for (const [fieldName, field] of Object.entries(schema.collections[collectionName].fields)) {
|
|
17
|
-
if (!
|
|
31
|
+
if (!allowedFieldsInCollection[collectionName]?.includes('*') &&
|
|
32
|
+
!allowedFieldsInCollection[collectionName]?.includes(fieldName)) {
|
|
18
33
|
continue;
|
|
19
34
|
}
|
|
20
35
|
const o2mRelation = schema.relations.find((relation) => relation.related_collection === collectionName && relation.meta?.one_field === fieldName);
|
|
21
|
-
if (o2mRelation &&
|
|
36
|
+
if (o2mRelation &&
|
|
37
|
+
!permissions?.some((permission) => permission.collection === o2mRelation.collection && actions.includes(permission.action))) {
|
|
22
38
|
continue;
|
|
23
39
|
}
|
|
24
40
|
fields[fieldName] = field;
|
|
@@ -31,29 +47,29 @@ export function reduceSchema(schema, fieldMap) {
|
|
|
31
47
|
reduced.relations = schema.relations.filter((relation) => {
|
|
32
48
|
let collectionsAllowed = true;
|
|
33
49
|
let fieldsAllowed = true;
|
|
34
|
-
if (Object.keys(
|
|
50
|
+
if (Object.keys(allowedFieldsInCollection).includes(relation.collection) === false) {
|
|
35
51
|
collectionsAllowed = false;
|
|
36
52
|
}
|
|
37
53
|
if (relation.related_collection &&
|
|
38
|
-
(Object.keys(
|
|
54
|
+
(Object.keys(allowedFieldsInCollection).includes(relation.related_collection) === false ||
|
|
39
55
|
// Ignore legacy permissions with an empty fields array
|
|
40
|
-
|
|
56
|
+
allowedFieldsInCollection[relation.related_collection]?.length === 0)) {
|
|
41
57
|
collectionsAllowed = false;
|
|
42
58
|
}
|
|
43
59
|
if (relation.meta?.one_allowed_collections &&
|
|
44
|
-
relation.meta.one_allowed_collections.every((collection) => Object.keys(
|
|
60
|
+
relation.meta.one_allowed_collections.every((collection) => Object.keys(allowedFieldsInCollection).includes(collection)) === false) {
|
|
45
61
|
collectionsAllowed = false;
|
|
46
62
|
}
|
|
47
|
-
if (!
|
|
48
|
-
(
|
|
49
|
-
|
|
63
|
+
if (!allowedFieldsInCollection[relation.collection] ||
|
|
64
|
+
(allowedFieldsInCollection[relation.collection]?.includes('*') === false &&
|
|
65
|
+
allowedFieldsInCollection[relation.collection]?.includes(relation.field) === false)) {
|
|
50
66
|
fieldsAllowed = false;
|
|
51
67
|
}
|
|
52
68
|
if (relation.related_collection &&
|
|
53
69
|
relation.meta?.one_field &&
|
|
54
|
-
(!
|
|
55
|
-
(
|
|
56
|
-
|
|
70
|
+
(!allowedFieldsInCollection[relation.related_collection] ||
|
|
71
|
+
(allowedFieldsInCollection[relation.related_collection]?.includes('*') === false &&
|
|
72
|
+
allowedFieldsInCollection[relation.related_collection]?.includes(relation.meta?.one_field) === false))) {
|
|
57
73
|
fieldsAllowed = false;
|
|
58
74
|
}
|
|
59
75
|
return collectionsAllowed && fieldsAllowed;
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
+
import type { Accountability } from '@directus/types';
|
|
1
2
|
import type { BasicAuthMessage } from './messages.js';
|
|
2
3
|
import type { AuthenticationState } from './types.js';
|
|
3
4
|
export declare function authenticateConnection(message: BasicAuthMessage & Record<string, any>): Promise<AuthenticationState>;
|
|
5
|
+
export declare function refreshAccountability(accountability: Accountability | null | undefined): Promise<Accountability>;
|
|
4
6
|
export declare function authenticationSuccess(uid?: string | number, refresh_token?: string): string;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { DEFAULT_AUTH_PROVIDER } from '../constants.js';
|
|
2
2
|
import { AuthenticationService } from '../services/index.js';
|
|
3
3
|
import { getAccountabilityForToken } from '../utils/get-accountability-for-token.js';
|
|
4
|
+
import { getPermissions } from '../utils/get-permissions.js';
|
|
4
5
|
import { getSchema } from '../utils/get-schema.js';
|
|
5
6
|
import { WebSocketError } from './errors.js';
|
|
6
7
|
import { getExpiresAtForToken } from './utils/get-expires-at-for-token.js';
|
|
@@ -32,6 +33,17 @@ export async function authenticateConnection(message) {
|
|
|
32
33
|
throw new WebSocketError('auth', 'AUTH_FAILED', 'Authentication failed.', message['uid']);
|
|
33
34
|
}
|
|
34
35
|
}
|
|
36
|
+
export async function refreshAccountability(accountability) {
|
|
37
|
+
accountability = accountability ?? {
|
|
38
|
+
role: null,
|
|
39
|
+
user: null,
|
|
40
|
+
admin: false,
|
|
41
|
+
app: false,
|
|
42
|
+
};
|
|
43
|
+
const schema = await getSchema();
|
|
44
|
+
const permissions = await getPermissions(accountability, schema);
|
|
45
|
+
return { ...accountability, permissions };
|
|
46
|
+
}
|
|
35
47
|
export function authenticationSuccess(uid, refresh_token) {
|
|
36
48
|
const message = {
|
|
37
49
|
type: 'auth',
|
|
@@ -4,7 +4,7 @@ import { useLogger } from '../../logger/index.js';
|
|
|
4
4
|
import { bindPubSub } from '../../services/graphql/subscription.js';
|
|
5
5
|
import { GraphQLService } from '../../services/index.js';
|
|
6
6
|
import { getSchema } from '../../utils/get-schema.js';
|
|
7
|
-
import { authenticateConnection } from '../authenticate.js';
|
|
7
|
+
import { authenticateConnection, refreshAccountability } from '../authenticate.js';
|
|
8
8
|
import { handleWebSocketError } from '../errors.js';
|
|
9
9
|
import { ConnectionParams, WebSocketMessage } from '../messages.js';
|
|
10
10
|
import { getMessageType } from '../utils/message.js';
|
|
@@ -64,6 +64,9 @@ export class GraphQLSubscriptionController extends SocketController {
|
|
|
64
64
|
client.close(CloseCode.Forbidden, 'Forbidden');
|
|
65
65
|
return;
|
|
66
66
|
}
|
|
67
|
+
else {
|
|
68
|
+
client.accountability = await refreshAccountability(client.accountability);
|
|
69
|
+
}
|
|
67
70
|
await cb(JSON.stringify(message));
|
|
68
71
|
}
|
|
69
72
|
catch (error) {
|
|
@@ -7,23 +7,19 @@ export function registerWebSocketEvents() {
|
|
|
7
7
|
actionsRegistered = true;
|
|
8
8
|
registerActionHooks([
|
|
9
9
|
'items',
|
|
10
|
-
'access',
|
|
11
10
|
'activity',
|
|
12
11
|
'collections',
|
|
13
12
|
'dashboards',
|
|
14
|
-
'flows',
|
|
15
13
|
'folders',
|
|
16
14
|
'notifications',
|
|
17
15
|
'operations',
|
|
18
16
|
'panels',
|
|
19
17
|
'permissions',
|
|
20
|
-
'policies',
|
|
21
18
|
'presets',
|
|
22
19
|
'revisions',
|
|
23
20
|
'roles',
|
|
24
21
|
'settings',
|
|
25
22
|
'shares',
|
|
26
|
-
'translations',
|
|
27
23
|
'users',
|
|
28
24
|
'versions',
|
|
29
25
|
'webhooks',
|
|
@@ -2,6 +2,7 @@ import { useEnv } from '@directus/env';
|
|
|
2
2
|
import { parseJSON } from '@directus/utils';
|
|
3
3
|
import emitter from '../../emitter.js';
|
|
4
4
|
import { useLogger } from '../../logger/index.js';
|
|
5
|
+
import { refreshAccountability } from '../authenticate.js';
|
|
5
6
|
import { WebSocketError, handleWebSocketError } from '../errors.js';
|
|
6
7
|
import { WebSocketMessage } from '../messages.js';
|
|
7
8
|
import SocketController from './base.js';
|
|
@@ -19,6 +20,7 @@ export class WebSocketController extends SocketController {
|
|
|
19
20
|
client.on('parsed-message', async (message) => {
|
|
20
21
|
try {
|
|
21
22
|
message = WebSocketMessage.parse(await emitter.emitFilter('websocket.message', message, { client }));
|
|
23
|
+
client.accountability = await refreshAccountability(client.accountability);
|
|
22
24
|
emitter.emitAction('websocket.message', { message, client });
|
|
23
25
|
}
|
|
24
26
|
catch (error) {
|
|
@@ -4,6 +4,7 @@ import { useBus } from '../../bus/index.js';
|
|
|
4
4
|
import emitter from '../../emitter.js';
|
|
5
5
|
import { getSchema } from '../../utils/get-schema.js';
|
|
6
6
|
import { sanitizeQuery } from '../../utils/sanitize-query.js';
|
|
7
|
+
import { refreshAccountability } from '../authenticate.js';
|
|
7
8
|
import { WebSocketError, handleWebSocketError } from '../errors.js';
|
|
8
9
|
import { WebSocketSubscribeMessage } from '../messages.js';
|
|
9
10
|
import { getPayload } from '../utils/items.js';
|
|
@@ -111,6 +112,7 @@ export class SubscribeHandler {
|
|
|
111
112
|
continue;
|
|
112
113
|
}
|
|
113
114
|
try {
|
|
115
|
+
client.accountability = await refreshAccountability(client.accountability);
|
|
114
116
|
const result = await getPayload(subscription, client.accountability, schema, event);
|
|
115
117
|
if (Array.isArray(result?.['data']) && result?.['data']?.length === 0)
|
|
116
118
|
continue;
|
|
@@ -39,5 +39,5 @@ export declare function getFieldsPayload(subscription: PSubscription, accountabi
|
|
|
39
39
|
* @param event Event data
|
|
40
40
|
* @returns the fetched data
|
|
41
41
|
*/
|
|
42
|
-
export declare function getItemsPayload(subscription: PSubscription, accountability: Accountability | null, schema: SchemaOverview, event?: WebSocketEvent): Promise<string | number |
|
|
42
|
+
export declare function getItemsPayload(subscription: PSubscription, accountability: Accountability | null, schema: SchemaOverview, event?: WebSocketEvent): Promise<string | number | import("@directus/types").Item | (string | number)[] | import("@directus/types").Item[]>;
|
|
43
43
|
export {};
|