diff --git a/backend/.sqlx/query-9739c91f85f36367cec44b12c921e2917afbcb249dbf52c82f06c943f0e1185d.json b/backend/.sqlx/query-0360207b5fb2a7f877c2608566454f40f7cbbcd20bcb84e5968ac3e21b6ea0f6.json similarity index 50% rename from backend/.sqlx/query-9739c91f85f36367cec44b12c921e2917afbcb249dbf52c82f06c943f0e1185d.json rename to backend/.sqlx/query-0360207b5fb2a7f877c2608566454f40f7cbbcd20bcb84e5968ac3e21b6ea0f6.json index af628eb1bd..2f3458dc56 100644 --- a/backend/.sqlx/query-9739c91f85f36367cec44b12c921e2917afbcb249dbf52c82f06c943f0e1185d.json +++ b/backend/.sqlx/query-0360207b5fb2a7f877c2608566454f40f7cbbcd20bcb84e5968ac3e21b6ea0f6.json @@ -1,6 +1,6 @@ { "db_name": "PostgreSQL", - "query": "INSERT INTO workspace_invite\n (workspace_id, email, is_admin, operator)\n SELECT $1::text, email, false, $3 FROM password WHERE $2::text = '*' OR email LIKE CONCAT('%', $2::text) AND NOT EXISTS (\n SELECT 1 FROM usr WHERE workspace_id = $1::text AND email = password.email\n )\n ON CONFLICT DO NOTHING", + "query": "INSERT INTO workspace_invite\n (workspace_id, email, is_admin, operator)\n SELECT $1::text, email, false, $3 FROM password WHERE ($2::text = '*' OR email LIKE CONCAT('%', $2::text)) AND NOT EXISTS (\n SELECT 1 FROM usr WHERE workspace_id = $1::text AND email = password.email\n )\n ON CONFLICT DO NOTHING", "describe": { "columns": [], "parameters": { @@ -12,5 +12,5 @@ }, "nullable": [] }, - "hash": "9739c91f85f36367cec44b12c921e2917afbcb249dbf52c82f06c943f0e1185d" + "hash": "0360207b5fb2a7f877c2608566454f40f7cbbcd20bcb84e5968ac3e21b6ea0f6" } diff --git a/backend/windmill-api/openapi.yaml b/backend/windmill-api/openapi.yaml index 51219fa615..a7ed5d8b90 100644 --- a/backend/windmill-api/openapi.yaml +++ b/backend/windmill-api/openapi.yaml @@ -1349,6 +1349,8 @@ paths: properties: operator: type: boolean + invite_all: + type: boolean responses: "200": @@ -6296,7 +6298,9 @@ paths: /w/{workspace}/job_helpers/duckdb_connection_settings: post: - summary: Converts an S3 resource to the set of instructions necessary to connect DuckDB to an S3 bucket + summary: + Converts an S3 resource to the set of instructions necessary to connect + DuckDB to an S3 bucket operationId: duckdbConnectionSettings tags: - helpers diff --git a/backend/windmill-api/src/workspaces.rs b/backend/windmill-api/src/workspaces.rs index 1642d9346a..10b574d952 100644 --- a/backend/windmill-api/src/workspaces.rs +++ b/backend/windmill-api/src/workspaces.rs @@ -748,13 +748,17 @@ async fn edit_auto_invite( // )); // } - if ea.invite_all.is_some_and(|x| x) && *CLOUD_HOSTED { + let domain = if ea.invite_all.is_some_and(|x| x) { + if *CLOUD_HOSTED { return Err(Error::BadRequest( "invite_all is only available locally".to_string(), )); - - } - let domain = email.split('@').last().unwrap(); + } else { + "*" + } + } else { + email.split('@').last().unwrap() + }; let mut tx = db.begin().await?; @@ -778,7 +782,7 @@ async fn edit_auto_invite( sqlx::query!( "INSERT INTO workspace_invite (workspace_id, email, is_admin, operator) - SELECT $1::text, email, false, $3 FROM password WHERE $2::text = '*' OR email LIKE CONCAT('%', $2::text) AND NOT EXISTS ( + SELECT $1::text, email, false, $3 FROM password WHERE ($2::text = '*' OR email LIKE CONCAT('%', $2::text)) AND NOT EXISTS ( SELECT 1 FROM usr WHERE workspace_id = $1::text AND email = password.email ) ON CONFLICT DO NOTHING", diff --git a/frontend/src/lib/components/Editor.svelte b/frontend/src/lib/components/Editor.svelte index 1f76d3792e..d0bcad2491 100644 --- a/frontend/src/lib/components/Editor.svelte +++ b/frontend/src/lib/components/Editor.svelte @@ -107,7 +107,7 @@ let websockets: WebSocket[] = [] let languageClients: MonacoLanguageClient[] = [] - let websocketInterval: NodeJS.Timer | undefined + let websocketInterval: NodeJS.Timeout | undefined let lastWsAttempt: Date = new Date() let nbWsAttempt = 0 let disposeMethod: () => void | undefined diff --git a/frontend/src/lib/components/InputTransformForm.svelte b/frontend/src/lib/components/InputTransformForm.svelte index 7b0ae2083e..ba22807dca 100644 --- a/frontend/src/lib/components/InputTransformForm.svelte +++ b/frontend/src/lib/components/InputTransformForm.svelte @@ -160,14 +160,16 @@ /> {#if isStaticTemplate(inputCat)} - - {'${...}'} - +
+ + {'${...}'} + +
{/if} {#if !noDynamicToggle} diff --git a/frontend/src/lib/components/InstanceSettings.svelte b/frontend/src/lib/components/InstanceSettings.svelte index 0a980e9e63..2c66b88834 100644 --- a/frontend/src/lib/components/InstanceSettings.svelte +++ b/frontend/src/lib/components/InstanceSettings.svelte @@ -376,7 +376,7 @@ type="text" placeholder={setting.placeholder} class={hasError - ? 'border !border-red-700 !border-opacity-30 !focus:border-red-700 !focus:border-opacity-30 !bg-red-100' + ? 'border !border-red-700 !border-opacity-30 !focus:border-red-700 !focus:border-opacity-30' : ''} bind:value={values[setting.key]} /> @@ -450,7 +450,7 @@ {#if hasError} - Base url must start with http:// or https:// and must not end with a + Base url must start with http:// or https:// and must NOT end with a trailing slash. {/if} diff --git a/frontend/src/lib/components/instanceSettings.ts b/frontend/src/lib/components/instanceSettings.ts index f332a95dba..b21a2619bd 100644 --- a/frontend/src/lib/components/instanceSettings.ts +++ b/frontend/src/lib/components/instanceSettings.ts @@ -32,7 +32,7 @@ export const settings: Record = { placeholder: 'https://windmill.com', storage: 'setting', isValid: (value: string | undefined) => - value ? value?.startsWith('http') && !value?.endsWith('/') : true + value ? value?.startsWith('http') && value.includes('://') && !value?.endsWith('/') : true }, { label: 'Request Size Limit In MB', diff --git a/frontend/src/lib/components/settings/WorkspaceUserSettings.svelte b/frontend/src/lib/components/settings/WorkspaceUserSettings.svelte index 0e980c5c5b..01ec66613c 100644 --- a/frontend/src/lib/components/settings/WorkspaceUserSettings.svelte +++ b/frontend/src/lib/components/settings/WorkspaceUserSettings.svelte @@ -20,6 +20,7 @@ import Cell from '../table/Cell.svelte' import Row from '../table/Row.svelte' import ConfirmationModal from '../common/confirmationModal/ConfirmationModal.svelte' + import { isCloudHosted } from '$lib/cloud' let users: User[] | undefined = undefined let invites: WorkspaceInvite[] = [] @@ -331,18 +332,20 @@ primary={false} />
- {#if auto_invite_domain != domain} + {#if auto_invite_domain != domain && auto_invite_domain != '*'}
{#if isCloudHosted()}Auto-invite any users from {domain}{:else}Auto-invite anyone joining + the instance{/if}
{/if} @@ -375,7 +378,11 @@ listInvites() }} > - Unset auto-invite from {auto_invite_domain} domain + {#if isCloudHosted()} + Unset auto-invite from {auto_invite_domain} domain + {:else} + Unset auto-invite anyone joining the instance + {/if}
diff --git a/frontend/src/routes/(root)/(logged)/user/(user)/create_workspace/+page.svelte b/frontend/src/routes/(root)/(logged)/user/(user)/create_workspace/+page.svelte index 85e6958f39..08a9868a62 100644 --- a/frontend/src/routes/(root)/(logged)/user/(user)/create_workspace/+page.svelte +++ b/frontend/src/routes/(root)/(logged)/user/(user)/create_workspace/+page.svelte @@ -13,6 +13,7 @@ import { sendUserToast } from '$lib/toast' import TestOpenaiKey from '$lib/components/copilot/TestOpenaiKey.svelte' import { switchWorkspace } from '$lib/storeUtils' + import { isCloudHosted } from '$lib/cloud' const rd = $page.url.searchParams.get('rd') @@ -55,7 +56,7 @@ if (auto_invite) { await WorkspaceService.editAutoInvite({ workspace: id, - requestBody: { operator: operatorOnly } + requestBody: { operator: operatorOnly, invite_all: !isCloudHosted() } }) } if (openAiKey != '') { @@ -180,13 +181,17 @@
An operator can only execute and view scripts/flows/apps from your workspace, and only those diff --git a/frontend/src/routes/(root)/(logged)/workspace_settings/+page.svelte b/frontend/src/routes/(root)/(logged)/workspace_settings/+page.svelte index 07dec52ab7..a0dccdcc32 100644 --- a/frontend/src/routes/(root)/(logged)/workspace_settings/+page.svelte +++ b/frontend/src/routes/(root)/(logged)/workspace_settings/+page.svelte @@ -285,9 +285,6 @@
Premium Plans
{/if} - -
Delete Workspace
-
{#if WORKSPACE_SHOW_WEBHOOK_CLI_SYNC}
Webhook
@@ -299,6 +296,9 @@
Windmill AI
+ +
Delete Workspace
+
{#if tab == 'users'}