Skip to content

[Task]: Sync Consent_Handler with the AI server's consent endpoints #23286

@thijsoo

Description

@thijsoo

Context — Why was this issue created?

Today, Consent_Handler (src/ai/consent/application/consent-handler.php) only stores or removes the _yoast_wpseo_ai_consent user meta in WordPress. The AI server is never informed when a user grants or revokes consent, so the server has no authoritative record of per-user consent and cannot enforce or audit it.

The AI server already exposes the necessary endpoints:

  • Grant: POST to the Consent endpoint — see grantConsent.
  • Revoke: the corresponding revoke operation on the same Consent resource.

Goal

Make Consent_Handler::grant_consent() and Consent_Handler::revoke_consent() also notify the AI server, so that the server's consent state stays in sync with the WordPress user meta.

What needs to be done

  • Extend Yoast\WP\SEO\AI\Consent\Application\Consent_Handler so that:
    • grant_consent() calls the AI server's grant-consent endpoint after writing the user meta.
    • revoke_consent() calls the AI server's revoke-consent endpoint before/after clearing the user meta.
  • Use the existing API_Client in src/ai/http-request/infrastructure/api-client.php — do not introduce a new HTTP client. Inject it through constructor DI; the container will rewire automatically after composer compile-di.
  • Wire the call through the existing Yoast\WP\SEO\AI\HTTP_Request\Application\Request_Handler so we get the standardised error mapping (Unauthorized_Exception, Forbidden_Exception, etc.) already handled in Consent_Route::consent().
  • Make sure the request is authenticated for the current user (consent is per-user). Reuse the same token plumbing used by other AI requests; coordinate with Token_Manager since it already depends on Consent_Handler.
  • Decide how to handle a failed server-side call:
    • On grant: if the server call fails, the local meta should not be left in an inconsistent state (either roll back or surface the error so the route returns 500).
    • On revoke: the local meta and token must still be invalidated even if the remote revoke fails (security-first); the failure should be logged.

UX or research needed

No UX work. Backend-only change.

Tips / possible solutions

  • The API base URL is filtered via Yoast\WP\SEO\ai_api_url, so the staging vs. production switch is already handled — no new config needed.
  • Consent_Route::consent() already catches the full set of HTTP-request exceptions and returns a 500 on failure, so propagating exceptions from Consent_Handler is the path of least resistance.
  • Watch out for the circular dependency risk: Token_Manager already depends on Consent_Handler. If the consent call needs a valid token, inject Request_Handler (not Token_Manager) into Consent_Handler and pass the token explicitly from the route.

Expected result / behaviour

  • When a user grants consent in the UI, the AI server receives a POST to its consent endpoint with that user's identity, in addition to the local user-meta write.
  • When a user revokes consent, the AI server receives the corresponding revoke call, the local user meta is deleted, and the token is invalidated (the latter two are already the case today).
  • Unit tests cover the new HTTP interaction for both grant_consent() and revoke_consent(), including the failure paths.

Documentation

No public documentation needed. Update the inline class docblock of Consent_Handler so it reflects the new responsibility (local meta + remote sync).

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No fields configured for Epic.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions