Chromium Code Reviews| Index: chrome/browser/resources/settings/people_page/setup_pin_dialog.js |
| diff --git a/chrome/browser/resources/settings/people_page/setup_pin_dialog.js b/chrome/browser/resources/settings/people_page/setup_pin_dialog.js |
| index 14da74e920079e25c9f623a7e76e97b124a5b19e..840a2f51d1d84534865e406b3bfe01f9743abeaa 100644 |
| --- a/chrome/browser/resources/settings/people_page/setup_pin_dialog.js |
| +++ b/chrome/browser/resources/settings/people_page/setup_pin_dialog.js |
| @@ -15,16 +15,6 @@ |
| (function() { |
| 'use strict'; |
| -/** |
| - * A list of the top-10 most commmonly used PINs. This list is taken from |
| - * www.datagenetics.com/blog/september32012/. |
| - * @const |
| - */ |
| -var WEAK_PINS = [ |
| - '1234', '1111', '0000', '1212', '7777', '1004', '2000', '4444', '2222', |
| - '6969' |
| -]; |
| - |
| Polymer({ |
| is: 'settings-setup-pin-dialog', |
| @@ -47,7 +37,10 @@ Polymer({ |
| * The actual problem message to display. |
| * @private |
| */ |
| - problemMessage_: String, |
| + problemMessage_: { |
| + type: String, |
| + value: '' |
| + }, |
| /** |
| * The type of problem class to show (warning or error). |
| @@ -68,6 +61,32 @@ Polymer({ |
| type: Boolean, |
| value: false |
| }, |
| + |
| + /** |
| + * checkCredential is a function thats calls an api to check if a pin has |
| + * any problems. It may be overriden for tests. |
| + * |
| + * @type {Function} |
| + * @private |
| + */ |
| + checkCredential_: { |
| + type: Object, |
| + value: function() { return chrome.quickUnlockPrivate.checkCredential; } |
| + }, |
| + |
| + /** |
| + * getCredentialRequirements is a function thats calls an api get the pin |
| + * policies. It may be overriden for tests. |
| + * |
| + * @type {Function} |
| + * @private |
| + */ |
| + getCredentialRequirements_: { |
| + type: Object, |
| + value: function() { |
| + return chrome.quickUnlockPrivate.getCredentialRequirements; |
| + } |
| + }, |
|
stevenjb
2016/12/14 23:46:34
Rather than make two overridable methods here (and
sammiequon
2016/12/15 17:21:08
Done.
|
| }, |
| /** @override */ |
| @@ -96,6 +115,7 @@ Polymer({ |
| this.pinKeyboardValue_ = ''; |
| this.enableSubmit_ = false; |
| this.isConfirmStep_ = false; |
| + this.hideProblem_(); |
| this.onPinChange_(); |
| }, |
| @@ -106,49 +126,12 @@ Polymer({ |
| }, |
| /** |
| - * Returns true if the given PIN is likely easy to guess. |
| - * @private |
| - * @param {string} pin |
| - * @return {boolean} |
| - */ |
| - isPinWeak_: function(pin) { |
| - // Warn if it's a top-10 pin. |
| - if (WEAK_PINS.includes(pin)) |
| - return true; |
| - |
| - // Warn if the PIN is consecutive digits. |
| - var delta = 0; |
| - for (var i = 1; i < pin.length; ++i) { |
| - var prev = Number(pin[i - 1]); |
| - var num = Number(pin[i]); |
| - if (Number.isNaN(prev) || Number.isNaN(num)) |
| - return false; |
| - delta = Math.max(delta, Math.abs(num - prev)); |
| - } |
| - |
| - return delta <= 1; |
| - }, |
| - |
| - /** |
| - * Returns true if the given PIN matches PIN requirements, such as minimum |
| - * length. |
| + * Returns true if the PIN is ready to be changed to a new value. |
| * @private |
| - * @param {string|undefined} pin |
| * @return {boolean} |
| */ |
| - isPinLongEnough_: function(pin) { |
| - return !!pin && pin.length >= 4; |
| - }, |
| - |
| - /** |
| - * Returns true if the currently entered PIN is the same as the initially |
| - * submitted PIN. |
| - * @private |
| - * @return {boolean} |
| - */ |
| - isPinConfirmed_: function() { |
| - return this.isPinLongEnough_(this.pinKeyboardValue_) && |
| - this.initialPin_ == this.pinKeyboardValue_; |
| + canSubmit_: function() { |
| + return this.initialPin_ == this.pinKeyboardValue_; |
| }, |
| /** |
| @@ -158,17 +141,36 @@ Polymer({ |
| * @param {string} problemClass |
|
stevenjb
2016/12/14 23:46:34
This should really be a locally defined enum.
sammiequon
2016/12/15 17:21:08
Done.
|
| */ |
| showProblem_: function(messageId, problemClass) { |
| - var previousMessage = this.problemMessage_; |
| + // Callback function which handles printing the appropriate message given |
| + // the |messageId|. |
| + function getRequirementsCallback(requirements) { |
| + var additionalInformation = ''; |
| + switch (messageId) { |
| + case 'configurePinTooShort': |
| + additionalInformation = requirements.minLength.toString(); |
| + break; |
| + case 'configurePinTooLong': |
| + additionalInformation = requirements.maxLength.toString(); |
| + break; |
| + case 'configurePinWeakPin': |
| + case 'configurePinMismatched': |
| + break; |
| + default: |
| + assertNotReached(); |
| + break; |
| + } |
| + this.problemMessage_ = this.i18n(messageId, additionalInformation); |
| + } |
|
stevenjb
2016/12/14 23:46:34
This is probably worth breaking out into a separat
sammiequon
2016/12/15 17:21:08
Done.
|
| - // Update problem info. |
| - this.problemMessage_ = this.i18n(messageId); |
| + this.getCredentialRequirements_( |
| + chrome.quickUnlockPrivate.QuickUnlockMode.PIN, |
| + getRequirementsCallback.bind(this)); |
| this.problemClass_ = problemClass; |
| this.updateStyles(); |
| - |
| - // If the problem message has changed, fire an alert. |
| - if (previousMessage != this.problemMessage_) |
| - this.$.problemDiv.setAttribute('role', 'alert'); |
| - }, |
| + this.enableSubmit_ = (problemClass != 'error'); |
| + if (messageId == 'configurePinMismatched') |
| + this.enableSubmit_ = false; |
|
stevenjb
2016/12/14 23:46:34
this.enableSubmit_ =
problemClass != 'error' &&
sammiequon
2016/12/15 17:21:08
Done.
|
| + }, |
| /** @private */ |
| hideProblem_: function() { |
| @@ -176,45 +178,81 @@ Polymer({ |
| this.problemClass_ = ''; |
| }, |
| + /** |
| + * Processes the message received from the quick unlock api and hides/shows |
| + * the problem based on the message. |
| + * @private |
| + * @param {chrome.quickUnlockPrivate.CredentialCheck} message The message |
| + * received from checkCredential. |
|
stevenjb
2016/12/14 23:46:34
4 space indent from @param
sammiequon
2016/12/15 17:21:08
Done.
|
| + */ |
| + processPinProblems_: function(message) { |
| + if (!message.errors.length && !message.warnings.length) { |
| + this.hideProblem_(); |
| + this.enableSubmit_ = true; |
| + return; |
| + } |
| + |
| + if (message.warnings.length) { |
| + switch (message.warnings[0]) { |
| + case 'TOO_WEAK': |
|
stevenjb
2016/12/14 23:46:34
This should be defined in quick_unlock_private.idl
sammiequon
2016/12/15 17:21:08
Done.
|
| + this.showProblem_('configurePinWeakPin', 'warning'); |
| + break; |
| + default: |
| + assertNotReached(); |
| + break; |
| + } |
| + } |
| + |
| + if (message.errors.length) { |
| + switch (message.errors[0]) { |
| + case 'TOO_SHORT': |
| + this.showProblem_('configurePinTooShort', 'error'); |
| + break; |
| + case 'TOO_LONG': |
| + this.showProblem_('configurePinTooLong', 'error'); |
| + break; |
| + case 'TOO_WEAK': |
| + this.showProblem_('configurePinWeakPin', 'error'); |
| + break; |
| + default: |
| + assertNotReached(); |
| + break; |
| + } |
| + } |
| + |
| + }, |
| + |
| /** @private */ |
| onPinChange_: function() { |
| if (!this.isConfirmStep_) { |
| - var isPinLongEnough = this.isPinLongEnough_(this.pinKeyboardValue_); |
| - var isWeak = isPinLongEnough && this.isPinWeak_(this.pinKeyboardValue_); |
| - |
| - if (!isPinLongEnough) |
| - this.showProblem_('configurePinTooShort', 'warning'); |
| - else if (isWeak) |
| - this.showProblem_('configurePinWeakPin', 'warning'); |
| - else |
| - this.hideProblem_(); |
| - |
| - this.enableSubmit_ = isPinLongEnough; |
| - |
| + if (this.pinKeyboardValue_) { |
| + this.checkCredential_( |
| + chrome.quickUnlockPrivate.QuickUnlockMode.PIN, |
| + this.pinKeyboardValue_, |
| + this.processPinProblems_.bind(this)); |
| + } |
|
stevenjb
2016/12/14 23:46:34
early exit and elim else
sammiequon
2016/12/15 17:21:08
Done.
|
| } else { |
| - if (this.isPinConfirmed_()) |
| + if (this.canSubmit_()) { |
| this.hideProblem_(); |
| - else |
| + this.enableSubmit_ = true; |
| + } else { |
| this.showProblem_('configurePinMismatched', 'warning'); |
| - |
| - this.enableSubmit_ = true; |
| + } |
| } |
| }, |
| /** @private */ |
| onPinSubmit_: function() { |
| if (!this.isConfirmStep_) { |
| - if (this.isPinLongEnough_(this.pinKeyboardValue_)) { |
| - this.initialPin_ = this.pinKeyboardValue_; |
| - this.pinKeyboardValue_ = ''; |
| - this.isConfirmStep_ = true; |
| - this.onPinChange_(); |
| - this.$.pinKeyboard.focus(); |
| - } |
| + this.initialPin_ = this.pinKeyboardValue_; |
| + this.pinKeyboardValue_ = ''; |
| + this.isConfirmStep_ = true; |
| + this.onPinChange_(); |
| + this.$.pinKeyboard.focus(); |
| } else { |
| // onPinSubmit_ gets called if the user hits enter on the PIN keyboard. |
| // The PIN is not guaranteed to be valid in that case. |
| - if (!this.isPinConfirmed_()) { |
| + if (!this.canSubmit_()) { |
| this.showProblem_('configurePinMismatched', 'error'); |
| return; |
| } |