mirror of
https://github.com/elyby/accounts-frontend.git
synced 2024-11-27 17:22:07 +05:30
#26: incapsulate auth flow rejection logic into a separate component
This commit is contained in:
parent
b0a6740751
commit
4733b79d75
@ -11,7 +11,6 @@ export default class BaseAuthBody extends Component {
|
||||
static contextTypes = {
|
||||
clearErrors: PropTypes.func.isRequired,
|
||||
resolve: PropTypes.func.isRequired,
|
||||
reject: PropTypes.func.isRequired,
|
||||
auth: PropTypes.shape({
|
||||
error: PropTypes.string,
|
||||
scopes: PropTypes.array
|
||||
|
25
src/components/auth/RejectionLink.jsx
Normal file
25
src/components/auth/RejectionLink.jsx
Normal file
@ -0,0 +1,25 @@
|
||||
import React, { PropTypes } from 'react';
|
||||
|
||||
import { FormattedMessage as Message } from 'react-intl';
|
||||
|
||||
export default function RejectionLink(props, context) {
|
||||
return (
|
||||
<a href="#" onClick={(event) => {
|
||||
event.preventDefault();
|
||||
|
||||
context.reject();
|
||||
}}>
|
||||
<Message {...props.label} />
|
||||
</a>
|
||||
);
|
||||
}
|
||||
|
||||
RejectionLink.displayName = 'RejectionLink';
|
||||
RejectionLink.propTypes = {
|
||||
label: PropTypes.shape({
|
||||
id: PropTypes.string
|
||||
}).isRequired
|
||||
};
|
||||
RejectionLink.contextTypes = {
|
||||
reject: PropTypes.func.isRequired
|
||||
};
|
@ -1,8 +1,7 @@
|
||||
import React from 'react';
|
||||
|
||||
import { FormattedMessage as Message } from 'react-intl';
|
||||
|
||||
import { Button } from 'components/ui/form';
|
||||
import RejectionLink from 'components/auth/RejectionLink';
|
||||
import AuthTitle from 'components/auth/AuthTitle';
|
||||
|
||||
import messages from './Activation.intl.json';
|
||||
@ -13,10 +12,6 @@ export default function Activation() {
|
||||
Title: () => <AuthTitle title={messages.accountActivationTitle} />,
|
||||
Body,
|
||||
Footer: () => <Button color="blue" label={messages.confirmEmail} />,
|
||||
Links: () => (
|
||||
<a href="#">
|
||||
<Message {...messages.didNotReceivedEmail} />
|
||||
</a>
|
||||
)
|
||||
Links: () => <RejectionLink label={messages.didNotReceivedEmail} />
|
||||
};
|
||||
}
|
||||
|
@ -1,32 +1,17 @@
|
||||
import React, { PropTypes } from 'react';
|
||||
|
||||
import { FormattedMessage as Message } from 'react-intl';
|
||||
import React from 'react';
|
||||
|
||||
import { Button } from 'components/ui/form';
|
||||
import RejectionLink from 'components/auth/RejectionLink';
|
||||
import AuthTitle from 'components/auth/AuthTitle';
|
||||
|
||||
import Body from './ChangePasswordBody';
|
||||
import messages from './ChangePassword.intl.json';
|
||||
|
||||
export default function ChangePassword() {
|
||||
const componentsMap = {
|
||||
return {
|
||||
Title: () => <AuthTitle title={messages.changePasswordTitle} />,
|
||||
Body,
|
||||
Footer: () => <Button color="darkBlue" label={messages.change} />,
|
||||
Links: (props, context) => (
|
||||
<a href="#" onClick={(event) => {
|
||||
event.preventDefault();
|
||||
|
||||
context.reject();
|
||||
}}>
|
||||
<Message {...messages.skipThisStep} />
|
||||
</a>
|
||||
)
|
||||
Links: () => <RejectionLink label={messages.skipThisStep} />
|
||||
};
|
||||
|
||||
componentsMap.Links.contextTypes = {
|
||||
reject: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
return componentsMap;
|
||||
}
|
||||
|
@ -1,8 +1,7 @@
|
||||
import React from 'react';
|
||||
|
||||
import { FormattedMessage as Message } from 'react-intl';
|
||||
|
||||
import { Button } from 'components/ui/form';
|
||||
import RejectionLink from 'components/auth/RejectionLink';
|
||||
import AuthTitle from 'components/auth/AuthTitle';
|
||||
|
||||
import messages from './ForgotPassword.intl.json';
|
||||
@ -13,10 +12,6 @@ export default function ForgotPassword() {
|
||||
Title: () => <AuthTitle title={messages.forgotPasswordTitle} />,
|
||||
Body,
|
||||
Footer: () => <Button color="lightViolet" label={messages.sendMail} />,
|
||||
Links: () => (
|
||||
<a href="/send-message">
|
||||
<Message {...messages.contactSupport} />
|
||||
</a>
|
||||
)
|
||||
Links: () => <RejectionLink label={messages.contactSupport} />
|
||||
};
|
||||
}
|
||||
|
@ -1,9 +1,7 @@
|
||||
import React from 'react';
|
||||
|
||||
import { FormattedMessage as Message } from 'react-intl';
|
||||
import { Link } from 'react-router';
|
||||
|
||||
import { Button } from 'components/ui/form';
|
||||
import RejectionLink from 'components/auth/RejectionLink';
|
||||
import AuthTitle from 'components/auth/AuthTitle';
|
||||
|
||||
import Body from './PasswordBody';
|
||||
@ -14,10 +12,6 @@ export default function Password() {
|
||||
Title: () => <AuthTitle title={messages.passwordTitle} />,
|
||||
Body,
|
||||
Footer: () => <Button color="green" label={messages.signInButton} />,
|
||||
Links: () => (
|
||||
<Link to="/forgot-password">
|
||||
<Message {...messages.forgotPassword} />
|
||||
</Link>
|
||||
)
|
||||
Links: () => <RejectionLink label={messages.forgotPassword} />
|
||||
};
|
||||
}
|
||||
|
@ -1,32 +1,17 @@
|
||||
import React, { PropTypes } from 'react';
|
||||
|
||||
import { FormattedMessage as Message } from 'react-intl';
|
||||
import React from 'react';
|
||||
|
||||
import { Button } from 'components/ui/form';
|
||||
import RejectionLink from 'components/auth/RejectionLink';
|
||||
import AuthTitle from 'components/auth/AuthTitle';
|
||||
|
||||
import messages from './Permissions.intl.json';
|
||||
import Body from './PermissionsBody';
|
||||
|
||||
export default function Permissions() {
|
||||
const componentsMap = {
|
||||
return {
|
||||
Title: () => <AuthTitle title={messages.permissionsTitle} />,
|
||||
Body,
|
||||
Footer: () => <Button color="orange" autoFocus label={messages.approve} />,
|
||||
Links: (props, context) => (
|
||||
<a href="#" onClick={(event) => {
|
||||
event.preventDefault();
|
||||
|
||||
context.reject();
|
||||
}}>
|
||||
<Message {...messages.decline} />
|
||||
</a>
|
||||
)
|
||||
Links: () => <RejectionLink label={messages.decline} />
|
||||
};
|
||||
|
||||
componentsMap.Links.contextTypes = {
|
||||
reject: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
return componentsMap;
|
||||
}
|
||||
|
@ -1,8 +1,7 @@
|
||||
import React from 'react';
|
||||
|
||||
import { FormattedMessage as Message } from 'react-intl';
|
||||
|
||||
import { Button } from 'components/ui/form';
|
||||
import RejectionLink from 'components/auth/RejectionLink';
|
||||
import AuthTitle from 'components/auth/AuthTitle';
|
||||
import activationMessages from 'components/auth/activation/Activation.intl.json';
|
||||
|
||||
@ -14,10 +13,6 @@ export default function Register() {
|
||||
Title: () => <AuthTitle title={messages.registerTitle} />,
|
||||
Body,
|
||||
Footer: () => <Button color="blue" label={messages.signUpButton} />,
|
||||
Links: () => (
|
||||
<a href="#">
|
||||
<Message {...activationMessages.didNotReceivedEmail} />
|
||||
</a>
|
||||
)
|
||||
Links: () => <RejectionLink label={activationMessages.didNotReceivedEmail} />
|
||||
};
|
||||
}
|
||||
|
@ -20,7 +20,6 @@ import ChangePassword from 'components/auth/changePassword/ChangePassword';
|
||||
import ForgotPassword from 'components/auth/forgotPassword/ForgotPassword';
|
||||
import Finish from 'components/auth/finish/Finish';
|
||||
|
||||
|
||||
import authFlow from 'services/authFlow';
|
||||
|
||||
export default function routesFactory(store) {
|
||||
@ -46,15 +45,15 @@ export default function routesFactory(store) {
|
||||
|
||||
<Route path="oauth" component={OAuthInit} {...startAuthFlow} />
|
||||
|
||||
<Route path="auth" component={AuthPage} {...startAuthFlow}>
|
||||
<Route path="/login" components={new Login()} />
|
||||
<Route path="/password" components={new Password()} />
|
||||
<Route path="/register" components={new Register()} />
|
||||
<Route path="/activation" components={new Activation()} />
|
||||
<Route path="/oauth/permissions" components={new Permissions()} />
|
||||
<Route path="/oauth/finish" component={Finish} />
|
||||
<Route path="/change-password" components={new ChangePassword()} />
|
||||
<Route path="/forgot-password" components={new ForgotPassword()} />
|
||||
<Route path="auth" component={AuthPage}>
|
||||
<Route path="/login" components={new Login()} {...startAuthFlow} />
|
||||
<Route path="/password" components={new Password()} {...startAuthFlow} />
|
||||
<Route path="/register" components={new Register()} {...startAuthFlow} />
|
||||
<Route path="/activation" components={new Activation()} {...startAuthFlow} />
|
||||
<Route path="/oauth/permissions" components={new Permissions()} {...startAuthFlow} />
|
||||
<Route path="/oauth/finish" component={Finish} {...startAuthFlow} />
|
||||
<Route path="/change-password" components={new ChangePassword()} {...startAuthFlow} />
|
||||
<Route path="/forgot-password" components={new ForgotPassword()} {...startAuthFlow} />
|
||||
</Route>
|
||||
|
||||
<Route path="profile" component={ProfilePage} {...userOnly}>
|
||||
|
@ -1,6 +1,5 @@
|
||||
import AbstractState from './AbstractState';
|
||||
import PasswordState from './PasswordState';
|
||||
import ForgotPasswordState from './ForgotPasswordState';
|
||||
|
||||
export default class LoginState extends AbstractState {
|
||||
enter(context) {
|
||||
@ -17,8 +16,4 @@ export default class LoginState extends AbstractState {
|
||||
context.run('login', payload)
|
||||
.then(() => context.setState(new PasswordState()));
|
||||
}
|
||||
|
||||
reject(context) {
|
||||
context.setState(new ForgotPasswordState());
|
||||
}
|
||||
}
|
||||
|
@ -86,12 +86,4 @@ describe('LoginState', () => {
|
||||
return promise.catch(mock.verify.bind(mock));
|
||||
});
|
||||
});
|
||||
|
||||
describe('#reject', () => {
|
||||
it('should transition to forgot password state', () => {
|
||||
expectState(mock, ForgotPasswordState);
|
||||
|
||||
state.reject(context);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user