@directus/api 14.1.2 → 16.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 +8 -6
- package/dist/auth/drivers/ldap.js +7 -4
- package/dist/auth/drivers/local.js +3 -2
- package/dist/auth/drivers/oauth2.js +11 -5
- package/dist/auth/drivers/openid.js +11 -5
- package/dist/auth/drivers/saml.js +6 -4
- package/dist/auth.js +7 -4
- package/dist/bus/index.d.ts +1 -0
- package/dist/bus/index.js +1 -0
- package/dist/bus/lib/use-bus.d.ts +9 -0
- package/dist/bus/lib/use-bus.js +21 -0
- package/dist/cache.js +9 -9
- package/dist/cli/commands/bootstrap/index.js +6 -2
- package/dist/cli/commands/count/index.js +2 -1
- package/dist/cli/commands/database/install.js +2 -1
- package/dist/cli/commands/database/migrate.js +2 -1
- package/dist/cli/commands/roles/create.js +2 -1
- package/dist/cli/commands/schema/apply.js +46 -34
- package/dist/cli/commands/schema/snapshot.js +6 -5
- package/dist/cli/commands/users/create.js +4 -3
- package/dist/cli/commands/users/passwd.js +5 -4
- package/dist/cli/index.js +2 -2
- package/dist/cli/load-extensions.js +4 -2
- package/dist/cli/utils/create-env/env-stub.liquid +1 -1
- package/dist/constants.d.ts +1 -1
- package/dist/constants.js +4 -1
- package/dist/controllers/assets.js +5 -3
- package/dist/controllers/auth.js +5 -4
- package/dist/controllers/extensions.js +18 -6
- package/dist/controllers/files.js +3 -3
- package/dist/controllers/schema.js +3 -2
- package/dist/controllers/shares.js +3 -3
- package/dist/database/helpers/index.d.ts +1 -1
- package/dist/database/index.d.ts +2 -1
- package/dist/database/index.js +11 -3
- package/dist/database/migrations/20210518A-add-foreign-key-constraints.js +3 -1
- package/dist/database/migrations/20210519A-add-system-fk-triggers.js +3 -1
- package/dist/database/migrations/20210802A-replace-groups.js +2 -1
- package/dist/database/migrations/20230721A-require-shares-fields.js +2 -1
- package/dist/database/migrations/20231215A-add-focalpoints.d.ts +3 -0
- package/dist/database/migrations/20231215A-add-focalpoints.js +12 -0
- package/dist/database/migrations/run.js +2 -1
- package/dist/database/run-ast.js +5 -2
- package/dist/database/system-data/app-access-permissions/app-access-permissions.yaml +0 -7
- package/dist/database/system-data/fields/files.yaml +16 -0
- package/dist/database/system-data/relations/relations.yaml +4 -0
- package/dist/emitter.d.ts +1 -0
- package/dist/emitter.js +4 -1
- package/dist/extensions/lib/get-extensions-path.d.ts +1 -1
- package/dist/extensions/lib/get-extensions-path.js +2 -1
- package/dist/extensions/lib/get-extensions.d.ts +1 -1
- package/dist/extensions/lib/get-extensions.js +32 -8
- package/dist/extensions/lib/get-shared-deps-mapping.js +7 -5
- package/dist/extensions/lib/sandbox/register/call-reference.js +4 -2
- package/dist/extensions/lib/sandbox/register/route.d.ts +1 -0
- package/dist/extensions/lib/sandbox/sdk/generators/log.js +2 -1
- package/dist/extensions/lib/sync-extensions.js +6 -4
- package/dist/extensions/manager.d.ts +5 -0
- package/dist/extensions/manager.js +84 -34
- package/dist/flows.js +13 -7
- package/dist/logger.d.ts +7 -6
- package/dist/logger.js +116 -91
- package/dist/mailer.js +4 -2
- package/dist/middleware/cache.js +4 -2
- package/dist/middleware/check-ip.js +25 -6
- package/dist/middleware/cors.js +2 -1
- package/dist/middleware/error-handler.js +5 -5
- package/dist/middleware/rate-limiter-global.js +4 -2
- package/dist/middleware/rate-limiter-ip.js +16 -12
- package/dist/middleware/respond.js +4 -2
- package/dist/operations/log/index.js +2 -1
- package/dist/rate-limiter.d.ts +2 -1
- package/dist/rate-limiter.js +5 -2
- package/dist/redis/index.d.ts +3 -0
- package/dist/redis/index.js +3 -0
- package/dist/redis/lib/create-redis.d.ts +7 -0
- package/dist/redis/lib/create-redis.js +12 -0
- package/dist/redis/lib/use-redis.d.ts +16 -0
- package/dist/redis/lib/use-redis.js +22 -0
- package/dist/redis/utils/redis-config-available.d.ts +4 -0
- package/dist/redis/utils/redis-config-available.js +8 -0
- package/dist/request/request-interceptor.js +7 -5
- package/dist/request/response-interceptor.js +2 -2
- package/dist/request/validate-ip.d.ts +1 -1
- package/dist/request/validate-ip.js +23 -7
- package/dist/server.d.ts +2 -0
- package/dist/server.js +11 -7
- package/dist/services/activity.js +5 -4
- package/dist/services/assets.d.ts +2 -0
- package/dist/services/assets.js +9 -4
- package/dist/services/authentication.js +17 -9
- package/dist/services/collections.js +5 -4
- package/dist/services/extensions.d.ts +15 -9
- package/dist/services/extensions.js +75 -40
- package/dist/services/fields.js +9 -4
- package/dist/services/files.d.ts +2 -2
- package/dist/services/files.js +22 -14
- package/dist/services/graphql/index.js +96 -18
- package/dist/services/graphql/subscription.js +2 -2
- package/dist/services/graphql/types/bigint.js +16 -5
- package/dist/services/graphql/utils/process-error.d.ts +4 -1
- package/dist/services/graphql/utils/process-error.js +10 -8
- package/dist/services/import-export/index.js +5 -3
- package/dist/services/items.js +12 -8
- package/dist/services/mail/index.js +4 -2
- package/dist/services/notifications.js +7 -3
- package/dist/services/payload.js +3 -3
- package/dist/services/relations.js +19 -10
- package/dist/services/server.js +7 -7
- package/dist/services/shares.js +3 -2
- package/dist/services/specifications.js +5 -4
- package/dist/services/users.js +24 -13
- package/dist/services/versions.js +6 -5
- package/dist/services/webhooks.d.ts +2 -2
- package/dist/services/webhooks.js +2 -2
- package/dist/services/websocket.d.ts +1 -1
- package/dist/services/websocket.js +4 -3
- package/dist/storage/register-drivers.js +2 -1
- package/dist/storage/register-locations.js +2 -1
- package/dist/synchronization.js +3 -1
- package/dist/telemetry/index.d.ts +4 -0
- package/dist/telemetry/index.js +4 -0
- package/dist/telemetry/lib/get-report.d.ts +5 -0
- package/dist/telemetry/lib/get-report.js +42 -0
- package/dist/telemetry/lib/init-telemetry.d.ts +11 -0
- package/dist/telemetry/lib/init-telemetry.js +30 -0
- package/dist/telemetry/lib/send-report.d.ts +5 -0
- package/dist/telemetry/lib/send-report.js +23 -0
- package/dist/telemetry/lib/track.d.ts +10 -0
- package/dist/telemetry/lib/track.js +30 -0
- package/dist/telemetry/types/report.d.ts +58 -0
- package/dist/telemetry/types/report.js +1 -0
- package/dist/telemetry/utils/get-item-count.d.ts +26 -0
- package/dist/telemetry/utils/get-item-count.js +36 -0
- package/dist/telemetry/utils/get-random-wait-time.d.ts +5 -0
- package/dist/telemetry/utils/get-random-wait-time.js +5 -0
- package/dist/telemetry/utils/get-user-count.d.ts +7 -0
- package/dist/telemetry/utils/get-user-count.js +30 -0
- package/dist/telemetry/utils/get-user-item-count.d.ts +13 -0
- package/dist/telemetry/utils/get-user-item-count.js +18 -0
- package/dist/types/assets.d.ts +2 -0
- package/dist/utils/apply-diff.js +2 -1
- package/dist/utils/apply-query.js +2 -2
- package/dist/utils/delete-from-require-cache.js +2 -1
- package/dist/utils/get-accountability-for-token.js +3 -2
- package/dist/utils/get-auth-providers.js +2 -1
- package/dist/utils/get-cache-headers.js +5 -2
- package/dist/utils/get-cache-key.js +1 -1
- package/dist/utils/get-config-from-env.js +2 -1
- package/dist/utils/get-default-value.js +4 -3
- package/dist/utils/get-ip-from-req.d.ts +1 -1
- package/dist/utils/get-ip-from-req.js +5 -3
- package/dist/utils/get-permissions.js +5 -3
- package/dist/utils/get-schema.js +5 -2
- package/dist/utils/get-snapshot-diff.js +7 -9
- package/dist/utils/get-snapshot.js +5 -5
- package/dist/utils/get-versioned-hash.js +1 -1
- package/dist/utils/ip-in-networks.d.ts +6 -0
- package/dist/utils/ip-in-networks.js +13 -0
- package/dist/utils/is-url-allowed.js +2 -1
- package/dist/utils/job-queue.d.ts +1 -0
- package/dist/utils/job-queue.js +3 -0
- package/dist/utils/md.d.ts +1 -1
- package/dist/utils/md.js +3 -2
- package/dist/utils/sanitize-query.js +7 -2
- package/dist/utils/sanitize-schema.d.ts +1 -1
- package/dist/utils/should-clear-cache.js +2 -1
- package/dist/utils/should-skip-cache.js +2 -1
- package/dist/utils/transformations.js +95 -12
- package/dist/utils/validate-env.js +4 -2
- package/dist/utils/validate-query.js +8 -3
- package/dist/utils/validate-snapshot.js +3 -3
- package/dist/utils/validate-storage.js +4 -2
- package/dist/webhooks.js +4 -3
- package/dist/websocket/controllers/base.d.ts +2 -0
- package/dist/websocket/controllers/base.js +12 -6
- package/dist/websocket/controllers/graphql.d.ts +2 -0
- package/dist/websocket/controllers/graphql.js +5 -3
- package/dist/websocket/controllers/hooks.js +3 -2
- package/dist/websocket/controllers/index.d.ts +2 -0
- package/dist/websocket/controllers/index.js +4 -2
- package/dist/websocket/controllers/rest.d.ts +2 -0
- package/dist/websocket/controllers/rest.js +4 -2
- package/dist/websocket/errors.js +2 -1
- package/dist/websocket/handlers/heartbeat.js +4 -3
- package/dist/websocket/handlers/subscribe.d.ts +2 -2
- package/dist/websocket/handlers/subscribe.js +5 -4
- package/dist/websocket/types.d.ts +3 -1
- package/package.json +114 -115
- package/dist/__utils__/items-utils.d.ts +0 -2
- package/dist/__utils__/items-utils.js +0 -31
- package/dist/__utils__/mock-env.d.ts +0 -18
- package/dist/__utils__/mock-env.js +0 -41
- package/dist/__utils__/schemas.d.ts +0 -13
- package/dist/__utils__/schemas.js +0 -301
- package/dist/__utils__/snapshots.d.ts +0 -5
- package/dist/__utils__/snapshots.js +0 -903
- package/dist/env.d.ts +0 -13
- package/dist/env.js +0 -505
- package/dist/messenger.d.ts +0 -24
- package/dist/messenger.js +0 -64
- package/dist/utils/package.d.ts +0 -2
- package/dist/utils/package.js +0 -6
- package/dist/utils/telemetry.d.ts +0 -1
- package/dist/utils/telemetry.js +0 -23
- package/dist/utils/to-boolean.d.ts +0 -4
- package/dist/utils/to-boolean.js +0 -6
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Action, FUNCTIONS } from '@directus/constants';
|
|
2
|
+
import { useEnv } from '@directus/env';
|
|
2
3
|
import { ErrorCode, ForbiddenError, InvalidPayloadError, isDirectusError } from '@directus/errors';
|
|
3
|
-
import { parseFilterFunctionPath } from '@directus/utils';
|
|
4
|
+
import { parseFilterFunctionPath, toBoolean } from '@directus/utils';
|
|
4
5
|
import argon2 from 'argon2';
|
|
5
6
|
import { GraphQLBoolean, GraphQLEnumType, GraphQLError, GraphQLFloat, GraphQLID, GraphQLInt, GraphQLList, GraphQLNonNull, GraphQLObjectType, GraphQLScalarType, GraphQLSchema, GraphQLString, GraphQLUnionType, NoSchemaIntrospectionCustomRule, execute, specifiedRules, validate, } from 'graphql';
|
|
6
7
|
import { GraphQLJSON, InputTypeComposer, ObjectTypeComposer, SchemaComposer, toInputObjectType } from 'graphql-compose';
|
|
@@ -8,14 +9,12 @@ import { assign, flatten, get, mapKeys, merge, omit, pick, set, transform, uniq
|
|
|
8
9
|
import { clearSystemCache, getCache } from '../../cache.js';
|
|
9
10
|
import { DEFAULT_AUTH_PROVIDER, GENERATE_SPECIAL } from '../../constants.js';
|
|
10
11
|
import getDatabase from '../../database/index.js';
|
|
11
|
-
import env from '../../env.js';
|
|
12
12
|
import { generateHash } from '../../utils/generate-hash.js';
|
|
13
13
|
import { getGraphQLType } from '../../utils/get-graphql-type.js';
|
|
14
14
|
import { getMilliseconds } from '../../utils/get-milliseconds.js';
|
|
15
15
|
import { getService } from '../../utils/get-service.js';
|
|
16
16
|
import { reduceSchema } from '../../utils/reduce-schema.js';
|
|
17
17
|
import { sanitizeQuery } from '../../utils/sanitize-query.js';
|
|
18
|
-
import { toBoolean } from '../../utils/to-boolean.js';
|
|
19
18
|
import { validateQuery } from '../../utils/validate-query.js';
|
|
20
19
|
import { ActivityService } from '../activity.js';
|
|
21
20
|
import { AuthenticationService } from '../authentication.js';
|
|
@@ -41,6 +40,7 @@ import { GraphQLStringOrFloat } from './types/string-or-float.js';
|
|
|
41
40
|
import { GraphQLVoid } from './types/void.js';
|
|
42
41
|
import { addPathToValidationError } from './utils/add-path-to-validation-error.js';
|
|
43
42
|
import processError from './utils/process-error.js';
|
|
43
|
+
const env = useEnv();
|
|
44
44
|
const validationRules = Array.from(specifiedRules);
|
|
45
45
|
if (env['GRAPHQL_INTROSPECTION'] === false) {
|
|
46
46
|
validationRules.push(NoSchemaIntrospectionCustomRule);
|
|
@@ -126,7 +126,7 @@ export class GraphQLService {
|
|
|
126
126
|
delete: { value: 'delete' },
|
|
127
127
|
},
|
|
128
128
|
});
|
|
129
|
-
const { ReadCollectionTypes } = getReadableTypes();
|
|
129
|
+
const { ReadCollectionTypes, VersionCollectionTypes } = getReadableTypes();
|
|
130
130
|
const { CreateCollectionTypes, UpdateCollectionTypes, DeleteCollectionTypes } = getWritableTypes();
|
|
131
131
|
const scopeFilter = (collection) => {
|
|
132
132
|
if (this.scope === 'items' && collection.collection.startsWith('directus_') === true)
|
|
@@ -158,6 +158,9 @@ export class GraphQLService {
|
|
|
158
158
|
acc[`${collectionName}_by_id`] = ReadCollectionTypes[collection.collection].getResolver(`${collection.collection}_by_id`);
|
|
159
159
|
acc[`${collectionName}_aggregated`] = ReadCollectionTypes[collection.collection].getResolver(`${collection.collection}_aggregated`);
|
|
160
160
|
}
|
|
161
|
+
if (this.scope === 'items') {
|
|
162
|
+
acc[`${collectionName}_by_version`] = VersionCollectionTypes[collection.collection].getResolver(`${collection.collection}_by_version`);
|
|
163
|
+
}
|
|
161
164
|
return acc;
|
|
162
165
|
}, {}));
|
|
163
166
|
}
|
|
@@ -221,6 +224,7 @@ export class GraphQLService {
|
|
|
221
224
|
*/
|
|
222
225
|
function getTypes(action) {
|
|
223
226
|
const CollectionTypes = {};
|
|
227
|
+
const VersionTypes = {};
|
|
224
228
|
const CountFunctions = schemaComposer.createObjectTC({
|
|
225
229
|
name: 'count_functions',
|
|
226
230
|
fields: {
|
|
@@ -289,13 +293,19 @@ export class GraphQLService {
|
|
|
289
293
|
type = new GraphQLNonNull(type);
|
|
290
294
|
}
|
|
291
295
|
if (collection.primary === field.field) {
|
|
292
|
-
|
|
296
|
+
// permissions IDs need to be nullable https://github.com/directus/directus/issues/20509
|
|
297
|
+
if (collection.collection === 'directus_permissions') {
|
|
298
|
+
type = GraphQLID;
|
|
299
|
+
}
|
|
300
|
+
else if (!field.defaultValue && !field.special.includes('uuid') && action === 'create') {
|
|
293
301
|
type = new GraphQLNonNull(GraphQLID);
|
|
294
302
|
}
|
|
295
|
-
else if (['create', 'update'].includes(action))
|
|
303
|
+
else if (['create', 'update'].includes(action)) {
|
|
296
304
|
type = GraphQLID;
|
|
297
|
-
|
|
305
|
+
}
|
|
306
|
+
else {
|
|
298
307
|
type = new GraphQLNonNull(GraphQLID);
|
|
308
|
+
}
|
|
299
309
|
}
|
|
300
310
|
acc[field.field] = {
|
|
301
311
|
type,
|
|
@@ -345,6 +355,9 @@ export class GraphQLService {
|
|
|
345
355
|
return acc;
|
|
346
356
|
}, {}),
|
|
347
357
|
});
|
|
358
|
+
if (self.scope === 'items') {
|
|
359
|
+
VersionTypes[collection.collection] = CollectionTypes[collection.collection].clone(`version_${collection.collection}`);
|
|
360
|
+
}
|
|
348
361
|
}
|
|
349
362
|
for (const relation of schema[action].relations) {
|
|
350
363
|
if (relation.related_collection) {
|
|
@@ -367,6 +380,16 @@ export class GraphQLService {
|
|
|
367
380
|
},
|
|
368
381
|
},
|
|
369
382
|
});
|
|
383
|
+
if (self.scope === 'items') {
|
|
384
|
+
VersionTypes[relation.related_collection]?.addFields({
|
|
385
|
+
[relation.meta.one_field]: {
|
|
386
|
+
type: GraphQLJSON,
|
|
387
|
+
resolve: (obj, _, __, info) => {
|
|
388
|
+
return obj[info?.path?.key ?? relation.meta.one_field];
|
|
389
|
+
},
|
|
390
|
+
},
|
|
391
|
+
});
|
|
392
|
+
}
|
|
370
393
|
}
|
|
371
394
|
}
|
|
372
395
|
else if (relation.meta?.one_allowed_collections && action === 'read') {
|
|
@@ -399,13 +422,13 @@ export class GraphQLService {
|
|
|
399
422
|
});
|
|
400
423
|
}
|
|
401
424
|
}
|
|
402
|
-
return { CollectionTypes };
|
|
425
|
+
return { CollectionTypes, VersionTypes };
|
|
403
426
|
}
|
|
404
427
|
/**
|
|
405
428
|
* Create readable types and attach resolvers for each. Also prepares full filter argument structures
|
|
406
429
|
*/
|
|
407
430
|
function getReadableTypes() {
|
|
408
|
-
const { CollectionTypes: ReadCollectionTypes } = getTypes('read');
|
|
431
|
+
const { CollectionTypes: ReadCollectionTypes, VersionTypes: VersionCollectionTypes } = getTypes('read');
|
|
409
432
|
const ReadableCollectionFilterTypes = {};
|
|
410
433
|
const AggregatedFunctions = {};
|
|
411
434
|
const AggregatedFields = {};
|
|
@@ -572,6 +595,47 @@ export class GraphQLService {
|
|
|
572
595
|
},
|
|
573
596
|
},
|
|
574
597
|
});
|
|
598
|
+
const BigIntFilterOperators = schemaComposer.createInputTC({
|
|
599
|
+
name: 'big_int_filter_operators',
|
|
600
|
+
fields: {
|
|
601
|
+
_eq: {
|
|
602
|
+
type: GraphQLBigInt,
|
|
603
|
+
},
|
|
604
|
+
_neq: {
|
|
605
|
+
type: GraphQLBigInt,
|
|
606
|
+
},
|
|
607
|
+
_in: {
|
|
608
|
+
type: new GraphQLList(GraphQLBigInt),
|
|
609
|
+
},
|
|
610
|
+
_nin: {
|
|
611
|
+
type: new GraphQLList(GraphQLBigInt),
|
|
612
|
+
},
|
|
613
|
+
_gt: {
|
|
614
|
+
type: GraphQLBigInt,
|
|
615
|
+
},
|
|
616
|
+
_gte: {
|
|
617
|
+
type: GraphQLBigInt,
|
|
618
|
+
},
|
|
619
|
+
_lt: {
|
|
620
|
+
type: GraphQLBigInt,
|
|
621
|
+
},
|
|
622
|
+
_lte: {
|
|
623
|
+
type: GraphQLBigInt,
|
|
624
|
+
},
|
|
625
|
+
_null: {
|
|
626
|
+
type: GraphQLBoolean,
|
|
627
|
+
},
|
|
628
|
+
_nnull: {
|
|
629
|
+
type: GraphQLBoolean,
|
|
630
|
+
},
|
|
631
|
+
_between: {
|
|
632
|
+
type: new GraphQLList(GraphQLBigInt),
|
|
633
|
+
},
|
|
634
|
+
_nbetween: {
|
|
635
|
+
type: new GraphQLList(GraphQLBigInt),
|
|
636
|
+
},
|
|
637
|
+
},
|
|
638
|
+
});
|
|
575
639
|
const GeometryFilterOperators = schemaComposer.createInputTC({
|
|
576
640
|
name: 'geometry_filter_operators',
|
|
577
641
|
fields: {
|
|
@@ -682,6 +746,8 @@ export class GraphQLService {
|
|
|
682
746
|
filterOperatorType = BooleanFilterOperators;
|
|
683
747
|
break;
|
|
684
748
|
case GraphQLBigInt:
|
|
749
|
+
filterOperatorType = BigIntFilterOperators;
|
|
750
|
+
break;
|
|
685
751
|
case GraphQLInt:
|
|
686
752
|
case GraphQLFloat:
|
|
687
753
|
filterOperatorType = NumberFilterOperators;
|
|
@@ -843,13 +909,6 @@ export class GraphQLService {
|
|
|
843
909
|
},
|
|
844
910
|
};
|
|
845
911
|
}
|
|
846
|
-
else {
|
|
847
|
-
resolver.args = {
|
|
848
|
-
version: {
|
|
849
|
-
type: GraphQLString,
|
|
850
|
-
},
|
|
851
|
-
};
|
|
852
|
-
}
|
|
853
912
|
ReadCollectionTypes[collection.collection].addResolver(resolver);
|
|
854
913
|
ReadCollectionTypes[collection.collection].addResolver({
|
|
855
914
|
name: `${collection.collection}_aggregated`,
|
|
@@ -885,7 +944,6 @@ export class GraphQLService {
|
|
|
885
944
|
type: ReadCollectionTypes[collection.collection],
|
|
886
945
|
args: {
|
|
887
946
|
id: new GraphQLNonNull(GraphQLID),
|
|
888
|
-
version: GraphQLString,
|
|
889
947
|
},
|
|
890
948
|
resolve: async ({ info, context }) => {
|
|
891
949
|
const result = await self.resolveQuery(info);
|
|
@@ -894,6 +952,23 @@ export class GraphQLService {
|
|
|
894
952
|
},
|
|
895
953
|
});
|
|
896
954
|
}
|
|
955
|
+
if (self.scope === 'items') {
|
|
956
|
+
VersionCollectionTypes[collection.collection].addResolver({
|
|
957
|
+
name: `${collection.collection}_by_version`,
|
|
958
|
+
type: VersionCollectionTypes[collection.collection],
|
|
959
|
+
args: collection.singleton
|
|
960
|
+
? { version: new GraphQLNonNull(GraphQLString) }
|
|
961
|
+
: {
|
|
962
|
+
version: new GraphQLNonNull(GraphQLString),
|
|
963
|
+
id: new GraphQLNonNull(GraphQLID),
|
|
964
|
+
},
|
|
965
|
+
resolve: async ({ info, context }) => {
|
|
966
|
+
const result = await self.resolveQuery(info);
|
|
967
|
+
context['data'] = result;
|
|
968
|
+
return result;
|
|
969
|
+
},
|
|
970
|
+
});
|
|
971
|
+
}
|
|
897
972
|
const eventName = `${collection.collection}_mutated`;
|
|
898
973
|
if (collection.collection in ReadCollectionTypes) {
|
|
899
974
|
const subscriptionType = schemaComposer.createObjectTC({
|
|
@@ -973,7 +1048,7 @@ export class GraphQLService {
|
|
|
973
1048
|
}
|
|
974
1049
|
}
|
|
975
1050
|
}
|
|
976
|
-
return { ReadCollectionTypes, ReadableCollectionFilterTypes };
|
|
1051
|
+
return { ReadCollectionTypes, VersionCollectionTypes, ReadableCollectionFilterTypes };
|
|
977
1052
|
}
|
|
978
1053
|
function getWritableTypes() {
|
|
979
1054
|
const { CollectionTypes: CreateCollectionTypes } = getTypes('create');
|
|
@@ -1135,6 +1210,9 @@ export class GraphQLService {
|
|
|
1135
1210
|
if (collection.endsWith('_by_id') && collection in this.schema.collections === false) {
|
|
1136
1211
|
collection = collection.slice(0, -6);
|
|
1137
1212
|
}
|
|
1213
|
+
if (collection.endsWith('_by_version') && collection in this.schema.collections === false) {
|
|
1214
|
+
collection = collection.slice(0, -11);
|
|
1215
|
+
}
|
|
1138
1216
|
}
|
|
1139
1217
|
if (args['id']) {
|
|
1140
1218
|
query.filter = {
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { EventEmitter, on } from 'events';
|
|
2
|
-
import {
|
|
2
|
+
import { useBus } from '../../bus/index.js';
|
|
3
3
|
import { getSchema } from '../../utils/get-schema.js';
|
|
4
4
|
import { refreshAccountability } from '../../websocket/authenticate.js';
|
|
5
5
|
import { getPayload } from '../../websocket/utils/items.js';
|
|
6
6
|
const messages = createPubSub(new EventEmitter());
|
|
7
7
|
export function bindPubSub() {
|
|
8
|
-
const messenger =
|
|
8
|
+
const messenger = useBus();
|
|
9
9
|
messenger.subscribe('websocket.event', (message) => {
|
|
10
10
|
messages.publish(`${message['collection']}_mutated`, message);
|
|
11
11
|
});
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import { GraphQLScalarType, Kind } from 'graphql';
|
|
2
|
+
// minimum and maximum int64 values database vendors use for big integer
|
|
3
|
+
const MIN_BIG_INT = -9223372036854775808n;
|
|
4
|
+
const MAX_BIG_INT = 9223372036854775807n;
|
|
2
5
|
export const GraphQLBigInt = new GraphQLScalarType({
|
|
3
6
|
name: 'GraphQLBigInt',
|
|
4
7
|
description: 'BigInt value',
|
|
@@ -26,11 +29,19 @@ export const GraphQLBigInt = new GraphQLScalarType({
|
|
|
26
29
|
},
|
|
27
30
|
});
|
|
28
31
|
function parseNumberValue(input) {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
if (isNaN(value) || value < Number.MIN_SAFE_INTEGER || value > Number.MAX_SAFE_INTEGER) {
|
|
32
|
+
// Attempt to parse the input as a regular integer
|
|
33
|
+
const intValue = Number(input);
|
|
34
|
+
if (isNaN(intValue)) {
|
|
33
35
|
throw new Error('Invalid GraphQLBigInt');
|
|
34
36
|
}
|
|
35
|
-
|
|
37
|
+
if (!Number.isSafeInteger(intValue)) {
|
|
38
|
+
// If the input is not a safe integer, its a big int, so return it as string,
|
|
39
|
+
// because currently string is the best way to handle big int due to knex limitations and JSON.stringify not able to serialise bigInt
|
|
40
|
+
const bigIntInput = BigInt(input);
|
|
41
|
+
if (bigIntInput < MIN_BIG_INT || bigIntInput > MAX_BIG_INT) {
|
|
42
|
+
throw new Error('Invalid GraphQLBigInt');
|
|
43
|
+
}
|
|
44
|
+
return input;
|
|
45
|
+
}
|
|
46
|
+
return intValue;
|
|
36
47
|
}
|
|
@@ -1,4 +1,7 @@
|
|
|
1
|
+
import { type DirectusError } from '@directus/errors';
|
|
1
2
|
import type { Accountability } from '@directus/types';
|
|
2
3
|
import type { GraphQLError, GraphQLFormattedError } from 'graphql';
|
|
3
|
-
declare const processError: (accountability: Accountability | null, error: Readonly<GraphQLError
|
|
4
|
+
declare const processError: (accountability: Accountability | null, error: Readonly<GraphQLError & {
|
|
5
|
+
originalError: GraphQLError | DirectusError | Error | undefined;
|
|
6
|
+
}>) => GraphQLFormattedError;
|
|
4
7
|
export default processError;
|
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
import { isDirectusError } from '@directus/errors';
|
|
2
|
-
import
|
|
2
|
+
import { useLogger } from '../../../logger.js';
|
|
3
3
|
const processError = (accountability, error) => {
|
|
4
|
+
const logger = useLogger();
|
|
4
5
|
logger.error(error);
|
|
5
|
-
|
|
6
|
+
let originalError = error.originalError;
|
|
7
|
+
if (originalError && 'originalError' in originalError) {
|
|
8
|
+
originalError = originalError.originalError;
|
|
9
|
+
}
|
|
6
10
|
if (isDirectusError(originalError)) {
|
|
7
11
|
return {
|
|
8
12
|
message: originalError.message,
|
|
@@ -10,6 +14,8 @@ const processError = (accountability, error) => {
|
|
|
10
14
|
code: originalError.code,
|
|
11
15
|
...(originalError.extensions ?? {}),
|
|
12
16
|
},
|
|
17
|
+
...(error.locations && { locations: error.locations }),
|
|
18
|
+
...(error.path && { path: error.path }),
|
|
13
19
|
};
|
|
14
20
|
}
|
|
15
21
|
else {
|
|
@@ -19,13 +25,9 @@ const processError = (accountability, error) => {
|
|
|
19
25
|
extensions: {
|
|
20
26
|
code: 'INTERNAL_SERVER_ERROR',
|
|
21
27
|
},
|
|
28
|
+
...(error.locations && { locations: error.locations }),
|
|
29
|
+
...(error.path && { path: error.path }),
|
|
22
30
|
};
|
|
23
|
-
if (error.locations) {
|
|
24
|
-
graphqlFormattedError.locations = error.locations;
|
|
25
|
-
}
|
|
26
|
-
if (error.path) {
|
|
27
|
-
graphqlFormattedError.path = error.path;
|
|
28
|
-
}
|
|
29
31
|
return graphqlFormattedError;
|
|
30
32
|
}
|
|
31
33
|
else {
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { useEnv } from '@directus/env';
|
|
2
|
+
import { ForbiddenError, InvalidPayloadError, ServiceUnavailableError, UnsupportedMediaTypeError, } from '@directus/errors';
|
|
1
3
|
import { parseJSON, toArray } from '@directus/utils';
|
|
2
4
|
import { queue } from 'async';
|
|
3
5
|
import destroyStream from 'destroy';
|
|
@@ -10,9 +12,7 @@ import Papa from 'papaparse';
|
|
|
10
12
|
import StreamArray from 'stream-json/streamers/StreamArray.js';
|
|
11
13
|
import getDatabase from '../../database/index.js';
|
|
12
14
|
import emitter from '../../emitter.js';
|
|
13
|
-
import
|
|
14
|
-
import { ForbiddenError, InvalidPayloadError, ServiceUnavailableError, UnsupportedMediaTypeError, } from '@directus/errors';
|
|
15
|
-
import logger from '../../logger.js';
|
|
15
|
+
import { useLogger } from '../../logger.js';
|
|
16
16
|
import { getDateFormatted } from '../../utils/get-date-formatted.js';
|
|
17
17
|
import { Url } from '../../utils/url.js';
|
|
18
18
|
import { userName } from '../../utils/user-name.js';
|
|
@@ -20,6 +20,8 @@ import { FilesService } from '../files.js';
|
|
|
20
20
|
import { ItemsService } from '../items.js';
|
|
21
21
|
import { NotificationsService } from '../notifications.js';
|
|
22
22
|
import { UsersService } from '../users.js';
|
|
23
|
+
const env = useEnv();
|
|
24
|
+
const logger = useLogger();
|
|
23
25
|
export class ImportService {
|
|
24
26
|
knex;
|
|
25
27
|
accountability;
|
package/dist/services/items.js
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
import { Action } from '@directus/constants';
|
|
2
|
+
import { useEnv } from '@directus/env';
|
|
3
|
+
import { ForbiddenError, InvalidPayloadError } from '@directus/errors';
|
|
2
4
|
import { assign, clone, cloneDeep, omit, pick, without } from 'lodash-es';
|
|
3
5
|
import { getCache } from '../cache.js';
|
|
6
|
+
import { translateDatabaseError } from '../database/errors/translate.js';
|
|
4
7
|
import { getHelpers } from '../database/helpers/index.js';
|
|
5
8
|
import getDatabase from '../database/index.js';
|
|
6
9
|
import runAST from '../database/run-ast.js';
|
|
7
10
|
import emitter from '../emitter.js';
|
|
8
|
-
import env from '../env.js';
|
|
9
|
-
import { ForbiddenError } from '@directus/errors';
|
|
10
|
-
import { translateDatabaseError } from '../database/errors/translate.js';
|
|
11
|
-
import { InvalidPayloadError } from '@directus/errors';
|
|
12
11
|
import getASTFromQuery from '../utils/get-ast-from-query.js';
|
|
13
12
|
import { shouldClearCache } from '../utils/should-clear-cache.js';
|
|
14
13
|
import { validateKeys } from '../utils/validate-keys.js';
|
|
15
14
|
import { AuthorizationService } from './authorization.js';
|
|
16
15
|
import { PayloadService } from './payload.js';
|
|
16
|
+
const env = useEnv();
|
|
17
17
|
export class ItemsService {
|
|
18
18
|
collection;
|
|
19
19
|
knex;
|
|
@@ -118,15 +118,19 @@ export class ItemsService {
|
|
|
118
118
|
const payloadWithTypeCasting = await payloadService.processValues('create', payloadWithoutAliases);
|
|
119
119
|
// The primary key can already exist in the payload.
|
|
120
120
|
// In case of manual string / UUID primary keys it's always provided at this point.
|
|
121
|
-
// In case of an integer primary key, it might be provided as the user can specify the value manually.
|
|
121
|
+
// In case of an (big) integer primary key, it might be provided as the user can specify the value manually.
|
|
122
122
|
let primaryKey = payloadWithTypeCasting[primaryKeyField];
|
|
123
|
+
if (primaryKey) {
|
|
124
|
+
validateKeys(this.schema, this.collection, primaryKeyField, primaryKey);
|
|
125
|
+
}
|
|
123
126
|
// If a PK of type number was provided, although the PK is set the auto_increment,
|
|
124
127
|
// depending on the database, the sequence might need to be reset to protect future PK collisions.
|
|
125
128
|
let autoIncrementSequenceNeedsToBeReset = false;
|
|
126
129
|
const pkField = this.schema.collections[this.collection].fields[primaryKeyField];
|
|
127
130
|
if (primaryKey &&
|
|
131
|
+
pkField &&
|
|
128
132
|
!opts.bypassAutoIncrementSequenceReset &&
|
|
129
|
-
pkField.type
|
|
133
|
+
['integer', 'bigInteger'].includes(pkField.type) &&
|
|
130
134
|
pkField.defaultValue === 'AUTO_INCREMENT') {
|
|
131
135
|
autoIncrementSequenceNeedsToBeReset = true;
|
|
132
136
|
}
|
|
@@ -505,7 +509,7 @@ export class ItemsService {
|
|
|
505
509
|
nestedActionEvents.push(...nestedActionEventsM2O);
|
|
506
510
|
nestedActionEvents.push(...nestedActionEventsA2O);
|
|
507
511
|
for (const key of keys) {
|
|
508
|
-
const { revisions, nestedActionEvents: nestedActionEventsO2M } = await payloadService.processO2M(
|
|
512
|
+
const { revisions, nestedActionEvents: nestedActionEventsO2M } = await payloadService.processO2M(payloadWithA2O, key, opts);
|
|
509
513
|
childrenRevisions.push(...revisions);
|
|
510
514
|
nestedActionEvents.push(...nestedActionEventsO2M);
|
|
511
515
|
}
|
|
@@ -569,7 +573,7 @@ export class ItemsService {
|
|
|
569
573
|
? ['items.update', `${this.collection}.items.update`]
|
|
570
574
|
: `${this.eventScope}.update`,
|
|
571
575
|
meta: {
|
|
572
|
-
payload,
|
|
576
|
+
payload: payloadWithPresets,
|
|
573
577
|
keys,
|
|
574
578
|
collection: this.collection,
|
|
575
579
|
},
|
|
@@ -1,14 +1,16 @@
|
|
|
1
|
+
import { useEnv } from '@directus/env';
|
|
1
2
|
import { InvalidPayloadError } from '@directus/errors';
|
|
2
3
|
import fse from 'fs-extra';
|
|
3
4
|
import { Liquid } from 'liquidjs';
|
|
4
5
|
import path from 'path';
|
|
5
6
|
import { fileURLToPath } from 'url';
|
|
6
7
|
import getDatabase from '../../database/index.js';
|
|
7
|
-
import env from '../../env.js';
|
|
8
8
|
import { getExtensionsPath } from '../../extensions/lib/get-extensions-path.js';
|
|
9
|
-
import
|
|
9
|
+
import { useLogger } from '../../logger.js';
|
|
10
10
|
import getMailer from '../../mailer.js';
|
|
11
11
|
import { Url } from '../../utils/url.js';
|
|
12
|
+
const env = useEnv();
|
|
13
|
+
const logger = useLogger();
|
|
12
14
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
13
15
|
const liquidEngine = new Liquid({
|
|
14
16
|
root: [path.resolve(getExtensionsPath(), 'templates'), path.resolve(__dirname, 'templates')],
|
|
@@ -1,10 +1,12 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
1
|
+
import { useEnv } from '@directus/env';
|
|
2
|
+
import { useLogger } from '../logger.js';
|
|
3
3
|
import { md } from '../utils/md.js';
|
|
4
4
|
import { Url } from '../utils/url.js';
|
|
5
5
|
import { ItemsService } from './items.js';
|
|
6
6
|
import { MailService } from './mail/index.js';
|
|
7
7
|
import { UsersService } from './users.js';
|
|
8
|
+
const env = useEnv();
|
|
9
|
+
const logger = useLogger();
|
|
8
10
|
export class NotificationsService extends ItemsService {
|
|
9
11
|
usersService;
|
|
10
12
|
mailService;
|
|
@@ -30,7 +32,9 @@ export class NotificationsService extends ItemsService {
|
|
|
30
32
|
const user = await this.usersService.readOne(data.recipient, {
|
|
31
33
|
fields: ['id', 'email', 'email_notifications', 'role.app_access'],
|
|
32
34
|
});
|
|
33
|
-
const manageUserAccountUrl = new Url(env['PUBLIC_URL'])
|
|
35
|
+
const manageUserAccountUrl = new Url(env['PUBLIC_URL'])
|
|
36
|
+
.addPath('admin', 'users', user['id'])
|
|
37
|
+
.toString();
|
|
34
38
|
const html = data.message ? md(data.message) : '';
|
|
35
39
|
if (user['email'] && user['email_notifications'] === true) {
|
|
36
40
|
try {
|
package/dist/services/payload.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
|
+
import { ForbiddenError, InvalidPayloadError } from '@directus/errors';
|
|
1
2
|
import { parseJSON, toArray } from '@directus/utils';
|
|
2
3
|
import { format, isValid, parseISO } from 'date-fns';
|
|
3
|
-
import
|
|
4
|
+
import { unflatten } from 'flat';
|
|
4
5
|
import Joi from 'joi';
|
|
5
6
|
import { clone, cloneDeep, isNil, isObject, isPlainObject, omit, pick } from 'lodash-es';
|
|
6
7
|
import { v4 as uuid } from 'uuid';
|
|
7
8
|
import { parse as wktToGeoJSON } from 'wellknown';
|
|
8
9
|
import { getHelpers } from '../database/helpers/index.js';
|
|
9
10
|
import getDatabase from '../database/index.js';
|
|
10
|
-
import { ForbiddenError, InvalidPayloadError } from '@directus/errors';
|
|
11
11
|
import { generateHash } from '../utils/generate-hash.js';
|
|
12
12
|
import { ItemsService } from './items.js';
|
|
13
13
|
/**
|
|
@@ -164,7 +164,7 @@ export class PayloadService {
|
|
|
164
164
|
const aggregateKeys = Object.keys(payload[0]).filter((key) => key.includes('->'));
|
|
165
165
|
if (aggregateKeys.length) {
|
|
166
166
|
for (const item of payload) {
|
|
167
|
-
Object.assign(item,
|
|
167
|
+
Object.assign(item, unflatten(pick(item, aggregateKeys), { delimiter: '->' }));
|
|
168
168
|
aggregateKeys.forEach((key) => delete item[key]);
|
|
169
169
|
}
|
|
170
170
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { ForbiddenError, InvalidPayloadError } from '@directus/errors';
|
|
1
2
|
import { createInspector } from '@directus/schema';
|
|
2
3
|
import { toArray } from '@directus/utils';
|
|
3
4
|
import { clearSystemCache, getCache } from '../cache.js';
|
|
@@ -5,7 +6,6 @@ import { getHelpers } from '../database/helpers/index.js';
|
|
|
5
6
|
import getDatabase, { getSchemaInspector } from '../database/index.js';
|
|
6
7
|
import { systemRelationRows } from '../database/system-data/relations/index.js';
|
|
7
8
|
import emitter from '../emitter.js';
|
|
8
|
-
import { ForbiddenError, InvalidPayloadError } from '@directus/errors';
|
|
9
9
|
import { getDefaultIndexName } from '../utils/get-default-index-name.js';
|
|
10
10
|
import { getSchema } from '../utils/get-schema.js';
|
|
11
11
|
import { ItemsService } from './items.js';
|
|
@@ -115,16 +115,18 @@ export class RelationsService {
|
|
|
115
115
|
if (!relation.field) {
|
|
116
116
|
throw new InvalidPayloadError({ reason: '"field" is required' });
|
|
117
117
|
}
|
|
118
|
-
|
|
118
|
+
const collectionSchema = this.schema.collections[relation.collection];
|
|
119
|
+
if (!collectionSchema) {
|
|
119
120
|
throw new InvalidPayloadError({ reason: `Collection "${relation.collection}" doesn't exist` });
|
|
120
121
|
}
|
|
121
|
-
|
|
122
|
+
const fieldSchema = collectionSchema.fields[relation.field];
|
|
123
|
+
if (!fieldSchema) {
|
|
122
124
|
throw new InvalidPayloadError({
|
|
123
125
|
reason: `Field "${relation.field}" doesn't exist in collection "${relation.collection}"`,
|
|
124
126
|
});
|
|
125
127
|
}
|
|
126
128
|
// A primary key should not be a foreign key
|
|
127
|
-
if (
|
|
129
|
+
if (collectionSchema.primary === relation.field) {
|
|
128
130
|
throw new InvalidPayloadError({
|
|
129
131
|
reason: `Field "${relation.field}" in collection "${relation.collection}" is a primary key`,
|
|
130
132
|
});
|
|
@@ -151,7 +153,7 @@ export class RelationsService {
|
|
|
151
153
|
await this.knex.transaction(async (trx) => {
|
|
152
154
|
if (relation.related_collection) {
|
|
153
155
|
await trx.schema.alterTable(relation.collection, async (table) => {
|
|
154
|
-
this.alterType(table, relation);
|
|
156
|
+
this.alterType(table, relation, fieldSchema.nullable);
|
|
155
157
|
const constraintName = getDefaultIndexName('foreign', relation.collection, relation.field);
|
|
156
158
|
const builder = table
|
|
157
159
|
.foreign(relation.field, constraintName)
|
|
@@ -198,10 +200,12 @@ export class RelationsService {
|
|
|
198
200
|
if (this.accountability && this.accountability.admin !== true) {
|
|
199
201
|
throw new ForbiddenError();
|
|
200
202
|
}
|
|
201
|
-
|
|
203
|
+
const collectionSchema = this.schema.collections[collection];
|
|
204
|
+
if (!collectionSchema) {
|
|
202
205
|
throw new InvalidPayloadError({ reason: `Collection "${collection}" doesn't exist` });
|
|
203
206
|
}
|
|
204
|
-
|
|
207
|
+
const fieldSchema = collectionSchema.fields[field];
|
|
208
|
+
if (!fieldSchema) {
|
|
205
209
|
throw new InvalidPayloadError({ reason: `Field "${field}" doesn't exist in collection "${collection}"` });
|
|
206
210
|
}
|
|
207
211
|
const existingRelation = this.schema.relations.find((existingRelation) => existingRelation.collection === collection && existingRelation.field === field);
|
|
@@ -225,7 +229,7 @@ export class RelationsService {
|
|
|
225
229
|
constraintName = this.helpers.schema.constraintName(constraintName);
|
|
226
230
|
existingRelation.schema.constraint_name = constraintName;
|
|
227
231
|
}
|
|
228
|
-
this.alterType(table, relation);
|
|
232
|
+
this.alterType(table, relation, fieldSchema.nullable);
|
|
229
233
|
const builder = table
|
|
230
234
|
.foreign(field, constraintName || undefined)
|
|
231
235
|
.references(`${existingRelation.related_collection}.${this.schema.collections[existingRelation.related_collection].primary}`);
|
|
@@ -447,11 +451,16 @@ export class RelationsService {
|
|
|
447
451
|
*
|
|
448
452
|
* @TODO This is a bit of a hack, and might be better of abstracted elsewhere
|
|
449
453
|
*/
|
|
450
|
-
alterType(table, relation) {
|
|
454
|
+
alterType(table, relation, nullable) {
|
|
451
455
|
const m2oFieldDBType = this.schema.collections[relation.collection].fields[relation.field].dbType;
|
|
452
456
|
const relatedFieldDBType = this.schema.collections[relation.related_collection].fields[this.schema.collections[relation.related_collection].primary].dbType;
|
|
453
457
|
if (m2oFieldDBType !== relatedFieldDBType && m2oFieldDBType === 'int' && relatedFieldDBType === 'int unsigned') {
|
|
454
|
-
table.specificType(relation.field, 'int unsigned')
|
|
458
|
+
const alterField = table.specificType(relation.field, 'int unsigned');
|
|
459
|
+
// Maintains the non-nullable state
|
|
460
|
+
if (!nullable) {
|
|
461
|
+
alterField.notNullable();
|
|
462
|
+
}
|
|
463
|
+
alterField.alter();
|
|
455
464
|
}
|
|
456
465
|
}
|
|
457
466
|
}
|
package/dist/services/server.js
CHANGED
|
@@ -1,19 +1,20 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { useEnv } from '@directus/env';
|
|
2
|
+
import { toArray, toBoolean } from '@directus/utils';
|
|
3
|
+
import { version } from 'directus/version';
|
|
2
4
|
import { merge } from 'lodash-es';
|
|
3
5
|
import { Readable } from 'node:stream';
|
|
4
6
|
import { performance } from 'perf_hooks';
|
|
5
7
|
import { getCache } from '../cache.js';
|
|
6
8
|
import getDatabase, { hasDatabaseConnection } from '../database/index.js';
|
|
7
|
-
import
|
|
8
|
-
import logger from '../logger.js';
|
|
9
|
+
import { useLogger } from '../logger.js';
|
|
9
10
|
import getMailer from '../mailer.js';
|
|
10
11
|
import { rateLimiterGlobal } from '../middleware/rate-limiter-global.js';
|
|
11
12
|
import { rateLimiter } from '../middleware/rate-limiter-ip.js';
|
|
12
13
|
import { SERVER_ONLINE } from '../server.js';
|
|
13
14
|
import { getStorage } from '../storage/index.js';
|
|
14
|
-
import { version } from '../utils/package.js';
|
|
15
|
-
import { toBoolean } from '../utils/to-boolean.js';
|
|
16
15
|
import { SettingsService } from './settings.js';
|
|
16
|
+
const env = useEnv();
|
|
17
|
+
const logger = useLogger();
|
|
17
18
|
export class ServerService {
|
|
18
19
|
knex;
|
|
19
20
|
accountability;
|
|
@@ -70,8 +71,6 @@ export class ServerService {
|
|
|
70
71
|
default: env['QUERY_LIMIT_DEFAULT'],
|
|
71
72
|
max: Number.isFinite(env['QUERY_LIMIT_MAX']) ? env['QUERY_LIMIT_MAX'] : -1,
|
|
72
73
|
};
|
|
73
|
-
}
|
|
74
|
-
if (this.accountability?.user) {
|
|
75
74
|
if (toBoolean(env['WEBSOCKETS_ENABLED'])) {
|
|
76
75
|
info['websocket'] = {};
|
|
77
76
|
info['websocket'].rest = toBoolean(env['WEBSOCKETS_REST_ENABLED'])
|
|
@@ -93,6 +92,7 @@ export class ServerService {
|
|
|
93
92
|
else {
|
|
94
93
|
info['websocket'] = false;
|
|
95
94
|
}
|
|
95
|
+
info['version'] = version;
|
|
96
96
|
}
|
|
97
97
|
return info;
|
|
98
98
|
}
|
package/dist/services/shares.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
+
import { useEnv } from '@directus/env';
|
|
2
|
+
import { ForbiddenError, InvalidCredentialsError } from '@directus/errors';
|
|
1
3
|
import argon2 from 'argon2';
|
|
2
4
|
import jwt from 'jsonwebtoken';
|
|
3
|
-
import env from '../env.js';
|
|
4
|
-
import { ForbiddenError, InvalidCredentialsError } from '@directus/errors';
|
|
5
5
|
import { getMilliseconds } from '../utils/get-milliseconds.js';
|
|
6
6
|
import { md } from '../utils/md.js';
|
|
7
7
|
import { Url } from '../utils/url.js';
|
|
@@ -10,6 +10,7 @@ import { AuthorizationService } from './authorization.js';
|
|
|
10
10
|
import { ItemsService } from './items.js';
|
|
11
11
|
import { MailService } from './mail/index.js';
|
|
12
12
|
import { UsersService } from './users.js';
|
|
13
|
+
const env = useEnv();
|
|
13
14
|
export class SharesService extends ItemsService {
|
|
14
15
|
authorizationService;
|
|
15
16
|
constructor(options) {
|