directus 9.4.2 → 9.5.2
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/README.md +1 -1
- package/dist/app.js +9 -0
- package/dist/auth/auth.d.ts +2 -1
- package/dist/auth/drivers/oauth2.js +10 -20
- package/dist/auth/drivers/openid.js +18 -8
- package/dist/cli/commands/init/index.js +8 -0
- package/dist/cli/commands/init/questions.d.ts +3 -0
- package/dist/cli/commands/init/questions.js +2 -0
- package/dist/cli/index.js +1 -1
- package/dist/cli/utils/create-db-connection.d.ts +1 -1
- package/dist/cli/utils/create-db-connection.js +11 -1
- package/dist/cli/utils/drivers.d.ts +1 -0
- package/dist/cli/utils/drivers.js +2 -1
- package/dist/controllers/extensions.js +1 -1
- package/dist/controllers/files.js +3 -0
- package/dist/controllers/utils.js +2 -0
- package/dist/database/helpers/date/index.d.ts +1 -0
- package/dist/database/helpers/date/index.js +3 -1
- package/dist/database/helpers/geometry/index.d.ts +1 -0
- package/dist/database/helpers/geometry/index.js +3 -1
- package/dist/database/helpers/index.d.ts +2 -0
- package/dist/database/helpers/index.js +2 -0
- package/dist/database/helpers/schema/dialects/cockroachdb.d.ts +16 -0
- package/dist/database/helpers/schema/dialects/cockroachdb.js +16 -0
- package/dist/database/helpers/schema/dialects/default.d.ts +3 -0
- package/dist/database/helpers/schema/dialects/default.js +7 -0
- package/dist/database/helpers/schema/dialects/oracle.d.ts +12 -0
- package/dist/database/helpers/schema/dialects/oracle.js +13 -0
- package/dist/database/helpers/schema/index.d.ts +7 -0
- package/dist/database/helpers/schema/index.js +17 -0
- package/dist/database/helpers/schema/types.d.ts +25 -0
- package/dist/database/helpers/schema/types.js +89 -0
- package/dist/database/index.d.ts +1 -1
- package/dist/database/index.js +66 -20
- package/dist/database/migrations/20201105B-change-webhook-url-type.js +6 -25
- package/dist/database/migrations/20210312A-webhooks-collections-text.js +6 -25
- package/dist/database/migrations/20210415A-make-filesize-nullable.js +9 -4
- package/dist/database/migrations/20210506A-rename-interfaces.js +1 -1
- package/dist/database/migrations/20210510A-restructure-relations.js +12 -4
- package/dist/database/migrations/20210525A-add-insights.js +2 -2
- package/dist/database/migrations/20210626A-change-filesize-bigint.js +5 -7
- package/dist/database/migrations/20210903A-add-auth-provider.js +11 -2
- package/dist/database/migrations/20210907A-webhooks-collections-not-null.js +6 -20
- package/dist/database/migrations/20210920A-webhooks-url-not-null.js +10 -14
- package/dist/database/migrations/20211211A-add-shares.js +2 -2
- package/dist/database/migrations/run.js +1 -1
- package/dist/database/run-ast.d.ts +1 -1
- package/dist/database/seeds/01-collections.yaml +1 -0
- package/dist/database/seeds/02-roles.yaml +1 -0
- package/dist/database/seeds/03-users.yaml +1 -0
- package/dist/database/system-data/app-access-permissions/app-access-permissions.yaml +8 -2
- package/dist/database/system-data/fields/collections.yaml +2 -0
- package/dist/database/system-data/relations/index.d.ts +1 -1
- package/dist/emitter.d.ts +3 -4
- package/dist/emitter.js +2 -8
- package/dist/env.js +1 -0
- package/dist/exceptions/database/translate.js +1 -0
- package/dist/exceptions/index.d.ts +1 -0
- package/dist/exceptions/index.js +1 -0
- package/dist/exceptions/unsupported-media-type.d.ts +4 -0
- package/dist/exceptions/unsupported-media-type.js +10 -0
- package/dist/extensions.d.ts +14 -8
- package/dist/extensions.js +136 -69
- package/dist/logger.js +22 -1
- package/dist/middleware/extract-token.js +1 -1
- package/dist/services/assets.js +3 -3
- package/dist/services/authentication.d.ts +2 -2
- package/dist/services/authentication.js +7 -2
- package/dist/services/authorization.d.ts +2 -3
- package/dist/services/collections.d.ts +2 -2
- package/dist/services/collections.js +20 -18
- package/dist/services/fields.d.ts +2 -3
- package/dist/services/fields.js +14 -10
- package/dist/services/graphql.d.ts +2 -1
- package/dist/services/graphql.js +4 -4
- package/dist/services/import.d.ts +2 -2
- package/dist/services/import.js +2 -1
- package/dist/services/items.d.ts +2 -2
- package/dist/services/items.js +22 -18
- package/dist/services/mail/index.d.ts +2 -2
- package/dist/services/meta.d.ts +2 -2
- package/dist/services/payload.d.ts +2 -2
- package/dist/services/payload.js +7 -3
- package/dist/services/relations.d.ts +2 -2
- package/dist/services/relations.js +4 -0
- package/dist/services/server.d.ts +2 -2
- package/dist/services/specifications.d.ts +2 -2
- package/dist/services/users.d.ts +2 -3
- package/dist/services/utils.d.ts +2 -2
- package/dist/types/ast.d.ts +1 -2
- package/dist/types/auth.d.ts +1 -3
- package/dist/types/index.d.ts +0 -3
- package/dist/types/index.js +0 -3
- package/dist/types/services.d.ts +1 -3
- package/dist/types/snapshot.d.ts +1 -2
- package/dist/utils/apply-query.d.ts +1 -2
- package/dist/utils/apply-query.js +1 -1
- package/dist/utils/apply-snapshot.d.ts +2 -1
- package/dist/utils/get-ast-from-query.d.ts +2 -3
- package/dist/utils/get-local-type.js +1 -1
- package/dist/utils/get-permissions.d.ts +1 -2
- package/dist/utils/get-permissions.js +1 -1
- package/dist/utils/get-relation-type.d.ts +1 -1
- package/dist/utils/get-schema.d.ts +1 -2
- package/dist/utils/get-snapshot.d.ts +2 -1
- package/dist/utils/md.js +1 -1
- package/dist/utils/merge-permissions-for-share.d.ts +1 -2
- package/dist/utils/reduce-schema.d.ts +1 -2
- package/example.env +8 -0
- package/package.json +23 -17
- package/dist/cli/index.test.d.ts +0 -1
- package/dist/cli/index.test.js +0 -58
- package/dist/middleware/cache.test.d.ts +0 -1
- package/dist/middleware/cache.test.js +0 -62
- package/dist/tests/database/migrations/run.test.d.ts +0 -1
- package/dist/tests/database/migrations/run.test.js +0 -29
- package/dist/types/extensions.d.ts +0 -43
- package/dist/types/extensions.js +0 -2
- package/dist/types/relation.d.ts +0 -21
- package/dist/types/relation.js +0 -2
- package/dist/types/schema.d.ts +0 -32
- package/dist/types/schema.js +0 -2
- package/dist/utils/get-cache-key.test.d.ts +0 -1
- package/dist/utils/get-cache-key.test.js +0 -53
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { RelationMeta } from '
|
|
1
|
+
import { RelationMeta } from '@directus/shared/types';
|
|
2
2
|
export declare const systemRelationRows: RelationMeta[];
|
package/dist/emitter.d.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { ActionHandler,
|
|
1
|
+
import { ActionHandler, EventContext, FilterHandler, InitHandler } from '@directus/shared/types';
|
|
2
2
|
export declare class Emitter {
|
|
3
3
|
private filterEmitter;
|
|
4
4
|
private actionEmitter;
|
|
5
5
|
private initEmitter;
|
|
6
6
|
constructor();
|
|
7
|
-
emitFilter<T>(event: string, payload: T, meta: Record<string, any>, context:
|
|
8
|
-
emitAction(event: string, meta: Record<string, any>, context:
|
|
7
|
+
emitFilter<T>(event: string | string[], payload: T, meta: Record<string, any>, context: EventContext): Promise<T>;
|
|
8
|
+
emitAction(event: string | string[], meta: Record<string, any>, context: EventContext): void;
|
|
9
9
|
emitInit(event: string, meta: Record<string, any>): Promise<void>;
|
|
10
10
|
onFilter(event: string, handler: FilterHandler): void;
|
|
11
11
|
onAction(event: string, handler: ActionHandler): void;
|
|
@@ -14,7 +14,6 @@ export declare class Emitter {
|
|
|
14
14
|
offAction(event: string, handler: ActionHandler): void;
|
|
15
15
|
offInit(event: string, handler: InitHandler): void;
|
|
16
16
|
offAll(): void;
|
|
17
|
-
private eventsToEmit;
|
|
18
17
|
}
|
|
19
18
|
declare const emitter: Emitter;
|
|
20
19
|
export default emitter;
|
package/dist/emitter.js
CHANGED
|
@@ -20,7 +20,7 @@ class Emitter {
|
|
|
20
20
|
this.initEmitter = new eventemitter2_1.EventEmitter2(emitterOptions);
|
|
21
21
|
}
|
|
22
22
|
async emitFilter(event, payload, meta, context) {
|
|
23
|
-
const events =
|
|
23
|
+
const events = Array.isArray(event) ? event : [event];
|
|
24
24
|
const listeners = events.flatMap((event) => this.filterEmitter.listeners(event));
|
|
25
25
|
let updatedPayload = payload;
|
|
26
26
|
for (const listener of listeners) {
|
|
@@ -32,7 +32,7 @@ class Emitter {
|
|
|
32
32
|
return updatedPayload;
|
|
33
33
|
}
|
|
34
34
|
emitAction(event, meta, context) {
|
|
35
|
-
const events =
|
|
35
|
+
const events = Array.isArray(event) ? event : [event];
|
|
36
36
|
for (const event of events) {
|
|
37
37
|
this.actionEmitter.emitAsync(event, meta, context).catch((err) => {
|
|
38
38
|
logger_1.default.warn(`An error was thrown while executing action "${event}"`);
|
|
@@ -72,12 +72,6 @@ class Emitter {
|
|
|
72
72
|
this.actionEmitter.removeAllListeners();
|
|
73
73
|
this.initEmitter.removeAllListeners();
|
|
74
74
|
}
|
|
75
|
-
eventsToEmit(event, meta) {
|
|
76
|
-
if (event.startsWith('items')) {
|
|
77
|
-
return [event, `${meta.collection}.${event}`];
|
|
78
|
-
}
|
|
79
|
-
return [event];
|
|
80
|
-
}
|
|
81
75
|
}
|
|
82
76
|
exports.Emitter = Emitter;
|
|
83
77
|
const emitter = new Emitter();
|
package/dist/env.js
CHANGED
|
@@ -14,5 +14,6 @@ export * from './range-not-satisfiable';
|
|
|
14
14
|
export * from './route-not-found';
|
|
15
15
|
export * from './service-unavailable';
|
|
16
16
|
export * from './unprocessable-entity';
|
|
17
|
+
export * from './unsupported-media-type';
|
|
17
18
|
export * from './user-suspended';
|
|
18
19
|
export * from './unexpected-response';
|
package/dist/exceptions/index.js
CHANGED
|
@@ -26,5 +26,6 @@ __exportStar(require("./range-not-satisfiable"), exports);
|
|
|
26
26
|
__exportStar(require("./route-not-found"), exports);
|
|
27
27
|
__exportStar(require("./service-unavailable"), exports);
|
|
28
28
|
__exportStar(require("./unprocessable-entity"), exports);
|
|
29
|
+
__exportStar(require("./unsupported-media-type"), exports);
|
|
29
30
|
__exportStar(require("./user-suspended"), exports);
|
|
30
31
|
__exportStar(require("./unexpected-response"), exports);
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.UnsupportedMediaTypeException = void 0;
|
|
4
|
+
const exceptions_1 = require("@directus/shared/exceptions");
|
|
5
|
+
class UnsupportedMediaTypeException extends exceptions_1.BaseException {
|
|
6
|
+
constructor(message, extensions) {
|
|
7
|
+
super(message, 415, 'UNSUPPORTED_MEDIA_TYPE', extensions);
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
exports.UnsupportedMediaTypeException = UnsupportedMediaTypeException;
|
package/dist/extensions.d.ts
CHANGED
|
@@ -1,23 +1,29 @@
|
|
|
1
1
|
import { Router } from 'express';
|
|
2
2
|
import { AppExtensionType, ExtensionType } from '@directus/shared/types';
|
|
3
3
|
export declare function getExtensionManager(): ExtensionManager;
|
|
4
|
+
declare type Options = {
|
|
5
|
+
schedule: boolean;
|
|
6
|
+
watch: boolean;
|
|
7
|
+
};
|
|
4
8
|
declare class ExtensionManager {
|
|
5
|
-
private
|
|
9
|
+
private isLoaded;
|
|
10
|
+
private options;
|
|
6
11
|
private extensions;
|
|
7
12
|
private appExtensions;
|
|
8
|
-
private
|
|
9
|
-
private apiEndpoints;
|
|
13
|
+
private apiExtensions;
|
|
10
14
|
private apiEmitter;
|
|
11
15
|
private endpointRouter;
|
|
12
|
-
private
|
|
16
|
+
private watcher;
|
|
13
17
|
constructor();
|
|
14
|
-
initialize(
|
|
15
|
-
schedule: boolean;
|
|
16
|
-
}): Promise<void>;
|
|
18
|
+
initialize(options?: Partial<Options>): Promise<void>;
|
|
17
19
|
reload(): Promise<void>;
|
|
18
|
-
|
|
20
|
+
getExtensionsList(type?: ExtensionType): string[];
|
|
19
21
|
getAppExtensions(type: AppExtensionType): string | undefined;
|
|
20
22
|
getEndpointRouter(): Router;
|
|
23
|
+
private load;
|
|
24
|
+
private unload;
|
|
25
|
+
private initializeWatcher;
|
|
26
|
+
private updateWatchedExtensions;
|
|
21
27
|
private getExtensions;
|
|
22
28
|
private generateExtensionBundles;
|
|
23
29
|
private getSharedDepsMapping;
|
package/dist/extensions.js
CHANGED
|
@@ -45,6 +45,8 @@ const plugin_alias_1 = __importDefault(require("@rollup/plugin-alias"));
|
|
|
45
45
|
const url_1 = require("./utils/url");
|
|
46
46
|
const get_module_default_1 = __importDefault(require("./utils/get-module-default"));
|
|
47
47
|
const lodash_1 = require("lodash");
|
|
48
|
+
const chokidar_1 = __importDefault(require("chokidar"));
|
|
49
|
+
const utils_1 = require("@directus/shared/utils");
|
|
48
50
|
let extensionManager;
|
|
49
51
|
function getExtensionManager() {
|
|
50
52
|
if (extensionManager) {
|
|
@@ -54,21 +56,73 @@ function getExtensionManager() {
|
|
|
54
56
|
return extensionManager;
|
|
55
57
|
}
|
|
56
58
|
exports.getExtensionManager = getExtensionManager;
|
|
59
|
+
const defaultOptions = {
|
|
60
|
+
schedule: true,
|
|
61
|
+
watch: env_1.default.EXTENSIONS_AUTO_RELOAD && env_1.default.NODE_ENV !== 'development',
|
|
62
|
+
};
|
|
57
63
|
class ExtensionManager {
|
|
58
64
|
constructor() {
|
|
59
|
-
this.
|
|
65
|
+
this.isLoaded = false;
|
|
60
66
|
this.extensions = [];
|
|
61
67
|
this.appExtensions = {};
|
|
62
|
-
this.
|
|
63
|
-
this.
|
|
64
|
-
this.
|
|
68
|
+
this.apiExtensions = { hooks: [], endpoints: [] };
|
|
69
|
+
this.watcher = null;
|
|
70
|
+
this.options = defaultOptions;
|
|
65
71
|
this.apiEmitter = new emitter_1.Emitter();
|
|
66
72
|
this.endpointRouter = (0, express_1.Router)();
|
|
67
73
|
}
|
|
68
|
-
async initialize(
|
|
69
|
-
this.
|
|
70
|
-
|
|
71
|
-
|
|
74
|
+
async initialize(options = {}) {
|
|
75
|
+
this.options = {
|
|
76
|
+
...defaultOptions,
|
|
77
|
+
...options,
|
|
78
|
+
};
|
|
79
|
+
this.initializeWatcher();
|
|
80
|
+
if (!this.isLoaded) {
|
|
81
|
+
await this.load();
|
|
82
|
+
this.updateWatchedExtensions(this.extensions);
|
|
83
|
+
const loadedExtensions = this.getExtensionsList();
|
|
84
|
+
if (loadedExtensions.length > 0) {
|
|
85
|
+
logger_1.default.info(`Loaded extensions: ${loadedExtensions.join(', ')}`);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
async reload() {
|
|
90
|
+
if (this.isLoaded) {
|
|
91
|
+
logger_1.default.info('Reloading extensions');
|
|
92
|
+
const prevExtensions = (0, lodash_1.clone)(this.extensions);
|
|
93
|
+
await this.unload();
|
|
94
|
+
await this.load();
|
|
95
|
+
const added = this.extensions.filter((extension) => !prevExtensions.some((prevExtension) => extension.path === prevExtension.path));
|
|
96
|
+
const removed = prevExtensions.filter((prevExtension) => !this.extensions.some((extension) => prevExtension.path === extension.path));
|
|
97
|
+
this.updateWatchedExtensions(added, removed);
|
|
98
|
+
const addedExtensions = added.map((extension) => extension.name);
|
|
99
|
+
const removedExtensions = removed.map((extension) => extension.name);
|
|
100
|
+
if (addedExtensions.length > 0) {
|
|
101
|
+
logger_1.default.info(`Added extensions: ${addedExtensions.join(', ')}`);
|
|
102
|
+
}
|
|
103
|
+
if (removedExtensions.length > 0) {
|
|
104
|
+
logger_1.default.info(`Removed extensions: ${removedExtensions.join(', ')}`);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
else {
|
|
108
|
+
logger_1.default.warn('Extensions have to be loaded before they can be reloaded');
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
getExtensionsList(type) {
|
|
112
|
+
if (type === undefined) {
|
|
113
|
+
return this.extensions.map((extension) => extension.name);
|
|
114
|
+
}
|
|
115
|
+
else {
|
|
116
|
+
return this.extensions.filter((extension) => extension.type === type).map((extension) => extension.name);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
getAppExtensions(type) {
|
|
120
|
+
return this.appExtensions[type];
|
|
121
|
+
}
|
|
122
|
+
getEndpointRouter() {
|
|
123
|
+
return this.endpointRouter;
|
|
124
|
+
}
|
|
125
|
+
async load() {
|
|
72
126
|
try {
|
|
73
127
|
await (0, node_1.ensureExtensionDirs)(env_1.default.EXTENSIONS_PATH, env_1.default.SERVE_APP ? constants_1.EXTENSION_TYPES : constants_1.API_EXTENSION_TYPES);
|
|
74
128
|
this.extensions = await this.getExtensions();
|
|
@@ -82,38 +136,42 @@ class ExtensionManager {
|
|
|
82
136
|
if (env_1.default.SERVE_APP) {
|
|
83
137
|
this.appExtensions = await this.generateExtensionBundles();
|
|
84
138
|
}
|
|
85
|
-
|
|
86
|
-
if (loadedExtensions.length > 0) {
|
|
87
|
-
logger_1.default.info(`Loaded extensions: ${loadedExtensions.join(', ')}`);
|
|
88
|
-
}
|
|
89
|
-
this.isInitialized = true;
|
|
139
|
+
this.isLoaded = true;
|
|
90
140
|
}
|
|
91
|
-
async
|
|
92
|
-
if (!this.isInitialized)
|
|
93
|
-
return;
|
|
94
|
-
logger_1.default.info('Reloading extensions');
|
|
141
|
+
async unload() {
|
|
95
142
|
this.unregisterHooks();
|
|
96
143
|
this.unregisterEndpoints();
|
|
97
144
|
this.apiEmitter.offAll();
|
|
98
145
|
if (env_1.default.SERVE_APP) {
|
|
99
146
|
this.appExtensions = {};
|
|
100
147
|
}
|
|
101
|
-
this.
|
|
102
|
-
await this.initialize();
|
|
148
|
+
this.isLoaded = false;
|
|
103
149
|
}
|
|
104
|
-
|
|
105
|
-
if (
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
150
|
+
initializeWatcher() {
|
|
151
|
+
if (this.options.watch && !this.watcher) {
|
|
152
|
+
logger_1.default.info('Watching extensions for changes...');
|
|
153
|
+
const localExtensionPaths = (env_1.default.SERVE_APP ? constants_1.EXTENSION_TYPES : constants_1.API_EXTENSION_TYPES).map((type) => path_1.default.posix.join(path_1.default.relative('.', env_1.default.EXTENSIONS_PATH).split(path_1.default.sep).join(path_1.default.posix.sep), (0, utils_1.pluralize)(type), '*', 'index.js'));
|
|
154
|
+
this.watcher = chokidar_1.default.watch([path_1.default.resolve('.', 'package.json'), ...localExtensionPaths], {
|
|
155
|
+
ignoreInitial: true,
|
|
156
|
+
});
|
|
157
|
+
this.watcher
|
|
158
|
+
.on('add', () => this.reload())
|
|
159
|
+
.on('change', () => this.reload())
|
|
160
|
+
.on('unlink', () => this.reload());
|
|
110
161
|
}
|
|
111
162
|
}
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
163
|
+
updateWatchedExtensions(added, removed = []) {
|
|
164
|
+
if (this.watcher) {
|
|
165
|
+
const toPackageExtensionPaths = (extensions) => extensions
|
|
166
|
+
.filter((extension) => !extension.local)
|
|
167
|
+
.map((extension) => extension.type !== 'pack'
|
|
168
|
+
? path_1.default.resolve(extension.path, extension.entrypoint || '')
|
|
169
|
+
: path_1.default.resolve(extension.path, 'package.json'));
|
|
170
|
+
const addedPackageExtensionPaths = toPackageExtensionPaths(added);
|
|
171
|
+
const removedPackageExtensionPaths = toPackageExtensionPaths(removed);
|
|
172
|
+
this.watcher.add(addedPackageExtensionPaths);
|
|
173
|
+
this.watcher.unwatch(removedPackageExtensionPaths);
|
|
174
|
+
}
|
|
117
175
|
}
|
|
118
176
|
async getExtensions() {
|
|
119
177
|
const packageExtensions = await (0, node_1.getPackageExtensions)('.', env_1.default.SERVE_APP ? constants_1.EXTENSION_PACKAGE_TYPES : constants_1.API_EXTENSION_PACKAGE_TYPES);
|
|
@@ -129,15 +187,21 @@ class ExtensionManager {
|
|
|
129
187
|
const bundles = {};
|
|
130
188
|
for (const extensionType of constants_1.APP_EXTENSION_TYPES) {
|
|
131
189
|
const entry = (0, node_1.generateExtensionsEntry)(extensionType, this.extensions);
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
190
|
+
try {
|
|
191
|
+
const bundle = await (0, rollup_1.rollup)({
|
|
192
|
+
input: 'entry',
|
|
193
|
+
external: Object.values(sharedDepsMapping),
|
|
194
|
+
makeAbsoluteExternalsRelative: false,
|
|
195
|
+
plugins: [(0, plugin_virtual_1.default)({ entry }), (0, plugin_alias_1.default)({ entries: internalImports })],
|
|
196
|
+
});
|
|
197
|
+
const { output } = await bundle.generate({ format: 'es', compact: true });
|
|
198
|
+
bundles[extensionType] = output[0].code;
|
|
199
|
+
await bundle.close();
|
|
200
|
+
}
|
|
201
|
+
catch (error) {
|
|
202
|
+
logger_1.default.warn(`Couldn't bundle App extensions`);
|
|
203
|
+
logger_1.default.warn(error);
|
|
204
|
+
}
|
|
141
205
|
}
|
|
142
206
|
return bundles;
|
|
143
207
|
}
|
|
@@ -185,38 +249,39 @@ class ExtensionManager {
|
|
|
185
249
|
const hookPath = path_1.default.resolve(hook.path, hook.entrypoint || '');
|
|
186
250
|
const hookInstance = require(hookPath);
|
|
187
251
|
const register = (0, get_module_default_1.default)(hookInstance);
|
|
252
|
+
const hookHandler = {
|
|
253
|
+
path: hookPath,
|
|
254
|
+
events: [],
|
|
255
|
+
};
|
|
188
256
|
const registerFunctions = {
|
|
189
257
|
filter: (event, handler) => {
|
|
190
258
|
emitter_1.default.onFilter(event, handler);
|
|
191
|
-
|
|
259
|
+
hookHandler.events.push({
|
|
192
260
|
type: 'filter',
|
|
193
|
-
|
|
194
|
-
event,
|
|
261
|
+
name: event,
|
|
195
262
|
handler,
|
|
196
263
|
});
|
|
197
264
|
},
|
|
198
265
|
action: (event, handler) => {
|
|
199
266
|
emitter_1.default.onAction(event, handler);
|
|
200
|
-
|
|
267
|
+
hookHandler.events.push({
|
|
201
268
|
type: 'action',
|
|
202
|
-
|
|
203
|
-
event,
|
|
269
|
+
name: event,
|
|
204
270
|
handler,
|
|
205
271
|
});
|
|
206
272
|
},
|
|
207
273
|
init: (event, handler) => {
|
|
208
274
|
emitter_1.default.onInit(event, handler);
|
|
209
|
-
|
|
275
|
+
hookHandler.events.push({
|
|
210
276
|
type: 'init',
|
|
211
|
-
|
|
212
|
-
event,
|
|
277
|
+
name: event,
|
|
213
278
|
handler,
|
|
214
279
|
});
|
|
215
280
|
},
|
|
216
281
|
schedule: (cron, handler) => {
|
|
217
282
|
if ((0, node_cron_1.validate)(cron)) {
|
|
218
283
|
const task = (0, node_cron_1.schedule)(cron, async () => {
|
|
219
|
-
if (this.
|
|
284
|
+
if (this.options.schedule) {
|
|
220
285
|
try {
|
|
221
286
|
await handler();
|
|
222
287
|
}
|
|
@@ -225,9 +290,8 @@ class ExtensionManager {
|
|
|
225
290
|
}
|
|
226
291
|
}
|
|
227
292
|
});
|
|
228
|
-
|
|
293
|
+
hookHandler.events.push({
|
|
229
294
|
type: 'schedule',
|
|
230
|
-
path: hookPath,
|
|
231
295
|
task,
|
|
232
296
|
});
|
|
233
297
|
}
|
|
@@ -245,6 +309,7 @@ class ExtensionManager {
|
|
|
245
309
|
logger: logger_1.default,
|
|
246
310
|
getSchema: get_schema_1.getSchema,
|
|
247
311
|
});
|
|
312
|
+
this.apiExtensions.hooks.push(hookHandler);
|
|
248
313
|
}
|
|
249
314
|
registerEndpoint(endpoint, router) {
|
|
250
315
|
const endpointPath = path_1.default.resolve(endpoint.path, endpoint.entrypoint || '');
|
|
@@ -263,35 +328,37 @@ class ExtensionManager {
|
|
|
263
328
|
logger: logger_1.default,
|
|
264
329
|
getSchema: get_schema_1.getSchema,
|
|
265
330
|
});
|
|
266
|
-
this.
|
|
331
|
+
this.apiExtensions.endpoints.push({
|
|
267
332
|
path: endpointPath,
|
|
268
333
|
});
|
|
269
334
|
}
|
|
270
335
|
unregisterHooks() {
|
|
271
|
-
for (const hook of this.
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
336
|
+
for (const hook of this.apiExtensions.hooks) {
|
|
337
|
+
for (const event of hook.events) {
|
|
338
|
+
switch (event.type) {
|
|
339
|
+
case 'filter':
|
|
340
|
+
emitter_1.default.offFilter(event.name, event.handler);
|
|
341
|
+
break;
|
|
342
|
+
case 'action':
|
|
343
|
+
emitter_1.default.offAction(event.name, event.handler);
|
|
344
|
+
break;
|
|
345
|
+
case 'init':
|
|
346
|
+
emitter_1.default.offInit(event.name, event.handler);
|
|
347
|
+
break;
|
|
348
|
+
case 'schedule':
|
|
349
|
+
event.task.stop();
|
|
350
|
+
break;
|
|
351
|
+
}
|
|
285
352
|
}
|
|
286
353
|
delete require.cache[require.resolve(hook.path)];
|
|
287
354
|
}
|
|
288
|
-
this.
|
|
355
|
+
this.apiExtensions.hooks = [];
|
|
289
356
|
}
|
|
290
357
|
unregisterEndpoints() {
|
|
291
|
-
for (const endpoint of this.
|
|
358
|
+
for (const endpoint of this.apiExtensions.endpoints) {
|
|
292
359
|
delete require.cache[require.resolve(endpoint.path)];
|
|
293
360
|
}
|
|
294
361
|
this.endpointRouter.stack = [];
|
|
295
|
-
this.
|
|
362
|
+
this.apiExtensions.endpoints = [];
|
|
296
363
|
}
|
|
297
364
|
}
|
package/dist/logger.js
CHANGED
|
@@ -25,6 +25,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
25
25
|
exports.expressLogger = void 0;
|
|
26
26
|
const pino_1 = __importDefault(require("pino"));
|
|
27
27
|
const pino_http_1 = __importStar(require("pino-http"));
|
|
28
|
+
const get_config_from_env_1 = require("./utils/get-config-from-env");
|
|
28
29
|
const url_1 = require("url");
|
|
29
30
|
const env_1 = __importDefault(require("./env"));
|
|
30
31
|
const pinoOptions = {
|
|
@@ -38,9 +39,29 @@ if (env_1.default.LOG_STYLE !== 'raw') {
|
|
|
38
39
|
pinoOptions.prettyPrint = true;
|
|
39
40
|
pinoOptions.prettifier = require('pino-colada');
|
|
40
41
|
}
|
|
41
|
-
const
|
|
42
|
+
const loggerEnvConfig = (0, get_config_from_env_1.getConfigFromEnv)('LOGGER_', 'LOGGER_HTTP');
|
|
43
|
+
// Expose custom log levels into formatter function
|
|
44
|
+
if (loggerEnvConfig.levels) {
|
|
45
|
+
const customLogLevels = {};
|
|
46
|
+
for (const el of loggerEnvConfig.levels.split(',')) {
|
|
47
|
+
const key_val = el.split(':');
|
|
48
|
+
customLogLevels[key_val[0].trim()] = key_val[1].trim();
|
|
49
|
+
}
|
|
50
|
+
pinoOptions.formatters = {
|
|
51
|
+
level(label, number) {
|
|
52
|
+
return {
|
|
53
|
+
severity: customLogLevels[label] || 'info',
|
|
54
|
+
level: number,
|
|
55
|
+
};
|
|
56
|
+
},
|
|
57
|
+
};
|
|
58
|
+
delete loggerEnvConfig.levels;
|
|
59
|
+
}
|
|
60
|
+
const logger = (0, pino_1.default)(Object.assign(pinoOptions, loggerEnvConfig));
|
|
61
|
+
const httpLoggerEnvConfig = (0, get_config_from_env_1.getConfigFromEnv)('LOGGER_HTTP', ['LOGGER_HTTP_LOGGER']);
|
|
42
62
|
exports.expressLogger = (0, pino_http_1.default)({
|
|
43
63
|
logger,
|
|
64
|
+
...httpLoggerEnvConfig,
|
|
44
65
|
}, {
|
|
45
66
|
serializers: {
|
|
46
67
|
req(request) {
|
|
@@ -15,7 +15,7 @@ const extractToken = (req, res, next) => {
|
|
|
15
15
|
}
|
|
16
16
|
if (req.headers && req.headers.authorization) {
|
|
17
17
|
const parts = req.headers.authorization.split(' ');
|
|
18
|
-
if (parts.length === 2 && parts[0] === '
|
|
18
|
+
if (parts.length === 2 && parts[0].toLowerCase() === 'bearer') {
|
|
19
19
|
token = parts[1];
|
|
20
20
|
}
|
|
21
21
|
}
|
package/dist/services/assets.js
CHANGED
|
@@ -52,9 +52,6 @@ class AssetsService {
|
|
|
52
52
|
.from('directus_settings')
|
|
53
53
|
.first();
|
|
54
54
|
const systemPublicKeys = Object.values(publicSettings || {});
|
|
55
|
-
if (systemPublicKeys.includes(id) === false && ((_a = this.accountability) === null || _a === void 0 ? void 0 : _a.admin) !== true) {
|
|
56
|
-
await this.authorizationService.checkAccess('read', 'directus_files', id);
|
|
57
|
-
}
|
|
58
55
|
/**
|
|
59
56
|
* This is a little annoying. Postgres will error out if you're trying to search in `where`
|
|
60
57
|
* with a wrong type. In case of directus_files where id is a uuid, we'll have to verify the
|
|
@@ -63,6 +60,9 @@ class AssetsService {
|
|
|
63
60
|
const isValidUUID = (0, uuid_validate_1.default)(id, 4);
|
|
64
61
|
if (isValidUUID === false)
|
|
65
62
|
throw new exceptions_1.ForbiddenException();
|
|
63
|
+
if (systemPublicKeys.includes(id) === false && ((_a = this.accountability) === null || _a === void 0 ? void 0 : _a.admin) !== true) {
|
|
64
|
+
await this.authorizationService.checkAccess('read', 'directus_files', id);
|
|
65
|
+
}
|
|
66
66
|
const file = (await this.knex.select('*').from('directus_files').where({ id }).first());
|
|
67
67
|
if (!file)
|
|
68
68
|
throw new exceptions_1.ForbiddenException();
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Knex } from 'knex';
|
|
2
2
|
import { ActivityService } from './activity';
|
|
3
|
-
import { AbstractServiceOptions,
|
|
4
|
-
import { Accountability } from '@directus/shared/types';
|
|
3
|
+
import { AbstractServiceOptions, LoginResult } from '../types';
|
|
4
|
+
import { Accountability, SchemaOverview } from '@directus/shared/types';
|
|
5
5
|
export declare class AuthenticationService {
|
|
6
6
|
knex: Knex;
|
|
7
7
|
accountability: Accountability | null;
|
|
@@ -43,7 +43,7 @@ class AuthenticationService {
|
|
|
43
43
|
const user = await this.knex
|
|
44
44
|
.select('u.id', 'u.first_name', 'u.last_name', 'u.email', 'u.password', 'u.status', 'u.role', 'r.admin_access', 'r.app_access', 'u.tfa_secret', 'u.provider', 'u.external_identifier', 'u.auth_data')
|
|
45
45
|
.from('directus_users as u')
|
|
46
|
-
.
|
|
46
|
+
.leftJoin('directus_roles as r', 'u.role', 'r.id')
|
|
47
47
|
.where('u.id', await provider.getUserID((0, lodash_1.cloneDeep)(payload)))
|
|
48
48
|
.andWhere('u.provider', providerName)
|
|
49
49
|
.first();
|
|
@@ -204,7 +204,9 @@ class AuthenticationService {
|
|
|
204
204
|
.from('directus_sessions AS s')
|
|
205
205
|
.leftJoin('directus_users AS u', 's.user', 'u.id')
|
|
206
206
|
.leftJoin('directus_shares AS d', 's.share', 'd.id')
|
|
207
|
-
.
|
|
207
|
+
.leftJoin('directus_roles AS r', (join) => {
|
|
208
|
+
join.onIn('r.id', [this.knex.ref('u.role'), this.knex.ref('d.role')]);
|
|
209
|
+
})
|
|
208
210
|
.where('s.token', refreshToken)
|
|
209
211
|
.andWhere('s.expires', '>=', new Date())
|
|
210
212
|
.andWhere((subQuery) => {
|
|
@@ -247,6 +249,9 @@ class AuthenticationService {
|
|
|
247
249
|
collection: record.share_collection,
|
|
248
250
|
item: record.share_item,
|
|
249
251
|
};
|
|
252
|
+
tokenPayload.app_access = false;
|
|
253
|
+
tokenPayload.admin_access = false;
|
|
254
|
+
delete tokenPayload.id;
|
|
250
255
|
}
|
|
251
256
|
const customClaims = await emitter_1.default.emitFilter('auth.jwt', tokenPayload, {
|
|
252
257
|
status: 'pending',
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { Knex } from 'knex';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { PermissionsAction } from '@directus/shared/types';
|
|
2
|
+
import { AbstractServiceOptions, AST, Item, PrimaryKey } from '../types';
|
|
3
|
+
import { PermissionsAction, Accountability, SchemaOverview } from '@directus/shared/types';
|
|
5
4
|
import { PayloadService } from './payload';
|
|
6
5
|
export declare class AuthorizationService {
|
|
7
6
|
knex: Knex;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import SchemaInspector from '@directus/schema';
|
|
2
2
|
import { Knex } from 'knex';
|
|
3
3
|
import Keyv from 'keyv';
|
|
4
|
-
import { AbstractServiceOptions, Collection, CollectionMeta,
|
|
5
|
-
import { Accountability, RawField } from '@directus/shared/types';
|
|
4
|
+
import { AbstractServiceOptions, Collection, CollectionMeta, MutationOptions } from '../types';
|
|
5
|
+
import { Accountability, RawField, SchemaOverview } from '@directus/shared/types';
|
|
6
6
|
import { Table } from 'knex-schema-inspector/dist/types/table';
|
|
7
7
|
export declare type RawCollection = {
|
|
8
8
|
collection: string;
|