diff options
Diffstat (limited to 'packages/meshbay-hub/src/meshbay_hub/static/app.js')
| -rw-r--r-- | packages/meshbay-hub/src/meshbay_hub/static/app.js | 33 |
1 files changed, 31 insertions, 2 deletions
diff --git a/packages/meshbay-hub/src/meshbay_hub/static/app.js b/packages/meshbay-hub/src/meshbay_hub/static/app.js index a48535a..abb3374 100644 --- a/packages/meshbay-hub/src/meshbay_hub/static/app.js +++ b/packages/meshbay-hub/src/meshbay_hub/static/app.js @@ -6,10 +6,15 @@ import { t, getLocale, setLocale, initLocale, LOCALES } from './i18n.js'; import { ZipStream, entriesUnder } from './zipstream.js'; import { transfers, formatSpeed } from './transfers.js'; import * as downloads from './downloads.js'; +import * as platform from './platform.js'; // ── Constants ──────────────────────────────────────────────────────────────── -const HUB = ''; +// Where the hub is. Empty in a browser — it served this page, so a relative +// path cannot be pointed at the wrong place. In the installed app the page +// comes from disk and has no origin of its own, so the base is configured. +// See platform.js. +const HUB = platform.hubBase(); const AUTH_KEY = 'mb_auth'; // Renew an access token with this much life left rather than waiting for it to // fail. Generous against a one-hour token: a film is watched without the hub @@ -1323,7 +1328,9 @@ function GroupPage({ groupId, group, token, username, userId, onRefreshAuth, // connection at all. Renewals are shared, so if one is already in // flight this waits for it instead of starting a second. const live = (await ensureFreshToken()) || token; - const transport = new window.MeshBayTransport('', live); + // The same base the API calls use: signaling is a hub endpoint like + // any other, and two sources for one address is how they drift. + const transport = new window.MeshBayTransport(HUB, live); transportRef.current = transport; const ack = await transport.connect( @@ -3941,6 +3948,15 @@ function SettingsPage({ user, theme, onThemeChange, groups }) { // Read from the hub rather than written here: the two constants that used to // sit in this markup said 0.1.0 and MNP 0.1 long after both had moved on. const [hubInfo, setHubInfo] = useState(null); + // On a desktop build, whether the OS is really holding the keys. Electron's + // safeStorage falls back to a fixed key when no keyring is running — a + // headless session, a minimal desktop — and does it silently. Somebody who + // believes the OS is protecting their keys deserves to be told when it is not. + const [keyBackend, setKeyBackend] = useState(''); + useEffect(() => { + if (!platform.secrets.available) return; + platform.secrets.backend().then(setKeyBackend).catch(() => {}); + }, []); useEffect(() => { hubFetch('/v1/hub/version').then(setHubInfo).catch(() => {}); @@ -4043,6 +4059,19 @@ function SettingsPage({ user, theme, onThemeChange, groups }) { </div> `} + ${keyBackend && html` + <div class="settings-section"> + <h3 class="settings-heading">${t('settings.keys_heading')}</h3> + <div class="settings-row"> + <span class="settings-label">${t('settings.keys_where')}</span> + <span class="settings-value">${keyBackend}</span> + </div> + ${keyBackend === 'unprotected_fallback' && html` + <p class="error-msg">${t('settings.keys_unprotected')}</p> + `} + </div> + `} + <div class="settings-section"> <h3 class="settings-heading">${t('settings.about')}</h3> <div class="settings-row"> |