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 /** |
| 219 * @type {PasswordManager} |
| 220 * @private |
| 221 */ |
| 222 passwordManager_: null, |
| 223 |
| 224 /** |
| 225 * @type {?function(!Array<PasswordManager.PasswordUiEntry>):void} |
| 226 * @private |
| 227 */ |
| 228 setSavedPasswordsListener_: null, |
| 229 |
| 230 /** |
| 231 * @type {?function(!Array<PasswordManager.ExceptionPair>):void} |
| 232 * @private |
| 233 */ |
| 234 setPasswordExceptionsListener_: null, |
| 235 |
| 236 /** @override */ |
| 237 ready: function() { |
| 238 // Create listener functions. |
| 239 var setSavedPasswordsListener = function(list) { |
| 240 this.savedPasswords = list; |
| 241 }.bind(this); |
| 242 |
| 243 var setPasswordExceptionsListener = function(list) { |
| 244 this.passwordExceptions = list; |
| 245 }.bind(this); |
| 246 |
| 247 this.setSavedPasswordsListener_ = setSavedPasswordsListener; |
| 248 this.setPasswordExceptionsListener_ = setPasswordExceptionsListener; |
| 249 |
| 250 // Set the manager. These can be overridden by tests. |
| 251 this.passwordManager_ = PasswordManagerImpl.getInstance(); |
| 252 |
| 253 // Request initial data. |
| 254 this.passwordManager_.getSavedPasswordList(setSavedPasswordsListener); |
| 255 this.passwordManager_.getExceptionList(setPasswordExceptionsListener); |
| 256 |
| 257 // Listen for changes. |
| 258 this.passwordManager_.addSavedPasswordListChangedListener( |
| 259 setSavedPasswordsListener); |
| 260 this.passwordManager_.addExceptionListChangedListener( |
| 261 setPasswordExceptionsListener); |
| 262 }, |
| 263 |
| 264 /** @override */ |
| 265 detached: function() { |
| 266 this.passwordManager_.removeSavedPasswordListChangedListener( |
| 267 /** @type {function(!Array<PasswordManager.PasswordUiEntry>):void} */( |
| 268 this.setSavedPasswordsListener_)); |
| 269 this.passwordManager_.removeExceptionListChangedListener( |
| 270 /** @type {function(!Array<PasswordManager.ExceptionPair>):void} */( |
| 271 this.setPasswordExceptionsListener_)); |
| 272 }, |
| 273 |
72 /** | 274 /** |
73 * Sets the password in the current password dialog if the loginPair matches. | 275 * Sets the password in the current password dialog if the loginPair matches. |
74 * @param {!chrome.passwordsPrivate.LoginPair} loginPair | 276 * @param {!chrome.passwordsPrivate.LoginPair} loginPair |
75 * @param {string} password | 277 * @param {string} password |
76 */ | 278 */ |
77 setPassword: function(loginPair, password) { | 279 setPassword: function(loginPair, password) { |
78 if (this.activePassword && | 280 if (this.activePassword && |
79 this.activePassword.loginPair.originUrl == loginPair.originUrl && | 281 this.activePassword.loginPair.originUrl == loginPair.originUrl && |
80 this.activePassword.loginPair.username == loginPair.username) { | 282 this.activePassword.loginPair.username == loginPair.username) { |
81 this.$$('password-edit-dialog').password = password; | 283 this.$$('password-edit-dialog').password = password; |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
123 return function(exception) { | 325 return function(exception) { |
124 return exception.exceptionUrl.includes(filter); | 326 return exception.exceptionUrl.includes(filter); |
125 }; | 327 }; |
126 }, | 328 }, |
127 | 329 |
128 /** | 330 /** |
129 * Fires an event that should delete the saved password. | 331 * Fires an event that should delete the saved password. |
130 * @private | 332 * @private |
131 */ | 333 */ |
132 onMenuRemovePasswordTap_: function() { | 334 onMenuRemovePasswordTap_: function() { |
133 this.fire('remove-saved-password', this.activePassword.loginPair); | 335 this.passwordManager_.removeSavedPassword(this.activePassword.loginPair); |
134 /** @type {CrActionMenuElement} */(this.$.menu).close(); | 336 /** @type {CrActionMenuElement} */(this.$.menu).close(); |
135 }, | 337 }, |
136 | 338 |
137 /** | 339 /** |
138 * Fires an event that should delete the password exception. | 340 * Fires an event that should delete the password exception. |
139 * @param {!ExceptionPairEntryEvent} e The polymer event. | 341 * @param {!ExceptionPairEntryEvent} e The polymer event. |
140 * @private | 342 * @private |
141 */ | 343 */ |
142 onRemoveExceptionButtonTap_: function(e) { | 344 onRemoveExceptionButtonTap_: function(e) { |
143 this.fire('remove-password-exception', e.model.item.exceptionUrl); | 345 this.passwordManager_.removeException(e.model.item.exceptionUrl); |
144 }, | 346 }, |
145 | 347 |
146 /** | 348 /** |
147 * Creates an empty password of specified length. | 349 * Creates an empty password of specified length. |
148 * @param {number} length | 350 * @param {number} length |
149 * @return {string} password | 351 * @return {string} password |
150 * @private | 352 * @private |
151 */ | 353 */ |
152 getEmptyPassword_: function(length) { return ' '.repeat(length); }, | 354 getEmptyPassword_: function(length) { return ' '.repeat(length); }, |
153 | 355 |
(...skipping 14 matching lines...) Expand all Loading... |
168 | 370 |
169 /** | 371 /** |
170 * Returns true if the list exists and has items. | 372 * Returns true if the list exists and has items. |
171 * @param {Array<Object>} list | 373 * @param {Array<Object>} list |
172 * @return {boolean} | 374 * @return {boolean} |
173 * @private | 375 * @private |
174 */ | 376 */ |
175 hasSome_: function(list) { | 377 hasSome_: function(list) { |
176 return !!(list && list.length); | 378 return !!(list && list.length); |
177 }, | 379 }, |
| 380 |
| 381 /** |
| 382 * Listens for the show-password event, and calls the private API. |
| 383 * @param {!Event} event |
| 384 * @private |
| 385 */ |
| 386 showPassword_: function(event) { |
| 387 this.passwordManager_.getPlaintextPassword( |
| 388 /** @type {!PasswordManager.LoginPair} */(event.detail), |
| 389 function(item) { |
| 390 this.setPassword(item.loginPair, item.plaintextPassword); |
| 391 }.bind(this)); |
| 392 }, |
178 }); | 393 }); |
179 })(); | 394 })(); |
OLD | NEW |