From 8199c469e8d1746ee1369c2d9d7bbb63ef68324e Mon Sep 17 00:00:00 2001 From: Grant Pannell <300992+DigitalDJ@users.noreply.github.com> Date: Tue, 23 Dec 2025 21:51:51 +1030 Subject: [PATCH 01/15] Add option to enforce TLS by redirecting HTTP requests to HTTPS (#1092) --- config.go | 2 + go.mod | 1 + go.sum | 2 + ui/localization/messages/da.json | 2 + ui/localization/messages/de.json | 2 + ui/localization/messages/en.json | 2 + ui/localization/messages/es.json | 2 + ui/localization/messages/fr.json | 2 + ui/localization/messages/it.json | 2 + ui/localization/messages/nb.json | 2 + ui/localization/messages/sv.json | 2 + ui/localization/messages/zh.json | 2 + .../devices.$id.settings.access._index.tsx | 94 ++++++++++++------- web.go | 39 +++++++- web_tls.go | 15 ++- 15 files changed, 134 insertions(+), 37 deletions(-) diff --git a/config.go b/config.go index a06febd56..d423489d3 100644 --- a/config.go +++ b/config.go @@ -107,6 +107,7 @@ type Config struct { DisplayDimAfterSec int `json:"display_dim_after_sec"` DisplayOffAfterSec int `json:"display_off_after_sec"` TLSMode string `json:"tls_mode"` // options: "self-signed", "user-defined", "" + TLSEnforce bool `json:"tls_enforce"` UsbConfig *usbgadget.Config `json:"usb_config"` UsbDevices *usbgadget.Devices `json:"usb_devices"` NetworkConfig *types.NetworkConfig `json:"network_config"` @@ -188,6 +189,7 @@ func getDefaultConfig() Config { // This is the "Standard" jiggler option in the UI JigglerConfig: func() *JigglerConfig { c := defaultJigglerConfig; return &c }(), TLSMode: "", + TLSEnforce: false, UsbConfig: func() *usbgadget.Config { c := defaultUsbConfig; return &c }(), UsbDevices: func() *usbgadget.Devices { c := defaultUsbDevices; return &c }(), NetworkConfig: func() *types.NetworkConfig { diff --git a/go.mod b/go.mod index aac587993..18d8dbf7a 100644 --- a/go.mod +++ b/go.mod @@ -51,6 +51,7 @@ require ( github.com/davecgh/go-spew v1.1.1 // indirect github.com/gabriel-vasile/mimetype v1.4.9 // indirect github.com/gin-contrib/sse v1.1.0 // indirect + github.com/gin-gonic/contrib v0.0.0-20250521004450-2b1292699c15 // indirect github.com/go-jose/go-jose/v4 v4.1.3 // indirect github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect diff --git a/go.sum b/go.sum index 8d33b159a..47ba798c0 100644 --- a/go.sum +++ b/go.sum @@ -42,6 +42,8 @@ github.com/gin-contrib/logger v1.2.6 h1:EPolruKUTzNXMVBD9LuAFQmRjTs7AH7yKGuXgYqr github.com/gin-contrib/logger v1.2.6/go.mod h1:7niPrd7F0Nscw/zvgz8RiGJxSdbKM2yfQNy8xCHcm64= github.com/gin-contrib/sse v1.1.0 h1:n0w2GMuUpWDVp7qSpvze6fAu9iRxJY4Hmj6AmBOU05w= github.com/gin-contrib/sse v1.1.0/go.mod h1:hxRZ5gVpWMT7Z0B0gSNYqqsSCNIJMjzvm6fqCz9vjwM= +github.com/gin-gonic/contrib v0.0.0-20250521004450-2b1292699c15 h1:AoSudS8CW8Mc9rRf5sO1vBtNxr2Ok6TaAICjgg5oKUY= +github.com/gin-gonic/contrib v0.0.0-20250521004450-2b1292699c15/go.mod h1:iqneQ2Df3omzIVTkIfn7c1acsVnMGiSLn4XF5Blh3Yg= github.com/gin-gonic/gin v1.10.1 h1:T0ujvqyCSqRopADpgPgiTT63DUQVSfojyME59Ei63pQ= github.com/gin-gonic/gin v1.10.1/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y= github.com/go-co-op/gocron/v2 v2.17.0 h1:e/oj6fcAM8vOOKZxv2Cgfmjo+s8AXC46po5ZPtaSea4= diff --git a/ui/localization/messages/da.json b/ui/localization/messages/da.json index d2064532f..b5bcf08f9 100644 --- a/ui/localization/messages/da.json +++ b/ui/localization/messages/da.json @@ -19,6 +19,8 @@ "access_description": "Administrer adgangskontrollen for enheden", "access_disable_protection": "Deaktiver beskyttelse", "access_enable_password": "Aktivér adgangskode", + "access_enforce_tls_label": "TLS afdwingen", + "access_enforce_tls_description": "Alle HTTP-verzoeken doorsturen naar HTTPS", "access_failed_deregister": "Kunne ikke afregistrere enhed: {error}", "access_failed_update_cloud_url": "Kunne ikke opdatere cloud-URL: {error}", "access_failed_update_tls": "Kunne ikke opdatere TLS-indstillinger: {error}", diff --git a/ui/localization/messages/de.json b/ui/localization/messages/de.json index 326baa165..21a83d202 100644 --- a/ui/localization/messages/de.json +++ b/ui/localization/messages/de.json @@ -19,6 +19,8 @@ "access_description": "Verwalten Sie die Zugriffssteuerung Ihres Geräts", "access_disable_protection": "Schutz deaktivieren", "access_enable_password": "Kennwort aktivieren", + "access_enforce_tls_label": "TLS erzwingen", + "access_enforce_tls_description": "Alle HTTP-Anfragen auf HTTPS umleiten", "access_failed_deregister": "Abmeldung des Geräts fehlgeschlagen: {error}", "access_failed_update_cloud_url": "Fehler beim Aktualisieren der Cloud-URL: {error}", "access_failed_update_tls": "TLS-Einstellungen konnten nicht aktualisiert werden: {error}", diff --git a/ui/localization/messages/en.json b/ui/localization/messages/en.json index a36874d0c..117015f44 100644 --- a/ui/localization/messages/en.json +++ b/ui/localization/messages/en.json @@ -19,6 +19,8 @@ "access_description": "Manage the Access Control of the device", "access_disable_protection": "Disable Protection", "access_enable_password": "Enable Password", + "access_enforce_tls_label": "Enforce TLS", + "access_enforce_tls_description": "Redirect all HTTP requests to HTTPS", "access_failed_deregister": "Failed to de-register device: {error}", "access_failed_update_cloud_url": "Failed to update cloud URL: {error}", "access_failed_update_tls": "Failed to update TLS settings: {error}", diff --git a/ui/localization/messages/es.json b/ui/localization/messages/es.json index cec167b1f..79b19723c 100644 --- a/ui/localization/messages/es.json +++ b/ui/localization/messages/es.json @@ -19,6 +19,8 @@ "access_description": "Administre el control de acceso del dispositivo", "access_disable_protection": "Desactivar la protección", "access_enable_password": "Activar contraseña", + "access_enforce_tls_label": "Aplicar TLS", + "access_enforce_tls_description": "Redirigir todas las solicitudes HTTP a HTTPS", "access_failed_deregister": "No se pudo cancelar el registro del dispositivo: {error}", "access_failed_update_cloud_url": "No se pudo actualizar la URL de la nube: {error}", "access_failed_update_tls": "No se pudo actualizar la configuración de TLS: {error}", diff --git a/ui/localization/messages/fr.json b/ui/localization/messages/fr.json index b86bc160b..cb9ce8c5f 100644 --- a/ui/localization/messages/fr.json +++ b/ui/localization/messages/fr.json @@ -19,6 +19,8 @@ "access_description": "Gérer le contrôle d'accès de l'appareil", "access_disable_protection": "Désactiver la protection", "access_enable_password": "Activer le mot de passe", + "access_enforce_tls_label": "Appliquer TLS", + "access_enforce_tls_description": "Rediriger toutes les requêtes HTTP vers HTTPS", "access_failed_deregister": "Échec de la désinscription du périphérique : {error}", "access_failed_update_cloud_url": "Échec de la mise à jour de l'URL du cloud : {error}", "access_failed_update_tls": "Échec de la mise à jour des paramètres TLS : {error}", diff --git a/ui/localization/messages/it.json b/ui/localization/messages/it.json index 3fe77fedf..9d3934234 100644 --- a/ui/localization/messages/it.json +++ b/ui/localization/messages/it.json @@ -19,6 +19,8 @@ "access_description": "Gestisci il controllo degli accessi del dispositivo", "access_disable_protection": "Disattiva la protezione", "access_enable_password": "Attiva password", + "access_enforce_tls_label": "Applica TLS", + "access_enforce_tls_description": "Reindirizza tutte le richieste HTTP a HTTPS", "access_failed_deregister": "Impossibile annullare la registrazione del dispositivo: {error}", "access_failed_update_cloud_url": "Impossibile aggiornare l'URL del cloud: {error}", "access_failed_update_tls": "Impossibile aggiornare le impostazioni TLS: {error}", diff --git a/ui/localization/messages/nb.json b/ui/localization/messages/nb.json index 59c8ea64c..aa9458dc7 100644 --- a/ui/localization/messages/nb.json +++ b/ui/localization/messages/nb.json @@ -19,6 +19,8 @@ "access_description": "Administrer tilgang til enheten", "access_disable_protection": "Deaktiver beskyttelse", "access_enable_password": "Aktiver passord", + "access_enforce_tls_label": "Håndhev TLS", + "access_enforce_tls_description": "Omdiriger alle HTTP-forespørsler til HTTPS", "access_failed_deregister": "Kunne ikke avregistrere enheten: {error}", "access_failed_update_cloud_url": "Kunne ikke oppdatere nettadressen til skyen: {error}", "access_failed_update_tls": "Kunne ikke oppdatere TLS-innstillingene: {error}", diff --git a/ui/localization/messages/sv.json b/ui/localization/messages/sv.json index 17c794f30..417354793 100644 --- a/ui/localization/messages/sv.json +++ b/ui/localization/messages/sv.json @@ -19,6 +19,8 @@ "access_description": "Hantera enhetens åtkomstkontroll", "access_disable_protection": "Inaktivera skydd", "access_enable_password": "Aktivera lösenord", + "access_enforce_tls_label": "Tillämpa TLS", + "access_enforce_tls_description": "Omdirigera alla HTTP-förfrågningar till HTTPS", "access_failed_deregister": "Misslyckades med att avregistrera enheten: {error}", "access_failed_update_cloud_url": "Misslyckades med att uppdatera moln-URL: {error}", "access_failed_update_tls": "Misslyckades med att uppdatera TLS-inställningarna: {error}", diff --git a/ui/localization/messages/zh.json b/ui/localization/messages/zh.json index 9510b518a..da0189138 100644 --- a/ui/localization/messages/zh.json +++ b/ui/localization/messages/zh.json @@ -19,6 +19,8 @@ "access_description": "管理设备的访问控制。", "access_disable_protection": "禁用保护", "access_enable_password": "启用密码", + "access_enforce_tls_label": "强制执行 TLS", + "access_enforce_tls_description": "将所有 HTTP 请求重定向到 HTTPS", "access_failed_deregister": "注销设备失败:{error}", "access_failed_update_cloud_url": "更新云地址失败:{error}", "access_failed_update_tls": "更新 TLS 设置失败:{error}", diff --git a/ui/src/routes/devices.$id.settings.access._index.tsx b/ui/src/routes/devices.$id.settings.access._index.tsx index adce74c89..68ca9ef11 100644 --- a/ui/src/routes/devices.$id.settings.access._index.tsx +++ b/ui/src/routes/devices.$id.settings.access._index.tsx @@ -4,6 +4,7 @@ import { ShieldCheckIcon } from "@heroicons/react/24/outline"; import { useDeviceUiNavigation } from "@hooks/useAppNavigation"; import { JsonRpcResponse, useJsonRpc } from "@hooks/useJsonRpc"; +import { CheckboxWithLabel } from "@components/Checkbox"; import { GridCard } from "@components/Card"; import { Button, LinkButton } from "@components/Button"; import { InputFieldWithLabel } from "@components/InputField"; @@ -24,6 +25,7 @@ import { CloudState } from "./adopt"; export interface TLSState { mode: "self-signed" | "custom" | "disabled"; + enforce: boolean; certificate?: string; privateKey?: string; } @@ -54,6 +56,7 @@ export default function SettingsAccessIndexRoute() { // Use a simple string identifier for the selected provider const [selectedProvider, setSelectedProvider] = useState("jetkvm"); const [tlsMode, setTlsMode] = useState("unknown"); + const [tlsEnforce, setTlsEnforce] = useState(false); const [tlsCert, setTlsCert] = useState(""); const [tlsKey, setTlsKey] = useState(""); @@ -84,6 +87,7 @@ export default function SettingsAccessIndexRoute() { const tlsState = resp.result as TLSState; setTlsMode(tlsState.mode); + setTlsEnforce(tlsState.enforce); if (tlsState.certificate) setTlsCert(tlsState.certificate); if (tlsState.privateKey) setTlsKey(tlsState.privateKey); }); @@ -148,12 +152,13 @@ export default function SettingsAccessIndexRoute() { // Function to update TLS state - accepts a mode parameter const updateTlsState = useCallback( - (mode: string, cert?: string, key?: string) => { + (mode: string, enforce: boolean, cert?: string, key?: string) => { const state = { mode } as TLSState; if (cert && key) { state.certificate = cert; state.privateKey = key; } + state.enforce = enforce; send("setTLSState", { state }, (resp: JsonRpcResponse) => { if ("error" in resp) { @@ -172,10 +177,11 @@ export default function SettingsAccessIndexRoute() { // Handle TLS mode change const handleTlsModeChange = (value: string) => { setTlsMode(value); + setTlsEnforce(value === "disabled" ? false : tlsEnforce); // For "disabled" and "self-signed" modes, immediately apply the settings if (value !== "custom") { - updateTlsState(value); + updateTlsState(value, tlsEnforce); } }; @@ -187,9 +193,17 @@ export default function SettingsAccessIndexRoute() { setTlsKey(value); }; + const handleTlsEnforceChange = (value: boolean) => { + setTlsEnforce(value); + // For "disabled" and "self-signed" modes, immediately apply the settings + if (tlsMode !== "custom") { + updateTlsState(tlsMode, value); + } + }; + // Update the custom TLS settings button click handler const handleCustomTlsUpdate = () => { - updateTlsState(tlsMode, tlsCert, tlsKey); + updateTlsState(tlsMode, tlsEnforce, tlsCert, tlsKey); }; // Fetch device ID and cloud state on component mount @@ -233,36 +247,50 @@ export default function SettingsAccessIndexRoute() { /> - {tlsMode === "custom" && ( - - - handleTlsCertChange(e.target.value)} - /> - handleTlsKeyChange(e.target.value)} - /> -
-
-
+ {(tlsMode === "custom" || tlsMode == "self-signed") && ( + <> + +
+ handleTlsEnforceChange(e.target.checked)} + /> +
+ {tlsMode === "custom" && ( + <> + + handleTlsCertChange(e.target.value)} + /> + handleTlsKeyChange(e.target.value)} + /> +
+
+ + )} +
+ )} Date: Wed, 24 Dec 2025 23:12:20 +1030 Subject: [PATCH 02/15] Ensure TLS Enforce can never be on when HTTPS mode is disabled (#1092) --- ui/src/routes/devices.$id.settings.access._index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/src/routes/devices.$id.settings.access._index.tsx b/ui/src/routes/devices.$id.settings.access._index.tsx index 68ca9ef11..555d5b2a5 100644 --- a/ui/src/routes/devices.$id.settings.access._index.tsx +++ b/ui/src/routes/devices.$id.settings.access._index.tsx @@ -158,7 +158,7 @@ export default function SettingsAccessIndexRoute() { state.certificate = cert; state.privateKey = key; } - state.enforce = enforce; + state.enforce = mode === "disabled" ? false : enforce; send("setTLSState", { state }, (resp: JsonRpcResponse) => { if ("error" in resp) { From ae8bddf71d85a6f459d7ef158b72d48a3f8bc77c Mon Sep 17 00:00:00 2001 From: Grant Pannell <300992+DigitalDJ@users.noreply.github.com> Date: Wed, 24 Dec 2025 23:15:27 +1030 Subject: [PATCH 03/15] Fix nesting spacing for custom TLS certificates (#1092) --- .../devices.$id.settings.access._index.tsx | 56 +++++++++---------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/ui/src/routes/devices.$id.settings.access._index.tsx b/ui/src/routes/devices.$id.settings.access._index.tsx index 555d5b2a5..226c5f20e 100644 --- a/ui/src/routes/devices.$id.settings.access._index.tsx +++ b/ui/src/routes/devices.$id.settings.access._index.tsx @@ -260,35 +260,35 @@ export default function SettingsAccessIndexRoute() { {tlsMode === "custom" && ( <> - - handleTlsCertChange(e.target.value)} - /> - handleTlsKeyChange(e.target.value)} - /> -
-
- - )} +
+
+ + )} )} From cbd44908b041bbd6ebea9d16f64093f90dee2aac Mon Sep 17 00:00:00 2001 From: Grant Pannell <300992+DigitalDJ@users.noreply.github.com> Date: Wed, 24 Dec 2025 23:19:18 +1030 Subject: [PATCH 04/15] Change flow of Enforce TLS enablement. Require pop-up acknolwedgement AND apply button. (#1092) --- ui/localization/messages/da.json | 5 +++ ui/localization/messages/de.json | 5 +++ ui/localization/messages/en.json | 5 +++ ui/localization/messages/es.json | 5 +++ ui/localization/messages/fr.json | 5 +++ ui/localization/messages/it.json | 5 +++ ui/localization/messages/nb.json | 5 +++ ui/localization/messages/sv.json | 5 +++ ui/localization/messages/zh.json | 5 +++ .../devices.$id.settings.access._index.tsx | 40 +++++++++++++++++-- 10 files changed, 81 insertions(+), 4 deletions(-) diff --git a/ui/localization/messages/da.json b/ui/localization/messages/da.json index b5bcf08f9..8c668f57c 100644 --- a/ui/localization/messages/da.json +++ b/ui/localization/messages/da.json @@ -21,6 +21,11 @@ "access_enable_password": "Aktivér adgangskode", "access_enforce_tls_label": "TLS afdwingen", "access_enforce_tls_description": "Alle HTTP-verzoeken doorsturen naar HTTPS", + "access_enforce_tls_warning_before": "Før du aktiverer denne funktion, skal du sørge for at du har:", + "access_enforce_tls_warning_confirm": "Jeg forstår, aktivér alligevel", + "access_enforce_tls_warning_description": "ADVARSEL: Dette vil begrænse webgrænsefladeadgang til kun HTTPS.", + "access_enforce_tls_warning_https": "HTTPS-tilstand er aktiveret og fungerer.", + "access_enforce_tls_warning_title": "Aktivér håndhævelse af TLS?", "access_failed_deregister": "Kunne ikke afregistrere enhed: {error}", "access_failed_update_cloud_url": "Kunne ikke opdatere cloud-URL: {error}", "access_failed_update_tls": "Kunne ikke opdatere TLS-indstillinger: {error}", diff --git a/ui/localization/messages/de.json b/ui/localization/messages/de.json index 21a83d202..28c78ef1d 100644 --- a/ui/localization/messages/de.json +++ b/ui/localization/messages/de.json @@ -21,6 +21,11 @@ "access_enable_password": "Kennwort aktivieren", "access_enforce_tls_label": "TLS erzwingen", "access_enforce_tls_description": "Alle HTTP-Anfragen auf HTTPS umleiten", + "access_enforce_tls_warning_before": "Bevor Sie diese Funktion aktivieren, stellen Sie sicher, dass Sie Folgendes haben:", + "access_enforce_tls_warning_confirm": "Ich verstehe, trotzdem aktivieren", + "access_enforce_tls_warning_description": "WARNUNG: Dadurch wird der Zugriff auf die Weboberfläche auf HTTPS beschränkt.", + "access_enforce_tls_warning_https": "Der HTTPS-Modus ist aktiviert und funktioniert.", + "access_enforce_tls_warning_title": "TLS erzwingen?", "access_failed_deregister": "Abmeldung des Geräts fehlgeschlagen: {error}", "access_failed_update_cloud_url": "Fehler beim Aktualisieren der Cloud-URL: {error}", "access_failed_update_tls": "TLS-Einstellungen konnten nicht aktualisiert werden: {error}", diff --git a/ui/localization/messages/en.json b/ui/localization/messages/en.json index 117015f44..bb46de731 100644 --- a/ui/localization/messages/en.json +++ b/ui/localization/messages/en.json @@ -21,6 +21,11 @@ "access_enable_password": "Enable Password", "access_enforce_tls_label": "Enforce TLS", "access_enforce_tls_description": "Redirect all HTTP requests to HTTPS", + "access_enforce_tls_warning_before": "Before enabling this feature, make sure you have:", + "access_enforce_tls_warning_confirm": "I Understand, Enable Anyway.", + "access_enforce_tls_warning_description": "WARNING: This will restrict web interface access to HTTPS only.", + "access_enforce_tls_warning_https": "HTTPS mode is enabled and working.", + "access_enforce_tls_warning_title": "Enable Enforce TLS?", "access_failed_deregister": "Failed to de-register device: {error}", "access_failed_update_cloud_url": "Failed to update cloud URL: {error}", "access_failed_update_tls": "Failed to update TLS settings: {error}", diff --git a/ui/localization/messages/es.json b/ui/localization/messages/es.json index 79b19723c..93a34a21f 100644 --- a/ui/localization/messages/es.json +++ b/ui/localization/messages/es.json @@ -21,6 +21,11 @@ "access_enable_password": "Activar contraseña", "access_enforce_tls_label": "Aplicar TLS", "access_enforce_tls_description": "Redirigir todas las solicitudes HTTP a HTTPS", + "access_enforce_tls_warning_before": "Antes de habilitar esta función, asegúrese de tener:", + "access_enforce_tls_warning_confirm": "Entiendo, habilitar de todas formas", + "access_enforce_tls_warning_description": "ADVERTENCIA: Esto restringirá el acceso a la interfaz web a HTTPS únicamente.", + "access_enforce_tls_warning_https": "El modo HTTPS está habilitado y funcionando.", + "access_enforce_tls_warning_title": "¿Habilitar Aplicar TLS?", "access_failed_deregister": "No se pudo cancelar el registro del dispositivo: {error}", "access_failed_update_cloud_url": "No se pudo actualizar la URL de la nube: {error}", "access_failed_update_tls": "No se pudo actualizar la configuración de TLS: {error}", diff --git a/ui/localization/messages/fr.json b/ui/localization/messages/fr.json index cb9ce8c5f..39e18a353 100644 --- a/ui/localization/messages/fr.json +++ b/ui/localization/messages/fr.json @@ -21,6 +21,11 @@ "access_enable_password": "Activer le mot de passe", "access_enforce_tls_label": "Appliquer TLS", "access_enforce_tls_description": "Rediriger toutes les requêtes HTTP vers HTTPS", + "access_enforce_tls_warning_before": "Avant d'activer cette fonctionnalité, assurez-vous d'avoir :", + "access_enforce_tls_warning_confirm": "Je comprends, j'active quand même", + "access_enforce_tls_warning_description": "AVERTISSEMENT : Ceci limitera l’accès à l’interface Web au protocole HTTPS uniquement.", + "access_enforce_tls_warning_https": "Le mode HTTPS est activé et fonctionnel.", + "access_enforce_tls_warning_title": "Activer l'application du protocole TLS ?", "access_failed_deregister": "Échec de la désinscription du périphérique : {error}", "access_failed_update_cloud_url": "Échec de la mise à jour de l'URL du cloud : {error}", "access_failed_update_tls": "Échec de la mise à jour des paramètres TLS : {error}", diff --git a/ui/localization/messages/it.json b/ui/localization/messages/it.json index 9d3934234..796d90229 100644 --- a/ui/localization/messages/it.json +++ b/ui/localization/messages/it.json @@ -21,6 +21,11 @@ "access_enable_password": "Attiva password", "access_enforce_tls_label": "Applica TLS", "access_enforce_tls_description": "Reindirizza tutte le richieste HTTP a HTTPS", + "access_enforce_tls_warning_before": "Prima di abilitare questa funzione, assicurati di avere:", + "access_enforce_tls_warning_confirm": "Capisco, abilita comunque", + "access_enforce_tls_warning_description": "ATTENZIONE: questo limiterà l'accesso all'interfaccia web solo a HTTPS.", + "access_enforce_tls_warning_https": "La modalità HTTPS è abilitata e funzionante.", + "access_enforce_tls_warning_title": "Abilitare l'opzione Applica TLS?", "access_failed_deregister": "Impossibile annullare la registrazione del dispositivo: {error}", "access_failed_update_cloud_url": "Impossibile aggiornare l'URL del cloud: {error}", "access_failed_update_tls": "Impossibile aggiornare le impostazioni TLS: {error}", diff --git a/ui/localization/messages/nb.json b/ui/localization/messages/nb.json index aa9458dc7..0fb0383aa 100644 --- a/ui/localization/messages/nb.json +++ b/ui/localization/messages/nb.json @@ -21,6 +21,11 @@ "access_enable_password": "Aktiver passord", "access_enforce_tls_label": "Håndhev TLS", "access_enforce_tls_description": "Omdiriger alle HTTP-forespørsler til HTTPS", + "access_enforce_tls_warning_before": "Før du aktiverer denne funksjonen, må du sørge for at du har:", + "access_enforce_tls_warning_confirm": "Jeg forstår, aktiver uansett", + "access_enforce_tls_warning_description": "ADVARSEL: Dette vil begrense tilgangen til webgrensesnittet til kun HTTPS.", + "access_enforce_tls_warning_https": "HTTPS-modus er aktivert og fungerer.", + "access_enforce_tls_warning_title": "Aktiver håndhevelse av TLS?", "access_failed_deregister": "Kunne ikke avregistrere enheten: {error}", "access_failed_update_cloud_url": "Kunne ikke oppdatere nettadressen til skyen: {error}", "access_failed_update_tls": "Kunne ikke oppdatere TLS-innstillingene: {error}", diff --git a/ui/localization/messages/sv.json b/ui/localization/messages/sv.json index 417354793..a67cf1f3d 100644 --- a/ui/localization/messages/sv.json +++ b/ui/localization/messages/sv.json @@ -21,6 +21,11 @@ "access_enable_password": "Aktivera lösenord", "access_enforce_tls_label": "Tillämpa TLS", "access_enforce_tls_description": "Omdirigera alla HTTP-förfrågningar till HTTPS", + "access_enforce_tls_warning_before": "Innan du aktiverar den här funktionen, se till att du har:", + "access_enforce_tls_warning_confirm": "Jag förstår, aktivera ändå", + "access_enforce_tls_warning_description": "VARNING: Detta begränsar åtkomsten till webbgränssnittet till endast HTTPS.", + "access_enforce_tls_warning_https": "HTTPS-läget är aktiverat och fungerar.", + "access_enforce_tls_warning_title": "Aktivera TLS?", "access_failed_deregister": "Misslyckades med att avregistrera enheten: {error}", "access_failed_update_cloud_url": "Misslyckades med att uppdatera moln-URL: {error}", "access_failed_update_tls": "Misslyckades med att uppdatera TLS-inställningarna: {error}", diff --git a/ui/localization/messages/zh.json b/ui/localization/messages/zh.json index da0189138..a1fb4d38c 100644 --- a/ui/localization/messages/zh.json +++ b/ui/localization/messages/zh.json @@ -21,6 +21,11 @@ "access_enable_password": "启用密码", "access_enforce_tls_label": "强制执行 TLS", "access_enforce_tls_description": "将所有 HTTP 请求重定向到 HTTPS", + "access_enforce_tls_warning_before": "启用此功能前,请确保您已具备以下条件:", + "access_enforce_tls_warning_confirm": "我已了解,确认启用", + "access_enforce_tls_warning_description": "警告:这将限制网页界面仅支持 HTTPS 访问。", + "access_enforce_tls_warning_https": "HTTPS模式已启用并正常工作。", + "access_enforce_tls_warning_title": "启用强制 TLS?", "access_failed_deregister": "注销设备失败:{error}", "access_failed_update_cloud_url": "更新云地址失败:{error}", "access_failed_update_tls": "更新 TLS 设置失败:{error}", diff --git a/ui/src/routes/devices.$id.settings.access._index.tsx b/ui/src/routes/devices.$id.settings.access._index.tsx index 226c5f20e..ce8b28277 100644 --- a/ui/src/routes/devices.$id.settings.access._index.tsx +++ b/ui/src/routes/devices.$id.settings.access._index.tsx @@ -5,6 +5,7 @@ import { ShieldCheckIcon } from "@heroicons/react/24/outline"; import { useDeviceUiNavigation } from "@hooks/useAppNavigation"; import { JsonRpcResponse, useJsonRpc } from "@hooks/useJsonRpc"; import { CheckboxWithLabel } from "@components/Checkbox"; +import { ConfirmDialog } from "@components/ConfirmDialog"; import { GridCard } from "@components/Card"; import { Button, LinkButton } from "@components/Button"; import { InputFieldWithLabel } from "@components/InputField"; @@ -59,6 +60,7 @@ export default function SettingsAccessIndexRoute() { const [tlsEnforce, setTlsEnforce] = useState(false); const [tlsCert, setTlsCert] = useState(""); const [tlsKey, setTlsKey] = useState(""); + const [showTlsEnforceWarning, setShowTlsEnforceWarning] = useState(false); const getCloudState = useCallback(() => { send("getCloudState", {}, (resp: JsonRpcResponse) => { @@ -194,13 +196,24 @@ export default function SettingsAccessIndexRoute() { }; const handleTlsEnforceChange = (value: boolean) => { - setTlsEnforce(value); - // For "disabled" and "self-signed" modes, immediately apply the settings - if (tlsMode !== "custom") { - updateTlsState(tlsMode, value); + // If trying to enable Enforce TLS, show warning first + if (value) { + setShowTlsEnforceWarning(true); + } + else { + setTlsEnforce(value); + // If HTTPS Mode is off, instantly disable Enforce TLS + if (tlsMode === "disabled") { + updateTlsState(tlsMode, value); + } } }; + const confirmTlsEnforceEnable = () => { + setTlsEnforce(true); + setShowTlsEnforceWarning(false); + }; + // Update the custom TLS settings button click handler const handleCustomTlsUpdate = () => { updateTlsState(tlsMode, tlsEnforce, tlsCert, tlsKey); @@ -290,6 +303,25 @@ export default function SettingsAccessIndexRoute() { )} + { + setShowTlsEnforceWarning(false); + }} + title={m.access_enforce_tls_warning_title()} + description={ + <> +

{m.access_enforce_tls_warning_description()}

+

{m.access_enforce_tls_warning_before()}

+
    +
  • {m.access_enforce_tls_warning_https()}
  • +
+ + } + variant="warning" + confirmText={m.access_enforce_tls_warning_confirm()} + onConfirm={confirmTlsEnforceEnable} + /> )} From 7fbd475d2ff505ed288fc4d4a9f2f551008e387a Mon Sep 17 00:00:00 2001 From: Grant Pannell <300992+DigitalDJ@users.noreply.github.com> Date: Wed, 24 Dec 2025 23:22:55 +1030 Subject: [PATCH 05/15] Fix web secure server not fully shutting down due to waiting on stopTLS channel. --- web_tls.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/web_tls.go b/web_tls.go index 1148be636..704c64fb9 100644 --- a/web_tls.go +++ b/web_tls.go @@ -207,6 +207,8 @@ func stopWebSecureServer() { return } stopTLS <- struct{}{} + close(stopTLS) + stopTLS = make(chan struct{}) } func startWebSecureServer() { From f72a4de98399189eac495fee93e68e3e2cfce683 Mon Sep 17 00:00:00 2001 From: Grant Pannell <300992+DigitalDJ@users.noreply.github.com> Date: Wed, 24 Dec 2025 23:26:43 +1030 Subject: [PATCH 06/15] Be more clear about setupRouter argument; don't pass config down, use directly. (#1092) --- web.go | 8 ++++---- web_tls.go | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/web.go b/web.go index 80af20349..a79f8d63b 100644 --- a/web.go +++ b/web.go @@ -74,7 +74,7 @@ var cachableFileExtensions = []string{ ".jpg", ".jpeg", ".png", ".svg", ".gif", ".webp", ".ico", ".woff2", } -func setupRouter(secureRedirect bool) *gin.Engine { +func setupRouter(isSecureServer bool) *gin.Engine { gin.SetMode(gin.ReleaseMode) gin.DisableConsoleColor() r := gin.Default() @@ -84,7 +84,7 @@ func setupRouter(secureRedirect bool) *gin.Engine { }), )) - if secureRedirect { + if !isSecureServer && config.TLSEnforce { r.Use(secure.Secure(secure.Options{ AllowedHosts: []string{}, SSLRedirect: true, @@ -586,7 +586,7 @@ var ( ) func RunWebServer() { - r := setupRouter(config.TLSMode != "" && config.TLSEnforce) + r := setupRouter(false) // Determine the binding address based on the config var bindAddress string @@ -620,7 +620,7 @@ func RunWebServer() { go func() { for range updateWebRouter { - server.Handler = setupRouter(config.TLSMode != "" && config.TLSEnforce) + server.Handler = setupRouter(false) } }() diff --git a/web_tls.go b/web_tls.go index 704c64fb9..67ea0da69 100644 --- a/web_tls.go +++ b/web_tls.go @@ -172,7 +172,7 @@ func runWebSecureServer() { tlsStarted = false }() - r := setupRouter(false) + r := setupRouter(true) server := &http.Server{ Addr: webSecureListen, From ce200438ce15ccaa143d685be37551b2f24ca616 Mon Sep 17 00:00:00 2001 From: Grant Pannell <300992+DigitalDJ@users.noreply.github.com> Date: Wed, 24 Dec 2025 23:28:02 +1030 Subject: [PATCH 07/15] Disable use of HSTS (#1092) --- web.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/web.go b/web.go index a79f8d63b..cbe6c2987 100644 --- a/web.go +++ b/web.go @@ -90,8 +90,8 @@ func setupRouter(isSecureServer bool) *gin.Engine { SSLRedirect: true, SSLHost: "", SSLProxyHeaders: map[string]string{"X-Forwarded-Proto": "https"}, - STSSeconds: 315360000, - STSIncludeSubdomains: true, + STSSeconds: 0, + STSIncludeSubdomains: false, FrameDeny: true, ContentTypeNosniff: true, BrowserXssFilter: true, From 897dde807553d1af667c5d5c10a6856e48d05c4c Mon Sep 17 00:00:00 2001 From: Grant Pannell <300992+DigitalDJ@users.noreply.github.com> Date: Wed, 24 Dec 2025 23:30:21 +1030 Subject: [PATCH 08/15] Delay handler swap when turning on TLS enforce to allow any pending WebRTC setting changes. (#1092) --- web.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/web.go b/web.go index cbe6c2987..9a3e99a2f 100644 --- a/web.go +++ b/web.go @@ -620,6 +620,9 @@ func RunWebServer() { go func() { for range updateWebRouter { + if config.TLSEnforce { + time.Sleep(3 * time.Second) + } server.Handler = setupRouter(false) } }() From 779fcaae07d473b5b0cbd70f49a7cc23eb44c992 Mon Sep 17 00:00:00 2001 From: Grant Pannell <300992+DigitalDJ@users.noreply.github.com> Date: Wed, 24 Dec 2025 23:33:09 +1030 Subject: [PATCH 09/15] Close update router channel on web server close (#1092) --- web.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/web.go b/web.go index 9a3e99a2f..cca4878ba 100644 --- a/web.go +++ b/web.go @@ -631,6 +631,8 @@ func RunWebServer() { if !errors.Is(err, http.ErrServerClosed) { panic(err) } + + close(updateWebRouter) } func handleDevice(c *gin.Context) { From 2cef0eae09ed77e09a2607536de538972e57e98b Mon Sep 17 00:00:00 2001 From: Grant Pannell <300992+DigitalDJ@users.noreply.github.com> Date: Wed, 24 Dec 2025 23:35:42 +1030 Subject: [PATCH 10/15] Fix getTLSState check TLSMode string "disabled" - config uses empty string to identify disabled. Default to disabled. (#1092) --- web_tls.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/web_tls.go b/web_tls.go index 67ea0da69..87251585b 100644 --- a/web_tls.go +++ b/web_tls.go @@ -71,10 +71,9 @@ func getTLSState() TLSState { s := TLSState{} s.Enforce = config.TLSEnforce + s.Mode = "disabled" switch config.TLSMode { - case "disabled": - s.Mode = "disabled" case "custom": s.Mode = "custom" cert := certStore.GetCertificate(webSecureCustomCertificateName) From 19e29bdbafcc3a8dab14b618a082910a168419d5 Mon Sep 17 00:00:00 2001 From: Grant Pannell <300992+DigitalDJ@users.noreply.github.com> Date: Wed, 24 Dec 2025 23:39:48 +1030 Subject: [PATCH 11/15] Be more defensive about enforcing TLS. Ensure TLS is successfully enabled before enforcing. (#1092) --- web_tls.go | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/web_tls.go b/web_tls.go index 87251585b..dabf24b64 100644 --- a/web_tls.go +++ b/web_tls.go @@ -70,7 +70,7 @@ func getCertificate(info *tls.ClientHelloInfo) (*tls.Certificate, error) { func getTLSState() TLSState { s := TLSState{} - s.Enforce = config.TLSEnforce + canEnforce := false s.Mode = "disabled" switch config.TLSMode { @@ -89,19 +89,21 @@ func getTLSState() TLSState { certPEM = append(certPEM, pem.EncodeToMemory(&block)...) } s.Certificate = string(certPEM) + canEnforce = true } case "self-signed": s.Mode = "self-signed" + canEnforce = true } + s.Enforce = canEnforce && config.TLSEnforce + return s } func setTLSState(s TLSState) error { var isChanged = false - var oldEnforce = config.TLSEnforce - - config.TLSEnforce = s.Enforce + oldEnforce := config.TLSEnforce switch s.Mode { case "disabled": @@ -124,11 +126,13 @@ func setTLSState(s TLSState) error { return fmt.Errorf("failed to save certificate: %w", err) } config.TLSMode = "custom" + config.TLSEnforce = s.Enforce case "self-signed": if config.TLSMode == "" { isChanged = true } config.TLSMode = "self-signed" + config.TLSEnforce = s.Enforce default: return fmt.Errorf("invalid TLS mode: %s", s.Mode) } From 96276d46f50db68f2507e331b4e2e32d5b8d21b3 Mon Sep 17 00:00:00 2001 From: Grant Pannell <300992+DigitalDJ@users.noreply.github.com> Date: Wed, 31 Dec 2025 19:45:48 +1030 Subject: [PATCH 12/15] Update translations to be more consistent for Enforce TLS. Change Enforce TLS to Enforce HTTP (TLS). --- ui/localization/messages/da.json | 12 ++++++------ ui/localization/messages/de.json | 12 ++++++------ ui/localization/messages/en.json | 4 ++-- ui/localization/messages/es.json | 8 ++++---- ui/localization/messages/fr.json | 10 +++++----- ui/localization/messages/it.json | 12 ++++++------ ui/localization/messages/nb.json | 10 +++++----- ui/localization/messages/sv.json | 8 ++++---- ui/localization/messages/zh.json | 12 ++++++------ 9 files changed, 44 insertions(+), 44 deletions(-) diff --git a/ui/localization/messages/da.json b/ui/localization/messages/da.json index 8c668f57c..b930b0d25 100644 --- a/ui/localization/messages/da.json +++ b/ui/localization/messages/da.json @@ -19,13 +19,13 @@ "access_description": "Administrer adgangskontrollen for enheden", "access_disable_protection": "Deaktiver beskyttelse", "access_enable_password": "Aktivér adgangskode", - "access_enforce_tls_label": "TLS afdwingen", - "access_enforce_tls_description": "Alle HTTP-verzoeken doorsturen naar HTTPS", - "access_enforce_tls_warning_before": "Før du aktiverer denne funktion, skal du sørge for at du har:", - "access_enforce_tls_warning_confirm": "Jeg forstår, aktivér alligevel", - "access_enforce_tls_warning_description": "ADVARSEL: Dette vil begrænse webgrænsefladeadgang til kun HTTPS.", + "access_enforce_tls_label": "Håndhæve HTTPS (TLS)", + "access_enforce_tls_description": "Omdiriger alle HTTP-anmodninger til HTTPS", + "access_enforce_tls_warning_before": "Før du aktiverer denne funktion, skal du sikre dig, at du har:", + "access_enforce_tls_warning_confirm": "Jeg forstår, aktiver alligevel.", + "access_enforce_tls_warning_description": "ADVARSEL: Dette vil begrænse adgangen til webgrænsefladen til kun HTTPS.", "access_enforce_tls_warning_https": "HTTPS-tilstand er aktiveret og fungerer.", - "access_enforce_tls_warning_title": "Aktivér håndhævelse af TLS?", + "access_enforce_tls_warning_title": "Vil du aktivere håndhæv HTTPS (TLS)?", "access_failed_deregister": "Kunne ikke afregistrere enhed: {error}", "access_failed_update_cloud_url": "Kunne ikke opdatere cloud-URL: {error}", "access_failed_update_tls": "Kunne ikke opdatere TLS-indstillinger: {error}", diff --git a/ui/localization/messages/de.json b/ui/localization/messages/de.json index 28c78ef1d..54fe5c0ad 100644 --- a/ui/localization/messages/de.json +++ b/ui/localization/messages/de.json @@ -19,13 +19,13 @@ "access_description": "Verwalten Sie die Zugriffssteuerung Ihres Geräts", "access_disable_protection": "Schutz deaktivieren", "access_enable_password": "Kennwort aktivieren", - "access_enforce_tls_label": "TLS erzwingen", - "access_enforce_tls_description": "Alle HTTP-Anfragen auf HTTPS umleiten", - "access_enforce_tls_warning_before": "Bevor Sie diese Funktion aktivieren, stellen Sie sicher, dass Sie Folgendes haben:", - "access_enforce_tls_warning_confirm": "Ich verstehe, trotzdem aktivieren", - "access_enforce_tls_warning_description": "WARNUNG: Dadurch wird der Zugriff auf die Weboberfläche auf HTTPS beschränkt.", + "access_enforce_tls_label": "HTTPS (TLS) erzwingen", + "access_enforce_tls_description": "Leiten Sie alle HTTP-Anfragen auf HTTPS um", + "access_enforce_tls_warning_before": "Bevor Sie diese Funktion aktivieren, stellen Sie sicher, dass Sie über Folgendes verfügen:", + "access_enforce_tls_warning_confirm": "Ich verstehe, aktivieren Sie es trotzdem.", + "access_enforce_tls_warning_description": "WARNUNG: Dadurch wird der Zugriff auf die Webschnittstelle nur auf HTTPS beschränkt.", "access_enforce_tls_warning_https": "Der HTTPS-Modus ist aktiviert und funktioniert.", - "access_enforce_tls_warning_title": "TLS erzwingen?", + "access_enforce_tls_warning_title": "HTTPS (TLS) erzwingen aktivieren?", "access_failed_deregister": "Abmeldung des Geräts fehlgeschlagen: {error}", "access_failed_update_cloud_url": "Fehler beim Aktualisieren der Cloud-URL: {error}", "access_failed_update_tls": "TLS-Einstellungen konnten nicht aktualisiert werden: {error}", diff --git a/ui/localization/messages/en.json b/ui/localization/messages/en.json index bb46de731..7ec2d7e82 100644 --- a/ui/localization/messages/en.json +++ b/ui/localization/messages/en.json @@ -19,13 +19,13 @@ "access_description": "Manage the Access Control of the device", "access_disable_protection": "Disable Protection", "access_enable_password": "Enable Password", - "access_enforce_tls_label": "Enforce TLS", + "access_enforce_tls_label": "Enforce HTTPS (TLS)", "access_enforce_tls_description": "Redirect all HTTP requests to HTTPS", "access_enforce_tls_warning_before": "Before enabling this feature, make sure you have:", "access_enforce_tls_warning_confirm": "I Understand, Enable Anyway.", "access_enforce_tls_warning_description": "WARNING: This will restrict web interface access to HTTPS only.", "access_enforce_tls_warning_https": "HTTPS mode is enabled and working.", - "access_enforce_tls_warning_title": "Enable Enforce TLS?", + "access_enforce_tls_warning_title": "Enable Enforce HTTPS (TLS)?", "access_failed_deregister": "Failed to de-register device: {error}", "access_failed_update_cloud_url": "Failed to update cloud URL: {error}", "access_failed_update_tls": "Failed to update TLS settings: {error}", diff --git a/ui/localization/messages/es.json b/ui/localization/messages/es.json index 93a34a21f..e6b9d98cc 100644 --- a/ui/localization/messages/es.json +++ b/ui/localization/messages/es.json @@ -19,13 +19,13 @@ "access_description": "Administre el control de acceso del dispositivo", "access_disable_protection": "Desactivar la protección", "access_enable_password": "Activar contraseña", - "access_enforce_tls_label": "Aplicar TLS", + "access_enforce_tls_label": "Aplicar HTTPS (TLS)", "access_enforce_tls_description": "Redirigir todas las solicitudes HTTP a HTTPS", "access_enforce_tls_warning_before": "Antes de habilitar esta función, asegúrese de tener:", - "access_enforce_tls_warning_confirm": "Entiendo, habilitar de todas formas", - "access_enforce_tls_warning_description": "ADVERTENCIA: Esto restringirá el acceso a la interfaz web a HTTPS únicamente.", + "access_enforce_tls_warning_confirm": "Entiendo, habilítelo de todos modos.", + "access_enforce_tls_warning_description": "ADVERTENCIA: Esto restringirá el acceso a la interfaz web solo a HTTPS.", "access_enforce_tls_warning_https": "El modo HTTPS está habilitado y funcionando.", - "access_enforce_tls_warning_title": "¿Habilitar Aplicar TLS?", + "access_enforce_tls_warning_title": "¿Habilitar aplicar HTTPS (TLS)?", "access_failed_deregister": "No se pudo cancelar el registro del dispositivo: {error}", "access_failed_update_cloud_url": "No se pudo actualizar la URL de la nube: {error}", "access_failed_update_tls": "No se pudo actualizar la configuración de TLS: {error}", diff --git a/ui/localization/messages/fr.json b/ui/localization/messages/fr.json index 39e18a353..7c011e697 100644 --- a/ui/localization/messages/fr.json +++ b/ui/localization/messages/fr.json @@ -19,13 +19,13 @@ "access_description": "Gérer le contrôle d'accès de l'appareil", "access_disable_protection": "Désactiver la protection", "access_enable_password": "Activer le mot de passe", - "access_enforce_tls_label": "Appliquer TLS", + "access_enforce_tls_label": "Appliquer HTTPS (TLS)", "access_enforce_tls_description": "Rediriger toutes les requêtes HTTP vers HTTPS", "access_enforce_tls_warning_before": "Avant d'activer cette fonctionnalité, assurez-vous d'avoir :", - "access_enforce_tls_warning_confirm": "Je comprends, j'active quand même", - "access_enforce_tls_warning_description": "AVERTISSEMENT : Ceci limitera l’accès à l’interface Web au protocole HTTPS uniquement.", - "access_enforce_tls_warning_https": "Le mode HTTPS est activé et fonctionnel.", - "access_enforce_tls_warning_title": "Activer l'application du protocole TLS ?", + "access_enforce_tls_warning_confirm": "Je comprends, activez quand même.", + "access_enforce_tls_warning_description": "AVERTISSEMENT : cela limitera l'accès à l'interface Web au HTTPS uniquement.", + "access_enforce_tls_warning_https": "Le mode HTTPS est activé et fonctionne.", + "access_enforce_tls_warning_title": "Activer Appliquer HTTPS (TLS) ?", "access_failed_deregister": "Échec de la désinscription du périphérique : {error}", "access_failed_update_cloud_url": "Échec de la mise à jour de l'URL du cloud : {error}", "access_failed_update_tls": "Échec de la mise à jour des paramètres TLS : {error}", diff --git a/ui/localization/messages/it.json b/ui/localization/messages/it.json index 796d90229..49a021147 100644 --- a/ui/localization/messages/it.json +++ b/ui/localization/messages/it.json @@ -19,13 +19,13 @@ "access_description": "Gestisci il controllo degli accessi del dispositivo", "access_disable_protection": "Disattiva la protezione", "access_enable_password": "Attiva password", - "access_enforce_tls_label": "Applica TLS", - "access_enforce_tls_description": "Reindirizza tutte le richieste HTTP a HTTPS", + "access_enforce_tls_label": "Applica HTTPS (TLS)", + "access_enforce_tls_description": "Reindirizzare tutte le richieste HTTP su HTTPS", "access_enforce_tls_warning_before": "Prima di abilitare questa funzione, assicurati di avere:", - "access_enforce_tls_warning_confirm": "Capisco, abilita comunque", - "access_enforce_tls_warning_description": "ATTENZIONE: questo limiterà l'accesso all'interfaccia web solo a HTTPS.", - "access_enforce_tls_warning_https": "La modalità HTTPS è abilitata e funzionante.", - "access_enforce_tls_warning_title": "Abilitare l'opzione Applica TLS?", + "access_enforce_tls_warning_confirm": "Ho capito, attiva comunque.", + "access_enforce_tls_warning_description": "ATTENZIONE: ciò limiterà l'accesso all'interfaccia web solo a HTTPS.", + "access_enforce_tls_warning_https": "La modalità HTTPS è abilitata e funziona.", + "access_enforce_tls_warning_title": "Abilitare l'applicazione HTTPS (TLS)?", "access_failed_deregister": "Impossibile annullare la registrazione del dispositivo: {error}", "access_failed_update_cloud_url": "Impossibile aggiornare l'URL del cloud: {error}", "access_failed_update_tls": "Impossibile aggiornare le impostazioni TLS: {error}", diff --git a/ui/localization/messages/nb.json b/ui/localization/messages/nb.json index 0fb0383aa..c8e66faae 100644 --- a/ui/localization/messages/nb.json +++ b/ui/localization/messages/nb.json @@ -19,13 +19,13 @@ "access_description": "Administrer tilgang til enheten", "access_disable_protection": "Deaktiver beskyttelse", "access_enable_password": "Aktiver passord", - "access_enforce_tls_label": "Håndhev TLS", + "access_enforce_tls_label": "Håndheve HTTPS (TLS)", "access_enforce_tls_description": "Omdiriger alle HTTP-forespørsler til HTTPS", - "access_enforce_tls_warning_before": "Før du aktiverer denne funksjonen, må du sørge for at du har:", - "access_enforce_tls_warning_confirm": "Jeg forstår, aktiver uansett", - "access_enforce_tls_warning_description": "ADVARSEL: Dette vil begrense tilgangen til webgrensesnittet til kun HTTPS.", + "access_enforce_tls_warning_before": "Før du aktiverer denne funksjonen, sørg for at du har:", + "access_enforce_tls_warning_confirm": "Jeg forstår, aktiver uansett.", + "access_enforce_tls_warning_description": "ADVARSEL: Dette vil begrense tilgangen til nettgrensesnittet kun til HTTPS.", "access_enforce_tls_warning_https": "HTTPS-modus er aktivert og fungerer.", - "access_enforce_tls_warning_title": "Aktiver håndhevelse av TLS?", + "access_enforce_tls_warning_title": "Vil du aktivere håndheve HTTPS (TLS)?", "access_failed_deregister": "Kunne ikke avregistrere enheten: {error}", "access_failed_update_cloud_url": "Kunne ikke oppdatere nettadressen til skyen: {error}", "access_failed_update_tls": "Kunne ikke oppdatere TLS-innstillingene: {error}", diff --git a/ui/localization/messages/sv.json b/ui/localization/messages/sv.json index a67cf1f3d..81268da0a 100644 --- a/ui/localization/messages/sv.json +++ b/ui/localization/messages/sv.json @@ -19,13 +19,13 @@ "access_description": "Hantera enhetens åtkomstkontroll", "access_disable_protection": "Inaktivera skydd", "access_enable_password": "Aktivera lösenord", - "access_enforce_tls_label": "Tillämpa TLS", + "access_enforce_tls_label": "Framtvinga HTTPS (TLS)", "access_enforce_tls_description": "Omdirigera alla HTTP-förfrågningar till HTTPS", "access_enforce_tls_warning_before": "Innan du aktiverar den här funktionen, se till att du har:", - "access_enforce_tls_warning_confirm": "Jag förstår, aktivera ändå", - "access_enforce_tls_warning_description": "VARNING: Detta begränsar åtkomsten till webbgränssnittet till endast HTTPS.", + "access_enforce_tls_warning_confirm": "Jag förstår, aktivera ändå.", + "access_enforce_tls_warning_description": "VARNING: Detta begränsar webbgränssnittsåtkomsten till endast HTTPS.", "access_enforce_tls_warning_https": "HTTPS-läget är aktiverat och fungerar.", - "access_enforce_tls_warning_title": "Aktivera TLS?", + "access_enforce_tls_warning_title": "Aktivera Enforce HTTPS (TLS)?", "access_failed_deregister": "Misslyckades med att avregistrera enheten: {error}", "access_failed_update_cloud_url": "Misslyckades med att uppdatera moln-URL: {error}", "access_failed_update_tls": "Misslyckades med att uppdatera TLS-inställningarna: {error}", diff --git a/ui/localization/messages/zh.json b/ui/localization/messages/zh.json index a1fb4d38c..e5efe7a29 100644 --- a/ui/localization/messages/zh.json +++ b/ui/localization/messages/zh.json @@ -19,13 +19,13 @@ "access_description": "管理设备的访问控制。", "access_disable_protection": "禁用保护", "access_enable_password": "启用密码", - "access_enforce_tls_label": "强制执行 TLS", + "access_enforce_tls_label": "强制执行 HTTPS (TLS)", "access_enforce_tls_description": "将所有 HTTP 请求重定向到 HTTPS", - "access_enforce_tls_warning_before": "启用此功能前,请确保您已具备以下条件:", - "access_enforce_tls_warning_confirm": "我已了解,确认启用", - "access_enforce_tls_warning_description": "警告:这将限制网页界面仅支持 HTTPS 访问。", - "access_enforce_tls_warning_https": "HTTPS模式已启用并正常工作。", - "access_enforce_tls_warning_title": "启用强制 TLS?", + "access_enforce_tls_warning_before": "在启用此功能之前,请确保您拥有:", + "access_enforce_tls_warning_confirm": "我明白了,无论如何启用。", + "access_enforce_tls_warning_description": "警告:这将限制 Web 界面仅访问 HTTPS。", + "access_enforce_tls_warning_https": "HTTPS 模式已启用并正在运行。", + "access_enforce_tls_warning_title": "启用强制 HTTPS (TLS)?", "access_failed_deregister": "注销设备失败:{error}", "access_failed_update_cloud_url": "更新云地址失败:{error}", "access_failed_update_tls": "更新 TLS 设置失败:{error}", From f882abcb7a4f0c6740a11b24b3d2c5f15f1044cc Mon Sep 17 00:00:00 2001 From: Grant Pannell <300992+DigitalDJ@users.noreply.github.com> Date: Wed, 31 Dec 2025 19:46:26 +1030 Subject: [PATCH 13/15] Allow UI to be IFRAME'd when using HTTPS --- web.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web.go b/web.go index cca4878ba..3480e9f4c 100644 --- a/web.go +++ b/web.go @@ -92,7 +92,7 @@ func setupRouter(isSecureServer bool) *gin.Engine { SSLProxyHeaders: map[string]string{"X-Forwarded-Proto": "https"}, STSSeconds: 0, STSIncludeSubdomains: false, - FrameDeny: true, + FrameDeny: false, ContentTypeNosniff: true, BrowserXssFilter: true, ContentSecurityPolicy: "default-src 'self'", From 93e5697cdfee3ce8ceae94a4b612fa3f8e1ad629 Mon Sep 17 00:00:00 2001 From: Grant Pannell <300992+DigitalDJ@users.noreply.github.com> Date: Wed, 31 Dec 2025 19:47:38 +1030 Subject: [PATCH 14/15] Clarify use of isChanged and re-route HTTP server after we signal the HTTPS server to start. (#1092) --- web_tls.go | 33 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/web_tls.go b/web_tls.go index dabf24b64..97b0c28f1 100644 --- a/web_tls.go +++ b/web_tls.go @@ -102,19 +102,19 @@ func getTLSState() TLSState { } func setTLSState(s TLSState) error { - var isChanged = false + var signalSecure = false oldEnforce := config.TLSEnforce switch s.Mode { case "disabled": if config.TLSMode != "" { - isChanged = true + signalSecure = true } config.TLSMode = "" config.TLSEnforce = false case "custom": if config.TLSMode == "" { - isChanged = true + signalSecure = true } // parse pem to cert and key if certStore == nil { @@ -129,7 +129,7 @@ func setTLSState(s TLSState) error { config.TLSEnforce = s.Enforce case "self-signed": if config.TLSMode == "" { - isChanged = true + signalSecure = true } config.TLSMode = "self-signed" config.TLSEnforce = s.Enforce @@ -137,22 +137,21 @@ func setTLSState(s TLSState) error { return fmt.Errorf("invalid TLS mode: %s", s.Mode) } - if oldEnforce != config.TLSEnforce { - logger.Info().Msg("Rerouting web server, as TLS enforcement changed") - updateWebRouter <- struct{}{} - } - - if !isChanged { + if signalSecure { + if config.TLSMode == "" { + websecureLogger.Info().Msg("Stopping websecure server, as TLS mode is disabled") + stopWebSecureServer() + } else { + websecureLogger.Info().Msg("Starting websecure server, as TLS mode is enabled") + startWebSecureServer() + } + } else { websecureLogger.Info().Msg("TLS enabled state is not changed, not starting/stopping websecure server") - return nil } - if config.TLSMode == "" { - websecureLogger.Info().Msg("Stopping websecure server, as TLS mode is disabled") - stopWebSecureServer() - } else { - websecureLogger.Info().Msg("Starting websecure server, as TLS mode is enabled") - startWebSecureServer() + if oldEnforce != config.TLSEnforce { + logger.Info().Msg("Rerouting web server, as TLS enforcement changed") + updateWebRouter <- struct{}{} } return nil From 4919cd93ec7ab948dc652b487c5cb278092141ec Mon Sep 17 00:00:00 2001 From: Grant Pannell <300992+DigitalDJ@users.noreply.github.com> Date: Tue, 6 Jan 2026 01:30:58 +1030 Subject: [PATCH 15/15] Fix hidden Update TLS Settings button when mode is self-signed --- .../devices.$id.settings.access._index.tsx | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/ui/src/routes/devices.$id.settings.access._index.tsx b/ui/src/routes/devices.$id.settings.access._index.tsx index ce8b28277..c2b46c712 100644 --- a/ui/src/routes/devices.$id.settings.access._index.tsx +++ b/ui/src/routes/devices.$id.settings.access._index.tsx @@ -292,16 +292,16 @@ export default function SettingsAccessIndexRoute() { value={tlsKey} onChange={e => handleTlsKeyChange(e.target.value)} /> -
-
)} +
+