import PropTypes from 'prop-types'; import { CssVarsProvider } from '@mui/joy/styles'; import { Modal, Button, FormControl, FormLabel, Input, Stack, DialogTitle, DialogContent, ModalDialog, Select, Option, Checkbox, IconButton, Tabs, TabList, Tab, TabPanel } from '@mui/joy'; import theme from '/src/theme'; import { useState } from 'react'; import Visibility from '@mui/icons-material/Visibility'; import VisibilityOff from '@mui/icons-material/VisibilityOff'; const AddHostModal = ({ isHidden, form, setForm, handleAddHost, setIsAddHostHidden }) => { const [showPassword, setShowPassword] = useState(false); const [showPassphrase, setShowPassphrase] = useState(false); const [activeTab, setActiveTab] = useState(0); const handleFileChange = (e) => { const file = e.target.files[0]; const supportedKeyTypes = { 'id_rsa': 'RSA', 'id_ed25519': 'ED25519', 'id_ecdsa': 'ECDSA', 'id_dsa': 'DSA', '.pem': 'PEM', '.key': 'KEY', '.ppk': 'PPK' }; const isValidKeyFile = Object.keys(supportedKeyTypes).some(ext => file.name.toLowerCase().includes(ext) || file.name.endsWith('.pub') ); if (isValidKeyFile) { const reader = new FileReader(); reader.onload = (event) => { const keyContent = event.target.result; let keyType = 'UNKNOWN'; // Detect key type from content if (keyContent.includes('BEGIN RSA PRIVATE KEY') || keyContent.includes('BEGIN RSA PUBLIC KEY')) { keyType = 'RSA'; } else if (keyContent.includes('BEGIN OPENSSH PRIVATE KEY') && keyContent.includes('ssh-ed25519')) { keyType = 'ED25519'; } else if (keyContent.includes('BEGIN EC PRIVATE KEY') || keyContent.includes('BEGIN EC PUBLIC KEY')) { keyType = 'ECDSA'; } else if (keyContent.includes('BEGIN DSA PRIVATE KEY')) { keyType = 'DSA'; } setForm(prev => ({ ...prev, privateKey: keyContent, keyType: keyType, authMethod: 'key' })); }; reader.readAsText(file); } else { alert('Please upload a valid SSH key file (RSA, ED25519, ECDSA, DSA, PEM, or PPK format).'); } }; const handleAuthChange = (newMethod) => { setForm((prev) => ({ ...prev, authMethod: newMethod, password: "", privateKey: "", keyType: "", passphrase: "" })); }; const isFormValid = () => { const { ip, user, port, authMethod, password, privateKey } = form; // Basic validation for required fields if (!ip?.trim() || !user?.trim() || !port) return false; // Port validation const portNum = Number(port); if (isNaN(portNum) || portNum < 1 || portNum > 65535) return false; // If not remembering host, only basic fields are required if (!form.rememberHost) return true; // Auth method validation only if remembering host if (form.rememberHost) { if (authMethod === 'Select Auth') return false; if (authMethod === 'password' && !password?.trim()) return false; if (authMethod === 'key' && !privateKey?.trim()) return false; } return true; }; const handleSubmit = (event) => { event.preventDefault(); if (!form.ip?.trim() || !form.user?.trim() || !form.port) { alert("Please fill out all required fields (IP, User, Port)."); return; } handleAddHost(); }; return ( setIsAddHostHidden(true)} sx={{ display: 'flex', justifyContent: 'center', alignItems: 'center', backdropFilter: 'blur(5px)', backgroundColor: 'rgba(0, 0, 0, 0.2)', }} > setActiveTab(val)} sx={{ width: '100%', mb: 0, backgroundColor: theme.palette.general.tertiary, }} > Basic Info Connection Authentication
Host Name setForm({ ...form, name: e.target.value })} sx={{ backgroundColor: theme.palette.general.primary, color: theme.palette.text.primary, }} /> Folder setForm({ ...form, folder: e.target.value })} sx={{ backgroundColor: theme.palette.general.primary, color: theme.palette.text.primary, }} /> Remember Host setForm({ ...form, rememberHost: e.target.checked, })} sx={{ color: theme.palette.text.primary, '&.Mui-checked': { color: theme.palette.text.primary, }, }} /> Host IP setForm({ ...form, ip: e.target.value })} required sx={{ backgroundColor: theme.palette.general.primary, color: theme.palette.text.primary, }} /> Host User setForm({ ...form, user: e.target.value })} required sx={{ backgroundColor: theme.palette.general.primary, color: theme.palette.text.primary, }} /> 65535}> Host Port setForm({ ...form, port: e.target.value })} min={1} max={65535} required sx={{ backgroundColor: theme.palette.general.primary, color: theme.palette.text.primary, }} /> Authentication Method {form.authMethod === 'password' && ( Password
setForm({ ...form, password: e.target.value })} sx={{ backgroundColor: theme.palette.general.primary, color: theme.palette.text.primary, flex: 1 }} /> setShowPassword(!showPassword)} sx={{ color: theme.palette.text.primary, marginLeft: 1 }} > {showPassword ? : }
)} {form.authMethod === 'key' && ( SSH Key {form.privateKey && ( Key Passphrase (optional)
setForm(prev => ({ ...prev, passphrase: e.target.value }))} sx={{ backgroundColor: theme.palette.general.primary, color: theme.palette.text.primary, flex: 1 }} /> setShowPassphrase(!showPassphrase)} sx={{ color: theme.palette.text.primary, marginLeft: 1 }} > {showPassphrase ? : }
)}
)} {form.rememberHost && ( Store Password setForm({ ...form, storePassword: e.target.checked })} sx={{ color: theme.palette.text.primary, '&.Mui-checked': { color: theme.palette.text.primary, }, }} /> )}
); }; AddHostModal.propTypes = { isHidden: PropTypes.bool.isRequired, form: PropTypes.object.isRequired, setForm: PropTypes.func.isRequired, handleAddHost: PropTypes.func.isRequired, setIsAddHostHidden: PropTypes.func.isRequired, }; export default AddHostModal;