diff --git a/backend/migrations/20251208123907_safety_custom_instance_db_user_pwd.down.sql b/backend/migrations/20251208123907_safety_custom_instance_db_user_pwd.down.sql new file mode 100644 index 0000000000..d2f607c5b8 --- /dev/null +++ b/backend/migrations/20251208123907_safety_custom_instance_db_user_pwd.down.sql @@ -0,0 +1 @@ +-- Add down migration script here diff --git a/backend/migrations/20251208123907_safety_custom_instance_db_user_pwd.up.sql b/backend/migrations/20251208123907_safety_custom_instance_db_user_pwd.up.sql new file mode 100644 index 0000000000..c5c6b670ae --- /dev/null +++ b/backend/migrations/20251208123907_safety_custom_instance_db_user_pwd.up.sql @@ -0,0 +1,32 @@ +DO $$ +DECLARE + pwd text; +BEGIN + SELECT gen_random_uuid()::text INTO pwd; + + IF EXISTS (SELECT 1 FROM pg_roles WHERE rolname = 'custom_instance_user') THEN + EXECUTE format('ALTER USER custom_instance_user WITH PASSWORD %L', pwd); + RAISE NOTICE 'Updated password for existing user custom_instance_user'; + ELSE + EXECUTE format('CREATE USER custom_instance_user WITH PASSWORD %L', pwd); + RAISE NOTICE 'Created new user custom_instance_user'; + END IF; + + IF NOT EXISTS (SELECT 1 FROM global_settings WHERE name = 'custom_instance_pg_databases') THEN + INSERT INTO global_settings (name, value) + VALUES ('custom_instance_pg_databases', jsonb_build_object( + 'user_pwd', pwd::text, + 'databases', jsonb_build_object() + )); + RAISE NOTICE 'Inserted new global setting for custom_instance_pg_databases'; + ELSE + UPDATE global_settings + SET value = jsonb_set(COALESCE(value, '{}'::jsonb), '{user_pwd}', to_jsonb(pwd::text)::jsonb) + WHERE name = 'custom_instance_pg_databases'; + RAISE NOTICE 'Updated user_pwd in existing global setting for custom_instance_pg_databases'; + END IF; +EXCEPTION + WHEN others THEN + RAISE NOTICE 'custom_instance_pg_databases migration error, skipping.'; +END +$$; diff --git a/backend/windmill-api/openapi.yaml b/backend/windmill-api/openapi.yaml index ded8a90fa2..912cc477c5 100644 --- a/backend/windmill-api/openapi.yaml +++ b/backend/windmill-api/openapi.yaml @@ -847,6 +847,20 @@ paths: schema: type: boolean + /settings/refresh_custom_instance_user_pwd: + post: + summary: Refreshes the password for the custom_instance_user + operationId: refreshCustomInstanceUserPwd + tags: + - setting + responses: + "200": + description: Success + content: + application/json: + schema: + type: object + /settings/list_custom_instance_pg_databases: post: summary: Returns the set-up statuses of custom instance pg databases diff --git a/backend/windmill-api/src/settings.rs b/backend/windmill-api/src/settings.rs index ec0fe5061e..9fa240088e 100644 --- a/backend/windmill-api/src/settings.rs +++ b/backend/windmill-api/src/settings.rs @@ -73,6 +73,10 @@ pub fn global_service() -> Router { "/list_custom_instance_pg_databases", post(list_custom_instance_pg_databases), ) + .route( + "/refresh_custom_instance_user_pwd", + post(refresh_custom_instance_user_pwd), + ) .route( "/setup_custom_instance_pg_database/:name", post(setup_custom_instance_pg_database), @@ -625,6 +629,47 @@ async fn list_custom_instance_pg_databases( return Ok(Json(result)); } +async fn refresh_custom_instance_user_pwd( + authed: ApiAuthed, + Extension(db): Extension, +) -> JsonResult<()> { + require_super_admin(&db, &authed.email).await?; + // 20251208123907_safety_custom_instance_db_user_pwd.up + let query = r#" + DO $$ + DECLARE + pwd text; + BEGIN + SELECT gen_random_uuid()::text INTO pwd; + + IF EXISTS (SELECT 1 FROM pg_roles WHERE rolname = 'custom_instance_user') THEN + EXECUTE format('ALTER USER custom_instance_user WITH PASSWORD %L', pwd); + RAISE NOTICE 'Updated password for existing user custom_instance_user'; + ELSE + EXECUTE format('CREATE USER custom_instance_user WITH PASSWORD %L', pwd); + RAISE NOTICE 'Created new user custom_instance_user'; + END IF; + + IF NOT EXISTS (SELECT 1 FROM global_settings WHERE name = 'custom_instance_pg_databases') THEN + INSERT INTO global_settings (name, value) + VALUES ('custom_instance_pg_databases', jsonb_build_object( + 'user_pwd', pwd::text, + 'databases', jsonb_build_object() + )); + RAISE NOTICE 'Inserted new global setting for custom_instance_pg_databases'; + ELSE + UPDATE global_settings + SET value = jsonb_set(COALESCE(value, '{}'::jsonb), '{user_pwd}', to_jsonb(pwd::text)::jsonb) + WHERE name = 'custom_instance_pg_databases'; + RAISE NOTICE 'Updated user_pwd in existing global setting for custom_instance_pg_databases'; + END IF; + END + $$; + "#; + sqlx::query(query).execute(&db).await?; + Ok(Json(())) +} + #[derive(Deserialize)] struct SetupCustomInstanceDbBody { tag: Option, diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 018107154f..717eb3c627 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -79,11 +79,11 @@ "windmill-parser-wasm-java": "1.510.1", "windmill-parser-wasm-nu": "1.510.1", "windmill-parser-wasm-php": "1.574.1", - "windmill-parser-wasm-py": "1.538.0", - "windmill-parser-wasm-regex": "1.576.3", + "windmill-parser-wasm-py": "1.589.3", + "windmill-parser-wasm-regex": "1.589.3", "windmill-parser-wasm-ruby": "1.526.1", "windmill-parser-wasm-rust": "1.558.1", - "windmill-parser-wasm-ts": "1.565.0", + "windmill-parser-wasm-ts": "1.589.3", "windmill-parser-wasm-yaml": "1.561.0", "windmill-sql-datatype-parser-wasm": "1.512.0", "windmill-utils-internal": "^1.3.1", @@ -13851,14 +13851,14 @@ "integrity": "sha512-COyid6B1RYs+bpzUCInsA4HY/WZkpDLfkQ90+AqU/TVTpzYSbAC2JCbIwy0cRElBvlhI4bQ+9Wg6hSQKMpEkpA==" }, "node_modules/windmill-parser-wasm-py": { - "version": "1.538.0", - "resolved": "https://registry.npmjs.org/windmill-parser-wasm-py/-/windmill-parser-wasm-py-1.538.0.tgz", - "integrity": "sha512-s+bdIgT/fA5em3zYUwF8D14uA/dZh7iu0krZYZQqZUO7txN37hwSCVfovbMkIwm4zPbsJ50mU8DRLt7UpAPZIw==" + "version": "1.589.3", + "resolved": "https://registry.npmjs.org/windmill-parser-wasm-py/-/windmill-parser-wasm-py-1.589.3.tgz", + "integrity": "sha512-ob1auYfqDyjaliXVluSKAuhfW09TefJ1rJjfDBnV5KCumkTBYGSchrGU+2AJYiuwCtljRE5CzTPBAo6JTaSKHA==" }, "node_modules/windmill-parser-wasm-regex": { - "version": "1.576.3", - "resolved": "https://registry.npmjs.org/windmill-parser-wasm-regex/-/windmill-parser-wasm-regex-1.576.3.tgz", - "integrity": "sha512-+5or2Gzi2W+DXU3cDqUB2sn3t3t1ZJ5BGpEh94r30fbm9yGxSy9QvxsURqv59ubKCjmm3oKwqApSyn+OqXSLjg==" + "version": "1.589.3", + "resolved": "https://registry.npmjs.org/windmill-parser-wasm-regex/-/windmill-parser-wasm-regex-1.589.3.tgz", + "integrity": "sha512-yfYxHtrTuW+vqovPvu1h0t9XmC1cLzE6Quxb6fke3rxKYxQ3scO31zvIeZs2hGlvi/nzJjtCCgmZRyqD6RVQXQ==" }, "node_modules/windmill-parser-wasm-ruby": { "version": "1.526.1", @@ -13871,9 +13871,9 @@ "integrity": "sha512-21S7lm1KF8zO1187rbq14hzPHII2RdM2+D44MoAh1F6VoaScj+Puq0z5B1O/hwn/95R/a9jBlL2D8jbkXtlD1A==" }, "node_modules/windmill-parser-wasm-ts": { - "version": "1.565.0", - "resolved": "https://registry.npmjs.org/windmill-parser-wasm-ts/-/windmill-parser-wasm-ts-1.565.0.tgz", - "integrity": "sha512-ui7dQ2kizWSG0ELpDU70Ccfk47EjC+yLI3tf6O+BdINs+YTjxA65MjShsvE3l4MnaxN8knbOLoSHkvIYCu77mg==" + "version": "1.589.3", + "resolved": "https://registry.npmjs.org/windmill-parser-wasm-ts/-/windmill-parser-wasm-ts-1.589.3.tgz", + "integrity": "sha512-PNyzEWo3qJxlocz1qmeh4IOxm8TzCeyAqqXFO4oyz9Lu6WAyCaSfefhZfaZG01wz3J1hJTZxymB9dDiv0VxgzQ==" }, "node_modules/windmill-parser-wasm-yaml": { "version": "1.561.0", diff --git a/frontend/package.json b/frontend/package.json index 54672c3367..c60082b434 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -24,11 +24,11 @@ "@melt-ui/pp": "^0.3.2", "@melt-ui/svelte": "^0.86.2", "@playwright/test": "^1.34.3", + "@tailwindcss/forms": "^0.5.3", "@sveltejs/adapter-static": "^3.0.6", "@sveltejs/kit": "^2.28.0", "@sveltejs/package": "^2.3.7", "@sveltejs/vite-plugin-svelte": "^6.1.1", - "@tailwindcss/forms": "^0.5.3", "@tailwindcss/typography": "^0.5.8", "@types/d3": "^7.4.0", "@types/d3-zoom": "^3.0.3", @@ -146,11 +146,11 @@ "windmill-parser-wasm-java": "1.510.1", "windmill-parser-wasm-nu": "1.510.1", "windmill-parser-wasm-php": "1.574.1", - "windmill-parser-wasm-py": "1.538.0", - "windmill-parser-wasm-regex": "1.576.3", + "windmill-parser-wasm-py": "1.589.3", + "windmill-parser-wasm-regex": "1.589.3", "windmill-parser-wasm-ruby": "1.526.1", "windmill-parser-wasm-rust": "1.558.1", - "windmill-parser-wasm-ts": "1.565.0", + "windmill-parser-wasm-ts": "1.589.3", "windmill-parser-wasm-yaml": "1.561.0", "windmill-sql-datatype-parser-wasm": "1.512.0", "windmill-utils-internal": "^1.3.1", @@ -543,4 +543,4 @@ "@rollup/rollup-linux-x64-gnu": "^4.35.0", "fsevents": "^2.3.3" } -} +} \ No newline at end of file diff --git a/frontend/src/lib/components/workspaceSettings/CustomInstanceDbWizardModal.svelte b/frontend/src/lib/components/workspaceSettings/CustomInstanceDbWizardModal.svelte index 9a8a2d443f..38157fcf09 100644 --- a/frontend/src/lib/components/workspaceSettings/CustomInstanceDbWizardModal.svelte +++ b/frontend/src/lib/components/workspaceSettings/CustomInstanceDbWizardModal.svelte @@ -16,9 +16,11 @@ import type { ConfirmationModalHandle } from '../common/confirmationModal/asyncConfirmationModal.svelte' import ExploreAssetButton from '../ExploreAssetButton.svelte' import type DBManagerDrawer from '../DBManagerDrawer.svelte' - import { ArrowRight } from 'lucide-svelte' + import { ArrowRight, InfoIcon } from 'lucide-svelte' import type { Snippet } from 'svelte' import { truncate } from '$lib/utils' + import Tooltip from '../meltComponents/Tooltip.svelte' + import { superadmin } from '$lib/stores' type Props = { customInstanceDbs: ResourceReturn @@ -81,7 +83,7 @@ /> -
+
{#if status?.error}
@@ -141,6 +143,20 @@ )} />
+ {#if $superadmin} + + + {#snippet text()} + Try this if there is an issue with your custom instance database password. + {/snippet} + + {/if} + diff --git a/frontend/src/lib/components/workspaceSettings/DucklakeSettings.svelte b/frontend/src/lib/components/workspaceSettings/DucklakeSettings.svelte index f3e9816783..88bdaa877b 100644 --- a/frontend/src/lib/components/workspaceSettings/DucklakeSettings.svelte +++ b/frontend/src/lib/components/workspaceSettings/DucklakeSettings.svelte @@ -358,6 +358,7 @@