0
0
Fork 0
mirror of https://github.com/healthchecks/healthchecks.git synced 2025-04-11 15:51:19 +00:00

Password strength meter and length check in the "Set Password" form

This commit is contained in:
Pēteris Caune 2019-04-29 23:16:49 +03:00
parent afaa8767cd
commit 23b197526c
No known key found for this signature in database
GPG key ID: E28D7679E9A9EDE2
8 changed files with 149 additions and 13 deletions

View file

@ -10,6 +10,7 @@ All notable changes to this project will be documented in this file.
- Can configure the email integration to only report the "down" events (#231)
- Add "Test!" function in the Integrations page (#207)
- Rate limiting for the log in attempts
- Password strength meter and length check in the "Set Password" form
## 1.6.0 - 2019-04-01

View file

@ -76,7 +76,7 @@ class ReportSettingsForm(forms.Form):
class SetPasswordForm(forms.Form):
password = forms.CharField()
password = forms.CharField(min_length=8)
class ChangeEmailForm(forms.Form):

View file

@ -0,0 +1,49 @@
from hc.test import BaseTestCase
class SetPasswordTestCase(BaseTestCase):
def test_it_shows_form(self):
token = self.profile.prepare_token("set-password")
self.client.login(username="alice@example.org", password="password")
r = self.client.get("/accounts/set_password/%s/" % token)
self.assertEqual(r.status_code, 200)
self.assertContains(r, "Please pick a password")
def test_it_checks_token(self):
self.profile.prepare_token("set-password")
self.client.login(username="alice@example.org", password="password")
# GET
r = self.client.get("/accounts/set_password/invalid-token/")
self.assertEqual(r.status_code, 400)
# POST
r = self.client.post("/accounts/set_password/invalid-token/")
self.assertEqual(r.status_code, 400)
def test_it_sets_password(self):
token = self.profile.prepare_token("set-password")
self.client.login(username="alice@example.org", password="password")
payload = {"password": "correct horse battery staple"}
r = self.client.post("/accounts/set_password/%s/" % token, payload)
self.assertEqual(r.status_code, 302)
old_password = self.alice.password
self.alice.refresh_from_db()
self.assertNotEqual(self.alice.password, old_password)
def test_post_checks_length(self):
token = self.profile.prepare_token("set-password")
self.client.login(username="alice@example.org", password="password")
payload = {"password": "abc"}
r = self.client.post("/accounts/set_password/%s/" % token, payload)
self.assertEqual(r.status_code, 200)
old_password = self.alice.password
self.alice.refresh_from_db()
self.assertEqual(self.alice.password, old_password)

View file

@ -0,0 +1,37 @@
#set-password-group #password {
border-color: #ddd;
box-shadow: none;
}
#meter {
margin: 3px 0 20px 0;
display: flex;
}
#meter div {
background: #ddd;
height: 5px;
flex: 1;
border-radius: 2px;
margin-right: 3px;
}
#meter div:last-child {
margin-right: 0;
}
#meter.score-1 .s1 {
background: #FF5252;
}
#meter.score-2 .s2 {
background: #FFAB40;
}
#meter.score-3 .s3 {
background: #9CCC65;
}
#meter.score-4 .s4 {
background: #22bc66;;
}

View file

@ -0,0 +1,8 @@
$(function () {
$pw = $("#password");
$meter = $("#meter");
$pw.on("input", function() {
var result = zxcvbn($pw.val());
$meter.attr("class", "score-" + result.score);
});
});

28
static/js/zxcvbn.js Normal file

File diff suppressed because one or more lines are too long

View file

@ -1,5 +1,5 @@
{% extends "base.html" %}
{% load hc_extras %}
{% load compress hc_extras static %}
{% block content %}
<div class="row">
@ -15,17 +15,20 @@
<form method="post">
{% csrf_token %}
<div class="form-group">
<div class="input-group input-group-lg">
<div class="input-group-addon">
<span class="icon-dots"></span>
</div>
<input
type="password"
class="form-control"
name="password"
placeholder="pick a password">
</div>
<div id="set-password-group" class="form-group">
<input
id="password"
type="password"
minlength="8"
class="form-control input-lg"
name="password"
placeholder="pick a password (at least 8 characters)">
<div id="meter">
<div class="s1 s2 s3 s4"></div>
<div class="s2 s3 s4"></div>
<div class="s3 s4"></div>
<div class="s4"></div>
</table>
</div>
<div class="clearfix">
@ -38,3 +41,12 @@
</div>
</div>
{% endblock %}
{% block scripts %}
{% compress js %}
<script src="{% static 'js/jquery-2.1.4.min.js' %}"></script>
<script src="{% static 'js/bootstrap.min.js' %}"></script>
<script src="{% static 'js/zxcvbn.js' %}"></script>
<script src="{% static 'js/set-password.js' %}"></script>
{% endcompress %}
{% endblock %}

View file

@ -46,6 +46,7 @@
<link rel="stylesheet" href="{% static 'css/snippet-copy.css' %}" type="text/css">
<link rel="stylesheet" href="{% static 'css/syntax.css' %}" type="text/css">
<link rel="stylesheet" href="{% static 'css/welcome.css' %}" type="text/css">
<link rel="stylesheet" href="{% static 'css/set_password.css' %}" type="text/css">
{% endcompress %}
</head>
<body class="page-{{ page }}">