Skip to content

Staging#16

Merged
MichaelWheeley merged 11 commits intoMichaelWheeley:feature/thai-language-devfrom
accius:Staging
Mar 22, 2026
Merged

Staging#16
MichaelWheeley merged 11 commits intoMichaelWheeley:feature/thai-language-devfrom
accius:Staging

Conversation

@MichaelWheeley
Copy link
Owner

What does this PR do?

Type of change

  • Bug fix
  • New feature
  • Performance improvement
  • Refactor / code cleanup
  • Documentation
  • Translation
  • Map layer plugin

How to test

Checklist

  • App loads without console errors
  • Tested in Dark, Light, and Retro themes
  • Responsive at different screen sizes (desktop + mobile)
  • If touching server.js: caches have TTLs and size caps (we serve 2,000+ concurrent users)
  • If adding an API route: includes caching and error handling
  • If adding a panel: wired into Modern, Classic, and Dockable layouts
  • No hardcoded colors — uses CSS variables (var(--accent-cyan), etc.)
  • No .bak, .old, console.log debug lines, or test scripts included

Screenshots (if visual change)

ceotjoe and others added 11 commits March 22, 2026 10:20
…anch

Reimplements all security fixes from feature/rig-bridge-security-assessment-fixes
onto Staging as a clean rewrite, preserving Staging's SmartSDR/RTL-TCP additions.

rig-bridge/core/config.js:
- Auto-generate apiToken via crypto.randomBytes on first run
- Add tokenDisplayed, fixSplit, udpBindAddress to DEFAULT_CONFIG
- Merge smartsdr/rtltcp config sections in loadConfig()

rig-bridge/core/server.js:
- Add isValidRemoteHost(), isValidPort(), makeRateLimiter() helpers
- Add requireAuth middleware (X-RigBridge-Token header)
- Add per-route rate limiters (freq/mode/ptt/cfg/token)
- GET /api/log/stream: authenticate via ?token= query param
- GET /api/ports: require auth
- GET /api/config: strip apiToken from response
- POST /api/config: require auth + SSRF host/port validation for all 5 plugin hosts
- POST /api/test, /api/logging: require auth
- POST /freq, /mode, /ptt: require auth + rate limit + input validation
- New endpoints: POST /api/auth/verify, GET /api/token,
  POST /api/token/regenerate, POST /api/setup/token-seen
- buildSetupHtml: login overlay, welcome banner, first-run token injection,
  full auth flow (doAutoLogin, doLogin, doLogout, authHeaders)

rig-bridge/plugins/*.js:
- flrig.js: add defensive host validation before XML-RPC connect
- rigctld.js: dual-mode protocol, fixSplit support, host validation
- tci.js: full WebSocket implementation (ws npm + native), host validation
- wsjtx-relay.js: UDP bind to 127.0.0.1 by default, udpBindAddress config
- rtl-tcp.js, smartsdr.js: add host validation (Staging-only plugins)

src/:
- RigContext.jsx: restore X-RigBridge-Token auth headers + 401 handling
- RigControlPanel.jsx: restore two-tier error banner (unauthorized vs daemon)
- SettingsPanel.jsx: restore API token field with show/hide toggle
- lang/en.json + 14 other languages: add 4 API token i18n keys

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add supported radio entries, setup sections, config field tables,
expected log output, troubleshooting rows, and project structure
entries for the two new Staging plugins (smartsdr.js, rtl-tcp.js).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Eliminates manual relay key and session ID copy-paste with two
complementary auto-configure flows.

OHC server (server/routes/wsjtx.js):
- GET /api/wsjtx/relay-credentials — returns WSJTX_RELAY_KEY to
  callers on localhost origins (CORS opened for local rig-bridge UI)
- OPTIONS preflight handler for the same route

OHC frontend:
- SettingsPanel.jsx: new WSJT-X Relay sub-section inside the Rig
  Control card (visible when rig control is enabled)
  - Shows session ID (read-only) with copy button
  - "Configure Relay on Rig Bridge" button: fetches relay key from
    /api/wsjtx/relay-credentials, then POSTs url+key+session+enabled
    to the configured rig-bridge /api/config in one click
  - Inline success/error feedback
- App.jsx: passes wsjtx.sessionId down to SettingsPanel
- 15 lang files: 10 new i18n keys for the WSJT-X relay UI

rig-bridge setup UI (rig-bridge/core/server.js):
- "Fetch credentials" button next to the OHC Server URL field
  auto-fills the relay key via GET {url}/api/wsjtx/relay-credentials
- Session ID help text directs users to OHC Settings to copy it
- fetchWsjtxCredentials() JS function with full error handling

rig-bridge/README.md:
- Replaces bare config table with three-option setup guide
  (Option A: push from OHC, Option B: fetch in rig-bridge UI,
   Option C: manual config)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The regex /\/$/ inside the buildSetupHtml template literal had its
backslash silently dropped (\/ is an unrecognized escape in template
literals, producing just /). This turned /\/$/ into //$/ which starts
a line comment in the generated HTML, making fetch() unclosed and
crashing the entire <script> block with 'Unexpected keyword if'.

Fix: use a character class /[/]$/ instead of an escaped slash, which
avoids the backslash-in-template-literal pitfall entirely.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
PTT polling:
- poll() now sends cmd 0x1c sub 0x00 (read TX state) on every tick,
  staggered 100 ms after the mode query
- handleData() gains case 0x1c to parse the response and call
  updateState('ptt', ...), so externally keyed TX (VOX, foot switch)
  is reflected in the UI without waiting for a write command

DV mode:
- 0x17 was mapped to 'DATA-FM'; corrected to 'DV' to match the
  rig-listener implementation (D-STAR voice mode on IC-705, IC-9700)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…esponses

Two fragile checks could falsely report PTT active:

1. IF; parser: `txState !== '0'` treated any unexpected byte at position 22
   (garbage on reconnect, model-specific extension, truncation artifact, or
   a bare empty string) as PTT ON. Changed to only assert ON for an explicit
   '1' (PTT TX) or '2' (CAT/linear TX).

2. TX; case: a bare `TX;` with no digit produced txDigit = '', which failed
   the `=== '0'` guard and fell through to updateState('ptt', true).
   Now only '1' or '2' assert ON; missing digit is silently ignored.

Both changes follow the same principle: require a positive match to assert
TX state rather than inferring it from the absence of '0'.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replaces English fallback text added in the credential-flow commit with
proper translations for all 10 WSJT-X relay keys across:
ca, de, es, fr, it, ja, ka, ko, ms, nl, pt, ru, sl, zh

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
When rig-bridge returns 403 on a PTT command (pttEnabled: false in its
config), the UI now clearly tells the user why PTT isn't working instead
of silently reverting the button.

RigContext.jsx:
- Detect res.status === 403 in setPTT, set error('ptt-disabled'), and
  revert the optimistic PTT state — same pattern as the 401 handler
- Clear ptt-disabled error on next successful PTT response

RigControlPanel.jsx:
- Amber warning banner (distinct from the red daemon/auth banners)
  shown when error === 'ptt-disabled'
- PTT button gains a 🔒 prefix, dashed border, and tooltip with the
  full message so the hint is visible even on small panels
- ptt-disabled excluded from the generic daemon-error fallback banner

i18n:
- New key app.rigControl.error.pttDisabled in en.json and all 14
  language files with proper translations

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Both rig-bridge's WSJT-X relay and a locally-running OpenHamClock
server bind to UDP 2237. Added a callout in the WSJT-X Relay section
explaining that rig-bridge must be started first, what the 'port already
in use' log message means, and how to recover.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Two root causes were producing spurious PTT=true in the Yaesu USB plugin:

1. IF; response PTT field is position-unreliable across models.
   The TX/RX flag at position 22 was confirmed only on the FT-991A.
   On FT-891, FT-710, FT-DX10 etc. the "unknown" byte at position 4
   may be absent, shifting all subsequent fields left by one — so the
   memory channel digit ('1' for channels 100-199) lands at position 22
   and triggers PTT=TX. Remove PTT parsing from case 'IF' entirely.

2. Missed auto-info TX0; (unkey) had no short-term recovery path.
   The 30-second keepalive was the only mechanism to recover a stuck
   PTT=true after the radio released TX.

Fix: add TX; (bare = read query, not set command) to the startup
sequence (IF;TX;) and to the 30-second keepalive (AI1;IF;TX;).
PTT state is now sourced exclusively from TX;/RX; responses, which
use an unambiguous 3-character format (TX0;/TX1;/TX2;) that is
consistent across all FT-series models.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ening

Feature/rig bridge security hardening & other enhancements
@MichaelWheeley MichaelWheeley merged commit 127969a into MichaelWheeley:feature/thai-language-dev Mar 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants