fix: redirect to email sign up on first login

This commit is contained in:
Oliver Eyton-Williams
2020-07-29 19:09:20 +02:00
committed by Mrugesh Mohapatra
parent 0642002005
commit 3dbe69707f
6 changed files with 53 additions and 61 deletions

View File

@ -101,11 +101,11 @@
}, },
"acceptedPrivacyTerms": { "acceptedPrivacyTerms": {
"type": "boolean", "type": "boolean",
"default": true "default": false
}, },
"sendQuincyEmail": { "sendQuincyEmail": {
"type": "boolean", "type": "boolean",
"default": true "default": false
}, },
"currentChallengeId": { "currentChallengeId": {
"type": "string", "type": "string",

View File

@ -140,7 +140,12 @@ we recommend using your email address: ${user.email} to sign in instead.
setAccessTokenToResponse({ accessToken }, req, res); setAccessTokenToResponse({ accessToken }, req, res);
req.login(user); req.login(user);
} }
return res.redirectWithFlash(redirect); // TODO: enable 'returnTo' for sign-up
if (user.acceptedPrivacyTerms) {
return res.redirectWithFlash(redirect);
} else {
return res.redirectWithFlash(`${homeLocation}/email-sign-up`);
}
} }
)(req, res, next); )(req, res, next);
}; };

View File

@ -33,7 +33,7 @@ const mapDispatchToProps = {
tryToShowDonationModal tryToShowDonationModal
}; };
const RedirectAcceptPrivacyTerm = createRedirect('/accept-privacy-terms'); const RedirectEmailSignUp = createRedirect('/email-sign-up');
class LearnLayout extends Component { class LearnLayout extends Component {
componentDidMount() { componentDidMount() {
@ -60,7 +60,7 @@ class LearnLayout extends Component {
} }
if (isSignedIn && !acceptedPrivacyTerms) { if (isSignedIn && !acceptedPrivacyTerms) {
return <RedirectAcceptPrivacyTerm />; return <RedirectEmailSignUp />;
} }
return ( return (

View File

@ -13,7 +13,7 @@ import {
import Helmet from 'react-helmet'; import Helmet from 'react-helmet';
import { createSelector } from 'reselect'; import { createSelector } from 'reselect';
import { ButtonSpacer, Spacer, Link } from '../components/helpers'; import { ButtonSpacer, Spacer } from '../components/helpers';
import { acceptTerms, userSelector } from '../redux'; import { acceptTerms, userSelector } from '../redux';
import createRedirect from '../components/createRedirect'; import createRedirect from '../components/createRedirect';
@ -31,16 +31,14 @@ const mapStateToProps = createSelector(
); );
const mapDispatchToProps = dispatch => const mapDispatchToProps = dispatch =>
bindActionCreators({ acceptTerms }, dispatch); bindActionCreators({ acceptTerms }, dispatch);
const RedirectHome = createRedirect('/'); const RedirectToLearn = createRedirect('/learn');
class AcceptPrivacyTerms extends Component { class AcceptPrivacyTerms extends Component {
constructor(props) { constructor(props) {
super(props); super(props);
this.state = { this.state = {
privacyPolicy: false, quincyEmail: false
termsOfService: false,
quincyEmail: true
}; };
this.createHandleChange = this.createHandleChange.bind(this); this.createHandleChange = this.createHandleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this); this.handleSubmit = this.handleSubmit.bind(this);
@ -55,74 +53,43 @@ class AcceptPrivacyTerms extends Component {
handleSubmit(e) { handleSubmit(e) {
e.preventDefault(); e.preventDefault();
const { privacyPolicy, termsOfService, quincyEmail } = this.state; const { quincyEmail } = this.state;
if (!privacyPolicy || !termsOfService) {
return null;
}
return this.props.acceptTerms(quincyEmail); return this.props.acceptTerms(quincyEmail);
} }
componentWillUnmount() {
// if a user navigates away from here we should set acceptedPrivacyTerms
// to true (so they do not get pulled back) without changing their email
// preferences (hence the null payload)
// This ensures the user has to click the checkbox and then click the
// 'Continue...' button to sign up.
if (!this.props.acceptedPrivacyTerms) {
this.props.acceptTerms(null);
}
}
render() { render() {
const { acceptedPrivacyTerms } = this.props; const { acceptedPrivacyTerms } = this.props;
if (acceptedPrivacyTerms) { if (acceptedPrivacyTerms) {
return <RedirectHome />; return <RedirectToLearn />;
} }
const { privacyPolicy, termsOfService, quincyEmail } = this.state; const { quincyEmail } = this.state;
return ( return (
<Fragment> <Fragment>
<Helmet> <Helmet>
<title>Privacy Policy and Terms of Service | freeCodeCamp.org</title> <title>Email Sign Up | freeCodeCamp.org</title>
</Helmet> </Helmet>
<Spacer size={2} /> <Spacer size={2} />
<Row className='text-center'> <Row className='text-center'>
<Col sm={8} smOffset={2} xs={12}> <Col sm={8} smOffset={2} xs={12}>
<h1> <h1>Email Sign Up </h1>
Please review our updated privacy policy and the terms of service.
</h1>
</Col> </Col>
</Row> </Row>
<Spacer size={2} /> <Spacer size={2} />
<Row> <Row>
<Col sm={8} smOffset={2} xs={12}> <Col sm={8} smOffset={2} xs={12}>
<form onSubmit={this.handleSubmit}> <form onSubmit={this.handleSubmit}>
<FormGroup>
<ControlLabel htmlFor='terms-of-service'>
Terms of Service
</ControlLabel>
<Spacer />
<Checkbox
checked={termsOfService}
id='terms-of-service'
inline={true}
onChange={this.createHandleChange('termsOfService')}
>
I accept the{' '}
<Link external={true} to='/news/terms-of-service'>
terms of service
</Link>{' '}
(required)
</Checkbox>
</FormGroup>
<Spacer />
<FormGroup>
<ControlLabel htmlFor='privacy-policy'>
Privacy Policy
</ControlLabel>
<Spacer />
<Checkbox
checked={privacyPolicy}
id='privacy-policy'
inline={true}
onChange={this.createHandleChange('privacyPolicy')}
>
I accept the{' '}
<Link external={true} to='/news/privacy-policy'>
privacy policy
</Link>{' '}
(required)
</Checkbox>
</FormGroup>
<Spacer />
<FormGroup> <FormGroup>
<ControlLabel htmlFor='quincy-email'> <ControlLabel htmlFor='quincy-email'>
Quincy's Emails Quincy's Emails
@ -142,7 +109,6 @@ class AcceptPrivacyTerms extends Component {
block={true} block={true}
bsStyle='primary' bsStyle='primary'
className='big-cta-btn' className='big-cta-btn'
disabled={!privacyPolicy || !termsOfService}
type='submit' type='submit'
> >
Continue to freeCodeCamp.org Continue to freeCodeCamp.org

View File

@ -10,7 +10,7 @@ function* acceptTermsSaga({ payload: quincyEmails }) {
try { try {
const { data: response } = yield call(putUserAcceptsTerms, quincyEmails); const { data: response } = yield call(putUserAcceptsTerms, quincyEmails);
yield put(acceptTermsComplete()); yield put(acceptTermsComplete(quincyEmails));
yield put(createFlashMessage(response)); yield put(createFlashMessage(response));
} catch (e) { } catch (e) {
yield put(acceptTermsError(e)); yield put(acceptTermsError(e));
@ -18,7 +18,7 @@ function* acceptTermsSaga({ payload: quincyEmails }) {
} }
function* acceptCompleteSaga() { function* acceptCompleteSaga() {
yield call(navigate, '/'); yield call(navigate, '/learn');
} }
export function createAcceptTermsSaga(types) { export function createAcceptTermsSaga(types) {

View File

@ -364,6 +364,27 @@ function spreadThePayloadOnUser(state, payload) {
export const reducer = handleActions( export const reducer = handleActions(
{ {
[types.acceptTermsComplete]: (state, { payload }) => {
const { appUsername } = state;
return {
...state,
user: {
...state.user,
[appUsername]: {
...state.user[appUsername],
// TODO: the user accepts the privacy terms in practice during auth
// however, it's currently being used to track if they've accepted
// or rejected the newsletter. Ideally this should be migrated,
// since they can't sign up without accepting the terms.
acceptedPrivacyTerms: true,
sendQuincyEmail:
payload === null
? state.user[appUsername].sendQuincyEmail
: payload
}
}
};
},
[types.allowBlockDonationRequests]: state => ({ [types.allowBlockDonationRequests]: state => ({
...state, ...state,
canRequestBlockDonation: true canRequestBlockDonation: true