mirror of
https://github.com/healthchecks/healthchecks.git
synced 2025-04-11 15:51:19 +00:00
A workaround for some email agents automatically opening "Unsubscribe" links
This commit is contained in:
parent
5f59d97d21
commit
b3c22dcfd2
10 changed files with 93 additions and 39 deletions
|
@ -13,6 +13,7 @@ All notable changes to this project will be documented in this file.
|
|||
- Show a warning when running with DEBUG=True
|
||||
- Add "channels" attribute to the Check API resource
|
||||
- Can specify channel codes when updating a check via API
|
||||
- Added a workaround for email agents automatically opening "Unsubscribe" links
|
||||
|
||||
### Bug Fixes
|
||||
- During DST transition, handle ambiguous dates as pre-transition
|
||||
|
|
|
@ -17,7 +17,7 @@ class UnsubscribeReportsTestCase(BaseTestCase):
|
|||
url = "/accounts/unsubscribe_reports/%s/" % sig
|
||||
|
||||
r = self.client.get(url)
|
||||
self.assertContains(r, "You have been unsubscribed")
|
||||
self.assertContains(r, "Unsubscribed")
|
||||
|
||||
self.profile.refresh_from_db()
|
||||
self.assertFalse(self.profile.reports_allowed)
|
||||
|
@ -30,3 +30,17 @@ class UnsubscribeReportsTestCase(BaseTestCase):
|
|||
url = "/accounts/unsubscribe_reports/invalid/"
|
||||
r = self.client.get(url)
|
||||
self.assertContains(r, "Incorrect Link")
|
||||
|
||||
def test_post_works(self):
|
||||
sig = signing.TimestampSigner(salt="reports").sign("alice")
|
||||
url = "/accounts/unsubscribe_reports/%s/" % sig
|
||||
|
||||
r = self.client.post(url)
|
||||
self.assertContains(r, "Unsubscribed")
|
||||
|
||||
def test_it_serves_confirmation_form(self):
|
||||
sig = signing.TimestampSigner(salt="reports").sign("alice")
|
||||
url = "/accounts/unsubscribe_reports/%s/?ask=1" % sig
|
||||
|
||||
r = self.client.get(url)
|
||||
self.assertContains(r, "Please press the button below")
|
||||
|
|
|
@ -355,6 +355,11 @@ def unsubscribe_reports(request, username):
|
|||
except signing.BadSignature:
|
||||
return render(request, "bad_link.html")
|
||||
|
||||
# Some email servers open links in emails to check for malicious content.
|
||||
# To work around this, we serve a form that auto-submits with JS.
|
||||
if "ask" in request.GET and request.method != "POST":
|
||||
return render(request, "accounts/unsubscribe_submit.html")
|
||||
|
||||
user = User.objects.get(username=username)
|
||||
profile = Profile.objects.for_user(user)
|
||||
profile.reports_allowed = False
|
||||
|
|
|
@ -36,3 +36,17 @@ class UnsubscribeEmailTestCase(BaseTestCase):
|
|||
|
||||
r = self.client.get(url)
|
||||
self.assertEqual(r.status_code, 400)
|
||||
|
||||
def test_post_works(self):
|
||||
token = self.channel.make_token()
|
||||
url = "/integrations/%s/unsub/%s/" % (self.channel.code, token)
|
||||
|
||||
r = self.client.post(url)
|
||||
self.assertContains(r, "has been unsubscribed", status_code=200)
|
||||
|
||||
def test_it_serves_confirmation_form(self):
|
||||
token = self.channel.make_token()
|
||||
url = "/integrations/%s/unsub/%s/?ask=1" % (self.channel.code, token)
|
||||
|
||||
r = self.client.get(url)
|
||||
self.assertContains(r, "Please press the button below")
|
||||
|
|
|
@ -516,6 +516,11 @@ def unsubscribe_email(request, code, token):
|
|||
if channel.kind != "email":
|
||||
return HttpResponseBadRequest()
|
||||
|
||||
# Some email servers open links in emails to check for malicious content.
|
||||
# To work around this, we serve a form that auto-submits with JS.
|
||||
if "ask" in request.GET and request.method != "POST":
|
||||
return render(request, "accounts/unsubscribe_submit.html")
|
||||
|
||||
channel.delete()
|
||||
return render(request, "front/unsubscribe_success.html")
|
||||
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
{% extends "base.html" %}
|
||||
{% extends "base_bare.html" %}
|
||||
{% load hc_extras %}
|
||||
|
||||
{% block title %}Unsubscribed{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="row">
|
||||
<div class="col-sm-6 col-sm-offset-3">
|
||||
<div class="hc-dialog">
|
||||
<h1>You have been unsubscribed</h1>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h1>Unsubscribed</h1>
|
||||
<p>
|
||||
Your email address has been unsubscribed from
|
||||
{% site_name %} reports.
|
||||
</p>
|
||||
{% endblock %}
|
||||
|
|
|
@ -2,23 +2,45 @@
|
|||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>{% block title %}{% site_name %} - Monitor Cron Jobs. Get Notified When Your Cron Jobs Fail{% endblock %}</title>
|
||||
<title>{% block title %}{% site_name %}{% endblock %}</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
||||
<link href='//fonts.googleapis.com/css?family=Open+Sans:400,300,600' rel='stylesheet' type='text/css'>
|
||||
<link rel="icon" type="image/x-icon" href="{% static 'img/favicon.ico' %}">
|
||||
|
||||
{% compress css %}
|
||||
<link rel="stylesheet" href="{% static 'css/bootstrap.css' %}" type="text/css">
|
||||
<link rel="stylesheet" href="{% static 'css/base.css' %}" type="text/css">
|
||||
<style>
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;
|
||||
text-align: center;
|
||||
margin: 10em;
|
||||
}
|
||||
|
||||
{% endcompress %}
|
||||
h1 {
|
||||
font-weight: 300;
|
||||
font-size: 30px;
|
||||
}
|
||||
|
||||
input {
|
||||
display: inline-block;
|
||||
margin-bottom: 0;
|
||||
font-weight: normal;
|
||||
text-align: center;
|
||||
vertical-align: middle;
|
||||
touch-action: manipulation;
|
||||
cursor: pointer;
|
||||
background-image: none;
|
||||
border: 1px solid transparent;
|
||||
white-space: nowrap;
|
||||
padding: 10px 16px;
|
||||
font-size: 18px;
|
||||
line-height: 1.3333333;
|
||||
border-radius: 6px;
|
||||
color: #ffffff;
|
||||
background-color: #22bc66;
|
||||
border-color: #1ea65a;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body class="page-{{ page }}">
|
||||
{% block containers %}
|
||||
<div class="container">
|
||||
{% block content %}{% endblock %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
<body>
|
||||
{% block content %}{% endblock %}
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -22,7 +22,7 @@ The {% escaped_site_name %} Team
|
|||
|
||||
{% block unsub %}
|
||||
<br>
|
||||
<a href="{{ unsub_link }}" target="_blank" style="color: #666666; text-decoration: underline;">
|
||||
<a href="{{ unsub_link }}?ask=1" target="_blank" style="color: #666666; text-decoration: underline;">
|
||||
Unsubscribe
|
||||
</a>
|
||||
{% endblock %}
|
||||
|
|
|
@ -41,7 +41,7 @@ The {% escaped_site_name %} Team
|
|||
|
||||
{% block unsub %}
|
||||
<br>
|
||||
<a href="{{ unsub_link }}" target="_blank" style="color: #666666; text-decoration: underline;">
|
||||
<a href="{{ unsub_link }}?ask=1" target="_blank" style="color: #666666; text-decoration: underline;">
|
||||
Unsubscribe
|
||||
</a>
|
||||
{% endblock %}
|
||||
|
|
|
@ -1,19 +1,12 @@
|
|||
{% extends "base.html" %}
|
||||
{% extends "base_bare.html" %}
|
||||
{% load hc_extras %}
|
||||
|
||||
{% block content %}
|
||||
<div class="row">
|
||||
<div class="col-sm-6 col-sm-offset-3">
|
||||
<div class="hc-dialog">
|
||||
<h1>Unsubscribed</h1>
|
||||
<div class="dialog-body">
|
||||
<p>
|
||||
Your email address has been unsubscribed from
|
||||
{% site_name %} notifications.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% block title %}Unsubscribed{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<h1>Unsubscribed</h1>
|
||||
<p>
|
||||
Your email address has been unsubscribed from
|
||||
{% site_name %} notifications.
|
||||
</p>
|
||||
{% endblock %}
|
||||
|
|
Loading…
Add table
Reference in a new issue