@directus/api 35.2.0 → 36.0.0-rc.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.
Files changed (192) hide show
  1. package/dist/ai/chat/models/chat-request.js +48 -48
  2. package/dist/ai/chat/models/object-request.js +6 -6
  3. package/dist/ai/chat/models/providers.js +14 -14
  4. package/dist/ai/chat/utils/parse-json-schema-7.js +22 -22
  5. package/dist/ai/mcp/server.js +44 -6
  6. package/dist/ai/mcp/utils.js +31 -0
  7. package/dist/ai/tools/assets/index.js +3 -3
  8. package/dist/ai/tools/collections/index.js +18 -18
  9. package/dist/ai/tools/fields/index.js +18 -18
  10. package/dist/ai/tools/files/index.js +18 -18
  11. package/dist/ai/tools/flows/index.js +16 -16
  12. package/dist/ai/tools/folders/index.js +18 -18
  13. package/dist/ai/tools/items/index.js +17 -17
  14. package/dist/ai/tools/operations/index.js +16 -16
  15. package/dist/ai/tools/relations/index.js +22 -22
  16. package/dist/ai/tools/schema/index.js +3 -3
  17. package/dist/ai/tools/schema.js +159 -159
  18. package/dist/ai/tools/system/index.js +3 -3
  19. package/dist/ai/tools/trigger-flow/index.js +3 -3
  20. package/dist/app.js +35 -11
  21. package/dist/auth/drivers/ldap.js +3 -1
  22. package/dist/auth/drivers/local.js +2 -0
  23. package/dist/auth/drivers/oauth2.js +3 -1
  24. package/dist/auth/drivers/openid.js +3 -1
  25. package/dist/auth/drivers/saml.js +2 -0
  26. package/dist/auth/utils/check-local-disabled.js +16 -0
  27. package/dist/auth/utils/check-sso-enabled.js +14 -0
  28. package/dist/auth.js +8 -5
  29. package/dist/cli/commands/bootstrap/index.js +3 -0
  30. package/dist/cli/commands/cache/clear.js +6 -1
  31. package/dist/cli/commands/roles/create.js +4 -1
  32. package/dist/cli/commands/users/create.js +3 -0
  33. package/dist/constants.js +8 -1
  34. package/dist/controllers/access.js +1 -1
  35. package/dist/controllers/activity.js +2 -1
  36. package/dist/controllers/assets.js +2 -0
  37. package/dist/controllers/auth.js +13 -5
  38. package/dist/controllers/collections.js +1 -1
  39. package/dist/controllers/comments.js +1 -1
  40. package/dist/controllers/dashboards.js +1 -1
  41. package/dist/controllers/fields.js +1 -1
  42. package/dist/controllers/files.js +3 -1
  43. package/dist/controllers/flows.js +6 -5
  44. package/dist/controllers/folders.js +1 -1
  45. package/dist/controllers/graphql.js +2 -0
  46. package/dist/controllers/items.js +3 -1
  47. package/dist/controllers/license.js +119 -0
  48. package/dist/controllers/mcp/index.js +38 -0
  49. package/dist/controllers/mcp/oauth-clients.js +68 -0
  50. package/dist/controllers/mcp/oauth-consent-page.js +316 -0
  51. package/dist/controllers/mcp/oauth.js +381 -0
  52. package/dist/controllers/mcp/templates/oauth-consent.liquid +62 -0
  53. package/dist/controllers/mcp/templates/oauth-error.liquid +28 -0
  54. package/dist/controllers/notifications.js +1 -1
  55. package/dist/controllers/operations.js +1 -1
  56. package/dist/controllers/panels.js +1 -1
  57. package/dist/controllers/permissions.js +1 -1
  58. package/dist/controllers/policies.js +1 -1
  59. package/dist/controllers/presets.js +1 -1
  60. package/dist/controllers/revisions.js +3 -2
  61. package/dist/controllers/roles.js +1 -1
  62. package/dist/controllers/server.js +38 -10
  63. package/dist/controllers/shares.js +1 -1
  64. package/dist/controllers/translations.js +1 -1
  65. package/dist/controllers/users.js +1 -1
  66. package/dist/controllers/utils.js +2 -2
  67. package/dist/controllers/versions.js +12 -5
  68. package/dist/database/get-ast-from-query/lib/convert-wildcards.js +10 -1
  69. package/dist/database/get-ast-from-query/lib/parse-fields.js +2 -1
  70. package/dist/database/helpers/fn/dialects/mysql.js +7 -12
  71. package/dist/database/helpers/fn/dialects/oracle.js +3 -4
  72. package/dist/database/helpers/fn/dialects/postgres.js +4 -26
  73. package/dist/database/helpers/fn/json/mysql-json-path.js +22 -0
  74. package/dist/database/helpers/fn/json/parse-function.js +14 -6
  75. package/dist/database/helpers/fn/json/postgres-json-path.js +54 -0
  76. package/dist/database/migrations/20260110A-add-ai-provider-settings.js +4 -4
  77. package/dist/database/migrations/20260217A-null-item-versions.js +14 -0
  78. package/dist/database/migrations/20260312A-add-ai-translation-settings.js +18 -0
  79. package/dist/database/migrations/20260507A-add-licensing.js +22 -0
  80. package/dist/database/migrations/20260512A-add-autosave-revision-interval.js +14 -0
  81. package/dist/database/migrations/20260512B-add-mcp-oauth.js +87 -0
  82. package/dist/database/run-ast/lib/apply-query/filter/operator.js +116 -33
  83. package/dist/database/run-ast/lib/apply-query/index.js +4 -1
  84. package/dist/database/run-ast/lib/apply-query/sort.js +17 -7
  85. package/dist/database/run-ast/lib/get-db-query.js +21 -9
  86. package/dist/database/run-ast/lib/parse-current-level.js +2 -1
  87. package/dist/database/run-ast/run-ast.js +2 -1
  88. package/dist/database/run-ast/utils/get-column.js +2 -1
  89. package/dist/database/run-ast/utils/merge-with-parent-items.js +5 -3
  90. package/dist/extensions/lib/installation/manager.js +1 -1
  91. package/dist/extensions/lib/sandbox/register/operation.js +1 -1
  92. package/dist/extensions/lib/sync/sync.js +1 -1
  93. package/dist/extensions/manager.js +3 -3
  94. package/dist/flows.js +5 -5
  95. package/dist/license/entitlements/lib/collections.js +37 -0
  96. package/dist/license/entitlements/lib/custom-llms-enabled.js +18 -0
  97. package/dist/license/entitlements/lib/custom-permission-rules-enabled.js +41 -0
  98. package/dist/license/entitlements/lib/flows.js +29 -0
  99. package/dist/license/entitlements/lib/seats.js +103 -0
  100. package/dist/license/entitlements/lib/sso-enabled.js +45 -0
  101. package/dist/license/entitlements/manager.js +256 -0
  102. package/dist/license/index.js +4 -0
  103. package/dist/license/manager.js +505 -0
  104. package/dist/license/utils/compute-license-status.js +27 -0
  105. package/dist/license/utils/get-core-grace-expires-at.js +38 -0
  106. package/dist/license/utils/get-license-key.js +23 -0
  107. package/dist/license/utils/get-license-token.js +23 -0
  108. package/dist/license/utils/handle-license-error.js +41 -0
  109. package/dist/license/utils/is-in-core-grace-period.js +11 -0
  110. package/dist/license/utils/is-sso-bypass-allowed.js +21 -0
  111. package/dist/license/utils/use-rpc.js +33 -0
  112. package/dist/middleware/cache.js +4 -1
  113. package/dist/middleware/error-handler.js +11 -0
  114. package/dist/middleware/extract-token.js +11 -2
  115. package/dist/middleware/is-admin.js +16 -0
  116. package/dist/middleware/is-locked.js +16 -0
  117. package/dist/middleware/mcp-oauth-guard.js +23 -0
  118. package/dist/middleware/request-counter.js +5 -2
  119. package/dist/packages/types/dist/index.js +117 -122
  120. package/dist/permissions/modules/process-ast/utils/extract-paths-from-query.js +10 -1
  121. package/dist/permissions/utils/get-unaliased-field-key.js +2 -1
  122. package/dist/request/is-denied-ip.js +2 -0
  123. package/dist/schedules/license.js +31 -0
  124. package/dist/schedules/oauth-cleanup.js +26 -0
  125. package/dist/schedules/retention.js +1 -1
  126. package/dist/schedules/telemetry.js +4 -1
  127. package/dist/schedules/tus.js +1 -1
  128. package/dist/schedules/utils/duration-to-cron.js +36 -0
  129. package/dist/services/activity.js +15 -0
  130. package/dist/services/authentication.js +12 -5
  131. package/dist/services/collections.js +40 -10
  132. package/dist/services/fields.js +6 -6
  133. package/dist/services/flows.js +12 -0
  134. package/dist/services/graphql/resolvers/system-admin.js +2 -2
  135. package/dist/services/graphql/resolvers/system-global.js +1 -1
  136. package/dist/services/graphql/resolvers/system.js +43 -27
  137. package/dist/services/graphql/schema/get-types.js +28 -7
  138. package/dist/services/graphql/schema/parse-query.js +8 -0
  139. package/dist/services/graphql/schema/read.js +12 -0
  140. package/dist/services/graphql/types/json-filter.js +30 -0
  141. package/dist/services/index.js +6 -6
  142. package/dist/services/items.js +32 -14
  143. package/dist/services/mcp-oauth/cimd.js +307 -0
  144. package/dist/services/mcp-oauth/index.js +1185 -0
  145. package/dist/services/mcp-oauth/types/error.js +22 -0
  146. package/dist/services/mcp-oauth/utils/cimd-egress.js +182 -0
  147. package/dist/services/mcp-oauth/utils/domain.js +21 -0
  148. package/dist/services/mcp-oauth/utils/loopback.js +11 -0
  149. package/dist/services/mcp-oauth/utils/redirect.js +84 -0
  150. package/dist/services/mcp-oauth/utils/registration-debug.js +131 -0
  151. package/dist/services/payload.js +2 -1
  152. package/dist/services/permissions.js +31 -9
  153. package/dist/services/revisions.js +15 -0
  154. package/dist/services/server.js +66 -68
  155. package/dist/services/settings.js +37 -3
  156. package/dist/services/users.js +23 -6
  157. package/dist/services/utils.js +6 -1
  158. package/dist/services/versions.js +160 -70
  159. package/dist/utils/calculate-field-depth.js +1 -0
  160. package/dist/utils/create-admin.js +3 -3
  161. package/dist/utils/deep-freeze.js +24 -0
  162. package/dist/utils/extract-function-name.js +13 -0
  163. package/dist/utils/generate-translations.js +5 -5
  164. package/dist/utils/get-accountability-for-token.js +13 -1
  165. package/dist/utils/get-cache-key.js +1 -1
  166. package/dist/utils/get-history-filter-query.js +22 -0
  167. package/dist/utils/get-schema.js +2 -2
  168. package/dist/utils/get-service.js +3 -3
  169. package/dist/utils/is-admin.js +9 -0
  170. package/dist/utils/is-unauthenticated.js +15 -0
  171. package/dist/utils/parse-oauth-scope.js +12 -0
  172. package/dist/utils/sanitize-query.js +2 -2
  173. package/dist/utils/split-field-path.js +29 -0
  174. package/dist/utils/store.js +1 -1
  175. package/dist/utils/transaction.js +2 -2
  176. package/dist/utils/translations-validation.js +2 -2
  177. package/dist/utils/validate-query.js +35 -4
  178. package/dist/utils/validate-user-count-integrity.js +28 -5
  179. package/dist/utils/verify-session-jwt.js +5 -2
  180. package/dist/utils/versioning/handle-version.js +131 -48
  181. package/dist/utils/versioning/remove-circular.js +17 -0
  182. package/dist/websocket/authenticate.js +2 -1
  183. package/dist/websocket/collab/collab.js +1 -1
  184. package/dist/websocket/collab/room.js +1 -1
  185. package/dist/websocket/controllers/base.js +12 -0
  186. package/dist/websocket/controllers/graphql.js +1 -1
  187. package/dist/websocket/handlers/subscribe.js +1 -1
  188. package/dist/websocket/messages.js +64 -64
  189. package/dist/websocket/utils/items.js +2 -2
  190. package/license +90 -80
  191. package/package.json +33 -32
  192. package/dist/controllers/mcp.js +0 -31
@@ -1,13 +1,13 @@
1
1
  import { requireText } from "../../../utils/require-text.js";
2
2
  import { defineTool } from "../define-tool.js";
3
3
  import { fileURLToPath } from "node:url";
4
- import { z } from "zod";
4
+ import { z as z$1 } from "zod";
5
5
  import { dirname, resolve } from "node:path";
6
6
 
7
7
  //#region src/ai/tools/system/index.ts
8
8
  const __dirname = dirname(fileURLToPath(import.meta.url));
9
- const SystemPromptInputSchema = z.object({});
10
- const SystemPromptValidateSchema = z.object({ promptOverride: z.union([z.string(), z.null()]).optional() });
9
+ const SystemPromptInputSchema = z$1.object({});
10
+ const SystemPromptValidateSchema = z$1.object({ promptOverride: z$1.union([z$1.string(), z$1.null()]).optional() });
11
11
  const system = defineTool({
12
12
  name: "system-prompt",
13
13
  description: requireText(resolve(__dirname, "./prompt-description.md")),
@@ -1,11 +1,11 @@
1
1
  import { requireText } from "../../../utils/require-text.js";
2
2
  import { defineTool } from "../define-tool.js";
3
- import { TriggerFlowInputSchema, TriggerFlowValidateSchema } from "../schema.js";
4
- import { getFlowManager } from "../../../flows.js";
5
3
  import { FlowsService } from "../../../services/flows.js";
4
+ import { getFlowManager } from "../../../flows.js";
5
+ import { TriggerFlowInputSchema, TriggerFlowValidateSchema } from "../schema.js";
6
6
  import { InvalidPayloadError } from "@directus/errors";
7
7
  import { fileURLToPath } from "node:url";
8
- import { z } from "zod";
8
+ import { z as z$1 } from "zod";
9
9
  import { dirname, resolve } from "node:path";
10
10
 
11
11
  //#region src/ai/tools/trigger-flow/index.ts
package/dist/app.js CHANGED
@@ -4,13 +4,15 @@ import { initAIDevTools } from "./ai/devtools/index.js";
4
4
  import { initAITelemetry } from "./ai/telemetry/index.js";
5
5
  import { isInstalled, validateDatabaseConnection, validateDatabaseExtensions, validateMigrations } from "./database/index.js";
6
6
  import emitter_default from "./emitter.js";
7
+ import schedule from "./schedules/license.js";
7
8
  import { Url } from "./utils/url.js";
9
+ import { getEntitlementManager } from "./license/entitlements/manager.js";
10
+ import { getFlowManager } from "./flows.js";
8
11
  import { getExtensionManager } from "./extensions/index.js";
9
12
  import { registerAuthProviders } from "./auth.js";
10
13
  import { ensureDeploymentWebhooks, registerDeploymentDrivers } from "./deployment.js";
11
- import rate_limiter_global_default from "./middleware/rate-limiter-global.js";
12
- import rate_limiter_ip_default from "./middleware/rate-limiter-ip.js";
13
- import { getFlowManager } from "./flows.js";
14
+ import { getLicenseManager } from "./license/manager.js";
15
+ import "./license/index.js";
14
16
  import { aiRouter } from "./ai/chat/router.js";
15
17
  import { aiFilesRouter } from "./ai/files/router.js";
16
18
  import access_default from "./controllers/access.js";
@@ -29,7 +31,10 @@ import flows_default from "./controllers/flows.js";
29
31
  import folders_default from "./controllers/folders.js";
30
32
  import graphql_default from "./controllers/graphql.js";
31
33
  import items_default from "./controllers/items.js";
32
- import mcp_default from "./controllers/mcp.js";
34
+ import license_default from "./controllers/license.js";
35
+ import mcp_default from "./controllers/mcp/index.js";
36
+ import oauth_clients_default from "./controllers/mcp/oauth-clients.js";
37
+ import { mcpOAuthProtectedRouter, mcpOAuthPublicRouter } from "./controllers/mcp/oauth.js";
33
38
  import metrics_default from "./controllers/metrics.js";
34
39
  import not_found_default from "./controllers/not-found.js";
35
40
  import notifications_default from "./controllers/notifications.js";
@@ -55,14 +60,18 @@ import cache_default from "./middleware/cache.js";
55
60
  import cors_default from "./middleware/cors.js";
56
61
  import { errorHandler } from "./middleware/error-handler.js";
57
62
  import extract_token_default from "./middleware/extract-token.js";
63
+ import mcp_oauth_guard_default from "./middleware/mcp-oauth-guard.js";
64
+ import rate_limiter_global_default from "./middleware/rate-limiter-global.js";
65
+ import rate_limiter_ip_default from "./middleware/rate-limiter-ip.js";
58
66
  import request_counter_default from "./middleware/request-counter.js";
59
67
  import sanitize_query_default from "./middleware/sanitize-query.js";
60
68
  import schema_default$1 from "./middleware/schema.js";
61
- import schedule from "./schedules/metrics.js";
62
- import schedule$1 from "./schedules/project.js";
63
- import schedule$2 from "./schedules/retention.js";
64
- import schedule$3 from "./schedules/telemetry.js";
65
- import schedule$4 from "./schedules/tus.js";
69
+ import schedule$1 from "./schedules/metrics.js";
70
+ import scheduleOAuthCleanup from "./schedules/oauth-cleanup.js";
71
+ import schedule$2 from "./schedules/project.js";
72
+ import schedule$3 from "./schedules/retention.js";
73
+ import schedule$4 from "./schedules/telemetry.js";
74
+ import schedule$5 from "./schedules/tus.js";
66
75
  import { validateStorage } from "./utils/validate-storage.js";
67
76
  import { createRequire } from "node:module";
68
77
  import { readFile } from "node:fs/promises";
@@ -91,8 +100,16 @@ async function createApp() {
91
100
  if (!env["SECRET"]) logger.warn(`"SECRET" env variable is missing. Using a random value instead. Tokens will not persist between restarts. This is not appropriate for production usage.`);
92
101
  if (typeof env["SECRET"] === "string" && Buffer.byteLength(env["SECRET"]) < 32) logger.warn("\"SECRET\" env variable is shorter than 32 bytes which is insecure. This is not appropriate for production usage.");
93
102
  if (!new Url(env["PUBLIC_URL"]).isAbsolute()) logger.warn("\"PUBLIC_URL\" should be a full URL");
103
+ if (env["MCP_OAUTH_ENABLED"] === true) {
104
+ if (toBoolean(env["MCP_ENABLED"]) !== true) {
105
+ logger.warn("MCP_OAUTH_ENABLED requires MCP_ENABLED=true. OAuth disabled.");
106
+ env["MCP_OAUTH_ENABLED"] = false;
107
+ }
108
+ }
94
109
  await validateDatabaseExtensions();
95
110
  await validateStorage();
111
+ await getLicenseManager().initialize();
112
+ getEntitlementManager().initialize();
96
113
  await registerAuthProviders();
97
114
  registerDeploymentDrivers();
98
115
  await ensureDeploymentWebhooks();
@@ -199,7 +216,10 @@ async function createApp() {
199
216
  if (env["RATE_LIMITER_ENABLED"] === true) app.use(rate_limiter_ip_default);
200
217
  app.get("/server/ping", (_req, res) => res.send("pong"));
201
218
  app.use("/deployments/webhooks", deployment_webhooks_default);
219
+ if (env["MCP_OAUTH_ENABLED"] === true) app.use(mcpOAuthPublicRouter);
202
220
  app.use(authenticate_default);
221
+ app.use(mcp_oauth_guard_default);
222
+ if (env["MCP_OAUTH_ENABLED"] === true) app.use(mcpOAuthProtectedRouter);
203
223
  app.use(schema_default$1);
204
224
  app.use(sanitize_query_default);
205
225
  app.use(request_counter_default);
@@ -222,6 +242,7 @@ async function createApp() {
222
242
  app.use("/flows", flows_default);
223
243
  app.use("/folders", folders_default);
224
244
  app.use("/items", items_default);
245
+ app.use("/license", license_default);
225
246
  if (toBoolean(env["MCP_ENABLED"]) === true) app.use("/mcp", mcp_default);
226
247
  if (toBoolean(env["AI_ENABLED"]) === true) {
227
248
  await initAIDevTools();
@@ -240,6 +261,7 @@ async function createApp() {
240
261
  app.use("/relations", relations_default);
241
262
  app.use("/revisions", revisions_default);
242
263
  app.use("/roles", roles_default);
264
+ if (toBoolean(env["MCP_OAUTH_ENABLED"]) === true) app.use("/mcp-oauth/clients", oauth_clients_default);
243
265
  app.use("/schema", schema_default);
244
266
  app.use("/server", server_default);
245
267
  app.use("/settings", settings_default);
@@ -253,11 +275,13 @@ async function createApp() {
253
275
  app.use(not_found_default);
254
276
  app.use(errorHandler);
255
277
  await emitter_default.emitInit("routes.after", { app });
256
- await schedule$2();
257
278
  await schedule$3();
258
279
  await schedule$4();
259
- await schedule();
280
+ await schedule$5();
260
281
  await schedule$1();
282
+ await schedule$2();
283
+ await schedule();
284
+ if (env["MCP_OAUTH_ENABLED"] === true) await scheduleOAuthCleanup();
261
285
  await emitter_default.emitInit("app.after", { app });
262
286
  return app;
263
287
  }
@@ -3,11 +3,12 @@ import { useLogger } from "../../logger/index.js";
3
3
  import { REFRESH_COOKIE_OPTIONS, SESSION_COOKIE_OPTIONS } from "../../constants.js";
4
4
  import database_default from "../../database/index.js";
5
5
  import emitter_default from "../../emitter.js";
6
- import { getSchema } from "../../utils/get-schema.js";
7
6
  import { createDefaultAccountability } from "../../permissions/utils/create-default-accountability.js";
7
+ import { getSchema } from "../../utils/get-schema.js";
8
8
  import { respond } from "../../middleware/respond.js";
9
9
  import { getIPFromReq } from "../../utils/get-ip-from-req.js";
10
10
  import { AuthDriver } from "../auth.js";
11
+ import { checkSsoEnabled } from "../utils/check-sso-enabled.js";
11
12
  import { AuthenticationService } from "../../services/authentication.js";
12
13
  import { useEnv } from "@directus/env";
13
14
  import { ErrorCode, InvalidCredentialsError, InvalidPayloadError, InvalidProviderConfigError, InvalidProviderError, ServiceUnavailableError, UnexpectedResponseError, isDirectusError } from "@directus/errors";
@@ -247,6 +248,7 @@ function createLDAPAuthRouter(provider) {
247
248
  mode: Joi.string().valid("cookie", "json", "session"),
248
249
  otp: Joi.string()
249
250
  }).unknown();
251
+ router.use(checkSsoEnabled);
250
252
  router.post("/", async_handler_default(async (req, res, next) => {
251
253
  const env = useEnv();
252
254
  const accountability = createDefaultAccountability({ ip: getIPFromReq(req) });
@@ -5,6 +5,7 @@ import { stall } from "../../utils/stall.js";
5
5
  import { respond } from "../../middleware/respond.js";
6
6
  import { getIPFromReq } from "../../utils/get-ip-from-req.js";
7
7
  import { AuthDriver } from "../auth.js";
8
+ import { checkLocalAuthDisabled } from "../utils/check-local-disabled.js";
8
9
  import { AuthenticationService } from "../../services/authentication.js";
9
10
  import { useEnv } from "@directus/env";
10
11
  import { InvalidCredentialsError, InvalidPayloadError } from "@directus/errors";
@@ -31,6 +32,7 @@ var LocalAuthDriver = class extends AuthDriver {
31
32
  function createLocalAuthRouter(provider) {
32
33
  const env = useEnv();
33
34
  const router = Router();
35
+ router.use(checkLocalAuthDisabled);
34
36
  const userLoginSchema = Joi.object({
35
37
  email: Joi.string().email().required(),
36
38
  password: Joi.string().required(),
@@ -5,13 +5,14 @@ import { REFRESH_COOKIE_OPTIONS, SESSION_COOKIE_OPTIONS } from "../../constants.
5
5
  import database_default from "../../database/index.js";
6
6
  import emitter_default from "../../emitter.js";
7
7
  import { getSecret } from "../../utils/get-secret.js";
8
- import { getSchema } from "../../utils/get-schema.js";
9
8
  import { Url } from "../../utils/url.js";
10
9
  import { createDefaultAccountability } from "../../permissions/utils/create-default-accountability.js";
11
10
  import { verifyJWT } from "../../utils/jwt.js";
11
+ import { getSchema } from "../../utils/get-schema.js";
12
12
  import { respond } from "../../middleware/respond.js";
13
13
  import { getIPFromReq } from "../../utils/get-ip-from-req.js";
14
14
  import { LocalAuthDriver } from "./local.js";
15
+ import { checkSsoEnabled } from "../utils/check-sso-enabled.js";
15
16
  import { generateCallbackUrl } from "../utils/generate-callback-url.js";
16
17
  import { resolveLoginRedirect } from "../utils/resolve-login-redirect.js";
17
18
  import { getAuthProvider } from "../../auth.js";
@@ -232,6 +233,7 @@ const handleError = (e) => {
232
233
  function createOAuth2AuthRouter(providerName) {
233
234
  const router = Router();
234
235
  const env = useEnv();
236
+ router.use(checkSsoEnabled);
235
237
  router.get("/", (req, res) => {
236
238
  const provider = getAuthProvider(providerName);
237
239
  const codeVerifier = provider.generateCodeVerifier();
@@ -5,13 +5,14 @@ import { REFRESH_COOKIE_OPTIONS, SESSION_COOKIE_OPTIONS } from "../../constants.
5
5
  import database_default from "../../database/index.js";
6
6
  import emitter_default from "../../emitter.js";
7
7
  import { getSecret } from "../../utils/get-secret.js";
8
- import { getSchema } from "../../utils/get-schema.js";
9
8
  import { Url } from "../../utils/url.js";
10
9
  import { createDefaultAccountability } from "../../permissions/utils/create-default-accountability.js";
11
10
  import { verifyJWT } from "../../utils/jwt.js";
11
+ import { getSchema } from "../../utils/get-schema.js";
12
12
  import { respond } from "../../middleware/respond.js";
13
13
  import { getIPFromReq } from "../../utils/get-ip-from-req.js";
14
14
  import { LocalAuthDriver } from "./local.js";
15
+ import { checkSsoEnabled } from "../utils/check-sso-enabled.js";
15
16
  import { generateCallbackUrl } from "../utils/generate-callback-url.js";
16
17
  import { resolveLoginRedirect } from "../utils/resolve-login-redirect.js";
17
18
  import { getAuthProvider } from "../../auth.js";
@@ -275,6 +276,7 @@ const handleError = (e) => {
275
276
  function createOpenIDAuthRouter(providerName) {
276
277
  const env = useEnv();
277
278
  const router = Router();
279
+ router.use(checkSsoEnabled);
278
280
  router.get("/", async_handler_default(async (req, res) => {
279
281
  const provider = getAuthProvider(providerName);
280
282
  const codeVerifier = provider.generateCodeVerifier();
@@ -7,6 +7,7 @@ import emitter_default from "../../emitter.js";
7
7
  import { getSchema } from "../../utils/get-schema.js";
8
8
  import { respond } from "../../middleware/respond.js";
9
9
  import { LocalAuthDriver } from "./local.js";
10
+ import { checkSsoEnabled } from "../utils/check-sso-enabled.js";
10
11
  import { resolveLoginRedirect } from "../utils/resolve-login-redirect.js";
11
12
  import { getAuthProvider } from "../../auth.js";
12
13
  import { AuthenticationService } from "../../services/authentication.js";
@@ -79,6 +80,7 @@ var SAMLAuthDriver = class extends LocalAuthDriver {
79
80
  function createSAMLAuthRouter(providerName) {
80
81
  const router = Router();
81
82
  const env = useEnv();
83
+ router.use(checkSsoEnabled);
82
84
  router.get("/metadata", async_handler_default(async (_req, res) => {
83
85
  const { sp } = getAuthProvider(providerName);
84
86
  return res.header("Content-Type", "text/xml").send(sp.getMetadata());
@@ -0,0 +1,16 @@
1
+ import async_handler_default from "../../utils/async-handler.js";
2
+ import { getEntitlementManager } from "../../license/entitlements/manager.js";
3
+ import "../../license/index.js";
4
+ import { useEnv } from "@directus/env";
5
+ import { RouteNotFoundError } from "@directus/errors";
6
+ import { toBoolean } from "@directus/utils";
7
+
8
+ //#region src/auth/utils/check-local-disabled.ts
9
+ const checkLocalAuthDisabled = async_handler_default(async (req, _res, next) => {
10
+ const env = useEnv();
11
+ if (getEntitlementManager().isEntitled("sso_enabled") && toBoolean(env["AUTH_DISABLE_DEFAULT"])) throw new RouteNotFoundError({ path: req.path });
12
+ return next();
13
+ });
14
+
15
+ //#endregion
16
+ export { checkLocalAuthDisabled };
@@ -0,0 +1,14 @@
1
+ import async_handler_default from "../../utils/async-handler.js";
2
+ import { getEntitlementManager } from "../../license/entitlements/manager.js";
3
+ import { isSSOBypassAllowed } from "../../license/utils/is-sso-bypass-allowed.js";
4
+ import "../../license/index.js";
5
+ import { RouteNotFoundError } from "@directus/errors";
6
+
7
+ //#region src/auth/utils/check-sso-enabled.ts
8
+ const checkSsoEnabled = async_handler_default(async (req, _res, next) => {
9
+ if (!(getEntitlementManager().isEntitled("sso_enabled") || await isSSOBypassAllowed())) throw new RouteNotFoundError({ path: req.path });
10
+ return next();
11
+ });
12
+
13
+ //#endregion
14
+ export { checkSsoEnabled };
package/dist/auth.js CHANGED
@@ -2,15 +2,17 @@ import { getConfigFromEnv } from "./utils/get-config-from-env.js";
2
2
  import { useLogger } from "./logger/index.js";
3
3
  import { DEFAULT_AUTH_PROVIDER } from "./constants.js";
4
4
  import database_default from "./database/index.js";
5
+ import { getEntitlementManager } from "./license/entitlements/manager.js";
5
6
  import { LocalAuthDriver } from "./auth/drivers/local.js";
6
7
  import { OAuth2AuthDriver } from "./auth/drivers/oauth2.js";
7
8
  import { OpenIDAuthDriver } from "./auth/drivers/openid.js";
8
9
  import { LDAPAuthDriver } from "./auth/drivers/ldap.js";
9
10
  import { SAMLAuthDriver } from "./auth/drivers/saml.js";
10
11
  import "./auth/drivers/index.js";
12
+ import "./license/index.js";
11
13
  import { useEnv } from "@directus/env";
12
14
  import { InvalidProviderConfigError } from "@directus/errors";
13
- import { toArray } from "@directus/utils";
15
+ import { toArray, toBoolean } from "@directus/utils";
14
16
 
15
17
  //#region src/auth.ts
16
18
  const providers = /* @__PURE__ */ new Map();
@@ -27,10 +29,11 @@ async function registerAuthProviders() {
27
29
  const logger = useLogger();
28
30
  const options = { knex: database_default() };
29
31
  const providerNames = toArray(env["AUTH_PROVIDERS"]);
30
- if (!env["AUTH_DISABLE_DEFAULT"]) {
31
- const defaultProvider = getProviderInstance("local", options);
32
- providers.set(DEFAULT_AUTH_PROVIDER, defaultProvider);
33
- }
32
+ const sso_allowed = getEntitlementManager().isEntitled("sso_enabled");
33
+ if (sso_allowed === false && env["AUTH_PROVIDERS"] && providerNames.length > 0) logger.warn("you have SSO providers configured these will be unavailable under the current license tier");
34
+ if (sso_allowed === false && toBoolean(env["AUTH_DISABLE_DEFAULT"])) logger.warn("you cannot disable the default auth provider under the current license tier");
35
+ const defaultProvider = getProviderInstance("local", options);
36
+ providers.set(DEFAULT_AUTH_PROVIDER, defaultProvider);
34
37
  if (!env["AUTH_PROVIDERS"]) return;
35
38
  providerNames.forEach((name) => {
36
39
  name = name.trim();
@@ -1,7 +1,9 @@
1
1
  import { useLogger } from "../../../logger/index.js";
2
2
  import database_default, { hasDatabaseConnection, isInstalled, validateDatabaseConnection } from "../../../database/index.js";
3
3
  import { getSchema } from "../../../utils/get-schema.js";
4
+ import { getEntitlementManager } from "../../../license/entitlements/manager.js";
4
5
  import { SettingsService } from "../../../services/settings.js";
6
+ import "../../../license/index.js";
5
7
  import { createAdmin } from "../../../utils/create-admin.js";
6
8
  import run from "../../../database/migrations/run.js";
7
9
  import runSeed from "../../../database/seeds/run.js";
@@ -21,6 +23,7 @@ async function bootstrap({ skipAdminInit }) {
21
23
  logger.info("Running migrations...");
22
24
  await run(database, "latest");
23
25
  const schema = await getSchema();
26
+ getEntitlementManager();
24
27
  if (skipAdminInit == null) await createAdmin(schema);
25
28
  else logger.info("Skipping creation of default Admin user and role...");
26
29
  const settingsService = new SettingsService({ schema });
@@ -1,5 +1,7 @@
1
1
  import { useLogger } from "../../../logger/index.js";
2
2
  import { clearSystemCache, getCache } from "../../../cache.js";
3
+ import { getEntitlementManager } from "../../../license/entitlements/manager.js";
4
+ import "../../../license/index.js";
3
5
  import { useEnv } from "@directus/env";
4
6
 
5
7
  //#region src/cli/commands/cache/clear.ts
@@ -12,7 +14,10 @@ async function cacheClear({ system, data }) {
12
14
  } else {
13
15
  const clearAll = !system && !data;
14
16
  try {
15
- if (clearAll || system) await clearSystemCache({ forced: true });
17
+ if (clearAll || system) {
18
+ await clearSystemCache({ forced: true });
19
+ await getEntitlementManager().clearCache();
20
+ }
16
21
  if (clearAll || data) {
17
22
  const { cache } = getCache();
18
23
  await cache?.clear();
@@ -1,10 +1,12 @@
1
1
  import { useLogger } from "../../../logger/index.js";
2
2
  import database_default from "../../../database/index.js";
3
- import { getSchema } from "../../../utils/get-schema.js";
4
3
  import { AccessService } from "../../../services/access.js";
4
+ import { getSchema } from "../../../utils/get-schema.js";
5
5
  import { RolesService } from "../../../services/roles.js";
6
6
  import { PoliciesService } from "../../../services/policies.js";
7
7
  import "../../../services/index.js";
8
+ import { getLicenseManager } from "../../../license/manager.js";
9
+ import "../../../license/index.js";
8
10
 
9
11
  //#region src/cli/commands/roles/create.ts
10
12
  async function rolesCreate({ role: name, admin, app }) {
@@ -14,6 +16,7 @@ async function rolesCreate({ role: name, admin, app }) {
14
16
  logger.error("Name is required");
15
17
  process.exit(1);
16
18
  }
19
+ await getLicenseManager().initialize();
17
20
  try {
18
21
  const schema = await getSchema();
19
22
  const rolesService = new RolesService({
@@ -2,6 +2,8 @@ import { useLogger } from "../../../logger/index.js";
2
2
  import database_default from "../../../database/index.js";
3
3
  import { getSchema } from "../../../utils/get-schema.js";
4
4
  import { UsersService } from "../../../services/users.js";
5
+ import { getLicenseManager } from "../../../license/manager.js";
6
+ import "../../../license/index.js";
5
7
 
6
8
  //#region src/cli/commands/users/create.ts
7
9
  async function usersCreate({ email, password, role }) {
@@ -11,6 +13,7 @@ async function usersCreate({ email, password, role }) {
11
13
  logger.error("Email, password, role are required");
12
14
  process.exit(1);
13
15
  }
16
+ await getLicenseManager().initialize();
14
17
  try {
15
18
  const id = await new UsersService({
16
19
  schema: await getSchema(),
package/dist/constants.js CHANGED
@@ -140,6 +140,13 @@ const RESUMABLE_UPLOADS = {
140
140
  SCHEDULE: String(env["TUS_CLEANUP_SCHEDULE"])
141
141
  };
142
142
  const ALLOWED_DB_DEFAULT_FUNCTIONS = ["gen_random_uuid()"];
143
+ const CUSTOM_LLM_FIELDS = [
144
+ "ai_openai_compatible_api_key",
145
+ "ai_openai_compatible_base_url",
146
+ "ai_openai_compatible_name",
147
+ "ai_openai_compatible_models",
148
+ "ai_openai_compatible_headers"
149
+ ];
143
150
 
144
151
  //#endregion
145
- export { ALIAS_TYPES, ALLOWED_DB_DEFAULT_FUNCTIONS, ASSET_TRANSFORM_QUERY_KEYS, COLUMN_TRANSFORMS, DEFAULT_AUTH_PROVIDER, FILE_UPLOADS, FILTER_VARIABLES, OAS_REQUIRED_SCHEMAS, REFRESH_COOKIE_OPTIONS, RESUMABLE_UPLOADS, SESSION_COOKIE_OPTIONS, SUPPORTED_IMAGE_METADATA_FORMATS, SUPPORTED_IMAGE_TRANSFORM_FORMATS, SYSTEM_ASSET_ALLOW_LIST, UUID_REGEX };
152
+ export { ALIAS_TYPES, ALLOWED_DB_DEFAULT_FUNCTIONS, ASSET_TRANSFORM_QUERY_KEYS, COLUMN_TRANSFORMS, CUSTOM_LLM_FIELDS, DEFAULT_AUTH_PROVIDER, FILE_UPLOADS, FILTER_VARIABLES, OAS_REQUIRED_SCHEMAS, REFRESH_COOKIE_OPTIONS, RESUMABLE_UPLOADS, SESSION_COOKIE_OPTIONS, SUPPORTED_IMAGE_METADATA_FORMATS, SUPPORTED_IMAGE_TRANSFORM_FORMATS, SYSTEM_ASSET_ALLOW_LIST, UUID_REGEX };
@@ -1,7 +1,7 @@
1
1
  import async_handler_default from "../utils/async-handler.js";
2
- import { sanitizeQuery } from "../utils/sanitize-query.js";
3
2
  import { AccessService } from "../services/access.js";
4
3
  import { respond } from "../middleware/respond.js";
4
+ import { sanitizeQuery } from "../utils/sanitize-query.js";
5
5
  import { MetaService } from "../services/meta.js";
6
6
  import use_collection_default from "../middleware/use-collection.js";
7
7
  import { validateBatch } from "../middleware/validate-batch.js";
@@ -22,7 +22,8 @@ const readHandler = async_handler_default(async (req, res, next) => {
22
22
  if (req.singleton) result = await service.readSingleton(req.sanitizedQuery);
23
23
  else if (req.body.keys) result = await service.readMany(req.body.keys, req.sanitizedQuery);
24
24
  else result = await service.readByQuery(req.sanitizedQuery);
25
- const meta = await metaService.getMetaForQuery("directus_activity", req.sanitizedQuery);
25
+ const historyQuery = service.getLimitedHistoryQuery(req.sanitizedQuery);
26
+ const meta = await metaService.getMetaForQuery("directus_activity", historyQuery);
26
27
  res.locals["payload"] = {
27
28
  data: result,
28
29
  meta
@@ -12,6 +12,7 @@ import { FilesService } from "../services/files.js";
12
12
  import { AssetsService } from "../services/assets.js";
13
13
  import { getCacheControlHeader } from "../utils/get-cache-headers.js";
14
14
  import use_collection_default from "../middleware/use-collection.js";
15
+ import is_locked_default from "../middleware/is-locked.js";
15
16
  import { useEnv } from "@directus/env";
16
17
  import { InvalidPayloadError, InvalidQueryError, RangeNotSatisfiableError } from "@directus/errors";
17
18
  import { getDateTimeFormatted, parseJSON } from "@directus/utils";
@@ -25,6 +26,7 @@ import contentDisposition from "content-disposition";
25
26
  const router = Router();
26
27
  const env = useEnv();
27
28
  router.use(use_collection_default("directus_files"));
29
+ router.use(is_locked_default("assets"));
28
30
  router.post("/folder/:pk", async_handler_default(async (req, res) => {
29
31
  const logger = useLogger();
30
32
  const { archive, complete, metadata } = await new AssetsService({
@@ -2,13 +2,15 @@ import async_handler_default from "../utils/async-handler.js";
2
2
  import { useLogger } from "../logger/index.js";
3
3
  import { DEFAULT_AUTH_PROVIDER, REFRESH_COOKIE_OPTIONS, SESSION_COOKIE_OPTIONS } from "../constants.js";
4
4
  import { getSecret } from "../utils/get-secret.js";
5
- import { getAuthProviders } from "../utils/get-auth-providers.js";
6
5
  import { createDefaultAccountability } from "../permissions/utils/create-default-accountability.js";
7
6
  import { verifyAccessJWT } from "../utils/jwt.js";
7
+ import { getAuthProviders } from "../utils/get-auth-providers.js";
8
+ import { getEntitlementManager } from "../license/entitlements/manager.js";
8
9
  import { UsersService } from "../services/users.js";
9
10
  import { respond } from "../middleware/respond.js";
10
11
  import { getIPFromReq } from "../utils/get-ip-from-req.js";
11
12
  import { createLocalAuthRouter } from "../auth/drivers/local.js";
13
+ import { isSSOBypassAllowed } from "../license/utils/is-sso-bypass-allowed.js";
12
14
  import { createOAuth2AuthRouter } from "../auth/drivers/oauth2.js";
13
15
  import { createOpenIDAuthRouter } from "../auth/drivers/openid.js";
14
16
  import { createLDAPAuthRouter } from "../auth/drivers/ldap.js";
@@ -16,8 +18,10 @@ import { createSAMLAuthRouter } from "../auth/drivers/saml.js";
16
18
  import "../auth/drivers/index.js";
17
19
  import { AuthenticationService } from "../services/authentication.js";
18
20
  import isDirectusJWT from "../utils/is-directus-jwt.js";
21
+ import "../license/index.js";
19
22
  import { useEnv } from "@directus/env";
20
23
  import { ErrorCode, InvalidPayloadError, isDirectusError } from "@directus/errors";
24
+ import { toBoolean } from "@directus/utils";
21
25
  import { Router } from "express";
22
26
 
23
27
  //#region src/controllers/auth.ts
@@ -50,7 +54,6 @@ for (const authProvider of authProviders) {
50
54
  }
51
55
  router.use(`/login/${authProvider.name}`, authRouter);
52
56
  }
53
- if (!env["AUTH_DISABLE_DEFAULT"]) router.use("/login", createLocalAuthRouter(DEFAULT_AUTH_PROVIDER));
54
57
  function getCurrentMode(req) {
55
58
  if (req.body.mode) return req.body.mode;
56
59
  if (req.body.refresh_token) return "json";
@@ -64,6 +67,7 @@ function getCurrentRefreshToken(req, mode) {
64
67
  if (isDirectusJWT(token)) return verifyAccessJWT(token, getSecret()).session;
65
68
  }
66
69
  }
70
+ router.use("/login", createLocalAuthRouter(DEFAULT_AUTH_PROVIDER));
67
71
  router.post("/refresh", async_handler_default(async (req, res, next) => {
68
72
  const accountability = createDefaultAccountability({ ip: getIPFromReq(req) });
69
73
  const userAgent = req.get("user-agent")?.substring(0, 1024);
@@ -145,10 +149,14 @@ router.post("/password/reset", async_handler_default(async (req, _res, next) =>
145
149
  return next();
146
150
  }), respond);
147
151
  router.get("/", async_handler_default(async (req, res, next) => {
148
- const sessionOnly = "sessionOnly" in req.query && (req.query["sessionOnly"] === "" || Boolean(req.query["sessionOnly"]));
152
+ let providers = getAuthProviders({ sessionOnly: "sessionOnly" in req.query && (req.query["sessionOnly"] === "" || Boolean(req.query["sessionOnly"])) });
153
+ const isSSOEnabled = getEntitlementManager().isEntitled("sso_enabled");
154
+ if (providers.length > 0 && !isSSOEnabled) {
155
+ if (!await isSSOBypassAllowed()) providers = [];
156
+ }
149
157
  res.locals["payload"] = {
150
- data: getAuthProviders({ sessionOnly }),
151
- disableDefault: env["AUTH_DISABLE_DEFAULT"]
158
+ data: providers,
159
+ disableDefault: isSSOEnabled ? toBoolean(env["AUTH_DISABLE_DEFAULT"]) : false
152
160
  };
153
161
  return next();
154
162
  }), respond);
@@ -1,7 +1,7 @@
1
1
  import async_handler_default from "../utils/async-handler.js";
2
- import { CollectionsService } from "../services/collections.js";
3
2
  import { respond } from "../middleware/respond.js";
4
3
  import { MetaService } from "../services/meta.js";
4
+ import { CollectionsService } from "../services/collections.js";
5
5
  import { validateBatch } from "../middleware/validate-batch.js";
6
6
  import { ErrorCode, isDirectusError } from "@directus/errors";
7
7
  import { Router } from "express";
@@ -1,7 +1,7 @@
1
1
  import async_handler_default from "../utils/async-handler.js";
2
- import { sanitizeQuery } from "../utils/sanitize-query.js";
3
2
  import { respond } from "../middleware/respond.js";
4
3
  import { CommentsService } from "../services/comments.js";
4
+ import { sanitizeQuery } from "../utils/sanitize-query.js";
5
5
  import { MetaService } from "../services/meta.js";
6
6
  import use_collection_default from "../middleware/use-collection.js";
7
7
  import { validateBatch } from "../middleware/validate-batch.js";
@@ -1,7 +1,7 @@
1
1
  import async_handler_default from "../utils/async-handler.js";
2
- import { sanitizeQuery } from "../utils/sanitize-query.js";
3
2
  import { respond } from "../middleware/respond.js";
4
3
  import { DashboardsService } from "../services/dashboards.js";
4
+ import { sanitizeQuery } from "../utils/sanitize-query.js";
5
5
  import { MetaService } from "../services/meta.js";
6
6
  import use_collection_default from "../middleware/use-collection.js";
7
7
  import { validateBatch } from "../middleware/validate-batch.js";
@@ -1,7 +1,7 @@
1
1
  import async_handler_default from "../utils/async-handler.js";
2
2
  import { ALIAS_TYPES } from "../constants.js";
3
- import { FieldsService, systemFieldUpdateSchema } from "../services/fields.js";
4
3
  import { respond } from "../middleware/respond.js";
4
+ import { FieldsService, systemFieldUpdateSchema } from "../services/fields.js";
5
5
  import use_collection_default from "../middleware/use-collection.js";
6
6
  import collection_exists_default from "../middleware/collection-exists.js";
7
7
  import { ErrorCode, ForbiddenError, InvalidPayloadError, isDirectusError } from "@directus/errors";
@@ -1,10 +1,11 @@
1
1
  import async_handler_default from "../utils/async-handler.js";
2
2
  import { FilesService } from "../services/files.js";
3
- import { sanitizeQuery } from "../utils/sanitize-query.js";
4
3
  import { respond } from "../middleware/respond.js";
4
+ import { sanitizeQuery } from "../utils/sanitize-query.js";
5
5
  import { MetaService } from "../services/meta.js";
6
6
  import use_collection_default from "../middleware/use-collection.js";
7
7
  import { validateBatch } from "../middleware/validate-batch.js";
8
+ import is_locked_default from "../middleware/is-locked.js";
8
9
  import path from "path";
9
10
  import { useEnv } from "@directus/env";
10
11
  import { ErrorCode, InvalidPayloadError, isDirectusError } from "@directus/errors";
@@ -20,6 +21,7 @@ import Busboy from "busboy";
20
21
  const router = express.Router();
21
22
  const env = useEnv();
22
23
  router.use(use_collection_default("directus_files"));
24
+ router.use(is_locked_default("files"));
23
25
  const multipartHandler = (req, res, next) => {
24
26
  if (req.is("multipart/form-data") === false) return next();
25
27
  let headers;
@@ -1,12 +1,13 @@
1
1
  import async_handler_default from "../utils/async-handler.js";
2
2
  import { UUID_REGEX } from "../constants.js";
3
- import { sanitizeQuery } from "../utils/sanitize-query.js";
3
+ import { FlowsService } from "../services/flows.js";
4
+ import { getFlowManager } from "../flows.js";
4
5
  import { respond } from "../middleware/respond.js";
6
+ import { sanitizeQuery } from "../utils/sanitize-query.js";
5
7
  import { MetaService } from "../services/meta.js";
6
- import { getFlowManager } from "../flows.js";
7
- import { FlowsService } from "../services/flows.js";
8
8
  import use_collection_default from "../middleware/use-collection.js";
9
9
  import { validateBatch } from "../middleware/validate-batch.js";
10
+ import is_locked_default from "../middleware/is-locked.js";
10
11
  import { ErrorCode, isDirectusError } from "@directus/errors";
11
12
  import express from "express";
12
13
 
@@ -28,8 +29,8 @@ const webhookFlowHandler = async_handler_default(async (req, res, next) => {
28
29
  res.locals["payload"] = result;
29
30
  return next();
30
31
  });
31
- router.get(`/trigger/:pk(${UUID_REGEX})`, webhookFlowHandler, respond);
32
- router.post(`/trigger/:pk(${UUID_REGEX})`, webhookFlowHandler, respond);
32
+ router.get(`/trigger/:pk(${UUID_REGEX})`, is_locked_default("flows"), webhookFlowHandler, respond);
33
+ router.post(`/trigger/:pk(${UUID_REGEX})`, is_locked_default("flows"), webhookFlowHandler, respond);
33
34
  router.post("/", async_handler_default(async (req, res, next) => {
34
35
  const service = new FlowsService({
35
36
  accountability: req.accountability,
@@ -1,7 +1,7 @@
1
1
  import async_handler_default from "../utils/async-handler.js";
2
2
  import { FoldersService } from "../services/folders.js";
3
- import { sanitizeQuery } from "../utils/sanitize-query.js";
4
3
  import { respond } from "../middleware/respond.js";
4
+ import { sanitizeQuery } from "../utils/sanitize-query.js";
5
5
  import { MetaService } from "../services/meta.js";
6
6
  import use_collection_default from "../middleware/use-collection.js";
7
7
  import { validateBatch } from "../middleware/validate-batch.js";