Ask user to logout all devices when changing password (#17523)

* Ask user to logout all devices when changing password

* missing import

* use core command
This commit is contained in:
Bram Kragten 2023-08-29 17:09:17 +02:00 committed by GitHub
parent 7040c6d469
commit 4e5d57b5f3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 59 additions and 7 deletions

View File

@ -61,7 +61,18 @@ export const createAuthForUser = async (
password, password,
}); });
export const adminChangePassword = async ( export const changePassword = (
hass: HomeAssistant,
current_password: string,
new_password: string
) =>
hass.callWS({
type: "config/auth_provider/homeassistant/change_password",
current_password,
new_password,
});
export const adminChangePassword = (
hass: HomeAssistant, hass: HomeAssistant,
userId: string, userId: string,
password: string password: string
@ -71,3 +82,8 @@ export const adminChangePassword = async (
user_id: userId, user_id: userId,
password, password,
}); });
export const deleteAllRefreshTokens = (hass: HomeAssistant) =>
hass.callWS({
type: "auth/delete_all_refresh_tokens",
});

View File

@ -14,6 +14,12 @@ import "../../components/ha-textfield";
import { haStyle } from "../../resources/styles"; import { haStyle } from "../../resources/styles";
import type { HomeAssistant } from "../../types"; import type { HomeAssistant } from "../../types";
import "../../components/ha-alert"; import "../../components/ha-alert";
import {
showAlertDialog,
showConfirmationDialog,
} from "../../dialogs/generic/show-dialog-box";
import { RefreshToken } from "../../data/refresh_token";
import { changePassword, deleteAllRefreshTokens } from "../../data/auth";
@customElement("ha-change-password-card") @customElement("ha-change-password-card")
class HaChangePasswordCard extends LitElement { class HaChangePasswordCard extends LitElement {
@ -31,6 +37,8 @@ class HaChangePasswordCard extends LitElement {
@state() private _passwordConfirm = ""; @state() private _passwordConfirm = "";
@property({ attribute: false }) public refreshTokens?: RefreshToken[];
protected render(): TemplateResult { protected render(): TemplateResult {
return html` return html`
<ha-card <ha-card
@ -148,11 +156,7 @@ class HaChangePasswordCard extends LitElement {
this._errorMsg = undefined; this._errorMsg = undefined;
try { try {
await this.hass.callWS({ await changePassword(this.hass, this._currentPassword, this._password);
type: "config/auth_provider/homeassistant/change_password",
current_password: this._currentPassword,
new_password: this._password,
});
} catch (err: any) { } catch (err: any) {
this._errorMsg = err.message; this._errorMsg = err.message;
return; return;
@ -163,6 +167,33 @@ class HaChangePasswordCard extends LitElement {
this._statusMsg = this.hass.localize( this._statusMsg = this.hass.localize(
"ui.panel.profile.change_password.success" "ui.panel.profile.change_password.success"
); );
if (
this.refreshTokens &&
(await showConfirmationDialog(this, {
title: this.hass.localize(
"ui.panel.profile.change_password.logout_all_sessions"
),
text: this.hass.localize(
"ui.panel.profile.change_password.logout_all_sessions_text"
),
dismissText: this.hass.localize("ui.common.no"),
confirmText: this.hass.localize("ui.common.yes"),
destructive: true,
}))
) {
try {
await deleteAllRefreshTokens(this.hass);
} catch (err: any) {
await showAlertDialog(this, {
title: this.hass.localize(
"ui.panel.profile.change_password.delete_failed"
),
text: err.message,
});
}
}
this._currentPassword = ""; this._currentPassword = "";
this._password = ""; this._password = "";
this._passwordConfirm = ""; this._passwordConfirm = "";

View File

@ -188,6 +188,8 @@ class HaPanelProfile extends LitElement {
) )
? html` ? html`
<ha-change-password-card <ha-change-password-card
.refreshTokens=${this._refreshTokens}
@hass-refresh-tokens=${this._refreshRefreshTokens}
.hass=${this.hass} .hass=${this.hass}
></ha-change-password-card> ></ha-change-password-card>
` `

View File

@ -5312,7 +5312,10 @@
"submit": "Submit", "submit": "Submit",
"error_new_mismatch": "Entered new password values do not match", "error_new_mismatch": "Entered new password values do not match",
"error_new_is_old": "New password must be different than current password", "error_new_is_old": "New password must be different than current password",
"success": "Password changed successfully" "success": "Password changed successfully",
"logout_all_sessions": "Do you want to log out from all devices?",
"logout_all_sessions_text": "This will require you to log in again on all devices with your new password, including this one.",
"delete_failed": "Not all devices could be logged out"
}, },
"mfa": { "mfa": {
"header": "Multi-factor authentication modules", "header": "Multi-factor authentication modules",