Conversation
…s to quickly schedule a full next pull from the API (which we are not using). It also clears the current entries as it believes it's going to pull a full history, This is not the case with SSE.
Don't call fetchFull() on a useVisibilityRefresh() in useWSJTX()
Port the intelligence layer from the OHC server's WSJTX route into the
rig-bridge plugin stack so SSE consumers receive rich events even when
no server relay is configured.
New shared library — rig-bridge/lib/wsjtx-enrich.js
• gridToLatLon() — Maidenhead grid → lat/lon (pure math)
• getBandFromHz() — Hz → band name (160 m – 70 cm)
• createGridCache() — callsign → grid cache (2 h TTL, per-instance)
• parseDecodeMessage()— FT8/FT4 text parser: CQ/QSO type, caller,
modifier, dxCall/deCall, embedded grid;
populates grid cache as a side-effect
• enrichDecode() — full decode enrichment + grid-cache fallback
• enrichStatus() — band name, band-change flag, DX/DE lat/lon
• enrichQso() — band name, dxGrid → lat/lon
• enrichWspr() — band name, grid → lat/lon
wsjtx-relay.js changes (Phases 1–4)
• CLEAR message → new `clear` bus event (was silently dropped before)
• WSPR_DECODE → new `wspr` bus event with enriched fields
• STATUS → enriched with band, bandChanged, dxLat/dxLon, deLat/deLon
• DECODE → enriched with parsed message fields, grid → lat/lon,
content-based dedup ID; duplicates are suppressed
• QSO_LOGGED → enriched with band + lat/lon; 60 s call+freq+mode dedup
• Grid cache pruned every 5 min; cleared per-client on CLEAR
• getStatus() now reports gridCacheSize
• Relay queue still receives raw (un-enriched) messages — server does
its own enrichment on the relay path (no double-processing)
digital-mode-base.js changes (MSHV / JTDX / JS8Call)
• Same enrichment applied via wsjtx-enrich helpers
• CLEAR forwarded as `clear` bus event (was silently dropped)
• STATUS/DECODE/QSO enriched identically to wsjtx-relay
• lastBand added to getStatus() alongside existing lastMode
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…chment
Adds opt-in background callsign → lat/lon resolution via the HamQTH DXCC
API, matching the server's Phase 5 behaviour but running entirely inside
the local rig-bridge process.
wsjtx-enrich.js
• createCallsignCache() — 24 h TTL cache for HamQTH results, separate
from the 2 h gridCache (different source, different lifetime)
• triggerHamqthLookup(callsign, cache, inflight, onResult) — fire-and-
forget HTTPS GET to hamqth.com/dxcc.php; max 5 concurrent requests
(inflightSet guard); writes result into callsignCache and calls
onResult so callers can emit a decode-update event
• enrichDecode() — accepts optional 5th param callsignCache; consults
it as a third fallback tier between gridCache and giving up
wsjtx-relay.js
• Instantiates callsignCache + hamqthInflight per plugin instance
• Passes callsignCache to enrichDecode() when cfg.hamqthLookup is true
• After emitting a decode with no lat/lon, calls triggerHamqthLookup
and on resolution emits a decode-update bus event with the resolved
callsign + coordinates for frontend live-patching
• gridPruneInterval now also prunes callsignCache every 5 min
• getStatus() reports callsignCacheSize, hamqthLookup flag, hamqthInflight
rig-bridge/core/server.js (Integrations tab UI)
• New "HamQTH callsign lookup" checkbox (id=wsjtxHamqth) with help text
explaining the internet requirement and 24 h cache
• populateIntegrations() reads w.hamqthLookup → checkbox
• saveIntegrations() writes checkbox → wsjtxRelay.hamqthLookup
• Status line now shows callsign cache size when hamqthLookup is active
and omits relay count when running in SSE-only mode
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
rig-bridge/rig-bridge.js
• decode handler was building a trimmed object that silently dropped all
fields added by wsjtx-enrich (lat, lon, band, grid, type, caller,
modifier, dxCall, deCall, gridSource). Now passes them all through.
• id forwarded directly from enrichDecode (content-based) instead of
being rebuilt; raw-decode fallback retained for non-enriched plugins.
• status handler forwards new enriched fields: band, bandChanged,
dxLat, dxLon, deLat, deLon.
• qso handler forwards: band, lat, lon, frequency, myCall, myGrid.
• New clear handler → broadcasts clientId + window to SSE.
• New wspr handler → broadcasts full enriched WSPR decode to SSE.
• New decode-update handler → broadcasts HamQTH-resolved callsign
coordinates to SSE for live map-pin patching.
src/hooks/useWSJTX.js
• status handler now stores band, bandChanged, dxLat, dxLon so DX
target resolution and band-change detection work without server.
• Band-change detection uses the bandChanged flag from the enriched
status event; falls back to manual prev-band comparison for the
server/relay path.
• New clear event handler: filters decodes by clientId.
• New wspr event handler: prepends to wspr array (capped at 100).
• New decode-update event handler: patches existing decodes that share
the resolved callsign and have no lat/lon yet (HamQTH async result).
src/layouts/ModernLayout.jsx
• Pass wsjtxWspr={wsjtx.wspr} to PSKReporterPanel so the WSPR tab
actually receives data (DockableApp already had this; ModernLayout
was the only layout missing it).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…nvention PSKReporterPanel filters on d.type === 'CQ' (uppercase), matching the OHC server's parseDecodeMessage output. wsjtx-enrich was using lowercase 'cq'/'qso', causing the CQ filter and the blue CQ row colour to never match in local SSE mode. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Installer scripts generated in `server/routes/rig-bridge.js` now automatically resolve the configured TCP port, TLS scheme, and bindAddress configuration dynamically. - Refactored both Windows and macOS/Linux installer scripts to halt and interactively request user confirmation after verifying that they read the `README.md` before launching the Setup UI. - Improved subdirectory flushing using recursive deletions (`rmdir /S` and `find -exec rm -rf`) prior to repo extraction to ensure stale files do not survive updates. - Refactored Rig Bridge `README.md` text to correctly define the new installation UI behavior.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…s work PORT was present in the shared ctx object but not destructured into rbn.js, causing a ReferenceError in every try/catch that called the internal /api/callsign/ endpoint. All three lookup paths (enrichSpotWithLocation, enrichSpotWithDXLocation, /api/rbn/location/) silently swallowed the error and cached a _failed marker, so no spot ever received skimmerLat/skimmerLon or dxLat/dxLon. In spotter mode this meant every spot failed the Number.isFinite(dxLat) guard and nothing rendered on the map, even though the stats count was correct. Also fix three CLAUDE.md violations (falsy && checks on lat/lon that would mishandle stations on the equator or prime meridian), and improve the spotter-mode debug log to show dxLat/dxLon/dxGrid instead of the irrelevant skimmer coordinates. Fixes: #897 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
fix(rbn): restore PORT in ctx destructuring so spotter-mode spots appear on map I verified it does what it should and teh other changes are good good code cleanup.
When a DX cluster spot is clicked, the callsign is now captured alongside the coordinates and displayed to the right of the grid locator in ModernLayout and ClassicLayout. Typing a grid manually clears the callsign. Persisted to localStorage. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…out) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…A spot click Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Polls /api/rbn/spots for all 18 IBP beacon callsigns every 60 s. When a beacon has been heard by RBN skimmers in the last 5 minutes, a compact "RBN N× +XdB" indicator appears beneath its location in the IBP panel, showing skimmer count and best SNR. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds ibp.title, ibp.cycleCountdown, ibp.cycleCountdown.tooltip, ibp.slotProgress.tooltip, ibp.footer, ibp.tune, ibp.rbn.heard, ibp.rbn.tooltip, plugins.layers.ibp.name and .description to: ca, de, es, fr, it, ja, ka, ko, ms, nl, pt, ru, sl, th, zh Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
IBP beacons transmit in CW but getModeFromFreq() returns DATA/USB for 14.100, 21.150, 24.930 and 28.200 MHz. Pass 'CW' explicitly as the second argument to tuneTo() in both IBPPanel and the map layer so all 5 beacon frequencies set the correct mode regardless of the band plan. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- th.json: improve ibp.rbn.tooltip and plugins.layers.ibp.description wording for more natural Thai - useIBPRBN.js: apply Prettier formatting (fetch options object style) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ckableApp Prevents button overlap when a long callsign is displayed alongside the grid locator in narrow dockable panels. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Feature/Show DX spot callsign in the DX panel
[fix] add periodic purges to emcomm.js caches
[fix] MUF_MAP_CACHE periodic purge
[fix] Validate that `imageUrl` parses as `https://*.nasa.gov` before fetching.
…api_presence [fix] lockout frequent POST to /api/presence
[fix] /api/health lockdown
[util] geo.js extends maidenhead grid support
Client side logging cleanup
fix(security): harden rig-bridge relay and status endpoints
Covers PRs #946, #945, #943, #942, #941, #940, #938, #935, #932 — all merged to Staging on 2026-05-04. Grouped into five themes: Cloud Relay credential overhaul (with breaking-change heads-up), API surface hardening, server cache leak closures, extended Maidenhead grid utilities, and the client-side console cleanup. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ion that guarantees isAuthed === true
…ve existing definitions of same function. Load in server.js and pass in ctx object.
[fix] fixes issue#950 non-NASA imageUrl report in throw
…ockdown [refactor] fixes issue #948 nit fix /api/health_lockdown redundant ternary
…presence [fix/refactor] fixes issue#949, cleanup lockout frequent POST to /api/presence
…nCache [refactor] Issue#947, create server/utils/cache.js with maintainCache
| method: 'POST', | ||
| headers: { 'Content-Type': 'application/json', 'X-RigBridge-Token': config.apiToken || '' }, | ||
| // Skip cert verification for loopback self-signed cert | ||
| rejectUnauthorized: false, |
| const entry = sessionId ? relayIssuedTokens.get(sessionId) : undefined; | ||
| if (!sessionId || !token || !entry || token !== entry.token) { | ||
| logWarn( | ||
| `[RigBridge] relay auth failed — sessionId: ${sessionId ? sessionId.slice(0, 8) + '…' : '(none)'}, ` + |
…ish-p533-data.yml workflow
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Cuts release v26.3.1 — the May server-side security and resource-hardening audit, plus extended grid-locator utilities and a quieter browser console.
WhatsNew entry already in tree (
164baa4);package.jsonbumped to26.3.1indc56b00so the modal surfaces on deploy.Highlights
Security / hardening
data/relay-tokens.json(replaces rawRIG_BRIDGE_RELAY_KEY), SSRF guard on/api/rig-bridge/status, long-poll cap of 10/IP, installer URL-injection guard, sharedserver/utils/ssrf.js. Cloud-relay plugin v2.1.3: TLS-aware loopback. Breaking for existing Cloud Relay users — must re-run Connect Cloud Relay once./api/presence— IP↔callsign binding with 60s lockout; [fix/refactor] fixes issue#949, cleanup lockout frequent POST to /api/presence #954 follow-up makes it actually work behind Railway's proxy (req.ipoverreq.socket.remoteAddress), corrects cleanup interval to 10 min, returns proper 429./api/healthunauth lockdown — endpoint counts, byte totals, MQTT broker state, in-flight upstream counters, visitor history all gated behind auth.imageUrlparses ashttps://*.nasa.govbefore fetching. #938 + [fix] fixes issue#950 non-NASA imageUrl report in throw #952 Dial-A-Moon NASA URL validator — closes the SSRF vector; [fix] fixes issue#950 non-NASA imageUrl report in throw #952 makes the rejected URL actually appear in the thrown error.Resource leaks closed
errorLogStateperiodic purge.maintainCache+ 200-entry caps + 10-min sweeps.MUF_MAP_CACHEperiodic purge.maintainCacheintoserver/utils/cache.js, standardises cache field on.timestamp.Cleanup / refactor
geo.jsMaidenhead grid extension (sizes 2/4/6/8 + bounding box) with 169-case test suite.console.log→console.debug/infoacross hooks/plugins/components.admin.jsredundant ternary removal (dead branches insideisAuthedspread).isMeticPress→isMetricPress).Test plan
/iturhfprop-serviceto empty (matching Staging)curl -s https://proppy-production.up.railway.app/api/healthreturns OHC's verbose JSON (not ITURHFProp minimal response) post-flip/api/presencerate-limit on production (one POST, second within 60s should 429)