mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-23 09:16:38 +00:00
Allow to change username (#21152)
This commit is contained in:
parent
23fcdf876c
commit
6a3041988a
@ -138,6 +138,17 @@ export const adminChangePassword = (
|
|||||||
password,
|
password,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const adminChangeUsername = (
|
||||||
|
hass: HomeAssistant,
|
||||||
|
userId: string,
|
||||||
|
username: string
|
||||||
|
) =>
|
||||||
|
hass.callWS<void>({
|
||||||
|
type: "config/auth_provider/homeassistant/admin_change_username",
|
||||||
|
user_id: userId,
|
||||||
|
username,
|
||||||
|
});
|
||||||
|
|
||||||
export const deleteAllRefreshTokens = (
|
export const deleteAllRefreshTokens = (
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
token_type?: RefreshTokenType,
|
token_type?: RefreshTokenType,
|
||||||
|
@ -8,6 +8,7 @@ import "../../../components/ha-formfield";
|
|||||||
import "../../../components/ha-picture-upload";
|
import "../../../components/ha-picture-upload";
|
||||||
import type { HaPictureUpload } from "../../../components/ha-picture-upload";
|
import type { HaPictureUpload } from "../../../components/ha-picture-upload";
|
||||||
import "../../../components/ha-textfield";
|
import "../../../components/ha-textfield";
|
||||||
|
import { adminChangeUsername } from "../../../data/auth";
|
||||||
import { PersonMutableParams } from "../../../data/person";
|
import { PersonMutableParams } from "../../../data/person";
|
||||||
import {
|
import {
|
||||||
deleteUser,
|
deleteUser,
|
||||||
@ -19,10 +20,11 @@ import {
|
|||||||
import {
|
import {
|
||||||
showAlertDialog,
|
showAlertDialog,
|
||||||
showConfirmationDialog,
|
showConfirmationDialog,
|
||||||
|
showPromptDialog,
|
||||||
} from "../../../dialogs/generic/show-dialog-box";
|
} from "../../../dialogs/generic/show-dialog-box";
|
||||||
import { CropOptions } from "../../../dialogs/image-cropper-dialog/show-image-cropper-dialog";
|
import { CropOptions } from "../../../dialogs/image-cropper-dialog/show-image-cropper-dialog";
|
||||||
import { ValueChangedEvent, HomeAssistant } from "../../../types";
|
|
||||||
import { haStyleDialog } from "../../../resources/styles";
|
import { haStyleDialog } from "../../../resources/styles";
|
||||||
|
import { HomeAssistant, ValueChangedEvent } from "../../../types";
|
||||||
import { documentationUrl } from "../../../util/documentation-url";
|
import { documentationUrl } from "../../../util/documentation-url";
|
||||||
import { showAddUserDialog } from "../users/show-dialog-add-user";
|
import { showAddUserDialog } from "../users/show-dialog-add-user";
|
||||||
import { showAdminChangePasswordDialog } from "../users/show-dialog-admin-change-password";
|
import { showAdminChangePasswordDialog } from "../users/show-dialog-admin-change-password";
|
||||||
@ -136,9 +138,9 @@ class DialogPersonDetail extends LitElement {
|
|||||||
></ha-picture-upload>
|
></ha-picture-upload>
|
||||||
|
|
||||||
<ha-formfield
|
<ha-formfield
|
||||||
.label=${this.hass!.localize(
|
.label=${`${this.hass!.localize(
|
||||||
"ui.panel.config.person.detail.allow_login"
|
"ui.panel.config.person.detail.allow_login"
|
||||||
)}
|
)}${this._user ? ` (${this._user.username})` : ""}`}
|
||||||
>
|
>
|
||||||
<ha-switch
|
<ha-switch
|
||||||
@change=${this._allowLoginChanged}
|
@change=${this._allowLoginChanged}
|
||||||
@ -244,6 +246,14 @@ class DialogPersonDetail extends LitElement {
|
|||||||
</mwc-button>
|
</mwc-button>
|
||||||
${this._user && this.hass.user?.is_owner
|
${this._user && this.hass.user?.is_owner
|
||||||
? html`<mwc-button
|
? html`<mwc-button
|
||||||
|
slot="secondaryAction"
|
||||||
|
@click=${this._changeUsername}
|
||||||
|
>
|
||||||
|
${this.hass.localize(
|
||||||
|
"ui.panel.config.users.editor.change_username"
|
||||||
|
)}
|
||||||
|
</mwc-button>
|
||||||
|
<mwc-button
|
||||||
slot="secondaryAction"
|
slot="secondaryAction"
|
||||||
@click=${this._changePassword}
|
@click=${this._changePassword}
|
||||||
>
|
>
|
||||||
@ -292,11 +302,14 @@ class DialogPersonDetail extends LitElement {
|
|||||||
userAddedCallback: async (user?: User) => {
|
userAddedCallback: async (user?: User) => {
|
||||||
if (user) {
|
if (user) {
|
||||||
target.checked = true;
|
target.checked = true;
|
||||||
|
if (this._params!.entry) {
|
||||||
|
await this._params!.updateEntry({ user_id: user.id });
|
||||||
|
}
|
||||||
|
this._params?.refreshUsers();
|
||||||
this._user = user;
|
this._user = user;
|
||||||
this._userId = user.id;
|
this._userId = user.id;
|
||||||
this._isAdmin = user.group_ids.includes(SYSTEM_GROUP_ID_ADMIN);
|
this._isAdmin = user.group_ids.includes(SYSTEM_GROUP_ID_ADMIN);
|
||||||
this._localOnly = user.local_only;
|
this._localOnly = user.local_only;
|
||||||
this._params?.refreshUsers();
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
name: this._name,
|
name: this._name,
|
||||||
@ -320,6 +333,9 @@ class DialogPersonDetail extends LitElement {
|
|||||||
await deleteUser(this.hass, this._userId);
|
await deleteUser(this.hass, this._userId);
|
||||||
this._params?.refreshUsers();
|
this._params?.refreshUsers();
|
||||||
this._userId = undefined;
|
this._userId = undefined;
|
||||||
|
this._user = undefined;
|
||||||
|
this._isAdmin = undefined;
|
||||||
|
this._localOnly = undefined;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -349,6 +365,53 @@ class DialogPersonDetail extends LitElement {
|
|||||||
showAdminChangePasswordDialog(this, { userId: this._user.id });
|
showAdminChangePasswordDialog(this, { userId: this._user.id });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async _changeUsername() {
|
||||||
|
if (!this._user) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const credential = this._user.credentials.find(
|
||||||
|
(cred) => cred.type === "homeassistant"
|
||||||
|
);
|
||||||
|
if (!credential) {
|
||||||
|
showAlertDialog(this, {
|
||||||
|
title: "No Home Assistant credentials found.",
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const newUsername = await showPromptDialog(this, {
|
||||||
|
inputLabel: this.hass.localize(
|
||||||
|
"ui.panel.config.users.change_username.new_username"
|
||||||
|
),
|
||||||
|
confirmText: this.hass.localize(
|
||||||
|
"ui.panel.config.users.change_username.change"
|
||||||
|
),
|
||||||
|
title: this.hass.localize(
|
||||||
|
"ui.panel.config.users.change_username.caption"
|
||||||
|
),
|
||||||
|
defaultValue: this._user.username!,
|
||||||
|
});
|
||||||
|
if (newUsername) {
|
||||||
|
try {
|
||||||
|
await adminChangeUsername(this.hass, this._user.id, newUsername);
|
||||||
|
this._params?.refreshUsers();
|
||||||
|
this._user = { ...this._user, username: newUsername };
|
||||||
|
showAlertDialog(this, {
|
||||||
|
text: this.hass.localize(
|
||||||
|
"ui.panel.config.users.change_username.username_changed"
|
||||||
|
),
|
||||||
|
});
|
||||||
|
} catch (err: any) {
|
||||||
|
showAlertDialog(this, {
|
||||||
|
title: this.hass.localize(
|
||||||
|
"ui.panel.config.users.change_username.failed"
|
||||||
|
),
|
||||||
|
text: err.message,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private async _updateEntry() {
|
private async _updateEntry() {
|
||||||
this._submitting = true;
|
this._submitting = true;
|
||||||
try {
|
try {
|
||||||
|
@ -10,12 +10,16 @@ import "../../../components/ha-label";
|
|||||||
import "../../../components/ha-svg-icon";
|
import "../../../components/ha-svg-icon";
|
||||||
import "../../../components/ha-switch";
|
import "../../../components/ha-switch";
|
||||||
import "../../../components/ha-textfield";
|
import "../../../components/ha-textfield";
|
||||||
|
import { adminChangeUsername } from "../../../data/auth";
|
||||||
import {
|
import {
|
||||||
computeUserBadges,
|
computeUserBadges,
|
||||||
SYSTEM_GROUP_ID_ADMIN,
|
SYSTEM_GROUP_ID_ADMIN,
|
||||||
SYSTEM_GROUP_ID_USER,
|
SYSTEM_GROUP_ID_USER,
|
||||||
} from "../../../data/user";
|
} from "../../../data/user";
|
||||||
import { showAlertDialog } from "../../../dialogs/generic/show-dialog-box";
|
import {
|
||||||
|
showAlertDialog,
|
||||||
|
showPromptDialog,
|
||||||
|
} from "../../../dialogs/generic/show-dialog-box";
|
||||||
import { haStyleDialog } from "../../../resources/styles";
|
import { haStyleDialog } from "../../../resources/styles";
|
||||||
import { HomeAssistant } from "../../../types";
|
import { HomeAssistant } from "../../../types";
|
||||||
import { showAdminChangePasswordDialog } from "./show-dialog-admin-change-password";
|
import { showAdminChangePasswordDialog } from "./show-dialog-admin-change-password";
|
||||||
@ -172,7 +176,11 @@ class DialogUserDetail extends LitElement {
|
|||||||
`
|
`
|
||||||
: ""}
|
: ""}
|
||||||
${!user.system_generated && this.hass.user?.is_owner
|
${!user.system_generated && this.hass.user?.is_owner
|
||||||
? html`<mwc-button @click=${this._changePassword}>
|
? html`<mwc-button @click=${this._changeUsername}>
|
||||||
|
${this.hass.localize(
|
||||||
|
"ui.panel.config.users.editor.change_username"
|
||||||
|
)} </mwc-button
|
||||||
|
><mwc-button @click=${this._changePassword}>
|
||||||
${this.hass.localize(
|
${this.hass.localize(
|
||||||
"ui.panel.config.users.editor.change_password"
|
"ui.panel.config.users.editor.change_password"
|
||||||
)}
|
)}
|
||||||
@ -250,6 +258,56 @@ class DialogUserDetail extends LitElement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async _changeUsername() {
|
||||||
|
const credential = this._params?.entry.credentials.find(
|
||||||
|
(cred) => cred.type === "homeassistant"
|
||||||
|
);
|
||||||
|
if (!credential) {
|
||||||
|
showAlertDialog(this, {
|
||||||
|
title: "No Home Assistant credentials found.",
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const newUsername = await showPromptDialog(this, {
|
||||||
|
inputLabel: this.hass.localize(
|
||||||
|
"ui.panel.config.users.change_username.new_username"
|
||||||
|
),
|
||||||
|
confirmText: this.hass.localize(
|
||||||
|
"ui.panel.config.users.change_username.change"
|
||||||
|
),
|
||||||
|
title: this.hass.localize(
|
||||||
|
"ui.panel.config.users.change_username.caption"
|
||||||
|
),
|
||||||
|
defaultValue: this._params!.entry.username!,
|
||||||
|
});
|
||||||
|
if (newUsername) {
|
||||||
|
try {
|
||||||
|
await adminChangeUsername(
|
||||||
|
this.hass,
|
||||||
|
this._params!.entry.id,
|
||||||
|
newUsername
|
||||||
|
);
|
||||||
|
this._params = {
|
||||||
|
...this._params!,
|
||||||
|
entry: { ...this._params!.entry, username: newUsername },
|
||||||
|
};
|
||||||
|
this._params.replaceEntry(this._params.entry);
|
||||||
|
showAlertDialog(this, {
|
||||||
|
text: this.hass.localize(
|
||||||
|
"ui.panel.config.users.change_username.username_changed"
|
||||||
|
),
|
||||||
|
});
|
||||||
|
} catch (err: any) {
|
||||||
|
showAlertDialog(this, {
|
||||||
|
title: this.hass.localize(
|
||||||
|
"ui.panel.config.users.change_username.failed"
|
||||||
|
),
|
||||||
|
text: err.message,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private async _changePassword() {
|
private async _changePassword() {
|
||||||
const credential = this._params?.entry.credentials.find(
|
const credential = this._params?.entry.credentials.find(
|
||||||
(cred) => cred.type === "homeassistant"
|
(cred) => cred.type === "homeassistant"
|
||||||
|
@ -237,6 +237,11 @@ export class HaConfigUsers extends LitElement {
|
|||||||
|
|
||||||
showUserDetailDialog(this, {
|
showUserDetailDialog(this, {
|
||||||
entry,
|
entry,
|
||||||
|
replaceEntry: (newEntry: User) => {
|
||||||
|
this._users = this._users!.map((ent) =>
|
||||||
|
ent.id === newEntry.id ? newEntry : ent
|
||||||
|
);
|
||||||
|
},
|
||||||
updateEntry: async (values) => {
|
updateEntry: async (values) => {
|
||||||
const updated = await updateUser(this.hass!, entry!.id, values);
|
const updated = await updateUser(this.hass!, entry!.id, values);
|
||||||
this._users = this._users!.map((ent) =>
|
this._users = this._users!.map((ent) =>
|
||||||
|
@ -4,6 +4,7 @@ import { UpdateUserParams, User } from "../../../data/user";
|
|||||||
export interface UserDetailDialogParams {
|
export interface UserDetailDialogParams {
|
||||||
entry: User;
|
entry: User;
|
||||||
updateEntry: (updates: Partial<UpdateUserParams>) => Promise<unknown>;
|
updateEntry: (updates: Partial<UpdateUserParams>) => Promise<unknown>;
|
||||||
|
replaceEntry: (entry: User) => void;
|
||||||
removeEntry: () => Promise<boolean>;
|
removeEntry: () => Promise<boolean>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4382,6 +4382,7 @@
|
|||||||
"name": "Display name",
|
"name": "Display name",
|
||||||
"username": "Username",
|
"username": "Username",
|
||||||
"change_password": "Change password",
|
"change_password": "Change password",
|
||||||
|
"change_username": "Change username",
|
||||||
"activate_user": "Activate user",
|
"activate_user": "Activate user",
|
||||||
"deactivate_user": "Deactivate user",
|
"deactivate_user": "Deactivate user",
|
||||||
"delete_user": "Delete user",
|
"delete_user": "Delete user",
|
||||||
@ -4415,6 +4416,13 @@
|
|||||||
"change": "Change",
|
"change": "Change",
|
||||||
"password_no_match": "Passwords don't match",
|
"password_no_match": "Passwords don't match",
|
||||||
"password_changed": "The password has been changed successfully."
|
"password_changed": "The password has been changed successfully."
|
||||||
|
},
|
||||||
|
"change_username": {
|
||||||
|
"caption": "Change username",
|
||||||
|
"new_username": "New username",
|
||||||
|
"change": "Change",
|
||||||
|
"username_changed": "The username has been changed successfully.",
|
||||||
|
"failed": "Failed to change username"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"application_credentials": {
|
"application_credentials": {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user