blob: 23fa2e101a31d6df4e1bddf730902c4bc549a8af [file] [log] [blame]
// Copyright 2016 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @fileoverview
*
* 'settings-password-prompt-dialog' shows a dialog which asks for the user to
* enter their password. It validates the password is correct. Once the user has
* entered their account password, the page fires an 'authenticated' event and
* updates the authToken binding.
*
* Example:
*
* <settings-password-prompt-dialog
* id="passwordPrompt"
* password-prompt-text="{{passwordPromptText}}"
* auth-token="{{authToken}}">
* </settings-password-prompt-dialog>
*/
import '//resources/cr_elements/cr_button/cr_button.js';
import '//resources/cr_elements/cr_dialog/cr_dialog.js';
import '//resources/cr_elements/cr_input/cr_input.js';
import '//resources/cr_elements/cr_shared_style.css.js';
import '../settings_shared.css.js';
import {CrDialogElement} from '//resources/cr_elements/cr_dialog/cr_dialog.js';
import {CrInputElement} from '//resources/cr_elements/cr_input/cr_input.js';
import {PolymerElement} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js';
import {getTemplate} from './password_prompt_dialog.html.js';
interface SettingsPasswordPromptDialogElement {
$: {
dialog: CrDialogElement,
};
}
class SettingsPasswordPromptDialogElement extends PolymerElement {
static get is() {
return 'settings-password-prompt-dialog';
}
static get template() {
return getTemplate();
}
static get properties() {
return {
/**
* The subtext to be displayed above the password input field. Embedders
* may choose to change this value for their specific use case.
*/
passwordPromptText: {
type: String,
notify: true,
value: '',
},
inputValue_: {
type: String,
value: '',
observer: 'onInputValueChange_',
},
/**
* Helper property which marks password as valid/invalid.
*/
passwordInvalid_: {
type: Boolean,
value: false,
},
/**
* Interface for chrome.quickUnlockPrivate calls. May be overridden by
* tests.
*/
quickUnlockPrivate: {type: Object, value: chrome.quickUnlockPrivate},
waitingForPasswordCheck_: {
type: Boolean,
value: false,
},
};
}
passwordPromptText: string;
private inputValue_: string;
private passwordInvalid_: boolean;
quickUnlockPrivate: typeof chrome.quickUnlockPrivate;
private waitingForPasswordCheck_: boolean;
get passwordInput(): CrInputElement {
return this.shadowRoot!.querySelector('cr-input')!;
}
override connectedCallback() {
super.connectedCallback();
this.$.dialog.showModal();
// This needs to occur at the next paint otherwise the password input will
// not receive focus.
window.setTimeout(() => {
// TODO(crbug.com/876377): This is unusual; the 'autofocus' attribute on
// the cr-input element should work. Investigate.
this.passwordInput.focus();
}, 1);
}
private onCancelTap_() {
if (this.$.dialog.open) {
this.$.dialog.close();
}
}
/**
* Run the account password check.
*/
private submitPassword_() {
this.waitingForPasswordCheck_ = true;
const password = this.passwordInput.value;
// The user might have started entering a password and then deleted it all.
// Do not submit/show an error in this case.
if (!password) {
this.passwordInvalid_ = false;
this.waitingForPasswordCheck_ = false;
return;
}
this.quickUnlockPrivate.getAuthToken(password, (tokenInfo) => {
this.waitingForPasswordCheck_ = false;
if (chrome.runtime.lastError) {
this.passwordInvalid_ = true;
// Select the whole password if user entered an incorrect password.
this.passwordInput.select();
return;
}
this.dispatchEvent(new CustomEvent(
'token-obtained',
{bubbles: true, composed: true, detail: tokenInfo}));
this.passwordInvalid_ = false;
if (this.$.dialog.open) {
this.$.dialog.close();
}
});
}
private onInputValueChange_() {
this.passwordInvalid_ = false;
}
private isConfirmEnabled_() {
return !this.waitingForPasswordCheck_ && !this.passwordInvalid_ &&
this.inputValue_;
}
}
customElements.define(
SettingsPasswordPromptDialogElement.is,
SettingsPasswordPromptDialogElement);