#125: support activation key in url

This commit is contained in:
SleepWalker 2016-06-05 15:16:41 +03:00
parent 2737c6502b
commit 64089bc7ab
5 changed files with 41 additions and 7 deletions

View File

@ -1,4 +1,4 @@
import React from 'react';
import React, { PropTypes } from 'react';
import { FormattedMessage as Message } from 'react-intl';
@ -12,9 +12,17 @@ export default class ActivationBody extends BaseAuthBody {
static displayName = 'ActivationBody';
static panelId = 'activation';
autoFocusField = 'key';
static propTypes = {
params: PropTypes.shape({
key: PropTypes.string
})
};
autoFocusField = this.props.params && this.props.params.key ? null : 'key';
render() {
const {key} = this.props.params;
return (
<div>
{this.renderErrors()}
@ -33,6 +41,9 @@ export default class ActivationBody extends BaseAuthBody {
color="blue"
style={{textAlign: 'center'}}
required
value={key}
readOnly={!!key}
autoComplete="off"
placeholder={messages.enterTheCode}
/>
</div>

View File

@ -35,7 +35,7 @@ export default function routesFactory(store) {
};
const userOnly = {
onEnter: ({location}, replace) => {
onEnter: (nextState, replace) => {
const {user} = store.getState();
if (user.isGuest) {
@ -56,7 +56,7 @@ export default function routesFactory(store) {
<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="/activation(/:key)" components={new Activation()} {...startAuthFlow} />
<Route path="/resend-activation" components={new ResendActivation()} {...startAuthFlow} />
<Route path="/oauth/permissions" components={new Permissions()} {...startAuthFlow} />
<Route path="/oauth/finish" component={Finish} {...startAuthFlow} />

View File

@ -4,12 +4,15 @@ import ResendActivationState from './ResendActivationState';
export default class ActivationState extends AbstractState {
enter(context) {
const {user} = context.getState();
const {user, routing} = context.getState();
if (user.isActive) {
context.setState(new CompleteState());
} else {
context.navigate('/activation');
const url = routing.location.pathname.includes('/activation')
? routing.location.pathname
: '/activation';
context.navigate(url);
}
}

View File

@ -7,7 +7,7 @@ export default class RecoverPasswordState extends AbstractState {
const {user, routing} = context.getState();
if (user.isGuest) {
const url = routing.location.pathname.indexOf('/recover-password') === 0
const url = routing.location.pathname.includes('/recover-password')
? routing.location.pathname
: '/recover-password';
context.navigate(url);

View File

@ -23,9 +23,13 @@ describe('ActivationState', () => {
describe('#enter', () => {
it('should navigate to /activation', () => {
const expectedPath = '/activation';
context.getState.returns({
user: {
isActive: false
},
routing: {
location: {pathname: expectedPath}
}
});
@ -34,6 +38,22 @@ describe('ActivationState', () => {
state.enter(context);
});
it('should navigate to /activation/key', () => {
const expectedPath = '/activation/sasx5AS4d61';
context.getState.returns({
user: {
isActive: false
},
routing: {
location: {pathname: expectedPath}
}
});
expectNavigate(mock, expectedPath);
state.enter(context);
});
it('should transition to complete state if account activated', () => {
context.getState.returns({
user: {