Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 /** | 5 /** |
| 6 * @fileoverview 'passwords-section' is the collapsible section containing | 6 * @fileoverview 'passwords-section' is the collapsible section containing |
| 7 * the list of saved passwords as well as the list of sites that will never | 7 * the list of saved passwords as well as the list of sites that will never |
| 8 * save any passwords. | 8 * save any passwords. |
| 9 */ | 9 */ |
| 10 | 10 |
| 11 /** | |
| 12 * Interface for all callbacks to the password API. | |
| 13 * @interface | |
| 14 */ | |
| 15 function PasswordManager() {} | |
| 16 | |
| 17 /** @typedef {chrome.passwordsPrivate.PasswordUiEntry} */ | |
| 18 PasswordManager.PasswordUiEntry; | |
| 19 | |
| 20 /** @typedef {chrome.passwordsPrivate.LoginPair} */ | |
| 21 PasswordManager.LoginPair; | |
| 22 | |
| 23 /** @typedef {chrome.passwordsPrivate.ExceptionPair} */ | |
| 24 PasswordManager.ExceptionPair; | |
| 25 | |
| 26 /** @typedef {chrome.passwordsPrivate.PlaintextPasswordEventParameters} */ | |
| 27 PasswordManager.PlaintextPasswordEvent; | |
| 28 | |
| 29 PasswordManager.prototype = { | |
| 30 /** | |
| 31 * Add an observer to the list of saved passwords. | |
| 32 * @param {function(!Array<!PasswordManager.PasswordUiEntry>):void} listener | |
| 33 */ | |
| 34 addSavedPasswordListChangedListener: assertNotReached, | |
| 35 | |
| 36 /** | |
| 37 * Remove an observer from the list of saved passwords. | |
| 38 * @param {function(!Array<!PasswordManager.PasswordUiEntry>):void} listener | |
| 39 */ | |
| 40 removeSavedPasswordListChangedListener: assertNotReached, | |
| 41 | |
| 42 /** | |
| 43 * Request the list of saved passwords. | |
| 44 * @param {function(!Array<!PasswordManager.PasswordUiEntry>):void} callback | |
| 45 */ | |
| 46 getSavedPasswordList: assertNotReached, | |
| 47 | |
| 48 /** | |
| 49 * Should remove the saved password and notify that the list has changed. | |
| 50 * @param {!PasswordManager.LoginPair} loginPair The saved password that | |
| 51 * should be removed from the list. No-op if |loginPair| is not found. | |
| 52 */ | |
| 53 removeSavedPassword: assertNotReached, | |
| 54 | |
| 55 /** | |
| 56 * Add an observer to the list of password exceptions. | |
| 57 * @param {function(!Array<!PasswordManager.ExceptionPair>):void} listener | |
| 58 */ | |
| 59 addExceptionListChangedListener: assertNotReached, | |
| 60 | |
| 61 /** | |
| 62 * Remove an observer from the list of password exceptions. | |
| 63 * @param {function(!Array<!PasswordManager.ExceptionPair>):void} listener | |
| 64 */ | |
| 65 removeExceptionListChangedListener: assertNotReached, | |
| 66 | |
| 67 /** | |
| 68 * Request the list of password exceptions. | |
| 69 * @param {function(!Array<!PasswordManager.ExceptionPair>):void} callback | |
| 70 */ | |
| 71 getExceptionList: assertNotReached, | |
| 72 | |
| 73 /** | |
| 74 * Should remove the password exception and notify that the list has changed. | |
| 75 * @param {string} exception The exception that should be removed from the | |
| 76 * list. No-op if |exception| is not in the list. | |
| 77 */ | |
| 78 removeException: assertNotReached, | |
| 79 | |
| 80 /** | |
| 81 * Gets the saved password for a given login pair. | |
| 82 * @param {!PasswordManager.LoginPair} loginPair The saved password that | |
| 83 * should be retrieved. | |
| 84 * @param {function(!PasswordManager.PlaintextPasswordEvent):void} callback | |
| 85 */ | |
| 86 getPlaintextPassword: assertNotReached, | |
| 87 }; | |
| 88 | |
| 89 /** | |
| 90 * Implementation that accesses the private API. | |
| 91 * @implements {PasswordManager} | |
| 92 * @constructor | |
| 93 */ | |
| 94 function PasswordManagerImpl() {} | |
| 95 cr.addSingletonGetter(PasswordManagerImpl); | |
| 96 | |
| 97 PasswordManagerImpl.prototype = { | |
| 98 __proto__: PasswordManager, | |
| 99 | |
| 100 /** @override */ | |
| 101 addSavedPasswordListChangedListener: function(listener) { | |
| 102 chrome.passwordsPrivate.onSavedPasswordsListChanged.addListener(listener); | |
| 103 }, | |
| 104 | |
| 105 /** @override */ | |
| 106 removeSavedPasswordListChangedListener: function(listener) { | |
| 107 chrome.passwordsPrivate.onSavedPasswordsListChanged.removeListener( | |
| 108 listener); | |
| 109 }, | |
| 110 | |
| 111 /** @override */ | |
| 112 getSavedPasswordList: function(callback) { | |
|
dpapad
2017/02/15 02:01:38
Nit (for a potential future CL cleanup): Since we
hcarmona
2017/02/15 18:18:24
This wasn't done because the callback can occur as
dpapad
2017/02/15 18:32:21
A single call to getSavedPasswordList() can invoke
| |
| 113 chrome.passwordsPrivate.getSavedPasswordList(callback); | |
| 114 }, | |
| 115 | |
| 116 /** @override */ | |
| 117 removeSavedPassword: function(loginPair) { | |
| 118 chrome.passwordsPrivate.removeSavedPassword(loginPair); | |
| 119 }, | |
| 120 | |
| 121 /** @override */ | |
| 122 addExceptionListChangedListener: function(listener) { | |
| 123 chrome.passwordsPrivate.onPasswordExceptionsListChanged.addListener( | |
| 124 listener); | |
| 125 }, | |
| 126 | |
| 127 /** @override */ | |
| 128 removeExceptionListChangedListener: function(listener) { | |
| 129 chrome.passwordsPrivate.onPasswordExceptionsListChanged.removeListener( | |
| 130 listener); | |
| 131 }, | |
| 132 | |
| 133 /** @override */ | |
| 134 getExceptionList: function(callback) { | |
| 135 chrome.passwordsPrivate.getPasswordExceptionList(callback); | |
| 136 }, | |
| 137 | |
| 138 /** @override */ | |
| 139 removeException: function(exception) { | |
| 140 chrome.passwordsPrivate.removePasswordException(exception); | |
| 141 }, | |
| 142 | |
| 143 /** @override */ | |
| 144 getPlaintextPassword: function(loginPair, callback) { | |
| 145 var listener = function(reply) { | |
| 146 // Only handle the reply for our loginPair request. | |
| 147 if (reply.loginPair.originUrl == loginPair.originUrl && | |
| 148 reply.loginPair.username == loginPair.username) { | |
| 149 chrome.passwordsPrivate.onPlaintextPasswordRetrieved.removeListener( | |
| 150 listener); | |
| 151 callback(reply); | |
| 152 } | |
| 153 }; | |
| 154 chrome.passwordsPrivate.onPlaintextPasswordRetrieved.addListener(listener); | |
| 155 chrome.passwordsPrivate.requestPlaintextPassword(loginPair); | |
| 156 }, | |
| 157 }; | |
| 158 | |
| 11 /** @typedef {!{model: !{item: !chrome.passwordsPrivate.PasswordUiEntry}}} */ | 159 /** @typedef {!{model: !{item: !chrome.passwordsPrivate.PasswordUiEntry}}} */ |
| 12 var PasswordUiEntryEvent; | 160 var PasswordUiEntryEvent; |
| 13 | 161 |
| 14 /** @typedef {!{model: !{item: !chrome.passwordsPrivate.ExceptionPair}}} */ | 162 /** @typedef {!{model: !{item: !chrome.passwordsPrivate.ExceptionPair}}} */ |
| 15 var ExceptionPairEntryEvent; | 163 var ExceptionPairEntryEvent; |
| 16 | 164 |
| 17 (function() { | 165 (function() { |
| 18 'use strict'; | 166 'use strict'; |
| 19 | 167 |
| 20 Polymer({ | 168 Polymer({ |
| 21 is: 'passwords-section', | 169 is: 'passwords-section', |
| 22 | 170 |
| 23 behaviors: [settings.GlobalScrollTargetBehavior], | 171 behaviors: [settings.GlobalScrollTargetBehavior], |
| 24 | 172 |
| 25 properties: { | 173 properties: { |
| 26 /** Preferences state. */ | 174 /** Preferences state. */ |
| 27 prefs: { | 175 prefs: { |
| 28 type: Object, | 176 type: Object, |
| 29 notify: true, | 177 notify: true, |
| 30 }, | 178 }, |
| 31 | 179 |
| 32 /** | 180 /** |
| 33 * An array of passwords to display. | 181 * An array of passwords to display. |
| 34 * @type {!Array<!chrome.passwordsPrivate.PasswordUiEntry>} | 182 * @type {!Array<!PasswordManager.PasswordUiEntry>} |
| 35 */ | 183 */ |
| 36 savedPasswords: { | 184 savedPasswords: Array, |
| 37 type: Array, | |
| 38 value: function() { return []; }, | |
| 39 }, | |
| 40 | 185 |
| 41 /** | 186 /** |
| 42 * An array of sites to display. | 187 * An array of sites to display. |
| 43 * @type {!Array<!chrome.passwordsPrivate.ExceptionPair>} | 188 * @type {!Array<!PasswordManager.ExceptionPair>} |
| 44 */ | 189 */ |
| 45 passwordExceptions: { | 190 passwordExceptions: Array, |
| 46 type: Array, | |
| 47 value: function() { return []; }, | |
| 48 }, | |
| 49 | 191 |
| 50 /** @override */ | 192 /** @override */ |
| 51 subpageRoute: { | 193 subpageRoute: { |
| 52 type: Object, | 194 type: Object, |
| 53 value: settings.Route.MANAGE_PASSWORDS, | 195 value: settings.Route.MANAGE_PASSWORDS, |
| 54 }, | 196 }, |
| 55 | 197 |
| 56 /** | 198 /** |
| 57 * The model for any password related action menus or dialogs. | 199 * The model for any password related action menus or dialogs. |
| 58 * @private {?chrome.passwordsPrivate.PasswordUiEntry} | 200 * @private {?chrome.passwordsPrivate.PasswordUiEntry} |
| 59 */ | 201 */ |
| 60 activePassword: Object, | 202 activePassword: Object, |
| 61 | 203 |
| 62 /** @private */ | 204 /** @private */ |
| 63 showPasswordEditDialog_: Boolean, | 205 showPasswordEditDialog_: Boolean, |
| 64 | 206 |
| 65 /** Filter on the saved passwords and exceptions. */ | 207 /** Filter on the saved passwords and exceptions. */ |
| 66 filter: { | 208 filter: { |
| 67 type: String, | 209 type: String, |
| 68 value: '', | 210 value: '', |
| 69 }, | 211 }, |
| 70 }, | 212 }, |
| 71 | 213 |
| 214 listeners: { | |
| 215 'show-password': 'showPassword_', | |
| 216 }, | |
| 217 | |
| 218 /** @type {PasswordManager} */ | |
| 219 passwordManager_: null, | |
| 220 | |
| 221 /** @type {?function(!Array<PasswordManager.PasswordUiEntry>):void} */ | |
| 222 setSavedPasswordsListener_: null, | |
| 223 | |
| 224 /** @type {?function(!Array<PasswordManager.ExceptionPair>):void} */ | |
| 225 setPasswordExceptionsListener_: null, | |
| 226 | |
| 227 /** @override */ | |
| 228 ready: function() { | |
| 229 // Create listener functions. | |
| 230 var setSavedPasswordsListener = function(list) { | |
| 231 this.savedPasswords = list; | |
| 232 }.bind(this); | |
| 233 | |
| 234 var setPasswordExceptionsListener = function(list) { | |
| 235 this.passwordExceptions = list; | |
| 236 }.bind(this); | |
| 237 | |
| 238 this.setSavedPasswordsListener_ = setSavedPasswordsListener; | |
|
dpapad
2017/02/15 02:01:38
Nit: Same question here as in autofill. Do we need
hcarmona
2017/02/15 18:18:23
Avoids type casting.
| |
| 239 this.setPasswordExceptionsListener_ = setPasswordExceptionsListener; | |
| 240 | |
| 241 // Set the manager. These can be overridden by tests. | |
| 242 this.passwordManager_ = PasswordManagerImpl.getInstance(); | |
| 243 | |
| 244 // Request initial data. | |
| 245 this.passwordManager_.getSavedPasswordList(setSavedPasswordsListener); | |
| 246 this.passwordManager_.getExceptionList(setPasswordExceptionsListener); | |
| 247 | |
| 248 // Listen for changes. | |
| 249 this.passwordManager_.addSavedPasswordListChangedListener( | |
| 250 setSavedPasswordsListener); | |
| 251 this.passwordManager_.addExceptionListChangedListener( | |
| 252 setPasswordExceptionsListener); | |
| 253 }, | |
| 254 | |
| 255 /** @override */ | |
| 256 detached: function() { | |
| 257 this.passwordManager_.removeSavedPasswordListChangedListener( | |
| 258 /** @type {function(!Array<PasswordManager.PasswordUiEntry>):void} */( | |
| 259 this.setSavedPasswordsListener_)); | |
| 260 this.passwordManager_.removeExceptionListChangedListener( | |
| 261 /** @type {function(!Array<PasswordManager.ExceptionPair>):void} */( | |
| 262 this.setPasswordExceptionsListener_)); | |
| 263 }, | |
| 264 | |
| 72 /** | 265 /** |
| 73 * Sets the password in the current password dialog if the loginPair matches. | 266 * Sets the password in the current password dialog if the loginPair matches. |
| 74 * @param {!chrome.passwordsPrivate.LoginPair} loginPair | 267 * @param {!chrome.passwordsPrivate.LoginPair} loginPair |
| 75 * @param {string} password | 268 * @param {string} password |
| 76 */ | 269 */ |
| 77 setPassword: function(loginPair, password) { | 270 setPassword: function(loginPair, password) { |
| 78 if (this.activePassword && | 271 if (this.activePassword && |
| 79 this.activePassword.loginPair.originUrl == loginPair.originUrl && | 272 this.activePassword.loginPair.originUrl == loginPair.originUrl && |
| 80 this.activePassword.loginPair.username == loginPair.username) { | 273 this.activePassword.loginPair.username == loginPair.username) { |
| 81 this.$$('password-edit-dialog').password = password; | 274 this.$$('password-edit-dialog').password = password; |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 123 return function(exception) { | 316 return function(exception) { |
| 124 return exception.exceptionUrl.includes(filter); | 317 return exception.exceptionUrl.includes(filter); |
| 125 }; | 318 }; |
| 126 }, | 319 }, |
| 127 | 320 |
| 128 /** | 321 /** |
| 129 * Fires an event that should delete the saved password. | 322 * Fires an event that should delete the saved password. |
| 130 * @private | 323 * @private |
| 131 */ | 324 */ |
| 132 onMenuRemovePasswordTap_: function() { | 325 onMenuRemovePasswordTap_: function() { |
| 133 this.fire('remove-saved-password', this.activePassword.loginPair); | 326 this.passwordManager_.removeSavedPassword(this.activePassword.loginPair); |
| 134 /** @type {CrActionMenuElement} */(this.$.menu).close(); | 327 /** @type {CrActionMenuElement} */(this.$.menu).close(); |
| 135 }, | 328 }, |
| 136 | 329 |
| 137 /** | 330 /** |
| 138 * Fires an event that should delete the password exception. | 331 * Fires an event that should delete the password exception. |
| 139 * @param {!ExceptionPairEntryEvent} e The polymer event. | 332 * @param {!ExceptionPairEntryEvent} e The polymer event. |
| 140 * @private | 333 * @private |
| 141 */ | 334 */ |
| 142 onRemoveExceptionButtonTap_: function(e) { | 335 onRemoveExceptionButtonTap_: function(e) { |
| 143 this.fire('remove-password-exception', e.model.item.exceptionUrl); | 336 this.passwordManager_.removeException(e.model.item.exceptionUrl); |
| 144 }, | 337 }, |
| 145 | 338 |
| 146 /** | 339 /** |
| 147 * Creates an empty password of specified length. | 340 * Creates an empty password of specified length. |
| 148 * @param {number} length | 341 * @param {number} length |
| 149 * @return {string} password | 342 * @return {string} password |
| 150 * @private | 343 * @private |
| 151 */ | 344 */ |
| 152 getEmptyPassword_: function(length) { return ' '.repeat(length); }, | 345 getEmptyPassword_: function(length) { return ' '.repeat(length); }, |
| 153 | 346 |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 168 | 361 |
| 169 /** | 362 /** |
| 170 * Returns true if the list exists and has items. | 363 * Returns true if the list exists and has items. |
| 171 * @param {Array<Object>} list | 364 * @param {Array<Object>} list |
| 172 * @return {boolean} | 365 * @return {boolean} |
| 173 * @private | 366 * @private |
| 174 */ | 367 */ |
| 175 hasSome_: function(list) { | 368 hasSome_: function(list) { |
| 176 return !!(list && list.length); | 369 return !!(list && list.length); |
| 177 }, | 370 }, |
| 371 | |
| 372 /** | |
| 373 * Listens for the show-password event, and calls the private API. | |
| 374 * @param {!Event} event | |
| 375 * @private | |
| 376 */ | |
| 377 showPassword_: function(event) { | |
| 378 this.passwordManager_.getPlaintextPassword( | |
| 379 /** @type {!PasswordManager.LoginPair} */(event.detail), | |
| 380 function(item) { | |
| 381 this.setPassword(item.loginPair, item.plaintextPassword); | |
| 382 }.bind(this)); | |
| 383 }, | |
| 178 }); | 384 }); |
| 179 })(); | 385 })(); |
| OLD | NEW |