From 9481b6614ab353d74329ddec16f6bdd7c553e314 Mon Sep 17 00:00:00 2001 From: Hermes Agent Date: Sun, 30 Aug 2026 20:46:39 +0000 Subject: [PATCH] fix(connections): allow toggling HTTPS off in Add Connection dialog The 'Use HTTPS' switch was disabled whenever the web client itself was served over HTTPS, making it impossible to add a plain-HTTP node. Keep the switch always interactive and instead show a mixed-content warning when HTTP is selected on an HTTPS-served page. Adds unit tests for the protocol toggle. --- apps/web/public/i18n/locales/en/dialog.json | 1 + .../AddConnectionDialog.test.tsx | 53 +++++++++++++++++++ .../AddConnectionDialog.tsx | 12 +++-- 3 files changed, 63 insertions(+), 3 deletions(-) create mode 100644 apps/web/src/components/Dialog/AddConnectionDialog/AddConnectionDialog.test.tsx diff --git a/apps/web/public/i18n/locales/en/dialog.json b/apps/web/public/i18n/locales/en/dialog.json index 5d8e36b4..84540471 100644 --- a/apps/web/public/i18n/locales/en/dialog.json +++ b/apps/web/public/i18n/locales/en/dialog.json @@ -79,6 +79,7 @@ "inputPlaceholder": "192.168.1.10 or meshtastic.local", "heading": "URL or IP", "useHttps": "Use HTTPS", + "mixedContentWarning": "This page is loaded over HTTPS. Your browser may block connections to an HTTP node.", "invalidUrl": { "title": "Invalid URL", "description": "Please enter a valid HTTP or HTTPS URL." diff --git a/apps/web/src/components/Dialog/AddConnectionDialog/AddConnectionDialog.test.tsx b/apps/web/src/components/Dialog/AddConnectionDialog/AddConnectionDialog.test.tsx new file mode 100644 index 00000000..f5512c27 --- /dev/null +++ b/apps/web/src/components/Dialog/AddConnectionDialog/AddConnectionDialog.test.tsx @@ -0,0 +1,53 @@ +import { fireEvent, render, screen } from "@testing-library/react"; +import { beforeEach, describe, expect, it, vi } from "vitest"; +import AddConnectionDialog from "./AddConnectionDialog.tsx"; + +vi.mock("@core/hooks/useToast.ts", () => ({ + useToast: () => ({ toast: vi.fn() }), +})); + +vi.mock("@app/pages/Connections/utils", () => ({ + testHttpReachable: vi.fn(() => Promise.resolve(true)), +})); + +const getSwitch = () => screen.getByRole("switch"); + +describe("AddConnectionDialog HTTPS toggle", () => { + beforeEach(() => { + vi.clearAllMocks(); + }); + + it("toggles between http and https when the app is served over http", () => { + render(); + + const sw = getSwitch(); + expect(sw).toHaveAttribute("aria-checked", "false"); + expect(sw).toBeEnabled(); + + fireEvent.click(sw); + expect(sw).toHaveAttribute("aria-checked", "true"); + + fireEvent.click(sw); + expect(sw).toHaveAttribute("aria-checked", "false"); + }); + + it("allows switching to http even when the app itself is served over https", () => { + render(); + const sw = getSwitch(); + expect(sw).toHaveAttribute("aria-checked", "true"); + expect(sw).toBeEnabled(); + + fireEvent.click(sw); + expect(sw).toHaveAttribute("aria-checked", "false"); + }); + + it("keeps the protocol in sync with the url input prefix", () => { + render(); + + // prefix reflects the current protocol + expect(screen.getByText("http://")).toBeInTheDocument(); + + fireEvent.click(getSwitch()); + expect(screen.getByText("https://")).toBeInTheDocument(); + }); +}); diff --git a/apps/web/src/components/Dialog/AddConnectionDialog/AddConnectionDialog.tsx b/apps/web/src/components/Dialog/AddConnectionDialog/AddConnectionDialog.tsx index f8c21a68..494af628 100644 --- a/apps/web/src/components/Dialog/AddConnectionDialog/AddConnectionDialog.tsx +++ b/apps/web/src/components/Dialog/AddConnectionDialog/AddConnectionDialog.tsx @@ -275,7 +275,6 @@ export default function AddConnectionDialog({ typeof navigator !== "undefined" && "bluetooth" in navigator; const serialSupported = typeof navigator !== "undefined" && "serial" in navigator; - const isURLHTTPS = isHTTPS; const reset = useCallback(() => { dispatch({ type: "RESET", payload: { isHTTPS } }); @@ -434,7 +433,6 @@ export default function AddConnectionDialog({
{ dispatch({ @@ -446,6 +444,14 @@ export default function AddConnectionDialog({ >
+ {isHTTPS && state.protocol === "http" && ( +

+ {t( + "addConnection.httpConnection.mixedContentWarning", + "This page is loaded over HTTPS. Your browser may block connections to an HTTP node.", + )} +

+ )}