import { ButtonGroup, Button, Box } from '@rocket.chat/fuselage'; import { SHA256 } from '@rocket.chat/sha256'; import { Page, PageFooter, PageHeader, PageScrollableContentWithShadow } from '@rocket.chat/ui-client'; import type { TranslationKey } from '@rocket.chat/ui-contexts'; import { useSetModal, useToastMessageDispatch, useUser, useLogout, useEndpoint, useTranslation, useSetting, useLayout, } from '@rocket.chat/ui-contexts'; import { useId, useState, useCallback } from 'react'; import { FormProvider, useForm } from 'react-hook-form'; import AccountProfileForm from './AccountProfileForm'; import ActionConfirmModal from './ActionConfirmModal'; import { getProfileInitialValues } from './getProfileInitialValues'; import ConfirmOwnerChangeModal from '../../../components/ConfirmOwnerChangeModal'; import { useAllowPasswordChange } from '../security/useAllowPasswordChange'; // TODO: enforce useMutation const AccountProfilePage = () => { const t = useTranslation(); const user = useUser(); const dispatchToastMessage = useToastMessageDispatch(); const { isMobile } = useLayout(); const setModal = useSetModal(); const logout = useLogout(); const [loggingOut, setLoggingOut] = useState(false); const erasureType = useSetting('Message_ErasureType'); const allowDeleteOwnAccount = useSetting('Accounts_AllowDeleteOwnAccount'); const { hasLocalPassword } = useAllowPasswordChange(); const methods = useForm({ defaultValues: getProfileInitialValues(user), reValidateMode: 'onBlur', }); const { reset, formState: { isDirty, isSubmitting }, } = methods; const logoutOtherClients = useEndpoint('POST', '/v1/users.logoutOtherClients'); const deleteOwnAccount = useEndpoint('POST', '/v1/users.deleteOwnAccount'); const handleLogoutOtherLocations = useCallback(async () => { setLoggingOut(true); try { await logoutOtherClients(); dispatchToastMessage({ type: 'success', message: t('Logged_out_of_other_clients_successfully'), }); } catch (error) { dispatchToastMessage({ type: 'error', message: error }); } setLoggingOut(false); }, [logoutOtherClients, dispatchToastMessage, t]); const handleConfirmOwnerChange = useCallback( (passwordOrUsername: string, shouldChangeOwner: string[], shouldBeRemoved: string[]) => { const handleConfirm = async (): Promise => { try { await deleteOwnAccount({ password: SHA256(passwordOrUsername), confirmRelinquish: true }); dispatchToastMessage({ type: 'success', message: t('User_has_been_deleted') }); setModal(null); logout(); } catch (error) { dispatchToastMessage({ type: 'error', message: error }); } }; return setModal( setModal(null)} contentTitle={t(`Delete_User_Warning_${erasureType}` as TranslationKey)} confirmText={t('Delete')} shouldChangeOwner={shouldChangeOwner} shouldBeRemoved={shouldBeRemoved} />, ); }, [erasureType, setModal, t, deleteOwnAccount, dispatchToastMessage, logout], ); const handleDeleteOwnAccount = useCallback(async () => { const handleConfirm = async (passwordOrUsername: string): Promise => { try { await deleteOwnAccount({ password: SHA256(passwordOrUsername) }); dispatchToastMessage({ type: 'success', message: t('User_has_been_deleted') }); setModal(null); } catch (error: any) { if (error.error === 'user-last-owner') { const { shouldChangeOwner, shouldBeRemoved } = error.details; return handleConfirmOwnerChange(passwordOrUsername, shouldChangeOwner, shouldBeRemoved); } if (error.errorType === 'error-invalid-password') { throw error; } dispatchToastMessage({ type: 'error', message: error }); } }; return setModal( setModal(null)} isPassword={hasLocalPassword} />); }, [dispatchToastMessage, hasLocalPassword, setModal, handleConfirmOwnerChange, deleteOwnAccount, t]); const profileFormId = useId(); return ( {allowDeleteOwnAccount && ( )} ); }; export default AccountProfilePage;