directus 9.17.0 → 9.17.1

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.
@@ -292,7 +292,7 @@ EXTENSIONS_AUTO_RELOAD=false
292
292
  EMAIL_FROM="no-reply@directus.io"
293
293
 
294
294
  # What to use to send emails. One of
295
- # sendmail, smtp, mailgun, ses.
295
+ # sendmail, smtp, mailgun, sendgrid, ses.
296
296
  EMAIL_TRANSPORT="sendmail"
297
297
  EMAIL_SENDMAIL_NEW_LINE="unix"
298
298
  EMAIL_SENDMAIL_PATH="/usr/sbin/sendmail"
@@ -319,3 +319,6 @@ EMAIL_SENDMAIL_PATH="/usr/sbin/sendmail"
319
319
  ## Email (Mailgun Transport)
320
320
  # EMAIL_MAILGUN_API_KEY="key-1234123412341234"
321
321
  # EMAIL_MAILGUN_DOMAIN="a domain name from https://app.mailgun.com/app/sending/domains"
322
+
323
+ ## Email (SendGrid Transport)
324
+ # EMAIL_SENDGRID_API_KEY="key-1234123412341234"
@@ -1,5 +1,5 @@
1
1
  import { SchemaHelper } from '../types';
2
2
  export declare class SchemaHelperSQLite extends SchemaHelper {
3
- preColumnDelete(): Promise<boolean>;
4
- postColumnDelete(): Promise<void>;
3
+ preColumnChange(): Promise<boolean>;
4
+ postColumnChange(): Promise<void>;
5
5
  }
@@ -3,14 +3,14 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.SchemaHelperSQLite = void 0;
4
4
  const types_1 = require("../types");
5
5
  class SchemaHelperSQLite extends types_1.SchemaHelper {
6
- async preColumnDelete() {
6
+ async preColumnChange() {
7
7
  const foreignCheckStatus = (await this.knex.raw('PRAGMA foreign_keys'))[0].foreign_keys === 1;
8
8
  if (foreignCheckStatus) {
9
9
  await this.knex.raw('PRAGMA foreign_keys = OFF');
10
10
  }
11
11
  return foreignCheckStatus;
12
12
  }
13
- async postColumnDelete() {
13
+ async postColumnChange() {
14
14
  await this.knex.raw('PRAGMA foreign_keys = ON');
15
15
  }
16
16
  }
@@ -11,7 +11,7 @@ export declare abstract class SchemaHelper extends DatabaseHelper {
11
11
  changeNullable(table: string, column: string, nullable: boolean): Promise<void>;
12
12
  changeToType(table: string, column: string, type: typeof KNEX_TYPES[number], options?: Options): Promise<void>;
13
13
  protected changeToTypeByCopy(table: string, column: string, type: typeof KNEX_TYPES[number], options: Options): Promise<void>;
14
- preColumnDelete(): Promise<boolean>;
15
- postColumnDelete(): Promise<void>;
14
+ preColumnChange(): Promise<boolean>;
15
+ postColumnChange(): Promise<void>;
16
16
  }
17
17
  export {};
@@ -56,10 +56,10 @@ class SchemaHelper extends types_1.DatabaseHelper {
56
56
  await this.changeNullable(table, column, options.nullable);
57
57
  }
58
58
  }
59
- async preColumnDelete() {
59
+ async preColumnChange() {
60
60
  return false;
61
61
  }
62
- async postColumnDelete() {
62
+ async postColumnChange() {
63
63
  return;
64
64
  }
65
65
  }
package/dist/env.js CHANGED
@@ -165,6 +165,7 @@ const allowedEnvironmentVars = [
165
165
  'EMAIL_MAILGUN_API_KEY',
166
166
  'EMAIL_MAILGUN_DOMAIN',
167
167
  'EMAIL_MAILGUN_HOST',
168
+ 'EMAIL_SENDGRID_API_KEY',
168
169
  'EMAIL_SES_CREDENTIALS__ACCESS_KEY_ID',
169
170
  'EMAIL_SES_CREDENTIALS__SECRET_ACCESS_KEY',
170
171
  'EMAIL_SES_REGION',
package/dist/mailer.js CHANGED
@@ -57,6 +57,12 @@ function getMailer() {
57
57
  host: env_1.default.EMAIL_MAILGUN_HOST || 'api.mailgun.net',
58
58
  }));
59
59
  }
60
+ else if (transportName === 'sendgrid') {
61
+ const sg = require('nodemailer-sendgrid');
62
+ transporter = nodemailer_1.default.createTransport(sg({
63
+ apiKey: env_1.default.EMAIL_SENDGRID_API_KEY,
64
+ }));
65
+ }
60
66
  else {
61
67
  logger_1.default.warn('Illegal transport given for email. Check the EMAIL_TRANSPORT env var.');
62
68
  }
@@ -222,6 +222,7 @@ class FieldsService {
222
222
  if (this.accountability && this.accountability.admin !== true) {
223
223
  throw new exceptions_1.ForbiddenException();
224
224
  }
225
+ const runPostColumnChange = await this.helpers.schema.preColumnChange();
225
226
  try {
226
227
  const exists = field.field in this.schema.collections[collection].fields ||
227
228
  (0, lodash_1.isNil)(await this.knex.select('id').from('directus_fields').where({ collection, field: field.field }).first()) === false;
@@ -276,6 +277,9 @@ class FieldsService {
276
277
  });
277
278
  }
278
279
  finally {
280
+ if (runPostColumnChange) {
281
+ await this.helpers.schema.postColumnChange();
282
+ }
279
283
  if (this.cache && env_1.default.CACHE_AUTO_PURGE) {
280
284
  await this.cache.clear();
281
285
  }
@@ -286,6 +290,7 @@ class FieldsService {
286
290
  if (this.accountability && this.accountability.admin !== true) {
287
291
  throw new exceptions_1.ForbiddenException();
288
292
  }
293
+ const runPostColumnChange = await this.helpers.schema.preColumnChange();
289
294
  try {
290
295
  const hookAdjustedField = await emitter_1.default.emitFilter(`fields.update`, field, {
291
296
  keys: [field.field],
@@ -341,6 +346,9 @@ class FieldsService {
341
346
  return field.field;
342
347
  }
343
348
  finally {
349
+ if (runPostColumnChange) {
350
+ await this.helpers.schema.postColumnChange();
351
+ }
344
352
  if (this.cache && env_1.default.CACHE_AUTO_PURGE) {
345
353
  await this.cache.clear();
346
354
  }
@@ -351,7 +359,7 @@ class FieldsService {
351
359
  if (this.accountability && this.accountability.admin !== true) {
352
360
  throw new exceptions_1.ForbiddenException();
353
361
  }
354
- const runPostColumnDelete = await this.helpers.schema.preColumnDelete();
362
+ const runPostColumnChange = await this.helpers.schema.preColumnChange();
355
363
  try {
356
364
  await emitter_1.default.emitFilter('fields.delete', [field], {
357
365
  collection: collection,
@@ -440,8 +448,8 @@ class FieldsService {
440
448
  });
441
449
  }
442
450
  finally {
443
- if (runPostColumnDelete) {
444
- await this.helpers.schema.postColumnDelete();
451
+ if (runPostColumnChange) {
452
+ await this.helpers.schema.postColumnChange();
445
453
  }
446
454
  if (this.cache && env_1.default.CACHE_AUTO_PURGE) {
447
455
  await this.cache.clear();
@@ -5,6 +5,7 @@ import { PermissionsService } from './permissions';
5
5
  import SchemaInspector from '@directus/schema';
6
6
  import Keyv from 'keyv';
7
7
  import { AbstractServiceOptions } from '../types';
8
+ import { Helpers } from '../database/helpers';
8
9
  export declare class RelationsService {
9
10
  knex: Knex;
10
11
  permissionsService: PermissionsService;
@@ -13,6 +14,7 @@ export declare class RelationsService {
13
14
  schema: SchemaOverview;
14
15
  relationsItemService: ItemsService<RelationMeta>;
15
16
  systemCache: Keyv<any>;
17
+ helpers: Helpers;
16
18
  constructor(options: AbstractServiceOptions);
17
19
  readAll(collection?: string, opts?: QueryOptions): Promise<Relation[]>;
18
20
  readOne(collection: string, field: string): Promise<Relation>;
@@ -36,6 +36,7 @@ const schema_1 = __importDefault(require("@directus/schema"));
36
36
  const database_1 = __importStar(require("../database"));
37
37
  const get_default_index_name_1 = require("../utils/get-default-index-name");
38
38
  const cache_1 = require("../cache");
39
+ const helpers_1 = require("../database/helpers");
39
40
  class RelationsService {
40
41
  constructor(options) {
41
42
  this.knex = options.knex || (0, database_1.default)();
@@ -51,6 +52,7 @@ class RelationsService {
51
52
  // happens in `filterForbidden` down below
52
53
  });
53
54
  this.systemCache = (0, cache_1.getCache)().systemCache;
55
+ this.helpers = (0, helpers_1.getHelpers)(this.knex);
54
56
  }
55
57
  async readAll(collection, opts) {
56
58
  if (this.accountability && this.accountability.admin !== true && this.hasReadAccess === false) {
@@ -150,6 +152,7 @@ class RelationsService {
150
152
  if (existingRelation) {
151
153
  throw new exceptions_1.InvalidPayloadException(`Field "${relation.field}" in collection "${relation.collection}" already has an associated relationship`);
152
154
  }
155
+ const runPostColumnChange = await this.helpers.schema.preColumnChange();
153
156
  try {
154
157
  const metaRow = {
155
158
  ...(relation.meta || {}),
@@ -182,6 +185,9 @@ class RelationsService {
182
185
  });
183
186
  }
184
187
  finally {
188
+ if (runPostColumnChange) {
189
+ await this.helpers.schema.postColumnChange();
190
+ }
185
191
  await (0, cache_1.clearSystemCache)();
186
192
  }
187
193
  }
@@ -204,6 +210,7 @@ class RelationsService {
204
210
  if (!existingRelation) {
205
211
  throw new exceptions_1.InvalidPayloadException(`Field "${field}" in collection "${collection}" doesn't have a relationship.`);
206
212
  }
213
+ const runPostColumnChange = await this.helpers.schema.preColumnChange();
207
214
  try {
208
215
  await this.knex.transaction(async (trx) => {
209
216
  if (existingRelation.related_collection) {
@@ -247,6 +254,9 @@ class RelationsService {
247
254
  });
248
255
  }
249
256
  finally {
257
+ if (runPostColumnChange) {
258
+ await this.helpers.schema.postColumnChange();
259
+ }
250
260
  await (0, cache_1.clearSystemCache)();
251
261
  }
252
262
  }
@@ -267,6 +277,7 @@ class RelationsService {
267
277
  if (!existingRelation) {
268
278
  throw new exceptions_1.InvalidPayloadException(`Field "${field}" in collection "${collection}" doesn't have a relationship.`);
269
279
  }
280
+ const runPostColumnChange = await this.helpers.schema.preColumnChange();
270
281
  try {
271
282
  await this.knex.transaction(async (trx) => {
272
283
  var _a;
@@ -284,6 +295,9 @@ class RelationsService {
284
295
  });
285
296
  }
286
297
  finally {
298
+ if (runPostColumnChange) {
299
+ await this.helpers.schema.postColumnChange();
300
+ }
287
301
  await (0, cache_1.clearSystemCache)();
288
302
  }
289
303
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "directus",
3
- "version": "9.17.0",
3
+ "version": "9.17.1",
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.",
@@ -66,16 +66,16 @@
66
66
  ],
67
67
  "dependencies": {
68
68
  "@aws-sdk/client-ses": "^3.107.0",
69
- "@directus/app": "9.17.0",
70
- "@directus/drive": "9.17.0",
71
- "@directus/drive-azure": "9.17.0",
72
- "@directus/drive-gcs": "9.17.0",
73
- "@directus/drive-s3": "9.17.0",
69
+ "@directus/app": "9.17.1",
70
+ "@directus/drive": "9.17.1",
71
+ "@directus/drive-azure": "9.17.1",
72
+ "@directus/drive-gcs": "9.17.1",
73
+ "@directus/drive-s3": "9.17.1",
74
74
  "@directus/extensions-sdk": "^9.14.1",
75
75
  "@directus/format-title": "^9.15.0",
76
- "@directus/schema": "9.17.0",
77
- "@directus/shared": "9.17.0",
78
- "@directus/specs": "9.17.0",
76
+ "@directus/schema": "9.17.1",
77
+ "@directus/shared": "9.17.1",
78
+ "@directus/specs": "9.17.1",
79
79
  "@godaddy/terminus": "^4.10.2",
80
80
  "@rollup/plugin-alias": "^3.1.9",
81
81
  "@rollup/plugin-virtual": "^2.1.0",
@@ -147,7 +147,6 @@
147
147
  "snappy": "^7.1.1",
148
148
  "stream-json": "^1.7.4",
149
149
  "strip-bom-stream": "^4.0.0",
150
- "supertest": "^6.2.3",
151
150
  "tmp-promise": "^3.0.3",
152
151
  "update-check": "^1.5.4",
153
152
  "uuid": "^8.3.2",
@@ -161,6 +160,7 @@
161
160
  "memcached": "^2.2.2",
162
161
  "mysql": "^2.18.1",
163
162
  "nodemailer-mailgun-transport": "^2.1.4",
163
+ "nodemailer-sendgrid": "^1.0.3",
164
164
  "pg": "^8.7.3",
165
165
  "sqlite3": "^5.0.8",
166
166
  "tedious": "^13.0.0"
@@ -216,6 +216,7 @@
216
216
  "jest": "28.1.2",
217
217
  "knex-mock-client": "1.8.4",
218
218
  "rimraf": "3.0.2",
219
+ "supertest": "^6.2.3",
219
220
  "ts-jest": "28.0.5",
220
221
  "ts-node": "^10.8.2",
221
222
  "ts-node-dev": "1.1.8",