directus 9.0.1 → 9.2.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 +2 -0
- package/dist/auth/drivers/ldap.js +9 -13
- package/dist/auth/drivers/oauth2.d.ts +1 -1
- package/dist/auth/drivers/oauth2.js +2 -2
- package/dist/auth/drivers/openid.d.ts +1 -1
- package/dist/auth/drivers/openid.js +8 -2
- package/dist/auth.js +5 -3
- package/dist/cli/commands/database/install.js +2 -4
- package/dist/cli/commands/schema/apply.js +26 -10
- package/dist/controllers/assets.js +0 -27
- package/dist/controllers/auth.js +7 -2
- package/dist/controllers/extensions.js +1 -1
- package/dist/controllers/notifications.d.ts +2 -0
- package/dist/controllers/notifications.js +147 -0
- package/dist/database/{functions/types.d.ts → helpers/date/dialects/mssql.d.ts} +2 -1
- package/dist/database/{functions → helpers/date}/dialects/mssql.js +4 -6
- package/dist/database/{functions → helpers/date}/dialects/mysql.d.ts +2 -4
- package/dist/database/{functions → helpers/date}/dialects/mysql.js +4 -6
- package/dist/database/{functions/dialects/mssql.d.ts → helpers/date/dialects/oracle.d.ts} +2 -4
- package/dist/database/{functions → helpers/date}/dialects/oracle.js +4 -6
- package/dist/database/helpers/date/dialects/postgres.d.ts +12 -0
- package/dist/database/{functions → helpers/date}/dialects/postgres.js +4 -6
- package/dist/database/{functions → helpers/date}/dialects/sqlite.d.ts +3 -4
- package/dist/database/helpers/date/dialects/sqlite.js +35 -0
- package/dist/database/helpers/date/index.d.ts +6 -0
- package/dist/database/helpers/date/index.js +15 -0
- package/dist/database/helpers/date/types.d.ts +13 -0
- package/dist/database/helpers/date/types.js +10 -0
- package/dist/database/helpers/geometry/dialects/mssql.d.ts +14 -0
- package/dist/database/helpers/geometry/dialects/mssql.js +36 -0
- package/dist/database/helpers/geometry/dialects/mysql.d.ts +7 -0
- package/dist/database/helpers/geometry/dialects/mysql.js +16 -0
- package/dist/database/helpers/geometry/dialects/oracle.d.ts +15 -0
- package/dist/database/helpers/geometry/dialects/oracle.js +39 -0
- package/dist/database/helpers/geometry/dialects/postgres.d.ts +10 -0
- package/dist/database/helpers/geometry/dialects/postgres.js +23 -0
- package/dist/database/helpers/geometry/dialects/redshift.d.ts +7 -0
- package/dist/database/helpers/geometry/dialects/redshift.js +16 -0
- package/dist/database/helpers/geometry/dialects/sqlite.d.ts +6 -0
- package/dist/database/helpers/geometry/dialects/sqlite.js +14 -0
- package/dist/database/helpers/geometry/index.d.ts +6 -0
- package/dist/database/helpers/geometry/index.js +15 -0
- package/dist/database/helpers/{geometry.d.ts → geometry/types.d.ts} +3 -7
- package/dist/database/helpers/geometry/types.js +54 -0
- package/dist/database/helpers/index.d.ts +8 -0
- package/dist/database/helpers/index.js +33 -0
- package/dist/database/helpers/types.d.ts +5 -0
- package/dist/database/helpers/types.js +9 -0
- package/dist/database/index.js +6 -6
- package/dist/database/migrations/20211118A-add-notifications.d.ts +3 -0
- package/dist/database/migrations/20211118A-add-notifications.js +28 -0
- package/dist/database/run-ast.js +5 -5
- package/dist/database/seeds/run.js +3 -3
- package/dist/database/system-data/app-access-permissions/app-access-permissions.yaml +14 -0
- package/dist/database/system-data/collections/collections.yaml +2 -0
- package/dist/database/system-data/fields/notifications.yaml +13 -0
- package/dist/database/system-data/fields/users.yaml +5 -0
- package/dist/database/system-data/relations/relations.yaml +6 -0
- package/dist/env.js +1 -0
- package/dist/extensions.js +17 -2
- package/dist/middleware/get-permissions.js +3 -102
- package/dist/middleware/sanitize-query.js +1 -1
- package/dist/services/activity.d.ts +7 -5
- package/dist/services/activity.js +87 -3
- package/dist/services/assets.js +14 -0
- package/dist/services/collections.js +12 -1
- package/dist/services/fields.d.ts +2 -0
- package/dist/services/fields.js +57 -26
- package/dist/services/files.d.ts +1 -1
- package/dist/services/files.js +13 -11
- package/dist/services/graphql.js +6 -0
- package/dist/services/index.d.ts +1 -0
- package/dist/services/index.js +1 -0
- package/dist/services/items.js +18 -29
- package/dist/services/mail/index.js +2 -2
- package/dist/services/mail/templates/base.liquid +153 -85
- package/dist/services/mail/templates/password-reset.liquid +3 -2
- package/dist/services/mail/templates/user-invitation.liquid +4 -4
- package/dist/services/notifications.d.ts +12 -0
- package/dist/services/notifications.js +41 -0
- package/dist/services/payload.d.ts +2 -0
- package/dist/services/payload.js +3 -3
- package/dist/services/users.js +1 -0
- package/dist/types/collection.d.ts +1 -0
- package/dist/utils/apply-query.js +9 -11
- package/dist/utils/apply-snapshot.js +27 -28
- package/dist/utils/get-column.js +2 -2
- package/dist/utils/get-default-index-name.js +2 -2
- package/dist/utils/get-local-type.js +11 -17
- package/dist/utils/get-permissions.d.ts +3 -0
- package/dist/utils/get-permissions.js +106 -0
- package/dist/utils/md.d.ts +4 -0
- package/dist/utils/md.js +15 -0
- package/dist/utils/merge-permissions.js +2 -2
- package/dist/utils/sanitize-query.js +4 -15
- package/dist/utils/user-name.d.ts +2 -0
- package/dist/utils/user-name.js +16 -0
- package/dist/utils/validate-query.js +1 -1
- package/dist/webhooks.js +16 -24
- package/package.json +27 -24
- package/dist/database/functions/dialects/oracle.d.ts +0 -14
- package/dist/database/functions/dialects/postgres.d.ts +0 -14
- package/dist/database/functions/dialects/sqlite.js +0 -33
- package/dist/database/functions/index.d.ts +0 -3
- package/dist/database/functions/index.js +0 -26
- package/dist/database/functions/types.js +0 -2
- package/dist/database/helpers/date.d.ts +0 -8
- package/dist/database/helpers/date.js +0 -44
- package/dist/database/helpers/geometry.js +0 -189
- package/dist/utils/get-simple-hash.d.ts +0 -5
- package/dist/utils/get-simple-hash.js +0 -15
|
@@ -36,14 +36,13 @@ async function applySnapshot(snapshot, options) {
|
|
|
36
36
|
// edits
|
|
37
37
|
snapshotDiff.fields = snapshotDiff.fields.filter((fieldDiff) => fieldDiff.collection !== collection);
|
|
38
38
|
}
|
|
39
|
-
if ((diff === null || diff === void 0 ? void 0 : diff[0].kind) === 'E') {
|
|
40
|
-
const
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
}
|
|
46
|
-
await collectionsService.updateOne(collection, updates);
|
|
39
|
+
if ((diff === null || diff === void 0 ? void 0 : diff[0].kind) === 'E' || (diff === null || diff === void 0 ? void 0 : diff[0].kind) === 'A') {
|
|
40
|
+
const newValues = snapshot.collections.find((field) => {
|
|
41
|
+
return field.collection === collection;
|
|
42
|
+
});
|
|
43
|
+
if (newValues) {
|
|
44
|
+
await collectionsService.updateOne(collection, newValues);
|
|
45
|
+
}
|
|
47
46
|
}
|
|
48
47
|
}
|
|
49
48
|
const fieldsService = new services_1.FieldsService({ knex: trx, schema: await (0, get_schema_1.getSchema)({ database: trx }) });
|
|
@@ -51,18 +50,15 @@ async function applySnapshot(snapshot, options) {
|
|
|
51
50
|
if ((diff === null || diff === void 0 ? void 0 : diff[0].kind) === 'N') {
|
|
52
51
|
await fieldsService.createField(collection, diff[0].rhs);
|
|
53
52
|
}
|
|
54
|
-
if ((diff === null || diff === void 0 ? void 0 : diff[0].kind) === 'E') {
|
|
55
|
-
const
|
|
56
|
-
|
|
57
|
-
return acc;
|
|
58
|
-
(0, lodash_1.set)(acc, edit.path, edit.rhs);
|
|
59
|
-
return acc;
|
|
60
|
-
}, {});
|
|
61
|
-
await fieldsService.updateField(collection, {
|
|
62
|
-
field,
|
|
63
|
-
type: 'unknown',
|
|
64
|
-
...updates,
|
|
53
|
+
if ((diff === null || diff === void 0 ? void 0 : diff[0].kind) === 'E' || (diff === null || diff === void 0 ? void 0 : diff[0].kind) === 'A') {
|
|
54
|
+
const newValues = snapshot.fields.find((snapshotField) => {
|
|
55
|
+
return snapshotField.collection === collection && snapshotField.field === field;
|
|
65
56
|
});
|
|
57
|
+
if (newValues) {
|
|
58
|
+
await fieldsService.updateField(collection, {
|
|
59
|
+
...newValues,
|
|
60
|
+
});
|
|
61
|
+
}
|
|
66
62
|
}
|
|
67
63
|
if ((diff === null || diff === void 0 ? void 0 : diff[0].kind) === 'D') {
|
|
68
64
|
await fieldsService.deleteField(collection, field);
|
|
@@ -72,18 +68,21 @@ async function applySnapshot(snapshot, options) {
|
|
|
72
68
|
}
|
|
73
69
|
}
|
|
74
70
|
const relationsService = new services_1.RelationsService({ knex: trx, schema: await (0, get_schema_1.getSchema)({ database: trx }) });
|
|
75
|
-
for (const { collection, field, diff
|
|
71
|
+
for (const { collection, field, diff } of snapshotDiff.relations) {
|
|
72
|
+
const structure = {};
|
|
73
|
+
for (const diffEdit of diff) {
|
|
74
|
+
(0, lodash_1.set)(structure, diffEdit.path, undefined);
|
|
75
|
+
}
|
|
76
76
|
if ((diff === null || diff === void 0 ? void 0 : diff[0].kind) === 'N') {
|
|
77
77
|
await relationsService.createOne(diff[0].rhs);
|
|
78
78
|
}
|
|
79
|
-
if ((diff === null || diff === void 0 ? void 0 : diff[0].kind) === 'E') {
|
|
80
|
-
const
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
}
|
|
86
|
-
await relationsService.updateOne(collection, field, updates);
|
|
79
|
+
if ((diff === null || diff === void 0 ? void 0 : diff[0].kind) === 'E' || (diff === null || diff === void 0 ? void 0 : diff[0].kind) === 'A') {
|
|
80
|
+
const newValues = snapshot.relations.find((relation) => {
|
|
81
|
+
return relation.collection === collection && relation.field === field;
|
|
82
|
+
});
|
|
83
|
+
if (newValues) {
|
|
84
|
+
await relationsService.updateOne(collection, field, newValues);
|
|
85
|
+
}
|
|
87
86
|
}
|
|
88
87
|
if ((diff === null || diff === void 0 ? void 0 : diff[0].kind) === 'D') {
|
|
89
88
|
await relationsService.deleteOne(collection, field);
|
package/dist/utils/get-column.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.getColumn = void 0;
|
|
4
|
-
const
|
|
4
|
+
const helpers_1 = require("../database/helpers");
|
|
5
5
|
const constants_1 = require("@directus/shared/constants");
|
|
6
6
|
const apply_function_to_column_name_1 = require("./apply-function-to-column-name");
|
|
7
7
|
/**
|
|
@@ -15,7 +15,7 @@ const apply_function_to_column_name_1 = require("./apply-function-to-column-name
|
|
|
15
15
|
* @returns Knex raw instance
|
|
16
16
|
*/
|
|
17
17
|
function getColumn(knex, table, column, alias = (0, apply_function_to_column_name_1.applyFunctionToColumnName)(column)) {
|
|
18
|
-
const fn = (0,
|
|
18
|
+
const { date: fn } = (0, helpers_1.getHelpers)(knex);
|
|
19
19
|
if (column.includes('(') && column.includes(')')) {
|
|
20
20
|
const functionName = column.split('(')[0];
|
|
21
21
|
const columnName = column.match(constants_1.REGEX_BETWEEN_PARENS)[1];
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.getDefaultIndexName = void 0;
|
|
4
|
-
const
|
|
4
|
+
const utils_1 = require("@directus/shared/utils");
|
|
5
5
|
/**
|
|
6
6
|
* Generate an index name for a given collection + fields combination.
|
|
7
7
|
*
|
|
@@ -18,7 +18,7 @@ function getDefaultIndexName(type, collection, fields) {
|
|
|
18
18
|
const indexName = (table + '_' + fields.join('_') + '_' + type).toLowerCase();
|
|
19
19
|
if (indexName.length <= 60)
|
|
20
20
|
return indexName;
|
|
21
|
-
const suffix = `__${(0,
|
|
21
|
+
const suffix = `__${(0, utils_1.getSimpleHash)(indexName)}_${type}`;
|
|
22
22
|
const prefix = indexName.substring(0, 60 - suffix.length);
|
|
23
23
|
return `${prefix}${suffix}`;
|
|
24
24
|
}
|
|
@@ -1,10 +1,5 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
const database_1 = require("../database");
|
|
7
|
-
const database_2 = __importDefault(require("../database"));
|
|
8
3
|
const localTypeMap = {
|
|
9
4
|
// Shared
|
|
10
5
|
boolean: 'boolean',
|
|
@@ -53,8 +48,10 @@ const localTypeMap = {
|
|
|
53
48
|
blob: 'binary',
|
|
54
49
|
mediumblob: 'binary',
|
|
55
50
|
'int unsigned': 'integer',
|
|
56
|
-
'tinyint
|
|
57
|
-
'
|
|
51
|
+
'tinyint unsigned': 'integer',
|
|
52
|
+
'smallint unsigned': 'integer',
|
|
53
|
+
'mediumint unsigned': 'integer',
|
|
54
|
+
'bigint unsigned': 'integer',
|
|
58
55
|
// MS SQL
|
|
59
56
|
bit: 'boolean',
|
|
60
57
|
smallmoney: 'float',
|
|
@@ -98,9 +95,10 @@ const localTypeMap = {
|
|
|
98
95
|
integerfirst: 'integer',
|
|
99
96
|
};
|
|
100
97
|
function getLocalType(column, field) {
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
const
|
|
98
|
+
if (!column)
|
|
99
|
+
return 'alias';
|
|
100
|
+
const dataType = column.data_type.toLowerCase();
|
|
101
|
+
const type = localTypeMap[dataType.split('(')[0]];
|
|
104
102
|
const special = field === null || field === void 0 ? void 0 : field.special;
|
|
105
103
|
if (special) {
|
|
106
104
|
if (special.includes('json'))
|
|
@@ -111,22 +109,18 @@ function getLocalType(column, field) {
|
|
|
111
109
|
return 'csv';
|
|
112
110
|
if (special.includes('uuid'))
|
|
113
111
|
return 'uuid';
|
|
114
|
-
if (type.startsWith('geometry')) {
|
|
112
|
+
if (type === null || type === void 0 ? void 0 : type.startsWith('geometry')) {
|
|
115
113
|
return special[0] || 'geometry';
|
|
116
114
|
}
|
|
117
115
|
}
|
|
118
116
|
/** Handle Postgres numeric decimals */
|
|
119
|
-
if (
|
|
117
|
+
if (dataType === 'numeric' && column.numeric_precision !== null && column.numeric_scale !== null) {
|
|
120
118
|
return 'decimal';
|
|
121
119
|
}
|
|
122
120
|
/** Handle MS SQL varchar(MAX) (eg TEXT) types */
|
|
123
|
-
if (column
|
|
121
|
+
if (column.data_type === 'nvarchar' && column.max_length === -1) {
|
|
124
122
|
return 'text';
|
|
125
123
|
}
|
|
126
|
-
/** Handle Boolean as TINYINT and edgecase MySQL where it still is just tinyint */
|
|
127
|
-
if (column && databaseClient === 'mysql' && column.data_type.toLowerCase() === 'tinyint') {
|
|
128
|
-
return 'boolean';
|
|
129
|
-
}
|
|
130
124
|
return type !== null && type !== void 0 ? type : 'unknown';
|
|
131
125
|
}
|
|
132
126
|
exports.default = getLocalType;
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.getPermissions = void 0;
|
|
7
|
+
const utils_1 = require("@directus/shared/utils");
|
|
8
|
+
const lodash_1 = require("lodash");
|
|
9
|
+
const database_1 = __importDefault(require("../database"));
|
|
10
|
+
const app_access_permissions_1 = require("../database/system-data/app-access-permissions");
|
|
11
|
+
const merge_permissions_1 = require("../utils/merge-permissions");
|
|
12
|
+
const users_1 = require("../services/users");
|
|
13
|
+
const roles_1 = require("../services/roles");
|
|
14
|
+
const cache_1 = require("../cache");
|
|
15
|
+
const object_hash_1 = __importDefault(require("object-hash"));
|
|
16
|
+
const env_1 = __importDefault(require("../env"));
|
|
17
|
+
async function getPermissions(accountability, schema) {
|
|
18
|
+
const database = (0, database_1.default)();
|
|
19
|
+
const { systemCache } = (0, cache_1.getCache)();
|
|
20
|
+
let permissions = [];
|
|
21
|
+
const { user, role, app, admin } = accountability;
|
|
22
|
+
const cacheKey = `permissions-${(0, object_hash_1.default)({ user, role, app, admin })}`;
|
|
23
|
+
if (env_1.default.CACHE_PERMISSIONS !== false) {
|
|
24
|
+
const cachedPermissions = await systemCache.get(cacheKey);
|
|
25
|
+
if (cachedPermissions) {
|
|
26
|
+
return cachedPermissions;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
if (accountability.admin !== true) {
|
|
30
|
+
const permissionsForRole = await database
|
|
31
|
+
.select('*')
|
|
32
|
+
.from('directus_permissions')
|
|
33
|
+
.where({ role: accountability.role });
|
|
34
|
+
const requiredPermissionData = {
|
|
35
|
+
$CURRENT_USER: [],
|
|
36
|
+
$CURRENT_ROLE: [],
|
|
37
|
+
};
|
|
38
|
+
permissions = permissionsForRole.map((permissionRaw) => {
|
|
39
|
+
const permission = (0, lodash_1.cloneDeep)(permissionRaw);
|
|
40
|
+
if (permission.permissions && typeof permission.permissions === 'string') {
|
|
41
|
+
permission.permissions = JSON.parse(permission.permissions);
|
|
42
|
+
}
|
|
43
|
+
else if (permission.permissions === null) {
|
|
44
|
+
permission.permissions = {};
|
|
45
|
+
}
|
|
46
|
+
if (permission.validation && typeof permission.validation === 'string') {
|
|
47
|
+
permission.validation = JSON.parse(permission.validation);
|
|
48
|
+
}
|
|
49
|
+
else if (permission.validation === null) {
|
|
50
|
+
permission.validation = {};
|
|
51
|
+
}
|
|
52
|
+
if (permission.presets && typeof permission.presets === 'string') {
|
|
53
|
+
permission.presets = JSON.parse(permission.presets);
|
|
54
|
+
}
|
|
55
|
+
else if (permission.presets === null) {
|
|
56
|
+
permission.presets = {};
|
|
57
|
+
}
|
|
58
|
+
if (permission.fields && typeof permission.fields === 'string') {
|
|
59
|
+
permission.fields = permission.fields.split(',');
|
|
60
|
+
}
|
|
61
|
+
else if (permission.fields === null) {
|
|
62
|
+
permission.fields = [];
|
|
63
|
+
}
|
|
64
|
+
const extractPermissionData = (val) => {
|
|
65
|
+
if (typeof val === 'string' && val.startsWith('$CURRENT_USER.')) {
|
|
66
|
+
requiredPermissionData.$CURRENT_USER.push(val.replace('$CURRENT_USER.', ''));
|
|
67
|
+
}
|
|
68
|
+
if (typeof val === 'string' && val.startsWith('$CURRENT_ROLE.')) {
|
|
69
|
+
requiredPermissionData.$CURRENT_ROLE.push(val.replace('$CURRENT_ROLE.', ''));
|
|
70
|
+
}
|
|
71
|
+
return val;
|
|
72
|
+
};
|
|
73
|
+
(0, utils_1.deepMap)(permission.permissions, extractPermissionData);
|
|
74
|
+
(0, utils_1.deepMap)(permission.validation, extractPermissionData);
|
|
75
|
+
(0, utils_1.deepMap)(permission.presets, extractPermissionData);
|
|
76
|
+
return permission;
|
|
77
|
+
});
|
|
78
|
+
if (accountability.app === true) {
|
|
79
|
+
permissions = (0, merge_permissions_1.mergePermissions)(permissions, app_access_permissions_1.appAccessMinimalPermissions.map((perm) => ({ ...perm, role: accountability.role })));
|
|
80
|
+
}
|
|
81
|
+
const usersService = new users_1.UsersService({ schema });
|
|
82
|
+
const rolesService = new roles_1.RolesService({ schema });
|
|
83
|
+
const filterContext = {};
|
|
84
|
+
if (accountability.user && requiredPermissionData.$CURRENT_USER.length > 0) {
|
|
85
|
+
filterContext.$CURRENT_USER = await usersService.readOne(accountability.user, {
|
|
86
|
+
fields: requiredPermissionData.$CURRENT_USER,
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
if (accountability.role && requiredPermissionData.$CURRENT_ROLE.length > 0) {
|
|
90
|
+
filterContext.$CURRENT_ROLE = await rolesService.readOne(accountability.role, {
|
|
91
|
+
fields: requiredPermissionData.$CURRENT_ROLE,
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
permissions = permissions.map((permission) => {
|
|
95
|
+
permission.permissions = (0, utils_1.parseFilter)(permission.permissions, accountability, filterContext);
|
|
96
|
+
permission.validation = (0, utils_1.parseFilter)(permission.validation, accountability, filterContext);
|
|
97
|
+
permission.presets = (0, utils_1.parseFilter)(permission.presets, accountability, filterContext);
|
|
98
|
+
return permission;
|
|
99
|
+
});
|
|
100
|
+
if (env_1.default.CACHE_PERMISSIONS !== false) {
|
|
101
|
+
await systemCache.set(cacheKey, permissions);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
return permissions;
|
|
105
|
+
}
|
|
106
|
+
exports.getPermissions = getPermissions;
|
package/dist/utils/md.js
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.md = void 0;
|
|
7
|
+
const marked_1 = require("marked");
|
|
8
|
+
const sanitize_html_1 = __importDefault(require("sanitize-html"));
|
|
9
|
+
/**
|
|
10
|
+
* Render and sanitize a markdown string
|
|
11
|
+
*/
|
|
12
|
+
function md(str) {
|
|
13
|
+
return (0, sanitize_html_1.default)((0, marked_1.parse)(str));
|
|
14
|
+
}
|
|
15
|
+
exports.md = md;
|
|
@@ -23,13 +23,13 @@ function mergePerm(currentPerm, newPerm) {
|
|
|
23
23
|
let validation = currentPerm.validation;
|
|
24
24
|
let fields = currentPerm.fields;
|
|
25
25
|
let presets = currentPerm.presets;
|
|
26
|
-
if (newPerm.permissions) {
|
|
26
|
+
if (newPerm.permissions && !(0, lodash_1.isEmpty)(newPerm.permissions)) {
|
|
27
27
|
if (currentPerm.permissions && Object.keys(currentPerm.permissions)[0] === '_or') {
|
|
28
28
|
permissions = {
|
|
29
29
|
_or: [...currentPerm.permissions._or, newPerm.permissions],
|
|
30
30
|
};
|
|
31
31
|
}
|
|
32
|
-
else if (currentPerm.permissions) {
|
|
32
|
+
else if (currentPerm.permissions && !(0, lodash_1.isEmpty)(currentPerm.permissions)) {
|
|
33
33
|
permissions = {
|
|
34
34
|
_or: [currentPerm.permissions, newPerm.permissions],
|
|
35
35
|
};
|
|
@@ -106,19 +106,7 @@ function sanitizeFilter(rawFilter, accountability) {
|
|
|
106
106
|
logger_1.default.warn('Invalid value passed for filter query parameter.');
|
|
107
107
|
}
|
|
108
108
|
}
|
|
109
|
-
|
|
110
|
-
try {
|
|
111
|
-
const parsed = JSON.parse(val);
|
|
112
|
-
if (typeof parsed == 'number' && !Number.isSafeInteger(parsed))
|
|
113
|
-
return val;
|
|
114
|
-
return parsed;
|
|
115
|
-
}
|
|
116
|
-
catch {
|
|
117
|
-
return val;
|
|
118
|
-
}
|
|
119
|
-
});
|
|
120
|
-
filters = (0, utils_1.parseFilter)(filters, accountability);
|
|
121
|
-
return filters;
|
|
109
|
+
return (0, utils_1.parseFilter)(filters, accountability);
|
|
122
110
|
}
|
|
123
111
|
function sanitizeLimit(rawLimit) {
|
|
124
112
|
if (rawLimit === undefined || rawLimit === null)
|
|
@@ -165,9 +153,10 @@ function sanitizeDeep(deep, accountability) {
|
|
|
165
153
|
const parsedSubQuery = sanitizeQuery({ [key.substring(1)]: value }, accountability);
|
|
166
154
|
// ...however we want to keep them for the nested structure of deep, otherwise there's no
|
|
167
155
|
// way of knowing when to keep nesting and when to stop
|
|
168
|
-
|
|
156
|
+
const [parsedKey, parsedValue] = Object.entries(parsedSubQuery)[0];
|
|
157
|
+
parsedLevel[`_${parsedKey}`] = parsedValue;
|
|
169
158
|
}
|
|
170
|
-
else {
|
|
159
|
+
else if ((0, lodash_1.isPlainObject)(value)) {
|
|
171
160
|
parse(value, [...path, key]);
|
|
172
161
|
}
|
|
173
162
|
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.userName = void 0;
|
|
4
|
+
function userName(user) {
|
|
5
|
+
if (user.first_name && user.last_name) {
|
|
6
|
+
return `${user.first_name} ${user.last_name}`;
|
|
7
|
+
}
|
|
8
|
+
if (user.first_name) {
|
|
9
|
+
return user.first_name;
|
|
10
|
+
}
|
|
11
|
+
if (user.email) {
|
|
12
|
+
return user.email;
|
|
13
|
+
}
|
|
14
|
+
return 'Unknown User';
|
|
15
|
+
}
|
|
16
|
+
exports.userName = userName;
|
|
@@ -100,7 +100,7 @@ function validateFilterPrimitive(value, key) {
|
|
|
100
100
|
false) {
|
|
101
101
|
throw new exceptions_1.InvalidQueryException(`The filter value for "${key}" has to be a string, number, or boolean`);
|
|
102
102
|
}
|
|
103
|
-
if (typeof value === 'number' && Number.isNaN(value)) {
|
|
103
|
+
if (typeof value === 'number' && (Number.isNaN(value) || !Number.isSafeInteger(value))) {
|
|
104
104
|
throw new exceptions_1.InvalidQueryException(`The filter value for "${key}" is not a valid number`);
|
|
105
105
|
}
|
|
106
106
|
if (typeof value === 'string' && value.length === 0) {
|
package/dist/webhooks.js
CHANGED
|
@@ -8,7 +8,6 @@ const axios_1 = __importDefault(require("axios"));
|
|
|
8
8
|
const database_1 = __importDefault(require("./database"));
|
|
9
9
|
const emitter_1 = __importDefault(require("./emitter"));
|
|
10
10
|
const logger_1 = __importDefault(require("./logger"));
|
|
11
|
-
const lodash_1 = require("lodash");
|
|
12
11
|
const services_1 = require("./services");
|
|
13
12
|
const get_schema_1 = require("./utils/get-schema");
|
|
14
13
|
let registered = [];
|
|
@@ -17,20 +16,12 @@ async function register() {
|
|
|
17
16
|
const webhookService = new services_1.WebhooksService({ knex: (0, database_1.default)(), schema: await (0, get_schema_1.getSchema)() });
|
|
18
17
|
const webhooks = await webhookService.readByQuery({ filter: { status: { _eq: 'active' } } });
|
|
19
18
|
for (const webhook of webhooks) {
|
|
20
|
-
|
|
21
|
-
const event =
|
|
22
|
-
const handler = createHandler(webhook);
|
|
19
|
+
for (const action of webhook.actions) {
|
|
20
|
+
const event = `items.${action}`;
|
|
21
|
+
const handler = createHandler(webhook, event);
|
|
23
22
|
emitter_1.default.onAction(event, handler);
|
|
24
23
|
registered.push({ event, handler });
|
|
25
24
|
}
|
|
26
|
-
else {
|
|
27
|
-
for (const action of webhook.actions) {
|
|
28
|
-
const event = `items.${action}`;
|
|
29
|
-
const handler = createHandler(webhook);
|
|
30
|
-
emitter_1.default.onAction(event, handler);
|
|
31
|
-
registered.push({ event, handler });
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
25
|
}
|
|
35
26
|
}
|
|
36
27
|
exports.register = register;
|
|
@@ -41,19 +32,20 @@ function unregister() {
|
|
|
41
32
|
registered = [];
|
|
42
33
|
}
|
|
43
34
|
exports.unregister = unregister;
|
|
44
|
-
function createHandler(webhook) {
|
|
45
|
-
return async (
|
|
46
|
-
if (webhook.collections.includes(
|
|
35
|
+
function createHandler(webhook, event) {
|
|
36
|
+
return async (meta, context) => {
|
|
37
|
+
if (webhook.collections.includes(meta.collection) === false)
|
|
47
38
|
return;
|
|
48
|
-
const webhookPayload =
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
39
|
+
const webhookPayload = {
|
|
40
|
+
event,
|
|
41
|
+
accountability: context.accountability
|
|
42
|
+
? {
|
|
43
|
+
user: context.accountability.user,
|
|
44
|
+
role: context.accountability.role,
|
|
45
|
+
}
|
|
46
|
+
: null,
|
|
47
|
+
...meta,
|
|
48
|
+
};
|
|
57
49
|
try {
|
|
58
50
|
await (0, axios_1.default)({
|
|
59
51
|
url: webhook.url,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "directus",
|
|
3
|
-
"version": "9.0
|
|
3
|
+
"version": "9.2.0",
|
|
4
4
|
"license": "GPL-3.0-only",
|
|
5
5
|
"homepage": "https://github.com/directus/directus#readme",
|
|
6
6
|
"description": "Directus is a real-time API and App dashboard for managing SQL database content.",
|
|
@@ -76,16 +76,16 @@
|
|
|
76
76
|
],
|
|
77
77
|
"dependencies": {
|
|
78
78
|
"@aws-sdk/client-ses": "^3.40.0",
|
|
79
|
-
"@directus/app": "9.0
|
|
80
|
-
"@directus/drive": "9.0
|
|
81
|
-
"@directus/drive-azure": "9.0
|
|
82
|
-
"@directus/drive-gcs": "9.0
|
|
83
|
-
"@directus/drive-s3": "9.0
|
|
84
|
-
"@directus/extensions-sdk": "9.0
|
|
85
|
-
"@directus/format-title": "9.0
|
|
86
|
-
"@directus/schema": "9.0
|
|
87
|
-
"@directus/shared": "9.0
|
|
88
|
-
"@directus/specs": "9.0
|
|
79
|
+
"@directus/app": "9.2.0",
|
|
80
|
+
"@directus/drive": "9.2.0",
|
|
81
|
+
"@directus/drive-azure": "9.2.0",
|
|
82
|
+
"@directus/drive-gcs": "9.2.0",
|
|
83
|
+
"@directus/drive-s3": "9.2.0",
|
|
84
|
+
"@directus/extensions-sdk": "9.2.0",
|
|
85
|
+
"@directus/format-title": "9.2.0",
|
|
86
|
+
"@directus/schema": "9.2.0",
|
|
87
|
+
"@directus/shared": "9.2.0",
|
|
88
|
+
"@directus/specs": "9.2.0",
|
|
89
89
|
"@godaddy/terminus": "^4.9.0",
|
|
90
90
|
"@rollup/plugin-alias": "^3.1.2",
|
|
91
91
|
"@rollup/plugin-virtual": "^2.0.3",
|
|
@@ -122,11 +122,12 @@
|
|
|
122
122
|
"jsonwebtoken": "^8.5.1",
|
|
123
123
|
"keyv": "^4.0.3",
|
|
124
124
|
"knex": "^0.95.11",
|
|
125
|
-
"knex-schema-inspector": "1.6.
|
|
125
|
+
"knex-schema-inspector": "1.6.6",
|
|
126
126
|
"ldapjs": "^2.3.1",
|
|
127
127
|
"liquidjs": "^9.25.0",
|
|
128
128
|
"lodash": "^4.17.21",
|
|
129
129
|
"macos-release": "^2.4.1",
|
|
130
|
+
"marked": "^4.0.3",
|
|
130
131
|
"mime-types": "^2.1.31",
|
|
131
132
|
"ms": "^2.1.3",
|
|
132
133
|
"nanoid": "^3.1.23",
|
|
@@ -145,6 +146,7 @@
|
|
|
145
146
|
"rate-limiter-flexible": "^2.2.2",
|
|
146
147
|
"resolve-cwd": "^3.0.0",
|
|
147
148
|
"rollup": "^2.52.1",
|
|
149
|
+
"sanitize-html": "^2.6.0",
|
|
148
150
|
"sharp": "^0.29.0",
|
|
149
151
|
"stream-json": "^1.7.1",
|
|
150
152
|
"supertest": "^6.1.6",
|
|
@@ -167,40 +169,41 @@
|
|
|
167
169
|
"sqlite3": "^5.0.2",
|
|
168
170
|
"tedious": "^13.0.0"
|
|
169
171
|
},
|
|
170
|
-
"gitHead": "
|
|
172
|
+
"gitHead": "776c105aacfda559a1ebf49cb2220599652f6c48",
|
|
171
173
|
"devDependencies": {
|
|
172
|
-
"@types/async": "3.2.
|
|
174
|
+
"@types/async": "3.2.10",
|
|
173
175
|
"@types/atob": "2.1.2",
|
|
174
|
-
"@types/body-parser": "1.19.
|
|
176
|
+
"@types/body-parser": "1.19.2",
|
|
175
177
|
"@types/busboy": "0.3.1",
|
|
176
178
|
"@types/cookie-parser": "1.4.2",
|
|
177
179
|
"@types/cors": "2.8.12",
|
|
178
180
|
"@types/deep-diff": "1.0.1",
|
|
179
181
|
"@types/destroy": "1.0.0",
|
|
180
182
|
"@types/express": "4.17.13",
|
|
181
|
-
"@types/express-pino-logger": "4.0.
|
|
183
|
+
"@types/express-pino-logger": "4.0.3",
|
|
182
184
|
"@types/express-session": "1.17.4",
|
|
183
185
|
"@types/flat": "5.0.2",
|
|
184
186
|
"@types/fs-extra": "9.0.13",
|
|
185
187
|
"@types/inquirer": "8.1.3",
|
|
186
|
-
"@types/jest": "27.0.
|
|
187
|
-
"@types/js-yaml": "4.0.
|
|
188
|
+
"@types/jest": "27.0.3",
|
|
189
|
+
"@types/js-yaml": "4.0.5",
|
|
188
190
|
"@types/json2csv": "5.0.3",
|
|
189
|
-
"@types/jsonwebtoken": "8.5.
|
|
191
|
+
"@types/jsonwebtoken": "8.5.6",
|
|
190
192
|
"@types/keyv": "3.1.3",
|
|
191
193
|
"@types/ldapjs": "2.2.2",
|
|
192
|
-
"@types/lodash": "4.14.
|
|
194
|
+
"@types/lodash": "4.14.177",
|
|
193
195
|
"@types/mime-types": "2.1.1",
|
|
194
196
|
"@types/ms": "0.7.31",
|
|
195
|
-
"@types/node": "16.11.
|
|
197
|
+
"@types/node": "16.11.9",
|
|
196
198
|
"@types/node-cron": "2.0.5",
|
|
197
199
|
"@types/nodemailer": "6.4.4",
|
|
198
200
|
"@types/object-hash": "2.2.1",
|
|
199
201
|
"@types/qs": "6.9.7",
|
|
200
|
-
"@types/
|
|
202
|
+
"@types/sanitize-html": "^2.5.0",
|
|
203
|
+
"@types/sharp": "0.29.4",
|
|
201
204
|
"@types/stream-json": "1.7.1",
|
|
202
205
|
"@types/supertest": "2.0.11",
|
|
203
|
-
"@types/uuid": "8.3.
|
|
206
|
+
"@types/uuid": "8.3.3",
|
|
204
207
|
"@types/uuid-validate": "0.0.1",
|
|
205
208
|
"@types/wellknown": "0.5.1",
|
|
206
209
|
"copyfiles": "2.4.1",
|
|
@@ -208,6 +211,6 @@
|
|
|
208
211
|
"jest": "27.3.1",
|
|
209
212
|
"ts-jest": "27.0.7",
|
|
210
213
|
"ts-node-dev": "1.1.8",
|
|
211
|
-
"typescript": "4.
|
|
214
|
+
"typescript": "4.5.2"
|
|
212
215
|
}
|
|
213
216
|
}
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { Knex } from 'knex';
|
|
2
|
-
import { HelperFn } from '../types';
|
|
3
|
-
export declare class HelperOracle implements HelperFn {
|
|
4
|
-
private knex;
|
|
5
|
-
constructor(knex: Knex);
|
|
6
|
-
year(table: string, column: string): Knex.Raw;
|
|
7
|
-
month(table: string, column: string): Knex.Raw;
|
|
8
|
-
week(table: string, column: string): Knex.Raw;
|
|
9
|
-
day(table: string, column: string): Knex.Raw;
|
|
10
|
-
weekday(table: string, column: string): Knex.Raw;
|
|
11
|
-
hour(table: string, column: string): Knex.Raw;
|
|
12
|
-
minute(table: string, column: string): Knex.Raw;
|
|
13
|
-
second(table: string, column: string): Knex.Raw;
|
|
14
|
-
}
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { Knex } from 'knex';
|
|
2
|
-
import { HelperFn } from '../types';
|
|
3
|
-
export declare class HelperPostgres implements HelperFn {
|
|
4
|
-
private knex;
|
|
5
|
-
constructor(knex: Knex);
|
|
6
|
-
year(table: string, column: string): Knex.Raw;
|
|
7
|
-
month(table: string, column: string): Knex.Raw;
|
|
8
|
-
week(table: string, column: string): Knex.Raw;
|
|
9
|
-
day(table: string, column: string): Knex.Raw;
|
|
10
|
-
weekday(table: string, column: string): Knex.Raw;
|
|
11
|
-
hour(table: string, column: string): Knex.Raw;
|
|
12
|
-
minute(table: string, column: string): Knex.Raw;
|
|
13
|
-
second(table: string, column: string): Knex.Raw;
|
|
14
|
-
}
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.HelperSQLite = void 0;
|
|
4
|
-
class HelperSQLite {
|
|
5
|
-
constructor(knex) {
|
|
6
|
-
this.knex = knex;
|
|
7
|
-
}
|
|
8
|
-
year(table, column) {
|
|
9
|
-
return this.knex.raw("strftime('%Y', ??.??)", [table, column]);
|
|
10
|
-
}
|
|
11
|
-
month(table, column) {
|
|
12
|
-
return this.knex.raw("strftime('%m', ??.??)", [table, column]);
|
|
13
|
-
}
|
|
14
|
-
week(table, column) {
|
|
15
|
-
return this.knex.raw("strftime('%W', ??.??)", [table, column]);
|
|
16
|
-
}
|
|
17
|
-
day(table, column) {
|
|
18
|
-
return this.knex.raw("strftime('%d', ??.??)", [table, column]);
|
|
19
|
-
}
|
|
20
|
-
weekday(table, column) {
|
|
21
|
-
return this.knex.raw("strftime('%w', ??.??)", [table, column]);
|
|
22
|
-
}
|
|
23
|
-
hour(table, column) {
|
|
24
|
-
return this.knex.raw("strftime('%H', ??.??)", [table, column]);
|
|
25
|
-
}
|
|
26
|
-
minute(table, column) {
|
|
27
|
-
return this.knex.raw("strftime('%M', ??.??)", [table, column]);
|
|
28
|
-
}
|
|
29
|
-
second(table, column) {
|
|
30
|
-
return this.knex.raw("strftime('%S', ??.??)", [table, column]);
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
exports.HelperSQLite = HelperSQLite;
|