fix(ui): gate-fronted https launches + signed-catalog App Store
Demo images / Build & push demo images (push) Failing after 36s

directAppUrl(), the legacy open() path, and resolveRuntimeLaunchUrl()
now upgrade to https only for ports the app gate fronts — decided from
the signed catalog's embedded manifest ports (auth gated/open), so
plain-HTTP publishes (legacy installs, auth:none API ports like
Cuprate's RPC) keep http instead of failing outright. fetchAppCatalog()
merges the daemon-verified signed catalog into the App Store listing
(signed entries appear immediately; community copy supplies featured
and curated metadata), and Marketplace.vue uses the same dynamic fetcher
as Discover so the grid sees signed-new apps too.
This commit is contained in:
archipelago
2026-08-31 18:41:00 -04:00
parent b8593c9090
commit 46cb0bfd37
7 changed files with 260 additions and 68 deletions
+8 -4
View File
@@ -4,6 +4,7 @@ import type { Ref } from 'vue'
import { computed } from 'vue'
import { PackageState, type PackageDataEntry } from '@/types/api'
import { matchPageScheme, resolveAppUrl } from '../appSession/appSessionConfig'
import { portIsGateFronted } from '../discover/curatedApps'
import { isAutoTabApp } from '@/utils/autoTabApps'
export type AppsTab = 'apps' | 'websites' | 'services'
@@ -301,10 +302,13 @@ export function resolveRuntimeLaunchUrl(pkg: PackageDataEntry): string {
if (!addr || typeof window === 'undefined') return addr
const local = addr.replace(/^http:\/\/(localhost|127\.0\.0\.1)(?=[:/]|$)/, `http://${window.location.hostname}`)
// The backend reports runtime URLs as http:// because that is how the app
// binds locally — on an HTTPS connection that is a cleartext downgrade
// (and mixed-content-blocked when opened from the dashboard). The gate
// serves TLS on every app port, so follow the page's scheme, exactly like
// resolveAppUrl() does for the same runtime URLs.
// binds locally — on an HTTPS connection that is a cleartext downgrade.
// Upgrade only when the app gate fronts the port (it serves TLS there);
// a container-published plain-HTTP port would fail over https outright.
try {
const port = new URL(local).port
if (!portIsGateFronted(pkg.manifest.id, port)) return local
} catch { /* keep as-is */ }
return matchPageScheme(local)
}