@ -506,7 +506,7 @@ a[href="/email-signup"], a[href="/email-signin"] {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
form.email-update .btn{
|
form.update-email .btn{
|
||||||
margin:0;
|
margin:0;
|
||||||
width:40%;
|
width:40%;
|
||||||
display:inline-block;
|
display:inline-block;
|
||||||
|
@ -12,21 +12,11 @@ const { defaultProfileImage } = require('../utils/constantStrings.json');
|
|||||||
const githubRegex = (/github/i);
|
const githubRegex = (/github/i);
|
||||||
const debug = debugFactory('fcc:models:userIdent');
|
const debug = debugFactory('fcc:models:userIdent');
|
||||||
|
|
||||||
function createAccessToken(user, ttl, cb) {
|
|
||||||
if (arguments.length === 2 && typeof ttl === 'function') {
|
|
||||||
cb = ttl;
|
|
||||||
ttl = 0;
|
|
||||||
}
|
|
||||||
user.accessTokens.create({
|
|
||||||
created: new Date(),
|
|
||||||
ttl: Math.min(ttl || user.constructor.settings.ttl,
|
|
||||||
user.constructor.settings.maxTTL)
|
|
||||||
}, cb);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default function(UserIdent) {
|
export default function(UserIdent) {
|
||||||
// original source
|
// original source
|
||||||
// github.com/strongloop/loopback-component-passport
|
// github.com/strongloop/loopback-component-passport
|
||||||
|
const createAccountMessage =
|
||||||
|
'Accounts can only be created using GitHub or though email';
|
||||||
UserIdent.login = function(
|
UserIdent.login = function(
|
||||||
provider,
|
provider,
|
||||||
authScheme,
|
authScheme,
|
||||||
@ -40,96 +30,93 @@ export default function(UserIdent) {
|
|||||||
cb = options;
|
cb = options;
|
||||||
options = {};
|
options = {};
|
||||||
}
|
}
|
||||||
var autoLogin = options.autoLogin || !options.autoLogin;
|
const userIdentityModel = UserIdent;
|
||||||
var userIdentityModel = UserIdent;
|
|
||||||
profile.id = profile.id || profile.openid;
|
profile.id = profile.id || profile.openid;
|
||||||
userIdentityModel.findOne({
|
const filter = {
|
||||||
where: {
|
where: {
|
||||||
provider: getSocialProvider(provider),
|
provider: getSocialProvider(provider),
|
||||||
externalId: profile.id
|
externalId: profile.id
|
||||||
}
|
}
|
||||||
}, function(err, identity) {
|
};
|
||||||
if (err) {
|
return userIdentityModel.findOne(filter)
|
||||||
return cb(err);
|
.then(identity => {
|
||||||
}
|
// identity already exists
|
||||||
if (identity) {
|
// find user and log them in
|
||||||
identity.credentials = credentials;
|
if (identity) {
|
||||||
return identity.updateAttributes({
|
identity.credentials = credentials;
|
||||||
profile: profile,
|
const options = {
|
||||||
credentials: credentials,
|
profile: profile,
|
||||||
modified: new Date()
|
credentials: credentials,
|
||||||
}, function(err) {
|
modified: new Date()
|
||||||
if (err) {
|
};
|
||||||
return cb(err);
|
return identity.updateAttributes(options)
|
||||||
}
|
// grab user associated with identity
|
||||||
// Find the user for the given identity
|
.then(() => identity.user())
|
||||||
return identity.user(function(err, user) {
|
.then(user => {
|
||||||
// Create access token if the autoLogin flag is set to true
|
// Create access token for user
|
||||||
if (!err && user && autoLogin) {
|
const options = {
|
||||||
return (options.createAccessToken || createAccessToken)(
|
created: new Date(),
|
||||||
user,
|
ttl: user.constructor.settings.ttl
|
||||||
function(err, token) {
|
};
|
||||||
cb(err, user, identity, token);
|
return user.accessTokens.create(options)
|
||||||
}
|
.then(token => ({ user, token }));
|
||||||
);
|
})
|
||||||
}
|
.then(({ token, user })=> {
|
||||||
return cb(err, user, identity);
|
cb(null, user, identity, token);
|
||||||
});
|
})
|
||||||
});
|
.catch(err => cb(err));
|
||||||
}
|
|
||||||
// Find the user model
|
|
||||||
var userModel = userIdentityModel.relations.user &&
|
|
||||||
userIdentityModel.relations.user.modelTo ||
|
|
||||||
loopback.getModelByType(loopback.User);
|
|
||||||
|
|
||||||
var userObj = options.profileToUser(provider, profile, options);
|
|
||||||
|
|
||||||
if (!userObj.email && !options.emailOptional) {
|
|
||||||
process.nextTick(function() {
|
|
||||||
return cb('email is missing from the user profile');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
var query;
|
|
||||||
if (userObj.email) {
|
|
||||||
query = { or: [
|
|
||||||
{ username: userObj.username },
|
|
||||||
{ email: userObj.email }
|
|
||||||
]};
|
|
||||||
} else {
|
|
||||||
query = { username: userObj.username };
|
|
||||||
}
|
|
||||||
return userModel.findOrCreate({ where: query }, userObj, (err, user) => {
|
|
||||||
if (err) {
|
|
||||||
return cb(err);
|
|
||||||
}
|
}
|
||||||
var date = new Date();
|
// Find the user model
|
||||||
return userIdentityModel.create({
|
const userModel = userIdentityModel.relations.user &&
|
||||||
provider: getSocialProvider(provider),
|
userIdentityModel.relations.user.modelTo ||
|
||||||
externalId: profile.id,
|
loopback.getModelByType(loopback.User);
|
||||||
authScheme: authScheme,
|
|
||||||
profile: profile,
|
const userObj = options.profileToUser(provider, profile, options);
|
||||||
credentials: credentials,
|
if (getSocialProvider(provider) !== 'github') {
|
||||||
userId: user.id,
|
const err = new Error(createAccountMessage);
|
||||||
created: date,
|
err.userMessage = createAccountMessage;
|
||||||
modified: date
|
err.messageType = 'info';
|
||||||
}, function(err, identity) {
|
err.redirectTo = '/signin';
|
||||||
if (!err && user && autoLogin) {
|
return process.nextTick(() => cb(err));
|
||||||
return (options.createAccessToken || createAccessToken)(
|
}
|
||||||
user,
|
|
||||||
function(err, token) {
|
let query;
|
||||||
cb(err, user, identity, token);
|
if (userObj.email) {
|
||||||
}
|
query = { or: [
|
||||||
);
|
{ username: userObj.username },
|
||||||
}
|
{ email: userObj.email }
|
||||||
return cb(err, user, identity);
|
]};
|
||||||
});
|
} else {
|
||||||
|
query = { username: userObj.username };
|
||||||
|
}
|
||||||
|
return userModel.findOrCreate({ where: query }, userObj)
|
||||||
|
.then(([ user ]) => {
|
||||||
|
const promises = [
|
||||||
|
userIdentityModel.create({
|
||||||
|
provider: getSocialProvider(provider),
|
||||||
|
externalId: profile.id,
|
||||||
|
authScheme: authScheme,
|
||||||
|
profile: profile,
|
||||||
|
credentials: credentials,
|
||||||
|
userId: user.id,
|
||||||
|
created: new Date(),
|
||||||
|
modified: new Date()
|
||||||
|
}),
|
||||||
|
user.accessTokens.create({
|
||||||
|
created: new Date(),
|
||||||
|
ttl: user.constructor.settings.ttl
|
||||||
|
})
|
||||||
|
];
|
||||||
|
return Promise.all(promises)
|
||||||
|
.then(([ identity, token ]) => ({ user, identity, token }));
|
||||||
|
})
|
||||||
|
.then(({ user, token, identity }) => cb(null, user, identity, token))
|
||||||
|
.catch(err => cb(err));
|
||||||
});
|
});
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
UserIdent.observe('before save', function(ctx, next) {
|
UserIdent.observe('before save', function(ctx, next) {
|
||||||
var userIdent = ctx.currentInstance || ctx.instance;
|
const userIdent = ctx.currentInstance || ctx.instance;
|
||||||
if (!userIdent) {
|
if (!userIdent) {
|
||||||
debug('no user identity instance found');
|
debug('no user identity instance found');
|
||||||
return next();
|
return next();
|
||||||
|
@ -41,6 +41,8 @@ module.exports = function(User) {
|
|||||||
User.definition.properties.rand.default = function() {
|
User.definition.properties.rand.default = function() {
|
||||||
return Math.random();
|
return Math.random();
|
||||||
};
|
};
|
||||||
|
// increase user accessToken ttl to 900 days
|
||||||
|
User.settings.ttl = 900 * 24 * 60 * 60 * 1000;
|
||||||
|
|
||||||
// username should not be in blacklist
|
// username should not be in blacklist
|
||||||
User.validatesExclusionOf('username', {
|
User.validatesExclusionOf('username', {
|
||||||
|
@ -241,7 +241,7 @@ module.exports = function(app) {
|
|||||||
if (!req.user) {
|
if (!req.user) {
|
||||||
return res.redirect('/');
|
return res.redirect('/');
|
||||||
}
|
}
|
||||||
return res.render('account/email-update', {
|
return res.render('account/update-email', {
|
||||||
title: 'Update your Email'
|
title: 'Update your Email'
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -13,18 +13,18 @@ import {
|
|||||||
const passportOptions = {
|
const passportOptions = {
|
||||||
emailOptional: true,
|
emailOptional: true,
|
||||||
profileToUser(provider, profile) {
|
profileToUser(provider, profile) {
|
||||||
var emails = profile.emails;
|
const emails = profile.emails;
|
||||||
// NOTE(berks): get email or set to null.
|
// NOTE(berks): get email or set to null.
|
||||||
// MongoDB indexs email but can be sparse(blank)
|
// MongoDB indexs email but can be sparse(blank)
|
||||||
var email = emails && emails[0] && emails[0].value ?
|
const email = emails && emails[0] && emails[0].value ?
|
||||||
emails[0].value :
|
emails[0].value :
|
||||||
null;
|
null;
|
||||||
|
|
||||||
// create random username
|
// create random username
|
||||||
// username will be assigned when camper signups for Github
|
// username will be assigned when camper signups for Github
|
||||||
var username = 'fcc' + uuid.v4().slice(0, 8);
|
const username = 'fcc' + uuid.v4().slice(0, 8);
|
||||||
var password = generateKey('password');
|
const password = generateKey('password');
|
||||||
var userObj = {
|
let userObj = {
|
||||||
username: username,
|
username: username,
|
||||||
password: password
|
password: password
|
||||||
};
|
};
|
||||||
@ -41,7 +41,7 @@ const passportOptions = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (/github/.test(provider)) {
|
if (/github/.test(provider)) {
|
||||||
setProfileFromGithub(userObj, profile, profile._json);
|
userObj = setProfileFromGithub(userObj, profile, profile._json);
|
||||||
}
|
}
|
||||||
return userObj;
|
return userObj;
|
||||||
}
|
}
|
||||||
|
@ -25,11 +25,11 @@ export default function prodErrorHandler() {
|
|||||||
var message = 'Oops! Something went wrong. Please try again later';
|
var message = 'Oops! Something went wrong. Please try again later';
|
||||||
if (type === 'html') {
|
if (type === 'html') {
|
||||||
if (typeof req.flash === 'function') {
|
if (typeof req.flash === 'function') {
|
||||||
req.flash('errors', {
|
req.flash(err.messageType || 'errors', {
|
||||||
msg: message
|
msg: err.userMessage || message
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return res.redirect('/map');
|
return res.redirect(err.redirectTo || '/map');
|
||||||
// json
|
// json
|
||||||
} else if (type === 'json') {
|
} else if (type === 'json') {
|
||||||
res.setHeader('Content-Type', 'application/json');
|
res.setHeader('Content-Type', 'application/json');
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
import assign from 'object.assign';
|
|
||||||
|
|
||||||
const providerHash = {
|
const providerHash = {
|
||||||
facebook: ({ id }) => id,
|
facebook: ({ id }) => id,
|
||||||
twitter: ({ username }) => username,
|
twitter: ({ username }) => username,
|
||||||
@ -32,15 +30,16 @@ export function setProfileFromGithub(
|
|||||||
name
|
name
|
||||||
}
|
}
|
||||||
) {
|
) {
|
||||||
return assign(
|
return Object.assign(
|
||||||
user,
|
user,
|
||||||
{ isGithubCool: true, isMigrationGrandfathered: false },
|
|
||||||
{
|
{
|
||||||
name,
|
name,
|
||||||
|
email: user.email || githubEmail,
|
||||||
username: username.toLowerCase(),
|
username: username.toLowerCase(),
|
||||||
location,
|
location,
|
||||||
joinedGithubOn,
|
joinedGithubOn,
|
||||||
website,
|
website,
|
||||||
|
isGithubCool: true,
|
||||||
picture,
|
picture,
|
||||||
githubId,
|
githubId,
|
||||||
githubURL,
|
githubURL,
|
||||||
|
@ -54,7 +54,7 @@ block content
|
|||||||
p.large-p.text-center
|
p.large-p.text-center
|
||||||
em #{user.email}
|
em #{user.email}
|
||||||
.col-xs-12
|
.col-xs-12
|
||||||
a.btn.btn-lg.btn-block.btn-primary.btn-link-social(href='/email-update')
|
a.btn.btn-lg.btn-block.btn-primary.btn-link-social(href='/update-email')
|
||||||
i.fa.fa-envelope
|
i.fa.fa-envelope
|
||||||
| Update my Email
|
| Update my Email
|
||||||
.row
|
.row
|
||||||
@ -100,7 +100,7 @@ block content
|
|||||||
p.large-p.text-center
|
p.large-p.text-center
|
||||||
| You don't have an email id associated to this account.
|
| You don't have an email id associated to this account.
|
||||||
.col-xs-12
|
.col-xs-12
|
||||||
a.btn.btn-lg.btn-block.btn-primary.btn-link-social(href='/email-update')
|
a.btn.btn-lg.btn-block.btn-primary.btn-link-social(href='/update-email')
|
||||||
i.fa.fa-envelope
|
i.fa.fa-envelope
|
||||||
| Update my Email
|
| Update my Email
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@ block content
|
|||||||
span.ion-close-circled#flash-close
|
span.ion-close-circled#flash-close
|
||||||
#flash-content
|
#flash-content
|
||||||
h2.text-center Update your email address here:
|
h2.text-center Update your email address here:
|
||||||
form.form-horizontal.email-update(method='POST', action='/api/users/#{user.id}/update-email', name="updateEmailForm")
|
form.form-horizontal.update-email(method='POST', action='/api/users/#{user.id}/update-email', name="updateEmailForm")
|
||||||
.row
|
.row
|
||||||
.col-sm-6.col-sm-offset-3
|
.col-sm-6.col-sm-offset-3
|
||||||
input(type='hidden', name='_csrf', value=_csrf)
|
input(type='hidden', name='_csrf', value=_csrf)
|
Reference in New Issue
Block a user