Skip to content

Protect Dashboard: Add a feature-flagged module that takes over the Protect page - #53182

Merged
enejb merged 14 commits into
trunkfrom
add/protect-dashboard-module
Oct 7, 2026
Merged

enejb merged 14 commits into
trunkfrom
add/protect-dashboard-module

Conversation

@enejb

@enejb enejb commented Oct 5, 2026 •

Copy link
Copy Markdown
Member

Fixes JETPACK-2930

Part of JETPACK-2879, JETPACK-2884

Contributes to JETPACK-2872

Proposed changes

  • Add a jetpack-protect-dashboard feature flag, off by default. While it is off, it removes the new protect-dashboard module from jetpack_get_available_modules, so the module can't be activated, doesn't load, and isn't listed.
  • Add a protect-dashboard module. Its slug isn't protect because that is already Brute Force protection. When active, it registers a Protect sidebar item on admin.php?page=jetpack-protect, the same address the Jetpack Protect plugin uses, so Protect's URL never changes.
  • When the Jetpack Protect plugin is also active, the module takes the page over instead of adding a second item. The plugin registers its item on _admin_menu; at admin_menu priority 999 (before Admin_Menu registers items at 1000), the module removes that item and the plugin's load- hooks for the page, then adds its own. The sidebar always shows one Protect item. The plugin's admin-bar link, threat-count badge and My Jetpack's manage link already point at page=jetpack-protect, so they follow along.
  • Put the dashboard in the shared packages/protect package (automattic/jetpack-protect, added in Protect: Rename plugin Composer package and add packages/protect #53298), so the Jetpack plugin's protect-dashboard module and, later, the Jetpack Protect plugin can share it. The Protect plugin doesn't use it yet; that's a follow-up.
  • The package holds the wp-build route (routes/dashboard, page id jetpack-protect-dashboard), the Automattic\Jetpack\Protect\Dashboard class that adds the menu item and loads the package's own build/, and its tests. For now the page only shows a "Protect" title.
  • The Jetpack plugin keeps only the feature flag and modules/protect-dashboard.php, which calls Dashboard::init() with the module name so the menu item is tied to the module.
  • My Jetpack: the Protect feature's delivery.jetpack now follows the flag, by checking whether the protect-dashboard module is on offer. With the flag on, the Features-tab Protect card treats Protect as part of Jetpack and switches the protect-dashboard module, instead of offering to install the Jetpack Protect plugin.
  • My Jetpack: Protect's manage link points at page=jetpack-protect once the dashboard has loaded. Dashboard::init() fires jetpack_protect_dashboard_initialized for this, the same way Backup signals its page.
  • The Jetpack plugin now requires the package. The pnpm-lock.yaml change is just the package's importer entry, which now has dependencies.

Related product discussion/links

Does this pull request change what data or activity we track or use?

No.

Testing instructions

  1. Build and sync the Jetpack plugin to a connected test site, e.g. a Jurassic Ninja site with JETPACK_AUTOLOAD_DEV set. Install and activate the Jetpack Protect plugin too.
  2. Flag off (default):
    • wp jetpack module activate protect-dashboard should fail with "protect-dashboard is not a valid module".
    • The sidebar should show one Protect item, and admin.php?page=jetpack-protect should render the Jetpack Protect plugin's page.
    • My Jetpack → Features: the Protect card should still offer the Jetpack Protect plugin.
  3. Turn the flag on, either from the Jurassic Ninja feature-flag UI or with wp companion feature-flag enable jetpack-protect-dashboard.
  4. Activate the module with wp jetpack module activate protect-dashboard, or with the Protect switch in My Jetpack → Features.
  5. Flag on, module on:
    • There should still be exactly one Protect item, linking to admin.php?page=jetpack-protect.
    • The page should be the new blank wp-build page titled "Protect", and none of the Jetpack Protect plugin's scripts should load on it.
  6. Deactivate the Jetpack Protect plugin. The Protect item and the new page should stay.
  7. Reactivate the plugin, then deactivate the module. The item should point back to the plugin's own page.
  8. Turn the flag off again with wp companion feature-flag disable jetpack-protect-dashboard. The plugin's page should return even though the module is still stored as active.

@enejb enejb self-assigned this Oct 5, 2026
@github-actions

github-actions Bot commented Oct 5, 2026 •

Copy link
Copy Markdown
Contributor

Are you an Automattician? Please test your changes on all WordPress.com environments to help mitigate accidental explosions.

  • To test on WoA, go to the Plugins menu on a WoA dev site. Click on the "Upload" button and follow the upgrade flow to be able to upload, install, and activate the Jetpack Beta plugin. Once the plugin is active, go to Jetpack > Jetpack Beta, select your plugin (Jetpack or WordPress.com Site Helper), and enable the add/protect-dashboard-module branch.
  • To test on Simple, run the following command on your sandbox:
bin/jetpack-downloader test jetpack add/protect-dashboard-module
bin/jetpack-downloader test jetpack-mu-wpcom-plugin add/protect-dashboard-module

Interested in more tips and information?

  • In your local development environment, use the jetpack rsync command to sync your changes to a WoA dev blog.
  • Read more about our development workflow here: PCYsg-eg0-p2
  • Figure out when your changes will be shipped to customers here: PCYsg-eg5-p2

@github-actions github-actions Bot added [Feature] Protect Dashboard [Plugin] Jetpack Issues about the Jetpack plugin. https://wordpress.org/plugins/jetpack/ labels Oct 5, 2026
@github-actions

github-actions Bot commented Oct 5, 2026 •

Copy link
Copy Markdown
Contributor

Thank you for your PR!

When contributing to Jetpack, we have a few suggestions that can help us test and review your patch:

  • ✅ Include a description of your PR changes.
  • ✅ Add a "[Status]" label (In Progress, Needs Review, ...).
  • ✅ Add testing instructions.
  • ✅ Specify whether this PR includes any changes to data or privacy.
  • ✅ Add changelog entries to affected projects

This comment will be updated as you work on your PR and make changes. If you think that some of those checks are not needed for your PR, please explain why you think so. Thanks for cooperation 🤖


Follow this PR Review Process:

  1. Ensure all required checks appearing at the bottom of this PR are passing.
  2. Make sure to test your changes on all platforms that it applies to. You're responsible for the quality of the code you ship.
  3. You can use GitHub's Reviewers functionality to request a review.
  4. When it's reviewed and merged, you will be pinged in Slack to deploy the changes to WordPress.com simple once the build is done.

If you have questions about anything, reach out in #jetpack-developers for guidance!


Jetpack plugin:

No scheduled milestone found for this plugin.

If you have any questions about the release process, please ask in the #jetpack-releases channel on Slack.


Inspect plugin:

No scheduled milestone found for this plugin.

If you have any questions about the release process, please ask in the #jetpack-releases channel on Slack.

@jp-launch-control

jp-launch-control Bot commented Oct 5, 2026 •

Copy link
Copy Markdown

Code Coverage Summary

Coverage changed in 3 files.

File Coverage Δ% Δ Uncovered
projects/plugins/jetpack/load-jetpack.php 0/60 (0.00%) 0.00% 1 ❤️‍🩹
projects/plugins/jetpack/modules/module-headings.php 1120/1156 (96.89%) -0.03% 1 ❤️‍🩹
projects/packages/my-jetpack/src/products/class-protect.php 184/202 (91.09%) 0.50% -1 💚

3 files are newly checked for coverage.

File Coverage
projects/plugins/jetpack/modules/protect-dashboard.php 0/4 (0.00%) 💔
projects/plugins/jetpack/_inc/lib/class-jetpack-protect-dashboard-feature-flags.php 3/15 (20.00%) 💔
projects/packages/protect/src/class-dashboard.php 45/67 (67.16%) 💚

Full summary · PHP report · JS report

Coverage check overridden by Covered by non-unit tests Use to ignore the Code coverage requirement check when E2Es or other non-unit tests cover the code .

'delivery' => array(
'jetpack' => false,
// The flag is registered by the Jetpack plugin, which owns the `protect-dashboard` module.
'jetpack' => Feature_Flags::is_enabled( 'jetpack-protect-dashboard' ),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pushed two commits: one points My Jetpack's Protect manage link at the new page when the module is active without the standalone plugin (it was going to protect-details or Jetpack Cloud), the other adds tests for the flag gate and the menu takeover.

One thing I left alone. With the flag on, the Protect plugin active and the module off, the Features card reads Off while Protect is running. resolveFeatureState() takes the module branch as soon as in_jetpack is true and never looks at plugin_status. The switch then only flips the module, so turning it on swaps the plugin's working dashboard for the blank page.

I tried counting an active plugin as "on" in that branch (the plugin branch below already does), but it applies to every hybrid feature, not just Protect, and it leaves the card saying active while its own switch says off. Bulk on/off gets confused the same way. So I backed it out.

What should that switch mean when both the plugin and the module can deliver the feature? Fine to leave for the PR that fills in the page, but I think it needs an answer before the flag defaults on.

@kraftbj
kraftbj added this pull request to stack #53235 October 6, 2026 16:22
*
* @param bool $in_jetpack Whether the Jetpack plugin delivers Protect. Default false.
*/
'jetpack' => (bool) apply_filters( 'jetpack_my_jetpack_protect_in_jetpack', false ),

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

This used to be just Feature_Flags::is_enabled( self::DASHBOARD ); Do we want to introduce another filter here?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

no, taking that out.

@kraftbj kraftbj added the Covered by non-unit tests Use to ignore the Code coverage requirement check when E2Es or other non-unit tests cover the code label Oct 6, 2026
kraftbj
kraftbj previously approved these changes Oct 6, 2026
@jboland88

Copy link
Copy Markdown
Contributor

Any reason not to go with packages/protect over packages/protect-ui?

Later PRs like #53190 and #53195 start bringing in supporting backend logic and rest routes that go outside the "UI Only" scope implied by the name. I think the package handling the whole of Protect's functionality (UX, API, Jetpack Backend) is correct - but the UI name seems misleading in that case.

@enejb

enejb commented Oct 6, 2026

Copy link
Copy Markdown
Member Author

Any reason not to go with packages/protect over packages/protect-ui?

yeah I wish I could have went with jetpack-protect but since http://github.com/Automattic/jetpack-protect already exist as a repo, so doing that wasn't possible.

I am open to naming suggestions though.

@jboland88

jboland88 commented Oct 7, 2026 •

Copy link
Copy Markdown
Contributor

yeah I wish I could have went with jetpack-protect but since http://github.com/Automattic/jetpack-protect already exist as a repo, so doing that wasn't possible.

Hmm. I was able to set it up:
#53298

This gives us a "Protect" package with the slug jetpack-protect

This does some renaming for the jetapck-protect plugin to use the -plugin suffix, which matches its existing mirror repo at Automattic/jetpack-protect-plugin

Automattic/jetpack-protect was not actually taken yet. It was just redirected by GH to the closest match. I added the new repo for Automattic/jetpack-protect and set it up as a mirror: https://github.com/Automattic/jetpack-protect

This same rename pattern was used when the Search plugin introduced a corresponding package in #21502. Though, fortunately for us, the repo names are already correct and don't need to be changed for protect.

enejb and others added 9 commits October 7, 2026 08:28
With the protect-dashboard module active and no standalone plugin, the link went to protect-details or Jetpack Cloud instead of the Protect page.
My Jetpack no longer depends on the feature flags package, so the Jetpack plugin now reports the flag through jetpack_my_jetpack_protect_in_jetpack.
Drops the filter added earlier. The flag already removes protect-dashboard from the available modules, so My Jetpack can ask whether the module exists.
@enejb
enejb force-pushed the add/protect-dashboard-module branch from a170ed7 to 65fe55c Compare October 7, 2026 15:33
@enejb
enejb force-pushed the add/protect-dashboard-module branch from 65fe55c to f45f123 Compare October 7, 2026 15:41

@kraftbj kraftbj left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Should this page opt out of JITMs the way Activity Log does (jetpack_display_jitms_on_screen)? There's no #jp-admin-notices here, so a fetched JITM would count a view without showing.

@enejb

enejb commented Oct 7, 2026

Copy link
Copy Markdown
Member Author

Should this page opt out of JITMs the way Activity Log does (jetpack_display_jitms_on_screen)?

@kraftbj lets fix this in the follow up? unless there are somethings here that are not ready.

@enejb
enejb merged commit a2689e7 into trunk Oct 7, 2026
118 checks passed
@enejb
enejb deleted the add/protect-dashboard-module branch October 7, 2026 17:48
@github-actions github-actions Bot added [Status] UI Changes Add this to PRs that change the UI so documentation can be updated. and removed [Status] In Progress labels Oct 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Covered by non-unit tests Use to ignore the Code coverage requirement check when E2Es or other non-unit tests cover the code Docs [Feature] Protect Dashboard [Package] My Jetpack [Package] Protect Ui [Package] Protect [Plugin] Inspect [Plugin] Jetpack Issues about the Jetpack plugin. https://wordpress.org/plugins/jetpack/ [Status] UI Changes Add this to PRs that change the UI so documentation can be updated. [Tests] Includes Tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants