diff --git a/public/app.js b/public/app.js index bd0f3ea..897b033 100644 --- a/public/app.js +++ b/public/app.js @@ -138,6 +138,7 @@ const els = { wavelogKeyInput: document.getElementById("wavelogKeyInput"), wavelogKeySaveBtn: document.getElementById("wavelogKeySaveBtn"), wavelogKeyMessage: document.getElementById("wavelogKeyMessage"), + wavelogInstanceLink: document.getElementById("wavelogInstanceLink"), openwebrxTxStatePill: document.getElementById("openwebrxTxStatePill"), rotorCurrent: document.getElementById("rotorCurrent"), rotorCompass: document.getElementById("rotorCompass"), @@ -1505,6 +1506,7 @@ async function refreshCurrentUser() { const result = await api("/v1/me", { authRequired: true }); state.user = result.user; state.wavelogApiKey = typeof result.wavelogApiKey === "string" ? result.wavelogApiKey : ""; + state.wavelogBaseUrl = typeof result.wavelogBaseUrl === "string" ? result.wavelogBaseUrl : ""; applyWavelogKeyToInput(); renderUserSettingsAuthMethods(); await ensureLanguageFromUserPreference(); @@ -1698,6 +1700,16 @@ function applyWavelogKeyToInput() { if (els.wavelogKeyInput) { els.wavelogKeyInput.value = String(state.wavelogApiKey || ""); } + if (els.wavelogInstanceLink) { + const url = String(state.wavelogBaseUrl || "").trim(); + if (url) { + els.wavelogInstanceLink.href = url; + els.wavelogInstanceLink.hidden = false; + } else { + els.wavelogInstanceLink.removeAttribute("href"); + els.wavelogInstanceLink.hidden = true; + } + } } async function saveWavelogKey() { @@ -1723,6 +1735,9 @@ async function openOpenWebRxSession() { const session = result && result.session ? result.session : null; if (result && typeof result.wavelogApiKey === "string") { state.wavelogApiKey = result.wavelogApiKey; + if (typeof result.wavelogBaseUrl === "string") { + state.wavelogBaseUrl = result.wavelogBaseUrl; + } applyWavelogKeyToInput(); } const sessionTicket = session && session.ticket ? String(session.ticket) : ""; @@ -1752,6 +1767,9 @@ async function openOpenWebRxExternal() { const session = result && result.session ? result.session : null; if (result && typeof result.wavelogApiKey === "string") { state.wavelogApiKey = result.wavelogApiKey; + if (typeof result.wavelogBaseUrl === "string") { + state.wavelogBaseUrl = result.wavelogBaseUrl; + } applyWavelogKeyToInput(); } const sessionTicket = session && session.ticket ? String(session.ticket) : ""; diff --git a/public/i18n/de.json b/public/i18n/de.json index 30fd217..5da7f5a 100644 --- a/public/i18n/de.json +++ b/public/i18n/de.json @@ -56,6 +56,7 @@ "Key speichern": "Key speichern", "Frequenz und Mode der Station werden beim Bandwechsel an dein Wavelog-Logbuch gesendet.": "Frequenz und Mode der Station werden beim Bandwechsel an dein Wavelog-Logbuch gesendet.", "Wavelog API Key gespeichert.": "Wavelog API Key gespeichert.", + "Wavelog öffnen": "Wavelog öffnen", "Reservierungen": "Reservierungen", "Naechsten Slot reservieren": "Naechsten Slot reservieren", "SWR Uebersicht": "SWR Uebersicht", diff --git a/public/i18n/en.json b/public/i18n/en.json index 6f5e4e7..9d98d70 100644 --- a/public/i18n/en.json +++ b/public/i18n/en.json @@ -56,6 +56,7 @@ "Key speichern": "Save key", "Frequenz und Mode der Station werden beim Bandwechsel an dein Wavelog-Logbuch gesendet.": "The station's frequency and mode are sent to your Wavelog logbook on band change.", "Wavelog API Key gespeichert.": "Wavelog API key saved.", + "Wavelog öffnen": "Open Wavelog", "Reservierungen": "Reservations", "Naechsten Slot reservieren": "Reserve next slot", "SWR Uebersicht": "SWR Overview", diff --git a/public/index.html b/public/index.html index a26bf3a..df58f0e 100644 --- a/public/index.html +++ b/public/index.html @@ -167,7 +167,10 @@

Session Key (Ticket): -

- +
+ + +
diff --git a/server/index.js b/server/index.js index 86e1fe0..11df935 100644 --- a/server/index.js +++ b/server/index.js @@ -360,7 +360,7 @@ async function routeRequest(req, res) { if (method === "GET" && url.pathname === "/v1/me") { const auth = requireAuth(req, res); if (!auth) return; - return sendJson(res, 200, { user: sanitizeUser(auth.user), wavelogApiKey: auth.user.wavelogApiKey || "", capabilities: userCapabilities(auth.user) }); + return sendJson(res, 200, { user: sanitizeUser(auth.user), wavelogApiKey: auth.user.wavelogApiKey || "", wavelogBaseUrl: wavelogBaseUrlPublic(), capabilities: userCapabilities(auth.user) }); } if (method === "GET" && url.pathname === "/v1/auth/session/diag") { @@ -3641,7 +3641,8 @@ async function handleOpenWebRxSessionIssue(res, user) { return sendJson(res, 200, { ok: true, session: result, - wavelogApiKey: user.wavelogApiKey || "" + wavelogApiKey: user.wavelogApiKey || "", + wavelogBaseUrl: wavelogBaseUrlPublic() }); } @@ -3719,6 +3720,12 @@ async function handleOpenWebRxBandSelect(res, user, body) { } } +// Public Wavelog base URL (for the UI link). Comes from runtime env only, so the +// private hostname is never baked into this (public) repo. +function wavelogBaseUrlPublic() { + return String(process.env.WAVELOG_BASE_URL || "").trim().replace(/\/+$/, ""); +} + // Push a frequency/mode to the active operator's Wavelog logbook (CAT API). // Best-effort: never throws into the caller's flow. async function sendWavelogCat(user, frequencyHz, mode) {