fixes and improvements
This commit is contained in:
@@ -81,6 +81,7 @@ function MachineEditor({
|
|||||||
isValidatingSSH,
|
isValidatingSSH,
|
||||||
sshValidationMessage,
|
sshValidationMessage,
|
||||||
sshValidationError,
|
sshValidationError,
|
||||||
|
sshValidationStatus,
|
||||||
}: {
|
}: {
|
||||||
title: string;
|
title: string;
|
||||||
hint?: string;
|
hint?: string;
|
||||||
@@ -95,6 +96,7 @@ function MachineEditor({
|
|||||||
isValidatingSSH: boolean;
|
isValidatingSSH: boolean;
|
||||||
sshValidationMessage: string;
|
sshValidationMessage: string;
|
||||||
sshValidationError: string;
|
sshValidationError: string;
|
||||||
|
sshValidationStatus: string;
|
||||||
}) {
|
}) {
|
||||||
const draft = machine;
|
const draft = machine;
|
||||||
const setDraft = onChange;
|
const setDraft = onChange;
|
||||||
@@ -429,10 +431,15 @@ function MachineEditor({
|
|||||||
{!isLocal && (
|
{!isLocal && (
|
||||||
<Stack spacing={1}>
|
<Stack spacing={1}>
|
||||||
<Alert severity="info">
|
<Alert severity="info">
|
||||||
Validate SSH before saving: this records the first trusted host key
|
Validate SSH before saving: this records the first trusted host
|
||||||
in the backend-managed known_hosts file, then checks SSH auth.
|
key in the backend-managed known_hosts file, then checks SSH
|
||||||
|
auth.
|
||||||
</Alert>
|
</Alert>
|
||||||
<Stack direction="row" spacing={1} sx={{ flexWrap: "wrap" }}>
|
<Stack
|
||||||
|
direction="row"
|
||||||
|
spacing={1}
|
||||||
|
sx={{ flexWrap: "wrap", alignItems: "center" }}
|
||||||
|
>
|
||||||
<Button
|
<Button
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
onClick={onValidateSSH}
|
onClick={onValidateSSH}
|
||||||
@@ -446,6 +453,9 @@ function MachineEditor({
|
|||||||
? "Validating SSH..."
|
? "Validating SSH..."
|
||||||
: "Validate SSH + trust host"}
|
: "Validate SSH + trust host"}
|
||||||
</Button>
|
</Button>
|
||||||
|
<Typography variant="caption" color="text.secondary">
|
||||||
|
SSH status: {sshValidationStatus || "Not tested yet"}
|
||||||
|
</Typography>
|
||||||
</Stack>
|
</Stack>
|
||||||
{sshValidationMessage && (
|
{sshValidationMessage && (
|
||||||
<Alert severity="success">{sshValidationMessage}</Alert>
|
<Alert severity="success">{sshValidationMessage}</Alert>
|
||||||
@@ -578,7 +588,11 @@ function SSHKeyManager({ sshKeys }: { sshKeys: SSHKey[] }) {
|
|||||||
/>
|
/>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Stack direction="row" spacing={1} sx={{ flexWrap: "wrap" }}>
|
<Stack
|
||||||
|
direction="row"
|
||||||
|
spacing={1}
|
||||||
|
sx={{ flexWrap: "wrap", alignItems: "center" }}
|
||||||
|
>
|
||||||
<Button
|
<Button
|
||||||
variant="contained"
|
variant="contained"
|
||||||
disabled={saveKey.isPending}
|
disabled={saveKey.isPending}
|
||||||
@@ -870,6 +884,7 @@ export function Settings() {
|
|||||||
const [tab, setTab] = useState<SettingsTab>("machines");
|
const [tab, setTab] = useState<SettingsTab>("machines");
|
||||||
const [sshValidationMessage, setSSHValidationMessage] = useState("");
|
const [sshValidationMessage, setSSHValidationMessage] = useState("");
|
||||||
const [sshValidationError, setSSHValidationError] = useState("");
|
const [sshValidationError, setSSHValidationError] = useState("");
|
||||||
|
const [sshValidationStatus, setSSHValidationStatus] = useState("");
|
||||||
const [machineDialogOpen, setMachineDialogOpen] = useState(false);
|
const [machineDialogOpen, setMachineDialogOpen] = useState(false);
|
||||||
const [machineDraft, setMachineDraft] = useState<MonitoringMachineInput>(
|
const [machineDraft, setMachineDraft] = useState<MonitoringMachineInput>(
|
||||||
emptyMachine(),
|
emptyMachine(),
|
||||||
@@ -892,6 +907,7 @@ export function Settings() {
|
|||||||
const clearSSHValidation = () => {
|
const clearSSHValidation = () => {
|
||||||
setSSHValidationMessage("");
|
setSSHValidationMessage("");
|
||||||
setSSHValidationError("");
|
setSSHValidationError("");
|
||||||
|
setSSHValidationStatus("");
|
||||||
};
|
};
|
||||||
const beginLocal = () => {
|
const beginLocal = () => {
|
||||||
clearSSHValidation();
|
clearSSHValidation();
|
||||||
@@ -931,10 +947,25 @@ export function Settings() {
|
|||||||
try {
|
try {
|
||||||
const result = await testMachineSSH.mutateAsync(machineDraft);
|
const result = await testMachineSSH.mutateAsync(machineDraft);
|
||||||
setSSHValidationMessage(result.message);
|
setSSHValidationMessage(result.message);
|
||||||
} catch (error) {
|
setSSHValidationStatus(
|
||||||
setSSHValidationError(
|
result.known_hosts_updated
|
||||||
error instanceof Error ? error.message : String(error),
|
? "Host key trusted and SSH auth succeeded."
|
||||||
|
: "Host key already trusted and SSH auth succeeded.",
|
||||||
);
|
);
|
||||||
|
} catch (error) {
|
||||||
|
const message = error instanceof Error ? error.message : String(error);
|
||||||
|
setSSHValidationError(message);
|
||||||
|
const lowered = message.toLowerCase();
|
||||||
|
if (lowered.includes("protocol banner")) {
|
||||||
|
setSSHValidationStatus("SSH banner not received.");
|
||||||
|
} else if (
|
||||||
|
lowered.includes("no authentication methods available") ||
|
||||||
|
lowered.includes("authentication failed")
|
||||||
|
) {
|
||||||
|
setSSHValidationStatus("SSH authentication failed.");
|
||||||
|
} else {
|
||||||
|
setSSHValidationStatus("SSH validation failed.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
return (
|
return (
|
||||||
@@ -1283,6 +1314,7 @@ export function Settings() {
|
|||||||
isValidatingSSH={testMachineSSH.isPending}
|
isValidatingSSH={testMachineSSH.isPending}
|
||||||
sshValidationMessage={sshValidationMessage}
|
sshValidationMessage={sshValidationMessage}
|
||||||
sshValidationError={sshValidationError}
|
sshValidationError={sshValidationError}
|
||||||
|
sshValidationStatus={sshValidationStatus}
|
||||||
/>
|
/>
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
<DialogFooter
|
<DialogFooter
|
||||||
|
|||||||
Reference in New Issue
Block a user