Skip to content

[ticket/10282] Unsubscribe from emails without logging in - #7117

Open
marc1706 wants to merge 28 commits into
phpbb:masterfrom
marc1706:ticket/10282
Open

marc1706 wants to merge 28 commits into
phpbb:masterfrom
marc1706:ticket/10282

Conversation

@marc1706

@marc1706 marc1706 commented Nov 7, 2026 •

Copy link
Copy Markdown
Member

Checklist:

  • Correct branch: master for new features; 3.3.x for fixes
  • Tests pass
  • Code follows coding guidelines: master and 3.3.x
  • Commit follows commit message format

Tracker ticket:

https://tracker.phpbb.com/browse/PHPBB-10282

…d sends

Otherwise headers such as List-Unsubscribe carry over to the next message.

PHPBB-10282
Avoids defining the path a second time in the email notification method.

PHPBB-10282
…f days

Links stay valid for 365 days by default, admins can change this in the
email settings. Setting it to 0 keeps links valid until the email address
changes.

PHPBB-10282
One-click requests for emails caused by watching a topic or forum only stop
watching that item, like the stop watching link does, instead of turning
off the whole notification type.

PHPBB-10282
Falls back to the type ID if its language string is not loaded.

PHPBB-10282
…lates

These templates are only sent as notifications, which always set
U_UNSUBSCRIBE. Only admin_activate is also sent directly and keeps the
condition. The test for hidden unsubscribe text only tested the condition
itself, so it is removed as well.

PHPBB-10282
MSSQL requires an explicit value for the identity column of
phpbb_user_notifications.

PHPBB-10282
The email notification method now depends on the router.

PHPBB-10282
Update emails can announce security fixes, so a one-click button in a
mail client must not turn them off. Their emails link to the
notification settings instead and signed links for them are rejected.

PHPBB-10282
…hing

Mail clients may repeat one-click requests. Types that already send no
emails are left alone, so repeated requests do not add log entries.

PHPBB-10282
The user ID from the request is already an integer and matches the
signed user row, so it is used directly instead of the user row.

PHPBB-10282

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 Changes recommended

Approval is blocked by unresolved critical unsubscribe idempotency/concurrency and HTTPS one-click security issues, plus acceptance of stale links for removed notification types.

3 open issues
What changed in this PR

Adds passwordless, signed email-unsubscribe support for notification recipients, including scoped unsubscribe actions, RFC 8058 one-click handling, configurable link expiry, templates, migrations, and automated coverage.

Changes:

  • Adds HMAC-signed unsubscribe URLs bound to the recipient’s current email address.
  • Adds an unauthenticated controller for item, notification-type, and all-email unsubscribe actions.
  • Updates notification templates, messenger headers, routing, configuration, language strings, and tests.

Open issues:

  • Make notification-type disabling idempotent and safe under repeated or concurrent requests.
  • Reject unsubscribe links for notification types that no longer exist.
  • Only emit RFC 8058 one-click headers when the endpoint uses HTTPS.

This pull request requires changes.

File Description
tests/​notification/​submit_post_base.php Provides a router mock for notification tests.
tests/​notification/​notification_method_webpush_test.php Provides router test infrastructure.
tests/​notification/​notification_method_email_test.php Updates email notification construction for routing support.
tests/​notification/​fixtures/​unsubscribe.xml Adds database fixtures for unsubscribe scenarios.
tests/​notification/​fixtures/​services_notification.yml Adds test parameters and synthetic services.
tests/​notification/​email_unsubscribe_link_test.php Tests signed-link generation, expiry, tampering, and email variables.
tests/​notification/​controller_email_unsubscribe_test.php Tests controller scopes, validation, logging, and preference changes.
tests/​notification/​base.php Provides router setup for notification tests.
tests/​messenger/​method_email_test.php Verifies unsubscribe-header cleanup between messages.
tests/​functional/​email_unsubscribe_test.php Covers end-to-end unsubscribe behavior.
tests/​email/​fixtures/​legacy_unsubscribe.txt Adds a legacy unsubscribe-header fixture.
tests/​email/​email_parsing_test.php Tests unsubscribe headers and updated email templates.
phpBB/​styles/​prosilver/​template/​notification_email_unsubscribe.html Adds the unsubscribe selection page template.
phpBB/​phpbb/​notification/​type/​update_maintenance.php Prevents one-click unsubscribe for update notifications.
phpBB/​phpbb/​notification/​type/​type_interface.php Defines unsubscribe capability and watched-item contracts.
phpBB/​phpbb/​notification/​type/​topic.php Identifies forum watch items for topic notifications.
phpBB/​phpbb/​notification/​type/​post.php Identifies topic watch items for post notifications.
phpBB/​phpbb/​notification/​type/​forum.php Identifies forum watch items for forum notifications.
phpBB/​phpbb/​notification/​type/​base.php Supplies default unsubscribe behavior for notification types.
phpBB/​phpbb/​notification/​method/​messenger_base.php Centralizes notification email template variables.
phpBB/​phpbb/​notification/​method/​email.php Generates signed unsubscribe URLs and adds them to notification messages.
phpBB/​phpbb/​notification/​manager.php Resolves shared preferences and manages email subscriptions.
phpBB/​phpbb/​notification/​controller/​email_unsubscribe.php Handles signed unsubscribe pages and one-click requests.
phpBB/​phpbb/​messenger/​method/​messenger_interface.php Adds the unsubscribe-header API.
phpBB/​phpbb/​messenger/​method/​email.php Emits RFC 8058 headers and resets message state.
phpBB/​phpbb/​messenger/​method/​base.php Adds a no-op unsubscribe-header implementation.
phpBB/​phpbb/​install/​module/​install_database/​task/​add_config_settings.php Generates the unsubscribe signing secret during installation.
phpBB/​phpbb/​db/​migration/​data/​v400/​email_unsubscribe.php Adds unsubscribe configuration during migration.
phpBB/​language/​en/​ucp.php Adds unsubscribe page and status language strings.
phpBB/​language/​en/​email/​update_security.txt Adds notification-settings guidance to security update emails.
phpBB/​language/​en/​email/​update_maintenance.txt Adds notification-settings guidance to maintenance emails.
phpBB/​language/​en/​email/​update_critical.txt Adds notification-settings guidance to critical update emails.
phpBB/​language/​en/​email/​topic_notify.txt Removes the legacy unsubscribe header.
phpBB/​language/​en/​email/​topic_in_queue.txt Adds an unsubscribe link to queued-topic emails.
phpBB/​language/​en/​email/​topic_disapproved.txt Adds an unsubscribe link to disapproved-topic emails.
phpBB/​language/​en/​email/​topic_approved.txt Adds an unsubscribe link to approved-topic emails.
phpBB/​language/​en/​email/​report_post.txt Adds an unsubscribe link to post-report emails.
phpBB/​language/​en/​email/​report_pm.txt Adds an unsubscribe link to private-message report emails.
phpBB/​language/​en/​email/​report_pm_closed.txt Adds an unsubscribe link to closed PM-report emails.
phpBB/​language/​en/​email/​report_deleted.txt Adds an unsubscribe link to deleted-report emails.
phpBB/​language/​en/​email/​report_closed.txt Adds an unsubscribe link to closed-report emails.
phpBB/​language/​en/​email/​quote.txt Replaces the settings link with an unsubscribe link.
phpBB/​language/​en/​email/​privmsg_notify.txt Adds an unsubscribe link to private-message notifications.
phpBB/​language/​en/​email/​post_in_queue.txt Adds an unsubscribe link to queued-post emails.
phpBB/​language/​en/​email/​post_disapproved.txt Adds an unsubscribe link to disapproved-post emails.
phpBB/​language/​en/​email/​post_approved.txt Adds an unsubscribe link to approved-post emails.
phpBB/​language/​en/​email/​pm_report_deleted.txt Adds an unsubscribe link to deleted PM-report emails.
phpBB/​language/​en/​email/​pm_report_closed.txt Adds an unsubscribe link to closed PM-report emails.
phpBB/​language/​en/​email/​newtopic_notify.txt Removes the legacy unsubscribe header.
phpBB/​language/​en/​email/​mention.txt Replaces the settings link with an unsubscribe link.
phpBB/​language/​en/​email/​group_request.txt Adds an unsubscribe link to group-request emails.
phpBB/​language/​en/​email/​forum_notify.txt Removes the legacy unsubscribe header.
phpBB/​language/​en/​email/​bookmark.txt Replaces the settings link with an unsubscribe link.
phpBB/​language/​en/​email/​admin_activate.txt Adds a conditional unsubscribe link.
phpBB/​language/​en/​acp/​common.php Adds unsubscribe audit-log messages.
phpBB/​language/​en/​acp/​board.php Adds the unsubscribe-link lifetime setting.
phpBB/​install/​schemas/​schema_data.sql Adds default unsubscribe configuration values.
phpBB/​includes/​acp/​acp_board.php Exposes unsubscribe-link expiry in board settings.
phpBB/​config/​default/​routing/​notifications.yml Registers the unsubscribe route.
phpBB/​config/​default/​container/​services_notification.yml Registers controller dependencies and router injection.

Review effort: Lite

Comment on lines +300 to +303
protected function unsubscribe_type(int $user_id, string $option_id): void
{
$this->manager->delete_subscription($option_id, 0, $this->email_method->get_type(), $user_id);
}
return $vars;
}

$messenger_method->set_list_unsubscribe($unsubscribe_url);
Comment on lines +151 to +152
if ($type_option !== null && !$type_option['type']->allows_email_unsubscribe())
{
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants