mirror of
https://github.com/home-assistant/frontend.git
synced 2025-04-25 05:47:20 +00:00
Allow owner users to change password of any user (#6698)
Co-authored-by: Paulus Schoutsen <balloob@gmail.com>
This commit is contained in:
parent
dc5b92030f
commit
7a4c9b128c
@ -44,3 +44,14 @@ export const createAuthForUser = async (
|
||||
username,
|
||||
password,
|
||||
});
|
||||
|
||||
export const adminChangePassword = async (
|
||||
hass: HomeAssistant,
|
||||
userId: string,
|
||||
password: string
|
||||
) =>
|
||||
hass.callWS<void>({
|
||||
type: "config/auth_provider/homeassistant/admin_change_password",
|
||||
user_id: userId,
|
||||
password,
|
||||
});
|
||||
|
@ -1,20 +1,21 @@
|
||||
import "@material/mwc-button";
|
||||
import "@polymer/paper-input/paper-input";
|
||||
import "../../../components/ha-circular-progress";
|
||||
import {
|
||||
css,
|
||||
CSSResult,
|
||||
customElement,
|
||||
html,
|
||||
internalProperty,
|
||||
LitElement,
|
||||
property,
|
||||
internalProperty,
|
||||
PropertyValues,
|
||||
TemplateResult,
|
||||
} from "lit-element";
|
||||
import { computeRTLDirection } from "../../../common/util/compute_rtl";
|
||||
import "../../../components/ha-circular-progress";
|
||||
import "../../../components/ha-dialog";
|
||||
import "../../../components/ha-switch";
|
||||
import "../../../components/ha-formfield";
|
||||
import "../../../components/ha-switch";
|
||||
import { createAuthForUser } from "../../../data/auth";
|
||||
import {
|
||||
createUser,
|
||||
@ -27,7 +28,6 @@ import { PolymerChangedEvent } from "../../../polymer-types";
|
||||
import { haStyleDialog } from "../../../resources/styles";
|
||||
import { HomeAssistant } from "../../../types";
|
||||
import { AddUserDialogParams } from "./show-dialog-add-user";
|
||||
import { computeRTLDirection } from "../../../common/util/compute_rtl";
|
||||
|
||||
@customElement("dialog-add-user")
|
||||
export class DialogAddUser extends LitElement {
|
||||
@ -46,6 +46,8 @@ export class DialogAddUser extends LitElement {
|
||||
|
||||
@internalProperty() private _password?: string;
|
||||
|
||||
@internalProperty() private _passwordConfirm?: string;
|
||||
|
||||
@internalProperty() private _isAdmin?: boolean;
|
||||
|
||||
public showDialog(params: AddUserDialogParams) {
|
||||
@ -53,6 +55,7 @@ export class DialogAddUser extends LitElement {
|
||||
this._name = "";
|
||||
this._username = "";
|
||||
this._password = "";
|
||||
this._passwordConfirm = "";
|
||||
this._isAdmin = false;
|
||||
this._error = undefined;
|
||||
this._loading = false;
|
||||
@ -83,17 +86,20 @@ export class DialogAddUser extends LitElement {
|
||||
${this._error ? html` <div class="error">${this._error}</div> ` : ""}
|
||||
<paper-input
|
||||
class="name"
|
||||
name="name"
|
||||
.label=${this.hass.localize("ui.panel.config.users.add_user.name")}
|
||||
.value=${this._name}
|
||||
required
|
||||
auto-validate
|
||||
autocapitalize="on"
|
||||
.errorMessage=${this.hass.localize("ui.common.error_required")}
|
||||
@value-changed=${this._nameChanged}
|
||||
@value-changed=${this._handleValueChanged}
|
||||
@blur=${this._maybePopulateUsername}
|
||||
></paper-input>
|
||||
|
||||
<paper-input
|
||||
class="username"
|
||||
name="username"
|
||||
.label=${this.hass.localize(
|
||||
"ui.panel.config.users.add_user.username"
|
||||
)}
|
||||
@ -101,20 +107,40 @@ export class DialogAddUser extends LitElement {
|
||||
required
|
||||
auto-validate
|
||||
autocapitalize="none"
|
||||
@value-changed=${this._usernameChanged}
|
||||
@value-changed=${this._handleValueChanged}
|
||||
.errorMessage=${this.hass.localize("ui.common.error_required")}
|
||||
></paper-input>
|
||||
|
||||
<paper-input
|
||||
.label=${this.hass.localize(
|
||||
"ui.panel.config.users.add_user.password"
|
||||
)}
|
||||
type="password"
|
||||
name="password"
|
||||
.value=${this._password}
|
||||
required
|
||||
auto-validate
|
||||
@value-changed=${this._passwordChanged}
|
||||
@value-changed=${this._handleValueChanged}
|
||||
.errorMessage=${this.hass.localize("ui.common.error_required")}
|
||||
></paper-input>
|
||||
|
||||
<paper-input
|
||||
label="${this.hass.localize(
|
||||
"ui.panel.config.users.add_user.password_confirm"
|
||||
)}"
|
||||
name="passwordConfirm"
|
||||
.value=${this._passwordConfirm}
|
||||
@value-changed=${this._handleValueChanged}
|
||||
required
|
||||
type="password"
|
||||
.invalid=${this._password !== "" &&
|
||||
this._passwordConfirm !== "" &&
|
||||
this._passwordConfirm !== this._password}
|
||||
.errorMessage="${this.hass.localize(
|
||||
"ui.panel.config.users.add_user.password_not_match"
|
||||
)}"
|
||||
></paper-input>
|
||||
|
||||
<ha-formfield
|
||||
.label=${this.hass.localize("ui.panel.config.users.editor.admin")}
|
||||
.dir=${computeRTLDirection(this.hass)}
|
||||
@ -147,7 +173,10 @@ export class DialogAddUser extends LitElement {
|
||||
: html`
|
||||
<mwc-button
|
||||
slot="primaryAction"
|
||||
.disabled=${!this._name || !this._username || !this._password}
|
||||
.disabled=${!this._name ||
|
||||
!this._username ||
|
||||
!this._password ||
|
||||
this._password !== this._passwordConfirm}
|
||||
@click=${this._createUser}
|
||||
>
|
||||
${this.hass.localize("ui.panel.config.users.add_user.create")}
|
||||
@ -173,19 +202,10 @@ export class DialogAddUser extends LitElement {
|
||||
}
|
||||
}
|
||||
|
||||
private _nameChanged(ev: PolymerChangedEvent<string>) {
|
||||
private _handleValueChanged(ev: PolymerChangedEvent<string>): void {
|
||||
this._error = undefined;
|
||||
this._name = ev.detail.value;
|
||||
}
|
||||
|
||||
private _usernameChanged(ev: PolymerChangedEvent<string>) {
|
||||
this._error = undefined;
|
||||
this._username = ev.detail.value;
|
||||
}
|
||||
|
||||
private _passwordChanged(ev: PolymerChangedEvent<string>) {
|
||||
this._error = undefined;
|
||||
this._password = ev.detail.value;
|
||||
const name = (ev.target as any).name;
|
||||
this[`_${name}`] = ev.detail.value;
|
||||
}
|
||||
|
||||
private async _adminChanged(ev): Promise<void> {
|
||||
|
@ -6,23 +6,28 @@ import {
|
||||
CSSResult,
|
||||
customElement,
|
||||
html,
|
||||
internalProperty,
|
||||
LitElement,
|
||||
property,
|
||||
internalProperty,
|
||||
TemplateResult,
|
||||
} from "lit-element";
|
||||
import { computeRTLDirection } from "../../../common/util/compute_rtl";
|
||||
import { createCloseHeading } from "../../../components/ha-dialog";
|
||||
import "../../../components/ha-switch";
|
||||
import "../../../components/ha-formfield";
|
||||
import "../../../components/ha-switch";
|
||||
import { adminChangePassword } from "../../../data/auth";
|
||||
import {
|
||||
SYSTEM_GROUP_ID_ADMIN,
|
||||
SYSTEM_GROUP_ID_USER,
|
||||
} from "../../../data/user";
|
||||
import {
|
||||
showAlertDialog,
|
||||
showPromptDialog,
|
||||
} from "../../../dialogs/generic/show-dialog-box";
|
||||
import { PolymerChangedEvent } from "../../../polymer-types";
|
||||
import { haStyleDialog } from "../../../resources/styles";
|
||||
import { HomeAssistant } from "../../../types";
|
||||
import { UserDetailDialogParams } from "./show-dialog-user-detail";
|
||||
import { computeRTLDirection } from "../../../common/util/compute_rtl";
|
||||
|
||||
@customElement("dialog-user-detail")
|
||||
class DialogUserDetail extends LitElement {
|
||||
@ -141,7 +146,15 @@ class DialogUserDetail extends LitElement {
|
||||
</paper-tooltip>
|
||||
`
|
||||
: ""}
|
||||
${!user.system_generated && this.hass.user?.is_owner
|
||||
? html`<mwc-button @click=${this._changePassword}>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.users.editor.change_password"
|
||||
)}
|
||||
</mwc-button>`
|
||||
: ""}
|
||||
</div>
|
||||
|
||||
<div slot="primaryAction">
|
||||
<mwc-button
|
||||
@click=${this._updateEntry}
|
||||
@ -202,6 +215,52 @@ class DialogUserDetail extends LitElement {
|
||||
}
|
||||
}
|
||||
|
||||
private async _changePassword() {
|
||||
const credential = this._params?.entry.credentials.find(
|
||||
(cred) => cred.type === "homeassistant"
|
||||
);
|
||||
if (!credential) {
|
||||
showAlertDialog(this, {
|
||||
title: "No Home Assistant credentials found.",
|
||||
});
|
||||
return;
|
||||
}
|
||||
const newPassword = await showPromptDialog(this, {
|
||||
title: this.hass.localize("ui.panel.config.users.editor.change_password"),
|
||||
inputType: "password",
|
||||
inputLabel: this.hass.localize(
|
||||
"ui.panel.config.users.editor.new_password"
|
||||
),
|
||||
});
|
||||
if (!newPassword) {
|
||||
return;
|
||||
}
|
||||
const confirmPassword = await showPromptDialog(this, {
|
||||
title: this.hass.localize("ui.panel.config.users.editor.change_password"),
|
||||
inputType: "password",
|
||||
inputLabel: this.hass.localize(
|
||||
"ui.panel.config.users.add_user.password_confirm"
|
||||
),
|
||||
});
|
||||
if (!confirmPassword) {
|
||||
return;
|
||||
}
|
||||
if (newPassword !== confirmPassword) {
|
||||
showAlertDialog(this, {
|
||||
title: this.hass.localize(
|
||||
"ui.panel.config.users.add_user.password_not_match"
|
||||
),
|
||||
});
|
||||
return;
|
||||
}
|
||||
await adminChangePassword(this.hass, this._params!.entry.id, newPassword);
|
||||
showAlertDialog(this, {
|
||||
title: this.hass.localize(
|
||||
"ui.panel.config.users.add_user.password_changed"
|
||||
),
|
||||
});
|
||||
}
|
||||
|
||||
private _close(): void {
|
||||
this._params = undefined;
|
||||
}
|
||||
|
@ -1654,6 +1654,8 @@
|
||||
"caption": "View user",
|
||||
"name": "Name",
|
||||
"change_password": "Change password",
|
||||
"new_password": "New Password",
|
||||
"password_changed": "The password is changed!",
|
||||
"activate_user": "Activate user",
|
||||
"deactivate_user": "Deactivate user",
|
||||
"delete_user": "Delete user",
|
||||
@ -1674,6 +1676,8 @@
|
||||
"name": "Name",
|
||||
"username": "Username",
|
||||
"password": "Password",
|
||||
"password_confirm": "Confirm Password",
|
||||
"password_not_match": "Passwords don't match",
|
||||
"create": "Create"
|
||||
}
|
||||
},
|
||||
|
Loading…
x
Reference in New Issue
Block a user