diff --git a/application/i18n/locales/en/vault.ts b/application/i18n/locales/en/vault.ts index 8129b07b1b..27360e10c9 100644 --- a/application/i18n/locales/en/vault.ts +++ b/application/i18n/locales/en/vault.ts @@ -91,6 +91,10 @@ export const enVaultMessages: Messages = { 'vault.import.mobaxterm.utf8Desc': 'Use for files saved or converted as UTF-8.', 'vault.import.mobaxterm.gb18030': 'Chinese Windows', 'vault.import.mobaxterm.gb18030Desc': 'Use for legacy files exported on Chinese Windows.', + 'vault.import.mobaxterm.masterPassword': 'Master password (optional)', + 'vault.import.mobaxterm.masterPasswordPlaceholder': 'Enter the MobaXterm master password', + 'vault.import.mobaxterm.masterPasswordHint': + 'Needed to import saved passwords from .mobaconf or MobaXterm.ini. Leave blank to import sessions only.', 'vault.import.sshConfig.chooseMode': 'Choose how to import your SSH config file.', 'vault.import.sshConfig.modeQuestion': 'How would you like to import?', 'vault.import.sshConfig.importOnly': 'Import Only', diff --git a/application/i18n/locales/es/vault.ts b/application/i18n/locales/es/vault.ts index 057acfd18b..48aab004a8 100644 --- a/application/i18n/locales/es/vault.ts +++ b/application/i18n/locales/es/vault.ts @@ -91,6 +91,10 @@ export const esVaultMessages: Messages = { 'vault.import.mobaxterm.utf8Desc': 'Úsalo para archivos guardados o convertidos como UTF-8.', 'vault.import.mobaxterm.gb18030': 'Windows en chino', 'vault.import.mobaxterm.gb18030Desc': 'Úsalo para archivos antiguos exportados en Windows en chino.', + 'vault.import.mobaxterm.masterPassword': 'Contraseña maestra (opcional)', + 'vault.import.mobaxterm.masterPasswordPlaceholder': 'Introduce la contraseña maestra de MobaXterm', + 'vault.import.mobaxterm.masterPasswordHint': + 'Hace falta para importar las contraseñas guardadas de .mobaconf o MobaXterm.ini. Déjalo vacío para importar solo las sesiones.', 'vault.import.sshConfig.chooseMode': 'Elige cómo importar tu archivo de configuración SSH.', 'vault.import.sshConfig.modeQuestion': '¿Cómo te gustaría importar?', 'vault.import.sshConfig.importOnly': 'Solo importar', diff --git a/application/i18n/locales/ru/vault.ts b/application/i18n/locales/ru/vault.ts index cf3bd7ae95..7d46a09579 100644 --- a/application/i18n/locales/ru/vault.ts +++ b/application/i18n/locales/ru/vault.ts @@ -128,6 +128,10 @@ export const ruVaultMessages: Messages = { 'vault.import.mobaxterm.utf8Desc': 'Для файлов, сохранённых или преобразованных в UTF-8.', 'vault.import.mobaxterm.gb18030': 'Китайская Windows', 'vault.import.mobaxterm.gb18030Desc': 'Для старых файлов, экспортированных в китайской Windows.', + 'vault.import.mobaxterm.masterPassword': 'Мастер-пароль (необязательно)', + 'vault.import.mobaxterm.masterPasswordPlaceholder': 'Введите мастер-пароль MobaXterm', + 'vault.import.mobaxterm.masterPasswordHint': + 'Нужен, чтобы импортировать сохранённые пароли из .mobaconf или MobaXterm.ini. Оставьте пустым, чтобы импортировать только сеансы.', 'vault.import.sshConfig.chooseMode': 'Выберите, как импортировать ваш файл SSH-конфига.', 'vault.import.sshConfig.modeQuestion': 'Как вы хотите выполнить импорт?', 'vault.import.sshConfig.importOnly': 'Только импорт', diff --git a/application/i18n/locales/vaultBulkImportLocales.test.ts b/application/i18n/locales/vaultBulkImportLocales.test.ts index 5f4bd578cd..fe7e9b7c54 100644 --- a/application/i18n/locales/vaultBulkImportLocales.test.ts +++ b/application/i18n/locales/vaultBulkImportLocales.test.ts @@ -24,6 +24,9 @@ const KEYS = [ "vault.import.progress.persistFailed", "vault.import.progress.rollbackFailed", "vault.import.sshConfig.managedDestinationHint", + "vault.import.mobaxterm.masterPassword", + "vault.import.mobaxterm.masterPasswordPlaceholder", + "vault.import.mobaxterm.masterPasswordHint", ] as const; test("bulk vault import and group-selection copy exists in every locale", () => { diff --git a/application/i18n/locales/zh-CN/core.ts b/application/i18n/locales/zh-CN/core.ts index f3d30b274c..cec22f093b 100644 --- a/application/i18n/locales/zh-CN/core.ts +++ b/application/i18n/locales/zh-CN/core.ts @@ -719,6 +719,10 @@ export const zhCNCoreMessages: Messages = { 'vault.import.mobaxterm.utf8Desc': '适用于已保存或转换为 UTF-8 的文件。', 'vault.import.mobaxterm.gb18030': '中文 Windows', 'vault.import.mobaxterm.gb18030Desc': '适用于中文 Windows 上导出的旧版文件。', + 'vault.import.mobaxterm.masterPassword': '主密码(可选)', + 'vault.import.mobaxterm.masterPasswordPlaceholder': '输入 MobaXterm 主密码', + 'vault.import.mobaxterm.masterPasswordHint': + '导入 .mobaconf 或 MobaXterm.ini 中保存的密码时需要填写。留空则只导入会话。', 'vault.import.sshConfig.chooseMode': '选择如何导入你的 SSH config 文件。', 'vault.import.sshConfig.modeQuestion': '你希望如何导入?', 'vault.import.sshConfig.importOnly': '仅导入', diff --git a/application/i18n/locales/zh-TW/core.ts b/application/i18n/locales/zh-TW/core.ts index d374ceae5f..2cf249bbe8 100644 --- a/application/i18n/locales/zh-TW/core.ts +++ b/application/i18n/locales/zh-TW/core.ts @@ -719,6 +719,10 @@ export const zhTWCoreMessages: Messages = { 'vault.import.mobaxterm.utf8Desc': '適用於已儲存或轉換為 UTF-8 的檔案。', 'vault.import.mobaxterm.gb18030': '中文 Windows', 'vault.import.mobaxterm.gb18030Desc': '適用於中文 Windows 上匯出的舊版檔案。', + 'vault.import.mobaxterm.masterPassword': '主密碼(選填)', + 'vault.import.mobaxterm.masterPasswordPlaceholder': '輸入 MobaXterm 主密碼', + 'vault.import.mobaxterm.masterPasswordHint': + '匯入 .mobaconf 或 MobaXterm.ini 中已儲存的密碼時需要填寫。留空則只匯入工作階段。', 'vault.import.sshConfig.chooseMode': '選擇如何匯入你的 SSH config 檔案。', 'vault.import.sshConfig.modeQuestion': '你希望如何匯入?', 'vault.import.sshConfig.importOnly': '僅匯入', diff --git a/application/state/useVaultImportHandlers.ts b/application/state/useVaultImportHandlers.ts index 911a013dd1..04175d3139 100644 --- a/application/state/useVaultImportHandlers.ts +++ b/application/state/useVaultImportHandlers.ts @@ -171,6 +171,7 @@ export function useVaultImportHandlers({ format, files, encoding: options?.encoding, + masterPassword: options?.masterPassword, signal, onProgress: (progress) => { if (!signal.aborted) updateProgress(progress); diff --git a/application/state/vaultImportOptions.ts b/application/state/vaultImportOptions.ts index 0984f26fa1..c17cf2ebe3 100644 --- a/application/state/vaultImportOptions.ts +++ b/application/state/vaultImportOptions.ts @@ -6,6 +6,7 @@ export type VaultImportOptions = { managed?: boolean; filePath?: string; encoding?: VaultImportFileEncoding; + masterPassword?: string; destination?: VaultImportDestination; }; diff --git a/components/vault/ImportVaultDialog.tsx b/components/vault/ImportVaultDialog.tsx index b8a7996370..fd9f3c796c 100644 --- a/components/vault/ImportVaultDialog.tsx +++ b/components/vault/ImportVaultDialog.tsx @@ -29,6 +29,7 @@ import type { } from "../../domain/vaultImport"; import { cn } from "../../lib/utils"; import { Button } from "../ui/button"; +import { Input } from "../ui/input"; import { Dialog, DialogContent, @@ -55,7 +56,7 @@ const OPTIONS: ImportOption[] = [ format: "mobaxterm", label: "MobaXterm", iconSrc: "/import/moba.jpg", - accept: ".ini,.mxtsessions,.txt", + accept: ".ini,.mxtsessions,.txt,.mobaconf", }, { format: "csv", @@ -406,6 +407,7 @@ export const ImportVaultDialog: React.FC = ({ const existingGroupQueryRef = useRef(existingGroupQuery); existingGroupQueryRef.current = existingGroupQuery; const [newGroup, setNewGroup] = useState(""); + const [mobaMasterPassword, setMobaMasterPassword] = useState(""); const destination = buildVaultImportDestination({ mode: destinationMode, existingGroup, @@ -438,6 +440,7 @@ export const ImportVaultDialog: React.FC = ({ setExistingGroup(groups[0] ?? ""); setExistingGroupQuery(groups[0] ?? ""); setNewGroup(""); + setMobaMasterPassword(""); }, [groups, open]); const pluginImporter = usePluginVaultImporter({ open, @@ -511,9 +514,12 @@ export const ImportVaultDialog: React.FC = ({ const handleMobaEncodingChoice = useCallback( (encoding: VaultImportFileEncoding) => { setStep("format"); - pickFile("mobaxterm", ".ini,.mxtsessions,.txt", { encoding }); + pickFile("mobaxterm", ".ini,.mxtsessions,.txt,.mobaconf", { + encoding, + masterPassword: mobaMasterPassword.trim() || undefined, + }); }, - [pickFile], + [mobaMasterPassword, pickFile], ); const handleSecureCrtChoice = useCallback( @@ -846,6 +852,25 @@ export const ImportVaultDialog: React.FC = ({ ))} +
+ + setMobaMasterPassword(event.target.value)} + placeholder={t("vault.import.mobaxterm.masterPasswordPlaceholder")} + /> +

+ {t("vault.import.mobaxterm.masterPasswordHint")} +

+