diff --git a/app/client/modules/volumes/components/volume-forms/sftp-form.tsx b/app/client/modules/volumes/components/volume-forms/sftp-form.tsx index 3b8de322..11fd499e 100644 --- a/app/client/modules/volumes/components/volume-forms/sftp-form.tsx +++ b/app/client/modules/volumes/components/volume-forms/sftp-form.tsx @@ -14,7 +14,7 @@ import { SecretInput } from "../../../../components/ui/secret-input"; import { Textarea } from "../../../../components/ui/textarea"; import { Switch } from "../../../../components/ui/switch"; import { Button } from "~/client/components/ui/button"; -import { generatePrivateKeyPem } from "~/utils/ssh"; +import { generateSshKeyPairPem } from "~/utils/ssh"; type Props = { form: UseFormReturn; @@ -24,25 +24,43 @@ export const SFTPForm = ({ form }: Props) => { const skipHostKeyCheck = useWatch({ control: form.control, name: "skipHostKeyCheck" }); const [isGeneratingKey, setIsGeneratingKey] = useState(false); const [keyGenerationError, setKeyGenerationError] = useState(null); + const [generatedPublicKey, setGeneratedPublicKey] = useState(null); + const [copyPublicKeyMessage, setCopyPublicKeyMessage] = useState(null); const handleGenerateKey = async () => { setIsGeneratingKey(true); setKeyGenerationError(null); try { - const privateKey = await generatePrivateKeyPem(); - form.setValue("privateKey", privateKey, { + const { privateKeyPem, publicKeyPem } = await generateSshKeyPairPem(); + form.setValue("privateKey", privateKeyPem, { shouldDirty: true, shouldTouch: true, shouldValidate: true, }); + setGeneratedPublicKey(publicKeyPem); } catch { + setGeneratedPublicKey(null); setKeyGenerationError("Could not generate SSH key in this browser."); } finally { setIsGeneratingKey(false); } }; + const handleCopyPublicKey = async () => { + setCopyPublicKeyMessage(null); + if (!generatedPublicKey) { + setKeyGenerationError("Generate a key first to copy its public key."); + return; + } + try { + await navigator.clipboard.writeText(generatedPublicKey); + setCopyPublicKeyMessage("Public key copied to clipboard."); + } catch { + setKeyGenerationError("Could not copy public key to clipboard."); + } + }; + return ( <> { SSH private key for authentication (optional if using password). - +
+ + +
The key is generated privately in your browser. Don't forget to save it! {keyGenerationError && {keyGenerationError}} + {copyPublicKeyMessage && {copyPublicKeyMessage}} )} />