feat(wavelog): link to the Wavelog instance next to the API key field

Show an "Open Wavelog" link beside the Wavelog API Key heading in the
OpenWebRX panel. The URL comes from the runtime WAVELOG_BASE_URL (exposed
via GET /v1/me and the OpenWebRX session response), so the private hostname
is never hardcoded in this public repo. The link is hidden when no base URL
is configured.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
ARCG Admin (Claude)
2026-10-22 21:21:27 +02:00
parent 3387ded386
commit 9862f751a2
5 changed files with 33 additions and 3 deletions

View File

@@ -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) : "";

View File

@@ -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",

View File

@@ -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",

View File

@@ -167,7 +167,10 @@
<p class="muted">Session Key (Ticket): <code id="openwebrxSessionTicket">-</code></p>
</div>
<div id="wavelogKeyBox" class="stack">
<div class="section-head">
<label for="wavelogKeyInput">Wavelog API Key (Rig-Key)</label>
<a id="wavelogInstanceLink" target="_blank" rel="noopener noreferrer" hidden>Wavelog öffnen</a>
</div>
<input id="wavelogKeyInput" type="text" autocomplete="off" spellcheck="false" placeholder="Wavelog API Key" />
<div class="actions">
<button id="wavelogKeySaveBtn" type="button" class="ghost-btn">Key speichern</button>

View File

@@ -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) {