feat(content-gate): personalized institutional access verification page#4596
Conversation
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.
There was a problem hiding this comment.
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_idto 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 RESTfetchfrom 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.
…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.
There was a problem hiding this comment.
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.
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.
dkoo
left a comment
There was a problem hiding this comment.
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.
|
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. |
|
Hey @miguelpeixe, good job getting this PR merged! 🎉 Now, the 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! ❤️ |
# [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))
|
🎉 This PR is included in version 6.37.0-alpha.1 🎉 The release is available on GitHub release Your semantic-release bot 📦🚀 |
# [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))
|
🎉 This PR is included in version 6.37.0 🎉 The release is available on GitHub release Your semantic-release bot 📦🚀 |

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:
/institutional-access/endpoint still works as before (no personalization).redirect_toparam works on institution permalinks:/institutional-access/<slug>/?redirect_to=/some-page/.Other information: