@directus/api 15.0.0 → 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 +6 -4
- package/dist/auth/drivers/ldap.js +7 -4
- package/dist/auth/drivers/local.js +3 -2
- package/dist/auth/drivers/oauth2.js +9 -2
- package/dist/auth/drivers/openid.js +9 -2
- 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 +2 -1
- 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/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.js +9 -2
- 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/emitter.js +3 -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 +6 -4
- package/dist/extensions/lib/sandbox/register/call-reference.js +4 -2
- package/dist/extensions/lib/sandbox/sdk/generators/log.js +2 -1
- package/dist/extensions/lib/sync-extensions.js +6 -4
- package/dist/extensions/manager.js +43 -19
- package/dist/flows.js +13 -7
- package/dist/logger.d.ts +7 -7
- package/dist/logger.js +116 -92
- 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 +2 -1
- 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 -2
- package/dist/redis/index.js +3 -2
- package/dist/redis/{create-redis.js → lib/create-redis.js} +2 -2
- 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.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 +74 -39
- 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 +46 -3
- 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/relations.js +19 -10
- package/dist/services/server.js +5 -4
- package/dist/services/shares.js +3 -2
- package/dist/services/specifications.js +2 -1
- package/dist/services/users.js +20 -9
- 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/lib/get-report.js +1 -1
- package/dist/telemetry/lib/init-telemetry.js +2 -2
- package/dist/telemetry/lib/send-report.js +1 -1
- package/dist/telemetry/lib/track.js +2 -3
- package/dist/telemetry/utils/get-user-count.js +1 -1
- package/dist/types/assets.d.ts +2 -0
- package/dist/utils/apply-diff.js +2 -1
- package/dist/utils/apply-query.js +0 -11
- 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-config-from-env.js +2 -1
- package/dist/utils/get-default-value.js +4 -3
- package/dist/utils/get-ip-from-req.js +4 -2
- 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 +4 -4
- 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/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 +7 -3
- package/dist/utils/validate-storage.js +4 -2
- package/dist/webhooks.js +4 -3
- package/dist/websocket/controllers/base.js +12 -6
- package/dist/websocket/controllers/graphql.js +4 -2
- package/dist/websocket/controllers/hooks.js +3 -2
- package/dist/websocket/controllers/index.js +4 -2
- 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/package.json +57 -57
- 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 -14
- package/dist/env.js +0 -511
- package/dist/messenger.d.ts +0 -24
- package/dist/messenger.js +0 -64
- package/dist/utils/to-boolean.d.ts +0 -4
- package/dist/utils/to-boolean.js +0 -6
- /package/dist/redis/{create-redis.d.ts → lib/create-redis.d.ts} +0 -0
- /package/dist/redis/{use-redis.d.ts → lib/use-redis.d.ts} +0 -0
- /package/dist/redis/{use-redis.js → lib/use-redis.js} +0 -0
package/dist/app.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { useEnv } from '@directus/env';
|
|
1
2
|
import { InvalidPayloadError, ServiceUnavailableError } from '@directus/errors';
|
|
2
3
|
import { handlePressure } from '@directus/pressure';
|
|
3
4
|
import cookieParser from 'cookie-parser';
|
|
@@ -40,10 +41,9 @@ import versionsRouter from './controllers/versions.js';
|
|
|
40
41
|
import webhooksRouter from './controllers/webhooks.js';
|
|
41
42
|
import { isInstalled, validateDatabaseConnection, validateDatabaseExtensions, validateMigrations, } from './database/index.js';
|
|
42
43
|
import emitter from './emitter.js';
|
|
43
|
-
import env from './env.js';
|
|
44
44
|
import { getExtensionManager } from './extensions/index.js';
|
|
45
45
|
import { getFlowManager } from './flows.js';
|
|
46
|
-
import
|
|
46
|
+
import { createExpressLogger, useLogger } from './logger.js';
|
|
47
47
|
import authenticate from './middleware/authenticate.js';
|
|
48
48
|
import cache from './middleware/cache.js';
|
|
49
49
|
import { checkIP } from './middleware/check-ip.js';
|
|
@@ -55,14 +55,16 @@ import rateLimiterGlobal from './middleware/rate-limiter-global.js';
|
|
|
55
55
|
import rateLimiter from './middleware/rate-limiter-ip.js';
|
|
56
56
|
import sanitizeQuery from './middleware/sanitize-query.js';
|
|
57
57
|
import schema from './middleware/schema.js';
|
|
58
|
+
import { initTelemetry } from './telemetry/index.js';
|
|
58
59
|
import { getConfigFromEnv } from './utils/get-config-from-env.js';
|
|
59
60
|
import { Url } from './utils/url.js';
|
|
60
61
|
import { validateEnv } from './utils/validate-env.js';
|
|
61
62
|
import { validateStorage } from './utils/validate-storage.js';
|
|
62
63
|
import { init as initWebhooks } from './webhooks.js';
|
|
63
|
-
import { initTelemetry } from './telemetry/index.js';
|
|
64
64
|
const require = createRequire(import.meta.url);
|
|
65
65
|
export default async function createApp() {
|
|
66
|
+
const env = useEnv();
|
|
67
|
+
const logger = useLogger();
|
|
66
68
|
const helmet = await import('helmet');
|
|
67
69
|
validateEnv(['KEY', 'SECRET']);
|
|
68
70
|
if (!new Url(env['PUBLIC_URL']).isAbsolute()) {
|
|
@@ -124,7 +126,7 @@ export default async function createApp() {
|
|
|
124
126
|
}
|
|
125
127
|
await emitter.emitInit('app.before', { app });
|
|
126
128
|
await emitter.emitInit('middlewares.before', { app });
|
|
127
|
-
app.use(
|
|
129
|
+
app.use(createExpressLogger());
|
|
128
130
|
app.use((_req, res, next) => {
|
|
129
131
|
res.setHeader('X-Powered-By', 'Directus');
|
|
130
132
|
next();
|
|
@@ -1,12 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { useEnv } from '@directus/env';
|
|
2
|
+
import { ErrorCode, InvalidCredentialsError, InvalidPayloadError, InvalidProviderConfigError, InvalidProviderError, ServiceUnavailableError, UnexpectedResponseError, isDirectusError, } from '@directus/errors';
|
|
2
3
|
import { Router } from 'express';
|
|
3
4
|
import Joi from 'joi';
|
|
4
5
|
import ldap from 'ldapjs';
|
|
5
6
|
import getDatabase from '../../database/index.js';
|
|
6
7
|
import emitter from '../../emitter.js';
|
|
7
|
-
import
|
|
8
|
-
import { ErrorCode, InvalidCredentialsError, InvalidPayloadError, InvalidProviderError, InvalidProviderConfigError, ServiceUnavailableError, UnexpectedResponseError, } from '@directus/errors';
|
|
9
|
-
import logger from '../../logger.js';
|
|
8
|
+
import { useLogger } from '../../logger.js';
|
|
10
9
|
import { respond } from '../../middleware/respond.js';
|
|
11
10
|
import { AuthenticationService } from '../../services/authentication.js';
|
|
12
11
|
import { UsersService } from '../../services/users.js';
|
|
@@ -24,6 +23,7 @@ export class LDAPAuthDriver extends AuthDriver {
|
|
|
24
23
|
config;
|
|
25
24
|
constructor(options, config) {
|
|
26
25
|
super(options, config);
|
|
26
|
+
const logger = useLogger();
|
|
27
27
|
const { bindDn, bindPassword, userDn, provider, clientUrl } = config;
|
|
28
28
|
if (bindDn === undefined ||
|
|
29
29
|
bindPassword === undefined ||
|
|
@@ -42,6 +42,7 @@ export class LDAPAuthDriver extends AuthDriver {
|
|
|
42
42
|
this.config = config;
|
|
43
43
|
}
|
|
44
44
|
async validateBindClient() {
|
|
45
|
+
const logger = useLogger();
|
|
45
46
|
const { bindDn, bindPassword, provider } = this.config;
|
|
46
47
|
return new Promise((resolve, reject) => {
|
|
47
48
|
// Healthcheck bind user
|
|
@@ -168,6 +169,7 @@ export class LDAPAuthDriver extends AuthDriver {
|
|
|
168
169
|
if (!payload['identifier']) {
|
|
169
170
|
throw new InvalidCredentialsError();
|
|
170
171
|
}
|
|
172
|
+
const logger = useLogger();
|
|
171
173
|
await this.validateBindClient();
|
|
172
174
|
const { userDn, userScope, userAttribute, groupDn, groupScope, groupAttribute, defaultRoleId } = this.config;
|
|
173
175
|
const userInfo = await this.fetchUserInfo(userDn, new ldap.EqualityFilter({
|
|
@@ -292,6 +294,7 @@ export function createLDAPAuthRouter(provider) {
|
|
|
292
294
|
otp: Joi.string(),
|
|
293
295
|
}).unknown();
|
|
294
296
|
router.post('/', asyncHandler(async (req, res, next) => {
|
|
297
|
+
const env = useEnv();
|
|
295
298
|
const accountability = {
|
|
296
299
|
ip: getIPFromReq(req),
|
|
297
300
|
role: null,
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
+
import { InvalidCredentialsError, InvalidPayloadError } from '@directus/errors';
|
|
1
2
|
import argon2 from 'argon2';
|
|
2
3
|
import { Router } from 'express';
|
|
3
4
|
import Joi from 'joi';
|
|
4
5
|
import { performance } from 'perf_hooks';
|
|
5
6
|
import { COOKIE_OPTIONS } from '../../constants.js';
|
|
6
|
-
import
|
|
7
|
-
import { InvalidCredentialsError, InvalidPayloadError } from '@directus/errors';
|
|
7
|
+
import { useEnv } from '@directus/env';
|
|
8
8
|
import { respond } from '../../middleware/respond.js';
|
|
9
9
|
import { AuthenticationService } from '../../services/authentication.js';
|
|
10
10
|
import asyncHandler from '../../utils/async-handler.js';
|
|
@@ -36,6 +36,7 @@ export class LocalAuthDriver extends AuthDriver {
|
|
|
36
36
|
}
|
|
37
37
|
}
|
|
38
38
|
export function createLocalAuthRouter(provider) {
|
|
39
|
+
const env = useEnv();
|
|
39
40
|
const router = Router();
|
|
40
41
|
const userLoginSchema = Joi.object({
|
|
41
42
|
email: Joi.string().email().required(),
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { useEnv } from '@directus/env';
|
|
1
2
|
import { ErrorCode, InvalidCredentialsError, InvalidProviderConfigError, InvalidProviderError, InvalidTokenError, isDirectusError, ServiceUnavailableError, } from '@directus/errors';
|
|
2
3
|
import { parseJSON } from '@directus/utils';
|
|
3
4
|
import express, { Router } from 'express';
|
|
@@ -7,8 +8,7 @@ import { errors, generators, Issuer } from 'openid-client';
|
|
|
7
8
|
import { getAuthProvider } from '../../auth.js';
|
|
8
9
|
import getDatabase from '../../database/index.js';
|
|
9
10
|
import emitter from '../../emitter.js';
|
|
10
|
-
import
|
|
11
|
-
import logger from '../../logger.js';
|
|
11
|
+
import { useLogger } from '../../logger.js';
|
|
12
12
|
import { respond } from '../../middleware/respond.js';
|
|
13
13
|
import { AuthenticationService } from '../../services/authentication.js';
|
|
14
14
|
import { UsersService } from '../../services/users.js';
|
|
@@ -25,6 +25,8 @@ export class OAuth2AuthDriver extends LocalAuthDriver {
|
|
|
25
25
|
config;
|
|
26
26
|
constructor(options, config) {
|
|
27
27
|
super(options, config);
|
|
28
|
+
const env = useEnv();
|
|
29
|
+
const logger = useLogger();
|
|
28
30
|
const { authorizeUrl, accessUrl, profileUrl, clientId, clientSecret, ...additionalConfig } = config;
|
|
29
31
|
if (!authorizeUrl || !accessUrl || !profileUrl || !clientId || !clientSecret || !additionalConfig['provider']) {
|
|
30
32
|
logger.error('Invalid provider config');
|
|
@@ -81,6 +83,7 @@ export class OAuth2AuthDriver extends LocalAuthDriver {
|
|
|
81
83
|
return user?.id;
|
|
82
84
|
}
|
|
83
85
|
async getUserID(payload) {
|
|
86
|
+
const logger = useLogger();
|
|
84
87
|
if (!payload['code'] || !payload['codeVerifier'] || !payload['state']) {
|
|
85
88
|
logger.warn('[OAuth2] No code, codeVerifier or state in payload');
|
|
86
89
|
throw new InvalidCredentialsError();
|
|
@@ -160,6 +163,7 @@ export class OAuth2AuthDriver extends LocalAuthDriver {
|
|
|
160
163
|
return this.refresh(user);
|
|
161
164
|
}
|
|
162
165
|
async refresh(user) {
|
|
166
|
+
const logger = useLogger();
|
|
163
167
|
let authData = user.auth_data;
|
|
164
168
|
if (typeof authData === 'string') {
|
|
165
169
|
try {
|
|
@@ -186,6 +190,7 @@ export class OAuth2AuthDriver extends LocalAuthDriver {
|
|
|
186
190
|
}
|
|
187
191
|
}
|
|
188
192
|
const handleError = (e) => {
|
|
193
|
+
const logger = useLogger();
|
|
189
194
|
if (e instanceof errors.OPError) {
|
|
190
195
|
if (e.error === 'invalid_grant') {
|
|
191
196
|
// Invalid token
|
|
@@ -209,6 +214,7 @@ const handleError = (e) => {
|
|
|
209
214
|
};
|
|
210
215
|
export function createOAuth2AuthRouter(providerName) {
|
|
211
216
|
const router = Router();
|
|
217
|
+
const env = useEnv();
|
|
212
218
|
router.get('/', (req, res) => {
|
|
213
219
|
const provider = getAuthProvider(providerName);
|
|
214
220
|
const codeVerifier = provider.generateCodeVerifier();
|
|
@@ -227,6 +233,7 @@ export function createOAuth2AuthRouter(providerName) {
|
|
|
227
233
|
res.redirect(303, `./callback?${new URLSearchParams(req.body)}`);
|
|
228
234
|
}, respond);
|
|
229
235
|
router.get('/callback', asyncHandler(async (req, res, next) => {
|
|
236
|
+
const logger = useLogger();
|
|
230
237
|
let tokenData;
|
|
231
238
|
try {
|
|
232
239
|
tokenData = jwt.verify(req.cookies[`oauth2.${providerName}`], env['SECRET'], {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { useEnv } from '@directus/env';
|
|
1
2
|
import { ErrorCode, InvalidCredentialsError, InvalidProviderConfigError, InvalidProviderError, InvalidTokenError, isDirectusError, ServiceUnavailableError, } from '@directus/errors';
|
|
2
3
|
import { parseJSON } from '@directus/utils';
|
|
3
4
|
import express, { Router } from 'express';
|
|
@@ -7,8 +8,7 @@ import { errors, generators, Issuer } from 'openid-client';
|
|
|
7
8
|
import { getAuthProvider } from '../../auth.js';
|
|
8
9
|
import getDatabase from '../../database/index.js';
|
|
9
10
|
import emitter from '../../emitter.js';
|
|
10
|
-
import
|
|
11
|
-
import logger from '../../logger.js';
|
|
11
|
+
import { useLogger } from '../../logger.js';
|
|
12
12
|
import { respond } from '../../middleware/respond.js';
|
|
13
13
|
import { AuthenticationService } from '../../services/authentication.js';
|
|
14
14
|
import { UsersService } from '../../services/users.js';
|
|
@@ -25,6 +25,8 @@ export class OpenIDAuthDriver extends LocalAuthDriver {
|
|
|
25
25
|
config;
|
|
26
26
|
constructor(options, config) {
|
|
27
27
|
super(options, config);
|
|
28
|
+
const env = useEnv();
|
|
29
|
+
const logger = useLogger();
|
|
28
30
|
const { issuerUrl, clientId, clientSecret, ...additionalConfig } = config;
|
|
29
31
|
if (!issuerUrl || !clientId || !clientSecret || !additionalConfig['provider']) {
|
|
30
32
|
logger.error('Invalid provider config');
|
|
@@ -93,6 +95,7 @@ export class OpenIDAuthDriver extends LocalAuthDriver {
|
|
|
93
95
|
return user?.id;
|
|
94
96
|
}
|
|
95
97
|
async getUserID(payload) {
|
|
98
|
+
const logger = useLogger();
|
|
96
99
|
if (!payload['code'] || !payload['codeVerifier'] || !payload['state']) {
|
|
97
100
|
logger.warn('[OpenID] No code, codeVerifier or state in payload');
|
|
98
101
|
throw new InvalidCredentialsError();
|
|
@@ -180,6 +183,7 @@ export class OpenIDAuthDriver extends LocalAuthDriver {
|
|
|
180
183
|
return this.refresh(user);
|
|
181
184
|
}
|
|
182
185
|
async refresh(user) {
|
|
186
|
+
const logger = useLogger();
|
|
183
187
|
let authData = user.auth_data;
|
|
184
188
|
if (typeof authData === 'string') {
|
|
185
189
|
try {
|
|
@@ -207,6 +211,7 @@ export class OpenIDAuthDriver extends LocalAuthDriver {
|
|
|
207
211
|
}
|
|
208
212
|
}
|
|
209
213
|
const handleError = (e) => {
|
|
214
|
+
const logger = useLogger();
|
|
210
215
|
if (e instanceof errors.OPError) {
|
|
211
216
|
if (e.error === 'invalid_grant') {
|
|
212
217
|
// Invalid token
|
|
@@ -229,6 +234,7 @@ const handleError = (e) => {
|
|
|
229
234
|
return e;
|
|
230
235
|
};
|
|
231
236
|
export function createOpenIDAuthRouter(providerName) {
|
|
237
|
+
const env = useEnv();
|
|
232
238
|
const router = Router();
|
|
233
239
|
router.get('/', asyncHandler(async (req, res) => {
|
|
234
240
|
const provider = getAuthProvider(providerName);
|
|
@@ -248,6 +254,7 @@ export function createOpenIDAuthRouter(providerName) {
|
|
|
248
254
|
res.redirect(303, `./callback?${new URLSearchParams(req.body)}`);
|
|
249
255
|
}, respond);
|
|
250
256
|
router.get('/callback', asyncHandler(async (req, res, next) => {
|
|
257
|
+
const logger = useLogger();
|
|
251
258
|
let tokenData;
|
|
252
259
|
try {
|
|
253
260
|
tokenData = jwt.verify(req.cookies[`openid.${providerName}`], env['SECRET'], {
|
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
import * as validator from '@authenio/samlify-node-xmllint';
|
|
2
|
-
import {
|
|
2
|
+
import { useEnv } from '@directus/env';
|
|
3
|
+
import { ErrorCode, InvalidCredentialsError, InvalidProviderError, isDirectusError } from '@directus/errors';
|
|
3
4
|
import express, { Router } from 'express';
|
|
4
5
|
import * as samlify from 'samlify';
|
|
5
6
|
import { getAuthProvider } from '../../auth.js';
|
|
6
7
|
import { COOKIE_OPTIONS } from '../../constants.js';
|
|
7
8
|
import getDatabase from '../../database/index.js';
|
|
8
9
|
import emitter from '../../emitter.js';
|
|
9
|
-
import
|
|
10
|
-
import { ErrorCode, InvalidCredentialsError, InvalidProviderError } from '@directus/errors';
|
|
11
|
-
import logger from '../../logger.js';
|
|
10
|
+
import { useLogger } from '../../logger.js';
|
|
12
11
|
import { respond } from '../../middleware/respond.js';
|
|
13
12
|
import { AuthenticationService } from '../../services/authentication.js';
|
|
14
13
|
import { UsersService } from '../../services/users.js';
|
|
@@ -38,6 +37,7 @@ export class SAMLAuthDriver extends LocalAuthDriver {
|
|
|
38
37
|
return user?.id;
|
|
39
38
|
}
|
|
40
39
|
async getUserID(payload) {
|
|
40
|
+
const logger = useLogger();
|
|
41
41
|
const { provider, emailKey, identifierKey, givenNameKey, familyNameKey, allowPublicRegistration } = this.config;
|
|
42
42
|
const email = payload[emailKey ?? 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress'];
|
|
43
43
|
const identifier = payload[identifierKey ?? 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier'];
|
|
@@ -79,6 +79,7 @@ export class SAMLAuthDriver extends LocalAuthDriver {
|
|
|
79
79
|
}
|
|
80
80
|
export function createSAMLAuthRouter(providerName) {
|
|
81
81
|
const router = Router();
|
|
82
|
+
const env = useEnv();
|
|
82
83
|
router.get('/metadata', asyncHandler(async (_req, res) => {
|
|
83
84
|
const { sp } = getAuthProvider(providerName);
|
|
84
85
|
return res.header('Content-Type', 'text/xml').send(sp.getMetadata());
|
|
@@ -106,6 +107,7 @@ export function createSAMLAuthRouter(providerName) {
|
|
|
106
107
|
return res.redirect(context);
|
|
107
108
|
}));
|
|
108
109
|
router.post('/acs', express.urlencoded({ extended: false }), asyncHandler(async (req, res, next) => {
|
|
110
|
+
const logger = useLogger();
|
|
109
111
|
const relayState = req.body?.RelayState;
|
|
110
112
|
try {
|
|
111
113
|
const { sp, idp } = getAuthProvider(providerName);
|
package/dist/auth.js
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
|
+
import { useEnv } from '@directus/env';
|
|
2
|
+
import { InvalidProviderConfigError } from '@directus/errors';
|
|
1
3
|
import { toArray } from '@directus/utils';
|
|
2
4
|
import { LDAPAuthDriver, LocalAuthDriver, OAuth2AuthDriver, OpenIDAuthDriver, SAMLAuthDriver, } from './auth/drivers/index.js';
|
|
3
5
|
import { DEFAULT_AUTH_PROVIDER } from './constants.js';
|
|
4
6
|
import getDatabase from './database/index.js';
|
|
5
|
-
import
|
|
6
|
-
import { InvalidProviderConfigError } from '@directus/errors';
|
|
7
|
-
import logger from './logger.js';
|
|
7
|
+
import { useLogger } from './logger.js';
|
|
8
8
|
import { getConfigFromEnv } from './utils/get-config-from-env.js';
|
|
9
9
|
import { getSchema } from './utils/get-schema.js';
|
|
10
|
-
const providerNames = toArray(env['AUTH_PROVIDERS']);
|
|
11
10
|
const providers = new Map();
|
|
12
11
|
export function getAuthProvider(provider) {
|
|
12
|
+
const logger = useLogger();
|
|
13
13
|
if (!providers.has(provider)) {
|
|
14
14
|
logger.error('Auth provider not configured');
|
|
15
15
|
throw new InvalidProviderConfigError({ provider });
|
|
@@ -17,7 +17,10 @@ export function getAuthProvider(provider) {
|
|
|
17
17
|
return providers.get(provider);
|
|
18
18
|
}
|
|
19
19
|
export async function registerAuthProviders() {
|
|
20
|
+
const env = useEnv();
|
|
21
|
+
const logger = useLogger();
|
|
20
22
|
const options = { knex: getDatabase(), schema: await getSchema() };
|
|
23
|
+
const providerNames = toArray(env['AUTH_PROVIDERS']);
|
|
21
24
|
// Register default provider if not disabled
|
|
22
25
|
if (!env['AUTH_DISABLE_DEFAULT']) {
|
|
23
26
|
const defaultProvider = getProviderInstance('local', options);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { useBus } from './lib/use-bus.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { useBus } from './lib/use-bus.js';
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { type Bus } from '@directus/memory';
|
|
2
|
+
export declare const _cache: {
|
|
3
|
+
bus: Bus | undefined;
|
|
4
|
+
};
|
|
5
|
+
/**
|
|
6
|
+
* Returns globally shared message bus. If Redis is available, will use a redis-driven pub/sub bus.
|
|
7
|
+
* Otherwise will default to a local-only bus.
|
|
8
|
+
*/
|
|
9
|
+
export declare const useBus: () => Bus;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { createBus } from '@directus/memory';
|
|
2
|
+
import { redisConfigAvailable, useRedis } from '../../redis/index.js';
|
|
3
|
+
export const _cache = {
|
|
4
|
+
bus: undefined,
|
|
5
|
+
};
|
|
6
|
+
/**
|
|
7
|
+
* Returns globally shared message bus. If Redis is available, will use a redis-driven pub/sub bus.
|
|
8
|
+
* Otherwise will default to a local-only bus.
|
|
9
|
+
*/
|
|
10
|
+
export const useBus = () => {
|
|
11
|
+
if (_cache.bus) {
|
|
12
|
+
return _cache.bus;
|
|
13
|
+
}
|
|
14
|
+
if (redisConfigAvailable()) {
|
|
15
|
+
_cache.bus = createBus({ type: 'redis', redis: useRedis(), namespace: 'directus:bus' });
|
|
16
|
+
}
|
|
17
|
+
else {
|
|
18
|
+
_cache.bus = createBus({ type: 'local' });
|
|
19
|
+
}
|
|
20
|
+
return _cache.bus;
|
|
21
|
+
};
|
package/dist/cache.js
CHANGED
|
@@ -1,13 +1,16 @@
|
|
|
1
|
+
import { useEnv } from '@directus/env';
|
|
1
2
|
import { getSimpleHash } from '@directus/utils';
|
|
2
3
|
import Keyv from 'keyv';
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
import {
|
|
4
|
+
import { useBus } from './bus/index.js';
|
|
5
|
+
import { useLogger } from './logger.js';
|
|
6
|
+
import { redisConfigAvailable } from './redis/index.js';
|
|
6
7
|
import { compress, decompress } from './utils/compress.js';
|
|
7
8
|
import { getConfigFromEnv } from './utils/get-config-from-env.js';
|
|
8
9
|
import { getMilliseconds } from './utils/get-milliseconds.js';
|
|
9
10
|
import { validateEnv } from './utils/validate-env.js';
|
|
10
11
|
import { createRequire } from 'node:module';
|
|
12
|
+
const logger = useLogger();
|
|
13
|
+
const env = useEnv();
|
|
11
14
|
const require = createRequire(import.meta.url);
|
|
12
15
|
let cache = null;
|
|
13
16
|
let systemCache = null;
|
|
@@ -15,11 +18,8 @@ let localSchemaCache = null;
|
|
|
15
18
|
let sharedSchemaCache = null;
|
|
16
19
|
let lockCache = null;
|
|
17
20
|
let messengerSubscribed = false;
|
|
18
|
-
const messenger =
|
|
19
|
-
if (env['
|
|
20
|
-
env['CACHE_STORE'] === 'memory' &&
|
|
21
|
-
env['CACHE_AUTO_PURGE'] &&
|
|
22
|
-
!messengerSubscribed) {
|
|
21
|
+
const messenger = useBus();
|
|
22
|
+
if (redisConfigAvailable() && env['CACHE_STORE'] === 'memory' && env['CACHE_AUTO_PURGE'] && !messengerSubscribed) {
|
|
23
23
|
messengerSubscribed = true;
|
|
24
24
|
messenger.subscribe('schemaChanged', async (opts) => {
|
|
25
25
|
if (cache && opts?.['autoPurgeCache'] !== false) {
|
|
@@ -122,7 +122,7 @@ function getConfig(store = 'memory', ttl, namespaceSuffix = '') {
|
|
|
122
122
|
};
|
|
123
123
|
if (store === 'redis') {
|
|
124
124
|
const KeyvRedis = require('@keyv/redis');
|
|
125
|
-
config.store = new KeyvRedis(env['REDIS'] || getConfigFromEnv('REDIS'));
|
|
125
|
+
config.store = new KeyvRedis(env['REDIS'] || getConfigFromEnv('REDIS'), { useRedisSets: false });
|
|
126
126
|
}
|
|
127
127
|
return config;
|
|
128
128
|
}
|
|
@@ -1,15 +1,17 @@
|
|
|
1
|
+
import { useEnv } from '@directus/env';
|
|
1
2
|
import getDatabase, { hasDatabaseConnection, isInstalled, validateDatabaseConnection, } from '../../../database/index.js';
|
|
2
3
|
import runMigrations from '../../../database/migrations/run.js';
|
|
3
4
|
import installDatabase from '../../../database/seeds/run.js';
|
|
4
|
-
import
|
|
5
|
-
import logger from '../../../logger.js';
|
|
5
|
+
import { useLogger } from '../../../logger.js';
|
|
6
6
|
import { RolesService } from '../../../services/roles.js';
|
|
7
7
|
import { SettingsService } from '../../../services/settings.js';
|
|
8
8
|
import { UsersService } from '../../../services/users.js';
|
|
9
9
|
import { getSchema } from '../../../utils/get-schema.js';
|
|
10
10
|
import { defaultAdminRole, defaultAdminUser } from '../../utils/defaults.js';
|
|
11
11
|
export default async function bootstrap({ skipAdminInit }) {
|
|
12
|
+
const logger = useLogger();
|
|
12
13
|
logger.info('Initializing bootstrap...');
|
|
14
|
+
const env = useEnv();
|
|
13
15
|
const database = getDatabase();
|
|
14
16
|
await waitForDatabase(database);
|
|
15
17
|
if ((await isInstalled()) === false) {
|
|
@@ -52,6 +54,8 @@ async function waitForDatabase(database) {
|
|
|
52
54
|
return database;
|
|
53
55
|
}
|
|
54
56
|
async function createDefaultAdmin(schema) {
|
|
57
|
+
const logger = useLogger();
|
|
58
|
+
const env = useEnv();
|
|
55
59
|
const { nanoid } = await import('nanoid');
|
|
56
60
|
logger.info('Setting up first admin role...');
|
|
57
61
|
const rolesService = new RolesService({ schema });
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import getDatabase from '../../../database/index.js';
|
|
2
|
-
import
|
|
2
|
+
import { useLogger } from '../../../logger.js';
|
|
3
3
|
export default async function count(collection) {
|
|
4
4
|
const database = getDatabase();
|
|
5
|
+
const logger = useLogger();
|
|
5
6
|
if (!collection) {
|
|
6
7
|
logger.error('Collection is required');
|
|
7
8
|
process.exit(1);
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import installSeeds from '../../../database/seeds/run.js';
|
|
2
2
|
import getDatabase from '../../../database/index.js';
|
|
3
|
-
import
|
|
3
|
+
import { useLogger } from '../../../logger.js';
|
|
4
4
|
export default async function start() {
|
|
5
5
|
const database = getDatabase();
|
|
6
|
+
const logger = useLogger();
|
|
6
7
|
try {
|
|
7
8
|
await installSeeds(database);
|
|
8
9
|
database.destroy();
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import run from '../../../database/migrations/run.js';
|
|
2
2
|
import getDatabase from '../../../database/index.js';
|
|
3
|
-
import
|
|
3
|
+
import { useLogger } from '../../../logger.js';
|
|
4
4
|
export default async function migrate(direction) {
|
|
5
5
|
const database = getDatabase();
|
|
6
|
+
const logger = useLogger();
|
|
6
7
|
try {
|
|
7
8
|
logger.info('Running migrations...');
|
|
8
9
|
await run(database, direction);
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { getSchema } from '../../../utils/get-schema.js';
|
|
2
2
|
import { RolesService } from '../../../services/roles.js';
|
|
3
3
|
import getDatabase from '../../../database/index.js';
|
|
4
|
-
import
|
|
4
|
+
import { useLogger } from '../../../logger.js';
|
|
5
5
|
export default async function rolesCreate({ role: name, admin }) {
|
|
6
6
|
const database = getDatabase();
|
|
7
|
+
const logger = useLogger();
|
|
7
8
|
if (!name) {
|
|
8
9
|
logger.error('Name is required');
|
|
9
10
|
process.exit(1);
|
|
@@ -5,13 +5,14 @@ import inquirer from 'inquirer';
|
|
|
5
5
|
import { load as loadYaml } from 'js-yaml';
|
|
6
6
|
import path from 'path';
|
|
7
7
|
import getDatabase, { isInstalled, validateDatabaseConnection } from '../../../database/index.js';
|
|
8
|
-
import
|
|
8
|
+
import { useLogger } from '../../../logger.js';
|
|
9
9
|
import { DiffKind } from '../../../types/index.js';
|
|
10
10
|
import { isNestedMetaUpdate } from '../../../utils/apply-diff.js';
|
|
11
11
|
import { applySnapshot } from '../../../utils/apply-snapshot.js';
|
|
12
12
|
import { getSnapshotDiff } from '../../../utils/get-snapshot-diff.js';
|
|
13
13
|
import { getSnapshot } from '../../../utils/get-snapshot.js';
|
|
14
14
|
export async function apply(snapshotPath, options) {
|
|
15
|
+
const logger = useLogger();
|
|
15
16
|
const filename = path.resolve(process.cwd(), snapshotPath);
|
|
16
17
|
const database = getDatabase();
|
|
17
18
|
await validateDatabaseConnection(database);
|
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
import
|
|
2
|
-
import logger from '../../../logger.js';
|
|
3
|
-
import { getSnapshot } from '../../../utils/get-snapshot.js';
|
|
4
|
-
import { constants as fsConstants, promises as fs } from 'fs';
|
|
5
|
-
import path from 'path';
|
|
1
|
+
import { promises as fs, constants as fsConstants } from 'fs';
|
|
6
2
|
import inquirer from 'inquirer';
|
|
7
3
|
import { dump as toYaml } from 'js-yaml';
|
|
4
|
+
import path from 'path';
|
|
5
|
+
import getDatabase from '../../../database/index.js';
|
|
6
|
+
import { useLogger } from '../../../logger.js';
|
|
7
|
+
import { getSnapshot } from '../../../utils/get-snapshot.js';
|
|
8
8
|
export async function snapshot(snapshotPath, options) {
|
|
9
9
|
const database = getDatabase();
|
|
10
|
+
const logger = useLogger();
|
|
10
11
|
try {
|
|
11
12
|
const snapshot = await getSnapshot({ database });
|
|
12
13
|
let snapshotString;
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import { getSchema } from '../../../utils/get-schema.js';
|
|
2
|
-
import { UsersService } from '../../../services/users.js';
|
|
3
1
|
import getDatabase from '../../../database/index.js';
|
|
4
|
-
import
|
|
2
|
+
import { useLogger } from '../../../logger.js';
|
|
3
|
+
import { UsersService } from '../../../services/users.js';
|
|
4
|
+
import { getSchema } from '../../../utils/get-schema.js';
|
|
5
5
|
export default async function usersCreate({ email, password, role, }) {
|
|
6
6
|
const database = getDatabase();
|
|
7
|
+
const logger = useLogger();
|
|
7
8
|
if (!email || !password || !role) {
|
|
8
9
|
logger.error('Email, password, role are required');
|
|
9
10
|
process.exit(1);
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import { getSchema } from '../../../utils/get-schema.js';
|
|
2
|
-
import { generateHash } from '../../../utils/generate-hash.js';
|
|
3
|
-
import { UsersService } from '../../../services/users.js';
|
|
4
1
|
import getDatabase from '../../../database/index.js';
|
|
5
|
-
import
|
|
2
|
+
import { useLogger } from '../../../logger.js';
|
|
3
|
+
import { UsersService } from '../../../services/users.js';
|
|
4
|
+
import { generateHash } from '../../../utils/generate-hash.js';
|
|
5
|
+
import { getSchema } from '../../../utils/get-schema.js';
|
|
6
6
|
export default async function usersPasswd({ email, password }) {
|
|
7
7
|
const database = getDatabase();
|
|
8
|
+
const logger = useLogger();
|
|
8
9
|
if (!email || !password) {
|
|
9
10
|
logger.error('Email and password are required');
|
|
10
11
|
process.exit(1);
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
+
import { useEnv } from '@directus/env';
|
|
1
2
|
import { isInstalled, validateMigrations } from '../database/index.js';
|
|
2
|
-
import env from '../env.js';
|
|
3
3
|
import { getExtensionManager } from '../extensions/index.js';
|
|
4
|
-
import
|
|
4
|
+
import { useLogger } from '../logger.js';
|
|
5
5
|
export const loadExtensions = async () => {
|
|
6
|
+
const env = useEnv();
|
|
7
|
+
const logger = useLogger();
|
|
6
8
|
if (!('DB_CLIENT' in env))
|
|
7
9
|
return;
|
|
8
10
|
const installed = await isInstalled();
|
|
@@ -187,7 +187,7 @@ STORAGE_LOCAL_ROOT="./uploads"
|
|
|
187
187
|
|
|
188
188
|
## A comma-separated list of metadata keys to collect during file upload. Use * for all
|
|
189
189
|
# Extracting all metadata might cause memory issues when the file has an unusually large set of metadata
|
|
190
|
-
# [ifd0.Make,ifd0.Model,exif.FNumber,exif.ExposureTime,exif.FocalLength,exif.
|
|
190
|
+
# [ifd0.Make,ifd0.Model,exif.FNumber,exif.ExposureTime,exif.FocalLength,exif.ISOSpeedRatings]
|
|
191
191
|
# FILE_METADATA_ALLOW_LIST=
|
|
192
192
|
|
|
193
193
|
####################################################################################################
|
package/dist/constants.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { CookieOptions } from 'express';
|
|
2
2
|
import type { TransformationParams } from './types/index.js';
|
|
3
3
|
export declare const SYSTEM_ASSET_ALLOW_LIST: TransformationParams[];
|
|
4
|
-
export declare const ASSET_TRANSFORM_QUERY_KEYS:
|
|
4
|
+
export declare const ASSET_TRANSFORM_QUERY_KEYS: readonly ["key", "transforms", "width", "height", "format", "fit", "quality", "withoutEnlargement", "focal_point_x", "focal_point_y"];
|
|
5
5
|
export declare const FILTER_VARIABLES: string[];
|
|
6
6
|
export declare const ALIAS_TYPES: string[];
|
|
7
7
|
export declare const DEFAULT_AUTH_PROVIDER = "default";
|
package/dist/constants.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { useEnv } from '@directus/env';
|
|
2
2
|
import { getMilliseconds } from './utils/get-milliseconds.js';
|
|
3
|
+
const env = useEnv();
|
|
3
4
|
export const SYSTEM_ASSET_ALLOW_LIST = [
|
|
4
5
|
{
|
|
5
6
|
key: 'system-small-cover',
|
|
@@ -41,6 +42,8 @@ export const ASSET_TRANSFORM_QUERY_KEYS = [
|
|
|
41
42
|
'fit',
|
|
42
43
|
'quality',
|
|
43
44
|
'withoutEnlargement',
|
|
45
|
+
'focal_point_x',
|
|
46
|
+
'focal_point_y',
|
|
44
47
|
];
|
|
45
48
|
export const FILTER_VARIABLES = ['$NOW', '$CURRENT_USER', '$CURRENT_ROLE'];
|
|
46
49
|
export const ALIAS_TYPES = ['alias', 'o2m', 'm2m', 'm2a', 'o2a', 'files', 'translations'];
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
+
import { useEnv } from '@directus/env';
|
|
2
|
+
import { InvalidQueryError, RangeNotSatisfiableError } from '@directus/errors';
|
|
1
3
|
import { parseJSON } from '@directus/utils';
|
|
2
4
|
import contentDisposition from 'content-disposition';
|
|
3
5
|
import { Router } from 'express';
|
|
4
6
|
import { merge, pick } from 'lodash-es';
|
|
5
7
|
import { ASSET_TRANSFORM_QUERY_KEYS, SYSTEM_ASSET_ALLOW_LIST } from '../constants.js';
|
|
6
8
|
import getDatabase from '../database/index.js';
|
|
7
|
-
import
|
|
8
|
-
import { InvalidQueryError, RangeNotSatisfiableError } from '@directus/errors';
|
|
9
|
-
import logger from '../logger.js';
|
|
9
|
+
import { useLogger } from '../logger.js';
|
|
10
10
|
import useCollection from '../middleware/use-collection.js';
|
|
11
11
|
import { AssetsService } from '../services/assets.js';
|
|
12
12
|
import { PayloadService } from '../services/payload.js';
|
|
@@ -16,6 +16,7 @@ import { getCacheControlHeader } from '../utils/get-cache-headers.js';
|
|
|
16
16
|
import { getConfigFromEnv } from '../utils/get-config-from-env.js';
|
|
17
17
|
import { getMilliseconds } from '../utils/get-milliseconds.js';
|
|
18
18
|
const router = Router();
|
|
19
|
+
const env = useEnv();
|
|
19
20
|
router.use(useCollection('directus_files'));
|
|
20
21
|
router.get('/:pk/:filename?',
|
|
21
22
|
// Validate query params
|
|
@@ -109,6 +110,7 @@ asyncHandler(async (req, res, next) => {
|
|
|
109
110
|
}),
|
|
110
111
|
// Return file
|
|
111
112
|
asyncHandler(async (req, res) => {
|
|
113
|
+
const logger = useLogger();
|
|
112
114
|
const id = req.params['pk'].substring(0, 36);
|
|
113
115
|
const service = new AssetsService({
|
|
114
116
|
accountability: req.accountability,
|