Move password confirmation to server side

This commit is contained in:
Garrow Bedrossian 2021-07-11 23:32:43 -04:00
parent c25e8eff9a
commit ce35f63c19
4 changed files with 31 additions and 26 deletions

View File

@ -3,9 +3,6 @@ import { Logo, Button, Input } from '@components/ui'
import { useUI } from '@components/ui/context' import { useUI } from '@components/ui/context'
import useCustomer from '@framework/customer/use-customer' import useCustomer from '@framework/customer/use-customer'
import useChangePassword from '@framework/auth/use-change-password' import useChangePassword from '@framework/auth/use-change-password'
import changePassword from '@framework/api/endpoints/change-password/change-password'
// import { validate } from 'email-validator'
interface Props { interface Props {
} }
@ -34,15 +31,26 @@ const ChangePassword: FC<Props> = () => {
const [disabled, setDisabled] = useState(false) const [disabled, setDisabled] = useState(false)
const { setModalView, closeModal } = useUI() const { setModalView, closeModal } = useUI()
const mismatchConfirmation = (newPassword !== confirmPassword) && newPassword !== ''
// // const login = useLogin() // // const login = useLogin()
// //
const handleChangePassword = async (e: React.SyntheticEvent<EventTarget>) => { const handleChangePassword = async (e: React.SyntheticEvent<EventTarget>) => {
console.log('handleChangePassword'); console.log('handleChangePassword');
e.preventDefault() e.preventDefault()
if (!dirty && !disabled) { // if (!dirty && !disabled) {
setDirty(true) setDirty(true)
handleValidation() handleValidation()
// }
if (newPassword !== confirmPassword) {
setDisabled(true)
setMessage('Passwords must match!')
return;
} else {
} }
try { try {
@ -51,7 +59,8 @@ const ChangePassword: FC<Props> = () => {
await changePassword({ await changePassword({
email, email,
currentPassword, currentPassword,
newPassword newPassword,
confirmPassword
}) })
setLoading(false) setLoading(false)
closeModal() closeModal()
@ -64,13 +73,14 @@ const ChangePassword: FC<Props> = () => {
} }
} }
// Halt unless the password is valid, and both new password fields match!
const handleValidation = useCallback(() => { const handleValidation = useCallback(() => {
// Test for Alphanumeric password // Test for Alphanumeric password
const validPassword = /^(?=.*[a-zA-Z])(?=.*[0-9])/.test(newPassword) const validPassword = /^(?=.*[a-zA-Z])(?=.*[0-9])/.test(newPassword)
// Unable to send form unless fields are valid. // Unable to send form unless fields are valid.
if (dirty) { if (dirty) {
setDisabled( newPassword.length < 7 || !validPassword ||newPassword != confirmPassword ) setDisabled( !validPassword || newPassword != confirmPassword )
} }
}, [newPassword, confirmPassword, dirty]) }, [newPassword, confirmPassword, dirty])
@ -89,25 +99,20 @@ const ChangePassword: FC<Props> = () => {
<div className='flex flex-col space-y-3'> <div className='flex flex-col space-y-3'>
{message && ( {message && (
<div className='text-red border border-red p-3'> <div className='text-red border border-red p-3'>
{message}. Did you {` `} {message}
<a
className='text-accent-9 inline font-bold hover:underline cursor-pointer'
onClick={() => setModalView('FORGOT_VIEW')}
>
forgot your password?
</a>
</div> </div>
)} )}
<Input type='email' disabled={true} value={email} /> <Input type='email' disabled={true} value={email} />
<Input type='password' autoComplete={'current-password'} placeholder='Current Password' onChange={setCurrentPassword} /> <Input type='password' autoComplete={'current-password'} placeholder='Current Password' onChange={setCurrentPassword} />
<Input type='password' autoComplete={'new-password'} placeholder='New Password' onChange={setNewPassword} /> <Input type='password' autoComplete={'new-password'} placeholder='New Password' onChange={setNewPassword} />
<Input type='password' autoComplete={'new-password'} placeholder='Confirm new Password' onChange={setConfirmPassword} /> <Input type='password' autoComplete={'new-password'} placeholder='Confirm new Password' onChange={setConfirmPassword} />
{ mismatchConfirmation && 'New password and confirmation must match.' }
<Button <Button
variant='slim' variant='slim'
type='submit' type='submit'
loading={loading} loading={loading}
disabled={disabled} disabled={disabled || mismatchConfirmation}
> >
Change Password Change Password
</Button> </Button>

View File

@ -3,17 +3,16 @@ import type { ChangePasswordEndpoint } from '.'
const changePassword: ChangePasswordEndpoint['handlers']['changePassword'] = async ({ const changePassword: ChangePasswordEndpoint['handlers']['changePassword'] = async ({
res, res,
body: { email, currentPassword, newPassword }, body: { email, currentPassword, newPassword, confirmPassword},
config, config,
commerce commerce
}) => { }) => {
// // TODO: Add proper validations with something like Ajv if (!(email && currentPassword && newPassword && confirmPassword)) {
// if (!(email && password)) { return res.status(400).json({
// return res.status(400).json({ data: null,
// data: null, errors: [{ message: 'Invalid request' }]
// errors: [{ message: 'Invalid request' }] })
// }) }
// }
// // TODO: validate the password and email // // TODO: validate the password and email
// // Passwords must be at least 7 characters and contain both alphabetic // // Passwords must be at least 7 characters and contain both alphabetic
// // and numeric characters. // // and numeric characters.

View File

@ -12,8 +12,8 @@ export const handler: MutationHook<ChangePasswordHook> = {
url: '/api/change-password', url: '/api/change-password',
method: 'POST', method: 'POST',
}, },
async fetcher({ input: { email, currentPassword, newPassword }, options, fetch }) { async fetcher({ input: { email, currentPassword, newPassword, confirmPassword }, options, fetch }) {
if (!(email && currentPassword && newPassword)) { if (!(email && currentPassword && newPassword && confirmPassword)) {
throw new CommerceError({ throw new CommerceError({
message: message:
'An email, current password, and new password are required to change password', 'An email, current password, and new password are required to change password',
@ -21,11 +21,11 @@ export const handler: MutationHook<ChangePasswordHook> = {
} }
console.log('fetcher') console.log('fetcher')
console.dir({ email, currentPassword, newPassword }) console.dir({ email, currentPassword, newPassword, confirmPassword })
return fetch({ return fetch({
...options, ...options,
body: { email, currentPassword, newPassword }, body: { email, currentPassword, newPassword, confirmPassword },
}) })
}, },
useHook: ({ fetch }) => () => { useHook: ({ fetch }) => () => {

View File

@ -2,6 +2,7 @@ export type ChangePasswordBody = {
email: string email: string
currentPassword: string currentPassword: string
newPassword: string newPassword: string
confirmPassword: string
} }
export type ChangePasswordTypes = { export type ChangePasswordTypes = {