diff --git a/web/settings/account-delete-modal.react.js b/web/settings/account-delete-modal.react.js index bac272b54..0de7be60a 100644 --- a/web/settings/account-delete-modal.react.js +++ b/web/settings/account-delete-modal.react.js @@ -1,186 +1,213 @@ // @flow import invariant from 'invariant'; import * as React from 'react'; import { deleteAccount, deleteAccountActionTypes, } from 'lib/actions/user-actions'; import { useModalContext } from 'lib/components/modal-provider.react'; import { preRequestUserStateSelector } from 'lib/selectors/account-selectors'; import { createLoadingStatusSelector } from 'lib/selectors/loading-selectors'; +import { accountHasPassword } from 'lib/shared/account-utils.js'; import type { LogOutResult } from 'lib/types/account-types'; import type { PreRequestUserState } from 'lib/types/session-types'; import type { DispatchActionPromise } from 'lib/utils/action-utils'; import { useDispatchActionPromise, useServerCall, } from 'lib/utils/action-utils'; import Button, { buttonThemes } from '../components/button.react'; import Input from '../modals/input.react'; import Modal from '../modals/modal.react'; import { useSelector } from '../redux/redux-utils'; import SWMansionIcon from '../SWMansionIcon.react.js'; import css from './account-delete-modal.css'; type Props = { + +isAccountWithPassword: boolean, +preRequestUserState: PreRequestUserState, +inputDisabled: boolean, +dispatchActionPromise: DispatchActionPromise, +deleteAccount: ( - password: string, + password: ?string, preRequestUserState: PreRequestUserState, ) => Promise, +popModal: () => void, }; type State = { - +currentPassword: string, + +currentPassword: ?string, +errorMessage: string, }; class AccountDeleteModal extends React.PureComponent { currentPasswordInput: ?HTMLInputElement; constructor(props: Props) { super(props); this.state = { - currentPassword: '', + currentPassword: props.isAccountWithPassword ? '' : null, errorMessage: '', }; } componentDidMount() { - invariant(this.currentPasswordInput, 'newPasswordInput ref unset'); - this.currentPasswordInput.focus(); + invariant( + !this.props.isAccountWithPassword || this.currentPasswordInput, + 'newPasswordInput ref unset', + ); + this.currentPasswordInput?.focus(); } render() { const { inputDisabled } = this.props; let errorMsg; if (this.state.errorMessage) { errorMsg = (
{this.state.errorMessage}
); } + let passwordConfirmation; + if (this.props.isAccountWithPassword) { + invariant( + this.state.currentPassword !== null && + this.state.currentPassword !== undefined, + 'currentPassword must be set if isAccountWithPassword', + ); + passwordConfirmation = ( + <> +

+ Please enter your account password to confirm your identity. +

+

Account password

+ + + ); + } + return (

Your account will be permanently deleted. There is no way to reverse this.

-

- Please enter your account password to confirm your identity. -

-

Account password

- + + {passwordConfirmation} +
{errorMsg}
); } currentPasswordInputRef = (currentPasswordInput: ?HTMLInputElement) => { this.currentPasswordInput = currentPasswordInput; }; onChangeCurrentPassword = (event: SyntheticEvent) => { const target = event.target; invariant(target instanceof HTMLInputElement, 'target not input'); this.setState({ currentPassword: target.value }); }; onDelete = (event: SyntheticEvent) => { event.preventDefault(); this.props.dispatchActionPromise( deleteAccountActionTypes, this.deleteAction(), ); }; async deleteAction() { try { const response = await this.props.deleteAccount( this.state.currentPassword, this.props.preRequestUserState, ); this.props.popModal(); return response; } catch (e) { const errorMessage = e.message === 'invalid_credentials' ? 'wrong password' : 'unknown error'; this.setState( { - currentPassword: '', + currentPassword: this.props.isAccountWithPassword ? '' : null, errorMessage: errorMessage, }, () => { invariant( - this.currentPasswordInput, + !this.props.isAccountWithPassword || this.currentPasswordInput, 'currentPasswordInput ref unset', ); - this.currentPasswordInput.focus(); + this.currentPasswordInput?.focus(); }, ); throw e; } } } const deleteAccountLoadingStatusSelector = createLoadingStatusSelector( deleteAccountActionTypes, ); const ConnectedAccountDeleteModal: React.ComponentType<{}> = React.memo<{}>( function ConnectedAccountDeleteModal(): React.Node { + const isAccountWithPassword = useSelector(state => + accountHasPassword(state.currentUserInfo), + ); const preRequestUserState = useSelector(preRequestUserStateSelector); const inputDisabled = useSelector( state => deleteAccountLoadingStatusSelector(state) === 'loading', ); const callDeleteAccount = useServerCall(deleteAccount); const dispatchActionPromise = useDispatchActionPromise(); const modalContext = useModalContext(); return ( ); }, ); export default ConnectedAccountDeleteModal;