Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(151)

Side by Side Diff: chrome/browser/resources/settings/people_page/quick_unlock_setup_pin.js

Issue 2098663002: Add settings screen that lets a user setup a PIN to unlock their device with. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@pin-unlock-settings-choose-method
Patch Set: Rebase account for parent CL changes Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 /**
6 * @fileoverview
7 * 'settings-quick-unlock-setup-pin' is the settings page for choosing a PIN.
8 *
9 * Example:
10 *
11 * <settings-quick-unlock-setup-pin
12 * set-modes="[[quickUnlockSetModes]]"
13 * current-route="{{currentRoute}}">
14 * </settings-quick-unlock-setup-pin>
15 */
16
17 (function() {
18 'use strict';
19
20 /**
21 * The step in the setup PIN flow.
22 * @const
23 */
24 var QuickUnlockSetupPinStep = {
tommycli 2016/07/13 19:31:11 I think the confirm/choose stuff could be simplifi
jdufault 2016/07/13 20:38:13 Done.
25 CHOOSE_PIN: 'choose-pin',
26 CONFIRM_PIN: 'confirm-pin'
27 };
28
29 /**
30 * The type of problem message to display. Each entry contains the i18n message
31 * id and the associated css class to display the problem with. At most one
32 * problem can be shown at a time.
33 * @const
34 */
35 var QuickUnlockSetupPinProblemType = {
tommycli 2016/07/13 19:31:12 If there's not going to be more than 3 errors, I t
jdufault 2016/07/13 20:38:13 I've done some renaming, but this makes the showPr
tommycli 2016/07/13 20:57:10 Okay, sounds good. Thanks for trying it.
36 TOO_SHORT: {
37 messageId: 'quickUnlockConfigurePinChoosePinTooShort',
38 class: 'error'
39 },
40 WEAK: {
41 messageId: 'quickUnlockConfigurePinChoosePinWeakPinWarning',
42 class: 'warning'
43 },
44 MISMATCHED: {
45 messageId: 'quickUnlockConfigurePinMismatchedPins',
46 class: 'error'
47 }
48 };
49
50 /**
51 * A list of the top-10 most commmonly used PINs. This list is taken from
52 * www.datagenetics.com/blog/september32012/.
53 * @const
54 */
55 var WEAK_PINS = [
56 '1234', '1111', '0000', '1212', '7777', '1004', '2000', '4444', '2222',
57 '6969'
58 ];
59
60 /**
61 * When the user should be shown an error/warning, wait for this long until
62 * showing them the problem, to give them a chance to stop typing.
63 * @const
64 */
65 var SHOW_PROBLEM_DELAY_IN_MS = 500;
tommycli 2016/07/13 19:31:12 Is the delay mechanism a requirement? Because othe
jdufault 2016/07/13 20:38:13 Without the delay, as you type the PIN you'll imme
66
67 Polymer({
68 is: 'settings-quick-unlock-setup-pin',
69
70 behaviors: [
tommycli 2016/07/13 19:31:12 formatting seems odd here
jdufault 2016/07/13 20:38:13 I've added a newline. I'm not sure otherwise what
71 QuickUnlockPasswordDetectBehavior, I18nBehavior
72 ],
73
74 properties: {
75 /**
76 * The current PIN keyboard value.
77 * @private
78 */
79 pinKeyboardValue_: String,
80
81 /**
82 * Stores the initial PIN value so it can be confirmed.
83 * @private
84 */
85 initialPin_: String,
86
87 /**
88 * String content of the title element.
89 * @private
90 */
91 titleMessage_: String,
tommycli 2016/07/13 19:31:11 Instead of a message variable, how about two dom-i
jdufault 2016/07/13 20:38:13 Done, I like this better.
92
93 /**
94 * String content of the continue/save button.
95 * @private
96 */
97 continueMessage_: String,
tommycli 2016/07/13 19:31:11 Ditto here.
jdufault 2016/07/13 20:38:13 Done.
98
99 /**
100 * Should the step-specific problem message be displayed?
101 * @private
102 */
103 showProblem_: Boolean,
tommycli 2016/07/13 19:31:12 I think you can axe this boolean and just make int
jdufault 2016/07/13 20:38:13 Done.
104
105 /**
106 * The actual problem message to display.
107 * @private
108 */
109 problemMessage_: String,
110
111 /**
112 * The type of problem class to show (warning or error).
113 */
114 problemClass_: String,
115
116 /**
117 * Should the step-specific submit button be displayed?
118 * @private
119 */
120 enableSubmit_: Boolean,
121
122 /**
123 * The current step/subpage we are on.
124 * @private
125 */
126 step_: {
127 type: String,
128 value: QuickUnlockSetupPinStep.CHOOSE_PIN,
129 },
130 },
131
132 observers: [
133 'onRouteChanged_(currentRoute)',
134 'onSetModesChanged_(setModes)'
135 ],
136
137 /** @override */
138 attached: function() {
139 this.resetState_();
140 this.askForPasswordIfUnset();
141 },
142
143 /** @private */
144 onRouteChanged_: function(currentRoute) {
145 if (this.isScreenActive(QuickUnlockScreen.SETUP_PIN)) {
146 this.askForPasswordIfUnset();
147 } else {
148 // If the user hits the back button, they can leave the element
149 // half-completed; therefore, reset state if the element is not active.
150 this.resetState_();
151 }
152 },
153
154 /** @private */
155 onSetModesChanged_: function() {
156 if (this.isScreenActive(QuickUnlockScreen.SETUP_PIN))
157 this.askForPasswordIfUnset();
158 },
159
160 /**
161 * Resets the element to the initial state.
162 * @private
163 */
164 resetState_: function() {
165 this.initialPin_ = '';
166 this.pinKeyboardValue_ = '';
167 this.showProblem_ = false;
168 this.enableSubmit_ = false;
169 this.setStep_(QuickUnlockSetupPinStep.CHOOSE_PIN);
170 this.onPinChange_();
171 },
172
173 /**
174 * Returns true if the given PIN is likely easy to guess.
175 * @private
176 */
177 isPinWeak_: function(pin) {
178 // Warn if it's a top-10 pin.
179 if (WEAK_PINS.includes(pin))
180 return true;
181
182 // Warn if the PIN is consecutive digits.
183 var delta = 0;
184 for (var i = 1; i < pin.length; ++i) {
185 var prev = Number(pin[i - 1]);
186 var num = Number(pin[i]);
187 if (Number.isNaN(prev) || Number.isNaN(num))
188 return false;
189 delta = Math.max(delta, Math.abs(num - prev));
190 }
191
192 return delta <= 1;
193 },
194
195 /**
196 * Returns true if the given PIN matches PIN requirements, such as minimum
197 * length.
198 * @private
199 */
200 isPinLongEnough_: function(pin) {
201 return pin.length >= 4;
202 },
203
204 /**
205 * Returns true if the PIN is ready to be changed to a new value.
206 * @private
207 */
208 canSubmit_: function() {
209 return this.isPinLongEnough_(this.pinKeyboardValue_) &&
210 this.initialPin_ == this.pinKeyboardValue_;
211 },
212
213 /**
214 * Notify the user about a problem. The problem will be shown after
215 * SHOW_PROBLEM_DELAY_IN_MS. The problem show can be cancelled by calling
216 * |this.cancelPendingProblem_()|.
217 * @private
218 */
219 postProblem_: function(problemType) {
220 function activateProblem() {
221 this.showProblem_ = true;
222 this.problemMessage_ = this.i18n(problemType.messageId);
223 this.problemClass_ = problemType.class;
224 setTimeout(this.updateStyles.bind(this));
tommycli 2016/07/13 19:31:11 Hmm... does it not work without this call? I've ne
jdufault 2016/07/13 20:38:13 The icon color is not updated without the call. I'
tommycli 2016/07/13 20:57:09 Cool. Getting rid of the setTimeout makes it much
225 }
226
227 this.cancelPendingProblem_();
228 this.pendingProblem_ = setTimeout(activateProblem.bind(this),
229 SHOW_PROBLEM_DELAY_IN_MS);
230 },
231
232 /** @private */
233 cancelPendingProblem_: function() {
234 if (this.pendingProblem_) {
235 clearTimeout(this.pendingProblem_);
236 delete this.pendingProblem_;
237 }
238 },
239
240 /** @private */
241 onPinChange_: function() {
242 // If the user typed, we want to reset the show problem timeout.
243 this.cancelPendingProblem_();
244
245 if (this.isChooseStep_()) {
246 var isPinLongEnough = this.isPinLongEnough_(this.pinKeyboardValue_);
247 var isWeak = isPinLongEnough && this.isPinWeak_(this.pinKeyboardValue_);
248
249 if (!isPinLongEnough && this.pinKeyboardValue_)
250 this.postProblem_(QuickUnlockSetupPinProblemType.TOO_SHORT);
251 else if (isWeak)
252 this.postProblem_(QuickUnlockSetupPinProblemType.WEAK);
253 else
254 this.showProblem_ = false;
255
256 this.enableSubmit_ = isPinLongEnough;
257
258 } else if (this.isConfirmStep_()) {
259 var canSubmit = this.canSubmit_();
260
261 if (!canSubmit && this.pinKeyboardValue_)
262 this.postProblem_(QuickUnlockSetupPinProblemType.MISMATCHED);
263 else
264 this.showProblem_ = false;
265
266 this.enableSubmit_ = canSubmit;
267 }
268 },
269
270 /** @private */
271 onPinSubmit_: function() {
272 if (this.isChooseStep_()) {
273 if (this.isPinLongEnough_(this.pinKeyboardValue_)) {
274 this.initialPin_ = this.pinKeyboardValue_;
275 this.pinKeyboardValue_ = '';
276 this.setStep_(QuickUnlockSetupPinStep.CONFIRM_PIN);
277 this.onPinChange_();
278 }
279 } else if (this.isConfirmStep_()) {
280 // onPinSubmit_ gets called if the user hits enter on the PIN keyboard.
281 // The PIN is not guaranteed to be valid in that case.
282 if (!this.canSubmit_())
283 return;
284
285 function onSetModesCompleted(didSet) {
286 if (!didSet) {
287 console.error('Failed to update pin');
288 return;
289 }
290
291 this.resetState_();
292 this.currentRoute = {
293 page: 'basic',
294 section: 'people',
295 subpage: [QuickUnlockScreen.CHOOSE_METHOD]
296 };
297 }
298
299 this.setModes.call(
300 null,
301 [chrome.quickUnlockPrivate.QuickUnlockMode.PIN],
302 [this.pinKeyboardValue_],
303 onSetModesCompleted.bind(this));
304 }
305 },
306
307 /** @private */
308 setStep_: function(step) {
309 this.step_ = step;
310 switch (this.step_) {
311 case QuickUnlockSetupPinStep.CHOOSE_PIN:
312 this.titleMessage_ = this.i18n('quickUnlockConfigurePinChoosePinTitle');
313 this.continueMessage_ =
314 this.i18n('quickUnlockConfigurePinContinueButton');
315 break;
316 case QuickUnlockSetupPinStep.CONFIRM_PIN:
317 this.titleMessage_ =
318 this.i18n('quickUnlockConfigurePinConfirmPinTitle');
319 this.continueMessage_ = this.i18n('save');
320 break;
321 }
322 },
323
324 /** @private */
325 isChooseStep_: function() {
326 return this.step_ == QuickUnlockSetupPinStep.CHOOSE_PIN;
327 },
328
329 /** @private */
330 isConfirmStep_: function() {
331 return this.step_ == QuickUnlockSetupPinStep.CONFIRM_PIN;
332 },
333 });
334
335 })();
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698