diff --git a/api-server/common/models/user.json b/api-server/common/models/user.json index a6e9f2ac4d6..80b1a66c26f 100644 --- a/api-server/common/models/user.json +++ b/api-server/common/models/user.json @@ -101,11 +101,11 @@ }, "acceptedPrivacyTerms": { "type": "boolean", - "default": true + "default": false }, "sendQuincyEmail": { "type": "boolean", - "default": true + "default": false }, "currentChallengeId": { "type": "string", diff --git a/api-server/server/component-passport.js b/api-server/server/component-passport.js index 2283a50e9cc..fa12146774b 100644 --- a/api-server/server/component-passport.js +++ b/api-server/server/component-passport.js @@ -140,7 +140,12 @@ we recommend using your email address: ${user.email} to sign in instead. setAccessTokenToResponse({ accessToken }, req, res); 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); }; diff --git a/client/src/components/layouts/Learn.js b/client/src/components/layouts/Learn.js index abf7e0cbdc8..96b3e2d4414 100644 --- a/client/src/components/layouts/Learn.js +++ b/client/src/components/layouts/Learn.js @@ -33,7 +33,7 @@ const mapDispatchToProps = { tryToShowDonationModal }; -const RedirectAcceptPrivacyTerm = createRedirect('/accept-privacy-terms'); +const RedirectEmailSignUp = createRedirect('/email-sign-up'); class LearnLayout extends Component { componentDidMount() { @@ -60,7 +60,7 @@ class LearnLayout extends Component { } if (isSignedIn && !acceptedPrivacyTerms) { - return ; + return ; } return ( diff --git a/client/src/pages/accept-privacy-terms.js b/client/src/pages/email-sign-up.js similarity index 57% rename from client/src/pages/accept-privacy-terms.js rename to client/src/pages/email-sign-up.js index db7908ec98e..95d6ef644ce 100644 --- a/client/src/pages/accept-privacy-terms.js +++ b/client/src/pages/email-sign-up.js @@ -13,7 +13,7 @@ import { import Helmet from 'react-helmet'; import { createSelector } from 'reselect'; -import { ButtonSpacer, Spacer, Link } from '../components/helpers'; +import { ButtonSpacer, Spacer } from '../components/helpers'; import { acceptTerms, userSelector } from '../redux'; import createRedirect from '../components/createRedirect'; @@ -31,16 +31,14 @@ const mapStateToProps = createSelector( ); const mapDispatchToProps = dispatch => bindActionCreators({ acceptTerms }, dispatch); -const RedirectHome = createRedirect('/'); +const RedirectToLearn = createRedirect('/learn'); class AcceptPrivacyTerms extends Component { constructor(props) { super(props); this.state = { - privacyPolicy: false, - termsOfService: false, - quincyEmail: true + quincyEmail: false }; this.createHandleChange = this.createHandleChange.bind(this); this.handleSubmit = this.handleSubmit.bind(this); @@ -55,74 +53,43 @@ class AcceptPrivacyTerms extends Component { handleSubmit(e) { e.preventDefault(); - const { privacyPolicy, termsOfService, quincyEmail } = this.state; - if (!privacyPolicy || !termsOfService) { - return null; - } + const { quincyEmail } = this.state; + 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() { const { acceptedPrivacyTerms } = this.props; if (acceptedPrivacyTerms) { - return ; + return ; } - const { privacyPolicy, termsOfService, quincyEmail } = this.state; + const { quincyEmail } = this.state; return ( - Privacy Policy and Terms of Service | freeCodeCamp.org + Email Sign Up | freeCodeCamp.org -

- Please review our updated privacy policy and the terms of service. -

+

Email Sign Up

- - - Terms of Service - - - - I accept the{' '} - - terms of service - {' '} - (required) - - - - - - Privacy Policy - - - - I accept the{' '} - - privacy policy - {' '} - (required) - - - Quincy's Emails @@ -142,7 +109,6 @@ class AcceptPrivacyTerms extends Component { block={true} bsStyle='primary' className='big-cta-btn' - disabled={!privacyPolicy || !termsOfService} type='submit' > Continue to freeCodeCamp.org diff --git a/client/src/redux/accept-terms-saga.js b/client/src/redux/accept-terms-saga.js index f8cb15ea696..af09e9c904a 100644 --- a/client/src/redux/accept-terms-saga.js +++ b/client/src/redux/accept-terms-saga.js @@ -10,7 +10,7 @@ function* acceptTermsSaga({ payload: quincyEmails }) { try { const { data: response } = yield call(putUserAcceptsTerms, quincyEmails); - yield put(acceptTermsComplete()); + yield put(acceptTermsComplete(quincyEmails)); yield put(createFlashMessage(response)); } catch (e) { yield put(acceptTermsError(e)); @@ -18,7 +18,7 @@ function* acceptTermsSaga({ payload: quincyEmails }) { } function* acceptCompleteSaga() { - yield call(navigate, '/'); + yield call(navigate, '/learn'); } export function createAcceptTermsSaga(types) { diff --git a/client/src/redux/index.js b/client/src/redux/index.js index 62f34750ffc..227c6f1b773 100644 --- a/client/src/redux/index.js +++ b/client/src/redux/index.js @@ -364,6 +364,27 @@ function spreadThePayloadOnUser(state, payload) { 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 => ({ ...state, canRequestBlockDonation: true