mirror of
				https://github.com/zulip/zulip.git
				synced 2025-11-04 05:53:43 +00:00 
			
		
		
		
	emails: Add one-click unsubscribe link to new login emails.
Fixes: #10547.
This commit is contained in:
		@@ -23,3 +23,7 @@ Server: {{ realm_uri }} Account: {{ user_email }} Time: {{ login_time }}
 | 
				
			|||||||
<p>If you recognize this login activity, you can archive this notice.</p>
 | 
					<p>If you recognize this login activity, you can archive this notice.</p>
 | 
				
			||||||
<p>Thanks,<br />Zulip Account Security</p>
 | 
					<p>Thanks,<br />Zulip Account Security</p>
 | 
				
			||||||
{% endblock %}
 | 
					{% endblock %}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					{% block manage_preferences %}
 | 
				
			||||||
 | 
					<p><a href="{{ realm_uri }}/#settings/notifications">Manage email preferences</a> | <a href="{{ unsubscribe_link }}">Unsubscribe from login notifications</a></p>
 | 
				
			||||||
 | 
					{% endblock %}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -10,6 +10,7 @@ from django.utils.timezone import \
 | 
				
			|||||||
from django.utils.timezone import now as timezone_now
 | 
					from django.utils.timezone import now as timezone_now
 | 
				
			||||||
from django.utils.translation import ugettext_lazy as _
 | 
					from django.utils.translation import ugettext_lazy as _
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from confirmation.models import one_click_unsubscribe_link
 | 
				
			||||||
from zerver.lib.queue import queue_json_publish
 | 
					from zerver.lib.queue import queue_json_publish
 | 
				
			||||||
from zerver.lib.send_email import FromAddress
 | 
					from zerver.lib.send_email import FromAddress
 | 
				
			||||||
from zerver.models import UserProfile
 | 
					from zerver.models import UserProfile
 | 
				
			||||||
@@ -91,6 +92,7 @@ def email_on_new_login(sender: Any, user: UserProfile, request: Any, **kwargs: A
 | 
				
			|||||||
        context['device_ip'] = request.META.get('REMOTE_ADDR') or _("Unknown IP address")
 | 
					        context['device_ip'] = request.META.get('REMOTE_ADDR') or _("Unknown IP address")
 | 
				
			||||||
        context['device_os'] = get_device_os(user_agent)
 | 
					        context['device_os'] = get_device_os(user_agent)
 | 
				
			||||||
        context['device_browser'] = get_device_browser(user_agent)
 | 
					        context['device_browser'] = get_device_browser(user_agent)
 | 
				
			||||||
 | 
					        context['unsubscribe_link'] = one_click_unsubscribe_link(user, 'login')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        email_dict = {
 | 
					        email_dict = {
 | 
				
			||||||
            'template_prefix': 'zerver/emails/notify_new_login',
 | 
					            'template_prefix': 'zerver/emails/notify_new_login',
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1568,6 +1568,24 @@ class EmailUnsubscribeTests(ZulipTestCase):
 | 
				
			|||||||
        self.assertFalse(user_profile.enable_digest_emails)
 | 
					        self.assertFalse(user_profile.enable_digest_emails)
 | 
				
			||||||
        self.assertEqual(0, ScheduledEmail.objects.filter(user=user_profile).count())
 | 
					        self.assertEqual(0, ScheduledEmail.objects.filter(user=user_profile).count())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_login_unsubscribe(self) -> None:
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        We provide one-click unsubscribe links in login
 | 
				
			||||||
 | 
					        e-mails that you can click even when logged out to update your
 | 
				
			||||||
 | 
					        email notification settings.
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        user_profile = self.example_user('hamlet')
 | 
				
			||||||
 | 
					        user_profile.enable_login_emails = True
 | 
				
			||||||
 | 
					        user_profile.save()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        unsubscribe_link = one_click_unsubscribe_link(user_profile, "login")
 | 
				
			||||||
 | 
					        result = self.client_get(urllib.parse.urlparse(unsubscribe_link).path)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertEqual(result.status_code, 200)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        user_profile.refresh_from_db()
 | 
				
			||||||
 | 
					        self.assertFalse(user_profile.enable_login_emails)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class RealmCreationTest(ZulipTestCase):
 | 
					class RealmCreationTest(ZulipTestCase):
 | 
				
			||||||
    @override_settings(OPEN_REALM_CREATION=True)
 | 
					    @override_settings(OPEN_REALM_CREATION=True)
 | 
				
			||||||
    def check_able_to_create_realm(self, email: str) -> None:
 | 
					    def check_able_to_create_realm(self, email: str) -> None:
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -34,6 +34,9 @@ def do_welcome_unsubscribe(user_profile: UserProfile) -> None:
 | 
				
			|||||||
def do_digest_unsubscribe(user_profile: UserProfile) -> None:
 | 
					def do_digest_unsubscribe(user_profile: UserProfile) -> None:
 | 
				
			||||||
    do_change_notification_settings(user_profile, 'enable_digest_emails', False)
 | 
					    do_change_notification_settings(user_profile, 'enable_digest_emails', False)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def do_login_unsubscribe(user_profile: UserProfile) -> None:
 | 
				
			||||||
 | 
					    do_change_notification_settings(user_profile, 'enable_login_emails', False)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# The keys are part of the URL for the unsubscribe link and must be valid
 | 
					# The keys are part of the URL for the unsubscribe link and must be valid
 | 
				
			||||||
# without encoding.
 | 
					# without encoding.
 | 
				
			||||||
# The values are a tuple of (display name, unsubscribe function), where the
 | 
					# The values are a tuple of (display name, unsubscribe function), where the
 | 
				
			||||||
@@ -41,7 +44,8 @@ def do_digest_unsubscribe(user_profile: UserProfile) -> None:
 | 
				
			|||||||
email_unsubscribers = {
 | 
					email_unsubscribers = {
 | 
				
			||||||
    "missed_messages": ("missed messages", do_missedmessage_unsubscribe),
 | 
					    "missed_messages": ("missed messages", do_missedmessage_unsubscribe),
 | 
				
			||||||
    "welcome": ("welcome", do_welcome_unsubscribe),
 | 
					    "welcome": ("welcome", do_welcome_unsubscribe),
 | 
				
			||||||
    "digest": ("digest", do_digest_unsubscribe)
 | 
					    "digest": ("digest", do_digest_unsubscribe),
 | 
				
			||||||
 | 
					    "login": ("login", do_login_unsubscribe)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Login NOT required. These are for one-click unsubscribes.
 | 
					# Login NOT required. These are for one-click unsubscribes.
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user