fix(email-change): Complete the update and confirm email flow

This commit is contained in:
Bouncey
2018-08-30 15:36:26 +01:00
committed by mrugesh mohapatra
parent 3f4af667ef
commit 22b3f5890e
6 changed files with 172 additions and 12 deletions

View File

@ -152,7 +152,7 @@ module.exports = function enableAuthentication(app) {
'success',
'Success! You have signed in to your account. Happy Coding!'
);
return res.redirect(homeLocation);
return res.redirectWithFlash(`${homeLocation}/welcome`);
})
.subscribe(() => {}, next)
);

View File

@ -0,0 +1,3 @@
.control-label.email-label {
text-align: left;
}

141
src/pages/update-email.js Normal file
View File

@ -0,0 +1,141 @@
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { Link } from 'gatsby';
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import { createSelector } from 'reselect';
import {
Form,
FormGroup,
FormControl,
ControlLabel,
Grid,
Row,
Col,
Button
} from 'react-bootstrap';
import Layout from '../components/Layout';
import { Spacer } from '../components/helpers';
import './update-email.css';
import { userSelector, updateMyEmail } from '../redux';
import { isString } from 'lodash';
import isEmail from 'validator/lib/isEmail';
const propTypes = {
isNewEmail: PropTypes.bool,
updateMyEmail: PropTypes.func.isRequired
};
const mapStateToProps = createSelector(
userSelector,
({ email, emailVerified }) => ({
isNewEmail: !email || emailVerified
})
);
const mapDispatchToProps = dispatch =>
bindActionCreators({ updateMyEmail }, dispatch);
const maybeEmailRE = /[\w\.\+]*?@\w*?\.\w+?/;
class UpdateEmail extends Component {
constructor(props) {
super(props);
this.state = {
emailValue: ''
};
// this.createSubmitHandler = this.createSubmitHandler.bind(this);
this.onChange = this.onChange.bind(this);
}
createSubmitHandler(fn) {
return e => {
e.preventDefault();
return fn(this.state.emailValue);
};
}
onChange(e) {
const change = e.target.value;
if (!isString(change)) {
return null;
}
return this.setState({
emailValue: change
});
}
getEmailValidationState() {
const { emailValue } = this.state;
if (maybeEmailRE.test(emailValue)) {
return isEmail(emailValue) ? 'success' : 'error';
}
return null;
}
render() {
const { isNewEmail, updateMyEmail } = this.props;
return (
<Layout>
<Spacer />
<h2 className='text-center'>Update your email address here:</h2>
<Grid>
<Row>
<Col sm={6} smOffset={3}>
<Row>
<Form
horizontal={true}
onSubmit={this.createSubmitHandler(updateMyEmail)}
>
<FormGroup
controlId='emailInput'
validationState={this.getEmailValidationState()}
>
<Col
className='email-label'
componentClass={ControlLabel}
sm={2}
>
Email
</Col>
<Col sm={10}>
<FormControl
onChange={this.onChange}
placeholder='camperbot@example.com'
required={true}
type='email'
/>
</Col>
</FormGroup>
<Button
block={true}
bsSize='lg'
bsStyle='primary'
disabled={this.getEmailValidationState() !== 'success'}
type='submit'
>
{isNewEmail ? 'Update my Email' : 'Verify Email'}
</Button>
</Form>
<p className='text-center'>
<Link to='/signout'>Sign out</Link>
</p>
</Row>
</Col>
</Row>
</Grid>
</Layout>
);
}
}
UpdateEmail.displayName = 'Update-Email';
UpdateEmail.propTypes = propTypes;
export default connect(
mapStateToProps,
mapDispatchToProps
)(UpdateEmail);

View File

@ -0,0 +1,23 @@
import { call, put, takeEvery } from 'redux-saga/effects';
import { updateMyEmailComplete, updateMyEmailError } from './';
import { createFlashMessage } from '../components/Flash/redux';
import { putUserUpdateEmail } from '../utils/ajax';
function* updateMyEmailSaga({ payload: newEmail }) {
try {
const { data: response } = yield call(putUserUpdateEmail, newEmail);
yield put(updateMyEmailComplete());
yield put(createFlashMessage(response));
} catch (e) {
yield put(updateMyEmailError(e));
}
}
export function createUpdateMyEmailSaga(types) {
return [
takeEvery(types.updateMyEmail, updateMyEmailSaga)
];
}

View File

@ -14,13 +14,8 @@ function put(path, body) {
return axios.put(`${base}${path}`, body);
}
function sniff(things) {
console.log(things);
return things;
}
export function getSessionUser() {
return get('/user/get-session-user').then(sniff);
return get('/user/get-session-user');
}
export function putUserAcceptsTerms(quincyEmails) {

View File

@ -1,9 +1,7 @@
# signin redirects
# auth redirects
/signup /signin 301
/email-signin /signin 301
/login /signin 301
/deprecated-signin /signin 301
# signout redirects
/logout /signout 301
/passwordless-change /confirm-email 301