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
package/dist/services/items.js
CHANGED
|
@@ -213,8 +213,16 @@ class ItemsService {
|
|
|
213
213
|
if (records === null) {
|
|
214
214
|
throw new exceptions_1.ForbiddenException();
|
|
215
215
|
}
|
|
216
|
+
const filteredRecords = await emitter_1.default.emitFilter(`${this.eventScope}.read`, records, {
|
|
217
|
+
query,
|
|
218
|
+
collection: this.collection,
|
|
219
|
+
}, {
|
|
220
|
+
database: this.knex,
|
|
221
|
+
schema: this.schema,
|
|
222
|
+
accountability: this.accountability,
|
|
223
|
+
});
|
|
216
224
|
emitter_1.default.emitAction(`${this.eventScope}.read`, {
|
|
217
|
-
payload:
|
|
225
|
+
payload: filteredRecords,
|
|
218
226
|
query,
|
|
219
227
|
collection: this.collection,
|
|
220
228
|
}, {
|
|
@@ -222,23 +230,15 @@ class ItemsService {
|
|
|
222
230
|
schema: this.schema,
|
|
223
231
|
accountability: this.accountability,
|
|
224
232
|
});
|
|
225
|
-
return
|
|
233
|
+
return filteredRecords;
|
|
226
234
|
}
|
|
227
235
|
/**
|
|
228
236
|
* Get single item by primary key
|
|
229
237
|
*/
|
|
230
|
-
async readOne(key, query, opts) {
|
|
231
|
-
query = query !== null && query !== void 0 ? query : {};
|
|
238
|
+
async readOne(key, query = {}, opts) {
|
|
232
239
|
const primaryKeyField = this.schema.collections[this.collection].primary;
|
|
233
|
-
const
|
|
234
|
-
|
|
235
|
-
filter: {
|
|
236
|
-
...(query.filter || {}),
|
|
237
|
-
[primaryKeyField]: {
|
|
238
|
-
_eq: key,
|
|
239
|
-
},
|
|
240
|
-
},
|
|
241
|
-
};
|
|
240
|
+
const filterWithKey = (0, lodash_1.assign)({}, query.filter, { [primaryKeyField]: { _eq: key } });
|
|
241
|
+
const queryWithKey = (0, lodash_1.assign)({}, query, { filter: filterWithKey });
|
|
242
242
|
const results = await this.readByQuery(queryWithKey, opts);
|
|
243
243
|
if (results.length === 0) {
|
|
244
244
|
throw new exceptions_1.ForbiddenException();
|
|
@@ -248,23 +248,12 @@ class ItemsService {
|
|
|
248
248
|
/**
|
|
249
249
|
* Get multiple items by primary keys
|
|
250
250
|
*/
|
|
251
|
-
async readMany(keys, query, opts) {
|
|
252
|
-
|
|
251
|
+
async readMany(keys, query = {}, opts) {
|
|
252
|
+
var _a;
|
|
253
253
|
const primaryKeyField = this.schema.collections[this.collection].primary;
|
|
254
|
-
const
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
_and: [
|
|
258
|
-
query.filter || {},
|
|
259
|
-
{
|
|
260
|
-
[primaryKeyField]: {
|
|
261
|
-
_in: keys,
|
|
262
|
-
},
|
|
263
|
-
},
|
|
264
|
-
],
|
|
265
|
-
},
|
|
266
|
-
};
|
|
267
|
-
const results = await this.readByQuery(queryWithKeys, opts);
|
|
254
|
+
const filterWithKey = { _and: [{ [primaryKeyField]: { _in: keys } }, (_a = query.filter) !== null && _a !== void 0 ? _a : {}] };
|
|
255
|
+
const queryWithKey = (0, lodash_1.assign)({}, query, { filter: filterWithKey });
|
|
256
|
+
const results = await this.readByQuery(queryWithKey, opts);
|
|
268
257
|
return results;
|
|
269
258
|
}
|
|
270
259
|
/**
|
|
@@ -33,10 +33,10 @@ class MailService {
|
|
|
33
33
|
async send(options) {
|
|
34
34
|
const { template, ...emailOptions } = options;
|
|
35
35
|
let { html } = options;
|
|
36
|
-
const
|
|
36
|
+
const defaultTemplateData = await this.getDefaultTemplateData();
|
|
37
|
+
const from = `${defaultTemplateData.projectName} <${options.from || env_1.default.EMAIL_FROM}>`;
|
|
37
38
|
if (template) {
|
|
38
39
|
let templateData = template.data;
|
|
39
|
-
const defaultTemplateData = await this.getDefaultTemplateData();
|
|
40
40
|
templateData = {
|
|
41
41
|
...defaultTemplateData,
|
|
42
42
|
...templateData,
|
|
@@ -1,95 +1,163 @@
|
|
|
1
|
-
<!
|
|
2
|
-
<html
|
|
3
|
-
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
4
3
|
<head>
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
4
|
+
|
|
5
|
+
<title>{{ projectName }} Email Service</title>
|
|
6
|
+
|
|
7
|
+
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
|
8
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
9
|
+
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
|
10
|
+
|
|
11
|
+
<style type="text/css" id="hs-inline-css">
|
|
12
|
+
/*<![CDATA[*/
|
|
13
|
+
|
|
14
|
+
/* CLIENT-SPECIFIC STYLES */
|
|
15
|
+
body, table, td, a {
|
|
16
|
+
-webkit-text-size-adjust: 100%;
|
|
17
|
+
-ms-text-size-adjust: 100%;
|
|
18
|
+
-webkit-font-smoothing: antialiased;
|
|
19
|
+
}
|
|
20
|
+
table, td { mso-table-lspace: 0pt; mso-table-rspace: 0pt; }
|
|
21
|
+
img { -ms-interpolation-mode: bicubic; }
|
|
22
|
+
|
|
23
|
+
/* RESET STYLES */
|
|
24
|
+
img { border: 0; height: auto; line-height: 100%; outline: none; text-decoration: none; }
|
|
25
|
+
table { border-collapse: collapse !important; }
|
|
26
|
+
body { height: 100% !important; margin: 0 !important; padding: 0 !important; width: 100% !important; }
|
|
27
|
+
|
|
28
|
+
/* iOS BLUE LINKS */
|
|
29
|
+
a[x-apple-data-detectors] {
|
|
30
|
+
color: inherit !important;
|
|
31
|
+
text-decoration: none !important;
|
|
32
|
+
font-size: inherit !important;
|
|
33
|
+
font-family: inherit !important;
|
|
34
|
+
font-weight: inherit !important;
|
|
35
|
+
line-height: inherit !important;
|
|
36
|
+
}
|
|
37
|
+
body a {
|
|
38
|
+
color: #00C897;
|
|
39
|
+
text-decoration: none;
|
|
40
|
+
}
|
|
41
|
+
hr {
|
|
42
|
+
width:66%;
|
|
43
|
+
margin:40px auto;
|
|
44
|
+
border:1px solid #d3dae4;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/* MOBILE STYLES */
|
|
48
|
+
@media screen and (max-width: 600px) {
|
|
49
|
+
.img-max {
|
|
50
|
+
width: 100% !important;
|
|
51
|
+
max-width: 100% !important;
|
|
52
|
+
height: auto !important;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
.max-width {
|
|
56
|
+
max-width: 100% !important;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
#content {
|
|
60
|
+
padding-left: 5% !important;
|
|
61
|
+
padding-right: 5% !important;
|
|
62
|
+
padding-top: 30px !important;
|
|
63
|
+
padding-bottom: 30px !important;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/* DARK MODE */
|
|
68
|
+
@media (prefers-color-scheme: dark) {
|
|
69
|
+
#background {
|
|
70
|
+
background-color: #172940 !important;
|
|
71
|
+
}
|
|
72
|
+
#content {
|
|
73
|
+
background-color: #071930 !important;
|
|
74
|
+
color: #FFFFFF !important;
|
|
75
|
+
}
|
|
76
|
+
.link {
|
|
77
|
+
color: #00c897 !important;
|
|
78
|
+
}
|
|
79
|
+
.button {
|
|
80
|
+
background-color:#0BA582 !important;
|
|
81
|
+
}
|
|
82
|
+
hr {
|
|
83
|
+
border:1px solid #172940 !important;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/* ANDROID CENTER FIX */
|
|
88
|
+
div[style*="margin: 16px 0;"] {
|
|
89
|
+
margin: 0 !important;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
blockquote {
|
|
93
|
+
background: #f0f4f9 !important;
|
|
94
|
+
border-radius: 4px !important;
|
|
95
|
+
margin: 0 !important;
|
|
96
|
+
padding: 24px !important;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
blockquote > p {
|
|
100
|
+
margin: 0 !important;
|
|
101
|
+
}
|
|
102
|
+
/*]]>*/
|
|
103
|
+
</style>
|
|
104
|
+
|
|
105
|
+
<meta name="generator" content="Directus">
|
|
106
|
+
<meta property="og:url" content="http://directus-20534155.hs-sites.com/7dea362b-3fac-3e00-956a-4952a3d4f474">
|
|
107
|
+
<meta name="x-apple-disable-message-reformatting">
|
|
108
|
+
<meta name="robots" content="noindex,follow">
|
|
109
|
+
|
|
50
110
|
</head>
|
|
111
|
+
<body style="-webkit-text-size-adjust:100%; -ms-text-size-adjust:100%; height:100% !important; width:100% !important; margin:0 !important; padding:0; !important background-color:#f6f6f6" bgcolor="#f6f6f6">
|
|
51
112
|
|
|
52
|
-
|
|
53
|
-
<
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
<img src="{{ projectLogo }}" alt="{{ projectName }}" width="130"
|
|
62
|
-
style="display: block;" />
|
|
63
|
-
</td>
|
|
64
|
-
</tr>
|
|
113
|
+
<!-- HIDDEN PREHEADER TEXT -->
|
|
114
|
+
<div class="preview-text" style="display:none;font-size:1px;color:#172940;line-height:1px;max-height:0px;max-width:0px;opacity:0;overflow:hidden;"> </div>
|
|
115
|
+
|
|
116
|
+
<table role="presentation" border="0" cellpadding="0" cellspacing="0" width="100%" style="-webkit-text-size-adjust:100%; -ms-text-size-adjust:100%; mso-table-lspace:0pt; mso-table-rspace:0pt; border-collapse:collapse !important">
|
|
117
|
+
<tbody>
|
|
118
|
+
<tr>
|
|
119
|
+
<td id="background" align="center" valign="top" width="100%" bgcolor="#172940" style="-webkit-text-size-adjust:100%; -ms-text-size-adjust:100%; mso-table-lspace:0pt; mso-table-rspace:0pt; background-size:cover; padding:50px 15px 0 15px; background-color:#172940">
|
|
120
|
+
<!--[if (gte mso 9)|(IE)]>
|
|
121
|
+
<table role="presentation" align="center" border="0" cellspacing="0" cellpadding="0" width="600">
|
|
65
122
|
<tr>
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
123
|
+
<td align="center" valign="top" width="600">
|
|
124
|
+
<![endif]-->
|
|
125
|
+
<table role="presentation" align="center" border="0" cellpadding="0" cellspacing="0" width="100%" style="-webkit-text-size-adjust:100%; -ms-text-size-adjust:100%; mso-table-lspace:0pt; mso-table-rspace:0pt; border-collapse:collapse !important; max-width:600px">
|
|
126
|
+
<tbody>
|
|
127
|
+
<tr>
|
|
128
|
+
<td align="left" valign="top" style="-webkit-text-size-adjust:100%; -ms-text-size-adjust:100%; mso-table-lspace:0pt; mso-table-rspace:0pt; padding:0 0 30px 0">
|
|
129
|
+
<table><tbody><tr><td align="center" valign="middle" style="background-color:{{ projectColor }};width:48px;height:48px;border-radius:4px;padding:6px;">
|
|
130
|
+
<img id="logo" src="{{ projectLogo }}" alt="{{ projectName }} Logo" width="40" height="auto" border="0" style="-ms-interpolation-mode:bicubic; border:0; height:auto; line-height:100%; outline:none; text-decoration:none; display:block; width:40px;object-fit:contain;">
|
|
131
|
+
</td></tr></tbody></table>
|
|
132
|
+
</td>
|
|
133
|
+
</tr>
|
|
134
|
+
<tr>
|
|
135
|
+
<td id="content" align="left" valign="top" style="-webkit-text-size-adjust:100%; -ms-text-size-adjust:100%; mso-table-lspace:0pt; mso-table-rspace:0pt; padding:40px 50px 50px 50px; font-family:Open Sans, Helvetica, Arial, sans-serif; border-radius:4px; box-shadow:0 4px 0 #15253A; background-color:#FFFFFE; color:#172940; font-size:15px; line-height:26px; margin:0" bgcolor="#FFFFFE">
|
|
136
|
+
<div id="hs_cos_wrapper_email_template_main_email_body" class="hs_cos_wrapper hs_cos_wrapper_widget hs_cos_wrapper_type_module" style="color: inherit; font-size: inherit; line-height: inherit;" data-hs-cos-general-type="widget" data-hs-cos-type="module">
|
|
137
|
+
|
|
71
138
|
{% block content %}{{ html }}{% endblock %}
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
<tr>
|
|
81
|
-
<td style="color:#b0bec5; font-family:Helvetica, Arial, sans-serif; font-size:12px;"
|
|
82
|
-
width="75%">
|
|
139
|
+
|
|
140
|
+
</div>
|
|
141
|
+
</td>
|
|
142
|
+
</tr>
|
|
143
|
+
<tr>
|
|
144
|
+
<td align="center" valign="middle" style="-webkit-text-size-adjust:100%; -ms-text-size-adjust:100%; mso-table-lspace:0pt; mso-table-rspace:0pt; padding:25px 0; font-family:Open Sans, Helvetica, Arial, sans-serif; color:#FFFFFE">
|
|
145
|
+
<p style="margin-bottom: 1em; color: #A2B5CD;font-size: 12px; line-height: 16px;">
|
|
146
|
+
Sent by the team at {{ projectName }} — <a style="-webkit-text-size-adjust:100%; -ms-text-size-adjust:100%; text-decoration:none; color:#A2B5CD" class="unsubscribe" data-unsubscribe="true" href="{{ url }}" data-hs-link-id="0" target="_blank">Manage Emails</a><br>
|
|
83
147
|
{% block footer %}{% endblock %}
|
|
84
|
-
</
|
|
85
|
-
</
|
|
86
|
-
</
|
|
87
|
-
</
|
|
148
|
+
</p>
|
|
149
|
+
</td>
|
|
150
|
+
</tr>
|
|
151
|
+
</tbody>
|
|
152
|
+
</table>
|
|
153
|
+
<!--[if (gte mso 9)|(IE)]>
|
|
154
|
+
</td>
|
|
88
155
|
</tr>
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
156
|
+
</table>
|
|
157
|
+
<![endif]-->
|
|
158
|
+
</td>
|
|
159
|
+
</tr>
|
|
160
|
+
</tbody>
|
|
92
161
|
</table>
|
|
93
162
|
</body>
|
|
94
|
-
|
|
95
163
|
</html>
|
|
@@ -7,17 +7,18 @@
|
|
|
7
7
|
|
|
8
8
|
<p style="text-align: center; padding: 20px 0;">
|
|
9
9
|
<a href="{{ url }}">
|
|
10
|
-
|
|
10
|
+
<b>Reset Your Password</b>
|
|
11
11
|
</a>
|
|
12
12
|
</p>
|
|
13
13
|
|
|
14
14
|
<p>
|
|
15
15
|
<b>Important: This link will expire in 24 hours.</b>
|
|
16
|
+
<br>
|
|
16
17
|
</p>
|
|
17
18
|
|
|
18
19
|
<p>
|
|
19
20
|
Thank you,<br>
|
|
20
|
-
{{ projectName }}
|
|
21
|
+
The {{ projectName }} Team
|
|
21
22
|
</p>
|
|
22
23
|
|
|
23
24
|
{% endblock %}
|
|
@@ -2,18 +2,18 @@
|
|
|
2
2
|
{% block content %}
|
|
3
3
|
|
|
4
4
|
<p>
|
|
5
|
-
|
|
5
|
+
You have been invited to join <i>{{ projectName }}</i>. Please click the button below to accept this invitation and join the project:
|
|
6
6
|
</p>
|
|
7
7
|
|
|
8
8
|
<p style="text-align: center; padding: 20px 0;">
|
|
9
9
|
<a href="{{ url }}">
|
|
10
|
-
Join {{ projectName }}
|
|
10
|
+
<b>Join {{ projectName }}</b>
|
|
11
11
|
</a>
|
|
12
12
|
</p>
|
|
13
13
|
|
|
14
14
|
<p>
|
|
15
|
-
Thank
|
|
16
|
-
{{ projectName }}
|
|
15
|
+
Thank you,<br>
|
|
16
|
+
The {{ projectName }} Team
|
|
17
17
|
</p>
|
|
18
18
|
|
|
19
19
|
{% endblock %}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { UsersService, MailService } from '.';
|
|
2
|
+
import { AbstractServiceOptions, PrimaryKey } from '../types';
|
|
3
|
+
import { ItemsService, MutationOptions } from './items';
|
|
4
|
+
import { Notification } from '@directus/shared/types';
|
|
5
|
+
export declare class NotificationsService extends ItemsService {
|
|
6
|
+
usersService: UsersService;
|
|
7
|
+
mailService: MailService;
|
|
8
|
+
constructor(options: AbstractServiceOptions);
|
|
9
|
+
createOne(data: Partial<Notification>, opts?: MutationOptions): Promise<PrimaryKey>;
|
|
10
|
+
createMany(data: Partial<Notification>[], opts?: MutationOptions): Promise<PrimaryKey[]>;
|
|
11
|
+
sendEmail(data: Partial<Notification>): Promise<void>;
|
|
12
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.NotificationsService = void 0;
|
|
4
|
+
const _1 = require(".");
|
|
5
|
+
const items_1 = require("./items");
|
|
6
|
+
const md_1 = require("../utils/md");
|
|
7
|
+
class NotificationsService extends items_1.ItemsService {
|
|
8
|
+
constructor(options) {
|
|
9
|
+
super('directus_notifications', options);
|
|
10
|
+
this.usersService = new _1.UsersService({ schema: this.schema });
|
|
11
|
+
this.mailService = new _1.MailService({ schema: this.schema, accountability: this.accountability });
|
|
12
|
+
}
|
|
13
|
+
async createOne(data, opts) {
|
|
14
|
+
await this.sendEmail(data);
|
|
15
|
+
return super.createOne(data, opts);
|
|
16
|
+
}
|
|
17
|
+
async createMany(data, opts) {
|
|
18
|
+
for (const notification of data) {
|
|
19
|
+
await this.sendEmail(notification);
|
|
20
|
+
}
|
|
21
|
+
return super.createMany(data, opts);
|
|
22
|
+
}
|
|
23
|
+
async sendEmail(data) {
|
|
24
|
+
if (data.recipient) {
|
|
25
|
+
const user = await this.usersService.readOne(data.recipient, { fields: ['email', 'email_notifications'] });
|
|
26
|
+
if (user.email && user.email_notifications === true) {
|
|
27
|
+
await this.mailService.send({
|
|
28
|
+
template: {
|
|
29
|
+
name: 'base',
|
|
30
|
+
data: {
|
|
31
|
+
html: data.message ? (0, md_1.md)(data.message) : '',
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
to: user.email,
|
|
35
|
+
subject: data.subject,
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
exports.NotificationsService = NotificationsService;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Knex } from 'knex';
|
|
2
2
|
import { AbstractServiceOptions, Item, PrimaryKey, SchemaOverview } from '../types';
|
|
3
3
|
import { Accountability } from '@directus/shared/types';
|
|
4
|
+
import { Helpers } from '../database/helpers';
|
|
4
5
|
declare type Action = 'create' | 'read' | 'update';
|
|
5
6
|
declare type Transformers = {
|
|
6
7
|
[type: string]: (context: {
|
|
@@ -18,6 +19,7 @@ declare type Transformers = {
|
|
|
18
19
|
export declare class PayloadService {
|
|
19
20
|
accountability: Accountability | null;
|
|
20
21
|
knex: Knex;
|
|
22
|
+
helpers: Helpers;
|
|
21
23
|
collection: string;
|
|
22
24
|
schema: SchemaOverview;
|
|
23
25
|
constructor(collection: string, options: AbstractServiceOptions);
|
package/dist/services/payload.js
CHANGED
|
@@ -13,7 +13,7 @@ const exceptions_1 = require("../exceptions");
|
|
|
13
13
|
const utils_1 = require("@directus/shared/utils");
|
|
14
14
|
const items_1 = require("./items");
|
|
15
15
|
const flat_1 = require("flat");
|
|
16
|
-
const
|
|
16
|
+
const helpers_1 = require("../database/helpers");
|
|
17
17
|
const wellknown_1 = require("wellknown");
|
|
18
18
|
const generate_hash_1 = require("../utils/generate-hash");
|
|
19
19
|
/**
|
|
@@ -111,6 +111,7 @@ class PayloadService {
|
|
|
111
111
|
};
|
|
112
112
|
this.accountability = options.accountability || null;
|
|
113
113
|
this.knex = options.knex || (0, database_1.default)();
|
|
114
|
+
this.helpers = (0, helpers_1.getHelpers)(this.knex);
|
|
114
115
|
this.collection = collection;
|
|
115
116
|
this.schema = options.schema;
|
|
116
117
|
return this;
|
|
@@ -188,10 +189,9 @@ class PayloadService {
|
|
|
188
189
|
* to check if the value is a raw instance before stringifying it in the next step.
|
|
189
190
|
*/
|
|
190
191
|
processGeometries(payloads, action) {
|
|
191
|
-
const helper = (0, geometry_1.getGeometryHelper)();
|
|
192
192
|
const process = action == 'read'
|
|
193
193
|
? (value) => (typeof value === 'string' ? (0, wellknown_1.parse)(value) : value)
|
|
194
|
-
: (value) =>
|
|
194
|
+
: (value) => this.helpers.st.fromGeoJSON(typeof value == 'string' ? JSON.parse(value) : value);
|
|
195
195
|
const fieldsInCollection = Object.entries(this.schema.collections[this.collection].fields);
|
|
196
196
|
const geometryColumns = fieldsInCollection.filter(([_, field]) => field.type.startsWith('geometry'));
|
|
197
197
|
for (const [name] of geometryColumns) {
|
package/dist/services/users.js
CHANGED
|
@@ -181,6 +181,7 @@ class UsersService extends items_1.ItemsService {
|
|
|
181
181
|
*/
|
|
182
182
|
async deleteMany(keys, opts) {
|
|
183
183
|
await this.checkRemainingAdminExistence(keys);
|
|
184
|
+
await this.knex('directus_notifications').update({ sender: null }).whereIn('sender', keys);
|
|
184
185
|
await super.deleteMany(keys, opts);
|
|
185
186
|
return keys;
|
|
186
187
|
}
|
|
@@ -9,6 +9,7 @@ export declare type CollectionMeta = {
|
|
|
9
9
|
translations: Record<string, string>;
|
|
10
10
|
item_duplication_fields: string[] | null;
|
|
11
11
|
accountability: 'all' | 'accountability' | null;
|
|
12
|
+
group: string | null;
|
|
12
13
|
};
|
|
13
14
|
export declare type Collection = {
|
|
14
15
|
collection: string;
|
|
@@ -11,8 +11,7 @@ const exceptions_1 = require("../exceptions");
|
|
|
11
11
|
const apply_function_to_column_name_1 = require("./apply-function-to-column-name");
|
|
12
12
|
const get_column_1 = require("./get-column");
|
|
13
13
|
const get_relation_type_1 = require("./get-relation-type");
|
|
14
|
-
const
|
|
15
|
-
const date_1 = require("../database/helpers/date");
|
|
14
|
+
const helpers_1 = require("../database/helpers");
|
|
16
15
|
const generateAlias = (0, nanoid_1.customAlphabet)('abcdefghijklmnopqrstuvwxyz', 5);
|
|
17
16
|
/**
|
|
18
17
|
* Apply the Query to a given Knex query builder instance
|
|
@@ -45,7 +44,7 @@ function applyQuery(knex, collection, dbQuery, query, schema, subQuery = false)
|
|
|
45
44
|
applySearch(schema, dbQuery, query.search, collection);
|
|
46
45
|
}
|
|
47
46
|
if (query.group) {
|
|
48
|
-
dbQuery.groupBy(query.group.map(apply_function_to_column_name_1.applyFunctionToColumnName));
|
|
47
|
+
dbQuery.groupBy(`${collection}.${query.group.map(apply_function_to_column_name_1.applyFunctionToColumnName)}`);
|
|
49
48
|
}
|
|
50
49
|
if (query.aggregate) {
|
|
51
50
|
applyAggregate(dbQuery, query.aggregate, collection);
|
|
@@ -117,6 +116,7 @@ exports.default = applyQuery;
|
|
|
117
116
|
* ```
|
|
118
117
|
*/
|
|
119
118
|
function applyFilter(knex, schema, rootQuery, rootFilter, collection, subQuery = false) {
|
|
119
|
+
const helpers = (0, helpers_1.getHelpers)(knex);
|
|
120
120
|
const relations = schema.relations;
|
|
121
121
|
const aliasMap = {};
|
|
122
122
|
addJoins(rootQuery, rootFilter, collection);
|
|
@@ -273,16 +273,15 @@ function applyFilter(knex, schema, rootQuery, rootFilter, collection, subQuery =
|
|
|
273
273
|
query.where(key, '!=', '');
|
|
274
274
|
});
|
|
275
275
|
}
|
|
276
|
-
const dateHelper = (0, date_1.getDateHelper)();
|
|
277
276
|
const [collection, field] = key.split('.');
|
|
278
277
|
if (collection in schema.collections && field in schema.collections[collection].fields) {
|
|
279
278
|
const type = schema.collections[collection].fields[field].type;
|
|
280
279
|
if (['date', 'dateTime', 'time', 'timestamp'].includes(type)) {
|
|
281
280
|
if (Array.isArray(compareValue)) {
|
|
282
|
-
compareValue = compareValue.map((val) =>
|
|
281
|
+
compareValue = compareValue.map((val) => helpers.date.parse(val));
|
|
283
282
|
}
|
|
284
283
|
else {
|
|
285
|
-
compareValue =
|
|
284
|
+
compareValue = helpers.date.parse(compareValue);
|
|
286
285
|
}
|
|
287
286
|
}
|
|
288
287
|
}
|
|
@@ -361,18 +360,17 @@ function applyFilter(knex, schema, rootQuery, rootFilter, collection, subQuery =
|
|
|
361
360
|
value = value.split(',');
|
|
362
361
|
dbQuery[logical].whereNotBetween(selectionRaw, value);
|
|
363
362
|
}
|
|
364
|
-
const geometryHelper = (0, geometry_1.getGeometryHelper)();
|
|
365
363
|
if (operator == '_intersects') {
|
|
366
|
-
dbQuery[logical].whereRaw(
|
|
364
|
+
dbQuery[logical].whereRaw(helpers.st.intersects(key, compareValue));
|
|
367
365
|
}
|
|
368
366
|
if (operator == '_nintersects') {
|
|
369
|
-
dbQuery[logical].whereRaw(
|
|
367
|
+
dbQuery[logical].whereRaw(helpers.st.nintersects(key, compareValue));
|
|
370
368
|
}
|
|
371
369
|
if (operator == '_intersects_bbox') {
|
|
372
|
-
dbQuery[logical].whereRaw(
|
|
370
|
+
dbQuery[logical].whereRaw(helpers.st.intersects_bbox(key, compareValue));
|
|
373
371
|
}
|
|
374
372
|
if (operator == '_nintersects_bbox') {
|
|
375
|
-
dbQuery[logical].whereRaw(
|
|
373
|
+
dbQuery[logical].whereRaw(helpers.st.nintersects_bbox(key, compareValue));
|
|
376
374
|
}
|
|
377
375
|
}
|
|
378
376
|
function getWhereColumn(path, collection) {
|