mirror of
https://github.com/vercel/commerce.git
synced 2025-06-19 21:51: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 useCustomer from '@framework/customer/use-customer'
|
||||
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 {
|
||||
}
|
||||
@ -34,15 +31,26 @@ const ChangePassword: FC<Props> = () => {
|
||||
const [disabled, setDisabled] = useState(false)
|
||||
const { setModalView, closeModal } = useUI()
|
||||
|
||||
const mismatchConfirmation = (newPassword !== confirmPassword) && newPassword !== ''
|
||||
|
||||
// // const login = useLogin()
|
||||
//
|
||||
const handleChangePassword = async (e: React.SyntheticEvent<EventTarget>) => {
|
||||
console.log('handleChangePassword');
|
||||
e.preventDefault()
|
||||
|
||||
if (!dirty && !disabled) {
|
||||
// if (!dirty && !disabled) {
|
||||
setDirty(true)
|
||||
handleValidation()
|
||||
// }
|
||||
|
||||
if (newPassword !== confirmPassword) {
|
||||
setDisabled(true)
|
||||
setMessage('Passwords must match!')
|
||||
return;
|
||||
} else {
|
||||
|
||||
|
||||
}
|
||||
|
||||
try {
|
||||
@ -51,7 +59,8 @@ const ChangePassword: FC<Props> = () => {
|
||||
await changePassword({
|
||||
email,
|
||||
currentPassword,
|
||||
newPassword
|
||||
newPassword,
|
||||
confirmPassword
|
||||
})
|
||||
setLoading(false)
|
||||
closeModal()
|
||||
@ -64,13 +73,14 @@ const ChangePassword: FC<Props> = () => {
|
||||
}
|
||||
}
|
||||
|
||||
// Halt unless the password is valid, and both new password fields match!
|
||||
const handleValidation = useCallback(() => {
|
||||
// Test for Alphanumeric password
|
||||
const validPassword = /^(?=.*[a-zA-Z])(?=.*[0-9])/.test(newPassword)
|
||||
|
||||
// Unable to send form unless fields are valid.
|
||||
if (dirty) {
|
||||
setDisabled( newPassword.length < 7 || !validPassword ||newPassword != confirmPassword )
|
||||
setDisabled( !validPassword || newPassword != confirmPassword )
|
||||
}
|
||||
}, [newPassword, confirmPassword, dirty])
|
||||
|
||||
@ -89,25 +99,20 @@ const ChangePassword: FC<Props> = () => {
|
||||
<div className='flex flex-col space-y-3'>
|
||||
{message && (
|
||||
<div className='text-red border border-red p-3'>
|
||||
{message}. Did you {` `}
|
||||
<a
|
||||
className='text-accent-9 inline font-bold hover:underline cursor-pointer'
|
||||
onClick={() => setModalView('FORGOT_VIEW')}
|
||||
>
|
||||
forgot your password?
|
||||
</a>
|
||||
{message}
|
||||
</div>
|
||||
)}
|
||||
<Input type='email' disabled={true} value={email} />
|
||||
<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='Confirm new Password' onChange={setConfirmPassword} />
|
||||
{ mismatchConfirmation && 'New password and confirmation must match.' }
|
||||
|
||||
<Button
|
||||
variant='slim'
|
||||
type='submit'
|
||||
loading={loading}
|
||||
disabled={disabled}
|
||||
disabled={disabled || mismatchConfirmation}
|
||||
>
|
||||
Change Password
|
||||
</Button>
|
||||
|
@ -3,17 +3,16 @@ import type { ChangePasswordEndpoint } from '.'
|
||||
|
||||
const changePassword: ChangePasswordEndpoint['handlers']['changePassword'] = async ({
|
||||
res,
|
||||
body: { email, currentPassword, newPassword },
|
||||
body: { email, currentPassword, newPassword, confirmPassword},
|
||||
config,
|
||||
commerce
|
||||
}) => {
|
||||
// // TODO: Add proper validations with something like Ajv
|
||||
// if (!(email && password)) {
|
||||
// return res.status(400).json({
|
||||
// data: null,
|
||||
// errors: [{ message: 'Invalid request' }]
|
||||
// })
|
||||
// }
|
||||
if (!(email && currentPassword && newPassword && confirmPassword)) {
|
||||
return res.status(400).json({
|
||||
data: null,
|
||||
errors: [{ message: 'Invalid request' }]
|
||||
})
|
||||
}
|
||||
// // TODO: validate the password and email
|
||||
// // Passwords must be at least 7 characters and contain both alphabetic
|
||||
// // and numeric characters.
|
||||
|
@ -12,8 +12,8 @@ export const handler: MutationHook<ChangePasswordHook> = {
|
||||
url: '/api/change-password',
|
||||
method: 'POST',
|
||||
},
|
||||
async fetcher({ input: { email, currentPassword, newPassword }, options, fetch }) {
|
||||
if (!(email && currentPassword && newPassword)) {
|
||||
async fetcher({ input: { email, currentPassword, newPassword, confirmPassword }, options, fetch }) {
|
||||
if (!(email && currentPassword && newPassword && confirmPassword)) {
|
||||
throw new CommerceError({
|
||||
message:
|
||||
'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.dir({ email, currentPassword, newPassword })
|
||||
console.dir({ email, currentPassword, newPassword, confirmPassword })
|
||||
|
||||
return fetch({
|
||||
...options,
|
||||
body: { email, currentPassword, newPassword },
|
||||
body: { email, currentPassword, newPassword, confirmPassword },
|
||||
})
|
||||
},
|
||||
useHook: ({ fetch }) => () => {
|
||||
|
@ -2,6 +2,7 @@ export type ChangePasswordBody = {
|
||||
email: string
|
||||
currentPassword: string
|
||||
newPassword: string
|
||||
confirmPassword: string
|
||||
}
|
||||
|
||||
export type ChangePasswordTypes = {
|
||||
|
Loading…
x
Reference in New Issue
Block a user