From a71a18bffdd95d5140262e1176778fa2c1b35add Mon Sep 17 00:00:00 2001 From: archipelago Date: Tue, 21 Jul 2026 08:32:52 -0400 Subject: [PATCH] fix(pine): serve the Connect-to-WiFi button over an http->https redirect The launcher must be a secure context for Web Bluetooth, but the UI opens local apps as http://host:port (resolveAppUrl), so an https-only launcher (v1.1.0) would break the Open button with a TLS mismatch. Serve http on 10380 (the Open target) that 301-redirects to the https listener on 10381, so the new tab lands on https where navigator.bluetooth is available. Bump pine 1.1.0 -> 1.1.1; re-sign the catalog (only the pine entry changes). Co-Authored-By: Claude Opus 4.8 (1M context) --- app-catalog/catalog.json | 2 +- apps/pine/manifest.yml | 16 ++++++++++++++-- neode-ui/public/catalog.json | 2 +- releases/app-catalog.json | 17 +++++++++++------ 4 files changed, 27 insertions(+), 10 deletions(-) diff --git a/app-catalog/catalog.json b/app-catalog/catalog.json index 4688db41..ac96bc22 100644 --- a/app-catalog/catalog.json +++ b/app-catalog/catalog.json @@ -373,7 +373,7 @@ { "id": "pine", "title": "Pine", - "version": "1.1.0", + "version": "1.1.1", "description": "A private voice assistant for your home. Pine runs speech-to-text (Whisper) and text-to-speech (Piper) on your own node and pairs with a PineVoice satellite speaker, so Home Assistant Assist works locally with nothing sent to the cloud.", "icon": "/assets/img/app-icons/pine.svg", "author": "Archipelago", diff --git a/apps/pine/manifest.yml b/apps/pine/manifest.yml index 9387384c..3785ce2f 100644 --- a/apps/pine/manifest.yml +++ b/apps/pine/manifest.yml @@ -1,7 +1,7 @@ app: id: pine name: Pine - version: "1.1.0" + version: "1.1.1" description: A private voice assistant for your home. Pine runs speech-to-text (Whisper) and text-to-speech (Piper) on your own node and pairs with a PineVoice satellite speaker, so Home Assistant Assist works locally with nothing sent to the cloud. category: home @@ -45,7 +45,14 @@ app: network_policy: isolated ports: + # 10380 (http) is the Open target — the UI launches apps as + # http://host:10380 (resolveAppUrl). nginx there 301-redirects to the https + # listener on 10381, so the new tab lands on a secure context where + # navigator.bluetooth (the "Connect Pine to WiFi" provisioner) works. - host: 10380 + container: 80 + protocol: tcp + - host: 10381 container: 443 protocol: tcp @@ -73,6 +80,11 @@ app: - path: /var/lib/archipelago/pine/nginx.conf overwrite: true content: | + server { + listen 80; + server_name _; + return 301 https://$host:10381$request_uri; + } server { listen 443 ssl; server_name _; @@ -305,7 +317,7 @@ app: description: Connect your speaker to WiFi and check the voice assistant type: ui port: 10380 - protocol: https + protocol: http path: / metadata: diff --git a/neode-ui/public/catalog.json b/neode-ui/public/catalog.json index 4688db41..ac96bc22 100644 --- a/neode-ui/public/catalog.json +++ b/neode-ui/public/catalog.json @@ -373,7 +373,7 @@ { "id": "pine", "title": "Pine", - "version": "1.1.0", + "version": "1.1.1", "description": "A private voice assistant for your home. Pine runs speech-to-text (Whisper) and text-to-speech (Piper) on your own node and pairs with a PineVoice satellite speaker, so Home Assistant Assist works locally with nothing sent to the cloud.", "icon": "/assets/img/app-icons/pine.svg", "author": "Archipelago", diff --git a/releases/app-catalog.json b/releases/app-catalog.json index 0606434e..4afd9464 100644 --- a/releases/app-catalog.json +++ b/releases/app-catalog.json @@ -3874,7 +3874,7 @@ "environment": [], "files": [ { - "content": "server {\n listen 443 ssl;\n server_name _;\n ssl_certificate /etc/nginx/tls.crt;\n ssl_certificate_key /etc/nginx/tls.key;\n root /usr/share/nginx/html;\n index index.html;\n location / { try_files $uri $uri/ /index.html; }\n}\n", + "content": "server {\n listen 80;\n server_name _;\n return 301 https://$host:10381$request_uri;\n}\nserver {\n listen 443 ssl;\n server_name _;\n ssl_certificate /etc/nginx/tls.crt;\n ssl_certificate_key /etc/nginx/tls.key;\n root /usr/share/nginx/html;\n index index.html;\n location / { try_files $uri $uri/ /index.html; }\n}\n", "overwrite": true, "path": "/var/lib/archipelago/pine/nginx.conf" }, @@ -3899,7 +3899,7 @@ "name": "Pine", "path": "/", "port": 10380, - "protocol": "https", + "protocol": "http", "type": "ui" } }, @@ -3923,9 +3923,14 @@ "name": "Pine", "ports": [ { - "container": 443, + "container": 80, "host": 10380, "protocol": "tcp" + }, + { + "container": 443, + "host": 10381, + "protocol": "tcp" } ], "resources": { @@ -3943,7 +3948,7 @@ "no_new_privileges": true, "readonly_root": false }, - "version": "1.1.0", + "version": "1.1.1", "volumes": [ { "options": [ @@ -3980,7 +3985,7 @@ ] } }, - "version": "1.1.0" + "version": "1.1.1" }, "pine-piper": { "manifest": { @@ -4641,7 +4646,7 @@ } }, "schema": 1, - "signature": "ee660b635640c9ac91d203330a7593132842bbd5650883183110f9829dfda417ab172211364860d7dd3f52ada19745850fad66f424a03faf27465cf3ff740301", + "signature": "aa471d39066c27f305aeefde39f239357d38af4bc6fe50aa2f6006690bb7a0cd7f4b0ecd6e866330c7055303ce433f27d94820964eff23efaa5a3a49883c9e08", "signed_by": "did:key:z6MkkidEnEpo6qHMCNSZoNKWtvQvxq3whnaME9wGgEFhq7ur", "updated": "2026-07-21" }