Impacted plugin
Jetpack
What
Add filter to allow custom handling of Account Protection verification email
How
Feature Request
Package: jetpack-account-protection — Email_Service::api_send_auth_email()
Problem
The password-detection verification email is sent entirely via the WPCOM API (Client::wpcom_json_api_request_as_blog() → /sites/{id}/jetpack-protect-send-verification-code). The email subject, body, sender, and template are controlled server-side with no local hooks or filters.
Sites that use custom email branding (wrapping all wp_mail() output in branded templates) cannot intercept or customize this email because it never passes through wp_mail(). This creates brand inconsistency — the password-detection login screen can be customized via the branding provider, but the verification email cannot.
Proposed Solution
Add a filter in Email_Service::api_send_auth_email() that fires before the WPCOM API call, allowing sites to handle the email send locally:
$handled = apply_filters(
'jetpack_account_protection_send_auth_email',
false,
$user_id,
$auth_code,
$blog_id
);
if ( $handled ) {
return true;
}
// ...existing WPCOM API call...
When the filter returns a truthy value, the WPCOM API call is skipped — the site is responsible for delivering the email (e.g. via wp_mail()). When no filter is attached, behavior is unchanged.
Use Case
Our client's WordPress VIP multisite uses a wp_mail filter (priority 999) to wrap all outgoing emails in branded HTML templates. Every other email from WordPress core, BuddyPress, and third-party plugins flows through this pipeline. The Account Protection verification email is the only one that bypasses it, resulting in users receiving a Jetpack-branded email after interacting with a fully site-branded login screen.
Alternatives Considered
- Patching
class-email-service.php locally: Works but is fragile across Jetpack updates and not recommended for vendor code.
- Reimplementing the entire verification flow: Disproportionate effort for what is essentially a missing filter.
- Filtering at the transport level (
phpmailer_init): Not possible since the email never enters the local mail pipeline.
Additional Context
- The auth code is already generated locally in
Password_Detection::generate_auth_code() and stored in a transient — the data needed to compose the email is available before the API call.
- A complementary filter for the email subject/body (for sites that still want WPCOM delivery but need content customization) would also be valuable, though the short-circuit filter above covers the primary use case.
Impacted plugin
Jetpack
What
Add filter to allow custom handling of Account Protection verification email
How
Feature Request
Package:
jetpack-account-protection—Email_Service::api_send_auth_email()Problem
The password-detection verification email is sent entirely via the WPCOM API (
Client::wpcom_json_api_request_as_blog()→/sites/{id}/jetpack-protect-send-verification-code). The email subject, body, sender, and template are controlled server-side with no local hooks or filters.Sites that use custom email branding (wrapping all
wp_mail()output in branded templates) cannot intercept or customize this email because it never passes throughwp_mail(). This creates brand inconsistency — the password-detection login screen can be customized via the branding provider, but the verification email cannot.Proposed Solution
Add a filter in
Email_Service::api_send_auth_email()that fires before the WPCOM API call, allowing sites to handle the email send locally:When the filter returns a truthy value, the WPCOM API call is skipped — the site is responsible for delivering the email (e.g. via
wp_mail()). When no filter is attached, behavior is unchanged.Use Case
Our client's WordPress VIP multisite uses a
wp_mailfilter (priority 999) to wrap all outgoing emails in branded HTML templates. Every other email from WordPress core, BuddyPress, and third-party plugins flows through this pipeline. The Account Protection verification email is the only one that bypasses it, resulting in users receiving a Jetpack-branded email after interacting with a fully site-branded login screen.Alternatives Considered
class-email-service.phplocally: Works but is fragile across Jetpack updates and not recommended for vendor code.phpmailer_init): Not possible since the email never enters the local mail pipeline.Additional Context
Password_Detection::generate_auth_code()and stored in a transient — the data needed to compose the email is available before the API call.