Skip to content

feat(content-gate): personalized institutional access verification page#4596

Merged
miguelpeixe merged 15 commits intotrunkfrom
feat/institutional-access-personalized-loading
Mar 25, 2026
Merged

feat(content-gate): personalized institutional access verification page#4596
miguelpeixe merged 15 commits intotrunkfrom
feat/institutional-access-personalized-loading

Conversation

@miguelpeixe
Copy link
Copy Markdown
Member

@miguelpeixe miguelpeixe commented Mar 24, 2026

All Submissions:

Changes proposed in this Pull Request:

Each institution now has its own access verification page at /institutional-access/{$slug}/. When a reader visits this URL, they see a personalized loading page with the institution's name and logo, and their access is verified against the institution's rules (IP range, email domain, and user data).

Publishers can set a featured image (logo) for each institution in the edit form.

Builds on #4593.

How to test the changes in this Pull Request:

  1. Create an institution with an IP range matching your local IP.
  2. Upload a logo via the new "Logo" field in the institution edit form. Save.
  3. Copy the institution access page URL from the list kebab menu.
  4. Paste in a fresh window and verify the loading page shows the institution's logo and name ("Verifying your access to University…").
  5. After verification, confirm you are redirected with a success snackbar showing the institution name.
  6. Remove your IP from the institution's range and revisit the permalink. Verify the error state appears with "Try again" and "Continue to site" buttons.
  7. Test an institution without a featured image — the loading page should still work, just without the logo.
  8. Test the generic /institutional-access/ endpoint still works as before (no personalization).
  9. Verify the redirect_to param works on institution permalinks: /institutional-access/<slug>/?redirect_to=/some-page/.
  10. In the admin, verify removing the logo works (click Remove, save, reload).

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?

Support ?institutional-access=1 query param on any URL with redirect
back to the same page. Add dedicated /institutional-access endpoint
with loading page, REST API for IP check, snackbar feedback with
institution name, and redirect_to param support.
Remove unused Newspack import, add leading slash to REST route,
prevent cache pollution on result pages, and add unit tests for
the REST endpoint, redirect URL building, and open redirect protection.
Use institution permalink as access verification page with institution-
specific checks. Add featured image support to institutions and display
it on the loading page. REST endpoint now accepts institution_id param
for targeted access checks using all institution rules.
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 per-institution “institutional access” permalinks that render a personalized verification/loading page (name + logo) and verifies access against a specific institution’s rules, while keeping the generic /institutional-access/ flow intact.

Changes:

  • Extends Institution editing UI/types to support setting a logo via featured_media.
  • Adds support for institution_id to the institutional access REST check and personalizes the loading page output (title/message/logo).
  • Exposes institution permalinks by updating the Institution CPT rewrite and intercepting singular institution requests to render the verification page.

Reviewed changes

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

File Description
src/wizards/audience/views/content-gates/types/index.d.ts Adds featured_media to Institution typing to support a per-institution logo.
src/wizards/audience/views/content-gates/institutions/edit.tsx Adds logo upload UI and resolves featured_media to an attachment for display/saving.
includes/content-gate/class-ip-access-rule.php Adds institution_id REST arg and personalization support in the loading page.
includes/content-gate/class-institution.php Makes institution permalinks available under /institutional-access/<slug>/ and renders personalized verification output on singular views.
Comments suppressed due to low confidence (1)

includes/content-gate/class-ip-access-rule.php:350

  • The IIFE returns early (return;) right after setting up the timeout/AbortController, which prevents the REST fetch from ever running. This will leave the page stuck until timeout and never redirect on success.
				var controller = new AbortController();
				var timer = setTimeout( function() {
					controller.abort();
					showError(
						<?php echo wp_json_encode( __( 'Verification timed out.', 'newspack-plugin' ) ); ?>,
						<?php echo wp_json_encode( __( 'Please check your connection and try again.', 'newspack-plugin' ) ); ?>
					);
				}, <?php echo (int) $timeout_ms; ?> );

				var minDelay = new Promise( function( resolve ) { setTimeout( resolve, 1000 ); } );

				Promise.all( [

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

Comment thread includes/content-gate/class-ip-access-rule.php Outdated
Comment thread includes/content-gate/class-institution.php
Comment thread includes/content-gate/class-ip-access-rule.php
…tion pages

Replace publicly_queryable CPT approach with a custom rewrite rule for
/institutional-access/<slug>/. This keeps the CPT fully private, avoids
REST API data leaks, and simplifies the implementation. Also bypass the
uncached gate for IP checks on the REST endpoint and add tests for the
institution_id param.
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 5 out of 6 changed files in this pull request and generated 4 comments.


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

Comment thread src/wizards/audience/views/content-gates/institutions/index.tsx Outdated
Comment thread tests/unit-tests/content-gate/class-ip-access-rule.php
Comment thread tests/unit-tests/content-gate/class-ip-access-rule.php
Comment thread tests/unit-tests/content-gate/class-ip-access-rule.php
Add error handling for clipboard API, properly restore REMOTE_ADDR
in tests using unset when originally absent, and suppress header
warnings in REST endpoint tests.
@miguelpeixe miguelpeixe marked this pull request as ready for review March 24, 2026 18:59
@miguelpeixe miguelpeixe requested a review from a team as a code owner March 24, 2026 18:59
@miguelpeixe miguelpeixe self-assigned this Mar 24, 2026
@miguelpeixe miguelpeixe added [Status] Needs Design Review [Status] Needs Review The issue or pull request needs to be reviewed labels Mar 24, 2026
Base automatically changed from feat/institutional-access-redirect to trunk March 25, 2026 15:39
Copy link
Copy Markdown
Contributor

@dkoo dkoo left a comment

Choose a reason for hiding this comment

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

Works well and looks great on the front-end! Adding per-institution share links with a feature to copy the link also makes this feature feel much more mature and publisher-friendly.

Some possible enhancements: we could also add a simple text input to the institution edit page to enter a redirect URL (which would simply append the encoded URL string with the redirect_to param to the share URL) and add a button inside the edit page to copy the link (currently only available in the DataView table). But these are nice-to-haves and not at all blocking.

@github-actions github-actions Bot added the [Status] Approved The pull request has been reviewed and is ready to merge label Mar 25, 2026
@github-actions github-actions Bot removed the [Status] Needs Review The issue or pull request needs to be reviewed label Mar 25, 2026
@miguelpeixe
Copy link
Copy Markdown
Member Author

Thanks, @dkoo!

I like this idea, but it adds some new UI that I'd like @thomasguillot's input before working on it. Since this is not a blocker, I'll merge this one and we can improve in another PR.

@miguelpeixe miguelpeixe merged commit 0eed591 into trunk Mar 25, 2026
9 checks passed
@miguelpeixe miguelpeixe deleted the feat/institutional-access-personalized-loading branch March 25, 2026 17:11
@github-actions
Copy link
Copy Markdown

Hey @miguelpeixe, good job getting this PR merged! 🎉

Now, the needs-changelog label has been added to it.

Please check if this PR needs to be included in the "Upcoming Changes" and "Release Notes" doc. If it doesn't, simply remove the label.

If it does, please add an entry to our shared document, with screenshots and testing instructions if applicable, then remove the label.

Thank you! ❤️

@thomasguillot
Copy link
Copy Markdown
Contributor

Screenshot 2026-03-26 at 13 12 13@2x

Copy access page URL should be in this kebab menu too.

For the redirect URL, we could add an optional field as part of the access rules.

matticbot pushed a commit that referenced this pull request Apr 2, 2026
# [6.37.0-alpha.1](v6.36.1...v6.37.0-alpha.1) (2026-04-02)

### Bug Fixes

* **card-settings-group:** change default actionType from chevron to none ([#4610](#4610)) ([00505ed](00505ed))
* **post-date:** preserve classic theme markup and fix archive titles ([#4602](#4602)) ([c5fb825](c5fb825))
* remove removal of block visibility ([#4595](#4595)) ([9396379](9396379))

### Features

* **access-control:** filter available lists by content restrictions ([#4589](#4589)) ([959127f](959127f)), closes [#4581](#4581) [#4583](#4583) [#4590](#4590)
* **access-control:** premium newsletters UI ([#4577](#4577)) ([6f8c891](6f8c891)), closes [#4581](#4581) [#4583](#4583) [#4590](#4590)
* **author-profile-social:** add support for colors, block spacing, brand style ([#4509](#4509)) ([21cf4c9](21cf4c9))
* campaigns wizard light UI refresh ([#4588](#4588)) ([6078c4b](6078c4b))
* **color-picker:** simplify component to use basecontrol ([#4581](#4581)) ([ff677ea](ff677ea))
* **components:** add CardFeature component ([#4583](#4583)) ([5aabb18](5aabb18))
* **content-gate:** institution management ui ([#4582](#4582)) ([ae88750](ae88750))
* **content-gate:** institutional access redirect and loading UX ([#4593](#4593)) ([548d236](548d236))
* **content-gate:** institutions ([#4574](#4574)) ([49b0c05](49b0c05))
* **content-gate:** personalized institutional access verification page ([#4596](#4596)) ([0eed591](0eed591))
* **image-upload:** simplify component to use basecontrol; remove info prop ([#4580](#4580)) ([d51eb54](d51eb54))
* **integrations:** add ActionScheduler group handling ([#4559](#4559)) ([411732a](411732a))
* **integrations:** promoted fields for content gate and campaign segmentation ([#4601](#4601)) ([f943df2](f943df2))
* **newspack-ui:** add stack layout and color utility classes ([#4600](#4600)) ([1934067](1934067))
* **post-date:** centralize date features from theme into plugin ([#4579](#4579)) ([19f15eb](19f15eb))
* **sync:** prevent stale data on retry, improve logging and error handling ([#4562](#4562)) ([5467f34](5467f34))
* **tags:** add private tags feature ([#4507](#4507)) ([06d7711](06d7711))
* **yoast:** add primary category utility and settings toggle ([#4563](#4563)) ([4b396c3](4b396c3))
@github-actions
Copy link
Copy Markdown

github-actions Bot commented Apr 2, 2026

🎉 This PR is included in version 6.37.0-alpha.1 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

matticbot pushed a commit that referenced this pull request Apr 13, 2026
# [6.37.0](v6.36.3...v6.37.0) (2026-04-13)

### Bug Fixes

* **card-settings-group:** change default actionType from chevron to none ([#4610](#4610)) ([00505ed](00505ed))
* **post-date:** preserve classic theme markup and fix archive titles ([#4602](#4602)) ([c5fb825](c5fb825))
* remove removal of block visibility ([#4595](#4595)) ([9396379](9396379))

### Features

* **access-control:** filter available lists by content restrictions ([#4589](#4589)) ([959127f](959127f)), closes [#4581](#4581) [#4583](#4583) [#4590](#4590)
* **access-control:** premium newsletters UI ([#4577](#4577)) ([6f8c891](6f8c891)), closes [#4581](#4581) [#4583](#4583) [#4590](#4590)
* **author-profile-social:** add support for colors, block spacing, brand style ([#4509](#4509)) ([21cf4c9](21cf4c9))
* campaigns wizard light UI refresh ([#4588](#4588)) ([6078c4b](6078c4b))
* **color-picker:** simplify component to use basecontrol ([#4581](#4581)) ([ff677ea](ff677ea))
* **components:** add CardFeature component ([#4583](#4583)) ([5aabb18](5aabb18))
* **content-gate:** institution management ui ([#4582](#4582)) ([ae88750](ae88750))
* **content-gate:** institutional access redirect and loading UX ([#4593](#4593)) ([548d236](548d236))
* **content-gate:** institutions ([#4574](#4574)) ([49b0c05](49b0c05))
* **content-gate:** personalized institutional access verification page ([#4596](#4596)) ([0eed591](0eed591))
* **image-upload:** simplify component to use basecontrol; remove info prop ([#4580](#4580)) ([d51eb54](d51eb54))
* **integrations:** add ActionScheduler group handling ([#4559](#4559)) ([411732a](411732a))
* **integrations:** promoted fields for content gate and campaign segmentation ([#4601](#4601)) ([f943df2](f943df2))
* **newspack-ui:** add stack layout and color utility classes ([#4600](#4600)) ([1934067](1934067))
* **post-date:** centralize date features from theme into plugin ([#4579](#4579)) ([19f15eb](19f15eb))
* **sync:** prevent stale data on retry, improve logging and error handling ([#4562](#4562)) ([5467f34](5467f34))
* **tags:** add private tags feature ([#4507](#4507)) ([06d7711](06d7711))
* **yoast:** add primary category utility and settings toggle ([#4563](#4563)) ([4b396c3](4b396c3))
@github-actions
Copy link
Copy Markdown

🎉 This PR is included in version 6.37.0 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

[Status] Approved The pull request has been reviewed and is ready to merge [Status] Needs Design Review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants