mirror of
https://github.com/vercel/commerce.git
synced 2025-06-20 06:01:21 +00:00
Move password confirmation to server side
This commit is contained in:
parent
c25e8eff9a
commit
ce35f63c19
@ -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>
|
||||||
|
@ -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.
|
||||||
|
@ -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 }) => () => {
|
||||||
|
@ -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 = {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user