Add a Site Health connection test and debug information section#192
Merged
Conversation
…ecrypted Salt rotation (a security plugin's scheduled rotation, a migration, or a regenerated wp-config.php) changes the key the OAuth tokens are encrypted with, leaving them permanently unreadable. Previously every publish then failed with a retry hint that could never succeed (see the 'inconsistent post visibility' wp.org support topic). - Flag the connection needs_reauth on decrypt failure (race-guarded on the ciphertext field that actually failed), so publishing short-circuits and the admin reconnect notice appears. - Persist a domain-separated fingerprint of the encryption key with the connection and use it to tell 'security keys changed' apart from corrupted data, with cause-specific notice copy. - Swap the editor-panel error for a reconnect link when re-saving cannot help. - Support an ATMOSPHERE_ENCRYPTION_KEY constant that takes precedence over AUTH_KEY/AUTH_SALT for sites that rotate salts deliberately.
Surfaces the Bluesky connection state where users and supporters actually look when something is wrong. The status test maps each connection state to the right severity, and the key-changed case guides the user to the ATMOSPHERE_ENCRYPTION_KEY constant so the next salt rotation doesn't break the connection again. The debug panel (version, connection status + reason, handle, DID, PDS endpoint, encryption key source, auto-publish, post types — no key or token material) makes support threads self-diagnosing. Mirrors the wordpress-activitypub Health_Check layout.
…te Health guidance Mirrors WordPress's own secret-key service: instead of a placeholder the user has to know how to replace, the key-changed guidance renders a define() line with a freshly generated 64-character random key that can be copied into wp-config.php as-is. Generated per render, never stored; wp_generate_password()'s character set contains no quotes or backslashes, so the value is safe in a single-quoted literal.
…rrors server-side Quality pass over the recovery work: - New helpers in functions.php — settings_url(), is_operator_disconnected() (owning the stale-marker rationale), get_reauth_reason() — replace triplicated predicates across the admin surfaces. - The reauth_reason vocabulary becomes Client::REAUTH_REASON_* constants; a mistyped string comparison failed soft to the generic expiry copy. - The publish-error REST field now carries a server-computed needs_reconnect flag, so the editor panel no longer hand-mirrors the PHP error-code list across languages. - Encryption::has_dedicated_key() owns the defined-and-non-empty check reused by the admin surfaces. - The reauth notice composes one shared tail sentence with per-cause lead sentences instead of four near-identical 40-word strings, and the key-changed wording is aligned with Site Health. - mark_needs_reauth() requires the guard field explicitly.
Quality pass: a single connection_state() resolver feeds both the status test and the debug panel instead of two parallel state ladders; the reauth reason and operator-disconnect gates now come from the shared helpers and Client::REAUTH_REASON_* constants; the dedicated-key probe reuses Encryption::has_dedicated_key().
…ze decrypt handling - Share the reauth cause sentences between the admin notice and Site Health via a single reauth_reason_lead() helper. - Register the Site Health filters only on admin and cron requests. - Use settings_url() for the remaining hardcoded admin redirects. - Move the needs_reconnect judgment into Client::is_reconnect_error(), next to the code paths that mint those error codes. - Route all connection-credential decrypts through Client::decrypt_field() so a failed decrypt always flags the row for reauth.
Contributor
There was a problem hiding this comment.
Pull request overview
Adds a WordPress Site Health integration to surface ATmosphere’s Bluesky connection state in both the Status tests and the Info → Debug information panel, making connection problems and reconnect guidance visible in a standard, support-friendly place. It also refactors a couple of connection/reconnect helpers so the same reconnect “cause” copy and reconnect classification logic is reused consistently across surfaces.
Changes:
- Introduces a new Site Health direct test plus an ATmosphere debug-information section (connection status, identity details, encryption key source, publishing config).
- Adds PHPUnit coverage to ensure each connection state maps to the intended Site Health severity and copy (including key-change guidance).
- Refactors shared connection helpers (centralized reconnect lead copy, centralized “needs reconnect” error classification, and a decrypt helper that flags reauth on failure).
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
includes/wp-admin/class-health-check.php |
Implements Site Health status test + debug info section, including key-change specific guidance/snippet. |
includes/class-atmosphere.php |
Wires the Site Health integration during admin requests and cron-run scheduled Site Health checks. |
tests/phpunit/tests/wp-admin/class-test-health-check.php |
Adds coverage for the status test + debug-information output across connection states. |
includes/functions.php |
Adds reauth_reason_lead() and settings_url() helpers used by multiple UI surfaces. |
includes/wp-admin/class-admin.php |
Reuses shared reconnect-lead copy and shared settings URL for redirects/notices. |
includes/oauth/class-client.php |
Adds decrypt_field() and centralizes reconnect-only error codes via is_reconnect_error(). |
includes/class-api.php |
Uses Client::decrypt_field() for dpop_jwk decrypt + consistent failure handling. |
.github/changelog/add-site-health-check |
Adds an end-user changelog entry for the new Site Health feature. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
# Conflicts: # build/editor-plugin/plugin.asset.php # build/editor-plugin/plugin.js # build/pre-publish-panel/plugin.asset.php # build/pre-publish-panel/plugin.js # docs/developer-docs.md # includes/class-api.php # includes/class-atmosphere.php # includes/class-block-editor.php # includes/functions.php # includes/oauth/class-client.php # includes/oauth/class-encryption.php # includes/wp-admin/class-admin.php # src/config.js # src/editor-plugin/plugin.js # tests/phpunit/tests/oauth/class-test-client-decrypt.php
… filters lazily The merge left Atmosphere's RECONNECT_ERROR_CODES const behind after both consumers moved to Client::is_reconnect_error() — delete it so the list really is declared once. Register the Site Health filters directly on the pull filters instead of a context-gated init hook: they only fire on Site Health surfaces (screen, weekly check, WP-CLI), so the class loads only there and the is_admin/cron gate — which missed the WP-CLI context — goes away. Use the canonical get_did() and get_pds_endpoint() accessors in the debug panel.
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.
Follow-up to #191 (based on that branch — the status test reads the
reauth_reasonmarker it introduces; will auto-retarget totrunkwhen #191 merges).Proposed changes:
Adds a Site Health integration (mirroring the wordpress-activitypub
Health_Checklayout), so connection problems are visible where users — and the people supporting them — actually look:ATMOSPHERE_ENCRYPTION_KEYinwp-config.phpbefore reconnecting so the next salt rotation doesn't break the connection again — and if the constant is defined but its value changed, says exactly that instead.Registered unconditionally on
init(not admin-gated) because the weeklywp_site_health_scheduled_checkcron runs direct tests in a non-admin context to feed the dashboard status counter.Other information:
Testing instructions:
npm run env-start) and open Tools → Site Health with no Bluesky account connected. Expected: a "recommended" item saying ATmosphere is not connected yet, linking to the settings page; the Info tab has an ATmosphere section with status "Not connected".npm run wp-env run cli wp config shuffle-salts) and publish a post to trip the decrypt failure. Expected: Site Health shows a critical issue explaining the security keys changed, with thedefine( 'ATMOSPHERE_ENCRYPTION_KEY', … );snippet and a settings-page link; the Info tab's connection status reads "Needs reconnect (security keys changed)".composer lintandnpm run env-testpass (929 tests).Changelog entry
Entry committed on the branch (
.github/changelog/add-site-health-check).Changelog Entry Details
Significance
Type
Message