Skip to content

feat(reader-activation): frontend registration API for integrations#4626

Draft
jason10lee wants to merge 32 commits intotrunkfrom
feat/integrations-reader-registration
Draft

feat(reader-activation): frontend registration API for integrations#4626
jason10lee wants to merge 32 commits intotrunkfrom
feat/integrations-reader-registration

Conversation

@jason10lee
Copy link
Copy Markdown
Contributor

@jason10lee jason10lee commented Apr 3, 2026

All Submissions:

Changes proposed in this Pull Request:

This PR adds a frontend reader registration API that allows third-party integrations to register readers from the browser, consistent with the existing process_auth_form() registration flow.

Integrations register via the newspack_frontend_registration_integrations filter. Each integration receives a deterministic HMAC key (derived from wp_salt('auth')) that is localized to the page. A new register() method on the newspackReaderActivation JS global handles the full flow: client-side validation, reCAPTCHA v3 token acquisition (when configured), and POST to a new REST endpoint at /newspack/v1/reader-activation/register. On success, the reader is created, authenticated, and the in-memory reader state is updated — matching the behavior of the existing auth modal registration.

Security mitigations follow the same patterns used by process_auth_form():

  • HMAC key validation — binds requests to a PHP-registered integration, preventing arbitrary callers (hash_equals for timing-safe comparison)
  • Honeypot fieldemail is the decoy, npe carries the real address (same convention as the auth form)
  • reCAPTCHA v3 — when configured, a token is acquired client-side and verified server-side via the existing Recaptcha::verify_captcha() bridge
  • Per-IP rate limiting — 10 requests/hour default, using wp_cache_incr with a transient fallback for sites without persistent object cache
  • Logged-in user handling — returns current reader data for authenticated users, making the API idempotent

Addresses NPPD-1070.

How to test the changes in this Pull Request:

We'll be adding a WisePops integration, but while we firm up the foundation, you'll need to create a stub integration to test:

  1. Add a mu-plugin to register a test integration:

    <?php
    add_filter( 'newspack_frontend_registration_integrations', function( $i ) {
        $i['manual-test'] = 'Manual Test';
        return $i;
    } );
  2. Visit the site frontend, view page source, and search for newspack_ras_config. Confirm it contains frontend_registration_integrations with a manual-test entry that has a key value, and a frontend_registration_url pointing to the REST endpoint.

  3. Successful registration — in the browser console:

    newspackReaderActivation.register(
      'test@example.com',
      'manual-test',
      { first_name: 'Test', last_name: 'User' }
    ).then(data => console.log('Success:', data))
     .catch(err => console.error('Error:', err));

    Expected: Success: { success: true, status: "created", email: "test@example.com" }. Verify the user appears in wp-admin Users with display name "Test User" and the customer role.

  4. Duplicate registration — run the same call again with the same email:

    newspackReaderActivation.register(
      'test@example.com',
      'manual-test'
    ).catch(err => console.error('Expected:', err.code, err.message));

    Expected: Expected: reader_already_exists A reader with this email address is already registered.

  5. Unknown integration — use an unregistered integration ID:

    newspackReaderActivation.register(
      'test2@example.com',
      'unknown-tool'
    ).catch(err => console.error('Expected:', err.message));

    Expected: immediate client-side rejection Expected: Unknown integration: unknown-tool

  6. Invalid email:

    newspackReaderActivation.register(
      'not-an-email',
      'manual-test'
    ).catch(err => console.error('Expected:', err.message));

    Expected: client-side rejection Expected: Invalid email address.

  7. Clean up: delete test users from wp-admin and remove the mu-plugin.

Other information:

  • Have you added an explanation of what your changes do and why you'd like us to include them?
  • Have you written new tests for your changes, as applicable?
  • Have you successfully ran tests with your changes locally?

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a public frontend “integration registration” flow for Reader Activation, exposing a new REST endpoint plus a JS API to let third-party scripts register readers from the browser with similar protections as the existing auth modal flow.

Changes:

  • Adds /newspack/v1/reader-activation/register REST endpoint with integration ID/key validation, honeypot, optional reCAPTCHA v3 verification, and per-IP rate limiting.
  • Localizes registered integrations + deterministic HMAC keys and the endpoint URL into newspack_ras_config.
  • Adds newspackReaderActivation.register() JS method and introduces unit tests for endpoint behavior.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 5 comments.

File Description
includes/reader-activation/class-reader-activation.php Localizes integration config and registers a new REST endpoint implementing the server-side registration flow + mitigations.
src/reader-activation/index.js Adds a register() method on the Reader Activation JS global to perform validation, optional reCAPTCHA token acquisition, and POST to the REST endpoint.
tests/unit-tests/reader-registration-endpoint.php Adds unit tests covering success, validation errors, honeypot behavior, logged-in rejection, and rate limiting for the new endpoint.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@jason10lee jason10lee requested a review from miguelpeixe April 7, 2026 21:38
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.

2 participants