mirror of https://github.com/jetkvm/kvm.git
Settings Advanced page
This commit is contained in:
parent
5613555b39
commit
0eb577b6f7
|
|
@ -544,6 +544,52 @@
|
||||||
"local_auth_update_current_password_label": "Current Password",
|
"local_auth_update_current_password_label": "Current Password",
|
||||||
"local_auth_update_description": "Enter your current password and a new password to update your local device protection.",
|
"local_auth_update_description": "Enter your current password and a new password to update your local device protection.",
|
||||||
"local_auth_update_new_password_label": "New Password",
|
"local_auth_update_new_password_label": "New Password",
|
||||||
|
"local_auth_update_password_button": "Update Password",
|
||||||
"local_auth_update_title": "Change Local Device Password",
|
"local_auth_update_title": "Change Local Device Password",
|
||||||
"local_auth_update_password_button": "Update Password"
|
|
||||||
|
"advanced_description": "Access additional settings for troubleshooting and customization",
|
||||||
|
"advanced_dev_channel_description": "Receive early updates from the development channel",
|
||||||
|
"advanced_dev_channel_title": "Dev Channel Updates",
|
||||||
|
"advanced_developer_mode_description": "Enable advanced features for developers",
|
||||||
|
"advanced_developer_mode_enabled_title": "Developer Mode Enabled",
|
||||||
|
"advanced_developer_mode_title": "Developer Mode",
|
||||||
|
"advanced_developer_mode_warning_advanced": "For advanced users only. Not for production use.",
|
||||||
|
"advanced_developer_mode_warning_risks": "Only use if you understand the risks",
|
||||||
|
"advanced_developer_mode_warning_security": "Security is weakened while active",
|
||||||
|
"advanced_disable_usb_emulation": "Disable USB Emulation",
|
||||||
|
"advanced_enable_usb_emulation": "Enable USB Emulation",
|
||||||
|
"advanced_error_loopback_disable": "Failed to disable loopback-only mode: {error}",
|
||||||
|
"advanced_error_loopback_enable": "Failed to enable loopback-only mode: {error}",
|
||||||
|
"advanced_error_reset_config": "Failed to reset configuration: {error}",
|
||||||
|
"advanced_error_set_dev_channel": "Failed to set dev channel state: {error}",
|
||||||
|
"advanced_error_set_dev_mode": "Failed to set dev mode: {error}",
|
||||||
|
"advanced_error_update_ssh_key": "Failed to update SSH key: {error}",
|
||||||
|
"advanced_error_usb_emulation_disable": "Failed to disable USB emulation: {error}",
|
||||||
|
"advanced_error_usb_emulation_enable": "Failed to enable USB emulation: {error}",
|
||||||
|
"advanced_loopback_only_description": "Restrict web interface access to localhost only (127.0.0.1)",
|
||||||
|
"advanced_loopback_only_title": "Loopback-Only Mode",
|
||||||
|
"advanced_loopback_warning_before": "Before enabling this feature, make sure you have either:",
|
||||||
|
"advanced_loopback_warning_cloud": "Cloud access enabled and working",
|
||||||
|
"advanced_loopback_warning_confirm": "I Understand, Enable Anyway",
|
||||||
|
"advanced_loopback_warning_description": "WARNING: This will restrict web interface access to localhost (127.0.0.1) only.",
|
||||||
|
"advanced_loopback_warning_ssh": "SSH access configured and tested",
|
||||||
|
"advanced_loopback_warning_title": "Enable Loopback-Only Mode?",
|
||||||
|
"advanced_reset_config_button": "Reset Config",
|
||||||
|
"advanced_reset_config_description": "Reset configuration to default. This will log you out.",
|
||||||
|
"advanced_reset_config_title": "Reset Configuration",
|
||||||
|
"advanced_ssh_access_description": "Add your SSH public key to enable secure remote access to the device",
|
||||||
|
"advanced_ssh_access_title": "SSH Access",
|
||||||
|
"advanced_ssh_default_user": "The default SSH user is",
|
||||||
|
"advanced_ssh_public_key_label": "SSH Public Key",
|
||||||
|
"advanced_ssh_public_key_placeholder": "Enter your SSH public key",
|
||||||
|
"advanced_success_loopback_disabled": "Loopback-only mode disabled. Restart your device to apply.",
|
||||||
|
"advanced_success_loopback_enabled": "Loopback-only mode enabled. Restart your device to apply.",
|
||||||
|
"advanced_success_reset_config": "Configuration reset to default successfully",
|
||||||
|
"advanced_success_update_ssh_key": "SSH key updated successfully",
|
||||||
|
"advanced_title": "Advanced",
|
||||||
|
"advanced_troubleshooting_mode_description": "Diagnostic tools and additional controls for troubleshooting and development purposes",
|
||||||
|
"advanced_troubleshooting_mode_title": "Troubleshooting Mode",
|
||||||
|
"advanced_update_ssh_key_button": "Update SSH Key",
|
||||||
|
"advanced_usb_emulation_description": "Control the USB emulation state",
|
||||||
|
"advanced_usb_emulation_title": "USB Emulation"
|
||||||
}
|
}
|
||||||
|
|
@ -1,17 +1,17 @@
|
||||||
import { useCallback, useEffect, useState } from "react";
|
import { useCallback, useEffect, useState } from "react";
|
||||||
|
|
||||||
|
import { useSettingsStore } from "@hooks/stores";
|
||||||
|
import { JsonRpcResponse, useJsonRpc } from "@hooks/useJsonRpc";
|
||||||
|
import { Button } from "@components/Button";
|
||||||
|
import Checkbox from "@components/Checkbox";
|
||||||
|
import { ConfirmDialog } from "@components/ConfirmDialog";
|
||||||
import { GridCard } from "@components/Card";
|
import { GridCard } from "@components/Card";
|
||||||
import { SettingsItem } from "@components/SettingsItem";
|
import { SettingsItem } from "@components/SettingsItem";
|
||||||
|
import { SettingsPageHeader } from "@components/SettingsPageheader";
|
||||||
import { Button } from "../components/Button";
|
import { TextAreaWithLabel } from "@components/TextArea";
|
||||||
import Checkbox from "../components/Checkbox";
|
import { isOnDevice } from "@/main";
|
||||||
import { ConfirmDialog } from "../components/ConfirmDialog";
|
import notifications from "@/notifications";
|
||||||
import { SettingsPageHeader } from "../components/SettingsPageheader";
|
import { m } from "@localizations/messages.js";
|
||||||
import { TextAreaWithLabel } from "../components/TextArea";
|
|
||||||
import { useSettingsStore } from "../hooks/stores";
|
|
||||||
import { JsonRpcResponse, useJsonRpc } from "../hooks/useJsonRpc";
|
|
||||||
import { isOnDevice } from "../main";
|
|
||||||
import notifications from "../notifications";
|
|
||||||
|
|
||||||
export default function SettingsAdvancedRoute() {
|
export default function SettingsAdvancedRoute() {
|
||||||
const { send } = useJsonRpc();
|
const { send } = useJsonRpc();
|
||||||
|
|
@ -65,7 +65,9 @@ export default function SettingsAdvancedRoute() {
|
||||||
send("setUsbEmulationState", { enabled: enabled }, (resp: JsonRpcResponse) => {
|
send("setUsbEmulationState", { enabled: enabled }, (resp: JsonRpcResponse) => {
|
||||||
if ("error" in resp) {
|
if ("error" in resp) {
|
||||||
notifications.error(
|
notifications.error(
|
||||||
`Failed to ${enabled ? "enable" : "disable"} USB emulation: ${resp.error.data || "Unknown error"}`,
|
enabled
|
||||||
|
? m.advanced_error_usb_emulation_enable({error: resp.error.data || m.unknown_error()})
|
||||||
|
: m.advanced_error_usb_emulation_disable({error: resp.error.data || m.unknown_error()})
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -80,11 +82,11 @@ export default function SettingsAdvancedRoute() {
|
||||||
send("resetConfig", {}, (resp: JsonRpcResponse) => {
|
send("resetConfig", {}, (resp: JsonRpcResponse) => {
|
||||||
if ("error" in resp) {
|
if ("error" in resp) {
|
||||||
notifications.error(
|
notifications.error(
|
||||||
`Failed to reset configuration: ${resp.error.data || "Unknown error"}`,
|
m.advanced_error_reset_config({error: resp.error.data || m.unknown_error()})
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
notifications.success("Configuration reset to default successfully");
|
notifications.success(m.advanced_success_reset_config());
|
||||||
});
|
});
|
||||||
}, [send]);
|
}, [send]);
|
||||||
|
|
||||||
|
|
@ -92,11 +94,11 @@ export default function SettingsAdvancedRoute() {
|
||||||
send("setSSHKeyState", { sshKey }, (resp: JsonRpcResponse) => {
|
send("setSSHKeyState", { sshKey }, (resp: JsonRpcResponse) => {
|
||||||
if ("error" in resp) {
|
if ("error" in resp) {
|
||||||
notifications.error(
|
notifications.error(
|
||||||
`Failed to update SSH key: ${resp.error.data || "Unknown error"}`,
|
m.advanced_error_update_ssh_key({error: resp.error.data || m.unknown_error()})
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
notifications.success("SSH key updated successfully");
|
notifications.success(m.advanced_success_update_ssh_key());
|
||||||
});
|
});
|
||||||
}, [send, sshKey]);
|
}, [send, sshKey]);
|
||||||
|
|
||||||
|
|
@ -105,7 +107,7 @@ export default function SettingsAdvancedRoute() {
|
||||||
send("setDevModeState", { enabled: developerMode }, (resp: JsonRpcResponse) => {
|
send("setDevModeState", { enabled: developerMode }, (resp: JsonRpcResponse) => {
|
||||||
if ("error" in resp) {
|
if ("error" in resp) {
|
||||||
notifications.error(
|
notifications.error(
|
||||||
`Failed to set dev mode: ${resp.error.data || "Unknown error"}`,
|
m.advanced_error_set_dev_mode({error: resp.error.data || m.unknown_error()})
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -120,7 +122,7 @@ export default function SettingsAdvancedRoute() {
|
||||||
send("setDevChannelState", { enabled }, (resp: JsonRpcResponse) => {
|
send("setDevChannelState", { enabled }, (resp: JsonRpcResponse) => {
|
||||||
if ("error" in resp) {
|
if ("error" in resp) {
|
||||||
notifications.error(
|
notifications.error(
|
||||||
`Failed to set dev channel state: ${resp.error.data || "Unknown error"}`,
|
m.advanced_error_set_dev_channel({error: resp.error.data || m.unknown_error()})
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -135,19 +137,17 @@ export default function SettingsAdvancedRoute() {
|
||||||
send("setLocalLoopbackOnly", { enabled }, (resp: JsonRpcResponse) => {
|
send("setLocalLoopbackOnly", { enabled }, (resp: JsonRpcResponse) => {
|
||||||
if ("error" in resp) {
|
if ("error" in resp) {
|
||||||
notifications.error(
|
notifications.error(
|
||||||
`Failed to ${enabled ? "enable" : "disable"} loopback-only mode: ${resp.error.data || "Unknown error"}`,
|
enabled
|
||||||
|
? m.advanced_error_loopback_enable({error: resp.error.data || m.unknown_error()})
|
||||||
|
: m.advanced_error_loopback_disable({error: resp.error.data || m.unknown_error()})
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
setLocalLoopbackOnly(enabled);
|
setLocalLoopbackOnly(enabled);
|
||||||
if (enabled) {
|
if (enabled) {
|
||||||
notifications.success(
|
notifications.success(m.advanced_success_loopback_enabled());
|
||||||
"Loopback-only mode enabled. Restart your device to apply.",
|
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
notifications.success(
|
notifications.success(m.advanced_success_loopback_disabled());
|
||||||
"Loopback-only mode disabled. Restart your device to apply.",
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
@ -175,14 +175,14 @@ export default function SettingsAdvancedRoute() {
|
||||||
return (
|
return (
|
||||||
<div className="space-y-4">
|
<div className="space-y-4">
|
||||||
<SettingsPageHeader
|
<SettingsPageHeader
|
||||||
title="Advanced"
|
title={m.advanced_title()}
|
||||||
description="Access additional settings for troubleshooting and customization"
|
description={m.advanced_description()}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<div className="space-y-4">
|
<div className="space-y-4">
|
||||||
<SettingsItem
|
<SettingsItem
|
||||||
title="Dev Channel Updates"
|
title={m.advanced_dev_channel_title()}
|
||||||
description="Receive early updates from the development channel"
|
description={m.advanced_dev_channel_description()}
|
||||||
>
|
>
|
||||||
<Checkbox
|
<Checkbox
|
||||||
checked={devChannel}
|
checked={devChannel}
|
||||||
|
|
@ -192,8 +192,8 @@ export default function SettingsAdvancedRoute() {
|
||||||
/>
|
/>
|
||||||
</SettingsItem>
|
</SettingsItem>
|
||||||
<SettingsItem
|
<SettingsItem
|
||||||
title="Developer Mode"
|
title={m.advanced_developer_mode_title()}
|
||||||
description="Enable advanced features for developers"
|
description={m.advanced_developer_mode_description()}
|
||||||
>
|
>
|
||||||
<Checkbox
|
<Checkbox
|
||||||
checked={settings.developerMode}
|
checked={settings.developerMode}
|
||||||
|
|
@ -219,18 +219,17 @@ export default function SettingsAdvancedRoute() {
|
||||||
<div className="space-y-3">
|
<div className="space-y-3">
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<h3 className="text-base font-bold text-slate-900 dark:text-white">
|
<h3 className="text-base font-bold text-slate-900 dark:text-white">
|
||||||
Developer Mode Enabled
|
{m.advanced_developer_mode_enabled_title()}
|
||||||
</h3>
|
</h3>
|
||||||
<div>
|
<div>
|
||||||
<ul className="list-disc space-y-1 pl-5 text-xs text-slate-700 dark:text-slate-300">
|
<ul className="list-disc space-y-1 pl-5 text-xs text-slate-700 dark:text-slate-300">
|
||||||
<li>Security is weakened while active</li>
|
<li>{m.advanced_developer_mode_warning_security()}</li>
|
||||||
<li>Only use if you understand the risks</li>
|
<li>{m.advanced_developer_mode_warning_risks()}</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="text-xs text-slate-700 dark:text-slate-300">
|
<div className="text-xs text-slate-700 dark:text-slate-300">
|
||||||
For advanced users only. Not for production use.
|
{m.advanced_developer_mode_warning_advanced()}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -238,8 +237,8 @@ export default function SettingsAdvancedRoute() {
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<SettingsItem
|
<SettingsItem
|
||||||
title="Loopback-Only Mode"
|
title={m.advanced_loopback_only_title()}
|
||||||
description="Restrict web interface access to localhost only (127.0.0.1)"
|
description={m.advanced_loopback_only_description()}
|
||||||
>
|
>
|
||||||
<Checkbox
|
<Checkbox
|
||||||
checked={localLoopbackOnly}
|
checked={localLoopbackOnly}
|
||||||
|
|
@ -250,25 +249,25 @@ export default function SettingsAdvancedRoute() {
|
||||||
{isOnDevice && settings.developerMode && (
|
{isOnDevice && settings.developerMode && (
|
||||||
<div className="space-y-4">
|
<div className="space-y-4">
|
||||||
<SettingsItem
|
<SettingsItem
|
||||||
title="SSH Access"
|
title={m.advanced_ssh_access_title()}
|
||||||
description="Add your SSH public key to enable secure remote access to the device"
|
description={m.advanced_ssh_access_description()}
|
||||||
/>
|
/>
|
||||||
<div className="space-y-4">
|
<div className="space-y-4">
|
||||||
<TextAreaWithLabel
|
<TextAreaWithLabel
|
||||||
label="SSH Public Key"
|
label={m.advanced_ssh_public_key_label()}
|
||||||
value={sshKey || ""}
|
value={sshKey || ""}
|
||||||
rows={3}
|
rows={3}
|
||||||
onChange={e => setSSHKey(e.target.value)}
|
onChange={e => setSSHKey(e.target.value)}
|
||||||
placeholder="Enter your SSH public key"
|
placeholder={m.advanced_ssh_public_key_placeholder()}
|
||||||
/>
|
/>
|
||||||
<p className="text-xs text-slate-600 dark:text-slate-400">
|
<p className="text-xs text-slate-600 dark:text-slate-400">
|
||||||
The default SSH user is <strong>root</strong>.
|
{m.advanced_ssh_default_user()}<strong>root</strong>.
|
||||||
</p>
|
</p>
|
||||||
<div className="flex items-center gap-x-2">
|
<div className="flex items-center gap-x-2">
|
||||||
<Button
|
<Button
|
||||||
size="SM"
|
size="SM"
|
||||||
theme="primary"
|
theme="primary"
|
||||||
text="Update SSH Key"
|
text={m.advanced_update_ssh_key_button()}
|
||||||
onClick={handleUpdateSSHKey}
|
onClick={handleUpdateSSHKey}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -277,8 +276,8 @@ export default function SettingsAdvancedRoute() {
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<SettingsItem
|
<SettingsItem
|
||||||
title="Troubleshooting Mode"
|
title={m.advanced_troubleshooting_mode_title()}
|
||||||
description="Diagnostic tools and additional controls for troubleshooting and development purposes"
|
description={m.advanced_troubleshooting_mode_description()}
|
||||||
>
|
>
|
||||||
<Checkbox
|
<Checkbox
|
||||||
defaultChecked={settings.debugMode}
|
defaultChecked={settings.debugMode}
|
||||||
|
|
@ -291,27 +290,27 @@ export default function SettingsAdvancedRoute() {
|
||||||
{settings.debugMode && (
|
{settings.debugMode && (
|
||||||
<>
|
<>
|
||||||
<SettingsItem
|
<SettingsItem
|
||||||
title="USB Emulation"
|
title={m.advanced_usb_emulation_title()}
|
||||||
description="Control the USB emulation state"
|
description={m.advanced_usb_emulation_description()}
|
||||||
>
|
>
|
||||||
<Button
|
<Button
|
||||||
size="SM"
|
size="SM"
|
||||||
theme="light"
|
theme="light"
|
||||||
text={
|
text={
|
||||||
usbEmulationEnabled ? "Disable USB Emulation" : "Enable USB Emulation"
|
usbEmulationEnabled ? m.advanced_disable_usb_emulation() : m.advanced_enable_usb_emulation()
|
||||||
}
|
}
|
||||||
onClick={() => handleUsbEmulationToggle(!usbEmulationEnabled)}
|
onClick={() => handleUsbEmulationToggle(!usbEmulationEnabled)}
|
||||||
/>
|
/>
|
||||||
</SettingsItem>
|
</SettingsItem>
|
||||||
|
|
||||||
<SettingsItem
|
<SettingsItem
|
||||||
title="Reset Configuration"
|
title={m.advanced_reset_config_title()}
|
||||||
description="Reset configuration to default. This will log you out."
|
description={m.advanced_reset_config_description()}
|
||||||
>
|
>
|
||||||
<Button
|
<Button
|
||||||
size="SM"
|
size="SM"
|
||||||
theme="light"
|
theme="light"
|
||||||
text="Reset Config"
|
text={m.advanced_reset_config_button()}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
handleResetConfig();
|
handleResetConfig();
|
||||||
window.location.reload();
|
window.location.reload();
|
||||||
|
|
@ -327,22 +326,23 @@ export default function SettingsAdvancedRoute() {
|
||||||
onClose={() => {
|
onClose={() => {
|
||||||
setShowLoopbackWarning(false);
|
setShowLoopbackWarning(false);
|
||||||
}}
|
}}
|
||||||
title="Enable Loopback-Only Mode?"
|
title={m.advanced_loopback_warning_title()}
|
||||||
description={
|
description={
|
||||||
<>
|
<>
|
||||||
<p>
|
<p>
|
||||||
WARNING: This will restrict web interface access to localhost (127.0.0.1)
|
{m.advanced_loopback_warning_description()}
|
||||||
only.
|
</p>
|
||||||
|
<p>
|
||||||
|
{m.advanced_loopback_warning_before()}
|
||||||
</p>
|
</p>
|
||||||
<p>Before enabling this feature, make sure you have either:</p>
|
|
||||||
<ul className="list-disc space-y-1 pl-5 text-xs text-slate-700 dark:text-slate-300">
|
<ul className="list-disc space-y-1 pl-5 text-xs text-slate-700 dark:text-slate-300">
|
||||||
<li>SSH access configured and tested</li>
|
<li>{m.advanced_loopback_warning_ssh()}</li>
|
||||||
<li>Cloud access enabled and working</li>
|
<li>{m.advanced_loopback_warning_cloud()}</li>
|
||||||
</ul>
|
</ul>
|
||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
variant="warning"
|
variant="warning"
|
||||||
confirmText="I Understand, Enable Anyway"
|
confirmText={m.advanced_loopback_warning_confirm()}
|
||||||
onConfirm={confirmLoopbackModeEnable}
|
onConfirm={confirmLoopbackModeEnable}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue