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) { | |
| 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 /** @override */ | |
| 222 ready: function() { | |
| 223 // Set the manager. These can be overridden by tests. | |
| 224 this.passwordManager_ = PasswordManagerImpl.getInstance(); | |
| 225 | |
| 226 // Request initial data. | |
| 227 this.passwordManager_.getSavedPasswordList( | |
| 228 this.setSavedPasswordsListener_.bind(this)); | |
| 229 this.passwordManager_.getExceptionList( | |
| 230 this.setPasswordExceptionsListener_.bind(this)); | |
| 231 | |
| 232 // Listen for changes. | |
| 233 this.passwordManager_.addSavedPasswordListChangedListener( | |
| 234 this.setSavedPasswordsListener_.bind(this)); | |
| 235 this.passwordManager_.addExceptionListChangedListener( | |
| 236 this.setPasswordExceptionsListener_.bind(this)); | |
| 237 }, | |
| 238 | |
| 239 /** @override */ | |
| 240 detached: function() { | |
| 241 this.passwordManager_.removeSavedPasswordListChangedListener( | |
| 242 this.setSavedPasswordsListener_); | |
|
dpapad
2017/02/14 20:43:18
This is now a different reference than the one pas
hcarmona
2017/02/15 00:13:34
Arg. Yes. Fixed. PTAL
| |
| 243 this.passwordManager_.removeExceptionListChangedListener( | |
| 244 this.setPasswordExceptionsListener_); | |
|
dpapad
2017/02/14 20:43:18
Same here.
hcarmona
2017/02/15 00:13:34
Acknowledged.
| |
| 245 }, | |
| 246 | |
| 72 /** | 247 /** |
| 73 * Sets the password in the current password dialog if the loginPair matches. | 248 * Sets the password in the current password dialog if the loginPair matches. |
| 74 * @param {!chrome.passwordsPrivate.LoginPair} loginPair | 249 * @param {!chrome.passwordsPrivate.LoginPair} loginPair |
| 75 * @param {string} password | 250 * @param {string} password |
| 76 */ | 251 */ |
| 77 setPassword: function(loginPair, password) { | 252 setPassword: function(loginPair, password) { |
| 78 if (this.activePassword && | 253 if (this.activePassword && |
| 79 this.activePassword.loginPair.originUrl == loginPair.originUrl && | 254 this.activePassword.loginPair.originUrl == loginPair.originUrl && |
| 80 this.activePassword.loginPair.username == loginPair.username) { | 255 this.activePassword.loginPair.username == loginPair.username) { |
| 81 this.$$('password-edit-dialog').password = password; | 256 this.$$('password-edit-dialog').password = password; |
| 82 } | 257 } |
| 83 }, | 258 }, |
| 84 | 259 |
| 260 /** @type {function(!Array<!PasswordManager.PasswordUiEntry>):void} */ | |
|
dpapad
2017/02/14 20:43:18
Why can't this be annotated like a normal member m
hcarmona
2017/02/15 00:13:35
Yes, that would have worked here, but had to go ba
| |
| 261 setSavedPasswordsListener_: function(list) { | |
| 262 this.savedPasswords = list; | |
| 263 }, | |
| 264 | |
| 265 /** @type {function(!Array<!PasswordManager.ExceptionPair>):void} */ | |
|
dpapad
2017/02/14 20:43:18
Same question here.
hcarmona
2017/02/15 00:13:35
Acknowledged.
| |
| 266 setPasswordExceptionsListener_: function(list) { | |
| 267 this.passwordExceptions = list; | |
| 268 }, | |
| 269 | |
| 85 /** | 270 /** |
| 86 * Shows the edit password dialog. | 271 * Shows the edit password dialog. |
| 87 * @param {!Event} e | 272 * @param {!Event} e |
| 88 * @private | 273 * @private |
| 89 */ | 274 */ |
| 90 onMenuEditPasswordTap_: function(e) { | 275 onMenuEditPasswordTap_: function(e) { |
| 91 e.preventDefault(); | 276 e.preventDefault(); |
| 92 /** @type {CrActionMenuElement} */(this.$.menu).close(); | 277 /** @type {CrActionMenuElement} */(this.$.menu).close(); |
| 93 this.showPasswordEditDialog_ = true; | 278 this.showPasswordEditDialog_ = true; |
| 94 }, | 279 }, |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 123 return function(exception) { | 308 return function(exception) { |
| 124 return exception.exceptionUrl.includes(filter); | 309 return exception.exceptionUrl.includes(filter); |
| 125 }; | 310 }; |
| 126 }, | 311 }, |
| 127 | 312 |
| 128 /** | 313 /** |
| 129 * Fires an event that should delete the saved password. | 314 * Fires an event that should delete the saved password. |
| 130 * @private | 315 * @private |
| 131 */ | 316 */ |
| 132 onMenuRemovePasswordTap_: function() { | 317 onMenuRemovePasswordTap_: function() { |
| 133 this.fire('remove-saved-password', this.activePassword.loginPair); | 318 this.passwordManager_.removeSavedPassword(this.activePassword.loginPair); |
| 134 /** @type {CrActionMenuElement} */(this.$.menu).close(); | 319 /** @type {CrActionMenuElement} */(this.$.menu).close(); |
| 135 }, | 320 }, |
| 136 | 321 |
| 137 /** | 322 /** |
| 138 * Fires an event that should delete the password exception. | 323 * Fires an event that should delete the password exception. |
| 139 * @param {!ExceptionPairEntryEvent} e The polymer event. | 324 * @param {!ExceptionPairEntryEvent} e The polymer event. |
| 140 * @private | 325 * @private |
| 141 */ | 326 */ |
| 142 onRemoveExceptionButtonTap_: function(e) { | 327 onRemoveExceptionButtonTap_: function(e) { |
| 143 this.fire('remove-password-exception', e.model.item.exceptionUrl); | 328 this.passwordManager_.removeException(e.model.item.exceptionUrl); |
| 144 }, | 329 }, |
| 145 | 330 |
| 146 /** | 331 /** |
| 147 * Creates an empty password of specified length. | 332 * Creates an empty password of specified length. |
| 148 * @param {number} length | 333 * @param {number} length |
| 149 * @return {string} password | 334 * @return {string} password |
| 150 * @private | 335 * @private |
| 151 */ | 336 */ |
| 152 getEmptyPassword_: function(length) { return ' '.repeat(length); }, | 337 getEmptyPassword_: function(length) { return ' '.repeat(length); }, |
| 153 | 338 |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 168 | 353 |
| 169 /** | 354 /** |
| 170 * Returns true if the list exists and has items. | 355 * Returns true if the list exists and has items. |
| 171 * @param {Array<Object>} list | 356 * @param {Array<Object>} list |
| 172 * @return {boolean} | 357 * @return {boolean} |
| 173 * @private | 358 * @private |
| 174 */ | 359 */ |
| 175 hasSome_: function(list) { | 360 hasSome_: function(list) { |
| 176 return !!(list && list.length); | 361 return !!(list && list.length); |
| 177 }, | 362 }, |
| 363 | |
| 364 /** | |
| 365 * Listens for the show-password event, and calls the private API. | |
| 366 * @param {!Event} event | |
| 367 * @private | |
| 368 */ | |
| 369 showPassword_: function(event) { | |
| 370 this.passwordManager_.getPlaintextPassword( | |
| 371 /** @type {!PasswordManager.LoginPair} */(event.detail), | |
| 372 function(item) { | |
| 373 this.setPassword(item.loginPair, item.plaintextPassword); | |
|
dpapad
2017/02/14 20:43:18
Nit: Lines 373-374 should have +4 spaces of indent
hcarmona
2017/02/15 00:13:34
Done.
| |
| 374 }.bind(this)); | |
| 375 }, | |
| 178 }); | 376 }); |
| 179 })(); | 377 })(); |
| OLD | NEW |