Skip to content

Validate BMLT root server on save (reject invalid/unreachable hostnames) [#282]#283

Merged
dgershman merged 2 commits into
mainfrom
feature/mayo-282-validate-root-server
May 23, 2026
Merged

Validate BMLT root server on save (reject invalid/unreachable hostnames) [#282]#283
dgershman merged 2 commits into
mainfrom
feature/mayo-282-validate-root-server

Conversation

@dgershman

Copy link
Copy Markdown
Contributor

Closes #282

Problem

The BMLT root server URL in Mayo settings was saved with only sanitize_text_field() — no check that it's a well-formed URL, let alone a real, reachable BMLT root server. A typo, a non-URL string, an http:// server, or a URL that isn't a BMLT root server was persisted silently and only surfaced later as broken/empty event lookups, with no indication that the root server was the cause.

Changes

  • New RootServerValidator helper (includes/Rest/Helpers/RootServerValidator.php) — layered checks, cheapest first:
    1. Format — reject anything that isn't a valid absolute URL (esc_url_raw() + wp_http_validate_url()), normalized with no trailing slash.
    2. Scheme — require https:// (mirrors the existing client-side rule).
    3. ReachabilityGET {url}/client_interface/json/?switcher=GetServerInfo via wp_remote_get() with a bounded 10s timeout; require HTTP 200 + JSON that looks like BMLT server info (a version field).
  • Save path (SettingsController::update_settings) — validates only when the value changes, and returns early on failure before any update_option(), so the previously stored value is preserved. Saving unrelated settings never triggers a network call; clearing to empty is allowed.
  • POST /validate-root-server (admin-only) + a "Test connection" button in the Settings UI to verify without saving.
  • apiFetch now surfaces the REST error message so the clear validation error reaches the user.
  • Changelog entry in readme.txt; regenerated languages/mayo-events-manager.pot for the new strings.

Acceptance criteria

  • Saving a malformed / non-URL bmlt_root_server is rejected with a clear error; previous value preserved.
  • Saving a well-formed URL that is not a reachable BMLT root server is rejected with a clear error.
  • Saving a valid, reachable BMLT root server succeeds as today.
  • Validation has a bounded (10s) timeout.
  • Unit coverage for the validator (valid/reachable, malformed, non-https, unreachable, non-200, reachable-but-not-BMLT) plus save-path reject/preserve and the new endpoint.

Testing

  • composer test526 tests pass (12 new).
  • composer lint — clean.
  • npm run build — compiles successfully.

🤖 Generated with Claude Code

dgershman and others added 2 commits May 23, 2026 10:55
…es [#282]

The BMLT root server URL was previously saved with only sanitize_text_field(),
so a typo, a non-URL string, an http:// server, or a URL that isn't a BMLT
root server was persisted silently and only surfaced later as broken/empty
event lookups.

Add RootServerValidator with layered checks (format -> https scheme -> live
GetServerInfo handshake with a bounded 10s timeout). Wire it into the settings
save path so an invalid or unreachable root server is rejected with a clear
error before anything is persisted, preserving the previously stored value.
Validation runs only when the value actually changes, so saving unrelated
settings never triggers a network call.

Also add an admin-only /validate-root-server REST endpoint and a "Test
connection" button in the Settings UI to verify without saving, and surface
REST error messages in the apiFetch wrapper.

Covered by new unit tests for the validator (valid/reachable, malformed,
non-https, unreachable, non-200, reachable-but-not-BMLT) and the save path
(reject + previous-value-preserved) and the new endpoint.

🐦‍⬛ Generated with Claude Code, orchestrated by Crow

Co-Authored-By: Claude <noreply@anthropic.com>
Crow-Session: 202F8173-BB91-4E6F-B986-1CE19C339F1A
…282]

Place the BMLT root server URL input and the Test connection button in a
single flex row (button vertically centered on the input) instead of stacking
the button below the field.

🐦‍⬛ Generated with Claude Code, orchestrated by Crow

Co-Authored-By: Claude <noreply@anthropic.com>
Crow-Session: 202F8173-BB91-4E6F-B986-1CE19C339F1A
@dgershman dgershman merged commit 80de76e into main May 23, 2026
3 checks passed
@dgershman dgershman deleted the feature/mayo-282-validate-root-server branch May 23, 2026 15:33
@dgershman dgershman linked an issue May 23, 2026 that may be closed by this pull request
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.

Validate BMLT root server on save (reject invalid/unreachable hostnames) API retrieval of service bodies fails

1 participant