import { FormField, FormItem, FormLabel, FormControl, } from "@/components/ui/form.tsx"; import { PasswordInput } from "@/components/ui/password-input.tsx"; import { Button } from "@/components/ui/button.tsx"; import { Tabs, TabsContent, TabsList, TabsTrigger, } from "@/components/ui/tabs.tsx"; import { Controller } from "react-hook-form"; import CodeMirror from "@uiw/react-codemirror"; import { EditorView } from "@codemirror/view"; import React from "react"; import { useTranslation } from "react-i18next"; import { toast } from "sonner"; import { generateKeyPair, generatePublicKeyFromPrivate, } from "@/ui/main-axios.ts"; import type { CredentialAuthenticationTabProps } from "./shared/tab-types"; export function CredentialAuthenticationTab({ form, authTab, setAuthTab, detectedKeyType, detectedPublicKeyType, keyDetectionLoading, publicKeyDetectionLoading, editorTheme, debouncedKeyDetection, debouncedPublicKeyDetection, getFriendlyKeyTypeName, }: CredentialAuthenticationTabProps) { const { t } = useTranslation(); return ( <> {t("credentials.authentication")} { const newAuthType = value as "password" | "key"; setAuthTab(newAuthType); form.setValue("authType", newAuthType); form.setValue("password", ""); form.setValue("key", null); form.setValue("keyPassword", ""); form.setValue("keyType", "auto"); }} className="flex-1 flex flex-col h-full min-h-0" > {t("credentials.password")} {t("credentials.key")} ( {t("credentials.password")} )} />
{t("credentials.generateKeyPair")}
{t("credentials.generateKeyPairDescription")}
( {t("credentials.sshPrivateKey")}
{ const file = e.target.files?.[0]; if (file) { try { const fileContent = await file.text(); field.onChange(fileContent); debouncedKeyDetection( fileContent, form.watch("keyPassword"), ); } catch (error) { console.error( "Failed to read uploaded file:", error, ); } } }} className="absolute inset-0 w-full h-full opacity-0 cursor-pointer" />
{ field.onChange(value); debouncedKeyDetection( value, form.watch("keyPassword"), ); }} placeholder={t("placeholders.pastePrivateKey")} theme={editorTheme} className="border border-input rounded-md overflow-hidden" minHeight="120px" basicSetup={{ lineNumbers: true, foldGutter: false, dropCursor: false, allowMultipleSelections: false, highlightSelectionMatches: false, searchKeymap: false, scrollPastEnd: false, }} extensions={[ EditorView.theme({ ".cm-scroller": { overflow: "auto", scrollbarWidth: "thin", scrollbarColor: "var(--scrollbar-thumb) var(--scrollbar-track)", }, }), ]} /> {detectedKeyType && (
{t("credentials.detectedKeyType")}:{" "} {getFriendlyKeyTypeName(detectedKeyType)} {keyDetectionLoading && ( ({t("credentials.detectingKeyType")}) )}
)}
)} /> ( {t("credentials.sshPublicKey")}
{ const file = e.target.files?.[0]; if (file) { try { const fileContent = await file.text(); field.onChange(fileContent); debouncedPublicKeyDetection(fileContent); } catch (error) { console.error( "Failed to read uploaded public key file:", error, ); } } }} className="absolute inset-0 w-full h-full opacity-0 cursor-pointer" />
{ field.onChange(value); debouncedPublicKeyDetection(value); }} placeholder={t("placeholders.pastePublicKey")} theme={editorTheme} className="border border-input rounded-md overflow-hidden" minHeight="120px" basicSetup={{ lineNumbers: true, foldGutter: false, dropCursor: false, allowMultipleSelections: false, highlightSelectionMatches: false, searchKeymap: false, scrollPastEnd: false, }} extensions={[ EditorView.theme({ ".cm-scroller": { overflow: "auto", scrollbarWidth: "thin", scrollbarColor: "var(--scrollbar-thumb) var(--scrollbar-track)", }, }), ]} /> {detectedPublicKeyType && field.value && (
{t("credentials.detectedKeyType")}:{" "} {getFriendlyKeyTypeName(detectedPublicKeyType)} {publicKeyDetectionLoading && ( ({t("credentials.detectingKeyType")}) )}
)}
)} />
( {t("credentials.keyPassword")} )} />
); }