playbook_ui 11.12.1.pre.alpha.passphrase1 → 11.12.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (31) hide show
  1. checksums.yaml +4 -4
  2. data/app/pb_kits/playbook/pb_passphrase/_passphrase.jsx +97 -56
  3. data/app/pb_kits/playbook/pb_passphrase/docs/_passphrase_breached.html.erb +1 -145
  4. data/app/pb_kits/playbook/pb_passphrase/docs/_passphrase_breached.jsx +3 -127
  5. data/app/pb_kits/playbook/pb_passphrase/docs/_passphrase_breached.md +2 -11
  6. data/app/pb_kits/playbook/pb_passphrase/docs/_passphrase_common.jsx +8 -90
  7. data/app/pb_kits/playbook/pb_passphrase/docs/_passphrase_default.html.erb +2 -0
  8. data/app/pb_kits/playbook/pb_passphrase/docs/_passphrase_default.jsx +20 -6
  9. data/app/pb_kits/playbook/pb_passphrase/docs/_passphrase_default.md +1 -0
  10. data/app/pb_kits/playbook/pb_passphrase/docs/_passphrase_input_props.html.erb +2 -2
  11. data/app/pb_kits/playbook/pb_passphrase/docs/_passphrase_input_props.jsx +1 -1
  12. data/app/pb_kits/playbook/pb_passphrase/docs/_passphrase_meter_settings.html.erb +5 -318
  13. data/app/pb_kits/playbook/pb_passphrase/docs/_passphrase_meter_settings.jsx +48 -134
  14. data/app/pb_kits/playbook/pb_passphrase/docs/_passphrase_meter_settings.md +5 -11
  15. data/app/pb_kits/playbook/pb_passphrase/docs/_passphrase_strength_change.jsx +20 -96
  16. data/app/pb_kits/playbook/pb_passphrase/docs/_passphrase_strength_change.md +2 -6
  17. data/app/pb_kits/playbook/pb_passphrase/docs/example.yml +0 -4
  18. data/app/pb_kits/playbook/pb_passphrase/docs/index.js +0 -1
  19. data/app/pb_kits/playbook/pb_passphrase/passphrase.html.erb +1 -1
  20. data/app/pb_kits/playbook/pb_passphrase/passphrase.rb +9 -5
  21. data/app/pb_kits/playbook/pb_passphrase/passphrase.test.jsx +47 -0
  22. data/app/pb_kits/playbook/pb_passphrase/passwordStrength.js +55 -0
  23. data/app/pb_kits/playbook/pb_passphrase/useHaveIBeenPwned.js +52 -0
  24. data/app/pb_kits/playbook/pb_passphrase/useZxcvbn.js +58 -0
  25. data/lib/playbook/version.rb +2 -2
  26. metadata +8 -9
  27. data/app/pb_kits/playbook/pb_passphrase/docs/_passphrase_common.html.erb +0 -136
  28. data/app/pb_kits/playbook/pb_passphrase/docs/_passphrase_common.md +0 -5
  29. data/app/pb_kits/playbook/pb_passphrase/docs/_passphrase_confirmation.html.erb +0 -51
  30. data/app/pb_kits/playbook/pb_passphrase/docs/_passphrase_confirmation.jsx +0 -39
  31. data/app/pb_kits/playbook/pb_passphrase/docs/_passphrase_strength_change.html.erb +0 -123
@@ -1,114 +1,32 @@
1
- import React, { useState, useEffect } from 'react'
1
+ import React, { useState } from 'react'
2
2
 
3
- import {Body, Caption, Passphrase, ProgressSimple} from '../..'
4
- import zxcvbn from 'zxcvbn'
3
+ import Passphrase from '../_passphrase'
4
+ import Body from '../../pb_body/_body'
5
5
 
6
6
  const PassphraseCommon = (props) => {
7
7
  const [input, setInput] = useState('')
8
- const [checkStrength, setCheckStrength] = useState({
9
- label: '',
10
- percent: 0,
11
- score: 0,
12
- variant: ''
13
- })
14
- const handleChange = (e) => setInput(e.target.value)
15
-
16
- const handleStrengthCalculation = (settings) => {
17
- const {
18
- passphrase = "",
19
- common = false,
20
- isPwned = false,
21
- averageThreshold = 2,
22
- minLength = 12,
23
- strongThreshold = 3,
24
- } = settings
25
-
26
- const resultByScore = {
27
- 0: {
28
- variant: 'negative',
29
- label: '',
30
- percent: 0,
31
- },
32
- 1: {
33
- variant: 'negative',
34
- label: 'This passphrase is too common',
35
- percent: 25,
36
- },
37
- 2: {
38
- variant: 'negative',
39
- label: 'Too weak',
40
- percent: 25,
41
- },
42
- 3: {
43
- variant: 'warning',
44
- label: 'Almost there, keep going!',
45
- percent: 50,
46
- },
47
- 4: {
48
- variant: 'positive',
49
- label: 'Success! Strong passphrase',
50
- percent: 100,
51
- }
52
- }
53
-
54
- const { score } = zxcvbn(passphrase);
55
-
56
- const noPassphrase = passphrase.length <= 0
57
- const commonPassphrase = common || isPwned
58
- const weakPassphrase = passphrase.length < minLength || score < averageThreshold
59
- const averagePassphrase = score < strongThreshold
60
- const strongPassphrase = score >= strongThreshold
61
8
 
62
- if (noPassphrase) {
63
- return {...resultByScore[0], score}
64
- } else if (commonPassphrase) {
65
- return {...resultByScore[1], score}
66
- } else if (weakPassphrase) {
67
- return {...resultByScore[2], score}
68
- } else if (averagePassphrase){
69
- return {...resultByScore[3], score}
70
- } else if (strongPassphrase) {
71
- return {...resultByScore[4], score}
72
- }
73
- }
9
+ const handleChange = (e) => setInput(e.target.value)
74
10
 
75
11
  const COMMON_PASSPHRASES = ['passphrase', 'apple', 'password', 'p@55w0rd']
76
12
 
77
- const isCommon = (passphrase) => {
13
+ const commonCheck = (passphrase) => {
78
14
  if (COMMON_PASSPHRASES.includes(passphrase))
79
15
  return true
80
16
  return false
81
17
  }
82
18
 
83
- useEffect(() => {
84
- const result = handleStrengthCalculation({ passphrase: input, common: isCommon(input) });
85
- setCheckStrength({ ...result })
86
- }, [input])
87
-
88
-
89
19
  return (
90
20
  <>
91
21
  <div>
92
- <Body
93
- marginBottom='md'
94
- text={`Try typing any of the following: ${COMMON_PASSPHRASES.join(', ')}`} />
22
+ <Body text={`Try typing any of the following: ${COMMON_PASSPHRASES.join(' ')}`} />
23
+ <br />
95
24
  <Passphrase
25
+ common={commonCheck(input)}
96
26
  onChange={handleChange}
97
27
  value={input}
98
28
  {...props}
99
29
  />
100
- {input.length > 0 && (
101
- <>
102
- <ProgressSimple
103
- className={input.length === 0 ? "progress-empty-input" : null}
104
- percent={checkStrength.percent}
105
- variant={checkStrength.variant}
106
- />
107
- <Caption size='xs'
108
- text={checkStrength.label}
109
- />
110
- </>
111
- )}
112
30
  </div>
113
31
  </>
114
32
  )
@@ -1 +1,3 @@
1
1
  <%= pb_rails("passphrase") %>
2
+
3
+ <%= pb_rails("passphrase", props: { confirmation: true}) %>
@@ -6,13 +6,27 @@ const PassphraseDefault = (props) => {
6
6
  const [input, setInput] = useState('')
7
7
  const handleChange = (e) => setInput(e.target.value)
8
8
 
9
+ const [confoInput, setConfoInput] = useState('')
10
+ const handleConfoChange = (e) => setConfoInput(e.target.value)
11
+
9
12
  return (
10
- <Passphrase
11
- id="my-passphrase"
12
- onChange={handleChange}
13
- value={input}
14
- {...props}
15
- />
13
+ <>
14
+ <div>
15
+ <Passphrase
16
+ id="my-passphrase"
17
+ onChange={handleChange}
18
+ value={input}
19
+ {...props}
20
+ />
21
+ <Passphrase
22
+ confirmation
23
+ onChange={handleConfoChange}
24
+ value={confoInput}
25
+ {...props}
26
+ />
27
+ <span>{input === confoInput ? 'They match!' : 'They don\'t match!'}</span>
28
+ </div>
29
+ </>
16
30
  )
17
31
  }
18
32
 
@@ -0,0 +1 @@
1
+ Use the `confirmation` prop to only include the label and show/hide icon.
@@ -4,7 +4,7 @@
4
4
  id: "my-disabled-passphrase",
5
5
  name: "my-disabled-field",
6
6
  },
7
- label: "Pass props directly to input kit"
7
+ label: "Input props passed directly to input kit"
8
8
  }) %>
9
9
 
10
10
  <%= pb_rails("passphrase", props: {
@@ -12,5 +12,5 @@
12
12
  id: "my-custome-id",
13
13
  name: "my-value-name",
14
14
  },
15
- label: "Set name and ID for use in form libraries"
15
+ label: "Set name, id, etc for use in forms"
16
16
  }) %>
@@ -36,7 +36,7 @@ const PassphraseInputProps = (props) => {
36
36
  {...props}
37
37
  />
38
38
  <Passphrase
39
- inputProps={{ name: 'my-value-name', id: 'my-value-id-2' }}
39
+ inputProps={{ name: 'my-value-name', id: 'my-value-id' }}
40
40
  label="Set name and ID for use in form libraries"
41
41
  onChange={handleChange}
42
42
  value={input}
@@ -1,323 +1,10 @@
1
- <%= pb_rails("passphrase", props: { label: "Default Settings", classname: "def_passphrase" }) %>
2
1
 
3
- <%= pb_rails("progress_simple", props: { percent: 0, id: "def_bar" }) %>
2
+ <%= pb_rails("passphrase", props: { label: "Default Settings"}) %>
4
3
 
5
- <%= pb_rails("caption", props: { size: 'xs', text: "hello", id: "def_caption" }) %>
4
+ <%= pb_rails("passphrase", props: { label: "Min length = 5", min_length: 5}) %>
6
5
 
7
- <%= pb_rails("text_input", props: { label: "Calculated Strength", value: "0", disabled: true, id: "calc_strength" }) %>
6
+ <%= pb_rails("passphrase", props: { label: "Min length = 30", min_length: 30}) %>
8
7
 
9
- <%= pb_rails("passphrase", props: { label: "Min length = 5", classname: "min_5" }) %>
8
+ <%= pb_rails("passphrase", props: { average_threshold: 1, label: "Average Threshold = 1"}) %>
10
9
 
11
- <%= pb_rails("progress_simple", props: { percent: 0, id: "min_5_bar" }) %>
12
-
13
- <%= pb_rails("caption", props: { size: 'xs', text: "hello", id: "min_5_caption" }) %>
14
-
15
- <%= pb_rails("passphrase", props: { label: "Min length = 30", classname: "min_30" }) %>
16
-
17
- <%= pb_rails("progress_simple", props: { percent: 0, id: "min_30_bar" }) %>
18
-
19
- <%= pb_rails("caption", props: { size: 'xs', text: "hello", id: "min_30_caption" }) %>
20
-
21
- <%= pb_rails("passphrase", props: { label: "Average Threshold = 1", classname: "avg_1" }) %>
22
-
23
- <%= pb_rails("progress_simple", props: { percent: 0, id: "avg_1_bar" }) %>
24
-
25
- <%= pb_rails("caption", props: { size: 'xs', text: "hello", id: "avg_1_caption" }) %>
26
-
27
- <%= pb_rails("passphrase", props: { label: "Strong Threshold = 4", classname: "strong_4" }) %>
28
-
29
- <%= pb_rails("progress_simple", props: { percent: 0, id: "strong_4_bar" }) %>
30
-
31
- <%= pb_rails("caption", props: { size: 'xs', text: "hello", id: "strong_4_caption" }) %>
32
-
33
-
34
-
35
- <%= javascript_tag do %>
36
- window.addEventListener("DOMContentLoaded", () => {
37
-
38
-
39
- // variables for the passphrase kits you are targeting
40
- const defPassphrase = document.querySelector(".def_passphrase").querySelector("input")
41
- const min5 = document.querySelector(".min_5").querySelector("input")
42
- const min30 = document.querySelector(".min_30").querySelector("input")
43
- const avg1 = document.querySelector(".avg_1").querySelector("input")
44
- const strong4 = document.querySelector(".strong_4").querySelector("input")
45
-
46
- // variable for the text_input kit you are targeting
47
- const calcStrength = document.querySelector("#calc_strength")
48
-
49
- // variables for the progress_simple kits you are targeting
50
- const defBarVariant = document.getElementById("def_bar")
51
- const defBarPercent = document.getElementById("def_bar").querySelector("div")
52
- const min5BarVariant = document.getElementById("min_5_bar")
53
- const min5BarPercent = document.getElementById("min_5_bar").querySelector("div")
54
- const min30BarVariant = document.getElementById("min_30_bar")
55
- const min30BarPercent = document.getElementById("min_30_bar").querySelector("div")
56
- const avg1BarVariant = document.getElementById("avg_1_bar")
57
- const avg1BarPercent = document.getElementById("avg_1_bar").querySelector("div")
58
- const strong4BarVariant = document.getElementById("strong_4_bar")
59
- const strong4BarPercent = document.getElementById("strong_4_bar").querySelector("div")
60
-
61
- // hide all the progress_simple bars
62
- defBarVariant.style.display = 'none';
63
- defBarPercent.style.display = 'none';
64
- min5BarVariant.style.display = 'none';
65
- min5BarPercent.style.display = 'none';
66
- min30BarVariant.style.display = 'none';
67
- min30BarPercent.style.display = 'none';
68
- avg1BarVariant.style.display = 'none';
69
- avg1BarPercent.style.display = 'none';
70
- strong4BarVariant.style.display = 'none';
71
- strong4BarPercent.style.display = 'none';
72
-
73
- // variables for the caption kits you are targeting
74
- const defCaption = document.getElementById("def_caption")
75
- const min5Caption = document.getElementById("min_5_caption")
76
- const min30Caption = document.getElementById("min_30_caption")
77
- const avg1Caption = document.getElementById("avg_1_caption")
78
- const strong4Caption = document.getElementById("strong_4_caption")
79
-
80
- // hide all the captions
81
- defCaption.style.display = 'none';
82
- min5Caption.style.display = 'none';
83
- min30Caption.style.display = 'none';
84
- avg1Caption.style.display = 'none';
85
- strong4Caption.style.display = 'none';
86
-
87
- // funtion that determines strenght of user passowrd using zxcvbn
88
- const handleStrengthCalculation = (settings) => {
89
-
90
- // define the settings object with its defaults
91
- const {
92
- passphrase = "",
93
- common = false,
94
- isPwned = false,
95
- averageThreshold = 2,
96
- minLength = 12,
97
- strongThreshold = 3,
98
- } = settings
99
-
100
- // define the resultsByScore objects, these return an object with a variant and percentage,
101
- // depending on the score of the password
102
- const resultByScore = {
103
- 0: {
104
- variant: 'negative',
105
- label: '',
106
- percent: 0,
107
- },
108
- 1: {
109
- variant: 'negative',
110
- label: 'This passphrase is too common',
111
- percent: 25,
112
- },
113
- 2: {
114
- variant: 'negative',
115
- label: 'Too weak',
116
- percent: 25,
117
- },
118
- 3: {
119
- variant: 'warning',
120
- label: 'Almost there, keep going!',
121
- percent: 50,
122
- },
123
- 4: {
124
- variant: 'positive',
125
- label: 'Success! Strong passphrase',
126
- percent: 100,
127
- }
128
- }
129
-
130
- const { score } = zxcvbn(passphrase);
131
-
132
- const noPassphrase = passphrase.length <= 0
133
- const commonPassphrase = common || isPwned
134
- const weakPassphrase = passphrase.length < minLength || score < averageThreshold
135
- const averagePassphrase = score < strongThreshold
136
- const strongPassphrase = score >= strongThreshold
137
-
138
- // conditional that returns the score of the password, along with the resultByScore object
139
- // so we can change the percantage and variant of the progress_simple kit
140
- if (noPassphrase) {
141
- return {...resultByScore[0], score}
142
- } else if (commonPassphrase) {
143
- return {...resultByScore[1], score}
144
- } else if (weakPassphrase) {
145
- return {...resultByScore[2], score}
146
- } else if (averagePassphrase){
147
- return {...resultByScore[3], score}
148
- } else if (strongPassphrase) {
149
- return {...resultByScore[4], score}
150
- }
151
- }
152
-
153
-
154
- // event listeners attached to the input field
155
- min5.addEventListener('input', (e) => {
156
- const passphrase = e.target.value;
157
-
158
- // defining setting object to spread into handleStrengthCalculation
159
- setting = {
160
- minLength: 5,
161
- }
162
-
163
- // pass in passphrase and setting object to handleStrengthCalculation and set that equal to result variable
164
- const result = handleStrengthCalculation({passphrase, ...setting})
165
-
166
- // set the value of the text_input to the score
167
- calcStrength.value = result.score
168
-
169
- // conditional statment to show or hide progress_simple bar and caption if user has entered a password
170
- if (passphrase) {
171
- min5BarVariant.style.display = 'block';
172
-
173
- min5BarPercent.style.display = 'block';
174
-
175
- min5Caption.style.display = 'block';
176
- } else {
177
- min5BarVariant.style.display = 'none';
178
-
179
- min5BarPercent.style.display = 'none';
180
-
181
- min5Caption.style.display = 'none';
182
- }
183
-
184
- // set the width of the progress_simple kit
185
- min5BarPercent.style.width = result.percent.toString()+ "%"
186
-
187
-
188
- // set the variant of the progress_simple kit
189
- min5BarVariant.setAttribute("class", "pb_progress_simple_kit_"+ result.variant +"_left");
190
-
191
-
192
- // set the text of the caption kit
193
- min5Caption.textContent = result.label
194
- });
195
-
196
- defPassphrase.addEventListener('input', (e) => {
197
- const passphrase = e.target.value;
198
-
199
- const result = handleStrengthCalculation({passphrase})
200
-
201
- calcStrength.value = result.score
202
-
203
- if (passphrase) {
204
- defBarVariant.style.display = 'block';
205
-
206
- defBarPercent.style.display = 'block';
207
-
208
- defCaption.style.display = 'block';
209
- } else {
210
- defBarVariant.style.display = 'none';
211
-
212
- defBarPercent.style.display = 'none';
213
-
214
- defCaption.style.display = 'none';
215
- }
216
-
217
- defBarPercent.style.width = result.percent.toString()+ "%"
218
-
219
- defBarVariant.setAttribute("class", "pb_progress_simple_kit_"+ result.variant +"_left");
220
-
221
- defCaption.textContent = result.label
222
-
223
- });
224
-
225
- min30.addEventListener('input', (e) => {
226
- const passphrase = e.target.value;
227
-
228
- setting = {
229
- minLength: 30,
230
- }
231
-
232
- const result = handleStrengthCalculation({passphrase, ...setting})
233
-
234
- calcStrength.value = result.score
235
-
236
- if (passphrase) {
237
- min30BarVariant.style.display = 'block';
238
-
239
- min30BarPercent.style.display = 'block';
240
-
241
- min30Caption.style.display = 'block';
242
- } else {
243
- min30BarVariant.style.display = 'none';
244
-
245
- min30BarPercent.style.display = 'none';
246
-
247
- min30Caption.style.display = 'none';
248
- }
249
-
250
- min30BarPercent.style.width = result.percent.toString()+ "%"
251
-
252
- min30BarVariant.setAttribute("class", "pb_progress_simple_kit_"+ result.variant +"_left");
253
-
254
- min30Caption.textContent = result.label
255
- });
256
-
257
- avg1.addEventListener('input', (e) => {
258
- const passphrase = e.target.value;
259
-
260
- setting = {
261
- averageThreshold: 1,
262
- }
263
-
264
- const result = handleStrengthCalculation({passphrase, ...setting})
265
-
266
- calcStrength.value = result.score
267
-
268
- if (passphrase) {
269
- avg1BarVariant.style.display = 'block';
270
-
271
- avg1BarPercent.style.display = 'block';
272
-
273
- avg1Caption.style.display = 'block';
274
- } else {
275
- avg1BarVariant.style.display = 'none';
276
-
277
- avg1BarPercent.style.display = 'none';
278
-
279
- avg1Caption.style.display = 'none';
280
- }
281
-
282
- avg1BarPercent.style.width = result.percent.toString()+ "%"
283
-
284
- avg1BarVariant.setAttribute("class", "pb_progress_simple_kit_"+ result.variant +"_left");
285
-
286
- avg1Caption.textContent = result.label
287
- });
288
-
289
- strong4.addEventListener('input', (e) => {
290
- const passphrase = e.target.value;
291
-
292
- setting = {
293
- strongThreshold: 4,
294
- }
295
-
296
- const result = handleStrengthCalculation({passphrase, ...setting})
297
-
298
- calcStrength.value = result.score
299
-
300
- if (passphrase) {
301
- strong4BarVariant.style.display = 'block';
302
-
303
- strong4BarPercent.style.display = 'block';
304
-
305
- strong4Caption.style.display = 'block';
306
- } else {
307
- strong4BarVariant.style.display = 'none';
308
-
309
- strong4BarPercent.style.display = 'none';
310
-
311
- strong4Caption.style.display = 'none';
312
- }
313
-
314
- strong4BarPercent.style.width = result.percent.toString()+ "%"
315
-
316
- strong4BarVariant.setAttribute("class", "pb_progress_simple_kit_"+ result.variant +"_left");
317
-
318
- strong4Caption.textContent = result.label
319
- });
320
-
321
-
322
- })
323
- <% end %>
10
+ <%= pb_rails("passphrase", props: { label: "Strong Threshold = 4", strong_threshold: 4}) %>