From ecb12d72fe75f687e1bfc46533ec1a65164ef230 Mon Sep 17 00:00:00 2001 From: ZacharyZcR Date: Sun, 14 Sep 2025 22:44:30 +0800 Subject: [PATCH 1/6] Fix SSH key upload and credential editing issues MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixed two major credential management issues: 1. Fix SSH key upload button not responding (Issue #232) - Error handling was silently swallowing exceptions - Added proper error propagation in axios functions - Improved error display to show specific error messages - Users now see actual error details instead of generic messages 2. Improve credential editing to show actual content - Both "Upload File" and "Paste Key" modes now display existing data - Upload mode: shows current key content in read-only preview area - Paste mode: shows editable key content in textarea - Smart input method switching preserves existing data - Enhanced button labels and status indicators Key changes: - Fixed handleApiError propagation in main-axios.ts credential functions - Enhanced CredentialEditor.tsx with key content preview - Improved error handling with console logging for debugging - Better UX with clear status indicators and preserved data These fixes resolve the "Add Credential button does nothing" issue and provide full visibility of credential content during editing. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- .../Apps/Credentials/CredentialEditor.tsx | 57 ++++++++++++++----- src/ui/main-axios.ts | 18 +++--- 2 files changed, 53 insertions(+), 22 deletions(-) diff --git a/src/ui/Desktop/Apps/Credentials/CredentialEditor.tsx b/src/ui/Desktop/Apps/Credentials/CredentialEditor.tsx index f0401878..a99cdccd 100644 --- a/src/ui/Desktop/Apps/Credentials/CredentialEditor.tsx +++ b/src/ui/Desktop/Apps/Credentials/CredentialEditor.tsx @@ -176,7 +176,7 @@ export function CredentialEditor({ if (defaultAuthType === "password") { formData.password = fullCredentialDetails.password || ""; } else if (defaultAuthType === "key") { - formData.key = "existing_key"; + formData.key = fullCredentialDetails.key || ""; formData.keyPassword = fullCredentialDetails.keyPassword || ""; formData.keyType = (fullCredentialDetails.keyType as any) || ("auto" as const); @@ -230,8 +230,6 @@ export function CredentialEditor({ if (data.key instanceof File) { const keyContent = await data.key.text(); submitData.key = keyContent; - } else if (data.key === "existing_key") { - delete submitData.key; } else { submitData.key = data.key; } @@ -259,7 +257,12 @@ export function CredentialEditor({ form.reset(); } catch (error) { - toast.error(t("credentials.failedToSaveCredential")); + console.error("Credential save error:", error); + if (error instanceof Error) { + toast.error(error.message); + } else { + toast.error(t("credentials.failedToSaveCredential")); + } } }; @@ -593,10 +596,22 @@ export function CredentialEditor({ value={keyInputMethod} onValueChange={(value) => { setKeyInputMethod(value as "upload" | "paste"); - if (value === "upload") { - form.setValue("key", null); + // Only reset key value if we're not editing an existing credential + if (!editingCredential) { + if (value === "upload") { + form.setValue("key", null); + } else { + form.setValue("key", ""); + } } else { - form.setValue("key", ""); + // For existing credentials, preserve the key data when switching methods + const currentKey = fullCredentialDetails?.key || ""; + if (value === "paste") { + form.setValue("key", currentKey); + } else { + // For upload mode, keep the current string value to show "existing key" status + form.setValue("key", currentKey); + } } }} className="w-full" @@ -642,13 +657,13 @@ export function CredentialEditor({ t("credentials.upload") } > - {field.value === "existing_key" - ? t("hosts.existingKey") - : field.value - ? editingCredential + {field.value instanceof File + ? field.value.name + : typeof field.value === "string" && field.value && editingCredential + ? t("hosts.existingKey") + " - " + t("credentials.updateKey") + : field.value ? t("credentials.updateKey") - : field.value.name - : t("credentials.upload")} + : t("credentials.upload")} @@ -656,6 +671,22 @@ export function CredentialEditor({ )} /> + {/* Show existing key content preview for upload mode */} + {editingCredential && fullCredentialDetails?.key && typeof form.watch("key") === "string" && ( + + {t("credentials.sshPrivateKey")} ({t("hosts.existingKey")}) + +