Skip to content

Commit

Permalink
fix: Add email confirmation field when deleting users with no password.
Browse files Browse the repository at this point in the history
We are only checking the email match on the frontend,
because if user is directly using the API, we can assume they
know their stuff enough not to accidentally delete their
account. Social auth users with password will also get the email
confirmation screen.
  • Loading branch information
shubham-padia committed Apr 17, 2024
1 parent 03f1ff8 commit d1fe382
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 23 deletions.
92 changes: 71 additions & 21 deletions frontend/web/components/modals/ConfirmDeleteAccount.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React, { FC, useEffect, useState } from 'react'
import Button from 'components/base/forms/Button'
import Utils from 'common/utils/utils'
import { Organisation } from 'common/types/responses'
import { AuthType, Organisation } from 'common/types/responses'
import { useDeleteAccountMutation } from 'common/services/useAccount'
import InputGroup from 'components/base/forms/InputGroup'
import ModalHR from './ModalHR'
Expand All @@ -10,13 +10,35 @@ import ErrorMessage from 'components/ErrorMessage'

type ConfirmDeleteAccountType = {
lastUserOrganisations: Organisation[]
email?: string
auth_type?: AuthType
}

const ERROR_MESSAGES = {
default: 'Error deleting your account.',
mismatchEmail:
'Error deleting your account, please ensure you have entered your current email.',
mismatchPassword:
'Error deleting your account, please ensure you have entered your current password.',
}
const ConfirmDeleteAccount: FC<ConfirmDeleteAccountType> = ({
auth_type,
email,
lastUserOrganisations,
}) => {
const [password, setPassword] = useState<string>('')
const [deleteUserAccount, { isError, isSuccess: updateSuccess }] =
useDeleteAccountMutation()
const [currentEmail, setCurrentEmail] = useState<string>('')
const [errorMessage, setErrorMessage] = useState<string>(
ERROR_MESSAGES.default,
)
const [isEmailMismatchError, setIsEmailMismatchError] =
useState<boolean>(false)
const [
deleteUserAccount,
{ isError: isMutationError, isSuccess: updateSuccess },
] = useDeleteAccountMutation()
const skipPasswordConfirmation =
auth_type === 'GOOGLE' || auth_type === 'GITHUB'

useEffect(() => {
if (updateSuccess) {
Expand Down Expand Up @@ -54,6 +76,20 @@ const ConfirmDeleteAccount: FC<ConfirmDeleteAccountType> = ({
<form
onSubmit={(e) => {
Utils.preventDefault(e)

if (skipPasswordConfirmation) {
if (currentEmail !== email) {
setIsEmailMismatchError(true)
setErrorMessage(ERROR_MESSAGES.mismatchEmail)
return
} else {
setIsEmailMismatchError(false)
setErrorMessage(ERROR_MESSAGES.default)
}
} else {
setErrorMessage(ERROR_MESSAGES.mismatchPassword)
}

deleteUserAccount({
current_password: password,
delete_orphan_organisations: true,
Expand All @@ -64,26 +100,40 @@ const ConfirmDeleteAccount: FC<ConfirmDeleteAccountType> = ({
<FormGroup>
<ModalBody lastUserOrganisations={lastUserOrganisations} />
</FormGroup>
<InputGroup
title='Confirm Password'
className='mb-0'
inputProps={{
className: 'full-width',
name: 'currentPassword',
}}
value={password}
onChange={(event: React.ChangeEvent<HTMLInputElement>) => {
setPassword(Utils.safeParseEventValue(event))
}}
type='password'
name='password'
/>
{isError && (
<ErrorMessage
error='Error deleting your account, please ensure you have entered your
current password.'
{skipPasswordConfirmation ? (
<InputGroup
title='Confirm Email'
className='mb-0'
inputProps={{
className: 'full-width',
name: 'currentEmail',
}}
value={currentEmail}
onChange={(event: React.ChangeEvent<HTMLInputElement>) => {
setCurrentEmail(Utils.safeParseEventValue(event))
}}
type='email'
name='currentEmail'
/>
) : (
<InputGroup
title='Confirm Password'
className='mb-0'
inputProps={{
className: 'full-width',
name: 'currentPassword',
}}
value={password}
onChange={(event: React.ChangeEvent<HTMLInputElement>) => {
setPassword(Utils.safeParseEventValue(event))
}}
type='password'
name='password'
/>
)}
{(isMutationError || isEmailMismatchError) && (
<ErrorMessage error={errorMessage} />
)}
</div>
<ModalHR />
<div className='modal-footer'>
Expand Down
12 changes: 10 additions & 2 deletions frontend/web/components/pages/AccountSettingsPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,14 @@ class TheComponent extends Component {
})
}

confirmDeleteAccount = (lastUserOrganisations, id) => {
confirmDeleteAccount = (lastUserOrganisations, id, email, auth_type) => {
openModal(
'Are you sure?',
<ConfirmDeleteAccount
userId={id}
lastUserOrganisations={lastUserOrganisations}
email={email}
auth_type={auth_type}
/>,
'p-0',
)
Expand Down Expand Up @@ -126,6 +128,7 @@ class TheComponent extends Component {
render() {
const {
state: {
auth_type,
current_password,
email,
error,
Expand Down Expand Up @@ -305,7 +308,12 @@ class TheComponent extends Component {
id='delete-user-btn'
data-test='delete-user-btn'
onClick={() =>
this.confirmDeleteAccount(lastUserOrganisations, id)
this.confirmDeleteAccount(
lastUserOrganisations,
id,
email,
auth_type,
)
}
className='btn-with-icon btn-remove'
>
Expand Down

0 comments on commit d1fe382

Please sign in to comment.