Commit 4e93b4cd authored by Jan Wilken Dörrie's avatar Jan Wilken Dörrie Committed by Commit Bot

[Passwords] Include Link in Password Check Removal Confirmation

This change adds a link to the origin to the dialog shown when removing
a compromised credential. Since injecting links to insecure domains is
not allowed due to the risk of XSS, this is limited to HTTPS origins.

Fixed: 1066790
Change-Id: I297c3e49b4388bed5c229959345741565b1d2092
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2133966Reviewed-by: default avatardpapad <dpapad@chromium.org>
Commit-Queue: Jan Wilken Dörrie <jdoerrie@chromium.org>
Cr-Commit-Position: refs/heads/master@{#817525}
parent 678eb60a
<!-- We have to include the shared settings style in order to properly -->
<!-- style the contained link in the dialog. -->
<style include="settings-shared"></style>
<cr-dialog id="dialog" close-text="$i18n{close}" <cr-dialog id="dialog" close-text="$i18n{close}"
ignore-popstate ignore-enter-key> ignore-popstate ignore-enter-key>
<div slot="title"> <div slot="title">
$i18n{removeCompromisedPasswordConfirmationTitle} $i18n{removeCompromisedPasswordConfirmationTitle}
</div> </div>
<div slot="body"> <div slot="body">
<span id="description"> <span id="link" hidden="[[!hasSecureChangePasswordUrl_(item)]]"
[[getRemovePasswordDescription_(item.formattedOrigin)]] inner-h-t-m-l="[[getRemovePasswordDescriptionHtml_(item)]]">
</span>
<span id="text" hidden="[[hasSecureChangePasswordUrl_(item)]]">
[[getRemovePasswordDescriptionText_(item)]]
</span> </span>
</div> </div>
<div slot="button-container"> <div slot="button-container">
......
...@@ -52,12 +52,43 @@ Polymer({ ...@@ -52,12 +52,43 @@ Polymer({
}, },
/** /**
* @private
* @return {boolean}
*/
hasSecureChangePasswordUrl_() {
const url = this.item.changePasswordUrl;
return !!url && (url.startsWith('https://') || url.startsWith('chrome://'));
},
/**
* Returns the remove password description with a linkified change password
* URL. Requires the change password URL to be present and secure.
* @private
* @return {string} * @return {string}
*/
getRemovePasswordDescriptionHtml_() {
if (!this.hasSecureChangePasswordUrl_()) {
return '';
}
const url = assert(this.item.changePasswordUrl);
const origin = this.item.formattedOrigin;
return this.i18nAdvanced(
'removeCompromisedPasswordConfirmationDescription', {
substitutions:
[origin, `<a href='${url}' target='_blank'>${origin}</a>`],
});
},
/**
* Returns the remove password description as a plain text.
* Used when the change password URL is not present or insecure.
* @private * @private
* @return {string}
*/ */
getRemovePasswordDescription_() { getRemovePasswordDescriptionText_() {
const origin = this.item.formattedOrigin;
return this.i18n( return this.i18n(
'removeCompromisedPasswordConfirmationDescription', 'removeCompromisedPasswordConfirmationDescription', origin, origin);
this.item.formattedOrigin, this.item.formattedOrigin); },
}
}); });
...@@ -534,6 +534,26 @@ suite('PasswordsCheckSection', function() { ...@@ -534,6 +534,26 @@ suite('PasswordsCheckSection', function() {
assertEquals('one.com', formattedOrigin); assertEquals('one.com', formattedOrigin);
}); });
// Tests that a secure change password URL gets linkified in the remove
// password confirmation dialog.
test('secureChangePasswordUrlInRemovePasswordConfirmationDialog', () => {
const entry = makeCompromisedCredential('one.com', 'test4', 'LEAKED', 0);
entry.changePasswordUrl = 'https://one.com';
const removeDialog = createRemovePasswordDialog(entry);
assertTrue(isElementVisible(removeDialog.$.link));
assertFalse(isElementVisible(removeDialog.$.text));
});
// Tests that an insecure change password URL does not get linkified in the
// remove password confirmation dialog.
test('insecureChangePasswordUrlInRemovePasswordConfirmationDialog', () => {
const entry = makeCompromisedCredential('one.com', 'test4', 'LEAKED', 0);
entry.changePasswordUrl = 'http://one.com';
const removeDialog = createRemovePasswordDialog(entry);
assertFalse(isElementVisible(removeDialog.$.link));
assertTrue(isElementVisible(removeDialog.$.text));
});
// A changing status is immediately reflected in title, icon and banner. // A changing status is immediately reflected in title, icon and banner.
test('updatesNumberOfCheckedPasswordsWhileRunning', async function() { test('updatesNumberOfCheckedPasswordsWhileRunning', async function() {
passwordManager.data.checkStatus = makePasswordCheckStatus( passwordManager.data.checkStatus = makePasswordCheckStatus(
......
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