playbook_ui 11.12.1.pre.alpha.passphrase1 → 11.12.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/app/pb_kits/playbook/pb_passphrase/_passphrase.jsx +97 -56
- data/app/pb_kits/playbook/pb_passphrase/docs/_passphrase_breached.html.erb +1 -145
- data/app/pb_kits/playbook/pb_passphrase/docs/_passphrase_breached.jsx +3 -127
- data/app/pb_kits/playbook/pb_passphrase/docs/_passphrase_breached.md +2 -11
- data/app/pb_kits/playbook/pb_passphrase/docs/_passphrase_common.jsx +8 -90
- data/app/pb_kits/playbook/pb_passphrase/docs/_passphrase_default.html.erb +2 -0
- data/app/pb_kits/playbook/pb_passphrase/docs/_passphrase_default.jsx +20 -6
- data/app/pb_kits/playbook/pb_passphrase/docs/_passphrase_default.md +1 -0
- data/app/pb_kits/playbook/pb_passphrase/docs/_passphrase_input_props.html.erb +2 -2
- data/app/pb_kits/playbook/pb_passphrase/docs/_passphrase_input_props.jsx +1 -1
- data/app/pb_kits/playbook/pb_passphrase/docs/_passphrase_meter_settings.html.erb +5 -318
- data/app/pb_kits/playbook/pb_passphrase/docs/_passphrase_meter_settings.jsx +48 -134
- data/app/pb_kits/playbook/pb_passphrase/docs/_passphrase_meter_settings.md +5 -11
- data/app/pb_kits/playbook/pb_passphrase/docs/_passphrase_strength_change.jsx +20 -96
- data/app/pb_kits/playbook/pb_passphrase/docs/_passphrase_strength_change.md +2 -6
- data/app/pb_kits/playbook/pb_passphrase/docs/example.yml +0 -4
- data/app/pb_kits/playbook/pb_passphrase/docs/index.js +0 -1
- data/app/pb_kits/playbook/pb_passphrase/passphrase.html.erb +1 -1
- data/app/pb_kits/playbook/pb_passphrase/passphrase.rb +9 -5
- data/app/pb_kits/playbook/pb_passphrase/passphrase.test.jsx +47 -0
- data/app/pb_kits/playbook/pb_passphrase/passwordStrength.js +55 -0
- data/app/pb_kits/playbook/pb_passphrase/useHaveIBeenPwned.js +52 -0
- data/app/pb_kits/playbook/pb_passphrase/useZxcvbn.js +58 -0
- data/lib/playbook/version.rb +2 -2
- metadata +8 -9
- data/app/pb_kits/playbook/pb_passphrase/docs/_passphrase_common.html.erb +0 -136
- data/app/pb_kits/playbook/pb_passphrase/docs/_passphrase_common.md +0 -5
- data/app/pb_kits/playbook/pb_passphrase/docs/_passphrase_confirmation.html.erb +0 -51
- data/app/pb_kits/playbook/pb_passphrase/docs/_passphrase_confirmation.jsx +0 -39
- data/app/pb_kits/playbook/pb_passphrase/docs/_passphrase_strength_change.html.erb +0 -123
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: playbook_ui
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 11.12.1
|
4
|
+
version: 11.12.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Power UX
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2022-11-
|
12
|
+
date: 2022-11-22 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: actionpack
|
@@ -1458,20 +1458,16 @@ files:
|
|
1458
1458
|
- app/pb_kits/playbook/pb_passphrase/docs/_passphrase_breached.html.erb
|
1459
1459
|
- app/pb_kits/playbook/pb_passphrase/docs/_passphrase_breached.jsx
|
1460
1460
|
- app/pb_kits/playbook/pb_passphrase/docs/_passphrase_breached.md
|
1461
|
-
- app/pb_kits/playbook/pb_passphrase/docs/_passphrase_common.html.erb
|
1462
1461
|
- app/pb_kits/playbook/pb_passphrase/docs/_passphrase_common.jsx
|
1463
|
-
- app/pb_kits/playbook/pb_passphrase/docs/_passphrase_common.md
|
1464
|
-
- app/pb_kits/playbook/pb_passphrase/docs/_passphrase_confirmation.html.erb
|
1465
|
-
- app/pb_kits/playbook/pb_passphrase/docs/_passphrase_confirmation.jsx
|
1466
1462
|
- app/pb_kits/playbook/pb_passphrase/docs/_passphrase_default.html.erb
|
1467
1463
|
- app/pb_kits/playbook/pb_passphrase/docs/_passphrase_default.jsx
|
1464
|
+
- app/pb_kits/playbook/pb_passphrase/docs/_passphrase_default.md
|
1468
1465
|
- app/pb_kits/playbook/pb_passphrase/docs/_passphrase_input_props.html.erb
|
1469
1466
|
- app/pb_kits/playbook/pb_passphrase/docs/_passphrase_input_props.jsx
|
1470
1467
|
- app/pb_kits/playbook/pb_passphrase/docs/_passphrase_input_props.md
|
1471
1468
|
- app/pb_kits/playbook/pb_passphrase/docs/_passphrase_meter_settings.html.erb
|
1472
1469
|
- app/pb_kits/playbook/pb_passphrase/docs/_passphrase_meter_settings.jsx
|
1473
1470
|
- app/pb_kits/playbook/pb_passphrase/docs/_passphrase_meter_settings.md
|
1474
|
-
- app/pb_kits/playbook/pb_passphrase/docs/_passphrase_strength_change.html.erb
|
1475
1471
|
- app/pb_kits/playbook/pb_passphrase/docs/_passphrase_strength_change.jsx
|
1476
1472
|
- app/pb_kits/playbook/pb_passphrase/docs/_passphrase_strength_change.md
|
1477
1473
|
- app/pb_kits/playbook/pb_passphrase/docs/_passphrase_tips.html.erb
|
@@ -1482,6 +1478,9 @@ files:
|
|
1482
1478
|
- app/pb_kits/playbook/pb_passphrase/passphrase.html.erb
|
1483
1479
|
- app/pb_kits/playbook/pb_passphrase/passphrase.rb
|
1484
1480
|
- app/pb_kits/playbook/pb_passphrase/passphrase.test.jsx
|
1481
|
+
- app/pb_kits/playbook/pb_passphrase/passwordStrength.js
|
1482
|
+
- app/pb_kits/playbook/pb_passphrase/useHaveIBeenPwned.js
|
1483
|
+
- app/pb_kits/playbook/pb_passphrase/useZxcvbn.js
|
1485
1484
|
- app/pb_kits/playbook/pb_person/_person.jsx
|
1486
1485
|
- app/pb_kits/playbook/pb_person/_person.scss
|
1487
1486
|
- app/pb_kits/playbook/pb_person/docs/_description.md
|
@@ -2352,9 +2351,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
2352
2351
|
version: '0'
|
2353
2352
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
2354
2353
|
requirements:
|
2355
|
-
- - "
|
2354
|
+
- - ">="
|
2356
2355
|
- !ruby/object:Gem::Version
|
2357
|
-
version:
|
2356
|
+
version: '0'
|
2358
2357
|
requirements: []
|
2359
2358
|
rubygems_version: 3.3.7
|
2360
2359
|
signing_key:
|
@@ -1,136 +0,0 @@
|
|
1
|
-
<%= pb_rails("body", props: {
|
2
|
-
margin_bottom: "md",
|
3
|
-
id: "body_common"
|
4
|
-
}) %>
|
5
|
-
|
6
|
-
<%= pb_rails("passphrase", props: { label: "Passphrase", classname: "passphrase_common" }) %>
|
7
|
-
|
8
|
-
<%= pb_rails("progress_simple", props: { percent: 0, id: "bar_common" }) %>
|
9
|
-
|
10
|
-
<%= pb_rails("caption", props: { size: 'xs', text: "hello", id: "caption_common" }) %>
|
11
|
-
|
12
|
-
|
13
|
-
<%= javascript_tag do %>
|
14
|
-
window.addEventListener("DOMContentLoaded", () => {
|
15
|
-
|
16
|
-
const commonText = document.querySelector("#body_common")
|
17
|
-
|
18
|
-
// variables for the kits you are targeting
|
19
|
-
const passphrase = document.querySelector(".passphrase_common").querySelector("input")
|
20
|
-
const barVariant = document.getElementById("bar_common")
|
21
|
-
const barPercent = document.getElementById("bar_common").querySelector("div")
|
22
|
-
const caption = document.getElementById("caption_common")
|
23
|
-
|
24
|
-
// hide the bar and captions
|
25
|
-
barVariant.style.display = 'none';
|
26
|
-
barPercent.style.display = 'none';
|
27
|
-
caption.style.display = 'none';
|
28
|
-
|
29
|
-
|
30
|
-
const handleStrengthCalculation = (settings) => {
|
31
|
-
const {
|
32
|
-
passphrase = "",
|
33
|
-
common = false,
|
34
|
-
isPwned = false,
|
35
|
-
averageThreshold = 2,
|
36
|
-
minLength = 12,
|
37
|
-
strongThreshold = 3,
|
38
|
-
} = settings
|
39
|
-
|
40
|
-
const resultByScore = {
|
41
|
-
0: {
|
42
|
-
variant: 'negative',
|
43
|
-
label: '',
|
44
|
-
percent: 0,
|
45
|
-
},
|
46
|
-
1: {
|
47
|
-
variant: 'negative',
|
48
|
-
label: 'This passphrase is too common',
|
49
|
-
percent: 25,
|
50
|
-
},
|
51
|
-
2: {
|
52
|
-
variant: 'negative',
|
53
|
-
label: 'Too weak',
|
54
|
-
percent: 25,
|
55
|
-
},
|
56
|
-
3: {
|
57
|
-
variant: 'warning',
|
58
|
-
label: 'Almost there, keep going!',
|
59
|
-
percent: 50,
|
60
|
-
},
|
61
|
-
4: {
|
62
|
-
variant: 'positive',
|
63
|
-
label: 'Success! Strong passphrase',
|
64
|
-
percent: 100,
|
65
|
-
}
|
66
|
-
}
|
67
|
-
|
68
|
-
const { score } = zxcvbn(passphrase);
|
69
|
-
|
70
|
-
const noPassphrase = passphrase.length <= 0
|
71
|
-
const commonPassphrase = common || isPwned
|
72
|
-
const weakPassphrase = passphrase.length < minLength || score < averageThreshold
|
73
|
-
const averagePassphrase = score < strongThreshold
|
74
|
-
const strongPassphrase = score >= strongThreshold
|
75
|
-
|
76
|
-
if (noPassphrase) {
|
77
|
-
return {...resultByScore[0], score}
|
78
|
-
} else if (commonPassphrase) {
|
79
|
-
return {...resultByScore[1], score}
|
80
|
-
} else if (weakPassphrase) {
|
81
|
-
return {...resultByScore[2], score}
|
82
|
-
} else if (averagePassphrase){
|
83
|
-
return {...resultByScore[3], score}
|
84
|
-
} else if (strongPassphrase) {
|
85
|
-
return {...resultByScore[4], score}
|
86
|
-
}
|
87
|
-
}
|
88
|
-
|
89
|
-
// array that holds the common passwords you wish to target
|
90
|
-
const COMMON_PASSPHRASES = ['passphrase', 'apple', 'password', 'p@55w0rd']
|
91
|
-
|
92
|
-
commonText.textContent = `Try typing any of the following: ${COMMON_PASSPHRASES.join(', ')}`
|
93
|
-
|
94
|
-
// function that checks if the user password is in the common password list
|
95
|
-
const isCommon = (passphrase) => {
|
96
|
-
if (COMMON_PASSPHRASES.includes(passphrase))
|
97
|
-
return true
|
98
|
-
return false
|
99
|
-
}
|
100
|
-
|
101
|
-
// event listeners attached to the input field
|
102
|
-
passphrase.addEventListener('input', (e) => {
|
103
|
-
const passphrase = e.target.value;
|
104
|
-
|
105
|
-
// pass in passphrase to the handleStrengthCalculation and set that equal to result variable
|
106
|
-
const result = handleStrengthCalculation({ passphrase: passphrase, common: isCommon(passphrase) })
|
107
|
-
|
108
|
-
// conditional statment to show or hide progress_simple bar and caption if user has entered a password
|
109
|
-
if (passphrase) {
|
110
|
-
barVariant.style.display = 'block';
|
111
|
-
|
112
|
-
barPercent.style.display = 'block';
|
113
|
-
|
114
|
-
caption.style.display = 'block';
|
115
|
-
} else {
|
116
|
-
barVariant.style.display = 'none';
|
117
|
-
|
118
|
-
barPercent.style.display = 'none';
|
119
|
-
|
120
|
-
caption.style.display = 'none';
|
121
|
-
}
|
122
|
-
|
123
|
-
// set the width of the progress_simple kit
|
124
|
-
barPercent.style.width = result.percent.toString()+ "%"
|
125
|
-
|
126
|
-
|
127
|
-
// set the variant of the progress_simple kit
|
128
|
-
barVariant.setAttribute("class", "pb_progress_simple_kit_"+ result.variant +"_left");
|
129
|
-
|
130
|
-
|
131
|
-
// set the text of the caption kit
|
132
|
-
caption.textContent = result.label
|
133
|
-
});
|
134
|
-
|
135
|
-
})
|
136
|
-
<% end %>
|
@@ -1,5 +0,0 @@
|
|
1
|
-
<div class="pb_pill_kit_warning"><div class="pb_title_kit_size_4 pb_pill_text">Disclaimer</div></div>
|
2
|
-
|
3
|
-
This example depends on the `zxcvbn` library.
|
4
|
-
|
5
|
-
You can use any library to achieve the same result, this example only intends to show how to add more features to the `Passphrase` kit.
|
@@ -1,51 +0,0 @@
|
|
1
|
-
<%= pb_rails("passphrase", props: { classname: "pass_input_1" }) %>
|
2
|
-
|
3
|
-
<%= pb_rails("passphrase", props: { confirmation: true, classname: "pass_input_2"}) %>
|
4
|
-
|
5
|
-
<div id="match"> </div>
|
6
|
-
|
7
|
-
<%= javascript_tag do %>
|
8
|
-
window.addEventListener("DOMContentLoaded", () => {
|
9
|
-
|
10
|
-
const useState = (defaultValue) => {
|
11
|
-
let value = defaultValue;
|
12
|
-
const getValue = () => value
|
13
|
-
const setValue = (newValue) => {
|
14
|
-
return value = newValue
|
15
|
-
}
|
16
|
-
return [getValue, setValue];
|
17
|
-
}
|
18
|
-
|
19
|
-
const [input, setInput] = useState('')
|
20
|
-
const [confirmationInput, setConfirmationInput] = useState('')
|
21
|
-
|
22
|
-
const match = document.querySelector("#match")
|
23
|
-
|
24
|
-
const input1 = document.querySelector(".pass_input_1").querySelector("input")
|
25
|
-
const input2 = document.querySelector(".pass_input_2").querySelector("input")
|
26
|
-
|
27
|
-
input1.addEventListener('input', (e) => {
|
28
|
-
setInput(e.target.value)
|
29
|
-
setMatchText()
|
30
|
-
});
|
31
|
-
|
32
|
-
input2.addEventListener('input', (e) => {
|
33
|
-
setConfirmationInput(e.target.value)
|
34
|
-
setMatchText()
|
35
|
-
});
|
36
|
-
|
37
|
-
const setMatchText = () => {
|
38
|
-
|
39
|
-
if (input() && confirmationInput()) {
|
40
|
-
if (input() === confirmationInput()) {
|
41
|
-
match.textContent = "They match!"
|
42
|
-
} else {
|
43
|
-
match.textContent = "They don't match!"
|
44
|
-
}
|
45
|
-
} else {
|
46
|
-
match.textContent = ""
|
47
|
-
}
|
48
|
-
|
49
|
-
}
|
50
|
-
})
|
51
|
-
<% end %>
|
@@ -1,39 +0,0 @@
|
|
1
|
-
import React, { useState } from 'react'
|
2
|
-
|
3
|
-
import {Body, Passphrase} from '../..'
|
4
|
-
|
5
|
-
const PassphraseConfirmation = (props) => {
|
6
|
-
const [input, setInput] = useState('')
|
7
|
-
const [confirmationInput, setConfirmationInput] = useState('')
|
8
|
-
|
9
|
-
const handleChange = (e) => setInput(e.target.value)
|
10
|
-
const handleConfirmationChange = (e) => setConfirmationInput(e.target.value)
|
11
|
-
|
12
|
-
return (
|
13
|
-
<>
|
14
|
-
<div>
|
15
|
-
<Passphrase
|
16
|
-
onChange={handleChange}
|
17
|
-
value={input}
|
18
|
-
{...props}
|
19
|
-
/>
|
20
|
-
<Passphrase
|
21
|
-
confirmation
|
22
|
-
onChange={handleConfirmationChange}
|
23
|
-
value={confirmationInput}
|
24
|
-
{...props}
|
25
|
-
/>
|
26
|
-
{input && confirmationInput && (
|
27
|
-
<Body
|
28
|
-
text={
|
29
|
-
input === confirmationInput ? "They match!" : "They don't match!"
|
30
|
-
}
|
31
|
-
{...props}
|
32
|
-
/>
|
33
|
-
)}
|
34
|
-
</div>
|
35
|
-
</>
|
36
|
-
);
|
37
|
-
}
|
38
|
-
|
39
|
-
export default PassphraseConfirmation
|
@@ -1,123 +0,0 @@
|
|
1
|
-
<%= pb_rails("passphrase", props: { label: "Passphrase", classname: "passphrase_change" }) %>
|
2
|
-
|
3
|
-
<%= pb_rails("progress_simple", props: { percent: 0, id: "bar_change" }) %>
|
4
|
-
|
5
|
-
<%= pb_rails("caption", props: { size: 'xs', text: "hello", id: "caption_change" }) %>
|
6
|
-
|
7
|
-
<%= pb_rails("text_input", props: { label: "Passphrase Strength", value: "0", disabled: true, id: "calc_strength_change" }) %>
|
8
|
-
|
9
|
-
|
10
|
-
<%= javascript_tag do %>
|
11
|
-
window.addEventListener("DOMContentLoaded", () => {
|
12
|
-
|
13
|
-
// variables for the kits you are targeting
|
14
|
-
const passphrase = document.querySelector(".passphrase_change").querySelector("input")
|
15
|
-
const calcStrength = document.querySelector("#calc_strength_change")
|
16
|
-
const barVariant = document.getElementById("bar_change")
|
17
|
-
const barPercent = document.getElementById("bar_change").querySelector("div")
|
18
|
-
const caption = document.getElementById("caption_change")
|
19
|
-
|
20
|
-
// hide the bar and captions
|
21
|
-
barVariant.style.display = 'none';
|
22
|
-
barPercent.style.display = 'none';
|
23
|
-
caption.style.display = 'none';
|
24
|
-
|
25
|
-
|
26
|
-
const handleStrengthCalculation = (settings) => {
|
27
|
-
const {
|
28
|
-
passphrase = "",
|
29
|
-
common = false,
|
30
|
-
isPwned = false,
|
31
|
-
averageThreshold = 2,
|
32
|
-
minLength = 12,
|
33
|
-
strongThreshold = 3,
|
34
|
-
} = settings
|
35
|
-
|
36
|
-
const resultByScore = {
|
37
|
-
0: {
|
38
|
-
variant: 'negative',
|
39
|
-
label: '',
|
40
|
-
percent: 0,
|
41
|
-
},
|
42
|
-
1: {
|
43
|
-
variant: 'negative',
|
44
|
-
label: 'This passphrase is too common',
|
45
|
-
percent: 25,
|
46
|
-
},
|
47
|
-
2: {
|
48
|
-
variant: 'negative',
|
49
|
-
label: 'Too weak',
|
50
|
-
percent: 25,
|
51
|
-
},
|
52
|
-
3: {
|
53
|
-
variant: 'warning',
|
54
|
-
label: 'Almost there, keep going!',
|
55
|
-
percent: 50,
|
56
|
-
},
|
57
|
-
4: {
|
58
|
-
variant: 'positive',
|
59
|
-
label: 'Success! Strong passphrase',
|
60
|
-
percent: 100,
|
61
|
-
}
|
62
|
-
}
|
63
|
-
|
64
|
-
const { score } = zxcvbn(passphrase);
|
65
|
-
|
66
|
-
const noPassphrase = passphrase.length <= 0
|
67
|
-
const commonPassphrase = common || isPwned
|
68
|
-
const weakPassphrase = passphrase.length < minLength || score < averageThreshold
|
69
|
-
const averagePassphrase = score < strongThreshold
|
70
|
-
const strongPassphrase = score >= strongThreshold
|
71
|
-
|
72
|
-
if (noPassphrase) {
|
73
|
-
return {...resultByScore[0], score}
|
74
|
-
} else if (commonPassphrase) {
|
75
|
-
return {...resultByScore[1], score}
|
76
|
-
} else if (weakPassphrase) {
|
77
|
-
return {...resultByScore[2], score}
|
78
|
-
} else if (averagePassphrase){
|
79
|
-
return {...resultByScore[3], score}
|
80
|
-
} else if (strongPassphrase) {
|
81
|
-
return {...resultByScore[4], score}
|
82
|
-
}
|
83
|
-
}
|
84
|
-
|
85
|
-
// event listeners attached to the input field
|
86
|
-
passphrase.addEventListener('input', (e) => {
|
87
|
-
const passphrase = e.target.value;
|
88
|
-
|
89
|
-
// pass in passphrase to the handleStrengthCalculation and set that equal to result variable
|
90
|
-
const result = handleStrengthCalculation({passphrase: passphrase})
|
91
|
-
|
92
|
-
// set the value of the text_input to the score
|
93
|
-
calcStrength.value = result.score
|
94
|
-
|
95
|
-
// conditional statment to show or hide progress_simple bar and caption if user has entered a password
|
96
|
-
if (passphrase) {
|
97
|
-
barVariant.style.display = 'block';
|
98
|
-
|
99
|
-
barPercent.style.display = 'block';
|
100
|
-
|
101
|
-
caption.style.display = 'block';
|
102
|
-
} else {
|
103
|
-
barVariant.style.display = 'none';
|
104
|
-
|
105
|
-
barPercent.style.display = 'none';
|
106
|
-
|
107
|
-
caption.style.display = 'none';
|
108
|
-
}
|
109
|
-
|
110
|
-
// set the width of the progress_simple kit
|
111
|
-
barPercent.style.width = result.percent.toString()+ "%"
|
112
|
-
|
113
|
-
|
114
|
-
// set the variant of the progress_simple kit
|
115
|
-
barVariant.setAttribute("class", "pb_progress_simple_kit_"+ result.variant +"_left");
|
116
|
-
|
117
|
-
|
118
|
-
// set the text of the caption kit
|
119
|
-
caption.textContent = result.label
|
120
|
-
});
|
121
|
-
|
122
|
-
})
|
123
|
-
<% end %>
|