Lomiri
Loading...
Searching...
No Matches
PasswordMeter.qml
1/*
2 * Copyright (C) 2015 Canonical Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 3.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17import QtQuick 2.12
18import Lomiri.Components 1.3
19
20Item {
21 property string password: ""
22 readonly property int passwordScore: scorePassword(password)
23 property var matching
24
25 function scorePassword(pass) {
26 var score = 0;
27 if (!pass)
28 return score;
29
30 // award every unique letter until 5 repetitions
31 var letters = Object();
32 for (var i=0; i<pass.length; i++) {
33 letters[pass[i]] = (letters[pass[i]] || 0) + 1;
34 score += 5.0 / letters[pass[i]];
35 }
36
37 // bonus points for mixing it up
38 var variations = {
39 digits: /\d/.test(pass),
40 lower: /[a-z]/.test(pass),
41 upper: /[A-Z]/.test(pass),
42 nonWords: /\W/.test(pass),
43 }
44
45 var variationCount = 0;
46 for (var check in variations) {
47 variationCount += (variations[check] === true) ? 1 : 0;
48 }
49 score += (variationCount - 1) * 10;
50
51 return parseInt(score);
52 }
53
54 Rectangle {
55 id: passwordStrengthMeter
56 anchors {
57 left: parent.left
58 right: parent.right
59 }
60 width: parent.width
61 height: units.gu(0.5)
62 color: {
63 if (passwordScore > 80)
64 return okColor;
65 else if (passwordScore > 60)
66 return "#f9c00f";
67 else if (passwordScore >= 30)
68 return errorColor;
69
70 return errorColor;
71 }
72 visible: password.length > 0
73 }
74
75 Label {
76 id: passwordStrengthInfo
77 anchors {
78 left: parent.left
79 right: parent.right
80 top: passwordStrengthMeter.bottom
81 topMargin: units.gu(.5)
82 }
83 wrapMode: Text.Wrap
84 text: {
85 if (matching !== undefined) {
86 if (password.length < 8)
87 return i18n.tr("Password too short");
88 else if (matching)
89 return i18n.tr("Passwords match");
90 else if (!matching)
91 return i18n.tr("Passwords do not match");
92 }
93
94 if (passwordScore > 80)
95 return i18n.tr("Strong password");
96 else if (passwordScore > 60)
97 return i18n.tr("Fair password");
98 else if (passwordScore >= 30)
99 return i18n.tr("Weak password");
100
101 return i18n.tr("Very weak password");
102 }
103 color: LomiriColors.ash
104 fontSize: "small"
105 font.weight: Font.Light
106 visible: password.length > 0
107 }
108}