directus 9.11.1 → 9.12.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.
Files changed (104) hide show
  1. package/dist/app.js +14 -1
  2. package/dist/cli/utils/create-env/env-stub.liquid +266 -9
  3. package/dist/constants.d.ts +1 -0
  4. package/dist/constants.js +5 -1
  5. package/dist/controllers/activity.js +1 -1
  6. package/dist/controllers/flows.d.ts +2 -0
  7. package/dist/controllers/flows.js +157 -0
  8. package/dist/controllers/folders.js +1 -1
  9. package/dist/controllers/notifications.js +1 -1
  10. package/dist/controllers/operations.d.ts +2 -0
  11. package/dist/controllers/operations.js +138 -0
  12. package/dist/database/helpers/fn/dialects/oracle.d.ts +9 -9
  13. package/dist/database/helpers/fn/dialects/oracle.js +22 -16
  14. package/dist/database/helpers/fn/dialects/sqlite.d.ts +9 -9
  15. package/dist/database/helpers/fn/dialects/sqlite.js +46 -16
  16. package/dist/database/helpers/fn/types.d.ts +12 -9
  17. package/dist/database/index.js +10 -19
  18. package/dist/database/migrations/20220429A-add-flows.d.ts +3 -0
  19. package/dist/database/migrations/20220429A-add-flows.js +83 -0
  20. package/dist/database/migrations/20220429B-add-color-to-insights-icon.d.ts +3 -0
  21. package/dist/database/migrations/20220429B-add-color-to-insights-icon.js +15 -0
  22. package/dist/database/migrations/20220429C-drop-non-null-from-ip-of-activity.d.ts +3 -0
  23. package/dist/database/migrations/20220429C-drop-non-null-from-ip-of-activity.js +15 -0
  24. package/dist/database/migrations/20220429D-drop-non-null-from-sender-of-notifications.d.ts +3 -0
  25. package/dist/database/migrations/20220429D-drop-non-null-from-sender-of-notifications.js +15 -0
  26. package/dist/database/seeds/05-activity.yaml +0 -1
  27. package/dist/database/system-data/collections/collections.yaml +4 -0
  28. package/dist/database/system-data/fields/flows.yaml +21 -0
  29. package/dist/database/system-data/fields/operations.yaml +19 -0
  30. package/dist/database/system-data/fields/users.yaml +2 -4
  31. package/dist/database/system-data/relations/relations.yaml +20 -0
  32. package/dist/env.d.ts +1 -1
  33. package/dist/env.js +6 -30
  34. package/dist/extensions.d.ts +5 -1
  35. package/dist/extensions.js +96 -39
  36. package/dist/flows.d.ts +22 -0
  37. package/dist/flows.js +332 -0
  38. package/dist/messenger.d.ts +24 -0
  39. package/dist/messenger.js +64 -0
  40. package/dist/operations/condition/index.d.ts +6 -0
  41. package/dist/operations/condition/index.js +15 -0
  42. package/dist/operations/item-create/index.d.ts +8 -0
  43. package/dist/operations/item-create/index.js +40 -0
  44. package/dist/operations/item-delete/index.d.ts +9 -0
  45. package/dist/operations/item-delete/index.js +45 -0
  46. package/dist/operations/item-read/index.d.ts +9 -0
  47. package/dist/operations/item-read/index.js +45 -0
  48. package/dist/operations/item-update/index.d.ts +10 -0
  49. package/dist/operations/item-update/index.js +50 -0
  50. package/dist/operations/log/index.d.ts +5 -0
  51. package/dist/operations/log/index.js +14 -0
  52. package/dist/operations/mail/index.d.ts +7 -0
  53. package/dist/operations/mail/index.js +16 -0
  54. package/dist/operations/notification/index.d.ts +8 -0
  55. package/dist/operations/notification/index.js +39 -0
  56. package/dist/operations/request/index.d.ts +12 -0
  57. package/dist/operations/request/index.js +18 -0
  58. package/dist/operations/sleep/index.d.ts +5 -0
  59. package/dist/operations/sleep/index.js +9 -0
  60. package/dist/operations/transform/index.d.ts +5 -0
  61. package/dist/operations/transform/index.js +10 -0
  62. package/dist/operations/trigger/index.d.ts +6 -0
  63. package/dist/operations/trigger/index.js +21 -0
  64. package/dist/services/activity.d.ts +1 -2
  65. package/dist/services/activity.js +10 -10
  66. package/dist/services/authentication.d.ts +2 -2
  67. package/dist/services/authentication.js +7 -7
  68. package/dist/services/authorization.js +12 -0
  69. package/dist/services/flows.d.ts +12 -0
  70. package/dist/services/flows.js +47 -0
  71. package/dist/services/graphql.js +13 -2
  72. package/dist/services/import-export.js +7 -3
  73. package/dist/services/index.d.ts +2 -0
  74. package/dist/services/index.js +2 -0
  75. package/dist/services/items.js +1 -1
  76. package/dist/services/mail/index.js +2 -1
  77. package/dist/services/notifications.d.ts +2 -1
  78. package/dist/services/notifications.js +4 -3
  79. package/dist/services/operations.d.ts +12 -0
  80. package/dist/services/operations.js +47 -0
  81. package/dist/services/users.js +5 -0
  82. package/dist/services/webhooks.d.ts +2 -0
  83. package/dist/services/webhooks.js +8 -7
  84. package/dist/types/events.d.ts +18 -0
  85. package/dist/types/events.js +2 -0
  86. package/dist/types/index.d.ts +1 -1
  87. package/dist/types/index.js +1 -1
  88. package/dist/utils/apply-snapshot.js +3 -0
  89. package/dist/utils/construct-flow-tree.d.ts +2 -0
  90. package/dist/utils/construct-flow-tree.js +31 -0
  91. package/dist/utils/get-accountability-for-role.d.ts +7 -0
  92. package/dist/utils/get-accountability-for-role.js +36 -0
  93. package/dist/utils/get-column.js +1 -1
  94. package/dist/utils/job-queue.d.ts +9 -0
  95. package/dist/utils/job-queue.js +24 -0
  96. package/dist/utils/operation-options.d.ts +3 -0
  97. package/dist/utils/operation-options.js +45 -0
  98. package/dist/utils/validate-query.js +1 -1
  99. package/dist/webhooks.d.ts +2 -0
  100. package/dist/webhooks.js +17 -2
  101. package/package.json +19 -15
  102. package/dist/types/activity.d.ts +0 -9
  103. package/dist/types/activity.js +0 -13
  104. package/example.env +0 -202
package/dist/app.js CHANGED
@@ -36,12 +36,14 @@ const dashboards_1 = __importDefault(require("./controllers/dashboards"));
36
36
  const extensions_1 = __importDefault(require("./controllers/extensions"));
37
37
  const fields_1 = __importDefault(require("./controllers/fields"));
38
38
  const files_1 = __importDefault(require("./controllers/files"));
39
+ const flows_1 = __importDefault(require("./controllers/flows"));
39
40
  const folders_1 = __importDefault(require("./controllers/folders"));
40
41
  const graphql_1 = __importDefault(require("./controllers/graphql"));
41
42
  const items_1 = __importDefault(require("./controllers/items"));
42
43
  const not_found_1 = __importDefault(require("./controllers/not-found"));
43
44
  const panels_1 = __importDefault(require("./controllers/panels"));
44
45
  const notifications_1 = __importDefault(require("./controllers/notifications"));
46
+ const operations_1 = __importDefault(require("./controllers/operations"));
45
47
  const permissions_1 = __importDefault(require("./controllers/permissions"));
46
48
  const presets_1 = __importDefault(require("./controllers/presets"));
47
49
  const relations_1 = __importDefault(require("./controllers/relations"));
@@ -58,6 +60,7 @@ const emitter_1 = __importDefault(require("./emitter"));
58
60
  const env_1 = __importDefault(require("./env"));
59
61
  const exceptions_1 = require("./exceptions");
60
62
  const extensions_2 = require("./extensions");
63
+ const flows_2 = require("./flows");
61
64
  const logger_1 = __importStar(require("./logger"));
62
65
  const authenticate_1 = __importDefault(require("./middleware/authenticate"));
63
66
  const get_permissions_1 = __importDefault(require("./middleware/get-permissions"));
@@ -69,6 +72,7 @@ const extract_token_1 = __importDefault(require("./middleware/extract-token"));
69
72
  const rate_limiter_1 = __importDefault(require("./middleware/rate-limiter"));
70
73
  const sanitize_query_1 = __importDefault(require("./middleware/sanitize-query"));
71
74
  const schema_1 = __importDefault(require("./middleware/schema"));
75
+ const constants_1 = require("./constants");
72
76
  const track_1 = require("./utils/track");
73
77
  const validate_env_1 = require("./utils/validate-env");
74
78
  const validate_storage_1 = require("./utils/validate-storage");
@@ -96,7 +100,9 @@ async function createApp() {
96
100
  await (0, cache_2.flushCaches)();
97
101
  await (0, auth_2.registerAuthProviders)();
98
102
  const extensionManager = (0, extensions_2.getExtensionManager)();
103
+ const flowManager = (0, flows_2.getFlowManager)();
99
104
  await extensionManager.initialize();
105
+ await flowManager.initialize();
100
106
  const app = (0, express_1.default)();
101
107
  app.disable('x-powered-by');
102
108
  app.set('trust proxy', env_1.default.IP_TRUST_PROXY);
@@ -152,6 +158,11 @@ async function createApp() {
152
158
  next();
153
159
  }
154
160
  });
161
+ app.get('/robots.txt', (_, res) => {
162
+ res.set('Content-Type', 'text/plain');
163
+ res.status(200);
164
+ res.send(constants_1.ROBOTSTXT);
165
+ });
155
166
  if (env_1.default.SERVE_APP) {
156
167
  const adminPath = require.resolve('@directus/app');
157
168
  const adminUrl = new url_1.Url(env_1.default.PUBLIC_URL).addPath('admin');
@@ -187,9 +198,11 @@ async function createApp() {
187
198
  app.use('/extensions', extensions_1.default);
188
199
  app.use('/fields', fields_1.default);
189
200
  app.use('/files', files_1.default);
201
+ app.use('/flows', flows_1.default);
190
202
  app.use('/folders', folders_1.default);
191
203
  app.use('/items', items_1.default);
192
204
  app.use('/notifications', notifications_1.default);
205
+ app.use('/operations', operations_1.default);
193
206
  app.use('/panels', panels_1.default);
194
207
  app.use('/permissions', permissions_1.default);
195
208
  app.use('/presets', presets_1.default);
@@ -210,7 +223,7 @@ async function createApp() {
210
223
  app.use(error_handler_1.default);
211
224
  await emitter_1.default.emitInit('routes.after', { app });
212
225
  // Register all webhooks
213
- await (0, webhooks_2.register)();
226
+ await (0, webhooks_2.init)();
214
227
  (0, track_1.track)('serverStarted');
215
228
  await emitter_1.default.emitInit('app.after', { app });
216
229
  return app;
@@ -1,60 +1,317 @@
1
1
  ####################################################################################################
2
- ## General
2
+ #
3
+ # These values set environment variables which modify core settings of Directus.
4
+ #
5
+ # Values in square brackets are the default values.
6
+ #
7
+ # The following options are not all possible options. For more, see
8
+ # https://docs.directus.io/configuration/config-options/
9
+ #
10
+ ####################################################################################################
11
+ ####################################################################################################
12
+
13
+ ### General
3
14
 
15
+ # IP or host the API listens on ["0.0.0.0"]
4
16
  HOST="0.0.0.0"
17
+
18
+ # The port Directus will run on [8055]
5
19
  PORT=8055
20
+
21
+ # The URL where your API can be reached on the web. It is also used for things like OAuth redirects,
22
+ # forgot-password emails, and logos that needs to be publicly available on the internet. ["/"]
6
23
  PUBLIC_URL="/"
24
+ # PUBLIC_URL="http://localhost:8055"
25
+
26
+ # What level of detail to log. [info]
27
+ # "fatal", "error", "warn", "info", "debug", "trace", "silent"
28
+ # LOG_LEVEL="info"
29
+
30
+ # Render the logs human readable (pretty) or as JSON (raw), [pretty]
31
+ # "pretty", "raw"
32
+ # LOG_STYLE="pretty"
33
+
34
+ # Controls the maximum request body size. Accepts number of bytes, or human readable string ["100kb"]
35
+ # MAX_PAYLOAD_SIZE="100kb"
36
+
37
+ # Where to redirect to when navigating to /. Accepts a relative path, absolute URL, or false to disable ["./admin"]
38
+ # ROOT_REDIRECT="./admin"
39
+
40
+ # Whether or not to serve the Admin App under /admin. [true]
41
+ # SERVE_APP=true
42
+
43
+ # Whether or not to enable GraphQL Introspection [true]
44
+ # GRAPHQL_INTROSPECTION=true
7
45
 
8
46
  ####################################################################################################
9
- ## Database
47
+ ### Database
48
+
49
+ # All DB_* environment variables are passed to the connection configuration of a Knex instance.
50
+ # Based on your project's needs, you can extend the DB_* environment variables with any config
51
+ # you need to pass to the database instance.
10
52
 
11
53
  {{ database }}
12
54
 
55
+
56
+ # These match the databases defined in the docker-compose file in the root of this repo
57
+
58
+ ## Postgres
59
+ # DB_CLIENT="pg"
60
+ # DB_HOST="localhost"
61
+ # DB_PORT=5432
62
+ # DB_DATABASE="directus"
63
+ # DB_USER="postgres"
64
+ # DB_PASSWORD="secret"
65
+
66
+ ## CockroachDB
67
+ # DB_CLIENT="cockroachdb"
68
+ # DB_HOST="localhost"
69
+ # DB_PORT=26257
70
+ # DB_DATABASE="directus"
71
+ # DB_USER="root"
72
+ # DB_PASSWORD=""
73
+
74
+ ## MySQL 8
75
+ # DB_CLIENT="mysql"
76
+ # DB_HOST="localhost"
77
+ # DB_PORT=3306
78
+ # DB_DATABASE="directus"
79
+ # DB_USER="root"
80
+ # DB_PASSWORD="secret"
81
+
82
+ ## MariaDB
83
+ # DB_CLIENT="mysql"
84
+ # DB_HOST="localhost"
85
+ # DB_PORT=3306
86
+ # DB_DATABASE="directus"
87
+ # DB_USER="root"
88
+ # DB_PASSWORD="secret"
89
+
90
+ ## MS SQL
91
+ # DB_CLIENT="mssql"
92
+ # DB_HOST="localhost"
93
+ # DB_PORT=1343
94
+ # DB_DATABASE="directus"
95
+ # DB_USER="sa"
96
+ # DB_PASSWORD="Test@123"
97
+
98
+ ## OracleDB
99
+ # DB_CLIENT="oracledb"
100
+ # DB_CONNECT_STRING="localhost:1521/XE"
101
+ # DB_USER="secretsysuser"
102
+ # DB_PASSWORD="secretpassword"
103
+
104
+ ## SQLite Example
105
+ # DB_CLIENT="sqlite3"
106
+ # DB_FILENAME="./data.db"
107
+
108
+ ## MySQL 5.7
109
+ # DB_CLIENT="mysql"
110
+ # DB_HOST="localhost"
111
+ # DB_PORT=3306
112
+ # DB_DATABASE="directus"
113
+ # DB_USER="root"
114
+ # DB_PASSWORD="secret"
115
+
13
116
  ####################################################################################################
14
- ## Rate Limiting
117
+ ### Rate Limiting
15
118
 
119
+ # Whether or not to enable rate limiting on the API [false]
16
120
  RATE_LIMITER_ENABLED=false
121
+
122
+ # Where to store the rate limiter counts [memory]
123
+ # memory, redis, memcache
17
124
  RATE_LIMITER_STORE=memory
125
+ # RATE_LIMITER_REDIS="redis://@127.0.0.1:5105"
126
+ # RATE_LIMITER_MEMCACHE="localhost:5109"
127
+
128
+ # The amount of allowed hits per duration [50]
18
129
  RATE_LIMITER_POINTS=25
130
+
131
+ # The time window in seconds in which the hits are counted [1]
19
132
  RATE_LIMITER_DURATION=1
20
133
 
21
134
  ####################################################################################################
22
- ## Cache
135
+ ### Caching
23
136
 
137
+ # Whether or not caching is enabled. [false]
24
138
  CACHE_ENABLED=false
25
139
 
140
+ # How long the cache is persisted ["5m"]
141
+ # CACHE_TTL="30m"
142
+
143
+ # How to scope the cache data ["directus-cache"]
144
+ # CACHE_NAMESPACE="directus-cache"
145
+
146
+ # Automatically purge the cache on create, update, and delete actions. [false]
147
+ # CACHE_AUTO_PURGE=true
148
+
149
+ # memory | redis | memcache
150
+ CACHE_STORE=memory
151
+
152
+ # How long assets will be cached for in the browser. Sets the max-age value of the Cache-Control header ["30m"]
153
+ ASSETS_CACHE_TTL="30m"
154
+
155
+ # CACHE_REDIS="redis://@127.0.0.1:5105"
156
+ # CACHE_MEMCACHE="localhost:5109"
157
+
26
158
  ####################################################################################################
27
- ## File Storage
159
+ ### File Storage
28
160
 
161
+ # A CSV of storage locations (eg: local,digitalocean,amazon) to use. You can use any names you'd like for these keys ["local"]
29
162
  STORAGE_LOCATIONS="local"
30
163
  STORAGE_LOCAL_DRIVER="local"
31
164
  STORAGE_LOCAL_ROOT="./uploads"
32
165
 
166
+ ## S3 Example (location name: DigitalOcean)
167
+ # STORAGE_DIGITALOCEAN_DRIVER="s3"
168
+ # STORAGE_DIGITALOCEAN_KEY="abcdef"
169
+ # STORAGE_DIGITALOCEAN_SECRET="ghijkl"
170
+ # STORAGE_DIGITALOCEAN_ENDPOINT="ams3.digitaloceanspaces.com"
171
+ # STORAGE_DIGITALOCEAN_BUCKET="my-files"
172
+ # STORAGE_DIGITALOCEAN_REGION="ams3"
173
+
174
+ ## Google Cloud Storage Example (location name: Google)
175
+ # STORAGE_GOOGLE_DRIVER="gcs"
176
+ # STORAGE_GOOGLE_KEY_FILENAME="abcdef"
177
+ # STORAGE_GOOGLE_BUCKET="my-files"
178
+
179
+
180
+ ## A comma-separated list of metadata keys to collect during file upload. Use * for all
181
+ # Extracting all metadata might cause memory issues when the file has an unusually large set of metadata
182
+ # [ifd0.Make,ifd0.Model,exif.FNumber,exif.ExposureTime,exif.FocalLength,exif.ISO]
183
+ # FILE_METADATA_ALLOW_LIST=
184
+
33
185
  ####################################################################################################
34
- ## Security
186
+ ### Security
35
187
 
36
188
  {{ security }}
37
189
 
190
+ # Unique identifier for the project
191
+ # KEY="xxxxxxx-xxxxxx-xxxxxxxx-xxxxxxxxxx"
192
+
193
+ # Secret string for the project
194
+ # SECRET="abcdef"
195
+
196
+ # The duration that the access token is valid ["15m"]
38
197
  ACCESS_TOKEN_TTL="15m"
198
+
199
+ # The duration that the refresh token is valid, and also how long users stay logged-in to the App ["7d"]
39
200
  REFRESH_TOKEN_TTL="7d"
201
+
202
+ # Whether or not to use a secure cookie for the refresh token in cookie mode [false]
40
203
  REFRESH_TOKEN_COOKIE_SECURE=false
204
+
205
+ # Value for sameSite in the refresh token cookie when in cookie mode ["lax"]
41
206
  REFRESH_TOKEN_COOKIE_SAME_SITE="lax"
207
+
208
+ # Name of refresh token cookie ["directus_refresh_token"]
42
209
  REFRESH_TOKEN_COOKIE_NAME="directus_refresh_token"
43
210
 
211
+ # Which domain to use for the refresh cookie. Useful for development mode.
212
+ # REFRESH_TOKEN_COOKIE_DOMAIN
213
+
214
+ # Whether or not to enable the CORS headers [false]
215
+ CORS_ENABLED=true
216
+
217
+ # Value for the Access-Control-Allow-Origin header. Use true to match the Origin header, or provide a domain or a CSV of domains for specific access [false]
218
+ CORS_ORIGIN=true
219
+
220
+ # Value for the Access-Control-Allow-Methods header [GET,POST,PATCH,DELETE]
221
+ CORS_METHODS=GET,POST,PATCH,DELETE
222
+
223
+ # Value for the Access-Control-Allow-Headers header [Content-Type,Authorization]
224
+ CORS_ALLOWED_HEADERS=Content-Type,Authorization
225
+
226
+ # Value for the Access-Control-Expose-Headers header [Content-R
227
+ CORS_EXPOSED_HEADERS=Content-Range
228
+
229
+ # Whether or not to send the Access-Control-Allow-Credentials header [true]
230
+ CORS_CREDENTIALS=true
231
+
232
+ # Value for the Access-Control-Max-Age header [18000]
233
+ CORS_MAX_AGE=18000
234
+
235
+ ####################################################################################################
236
+ ### Argon2
237
+
238
+ # How much memory to use when generating hashes, in KiB [4096]
239
+ # HASH_MEMORY_COST=81920
240
+
241
+ # The length of the hash function output in bytes [32]
242
+ # HASH_HASH_LENGTH=32
243
+
244
+ # The amount of passes (iterations) used by the hash function. It increases hash strength at the cost of time required to compute [3]
245
+ # HASH_TIME_COST=10
246
+
247
+ # The amount of threads to compute the hash on. Each thread has a memory pool with HASH_MEMORY_COST size [1]
248
+ # HASH_PARALLELISM=2
249
+
250
+ # The variant of the hash function (0: argon2d, 1: argon2i, or 2: argon2id) [1]
251
+ # HASH_TYPE=2
252
+
253
+ An extra and optional non-secret value. The value will be included B64 encoded in the parameters portion of the digest []
254
+ # HASH_ASSOCIATED_DATA=foo
255
+
44
256
  ####################################################################################################
45
- ## Auth Providers
257
+ ### Auth Providers
46
258
 
259
+ # A comma-separated list of auth providers []
47
260
  AUTH_PROVIDERS=""
261
+ # AUTH_PROVIDERS="github"
262
+
263
+ # AUTH_GITHUB_DRIVER="oauth2"
264
+ # AUTH_GITHUB_CLIENT_ID="73e...4b"
265
+ # AUTH_GITHUB_CLIENT_SECRET="b9...98"
266
+ # AUTH_GITHUB_AUTHORIZE_URL="https://github.com/login/oauth/authorize"
267
+ # AUTH_GITHUB_ACCESS_URL="https://github.com/login/oauth/access_token"
268
+ # AUTH_GITHUB_PROFILE_URL="https://api.github.com/user"
269
+ # AUTH_GITHUB_ALLOW_PUBLIC_REGISTRATION=true
270
+ # AUTH_GITHUB_DEFAULT_ROLE_ID="82424427-c9d4-4289-8bc5-ed1bf8422c90"
271
+ # AUTH_GITHUB_ICON="github"
272
+ # AUTH_GITHUB_EMAIL_KEY="email"
273
+ # AUTH_GITHUB_IDENTIFIER_KEY="login"
48
274
 
49
275
  ####################################################################################################
50
- ## Extensions
276
+ ### Extensions
51
277
 
278
+ # Path to your local extensions folder ["./extensions"]
52
279
  EXTENSIONS_PATH="./extensions"
53
280
 
281
+ # Automatically reload extensions when they have changed [false]
282
+ EXTENSIONS_AUTO_RELOAD=false
283
+
54
284
  ####################################################################################################
55
- ## Email
285
+ ### Email
56
286
 
287
+ # Email address from which emails are sent ["no-reply@directus.io"]
57
288
  EMAIL_FROM="no-reply@directus.io"
289
+
290
+ # What to use to send emails. One of
291
+ # sendmail, smtp, mailgun, ses.
58
292
  EMAIL_TRANSPORT="sendmail"
59
293
  EMAIL_SENDMAIL_NEW_LINE="unix"
60
294
  EMAIL_SENDMAIL_PATH="/usr/sbin/sendmail"
295
+
296
+ ## Email (Sendmail Transport)
297
+
298
+ # What new line style to use in sendmail ["unix"]
299
+ EMAIL_SENDMAIL_NEW_LINE="unix"
300
+
301
+ # Path to your sendmail executable ["/usr/sbin/sendmail"]
302
+ EMAIL_SENDMAIL_PATH="/usr/sbin/sendmail"
303
+
304
+ ## Email (SMTP Transport)
305
+ # EMAIL_SMTP_HOST="localhost"
306
+
307
+ # Use SMTP pooling
308
+ # EMAIL_SMTP_POOL=true
309
+ # EMAIL_SMTP_PORT=465
310
+ # EMAIL_SMTP_SECURE=false # Use TLS
311
+ # EMAIL_SMTP_IGNORE_TLS=false
312
+ # EMAIL_SMTP_USER="username"
313
+ # EMAIL_SMTP_PASSWORD="password"
314
+
315
+ ## Email (Mailgun Transport)
316
+ # EMAIL_MAILGUN_API_KEY="key-1234123412341234"
317
+ # EMAIL_MAILGUN_DOMAIN="a domain name from https://app.mailgun.com/app/sending/domains"
@@ -13,3 +13,4 @@ export declare const COOKIE_OPTIONS: {
13
13
  secure: any;
14
14
  sameSite: "lax" | "strict" | "none";
15
15
  };
16
+ export declare const ROBOTSTXT: string;
package/dist/constants.js CHANGED
@@ -4,7 +4,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  var _a;
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
- exports.COOKIE_OPTIONS = exports.UUID_REGEX = exports.COLUMN_TRANSFORMS = exports.DEFAULT_AUTH_PROVIDER = exports.ALIAS_TYPES = exports.FILTER_VARIABLES = exports.ASSET_TRANSFORM_QUERY_KEYS = exports.SYSTEM_ASSET_ALLOW_LIST = void 0;
7
+ exports.ROBOTSTXT = exports.COOKIE_OPTIONS = exports.UUID_REGEX = exports.COLUMN_TRANSFORMS = exports.DEFAULT_AUTH_PROVIDER = exports.ALIAS_TYPES = exports.FILTER_VARIABLES = exports.ASSET_TRANSFORM_QUERY_KEYS = exports.SYSTEM_ASSET_ALLOW_LIST = void 0;
8
8
  const env_1 = __importDefault(require("./env"));
9
9
  const ms_1 = __importDefault(require("ms"));
10
10
  exports.SYSTEM_ASSET_ALLOW_LIST = [
@@ -55,3 +55,7 @@ exports.COOKIE_OPTIONS = {
55
55
  secure: (_a = env_1.default.REFRESH_TOKEN_COOKIE_SECURE) !== null && _a !== void 0 ? _a : false,
56
56
  sameSite: env_1.default.REFRESH_TOKEN_COOKIE_SAME_SITE || 'strict',
57
57
  };
58
+ exports.ROBOTSTXT = `
59
+ User-agent: *
60
+ Disallow: /
61
+ `.trim();
@@ -3,6 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
+ const types_1 = require("@directus/shared/types");
6
7
  const express_1 = __importDefault(require("express"));
7
8
  const joi_1 = __importDefault(require("joi"));
8
9
  const exceptions_1 = require("../exceptions");
@@ -10,7 +11,6 @@ const respond_1 = require("../middleware/respond");
10
11
  const use_collection_1 = __importDefault(require("../middleware/use-collection"));
11
12
  const validate_batch_1 = require("../middleware/validate-batch");
12
13
  const services_1 = require("../services");
13
- const types_1 = require("../types");
14
14
  const async_handler_1 = __importDefault(require("../utils/async-handler"));
15
15
  const get_ip_from_req_1 = require("../utils/get-ip-from-req");
16
16
  const router = express_1.default.Router();
@@ -0,0 +1,2 @@
1
+ declare const router: import("express-serve-static-core").Router;
2
+ export default router;
@@ -0,0 +1,157 @@
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
+ const express_1 = __importDefault(require("express"));
7
+ const constants_1 = require("../constants");
8
+ const exceptions_1 = require("../exceptions");
9
+ const flows_1 = require("../flows");
10
+ const respond_1 = require("../middleware/respond");
11
+ const use_collection_1 = __importDefault(require("../middleware/use-collection"));
12
+ const validate_batch_1 = require("../middleware/validate-batch");
13
+ const services_1 = require("../services");
14
+ const async_handler_1 = __importDefault(require("../utils/async-handler"));
15
+ const router = express_1.default.Router();
16
+ router.use((0, use_collection_1.default)('directus_flows'));
17
+ const webhookFlowHandler = (0, async_handler_1.default)(async (req, res, next) => {
18
+ const flowManager = (0, flows_1.getFlowManager)();
19
+ const result = await flowManager.runWebhookFlow(`${req.method}-${req.params.pk}`, {
20
+ path: req.path,
21
+ query: req.query,
22
+ body: req.body,
23
+ method: req.method,
24
+ headers: req.headers,
25
+ }, {
26
+ accountability: req.accountability,
27
+ schema: req.schema,
28
+ });
29
+ res.locals.payload = result;
30
+ return next();
31
+ });
32
+ router.get(`/trigger/:pk(${constants_1.UUID_REGEX})`, webhookFlowHandler, respond_1.respond);
33
+ router.post(`/trigger/:pk(${constants_1.UUID_REGEX})`, webhookFlowHandler, respond_1.respond);
34
+ router.post('/', (0, async_handler_1.default)(async (req, res, next) => {
35
+ const service = new services_1.FlowsService({
36
+ accountability: req.accountability,
37
+ schema: req.schema,
38
+ });
39
+ const savedKeys = [];
40
+ if (Array.isArray(req.body)) {
41
+ const keys = await service.createMany(req.body);
42
+ savedKeys.push(...keys);
43
+ }
44
+ else {
45
+ const key = await service.createOne(req.body);
46
+ savedKeys.push(key);
47
+ }
48
+ try {
49
+ if (Array.isArray(req.body)) {
50
+ const items = await service.readMany(savedKeys, req.sanitizedQuery);
51
+ res.locals.payload = { data: items };
52
+ }
53
+ else {
54
+ const item = await service.readOne(savedKeys[0], req.sanitizedQuery);
55
+ res.locals.payload = { data: item };
56
+ }
57
+ }
58
+ catch (error) {
59
+ if (error instanceof exceptions_1.ForbiddenException) {
60
+ return next();
61
+ }
62
+ throw error;
63
+ }
64
+ return next();
65
+ }), respond_1.respond);
66
+ const readHandler = (0, async_handler_1.default)(async (req, res, next) => {
67
+ const service = new services_1.FlowsService({
68
+ accountability: req.accountability,
69
+ schema: req.schema,
70
+ });
71
+ const metaService = new services_1.MetaService({
72
+ accountability: req.accountability,
73
+ schema: req.schema,
74
+ });
75
+ const records = await service.readByQuery(req.sanitizedQuery);
76
+ const meta = await metaService.getMetaForQuery(req.collection, req.sanitizedQuery);
77
+ res.locals.payload = { data: records || null, meta };
78
+ return next();
79
+ });
80
+ router.get('/', (0, validate_batch_1.validateBatch)('read'), readHandler, respond_1.respond);
81
+ router.search('/', (0, validate_batch_1.validateBatch)('read'), readHandler, respond_1.respond);
82
+ router.get('/:pk', (0, async_handler_1.default)(async (req, res, next) => {
83
+ const service = new services_1.FlowsService({
84
+ accountability: req.accountability,
85
+ schema: req.schema,
86
+ });
87
+ const record = await service.readOne(req.params.pk, req.sanitizedQuery);
88
+ res.locals.payload = { data: record || null };
89
+ return next();
90
+ }), respond_1.respond);
91
+ router.patch('/', (0, validate_batch_1.validateBatch)('update'), (0, async_handler_1.default)(async (req, res, next) => {
92
+ const service = new services_1.FlowsService({
93
+ accountability: req.accountability,
94
+ schema: req.schema,
95
+ });
96
+ let keys = [];
97
+ if (req.body.keys) {
98
+ keys = await service.updateMany(req.body.keys, req.body.data);
99
+ }
100
+ else {
101
+ keys = await service.updateByQuery(req.body.query, req.body.data);
102
+ }
103
+ try {
104
+ const result = await service.readMany(keys, req.sanitizedQuery);
105
+ res.locals.payload = { data: result };
106
+ }
107
+ catch (error) {
108
+ if (error instanceof exceptions_1.ForbiddenException) {
109
+ return next();
110
+ }
111
+ throw error;
112
+ }
113
+ return next();
114
+ }), respond_1.respond);
115
+ router.patch('/:pk', (0, async_handler_1.default)(async (req, res, next) => {
116
+ const service = new services_1.FlowsService({
117
+ accountability: req.accountability,
118
+ schema: req.schema,
119
+ });
120
+ const primaryKey = await service.updateOne(req.params.pk, req.body);
121
+ try {
122
+ const item = await service.readOne(primaryKey, req.sanitizedQuery);
123
+ res.locals.payload = { data: item || null };
124
+ }
125
+ catch (error) {
126
+ if (error instanceof exceptions_1.ForbiddenException) {
127
+ return next();
128
+ }
129
+ throw error;
130
+ }
131
+ return next();
132
+ }), respond_1.respond);
133
+ router.delete('/', (0, async_handler_1.default)(async (req, res, next) => {
134
+ const service = new services_1.FlowsService({
135
+ accountability: req.accountability,
136
+ schema: req.schema,
137
+ });
138
+ if (Array.isArray(req.body)) {
139
+ await service.deleteMany(req.body);
140
+ }
141
+ else if (req.body.keys) {
142
+ await service.deleteMany(req.body.keys);
143
+ }
144
+ else {
145
+ await service.deleteByQuery(req.body.query);
146
+ }
147
+ return next();
148
+ }), respond_1.respond);
149
+ router.delete('/:pk', (0, async_handler_1.default)(async (req, res, next) => {
150
+ const service = new services_1.FlowsService({
151
+ accountability: req.accountability,
152
+ schema: req.schema,
153
+ });
154
+ await service.deleteOne(req.params.pk);
155
+ return next();
156
+ }), respond_1.respond);
157
+ exports.default = router;
@@ -63,7 +63,7 @@ const readHandler = (0, async_handler_1.default)(async (req, res, next) => {
63
63
  else {
64
64
  result = await service.readByQuery(req.sanitizedQuery);
65
65
  }
66
- const meta = await metaService.getMetaForQuery('directus_files', req.sanitizedQuery);
66
+ const meta = await metaService.getMetaForQuery('directus_folders', req.sanitizedQuery);
67
67
  res.locals.payload = { data: result, meta };
68
68
  return next();
69
69
  });
@@ -63,7 +63,7 @@ const readHandler = (0, async_handler_1.default)(async (req, res, next) => {
63
63
  else {
64
64
  result = await service.readByQuery(req.sanitizedQuery);
65
65
  }
66
- const meta = await metaService.getMetaForQuery('directus_presets', req.sanitizedQuery);
66
+ const meta = await metaService.getMetaForQuery('directus_notifications', req.sanitizedQuery);
67
67
  res.locals.payload = { data: result, meta };
68
68
  return next();
69
69
  });
@@ -0,0 +1,2 @@
1
+ declare const router: import("express-serve-static-core").Router;
2
+ export default router;