diff --git a/src/components/dashboard/users/UserPasswordForm.tsx b/src/components/dashboard/users/UserPasswordForm.tsx index f8eda449588..0ab5dd50cfb 100644 --- a/src/components/dashboard/users/UserPasswordForm.tsx +++ b/src/components/dashboard/users/UserPasswordForm.tsx @@ -1,4 +1,5 @@ import React, { FunctionComponent, useCallback, useEffect, useRef } from 'react'; +import type { UserDto } from '@jellyfin/sdk/lib/generated-client'; import Dashboard from '../../../utils/dashboard'; import globalize from '../../../scripts/globalize'; import LibraryMenu from '../../../scripts/libraryMenu'; @@ -14,6 +15,7 @@ type IProps = { const UserPasswordForm: FunctionComponent = ({ userId }: IProps) => { const element = useRef(null); + const user = useRef(); const loadUser = useCallback(async () => { const page = element.current; @@ -28,17 +30,17 @@ const UserPasswordForm: FunctionComponent = ({ userId }: IProps) => { return; } - const user = await window.ApiClient.getUser(userId); + user.current = await window.ApiClient.getUser(userId); const loggedInUser = await Dashboard.getCurrentUser(); - if (!user.Policy || !user.Configuration) { + if (!user.current.Policy || !user.current.Configuration) { throw new Error('Unexpected null user policy or configuration'); } - LibraryMenu.setTitle(user.Name); + LibraryMenu.setTitle(user.current.Name); - if (user.HasConfiguredPassword) { - if (!user.Policy?.IsAdministrator) { + if (user.current.HasConfiguredPassword) { + if (!user.current.Policy?.IsAdministrator) { (page.querySelector('#btnResetPassword') as HTMLDivElement).classList.remove('hide'); } (page.querySelector('#fldCurrentPassword') as HTMLDivElement).classList.remove('hide'); @@ -47,7 +49,7 @@ const UserPasswordForm: FunctionComponent = ({ userId }: IProps) => { (page.querySelector('#fldCurrentPassword') as HTMLDivElement).classList.add('hide'); } - const canChangePassword = loggedInUser?.Policy?.IsAdministrator || user.Policy.EnableUserPreferenceAccess; + const canChangePassword = loggedInUser?.Policy?.IsAdministrator || user.current.Policy.EnableUserPreferenceAccess; (page.querySelector('.passwordSection') as HTMLDivElement).classList.toggle('hide', !canChangePassword); import('../../autoFocuser').then(({ default: autoFocuser }) => { @@ -76,6 +78,8 @@ const UserPasswordForm: FunctionComponent = ({ userId }: IProps) => { const onSubmit = (e: Event) => { if ((page.querySelector('#txtNewPassword') as HTMLInputElement).value != (page.querySelector('#txtNewPasswordConfirm') as HTMLInputElement).value) { toast(globalize.translate('PasswordMatchError')); + } else if ((page.querySelector('#txtNewPassword') as HTMLInputElement).value == '' && user.current?.Policy?.IsAdministrator) { + toast(globalize.translate('PasswordMissingSaveError')); } else { loading.show(); savePassword(); diff --git a/src/strings/en-us.json b/src/strings/en-us.json index 12023468eb2..218b3882924 100644 --- a/src/strings/en-us.json +++ b/src/strings/en-us.json @@ -1246,6 +1246,7 @@ "PasswordResetComplete": "The password has been reset.", "PasswordResetConfirmation": "Are you sure you wish to reset the password?", "PasswordResetProviderHelp": "Pick a password reset provider to be used when this user requests a password reset.", + "PasswordMissingSaveError": "New password cannot be empty.", "PasswordSaved": "Password saved.", "PathNotFound": "The path could not be found. Please ensure the path is valid and try again.", "Penciller": "Penciler",