Skip to content

Commit 0277681

Browse files
committed
fix: Add email confirmation field when deleting users with no password.
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.
1 parent 6d4b0c2 commit 0277681

File tree

2 files changed

+81
-23
lines changed

2 files changed

+81
-23
lines changed

frontend/web/components/modals/ConfirmDeleteAccount.tsx

+71-21
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import React, { FC, useEffect, useState } from 'react'
22
import Button from 'components/base/forms/Button'
33
import Utils from 'common/utils/utils'
4-
import { Organisation } from 'common/types/responses'
4+
import { AuthType, Organisation } from 'common/types/responses'
55
import { useDeleteAccountMutation } from 'common/services/useAccount'
66
import InputGroup from 'components/base/forms/InputGroup'
77
import ModalHR from './ModalHR'
@@ -10,13 +10,35 @@ import ErrorMessage from 'components/ErrorMessage'
1010

1111
type ConfirmDeleteAccountType = {
1212
lastUserOrganisations: Organisation[]
13+
email?: string
14+
auth_type?: AuthType
15+
}
16+
17+
const ERROR_MESSAGES = {
18+
default: 'Error deleting your account.',
19+
mismatchEmail:
20+
'Error deleting your account, please ensure you have entered your current email.',
21+
mismatchPassword:
22+
'Error deleting your account, please ensure you have entered your current password.',
1323
}
1424
const ConfirmDeleteAccount: FC<ConfirmDeleteAccountType> = ({
25+
auth_type,
26+
email,
1527
lastUserOrganisations,
1628
}) => {
1729
const [password, setPassword] = useState<string>('')
18-
const [deleteUserAccount, { isError, isSuccess: updateSuccess }] =
19-
useDeleteAccountMutation()
30+
const [currentEmail, setCurrentEmail] = useState<string>('')
31+
const [errorMessage, setErrorMessage] = useState<string>(
32+
ERROR_MESSAGES.default,
33+
)
34+
const [isEmailMismatchError, setIsEmailMismatchError] =
35+
useState<boolean>(false)
36+
const [
37+
deleteUserAccount,
38+
{ isError: isMutationError, isSuccess: updateSuccess },
39+
] = useDeleteAccountMutation()
40+
const skipPasswordConfirmation =
41+
auth_type === 'GOOGLE' || auth_type === 'GITHUB'
2042

2143
useEffect(() => {
2244
if (updateSuccess) {
@@ -54,6 +76,20 @@ const ConfirmDeleteAccount: FC<ConfirmDeleteAccountType> = ({
5476
<form
5577
onSubmit={(e) => {
5678
Utils.preventDefault(e)
79+
80+
if (skipPasswordConfirmation) {
81+
if (currentEmail !== email) {
82+
setIsEmailMismatchError(true)
83+
setErrorMessage(ERROR_MESSAGES.mismatchEmail)
84+
return
85+
} else {
86+
setIsEmailMismatchError(false)
87+
setErrorMessage(ERROR_MESSAGES.default)
88+
}
89+
} else {
90+
setErrorMessage(ERROR_MESSAGES.mismatchPassword)
91+
}
92+
5793
deleteUserAccount({
5894
current_password: password,
5995
delete_orphan_organisations: true,
@@ -64,26 +100,40 @@ const ConfirmDeleteAccount: FC<ConfirmDeleteAccountType> = ({
64100
<FormGroup>
65101
<ModalBody lastUserOrganisations={lastUserOrganisations} />
66102
</FormGroup>
67-
<InputGroup
68-
title='Confirm Password'
69-
className='mb-0'
70-
inputProps={{
71-
className: 'full-width',
72-
name: 'currentPassword',
73-
}}
74-
value={password}
75-
onChange={(event: React.ChangeEvent<HTMLInputElement>) => {
76-
setPassword(Utils.safeParseEventValue(event))
77-
}}
78-
type='password'
79-
name='password'
80-
/>
81-
{isError && (
82-
<ErrorMessage
83-
error='Error deleting your account, please ensure you have entered your
84-
current password.'
103+
{skipPasswordConfirmation ? (
104+
<InputGroup
105+
title='Confirm Email'
106+
className='mb-0'
107+
inputProps={{
108+
className: 'full-width',
109+
name: 'currentEmail',
110+
}}
111+
value={currentEmail}
112+
onChange={(event: React.ChangeEvent<HTMLInputElement>) => {
113+
setCurrentEmail(Utils.safeParseEventValue(event))
114+
}}
115+
type='email'
116+
name='currentEmail'
117+
/>
118+
) : (
119+
<InputGroup
120+
title='Confirm Password'
121+
className='mb-0'
122+
inputProps={{
123+
className: 'full-width',
124+
name: 'currentPassword',
125+
}}
126+
value={password}
127+
onChange={(event: React.ChangeEvent<HTMLInputElement>) => {
128+
setPassword(Utils.safeParseEventValue(event))
129+
}}
130+
type='password'
131+
name='password'
85132
/>
86133
)}
134+
{(isMutationError || isEmailMismatchError) && (
135+
<ErrorMessage error={errorMessage} />
136+
)}
87137
</div>
88138
<ModalHR />
89139
<div className='modal-footer'>

frontend/web/components/pages/AccountSettingsPage.js

+10-2
Original file line numberDiff line numberDiff line change
@@ -56,12 +56,14 @@ class TheComponent extends Component {
5656
})
5757
}
5858

59-
confirmDeleteAccount = (lastUserOrganisations, id) => {
59+
confirmDeleteAccount = (lastUserOrganisations, id, email, auth_type) => {
6060
openModal(
6161
'Are you sure?',
6262
<ConfirmDeleteAccount
6363
userId={id}
6464
lastUserOrganisations={lastUserOrganisations}
65+
email={email}
66+
auth_type={auth_type}
6567
/>,
6668
'p-0',
6769
)
@@ -126,6 +128,7 @@ class TheComponent extends Component {
126128
render() {
127129
const {
128130
state: {
131+
auth_type,
129132
current_password,
130133
email,
131134
error,
@@ -305,7 +308,12 @@ class TheComponent extends Component {
305308
id='delete-user-btn'
306309
data-test='delete-user-btn'
307310
onClick={() =>
308-
this.confirmDeleteAccount(lastUserOrganisations, id)
311+
this.confirmDeleteAccount(
312+
lastUserOrganisations,
313+
id,
314+
email,
315+
auth_type,
316+
)
309317
}
310318
className='btn-with-icon btn-remove'
311319
>

0 commit comments

Comments
 (0)