mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-28 03:36:44 +00:00
Improve password change card (#7756)
Co-authored-by: Bram Kragten <mail@bramkragten.nl>
This commit is contained in:
parent
c4f850cb14
commit
3313572606
@ -1,154 +0,0 @@
|
|||||||
import "@material/mwc-button";
|
|
||||||
import "@polymer/paper-dialog/paper-dialog";
|
|
||||||
import "../../components/ha-circular-progress";
|
|
||||||
import { html } from "@polymer/polymer/lib/utils/html-tag";
|
|
||||||
/* eslint-plugin-disable lit */
|
|
||||||
import { PolymerElement } from "@polymer/polymer/polymer-element";
|
|
||||||
import "../../components/ha-card";
|
|
||||||
import LocalizeMixin from "../../mixins/localize-mixin";
|
|
||||||
import "../../styles/polymer-ha-style";
|
|
||||||
|
|
||||||
/*
|
|
||||||
* @appliesMixin LocalizeMixin
|
|
||||||
*/
|
|
||||||
class HaChangePasswordCard extends LocalizeMixin(PolymerElement) {
|
|
||||||
static get template() {
|
|
||||||
return html`
|
|
||||||
<style include="ha-style">
|
|
||||||
.error {
|
|
||||||
color: red;
|
|
||||||
}
|
|
||||||
.status {
|
|
||||||
color: var(--primary-color);
|
|
||||||
}
|
|
||||||
.error,
|
|
||||||
.status {
|
|
||||||
position: absolute;
|
|
||||||
top: -4px;
|
|
||||||
}
|
|
||||||
.currentPassword {
|
|
||||||
margin-top: -4px;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
<div>
|
|
||||||
<ha-card
|
|
||||||
header="[[localize('ui.panel.profile.change_password.header')]]"
|
|
||||||
>
|
|
||||||
<div class="card-content">
|
|
||||||
<template is="dom-if" if="[[_errorMsg]]">
|
|
||||||
<div class="error">[[_errorMsg]]</div>
|
|
||||||
</template>
|
|
||||||
<template is="dom-if" if="[[_statusMsg]]">
|
|
||||||
<div class="status">[[_statusMsg]]</div>
|
|
||||||
</template>
|
|
||||||
<paper-input
|
|
||||||
class="currentPassword"
|
|
||||||
label="[[localize('ui.panel.profile.change_password.current_password')]]"
|
|
||||||
type="password"
|
|
||||||
value="{{_currentPassword}}"
|
|
||||||
required
|
|
||||||
auto-validate
|
|
||||||
error-message="[[localize('ui.panel.profile.change_password.error_required')]]"
|
|
||||||
></paper-input>
|
|
||||||
<template is="dom-if" if="[[_currentPassword]]">
|
|
||||||
<paper-input
|
|
||||||
label="[[localize('ui.panel.profile.change_password.new_password')]]"
|
|
||||||
type="password"
|
|
||||||
value="{{_password1}}"
|
|
||||||
required
|
|
||||||
auto-validate
|
|
||||||
error-message="[[localize('ui.panel.profile.change_password.error_required')]]"
|
|
||||||
></paper-input>
|
|
||||||
<paper-input
|
|
||||||
label="[[localize('ui.panel.profile.change_password.confirm_new_password')]]"
|
|
||||||
type="password"
|
|
||||||
value="{{_password2}}"
|
|
||||||
required
|
|
||||||
auto-validate
|
|
||||||
error-message="[[localize('ui.panel.profile.change_password.error_required')]]"
|
|
||||||
></paper-input>
|
|
||||||
</template>
|
|
||||||
</div>
|
|
||||||
<div class="card-actions">
|
|
||||||
<template is="dom-if" if="[[_loading]]">
|
|
||||||
<div><ha-circular-progress active></ha-circular-progress></div>
|
|
||||||
</template>
|
|
||||||
<template is="dom-if" if="[[!_loading]]">
|
|
||||||
<mwc-button on-click="_changePassword"
|
|
||||||
>[[localize('ui.panel.profile.change_password.submit')]]</mwc-button
|
|
||||||
>
|
|
||||||
</template>
|
|
||||||
</div>
|
|
||||||
</ha-card>
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
}
|
|
||||||
|
|
||||||
static get properties() {
|
|
||||||
return {
|
|
||||||
hass: Object,
|
|
||||||
|
|
||||||
_loading: {
|
|
||||||
type: Boolean,
|
|
||||||
value: false,
|
|
||||||
},
|
|
||||||
|
|
||||||
// Error message when can't talk to server etc
|
|
||||||
_statusMsg: String,
|
|
||||||
_errorMsg: String,
|
|
||||||
|
|
||||||
_currentPassword: String,
|
|
||||||
_password1: String,
|
|
||||||
_password2: String,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
ready() {
|
|
||||||
super.ready();
|
|
||||||
this.addEventListener("keypress", (ev) => {
|
|
||||||
this._statusMsg = null;
|
|
||||||
if (ev.keyCode === 13) {
|
|
||||||
this._changePassword();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
async _changePassword() {
|
|
||||||
this._statusMsg = null;
|
|
||||||
if (!this._currentPassword || !this._password1 || !this._password2) return;
|
|
||||||
|
|
||||||
if (this._password1 !== this._password2) {
|
|
||||||
this._errorMsg = "New password confirmation doesn't match";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this._currentPassword === this._password1) {
|
|
||||||
this._errorMsg = "New password must be different than current password";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this._loading = true;
|
|
||||||
this._errorMsg = null;
|
|
||||||
|
|
||||||
try {
|
|
||||||
await this.hass.callWS({
|
|
||||||
type: "config/auth_provider/homeassistant/change_password",
|
|
||||||
current_password: this._currentPassword,
|
|
||||||
new_password: this._password1,
|
|
||||||
});
|
|
||||||
|
|
||||||
this.setProperties({
|
|
||||||
_statusMsg: "Password changed successfully",
|
|
||||||
_currentPassword: null,
|
|
||||||
_password1: null,
|
|
||||||
_password2: null,
|
|
||||||
});
|
|
||||||
} catch (err) {
|
|
||||||
this._errorMsg = err.message;
|
|
||||||
}
|
|
||||||
|
|
||||||
this._loading = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
customElements.define("ha-change-password-card", HaChangePasswordCard);
|
|
195
src/panels/profile/ha-change-password-card.ts
Normal file
195
src/panels/profile/ha-change-password-card.ts
Normal file
@ -0,0 +1,195 @@
|
|||||||
|
import "@polymer/paper-input/paper-input";
|
||||||
|
import "@polymer/paper-dialog/paper-dialog";
|
||||||
|
import {
|
||||||
|
css,
|
||||||
|
CSSResult,
|
||||||
|
customElement,
|
||||||
|
html,
|
||||||
|
internalProperty,
|
||||||
|
LitElement,
|
||||||
|
property,
|
||||||
|
PropertyValues,
|
||||||
|
TemplateResult,
|
||||||
|
} from "lit-element";
|
||||||
|
import "@material/mwc-button";
|
||||||
|
import "../../components/ha-circular-progress";
|
||||||
|
import "../../components/ha-card";
|
||||||
|
import { haStyle } from "../../resources/styles";
|
||||||
|
import type { HomeAssistant } from "../../types";
|
||||||
|
|
||||||
|
@customElement("ha-change-password-card")
|
||||||
|
class HaChangePasswordCard extends LitElement {
|
||||||
|
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||||
|
|
||||||
|
@internalProperty() private _loading = false;
|
||||||
|
|
||||||
|
@internalProperty() private _statusMsg?: string;
|
||||||
|
|
||||||
|
@internalProperty() private _errorMsg?: string;
|
||||||
|
|
||||||
|
@internalProperty() private _currentPassword?: string;
|
||||||
|
|
||||||
|
@internalProperty() private _password?: string;
|
||||||
|
|
||||||
|
@internalProperty() private _passwordConfirm?: string;
|
||||||
|
|
||||||
|
protected render(): TemplateResult {
|
||||||
|
return html`
|
||||||
|
<div>
|
||||||
|
<ha-card
|
||||||
|
.header=${this.hass.localize(
|
||||||
|
"ui.panel.profile.change_password.header"
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<div class="card-content">
|
||||||
|
${this._errorMsg
|
||||||
|
? html` <div class="error">${this._errorMsg}</div> `
|
||||||
|
: ""}
|
||||||
|
${this._statusMsg
|
||||||
|
? html` <div class="status">${this._statusMsg}</div> `
|
||||||
|
: ""}
|
||||||
|
|
||||||
|
<paper-input
|
||||||
|
id="currentPassword"
|
||||||
|
.label=${this.hass.localize(
|
||||||
|
"ui.panel.profile.change_password.current_password"
|
||||||
|
)}
|
||||||
|
type="password"
|
||||||
|
.value=${this._currentPassword}
|
||||||
|
@value-changed=${this._currentPasswordChanged}
|
||||||
|
required
|
||||||
|
></paper-input>
|
||||||
|
|
||||||
|
${this._currentPassword
|
||||||
|
? html` <paper-input
|
||||||
|
.label=${this.hass.localize(
|
||||||
|
"ui.panel.profile.change_password.new_password"
|
||||||
|
)}
|
||||||
|
name="password"
|
||||||
|
type="password"
|
||||||
|
.value=${this._password}
|
||||||
|
@value-changed=${this._newPasswordChanged}
|
||||||
|
required
|
||||||
|
auto-validate
|
||||||
|
></paper-input>
|
||||||
|
<paper-input
|
||||||
|
.label=${this.hass.localize(
|
||||||
|
"ui.panel.profile.change_password.confirm_new_password"
|
||||||
|
)}
|
||||||
|
name="passwordConfirm"
|
||||||
|
type="password"
|
||||||
|
.value=${this._passwordConfirm}
|
||||||
|
@value-changed=${this._newPasswordConfirmChanged}
|
||||||
|
required
|
||||||
|
auto-validate
|
||||||
|
></paper-input>`
|
||||||
|
: ""}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card-actions">
|
||||||
|
${this._loading
|
||||||
|
? html`<div>
|
||||||
|
<ha-circular-progress active></ha-circular-progress>
|
||||||
|
</div>`
|
||||||
|
: html`<mwc-button
|
||||||
|
@click=${this._changePassword}
|
||||||
|
.disabled=${!this._passwordConfirm}
|
||||||
|
>${this.hass.localize(
|
||||||
|
"ui.panel.profile.change_password.submit"
|
||||||
|
)}</mwc-button
|
||||||
|
>`}
|
||||||
|
</div>
|
||||||
|
</ha-card>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
private _currentPasswordChanged(ev: CustomEvent) {
|
||||||
|
this._currentPassword = ev.detail.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
private _newPasswordChanged(ev: CustomEvent) {
|
||||||
|
this._password = ev.detail.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
private _newPasswordConfirmChanged(ev: CustomEvent) {
|
||||||
|
this._passwordConfirm = ev.detail.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected firstUpdated(changedProps: PropertyValues) {
|
||||||
|
super.firstUpdated(changedProps);
|
||||||
|
this.addEventListener("keypress", (ev) => {
|
||||||
|
this._statusMsg = undefined;
|
||||||
|
if (ev.keyCode === 13) {
|
||||||
|
this._changePassword();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private async _changePassword() {
|
||||||
|
this._statusMsg = undefined;
|
||||||
|
if (!this._currentPassword || !this._password || !this._passwordConfirm) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this._password !== this._passwordConfirm) {
|
||||||
|
this._errorMsg = this.hass.localize(
|
||||||
|
"ui.panel.profile.change_password.error_new_mismatch"
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this._currentPassword === this._password) {
|
||||||
|
this._errorMsg = this.hass.localize(
|
||||||
|
"ui.panel.profile.change_password.error_new_is_old"
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this._loading = true;
|
||||||
|
this._errorMsg = undefined;
|
||||||
|
|
||||||
|
try {
|
||||||
|
await this.hass.callWS({
|
||||||
|
type: "config/auth_provider/homeassistant/change_password",
|
||||||
|
current_password: this._currentPassword,
|
||||||
|
new_password: this._password,
|
||||||
|
});
|
||||||
|
} catch (err) {
|
||||||
|
this._errorMsg = err.message;
|
||||||
|
return;
|
||||||
|
} finally {
|
||||||
|
this._loading = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
this._statusMsg = this.hass.localize(
|
||||||
|
"ui.panel.profile.change_password.success"
|
||||||
|
);
|
||||||
|
this._currentPassword = undefined;
|
||||||
|
this._password = undefined;
|
||||||
|
this._passwordConfirm = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
static get styles(): CSSResult[] {
|
||||||
|
return [
|
||||||
|
haStyle,
|
||||||
|
css`
|
||||||
|
.error {
|
||||||
|
color: var(--error-color);
|
||||||
|
}
|
||||||
|
.status {
|
||||||
|
color: var(--primary-color);
|
||||||
|
}
|
||||||
|
#currentPassword {
|
||||||
|
margin-top: -8px;
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface HTMLElementTagNameMap {
|
||||||
|
"ha-change-password-card": HaChangePasswordCard;
|
||||||
|
}
|
||||||
|
}
|
@ -2897,7 +2897,10 @@
|
|||||||
"new_password": "New Password",
|
"new_password": "New Password",
|
||||||
"confirm_new_password": "Confirm New Password",
|
"confirm_new_password": "Confirm New Password",
|
||||||
"error_required": "Required",
|
"error_required": "Required",
|
||||||
"submit": "Submit"
|
"submit": "Submit",
|
||||||
|
"error_new_mismatch": "Entered new password values do not match",
|
||||||
|
"error_new_is_old": "New password must be different than current password",
|
||||||
|
"success": "Password changed successfully"
|
||||||
},
|
},
|
||||||
"mfa": {
|
"mfa": {
|
||||||
"header": "Multi-factor Authentication Modules",
|
"header": "Multi-factor Authentication Modules",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user