Skip to content
Snippets Groups Projects
Commit 9d2d63e4 authored by Alexandru Munteanu's avatar Alexandru Munteanu
Browse files

feat(reset-password): implement the reset password flow

parent 614cccd4
No related branches found
No related tags found
2 merge requests!13Sprint #14,!12Signup functionality
......@@ -41,9 +41,30 @@ const signUpUser = history => (values, dispatch) =>
})
.catch(handleFormError)
const resetUserPassword = history => ({ email }, dispatch) =>
create(`/users/forgot-password`, { email })
.then(r => {
// go to dedicated route
history.push('/')
})
.catch(handleFormError)
const setNewPassword = history => ({ email, token, password }, dispatch) =>
create(`/users/reset-password`, { email, token, password })
.then(() => {
login(dispatch, { username: email, password }, history).then(() =>
history.push('/'),
)
})
.catch(handleFormError)
export default compose(
withJournal,
withState('step', 'changeStep', 0),
withState(
'step',
'changeStep',
({ type }) => (type === 'forgotPassword' || type === 'setPassword' ? 1 : 0),
),
withProps(({ location }) => {
const params = new URLSearchParams(location.search)
const email = params.get('email') || ''
......@@ -67,13 +88,26 @@ export default compose(
withHandlers({
nextStep: ({ changeStep }) => () => changeStep(step => step + 1),
prevStep: ({ changeStep }) => () => changeStep(step => step - 1),
submitConfirmation: ({
confirmInvitation: ({
initialValues: { email = '', token = '' },
history,
}) => confirmUser(email, token, history),
signUp: ({ history }) => signUpUser(history),
forgotPassword: ({ history }) => resetUserPassword(history),
setNewPassword: ({ history }) => setNewPassword(history),
}),
withProps(({ type, signUp, submitConfirmation }) => ({
onSubmit: type === 'signup' ? signUp : submitConfirmation,
})),
withProps(
({ type, signUp, confirmInvitation, forgotPassword, setNewPassword }) => {
switch (type) {
case 'forgotPassword':
return { onSubmit: forgotPassword }
case 'signup':
return { onSubmit: signUp }
case 'setPassword':
return { onSubmit: setNewPassword }
default:
return { onSubmit: confirmInvitation }
}
},
),
)(SignUpInvitation)
import React from 'react'
import React, { Fragment } from 'react'
import { reduxForm } from 'redux-form'
import { required } from 'xpub-validators'
import { Button, ValidatedField, TextField } from '@pubsweet/ui'
......@@ -11,20 +11,43 @@ const { Row, Err, Label, RowItem, FormContainer } = FormItems
const PasswordField = input => <TextField {...input} type="password" />
const EmailField = input => <TextField {...input} type="email" />
const Step1 = ({ handleSubmit, error, type, prevStep, submitting }) => (
<FormContainer onSubmit={handleSubmit}>
{type === 'signup' && (
<Row>
<RowItem vertical>
<Label>Email</Label>
<ValidatedField
component={EmailField}
name="email"
validate={[required, emailValidator]}
/>
</RowItem>
</Row>
)}
const SignUpForm = () => (
<Fragment>
<Row>
<RowItem vertical>
<Label>Email</Label>
<ValidatedField
component={EmailField}
name="email"
validate={[required, emailValidator]}
/>
</RowItem>
</Row>
<Row>
<RowItem vertical>
<Label>Password</Label>
<ValidatedField
component={PasswordField}
name="password"
validate={[required]}
/>
</RowItem>
</Row>
<Row>
<RowItem vertical>
<Label>Confirm password</Label>
<ValidatedField
component={PasswordField}
name="confirmPassword"
validate={[required]}
/>
</RowItem>
</Row>
</Fragment>
)
const InviteForm = () => (
<Fragment>
<Row>
<RowItem vertical>
<Label>Password</Label>
......@@ -45,6 +68,37 @@ const Step1 = ({ handleSubmit, error, type, prevStep, submitting }) => (
/>
</RowItem>
</Row>
</Fragment>
)
const ForgotEmailForm = () => (
<Fragment>
<Row>
<RowItem vertical>
<Label>Email</Label>
<ValidatedField
component={EmailField}
name="email"
validate={[required, emailValidator]}
/>
</RowItem>
</Row>
</Fragment>
)
const withoutBack = ['forgotPassword', 'setPassword']
const Step1 = ({
error,
prevStep,
submitting,
handleSubmit,
type = 'invite',
}) => (
<FormContainer onSubmit={handleSubmit}>
{type === 'signup' && <SignUpForm />}
{type === 'setPassword' && <InviteForm />}
{type === 'forgotPassword' && <ForgotEmailForm />}
{type === 'invite' && <InviteForm />}
{error && (
<Row>
<RowItem>
......@@ -53,10 +107,13 @@ const Step1 = ({ handleSubmit, error, type, prevStep, submitting }) => (
</Row>
)}
<Row />
<Row>
<Button onClick={prevStep} type="button">
BACK
</Button>
{!withoutBack.includes(type) && (
<Button onClick={prevStep} type="button">
BACK
</Button>
)}
<Button disabled={submitting} primary type="submit">
CONFIRM
</Button>
......
......@@ -26,7 +26,7 @@ import {
import FaradayApp from './FaradayApp'
const LoginPage = withProps({ passwordReset: false })(Login)
const LoginPage = withProps({ passwordReset: true })(Login)
const PrivateRoute = ({ component: Component, ...rest }) => (
<Route
......@@ -43,6 +43,7 @@ const Routes = () => (
<FaradayApp>
<Switch>
<Route component={LoginPage} exact path="/login" />
<Route component={SignUpInvitationPage} exact path="/invite" />
<Route
component={routeParams => (
<SignUpInvitationPage
......@@ -55,6 +56,30 @@ const Routes = () => (
exact
path="/signup"
/>
<Route
component={routeParams => (
<SignUpInvitationPage
subtitle={null}
title="Reset password"
type="forgotPassword"
{...routeParams}
/>
)}
exact
path="/password-reset"
/>
<Route
component={routeParams => (
<SignUpInvitationPage
subtitle={null}
title="Set new password"
type="setPassword"
{...routeParams}
/>
)}
exact
path="/forgot-password"
/>
<Route component={ConfirmAccount} exact path="/confirm-signup" />
<PrivateRoute component={DashboardPage} exact path="/" />
<PrivateRoute
......@@ -75,7 +100,6 @@ const Routes = () => (
exact
path="/projects/:project/versions/:version/submit"
/>
<Route component={SignUpInvitationPage} exact path="/invite" />
<Route component={ReviewerSignUp} exact path="/invite-reviewer" />
<PrivateRoute
component={ManuscriptPage}
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment