Skip to content

Commit

Permalink
feat(email-settings): Add email settings
Browse files Browse the repository at this point in the history
  • Loading branch information
Bouncey committed Sep 21, 2018
1 parent 147e61e commit 2de2143
Show file tree
Hide file tree
Showing 11 changed files with 420 additions and 139 deletions.
93 changes: 42 additions & 51 deletions api-server/common/models/User-Identity.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import { wrapHandledError } from '../../server/utils/create-handled-error.js';
// const log = debug('fcc:models:userIdent');

export default function(UserIdent) {

UserIdent.on('dataSourceAttached', () => {
UserIdent.findOne$ = observeMethod(UserIdent, 'findOne');
});
Expand All @@ -33,7 +32,7 @@ export default function(UserIdent) {
// get the social provider data and the external id from auth0
profile.id = profile.id || profile.openid;
const auth0IdString = '' + profile.id;
const [ provider, socialExtId ] = auth0IdString.split('|');
const [provider, socialExtId] = auth0IdString.split('|');
const query = {
where: {
provider: provider,
Expand All @@ -42,8 +41,10 @@ export default function(UserIdent) {
include: 'user'
};
// get the email from the auth0 (its expected from social providers)
const email = (profile && profile.emails && profile.emails[0]) ?
profile.emails[0].value : '';
const email =
profile && profile.emails && profile.emails[0]
? profile.emails[0].value
: '';
if (!isEmail('' + email)) {
throw wrapHandledError(
new Error('invalid or empty email recieved from auth0'),
Expand All @@ -60,12 +61,11 @@ export default function(UserIdent) {
}

if (provider === 'email') {

return User.findOne$({ where: { email } })
.flatMap(user => {
return user ?
Observable.of(user) :
User.create$({ email }).toPromise();
return user
? Observable.of(user)
: User.create$({ email }).toPromise();
})
.flatMap(user => {
if (!user) {
Expand All @@ -81,56 +81,51 @@ export default function(UserIdent) {
}
);
}
const createToken = observeQuery(
AccessToken,
'create',
{
userId: user.id,
created: new Date(),
ttl: user.constructor.settings.ttl
}
);
const updateUser = user.update$({
emailVerified: true,
emailAuthLinkTTL: null,
emailVerifyTTL: null
const createToken = observeQuery(AccessToken, 'create', {
userId: user.id,
created: new Date(),
ttl: user.constructor.settings.ttl
});
const updateUserPromise = new Promise((resolve, reject) =>
user.updateAttributes(
{
emailVerified: true,
emailAuthLinkTTL: null,
emailVerifyTTL: null
},
err => {
if (err) {
return reject(err);
}
return resolve();
}
)
);
return Observable.combineLatest(
Observable.of(user),
createToken,
updateUser,
(user, token) => ({user, token})
Observable.fromPromise(updateUserPromise),
(user, token) => ({ user, token })
);
})
.subscribe(
({ user, token }) => cb(null, user, null, token),
cb
);

.subscribe(({ user, token }) => cb(null, user, null, token), cb);
} else {

return UserIdent.findOne$(query)
.flatMap(identity => {
return identity ?
Observable.of(identity.user()) :
User.findOne$({ where: { email } })
.flatMap(user => {
return user ?
Observable.of(user) :
User.create$({ email }).toPromise();
return identity
? Observable.of(identity.user())
: User.findOne$({ where: { email } }).flatMap(user => {
return user
? Observable.of(user)
: User.create$({ email }).toPromise();
});
})
.flatMap(user => {

const createToken = observeQuery(
AccessToken,
'create',
{
userId: user.id,
created: new Date(),
ttl: user.constructor.settings.ttl
}
);
const createToken = observeQuery(AccessToken, 'create', {
userId: user.id,
created: new Date(),
ttl: user.constructor.settings.ttl
});
const updateUser = user.update$({
email: email,
emailVerified: true,
Expand All @@ -144,11 +139,7 @@ export default function(UserIdent) {
(user, token) => ({ user, token })
);
})
.subscribe(
({ user, token }) => cb(null, user, null, token),
cb
);

.subscribe(({ user, token }) => cb(null, user, null, token), cb);
}
};
}
18 changes: 11 additions & 7 deletions api-server/common/models/user.js
Original file line number Diff line number Diff line change
Expand Up @@ -614,10 +614,8 @@ module.exports = function(User) {
this.update$({ emailAuthLinkTTL })
);
})
.map(() =>
dedent`
Check your email and click the link we sent you to confirm you email.
`
.map(() => 'Check your email and click the link we sent you to confirm' +
' your new email address.'
);
}

Expand Down Expand Up @@ -691,12 +689,18 @@ module.exports = function(User) {
}
})
.flatMap(()=>{
const updatePromise = new Promise((resolve, reject) =>
this.updateAttributes(updateConfig, err => {
if (err) {
return reject(err);
}
return resolve();
}));
return Observable.forkJoin(
this.update$(updateConfig),
Observable.fromPromise(updatePromise),
this.requestAuthEmail(false, newEmail),
(_, message) => message
)
.doOnNext(() => this.manualReload());
);
});

} else {
Expand Down
6 changes: 2 additions & 4 deletions api-server/server/middlewares/email-not-verified-notice.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,12 @@ import dedent from 'dedent';

const ALLOWED_METHODS = ['GET'];
const EXCLUDED_PATHS = [
'/api/flyers/findOne',
'/signout',
'/accept-privacy-terms',
'/update-email',
'/confirm-email',
'/passwordless-change',
'/external/services/user'
];
'/passwordless-change'
].reduce((list, item) => [...list, item, `/internal${item}`], []);

export default function emailNotVerifiedNotice() {
return function(req, res, next) {
Expand Down
44 changes: 38 additions & 6 deletions client/src/client-only-routes/ShowSettings.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,25 @@ import { submitNewAbout, updateUserFlag } from '../redux/settings';
import Layout from '../components/Layout';
import Spacer from '../components/helpers/Spacer';
import Loader from '../components/helpers/Loader';
import { FullWidthRow } from '../components/helpers';
import FullWidthRow from '../components/helpers/FullWidthRow';
import About from '../components/settings/About';
import Privacy from '../components/settings/Privacy';
import Email from '../components/settings/Email';

const propTypes = {
about: PropTypes.string,
email: PropTypes.string,
isEmailVerified: PropTypes.bool,
location: PropTypes.string,
name: PropTypes.string,
picture: PropTypes.string,
points: PropTypes.number,
sendQuincyEmail: PropTypes.bool,
showLoading: PropTypes.bool,
submitNewAbout: PropTypes.func.isRequired,
theme: PropTypes.string,
toggleNightMode: PropTypes.func.isRequired,
updateQuincyEmail: PropTypes.func.isRequired,
username: PropTypes.string
};

Expand All @@ -34,8 +39,22 @@ const mapStateToProps = createSelector(
userSelector,
(
showLoading,
{ username = '', about, picture, points, name, location, theme }
{
username = '',
about,
email,
sendQuincyEmail,
isEmailVerified,
picture,
points,
name,
location,
theme
}
) => ({
email,
sendQuincyEmail,
isEmailVerified,
showLoading,
username,
about,
Expand All @@ -49,12 +68,19 @@ const mapStateToProps = createSelector(

const mapDispatchToProps = dispatch =>
bindActionCreators(
{ submitNewAbout, toggleNightMode: theme => updateUserFlag({theme}) },
{
submitNewAbout,
toggleNightMode: theme => updateUserFlag({ theme }),
updateQuincyEmail: sendQuincyEmail => updateUserFlag({ sendQuincyEmail })
},
dispatch
);

function ShowSettings(props) {
const {
email,
isEmailVerified,
sendQuincyEmail,
showLoading,
username,
about,
Expand All @@ -64,7 +90,8 @@ function ShowSettings(props) {
location,
name,
submitNewAbout,
toggleNightMode
toggleNightMode,
updateQuincyEmail
} = props;

if (showLoading) {
Expand Down Expand Up @@ -120,9 +147,14 @@ function ShowSettings(props) {
<Spacer />
<Privacy />
<Spacer />
{/* <EmailSettings />
<Email
email={email}
isEmailVerified={isEmailVerified}
sendQuincyEmail={sendQuincyEmail}
updateQuincyEmail={updateQuincyEmail}
/>
<Spacer />
<InternetSettings />
{/* <InternetSettings />
<Spacer />
<PortfolioSettings />
<Spacer />
Expand Down
Loading

0 comments on commit 2de2143

Please sign in to comment.