diff --git a/webapp/packages/core-blocks/src/Containers/GroupBack.tsx b/webapp/packages/core-blocks/src/Containers/GroupBack.tsx index bbf662dc7b7..c4ba98dedcd 100644 --- a/webapp/packages/core-blocks/src/Containers/GroupBack.tsx +++ b/webapp/packages/core-blocks/src/Containers/GroupBack.tsx @@ -1,6 +1,6 @@ /* * CloudBeaver - Cloud Database Manager - * Copyright (C) 2020-2024 DBeaver Corp and others + * Copyright (C) 2020-2026 DBeaver Corp and others * * Licensed under the Apache License, Version 2.0. * you may not use this file except in compliance with the License. @@ -17,7 +17,7 @@ export const GroupBack: React.FC> = func const styles = useS(classes); return ( - + {children} diff --git a/webapp/packages/core-blocks/src/Flex/Flex.module.css b/webapp/packages/core-blocks/src/Flex/Flex.module.css index cbc9739dbaf..393463f3a92 100644 --- a/webapp/packages/core-blocks/src/Flex/Flex.module.css +++ b/webapp/packages/core-blocks/src/Flex/Flex.module.css @@ -14,6 +14,10 @@ overflow: auto; } + &[data-s-gap='xxs'] { + gap: 4px; + } + &[data-s-gap='xs'] { gap: 8px; } diff --git a/webapp/packages/core-blocks/src/Flex/Flex.tsx b/webapp/packages/core-blocks/src/Flex/Flex.tsx index a307f96cd85..bd62bc9b355 100644 --- a/webapp/packages/core-blocks/src/Flex/Flex.tsx +++ b/webapp/packages/core-blocks/src/Flex/Flex.tsx @@ -1,6 +1,6 @@ /* * CloudBeaver - Cloud Database Manager - * Copyright (C) 2020-2024 DBeaver Corp and others + * Copyright (C) 2020-2026 DBeaver Corp and others * * Licensed under the Apache License, Version 2.0. * you may not use this file except in compliance with the License. @@ -12,7 +12,7 @@ import classes from './Flex.module.css'; interface Props extends React.HTMLAttributes { overflow?: boolean; - gap?: 'xs' | 'md' | 'lg'; + gap?: 'xxs' | 'xs' | 'md' | 'lg'; wrap?: React.CSSProperties['flexWrap']; direction?: React.CSSProperties['flexDirection']; align?: React.CSSProperties['alignItems']; diff --git a/webapp/packages/core-connections/src/index.ts b/webapp/packages/core-connections/src/index.ts index 537beabf846..60c42aa6f48 100644 --- a/webapp/packages/core-connections/src/index.ts +++ b/webapp/packages/core-connections/src/index.ts @@ -1,6 +1,6 @@ /* * CloudBeaver - Cloud Database Manager - * Copyright (C) 2020-2025 DBeaver Corp and others + * Copyright (C) 2020-2026 DBeaver Corp and others * * Licensed under the Apache License, Version 2.0. * you may not use this file except in compliance with the License. diff --git a/webapp/packages/core-connections/src/locales/de.ts b/webapp/packages/core-connections/src/locales/de.ts index 963de89116c..5b2c1936fb8 100644 --- a/webapp/packages/core-connections/src/locales/de.ts +++ b/webapp/packages/core-connections/src/locales/de.ts @@ -38,10 +38,6 @@ export default [ ['connections_connection_test_fail', 'Verbindungstest ist fehlgeschlagen'], ['connections_network_handler_default_user', 'Benutzer'], ['connections_network_handler_default_password', 'Passwort'], - ['connections_network_handler_ssh_tunnel_user', 'Benutzer'], - ['connections_network_handler_ssh_tunnel_password', 'Passwort'], - ['connections_network_handler_ssh_tunnel_auth_type', 'Authentifizierungsmethode'], - ['connections_network_handler_ssh_tunnel_advanced_settings', 'Erweiterte Einstellungen'], ['connections_not_found', 'Es wurden keine Datenbankverbindungen gefunden'], ['core_connections_settings_disable', 'Disable'], diff --git a/webapp/packages/core-connections/src/locales/en.ts b/webapp/packages/core-connections/src/locales/en.ts index d72526c95ab..a4b4fe4d807 100644 --- a/webapp/packages/core-connections/src/locales/en.ts +++ b/webapp/packages/core-connections/src/locales/en.ts @@ -59,15 +59,6 @@ export default [ ['connections_network_handler_default_password', 'Password'], ['connections_network_handler_ssh_tunnel_title', 'SSH Tunnel'], ['connections_network_handler_ssh_tunnel_enable', 'Use SSH Tunnel'], - ['connections_network_handler_ssh_tunnel_host', 'Host'], - ['connections_network_handler_ssh_tunnel_port', 'Port'], - ['connections_network_handler_ssh_tunnel_user', 'User'], - ['connections_network_handler_ssh_tunnel_password', 'Password'], - ['connections_network_handler_ssh_tunnel_auth_type', 'Authentication method'], - ['connections_network_handler_ssh_tunnel_private_key', 'Private Key'], - ['connections_network_handler_ssh_tunnel_advanced_settings', 'Advanced Settings'], - ['connections_network_handler_ssh_tunnel_advanced_settings_alive_interval', 'Alive interval (ms)'], - ['connections_network_handler_ssh_tunnel_advanced_settings_connect_timeout', 'Connect timeout (ms)'], ['connections_driver_search_placeholder', 'Type driver name...'], ['connections_not_found', 'No database connections were found'], diff --git a/webapp/packages/core-connections/src/locales/fr.ts b/webapp/packages/core-connections/src/locales/fr.ts index 9dca6d24285..91a8cf708f2 100644 --- a/webapp/packages/core-connections/src/locales/fr.ts +++ b/webapp/packages/core-connections/src/locales/fr.ts @@ -64,15 +64,6 @@ export default [ ['connections_network_handler_default_password', 'Mot de passe'], ['connections_network_handler_ssh_tunnel_title', 'Tunnel SSH'], ['connections_network_handler_ssh_tunnel_enable', 'Utiliser le tunnel SSH'], - ['connections_network_handler_ssh_tunnel_host', 'Hôte'], - ['connections_network_handler_ssh_tunnel_port', 'Port'], - ['connections_network_handler_ssh_tunnel_user', 'Utilisateur'], - ['connections_network_handler_ssh_tunnel_password', 'Mot de passe'], - ['connections_network_handler_ssh_tunnel_auth_type', "Méthode d'authentification"], - ['connections_network_handler_ssh_tunnel_private_key', 'Clé privée'], - ['connections_network_handler_ssh_tunnel_advanced_settings', 'Paramètres avancés'], - ['connections_network_handler_ssh_tunnel_advanced_settings_alive_interval', 'Intervalle de maintien en vie (ms)'], - ['connections_network_handler_ssh_tunnel_advanced_settings_connect_timeout', 'Délai de connexion (ms)'], ['connections_driver_search_placeholder', 'Saisir le nom du pilote...'], ['connections_not_found', 'Aucune connexion de base de données trouvée'], diff --git a/webapp/packages/core-connections/src/locales/it.ts b/webapp/packages/core-connections/src/locales/it.ts index 7f2bd972ab3..c32d583e7d2 100644 --- a/webapp/packages/core-connections/src/locales/it.ts +++ b/webapp/packages/core-connections/src/locales/it.ts @@ -57,15 +57,6 @@ export default [ ['connections_network_handler_default_password', 'Password'], ['connections_network_handler_ssh_tunnel_title', 'Tunnel SSH'], ['connections_network_handler_ssh_tunnel_enable', 'Usa il Tunnel SSH'], - ['connections_network_handler_ssh_tunnel_host', 'Host'], - ['connections_network_handler_ssh_tunnel_port', 'Porta'], - ['connections_network_handler_ssh_tunnel_user', 'Utente'], - ['connections_network_handler_ssh_tunnel_password', 'Password'], - ['connections_network_handler_ssh_tunnel_auth_type', 'Authentication method'], - ['connections_network_handler_ssh_tunnel_private_key', 'Private key'], - ['connections_network_handler_ssh_tunnel_advanced_settings', 'Advanced Settings'], - ['connections_network_handler_ssh_tunnel_advanced_settings_alive_interval', 'Alive interval (ms)'], - ['connections_network_handler_ssh_tunnel_advanced_settings_connect_timeout', 'Connect timeout (ms)'], ['connections_driver_search_placeholder', 'Digita il nome del driver...'], ['connections_not_found', 'Nessuna connessione al database trovata'], diff --git a/webapp/packages/core-connections/src/locales/ru.ts b/webapp/packages/core-connections/src/locales/ru.ts index 76b631b8f91..e37352e3284 100644 --- a/webapp/packages/core-connections/src/locales/ru.ts +++ b/webapp/packages/core-connections/src/locales/ru.ts @@ -68,15 +68,6 @@ export default [ ['connections_network_handler_default_password', 'Пароль'], ['connections_network_handler_ssh_tunnel_title', 'SSH Тунель'], ['connections_network_handler_ssh_tunnel_enable', 'Использовать SSH Тунель'], - ['connections_network_handler_ssh_tunnel_host', 'Хост'], - ['connections_network_handler_ssh_tunnel_port', 'Порт'], - ['connections_network_handler_ssh_tunnel_user', 'Пользователь'], - ['connections_network_handler_ssh_tunnel_password', 'Пароль'], - ['connections_network_handler_ssh_tunnel_auth_type', 'Метод аутентификации'], - ['connections_network_handler_ssh_tunnel_private_key', 'Приватный ключ'], - ['connections_network_handler_ssh_tunnel_advanced_settings', 'Дополнительные настройки'], - ['connections_network_handler_ssh_tunnel_advanced_settings_alive_interval', 'Интервал keep-alive (мс)'], - ['connections_network_handler_ssh_tunnel_advanced_settings_connect_timeout', 'Тайм-аут подключения (мс)'], ['connections_driver_search_placeholder', 'Введите название драйвера...'], ['connections_not_found', 'Подключения к базам данных не найдены'], diff --git a/webapp/packages/core-connections/src/locales/vi.ts b/webapp/packages/core-connections/src/locales/vi.ts index eab661ccfe9..d687e2ee9fd 100644 --- a/webapp/packages/core-connections/src/locales/vi.ts +++ b/webapp/packages/core-connections/src/locales/vi.ts @@ -74,15 +74,6 @@ export default [ ['connections_network_handler_default_password', 'Mật khẩu'], ['connections_network_handler_ssh_tunnel_title', 'Tunnel SSH'], ['connections_network_handler_ssh_tunnel_enable', 'Sử dụng Tunnel SSH'], - ['connections_network_handler_ssh_tunnel_host', 'Máy chủ'], - ['connections_network_handler_ssh_tunnel_port', 'Cổng'], - ['connections_network_handler_ssh_tunnel_user', 'Người dùng'], - ['connections_network_handler_ssh_tunnel_password', 'Mật khẩu'], - ['connections_network_handler_ssh_tunnel_auth_type', 'Phương thức xác thực'], - ['connections_network_handler_ssh_tunnel_private_key', 'Khóa riêng'], - ['connections_network_handler_ssh_tunnel_advanced_settings', 'Cài đặt nâng cao'], - ['connections_network_handler_ssh_tunnel_advanced_settings_alive_interval', 'Khoảng thời gian giữ kết nối (ms)'], - ['connections_network_handler_ssh_tunnel_advanced_settings_connect_timeout', 'Thời gian chờ kết nối (ms)'], ['connections_driver_search_placeholder', 'Nhập tên trình điều khiển (driver)...'], ['connections_not_found', 'Không tìm thấy kết nối cơ sở dữ liệu'], [ diff --git a/webapp/packages/core-connections/src/locales/zh.ts b/webapp/packages/core-connections/src/locales/zh.ts index f009d1d1780..ea17a34fdb2 100644 --- a/webapp/packages/core-connections/src/locales/zh.ts +++ b/webapp/packages/core-connections/src/locales/zh.ts @@ -51,15 +51,6 @@ export default [ ['connections_network_handler_default_password', '密码'], ['connections_network_handler_ssh_tunnel_title', 'SSH隧道'], ['connections_network_handler_ssh_tunnel_enable', '使用SSH隧道'], - ['connections_network_handler_ssh_tunnel_host', '主机'], - ['connections_network_handler_ssh_tunnel_port', '端口'], - ['connections_network_handler_ssh_tunnel_user', '用户'], - ['connections_network_handler_ssh_tunnel_password', '密码'], - ['connections_network_handler_ssh_tunnel_auth_type', '认证方式'], - ['connections_network_handler_ssh_tunnel_private_key', '私钥'], - ['connections_network_handler_ssh_tunnel_advanced_settings', '高级设置'], - ['connections_network_handler_ssh_tunnel_advanced_settings_alive_interval', '活动间隔 (ms)'], - ['connections_network_handler_ssh_tunnel_advanced_settings_connect_timeout', '连接超时 (ms)'], ['connections_driver_search_placeholder', '输入驱动名称...'], ['connections_not_found', '未找到数据库连接'], diff --git a/webapp/packages/plugin-connection-network-handlers/package.json b/webapp/packages/plugin-connection-network-handlers/package.json new file mode 100644 index 00000000000..981850ad814 --- /dev/null +++ b/webapp/packages/plugin-connection-network-handlers/package.json @@ -0,0 +1,47 @@ +{ + "name": "@cloudbeaver/plugin-connection-network-handlers", + "type": "module", + "sideEffects": [ + "./lib/module.js", + "./lib/index.js", + "src/**/*.css", + "public/**/*" + ], + "version": "0.1.0", + "description": "", + "license": "Apache-2.0", + "exports": { + ".": "./lib/index.js", + "./module": "./lib/module.js" + }, + "scripts": { + "build": "tsc -b", + "clean": "rimraf --glob lib", + "lint": "eslint ./src/ --ext .ts,.tsx", + "test": "dbeaver-test", + "validate-dependencies": "core-cli-validate-dependencies" + }, + "dependencies": { + "@cloudbeaver/core-blocks": "workspace:*", + "@cloudbeaver/core-connections": "workspace:*", + "@cloudbeaver/core-di": "workspace:*", + "@cloudbeaver/core-localization": "workspace:*", + "@cloudbeaver/core-projects": "workspace:*", + "@cloudbeaver/core-root": "workspace:*", + "@cloudbeaver/core-sdk": "workspace:*", + "@cloudbeaver/core-utils": "workspace:*", + "mobx": "^6", + "mobx-react-lite": "^4", + "react": "^19", + "react-dom": "^19" + }, + "devDependencies": { + "@cloudbeaver/core-cli": "workspace:*", + "@cloudbeaver/tsconfig": "workspace:*", + "@dbeaver/cli": "workspace:*", + "@types/react": "^19", + "rimraf": "^6", + "tslib": "^2", + "typescript": "^5" + } +} diff --git a/webapp/packages/plugin-connection-network-handlers/src/LocaleService.ts b/webapp/packages/plugin-connection-network-handlers/src/LocaleService.ts new file mode 100644 index 00000000000..888ca001032 --- /dev/null +++ b/webapp/packages/plugin-connection-network-handlers/src/LocaleService.ts @@ -0,0 +1,39 @@ +/* + * CloudBeaver - Cloud Database Manager + * Copyright (C) 2020-2026 DBeaver Corp and others + * + * Licensed under the Apache License, Version 2.0. + * you may not use this file except in compliance with the License. + */ +import { Bootstrap, injectable } from '@cloudbeaver/core-di'; +import { LocalizationService } from '@cloudbeaver/core-localization'; + +@injectable(() => [LocalizationService]) +export class LocaleService extends Bootstrap { + constructor(private readonly localizationService: LocalizationService) { + super(); + } + + override register(): void { + this.localizationService.addProvider(this.provider.bind(this)); + } + + private async provider(locale: string) { + switch (locale) { + case 'ru': + return (await import('./locales/ru.js')).default; + case 'de': + return (await import('./locales/de.js')).default; + case 'it': + return (await import('./locales/it.js')).default; + case 'zh': + return (await import('./locales/zh.js')).default; + case 'fr': + return (await import('./locales/fr.js')).default; + case 'vi': + return (await import('./locales/vi.js')).default; + default: + return (await import('./locales/en.js')).default; + } + } +} diff --git a/webapp/packages/plugin-connection-network-handlers/src/SSH/SSHForm.tsx b/webapp/packages/plugin-connection-network-handlers/src/SSH/SSHForm.tsx new file mode 100644 index 00000000000..c1356971fa4 --- /dev/null +++ b/webapp/packages/plugin-connection-network-handlers/src/SSH/SSHForm.tsx @@ -0,0 +1,170 @@ +/* + * CloudBeaver - Cloud Database Manager + * Copyright (C) 2020-2026 DBeaver Corp and others + * + * Licensed under the Apache License, Version 2.0. + * you may not use this file except in compliance with the License. + */ +import { observer } from 'mobx-react-lite'; +import { useCallback } from 'react'; + +import { + Container, + Expandable, + FieldCheckbox, + InputField, + Select, + Switch, + useAdministrationSettings, + useResource, + useTranslate, +} from '@cloudbeaver/core-blocks'; +import { NetworkHandlerAuthType, type NetworkHandlerConfigInput } from '@cloudbeaver/core-sdk'; + +import { sshAuthTypes } from './sshAuthTypes.js'; +import { SSHKeyUploader } from './SSHKeyUploader.js'; +import { SSH_TUNNEL_ID } from '@cloudbeaver/core-connections'; +import { useService } from '@cloudbeaver/core-di'; +import { ProjectInfoResource } from '@cloudbeaver/core-projects'; +import { ServerConfigResource } from '@cloudbeaver/core-root'; + +export interface ISSHCredentialsSavingConfig { + enabled: boolean; + isSharedProject: boolean; + isDistributed: boolean; + checkboxId?: string; +} + +export interface ISSHFormProps { + state: NetworkHandlerConfigInput; + initialState?: NetworkHandlerConfigInput | null; + disabled?: boolean; + readonly?: boolean; + sharedCredentials?: boolean; + projectId: string; +} + +export const SSHForm = observer(function SSHForm({ state, initialState, disabled, readonly, sharedCredentials = false, projectId }) { + const translate = useTranslate(); + + const enabled = state.enabled; + const disabledInternal = disabled || readonly || enabled === false; + const keyAuth = state.authType === NetworkHandlerAuthType.PublicKey; + const serverConfigResource = useResource(SSHForm, ServerConfigResource, undefined); + + const passwordLabel = keyAuth ? 'Passphrase' : translate('plugin_connection_network_handlers_ssh_tunnel_password'); + const passwordSaved = initialState?.password === '' && initialState?.authType === state.authType; + const keySaved = initialState?.key === ''; + + const aliveIntervalLabel = translate('plugin_connection_network_handlers_ssh_tunnel_advanced_settings_alive_interval'); + const connectTimeoutLabel = translate('plugin_connection_network_handlers_ssh_tunnel_advanced_settings_connect_timeout'); + const { credentialsSavingEnabled } = useAdministrationSettings(); + const projectInfoResource = useService(ProjectInfoResource); + const isSharedProject = projectInfoResource.isProjectShared(projectId); + const showSaveCredentials = credentialsSavingEnabled && !sharedCredentials; + + const handleAuthTypeChange = useCallback(() => { + state.password = ''; + }, [state]); + + return ( + <> + + {translate('connections_network_handler_ssh_tunnel_enable')} + + + + + {translate('plugin_connection_network_handlers_ssh_tunnel_host')} + + + {translate('plugin_connection_network_handlers_ssh_tunnel_port')} + + + + + {translate('plugin_connection_network_handlers_ssh_tunnel_user')} + + + {passwordLabel} + + {keyAuth && } + + {showSaveCredentials && ( + + {translate( + !isSharedProject || serverConfigResource.data?.distributed + ? 'plugin_connection_network_handlers_save_credentials_for_user' + : 'plugin_connection_network_handlers_save_credentials_shared', + )} + + )} + + + + + {aliveIntervalLabel} + + + {connectTimeoutLabel} + + + + + + ); +}); diff --git a/webapp/packages/plugin-connections/src/ConnectionForm/SSH/SSHKeyUploader.tsx b/webapp/packages/plugin-connection-network-handlers/src/SSH/SSHKeyUploader.tsx similarity index 95% rename from webapp/packages/plugin-connections/src/ConnectionForm/SSH/SSHKeyUploader.tsx rename to webapp/packages/plugin-connection-network-handlers/src/SSH/SSHKeyUploader.tsx index c84af42db1a..9cb7d6f5adb 100644 --- a/webapp/packages/plugin-connections/src/ConnectionForm/SSH/SSHKeyUploader.tsx +++ b/webapp/packages/plugin-connection-network-handlers/src/SSH/SSHKeyUploader.tsx @@ -48,7 +48,7 @@ export const SSHKeyUploader = observer(function SSHKeyUploader({ state, s required={state.savePassword && !saved} medium > - {translate('connections_network_handler_ssh_tunnel_private_key')} + {translate('plugin_connection_network_handlers_ssh_tunnel_private_key')} diff --git a/webapp/packages/plugin-connection-network-handlers/src/SSH/getNetworkHandlerDefaultProperties.ts b/webapp/packages/plugin-connection-network-handlers/src/SSH/getNetworkHandlerDefaultProperties.ts new file mode 100644 index 00000000000..a5e74b7907b --- /dev/null +++ b/webapp/packages/plugin-connection-network-handlers/src/SSH/getNetworkHandlerDefaultProperties.ts @@ -0,0 +1,18 @@ +/* + * CloudBeaver - Cloud Database Manager + * Copyright (C) 2020-2026 DBeaver Corp and others + * + * Licensed under the Apache License, Version 2.0. + * you may not use this file except in compliance with the License. + */ +import type { NetworkHandlerDescriptor } from '@cloudbeaver/core-sdk'; + +export function getNetworkHandlerDefaultProperties(handler: NetworkHandlerDescriptor): Record { + const properties: Record = {}; + for (const property of handler.properties) { + if (!property.features.includes('password')) { + properties[property.id!] = property.value; + } + } + return properties; +} diff --git a/webapp/packages/plugin-connections/src/ConnectionForm/SSH/authTypes.ts b/webapp/packages/plugin-connection-network-handlers/src/SSH/sshAuthTypes.ts similarity index 85% rename from webapp/packages/plugin-connections/src/ConnectionForm/SSH/authTypes.ts rename to webapp/packages/plugin-connection-network-handlers/src/SSH/sshAuthTypes.ts index e6e65fc63f7..d72d3b73458 100644 --- a/webapp/packages/plugin-connections/src/ConnectionForm/SSH/authTypes.ts +++ b/webapp/packages/plugin-connection-network-handlers/src/SSH/sshAuthTypes.ts @@ -1,6 +1,6 @@ /* * CloudBeaver - Cloud Database Manager - * Copyright (C) 2020-2024 DBeaver Corp and others + * Copyright (C) 2020-2026 DBeaver Corp and others * * Licensed under the Apache License, Version 2.0. * you may not use this file except in compliance with the License. @@ -13,7 +13,7 @@ interface IAuthType { label: TLocalizationToken; } -export const authTypes: IAuthType[] = [ +export const sshAuthTypes: IAuthType[] = [ { key: NetworkHandlerAuthType.Password, label: 'Password', diff --git a/webapp/packages/plugin-connection-network-handlers/src/SSH/sshHelpers.ts b/webapp/packages/plugin-connection-network-handlers/src/SSH/sshHelpers.ts new file mode 100644 index 00000000000..68a75078ae6 --- /dev/null +++ b/webapp/packages/plugin-connection-network-handlers/src/SSH/sshHelpers.ts @@ -0,0 +1,83 @@ +/* + * CloudBeaver - Cloud Database Manager + * Copyright (C) 2020-2026 DBeaver Corp and others + * + * Licensed under the Apache License, Version 2.0. + * you may not use this file except in compliance with the License. + */ +import { SSH_TUNNEL_ID } from '@cloudbeaver/core-connections'; +import { NetworkHandlerAuthType, type NetworkHandlerConfigInput } from '@cloudbeaver/core-sdk'; +import { toJS } from 'mobx'; + +export const SSH_DEFAULT_HANDLER_CONFIG: () => NetworkHandlerConfigInput = () => ({ + id: SSH_TUNNEL_ID, + enabled: false, + authType: NetworkHandlerAuthType.Password, + password: undefined, + savePassword: false, + userName: '', + key: undefined, + properties: { + port: 22, + host: '', + aliveInterval: '0', + sshConnectTimeout: '10000', + }, +}); + +export function isSSHPasswordChanged(handler: NetworkHandlerConfigInput, initial?: NetworkHandlerConfigInput | null): boolean { + if (!initial && !handler.enabled) { + return false; + } + + return ( + (((initial?.password === null && handler.password !== null) || initial?.password === '') && handler.password !== '') || !!handler.password?.length + ); +} + +export function isSSHKeyChanged(handler: NetworkHandlerConfigInput, initial?: NetworkHandlerConfigInput | null): boolean { + if (!initial && !handler.enabled) { + return false; + } + + return (((initial?.key === null && handler.key !== null) || initial?.key === '') && handler.key !== '') || !!handler.key?.length; +} + +export function getSSHHandlerConfig( + state: NetworkHandlerConfigInput, + initialState?: NetworkHandlerConfigInput | null, + savePassword?: boolean, +): NetworkHandlerConfigInput { + const passwordChanged = isSSHPasswordChanged(state, initialState); + const keyChanged = isSSHKeyChanged(state, initialState); + + const handlerConfig: NetworkHandlerConfigInput = { + ...state, + savePassword: (state.savePassword ?? false) || (savePassword ?? false), + key: state.authType === NetworkHandlerAuthType.PublicKey && keyChanged ? state.key : undefined, + password: passwordChanged ? state.password : undefined, + }; + + delete handlerConfig.secureProperties; + + return trimSSHConfig(handlerConfig); +} + +function trimSSHConfig(input: NetworkHandlerConfigInput): NetworkHandlerConfigInput { + const trimmedInput = toJS(input); + const attributesToTrim = Object.keys(input) as (keyof NetworkHandlerConfigInput)[]; + + for (const key of attributesToTrim) { + if (typeof trimmedInput[key] === 'string') { + trimmedInput[key] = trimmedInput[key]?.trim(); + } + } + + for (const key in trimmedInput.properties) { + if (typeof trimmedInput.properties[key] === 'string') { + trimmedInput.properties[key] = trimmedInput.properties[key]?.trim(); + } + } + + return trimmedInput; +} diff --git a/webapp/packages/plugin-connection-network-handlers/src/SSH/validateSSHConfig.ts b/webapp/packages/plugin-connection-network-handlers/src/SSH/validateSSHConfig.ts new file mode 100644 index 00000000000..4a94363ba37 --- /dev/null +++ b/webapp/packages/plugin-connection-network-handlers/src/SSH/validateSSHConfig.ts @@ -0,0 +1,40 @@ +/* + * CloudBeaver - Cloud Database Manager + * Copyright (C) 2020-2026 DBeaver Corp and others + * + * Licensed under the Apache License, Version 2.0. + * you may not use this file except in compliance with the License. + */ +import { NetworkHandlerAuthType, type NetworkHandlerConfigInput } from '@cloudbeaver/core-sdk'; + +export function validateSSHConfig(state: NetworkHandlerConfigInput, initialState?: NetworkHandlerConfigInput | null): string[] { + const errors: string[] = []; + + if (!state.properties?.['host']?.trim().length) { + errors.push("Field SSH 'Host' can't be empty"); + } + + const port = Number(String(state.properties?.['port'] ?? '').trim()); + if (isNaN(port) || port < 1) { + errors.push("Field SSH 'Port' must be a positive number"); + } + + if (state.savePassword && !state.userName?.trim()?.length) { + errors.push("Field SSH 'User' can't be empty"); + } + + const keyAuth = state.authType === NetworkHandlerAuthType.PublicKey; + const keySaved = initialState?.key === ''; + + if (keyAuth && state.savePassword && !keySaved && !state.key?.length) { + errors.push("Field SSH 'Private key' can't be empty"); + } + + const passwordSaved = initialState?.password === '' && initialState?.authType === state.authType; + + if (!keyAuth && state.savePassword && !passwordSaved && !state.password?.length) { + errors.push("Field SSH 'Password' can't be empty"); + } + + return errors; +} diff --git a/webapp/packages/plugin-connection-network-handlers/src/index.ts b/webapp/packages/plugin-connection-network-handlers/src/index.ts new file mode 100644 index 00000000000..798b21e1025 --- /dev/null +++ b/webapp/packages/plugin-connection-network-handlers/src/index.ts @@ -0,0 +1,16 @@ +/* + * CloudBeaver - Cloud Database Manager + * Copyright (C) 2020-2026 DBeaver Corp and others + * + * Licensed under the Apache License, Version 2.0. + * you may not use this file except in compliance with the License. + */ + +import './module.js'; + +export * from './SSH/SSHForm.js'; +export * from './SSH/SSHKeyUploader.js'; +export * from './SSH/sshAuthTypes.js'; +export * from './SSH/validateSSHConfig.js'; +export * from './SSH/getNetworkHandlerDefaultProperties.js'; +export * from './SSH/sshHelpers.js'; diff --git a/webapp/packages/plugin-connection-network-handlers/src/locales/de.ts b/webapp/packages/plugin-connection-network-handlers/src/locales/de.ts new file mode 100644 index 00000000000..18eec516eb2 --- /dev/null +++ b/webapp/packages/plugin-connection-network-handlers/src/locales/de.ts @@ -0,0 +1,23 @@ +/* + * CloudBeaver - Cloud Database Manager + * Copyright (C) 2020-2026 DBeaver Corp and others + * + * Licensed under the Apache License, Version 2.0. + * you may not use this file except in compliance with the License. + */ + +export default [ + ['plugin_connection_network_handlers_ssh_tunnel_auth_type', 'Authentifizierungsmethode'], + ['plugin_connection_network_handlers_ssh_tunnel_host', 'Host'], + ['plugin_connection_network_handlers_ssh_tunnel_port', 'Port'], + ['plugin_connection_network_handlers_ssh_tunnel_user', 'Benutzer'], + ['plugin_connection_network_handlers_ssh_tunnel_password', 'Passwort'], + ['plugin_connection_network_handlers_ssh_tunnel_private_key', 'Privater Schlüssel'], + ['plugin_connection_network_handlers_ssh_tunnel_advanced_settings', 'Erweiterte Einstellungen'], + ['plugin_connection_network_handlers_ssh_tunnel_advanced_settings_alive_interval', 'Keep-alive-Intervall (ms)'], + ['plugin_connection_network_handlers_ssh_tunnel_advanced_settings_connect_timeout', 'Verbindungs-Timeout (ms)'], + ['plugin_connection_network_handlers_save_credentials_for_user', 'Zugangsdaten für den aktuellen Benutzer speichern'], + ['plugin_connection_network_handlers_save_credentials_for_user_tooltip', 'Diese Zugangsdaten werden für die automatische Verbindung verwendet'], + ['plugin_connection_network_handlers_save_credentials_shared', 'Zugangsdaten für alle Benutzer mit Zugriff speichern'], + ['plugin_connection_network_handlers_save_credentials_shared_tooltip', 'Diese Zugangsdaten werden für die automatische Verbindung für alle Benutzer mit Zugriff verwendet'], +]; diff --git a/webapp/packages/plugin-connection-network-handlers/src/locales/en.ts b/webapp/packages/plugin-connection-network-handlers/src/locales/en.ts new file mode 100644 index 00000000000..e2a396562ec --- /dev/null +++ b/webapp/packages/plugin-connection-network-handlers/src/locales/en.ts @@ -0,0 +1,26 @@ +/* + * CloudBeaver - Cloud Database Manager + * Copyright (C) 2020-2026 DBeaver Corp and others + * + * Licensed under the Apache License, Version 2.0. + * you may not use this file except in compliance with the License. + */ + +export default [ + ['plugin_connection_network_handlers_ssh_tunnel_auth_type', 'Authentication method'], + ['plugin_connection_network_handlers_ssh_tunnel_host', 'Host'], + ['plugin_connection_network_handlers_ssh_tunnel_port', 'Port'], + ['plugin_connection_network_handlers_ssh_tunnel_user', 'User'], + ['plugin_connection_network_handlers_ssh_tunnel_password', 'Password'], + ['plugin_connection_network_handlers_ssh_tunnel_private_key', 'Private Key'], + ['plugin_connection_network_handlers_ssh_tunnel_advanced_settings', 'Advanced Settings'], + ['plugin_connection_network_handlers_ssh_tunnel_advanced_settings_alive_interval', 'Alive interval (ms)'], + ['plugin_connection_network_handlers_ssh_tunnel_advanced_settings_connect_timeout', 'Connect timeout (ms)'], + ['plugin_connection_network_handlers_save_credentials_for_user', 'Save credentials for the current user'], + ['plugin_connection_network_handlers_save_credentials_for_user_tooltip', 'These credentials will be used to make automatic connection'], + ['plugin_connection_network_handlers_save_credentials_shared', 'Save credentials for all users with access'], + [ + 'plugin_connection_network_handlers_save_credentials_shared_tooltip', + 'These credentials will be used to make automatic connection for all users having access', + ], +]; diff --git a/webapp/packages/plugin-connection-network-handlers/src/locales/fr.ts b/webapp/packages/plugin-connection-network-handlers/src/locales/fr.ts new file mode 100644 index 00000000000..1063fdd03d9 --- /dev/null +++ b/webapp/packages/plugin-connection-network-handlers/src/locales/fr.ts @@ -0,0 +1,23 @@ +/* + * CloudBeaver - Cloud Database Manager + * Copyright (C) 2020-2026 DBeaver Corp and others + * + * Licensed under the Apache License, Version 2.0. + * you may not use this file except in compliance with the License. + */ + +export default [ + ['plugin_connection_network_handlers_ssh_tunnel_auth_type', "Méthode d'authentification"], + ['plugin_connection_network_handlers_ssh_tunnel_host', 'Hôte'], + ['plugin_connection_network_handlers_ssh_tunnel_port', 'Port'], + ['plugin_connection_network_handlers_ssh_tunnel_user', 'Utilisateur'], + ['plugin_connection_network_handlers_ssh_tunnel_password', 'Mot de passe'], + ['plugin_connection_network_handlers_ssh_tunnel_private_key', 'Clé privée'], + ['plugin_connection_network_handlers_ssh_tunnel_advanced_settings', 'Paramètres avancés'], + ['plugin_connection_network_handlers_ssh_tunnel_advanced_settings_alive_interval', 'Intervalle de maintien en vie (ms)'], + ['plugin_connection_network_handlers_ssh_tunnel_advanced_settings_connect_timeout', 'Délai de connexion (ms)'], + ['plugin_connection_network_handlers_save_credentials_for_user', 'Enregistrer les identifiants pour l\'utilisateur actuel'], + ['plugin_connection_network_handlers_save_credentials_for_user_tooltip', 'Ces identifiants seront utilisés pour établir une connexion automatique'], + ['plugin_connection_network_handlers_save_credentials_shared', 'Enregistrer les identifiants pour tous les utilisateurs ayant accès'], + ['plugin_connection_network_handlers_save_credentials_shared_tooltip', 'Ces identifiants seront utilisés pour établir une connexion automatique pour tous les utilisateurs ayant accès'], +]; diff --git a/webapp/packages/plugin-connection-network-handlers/src/locales/it.ts b/webapp/packages/plugin-connection-network-handlers/src/locales/it.ts new file mode 100644 index 00000000000..231f8f0e1f2 --- /dev/null +++ b/webapp/packages/plugin-connection-network-handlers/src/locales/it.ts @@ -0,0 +1,23 @@ +/* + * CloudBeaver - Cloud Database Manager + * Copyright (C) 2020-2026 DBeaver Corp and others + * + * Licensed under the Apache License, Version 2.0. + * you may not use this file except in compliance with the License. + */ + +export default [ + ['plugin_connection_network_handlers_ssh_tunnel_auth_type', 'Metodo di autenticazione'], + ['plugin_connection_network_handlers_ssh_tunnel_host', 'Host'], + ['plugin_connection_network_handlers_ssh_tunnel_port', 'Porta'], + ['plugin_connection_network_handlers_ssh_tunnel_user', 'Utente'], + ['plugin_connection_network_handlers_ssh_tunnel_password', 'Password'], + ['plugin_connection_network_handlers_ssh_tunnel_private_key', 'Chiave privata'], + ['plugin_connection_network_handlers_ssh_tunnel_advanced_settings', 'Impostazioni avanzate'], + ['plugin_connection_network_handlers_ssh_tunnel_advanced_settings_alive_interval', 'Intervallo keep-alive (ms)'], + ['plugin_connection_network_handlers_ssh_tunnel_advanced_settings_connect_timeout', 'Timeout connessione (ms)'], + ['plugin_connection_network_handlers_save_credentials_for_user', 'Salva le credenziali per l\'utente corrente'], + ['plugin_connection_network_handlers_save_credentials_for_user_tooltip', 'Queste credenziali verranno utilizzate per la connessione automatica'], + ['plugin_connection_network_handlers_save_credentials_shared', 'Salva le credenziali per tutti gli utenti con accesso'], + ['plugin_connection_network_handlers_save_credentials_shared_tooltip', 'Queste credenziali verranno utilizzate per la connessione automatica per tutti gli utenti con accesso'], +]; diff --git a/webapp/packages/plugin-connection-network-handlers/src/locales/ru.ts b/webapp/packages/plugin-connection-network-handlers/src/locales/ru.ts new file mode 100644 index 00000000000..cd265fadd51 --- /dev/null +++ b/webapp/packages/plugin-connection-network-handlers/src/locales/ru.ts @@ -0,0 +1,23 @@ +/* + * CloudBeaver - Cloud Database Manager + * Copyright (C) 2020-2026 DBeaver Corp and others + * + * Licensed under the Apache License, Version 2.0. + * you may not use this file except in compliance with the License. + */ + +export default [ + ['plugin_connection_network_handlers_ssh_tunnel_auth_type', 'Метод аутентификации'], + ['plugin_connection_network_handlers_ssh_tunnel_host', 'Хост'], + ['plugin_connection_network_handlers_ssh_tunnel_port', 'Порт'], + ['plugin_connection_network_handlers_ssh_tunnel_user', 'Пользователь'], + ['plugin_connection_network_handlers_ssh_tunnel_password', 'Пароль'], + ['plugin_connection_network_handlers_ssh_tunnel_private_key', 'Приватный ключ'], + ['plugin_connection_network_handlers_ssh_tunnel_advanced_settings', 'Дополнительные настройки'], + ['plugin_connection_network_handlers_ssh_tunnel_advanced_settings_alive_interval', 'Интервал keep-alive (мс)'], + ['plugin_connection_network_handlers_ssh_tunnel_advanced_settings_connect_timeout', 'Тайм-аут подключения (мс)'], + ['plugin_connection_network_handlers_save_credentials_for_user', 'Сохранить данные для текущего пользователя'], + ['plugin_connection_network_handlers_save_credentials_for_user_tooltip', 'Эти учетные данные будут использоваться для автоматического подключения'], + ['plugin_connection_network_handlers_save_credentials_shared', 'Запомнить данные для всех пользователей с доступом'], + ['plugin_connection_network_handlers_save_credentials_shared_tooltip', 'Эти учетные данные будут использоваться для автоматического подключения для всех пользователей с доступом'], +]; diff --git a/webapp/packages/plugin-connection-network-handlers/src/locales/vi.ts b/webapp/packages/plugin-connection-network-handlers/src/locales/vi.ts new file mode 100644 index 00000000000..50ff52cb5ce --- /dev/null +++ b/webapp/packages/plugin-connection-network-handlers/src/locales/vi.ts @@ -0,0 +1,23 @@ +/* + * CloudBeaver - Cloud Database Manager + * Copyright (C) 2020-2026 DBeaver Corp and others + * + * Licensed under the Apache License, Version 2.0. + * you may not use this file except in compliance with the License. + */ + +export default [ + ['plugin_connection_network_handlers_ssh_tunnel_auth_type', 'Phương thức xác thực'], + ['plugin_connection_network_handlers_ssh_tunnel_host', 'Máy chủ'], + ['plugin_connection_network_handlers_ssh_tunnel_port', 'Cổng'], + ['plugin_connection_network_handlers_ssh_tunnel_user', 'Người dùng'], + ['plugin_connection_network_handlers_ssh_tunnel_password', 'Mật khẩu'], + ['plugin_connection_network_handlers_ssh_tunnel_private_key', 'Khóa riêng'], + ['plugin_connection_network_handlers_ssh_tunnel_advanced_settings', 'Cài đặt nâng cao'], + ['plugin_connection_network_handlers_ssh_tunnel_advanced_settings_alive_interval', 'Khoảng thời gian giữ kết nối (ms)'], + ['plugin_connection_network_handlers_ssh_tunnel_advanced_settings_connect_timeout', 'Thời gian chờ kết nối (ms)'], + ['plugin_connection_network_handlers_save_credentials_for_user', 'Lưu thông tin xác thực cho người dùng hiện tại'], + ['plugin_connection_network_handlers_save_credentials_for_user_tooltip', 'Thông tin xác thực này sẽ được sử dụng để kết nối tự động'], + ['plugin_connection_network_handlers_save_credentials_shared', 'Lưu thông tin xác thực cho tất cả người dùng có quyền truy cập'], + ['plugin_connection_network_handlers_save_credentials_shared_tooltip', 'Thông tin xác thực này sẽ được sử dụng để kết nối tự động cho tất cả người dùng có quyền truy cập'], +]; diff --git a/webapp/packages/plugin-connection-network-handlers/src/locales/zh.ts b/webapp/packages/plugin-connection-network-handlers/src/locales/zh.ts new file mode 100644 index 00000000000..cfa7d2687b7 --- /dev/null +++ b/webapp/packages/plugin-connection-network-handlers/src/locales/zh.ts @@ -0,0 +1,23 @@ +/* + * CloudBeaver - Cloud Database Manager + * Copyright (C) 2020-2026 DBeaver Corp and others + * + * Licensed under the Apache License, Version 2.0. + * you may not use this file except in compliance with the License. + */ + +export default [ + ['plugin_connection_network_handlers_ssh_tunnel_auth_type', '认证方式'], + ['plugin_connection_network_handlers_ssh_tunnel_host', '主机'], + ['plugin_connection_network_handlers_ssh_tunnel_port', '端口'], + ['plugin_connection_network_handlers_ssh_tunnel_user', '用户'], + ['plugin_connection_network_handlers_ssh_tunnel_password', '密码'], + ['plugin_connection_network_handlers_ssh_tunnel_private_key', '私钥'], + ['plugin_connection_network_handlers_ssh_tunnel_advanced_settings', '高级设置'], + ['plugin_connection_network_handlers_ssh_tunnel_advanced_settings_alive_interval', '活动间隔 (ms)'], + ['plugin_connection_network_handlers_ssh_tunnel_advanced_settings_connect_timeout', '连接超时 (ms)'], + ['plugin_connection_network_handlers_save_credentials_for_user', '为当前用户保存凭证'], + ['plugin_connection_network_handlers_save_credentials_for_user_tooltip', '凭证将用于自动连接数据库'], + ['plugin_connection_network_handlers_save_credentials_shared', '为所有访问用户保存凭证'], + ['plugin_connection_network_handlers_save_credentials_shared_tooltip', '凭证将用于为所有访问用户自动连接数据库'], +]; diff --git a/webapp/packages/plugin-connection-network-handlers/src/module.ts b/webapp/packages/plugin-connection-network-handlers/src/module.ts new file mode 100644 index 00000000000..82609520238 --- /dev/null +++ b/webapp/packages/plugin-connection-network-handlers/src/module.ts @@ -0,0 +1,18 @@ +/* + * CloudBeaver - Cloud Database Manager + * Copyright (C) 2020-2026 DBeaver Corp and others + * + * Licensed under the Apache License, Version 2.0. + * you may not use this file except in compliance with the License. + */ + +import { Bootstrap, ModuleRegistry } from '@cloudbeaver/core-di'; +import { LocaleService } from './LocaleService.js'; + +export default ModuleRegistry.add({ + name: '@cloudbeaver/plugin-connection-network-handlers', + + configure: serviceCollection => { + serviceCollection.addSingleton(Bootstrap, LocaleService); + }, +}); diff --git a/webapp/packages/plugin-connection-network-handlers/tsconfig.json b/webapp/packages/plugin-connection-network-handlers/tsconfig.json new file mode 100644 index 00000000000..7d4ce6fe971 --- /dev/null +++ b/webapp/packages/plugin-connection-network-handlers/tsconfig.json @@ -0,0 +1,54 @@ +{ + "extends": "@cloudbeaver/tsconfig/tsconfig.json", + "compilerOptions": { + "rootDir": "src", + "outDir": "lib", + "tsBuildInfoFile": "lib/tsconfig.tsbuildinfo", + "composite": true + }, + "references": [ + { + "path": "../../common-typescript/@dbeaver/cli" + }, + { + "path": "../core-blocks" + }, + { + "path": "../core-cli" + }, + { + "path": "../core-connections" + }, + { + "path": "../core-di" + }, + { + "path": "../core-di/tsconfig.json" + }, + { + "path": "../core-localization" + }, + { + "path": "../core-projects" + }, + { + "path": "../core-root" + }, + { + "path": "../core-sdk" + }, + { + "path": "../core-utils" + } + ], + "include": [ + "__custom_mocks__/**/*", + "src/**/*", + "src/**/*.json", + "src/**/*.css" + ], + "exclude": [ + "**/node_modules", + "lib/**/*" + ] +} diff --git a/webapp/packages/plugin-connections/package.json b/webapp/packages/plugin-connections/package.json index c86ef66330c..f6ed1326d96 100644 --- a/webapp/packages/plugin-connections/package.json +++ b/webapp/packages/plugin-connections/package.json @@ -42,6 +42,7 @@ "@cloudbeaver/core-utils": "workspace:*", "@cloudbeaver/core-view": "workspace:*", "@cloudbeaver/plugin-authentication": "workspace:*", + "@cloudbeaver/plugin-connection-network-handlers": "workspace:*", "@cloudbeaver/plugin-navigation-tree": "workspace:*", "@cloudbeaver/plugin-projects": "workspace:*", "@cloudbeaver/plugin-top-app-bar": "workspace:*", diff --git a/webapp/packages/plugin-connections/src/ConnectionAuthentication/NetworkHandlerAuthForm.tsx b/webapp/packages/plugin-connections/src/ConnectionAuthentication/NetworkHandlerAuthForm.tsx index 854b976c599..be7f1924e84 100644 --- a/webapp/packages/plugin-connections/src/ConnectionAuthentication/NetworkHandlerAuthForm.tsx +++ b/webapp/packages/plugin-connections/src/ConnectionAuthentication/NetworkHandlerAuthForm.tsx @@ -14,7 +14,7 @@ import { ProjectInfoResource } from '@cloudbeaver/core-projects'; import { ServerConfigResource } from '@cloudbeaver/core-root'; import { NetworkHandlerAuthType, type NetworkHandlerConfigInput } from '@cloudbeaver/core-sdk'; -import { SSHKeyUploader } from '../ConnectionForm/SSH/SSHKeyUploader.js'; +import { SSHKeyUploader } from '@cloudbeaver/plugin-connection-network-handlers'; import { PROPERTY_FEATURE_SECURED } from '../ConnectionForm/SSL/PROPERTY_FEATURE_SECURED.js'; interface Props { diff --git a/webapp/packages/plugin-connections/src/ConnectionForm/SSH/ConnectionFormSSHPart.ts b/webapp/packages/plugin-connections/src/ConnectionForm/SSH/ConnectionFormSSHPart.ts index 324f3106864..d0204900bb6 100644 --- a/webapp/packages/plugin-connections/src/ConnectionForm/SSH/ConnectionFormSSHPart.ts +++ b/webapp/packages/plugin-connections/src/ConnectionForm/SSH/ConnectionFormSSHPart.ts @@ -10,7 +10,6 @@ import { FormPart, formValidationContext, type IFormState } from '@cloudbeaver/c import type { IExecutionContextProvider } from '@cloudbeaver/core-executor'; import { DriverConfigurationType, - NetworkHandlerAuthType, type NetworkHandlerConfigInput, type NetworkHandlerDescriptor, } from '@cloudbeaver/core-sdk'; @@ -19,25 +18,9 @@ import { toJS } from 'mobx'; import type { IConnectionFormState } from '../IConnectionFormState.js'; import type { INetworkHandlerConfig } from '../Options/IConnectionNetworkHanler.js'; import { ConnectionFormOptionsPart } from '../Options/ConnectionFormOptionsPart.js'; +import { getNetworkHandlerDefaultProperties, getSSHHandlerConfig, SSH_DEFAULT_HANDLER_CONFIG, validateSSHConfig } from '@cloudbeaver/plugin-connection-network-handlers'; -const getDefaultState = () => - ({ - id: SSH_TUNNEL_ID, - enabled: false, - authType: NetworkHandlerAuthType.Password, - // should initially undefined cause if it's empty string it counts as saved password - password: undefined, - savePassword: false, - userName: '', - // should initially undefined cause if it's empty string it counts as saved private key - key: undefined, - properties: { - port: 22, - host: '', - aliveInterval: '0', - sshConnectTimeout: '10000', - }, - }) as INetworkHandlerConfig; +const getDefaultState = (): INetworkHandlerConfig => SSH_DEFAULT_HANDLER_CONFIG() as INetworkHandlerConfig; export class ConnectionFormSSHPart extends FormPart { constructor( @@ -50,19 +33,7 @@ export class ConnectionFormSSHPart extends FormPart = {}; - if (handlerDescriptor) { - for (const property of handlerDescriptor.properties) { - if (!property.features.includes('password')) { - properties[property.id!] = property.value; - } - } - } - state.properties = { - ...properties, + ...getNetworkHandlerDefaultProperties(handlerDescriptor), ...state.properties, }; } @@ -124,7 +86,7 @@ export class ConnectionFormSSHPart extends FormPart = observer(function SSH({ formState, handlerState, tabId }) { const { selected } = useTab(tabId); const [loading, setLoading] = useState(false); - const { credentialsSavingEnabled } = useAdministrationSettings(); const networkHandlerResource = useService(NetworkHandlerResource); - const serverConfigResource = useResource(SSH, ServerConfigResource, undefined, { - active: selected, - }); - const SSHPart = getConnectionFormSSHPart(formState); + + const sshPart = getConnectionFormSSHPart(formState); + const optionsPart = getConnectionFormOptionsPart(formState); async function testConnection() { setLoading(true); - const config = SSHPart.getConfig(); - await networkHandlerResource.test(config, formState.state.projectId, formState.state.connectionId); - setLoading(false); + const config = sshPart.getConfig(); + try { + await networkHandlerResource.test(config, formState.state.projectId, formState.state.connectionId); + } finally { + setLoading(false); + } } const style = useS(styles); @@ -68,124 +48,23 @@ export const SSH: TabContainerPanelComponent = observer(function SSH({ fo const disabled = formState.isDisabled || loading || formState.isReadOnly; const enabled = handlerState.enabled || false; const keyAuth = handlerState.authType === NetworkHandlerAuthType.PublicKey; - const passwordFilled = (SSHPart.initialState?.password === null && handlerState.password !== '') || !!handlerState.password?.length; + const passwordFilled = (sshPart.initialState?.password === null && handlerState.password !== '') || !!handlerState.password?.length; const testAvailable = keyAuth ? !!handlerState.key?.length : passwordFilled; - const passwordLabel = keyAuth ? 'Passphrase' : translate('connections_network_handler_ssh_tunnel_password'); - const passwordSaved = SSHPart.initialState?.password === '' && SSHPart.initialState.authType === handlerState.authType; - const keySaved = SSHPart.initialState?.key === ''; - const projectInfoResource = useService(ProjectInfoResource); - const isSharedProject = projectInfoResource.isProjectShared(formState.state.projectId); - const optionsPart = getConnectionFormOptionsPart(formState); - - const aliveIntervalLabel = translate('connections_network_handler_ssh_tunnel_advanced_settings_alive_interval'); - const connectTimeoutLabel = translate('connections_network_handler_ssh_tunnel_advanced_settings_connect_timeout'); - - const authTypeChangeHandler = useCallback(() => { - handlerState.password = ''; - }, []); - useAutoLoad(SSH, [SSHPart, optionsPart], selected); + useAutoLoad(SSH, [sshPart, optionsPart], selected); return (
- - {translate('connections_network_handler_ssh_tunnel_enable')} - - - - - {translate('connections_network_handler_ssh_tunnel_host')} - - - {translate('connections_network_handler_ssh_tunnel_port')} - - - - - {translate('connections_network_handler_ssh_tunnel_user')} - - - {passwordLabel} - - {keyAuth && } - - {credentialsSavingEnabled && !optionsPart.state.sharedCredentials && ( - - {translate( - !isSharedProject || serverConfigResource.data?.distributed - ? 'connections_connection_authentication_save_credentials_for_user' - : 'connections_connection_edit_save_credentials_shared', - )} - - )} - - - - - {aliveIntervalLabel} - - - {connectTimeoutLabel} - - - - + initialState={sshPart.initialState} + disabled={disabled} + readonly={formState.isReadOnly} + sharedCredentials={optionsPart.state.sharedCredentials} + projectId={formState.state.projectId} + />