Commit 5de8f538 authored by Viktor Semeniuk's avatar Viktor Semeniuk Committed by Commit Bot

[Password Manager] Adding a "remove compromised credential" disclaimer

This change adds confirmation dialog when user clicks on remove password
button inside menu.

Bug: 1047726, 1061088
Change-Id: I0e090c47dddb896cf1a8d6e847ef11f738cfeb5e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2096685
Commit-Queue: Viktor Semeniuk <vsemeniuk@google.com>
Reviewed-by: default avatardpapad <dpapad@chromium.org>
Reviewed-by: default avatarJan Wilken Dörrie <jdoerrie@chromium.org>
Cr-Commit-Position: refs/heads/master@{#750941}
parent 5deffe0f
...@@ -21,6 +21,7 @@ js_type_check("closure_compile") { ...@@ -21,6 +21,7 @@ js_type_check("closure_compile") {
":password_edit_dialog", ":password_edit_dialog",
":password_list_item", ":password_list_item",
":password_manager_proxy", ":password_manager_proxy",
":password_remove_confirmation_dialog",
":passwords_section", ":passwords_section",
":payments_list", ":payments_list",
":payments_section", ":payments_section",
...@@ -110,6 +111,14 @@ js_library("password_check_edit_dialog") { ...@@ -110,6 +111,14 @@ js_library("password_check_edit_dialog") {
] ]
} }
js_library("password_remove_confirmation_dialog") {
deps = [
":password_manager_proxy",
"//ui/webui/resources/js:assert",
"//ui/webui/resources/js:i18n_behavior",
]
}
js_library("password_check_list_item") { js_library("password_check_list_item") {
deps = [ deps = [
":password_manager_proxy", ":password_manager_proxy",
...@@ -195,6 +204,7 @@ js_type_check("closure_compile_module") { ...@@ -195,6 +204,7 @@ js_type_check("closure_compile_module") {
":password_edit_dialog.m", ":password_edit_dialog.m",
":password_list_item.m", ":password_list_item.m",
":password_manager_proxy.m", ":password_manager_proxy.m",
":password_remove_confirmation_dialog.m",
":passwords_export_dialog.m", ":passwords_export_dialog.m",
":passwords_section.m", ":passwords_section.m",
":payments_list.m", ":payments_list.m",
...@@ -319,6 +329,17 @@ js_library("password_edit_dialog.m") { ...@@ -319,6 +329,17 @@ js_library("password_edit_dialog.m") {
extra_deps = [ ":password_edit_dialog_module" ] extra_deps = [ ":password_edit_dialog_module" ]
} }
js_library("password_remove_confirmation_dialog.m") {
sources = [ "$root_gen_dir/chrome/browser/resources/settings/autofill_page/password_remove_confirmation_dialog.m.js" ]
deps = [
":password_manager_proxy.m",
"//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
"//ui/webui/resources/js:assert.m",
"//ui/webui/resources/js:i18n_behavior.m",
]
extra_deps = [ ":password_remove_confirmation_dialog_module" ]
}
js_library("password_list_item.m") { js_library("password_list_item.m") {
sources = [ "$root_gen_dir/chrome/browser/resources/settings/autofill_page/password_list_item.m.js" ] sources = [ "$root_gen_dir/chrome/browser/resources/settings/autofill_page/password_list_item.m.js" ]
deps = [ deps = [
...@@ -437,6 +458,7 @@ group("polymer3_elements") { ...@@ -437,6 +458,7 @@ group("polymer3_elements") {
":password_check_module", ":password_check_module",
":password_edit_dialog_module", ":password_edit_dialog_module",
":password_list_item_module", ":password_list_item_module",
":password_remove_confirmation_dialog_module",
":passwords_export_dialog_module", ":passwords_export_dialog_module",
":passwords_section_module", ":passwords_section_module",
":passwords_shared_css_module", ":passwords_shared_css_module",
...@@ -553,6 +575,17 @@ polymer_modulizer("passwords_export_dialog") { ...@@ -553,6 +575,17 @@ polymer_modulizer("passwords_export_dialog") {
auto_imports = settings_auto_imports + [ "chrome/browser/resources/settings/autofill_page/password_manager_proxy.html|PasswordManagerImpl, PasswordManagerProxy" ] auto_imports = settings_auto_imports + [ "chrome/browser/resources/settings/autofill_page/password_manager_proxy.html|PasswordManagerImpl, PasswordManagerProxy" ]
} }
polymer_modulizer("password_remove_confirmation_dialog") {
js_file = "password_remove_confirmation_dialog.js"
html_file = "password_remove_confirmation_dialog.html"
html_type = "dom-module"
auto_imports = [
"chrome/browser/resources/settings/autofill_page/password_manager_proxy.html|PasswordManagerImpl,PasswordManagerProxy",
"ui/webui/resources/html/assert.html|assert",
]
namespace_rewrites = settings_namespace_rewrites
}
polymer_modulizer("passwords_section") { polymer_modulizer("passwords_section") {
js_file = "passwords_section.js" js_file = "passwords_section.js"
html_file = "passwords_section.html" html_file = "passwords_section.html"
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
<link rel="import" href="password_check_edit_dialog.html"> <link rel="import" href="password_check_edit_dialog.html">
<link rel="import" href="password_check_list_item.html"> <link rel="import" href="password_check_list_item.html">
<link rel="import" href="password_manager_proxy.html"> <link rel="import" href="password_manager_proxy.html">
<link rel="import" href="password_remove_confirmation_dialog.html">
<dom-module id="settings-password-check"> <dom-module id="settings-password-check">
<template> <template>
...@@ -141,6 +142,11 @@ ...@@ -141,6 +142,11 @@
on-close="onPasswordEditDialogClosed_" item="[[activePassword_]]"> on-close="onPasswordEditDialogClosed_" item="[[activePassword_]]">
</setiings-password-check-edit-dialog> </setiings-password-check-edit-dialog>
</template> </template>
<template is="dom-if" if="[[showPasswordRemoveDialog_]]" restamp>
<settings-password-remove-confirmation-dialog
on-close="onPasswordRemoveDialogClosed_" item="[[activePassword_]]">
</settings-password-remove-confirmation-dialog>
</template>
</template> </template>
<script src="password_check.js"></script> <script src="password_check.js"></script>
</dom-module> </dom-module>
...@@ -71,6 +71,9 @@ Polymer({ ...@@ -71,6 +71,9 @@ Polymer({
/** @private */ /** @private */
showPasswordEditDialog_: Boolean, showPasswordEditDialog_: Boolean,
/** @private */
showPasswordRemoveDialog_: Boolean,
/** /**
* The password that the user is interacting with now. * The password that the user is interacting with now.
* @private {?PasswordManagerProxy.CompromisedCredential} * @private {?PasswordManagerProxy.CompromisedCredential}
...@@ -213,8 +216,14 @@ Polymer({ ...@@ -213,8 +216,14 @@ Polymer({
/** @private */ /** @private */
onMenuRemovePasswordClick_() { onMenuRemovePasswordClick_() {
this.$.moreActionsMenu.close(); this.$.moreActionsMenu.close();
this.showPasswordRemoveDialog_ = true;
},
// TODO(crbug.com/1047726) Implement dialog. /** @private */
onPasswordRemoveDialogClosed_() {
this.showPasswordRemoveDialog_ = false;
cr.ui.focusWithoutInk(assert(this.activeDialogAnchor_));
this.activeDialogAnchor_ = null;
}, },
/** @private */ /** @private */
......
...@@ -173,6 +173,12 @@ ...@@ -173,6 +173,12 @@
*/ */
getPasswordCheckStatus() {} getPasswordCheckStatus() {}
/**
* Requests to remove |compromisedCredential| from the password store.
* @param {!PasswordManagerProxy.CompromisedCredential} compromisedCredential
*/
removeCompromisedCredential(compromisedCredential) {}
/** /**
* Add an observer to the compromised passwords change. * Add an observer to the compromised passwords change.
* @param {function(!PasswordManagerProxy.CompromisedCredentials):void} * @param {function(!PasswordManagerProxy.CompromisedCredentials):void}
...@@ -393,6 +399,11 @@ PasswordManagerProxy.PasswordCheckStatus; ...@@ -393,6 +399,11 @@ PasswordManagerProxy.PasswordCheckStatus;
}); });
} }
/** @override */
removeCompromisedCredential(compromisedCredential) {
chrome.passwordsPrivate.removeCompromisedCredential(compromisedCredential);
}
/** @override */ /** @override */
addCompromisedCredentialsListener(listener) { addCompromisedCredentialsListener(listener) {
chrome.passwordsPrivate.onCompromisedCredentialsChanged.addListener( chrome.passwordsPrivate.onCompromisedCredentialsChanged.addListener(
......
<link rel="import" href="chrome://resources/html/polymer.html">
<link rel="import" href="chrome://resources/cr_elements/cr_button/cr_button.html">
<link rel="import" href="chrome://resources/cr_elements/cr_dialog/cr_dialog.html">
<link rel="import" href="chrome://resources/html/assert.html">
<link rel="import" href="chrome://resources/html/i18n_behavior.html">
<link rel="import" href="password_manager_proxy.html">
<link rel="import" href="../i18n_setup.html">
<dom-module id="settings-password-remove-confirmation-dialog">
<template>
<cr-dialog id="dialog" close-text="$i18n{close}"
ignore-popstate ignore-enter-key>
<div slot="title">
$i18n{removeCompromisedPasswordConfirmationTitle}
</div>
<div slot="body">
<span id="description">
[[getRemovePasswordDescription_(item.formattedOrigin)]]
</span>
</div>
<div slot="button-container">
<cr-button class="cancel-button" on-click="onCancelClick_" id="cancel">
$i18n{cancel}
</cr-button>
<cr-button class="action-button" on-click="onRemoveClick_" id="remove">
$i18n{removeCompromisedPassword}
</cr-button>
</div>
</cr-dialog>
</template>
<script src="password_remove_confirmation_dialog.js"></script>
</dom-module>
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
Polymer({
is: 'settings-password-remove-confirmation-dialog',
behaviors: [I18nBehavior],
properties: {
/**
* The password that is being displayed.
* @private {?PasswordManagerProxy.CompromisedCredential}
*/
item: Object,
},
/** @private {PasswordManagerProxy} */
passwordManager_: null,
/** @override */
attached() {
// Set the manager. These can be overridden by tests.
this.passwordManager_ = PasswordManagerImpl.getInstance();
this.$.dialog.showModal();
},
/** @private */
onRemoveClick_() {
this.passwordManager_.removeCompromisedCredential(assert(this.item));
this.$.dialog.close();
},
/** @private */
onCancelClick_() {
this.$.dialog.close();
},
/**
* @return {string}
* @private
*/
getRemovePasswordDescription_() {
return this.i18n(
'removeCompromisedPasswordConfirmationDescription',
this.item.formattedOrigin);
}
});
...@@ -709,6 +709,12 @@ ...@@ -709,6 +709,12 @@
file="autofill_page/passwords_export_dialog.js" file="autofill_page/passwords_export_dialog.js"
type="chrome_html" type="chrome_html"
preprocess="true" /> preprocess="true" />
<structure name="IDR_SETTINGS_PASSWORD_REMOVE_CONFIRMATION_DIALOG_HTML"
file="autofill_page/password_remove_confirmation_dialog.html"
type="chrome_html" />
<structure name="IDR_SETTINGS_PASSWORD_REMOVE_CONFIRMATION_DIALOG_JS"
file="autofill_page/password_remove_confirmation_dialog.js"
type="chrome_html" />
<structure name="IDR_SETTINGS_PAYMENTS_SECTION_HTML" <structure name="IDR_SETTINGS_PAYMENTS_SECTION_HTML"
file="autofill_page/payments_section.html" file="autofill_page/payments_section.html"
type="chrome_html" /> type="chrome_html" />
......
...@@ -114,6 +114,10 @@ ...@@ -114,6 +114,10 @@
file="${root_gen_dir}/chrome/browser/resources/settings/autofill_page/password_manager_proxy.m.js" file="${root_gen_dir}/chrome/browser/resources/settings/autofill_page/password_manager_proxy.m.js"
use_base_dir="false" use_base_dir="false"
type="BINDATA" /> type="BINDATA" />
<include name="IDR_SETTINGS_AUTOFILL_PAGE_PASSWORD_REMOVE_CONFIRMATION_DIALOG_M_JS"
file="${root_gen_dir}/chrome/browser/resources/settings/autofill_page/password_remove_confirmation_dialog.m.js"
use_base_dir="false"
type="BINDATA" />
<include name="IDR_SETTINGS_AUTOFILL_PAGE_PASSWORDS_SECTION_M_JS" <include name="IDR_SETTINGS_AUTOFILL_PAGE_PASSWORDS_SECTION_M_JS"
file="${root_gen_dir}/chrome/browser/resources/settings/autofill_page/passwords_section.m.js" file="${root_gen_dir}/chrome/browser/resources/settings/autofill_page/passwords_section.m.js"
use_base_dir="false" use_base_dir="false"
......
...@@ -53,6 +53,20 @@ cr.define('settings_passwords_check', function() { ...@@ -53,6 +53,20 @@ cr.define('settings_passwords_check', function() {
element.offsetParent !== null; // Considers parents hiding |element|. element.offsetParent !== null; // Considers parents hiding |element|.
} }
/**
* Helper method used to create a remove password confirmation dialog.
* @param {!chrome.passwordsPrivate.CompromisedCredential} entry
*/
function createRemovePasswordDialog(entry) {
const element =
document.createElement('settings-password-remove-confirmation-dialog');
element.item = entry;
document.body.appendChild(element);
Polymer.dom.flush();
return element;
}
/** /**
* Helper method used to randomize array. * Helper method used to randomize array.
* @param {!Array<!chrome.passwordsPrivate.CompromisedCredential>} array * @param {!Array<!chrome.passwordsPrivate.CompromisedCredential>} array
...@@ -415,6 +429,21 @@ cr.define('settings_passwords_check', function() { ...@@ -415,6 +429,21 @@ cr.define('settings_passwords_check', function() {
}); });
}); });
// Test verifies that clicking remove button is calling proper
// proxy function.
test('testRemovePasswordConfirmationDialog', function() {
const entry = autofill_test_util.makeCompromisedCredential(
'one.com', 'test4', 'LEAKED', 0);
const removeDialog = createRemovePasswordDialog(entry);
removeDialog.$.remove.click();
return passwordManager.whenCalled('removeCompromisedCredential')
.then(({id, username, formattedOrigin}) => {
assertEquals(0 , id);
assertEquals('test4', username);
assertEquals('one.com', formattedOrigin);
});
});
// A changing status is immediately reflected in title, icon and banner. // A changing status is immediately reflected in title, icon and banner.
test('testUpdatesNumberOfCheckedPasswordsWhileRunning', function() { test('testUpdatesNumberOfCheckedPasswordsWhileRunning', function() {
passwordManager.data.checkStatus = passwordManager.data.checkStatus =
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
'getPasswordCheckStatus', 'getPasswordCheckStatus',
'getPlainttextCompromisedPassword', 'getPlainttextCompromisedPassword',
'changeCompromisedCredential', 'changeCompromisedCredential',
'removeCompromisedCredential',
]); ]);
this.actual_ = new autofill_test_util.PasswordManagerExpectations(); this.actual_ = new autofill_test_util.PasswordManagerExpectations();
...@@ -207,4 +208,9 @@ ...@@ -207,4 +208,9 @@
this.methodCalled('changeCompromisedCredential', {credential, newPassword}); this.methodCalled('changeCompromisedCredential', {credential, newPassword});
return Promise.resolve(); return Promise.resolve();
} }
/** @override */
removeCompromisedCredential(compromisedCredential) {
this.methodCalled('removeCompromisedCredential', compromisedCredential);
}
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment