Skip to content
This repository was archived by the owner on Aug 30, 2021. It is now read-only.

Commit 00f3940

Browse files
author
Kentaro Wakayama
committed
Add joining of multiple accounts
1 parent f150407 commit 00f3940

File tree

6 files changed

+150
-118
lines changed

6 files changed

+150
-118
lines changed

app/controllers/users.js

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,4 +247,98 @@ exports.hasAuthorization = function(req, res, next) {
247247
}
248248

249249
next();
250+
};
251+
252+
/**
253+
* Helper function to save or update a user.
254+
* When the user is logged in, it joins the user data to the existing one.
255+
* Otherwise it creates a new user.
256+
*
257+
* @author Kentaro Wakayama
258+
*
259+
* @date 2014-04-09
260+
*
261+
* @param {Object} req This is the request object which contains the user when he is signed in.
262+
* @param {String} token This is the accesstoken.
263+
* @param {String} tokenSecret This is the refreshtoken.
264+
* @param {Object} profile This is the user profile of the current provider.
265+
* @param {Function} done Callback to supply Passport with the user that authenticated.
266+
*
267+
* @param {Object} providerData This Object contains all data which is specific for the provider
268+
* @param {String} providerData.provider This is the passport provider name.
269+
* @param {String} providerData.idKey This is the Key / Attribute name for saving / retrieving the provider id.
270+
* @param {String} providerData.name This is the user's name.
271+
* @param {String} [providerData.email] This is the user's email.
272+
* @param {String} providerData.username This is the user's username.
273+
*
274+
* @return {[type]} [description]
275+
*/
276+
exports.saveOrUpdate = function(req, token, tokenSecret, profile, done, providerData) {
277+
var provider = providerData.provider;
278+
var idKey = providerData.idKey;
279+
var searchProviderKey = provider + '.' + idKey;
280+
var searchObject = {};
281+
searchObject[searchProviderKey] = profile.id;
282+
283+
if (!req.user) {
284+
// no user active, this is a fresh login
285+
User.findOne(searchObject, function(err, user) {
286+
if (err) {
287+
return done(err);
288+
}
289+
if (!user) {
290+
291+
var possibleUsername = '';
292+
if (providerData.email) {
293+
possibleUsername = providerData.email.split('@')[0];
294+
} else {
295+
possibleUsername = profile.username;
296+
}
297+
298+
User.findUniqueUsername(possibleUsername, null, function(availableUsername) {
299+
user = new User({
300+
firstName: providerData.firstName,
301+
lastName: providerData.lastName,
302+
username: availableUsername,
303+
displayName: providerData.displayName,
304+
email: providerData.email,
305+
provider: provider,
306+
});
307+
308+
user[provider] = profile._json;
309+
user[provider].token = token;
310+
user[provider].tokenSecret = tokenSecret;
311+
user.save(function(err) {
312+
if (err) console.log(err);
313+
return done(err, user);
314+
});
315+
});
316+
} else {
317+
user[provider].token = token;
318+
user[provider].tokenSecret = tokenSecret;
319+
user.save(function(err) {
320+
if (err) console.log(err);
321+
return done(err, user);
322+
});
323+
}
324+
});
325+
} else {
326+
// a user is already logged in, join the provider data to the existing user.
327+
User.findById( req.user._id, function(err, user) {
328+
if (err) {
329+
return done(err);
330+
}
331+
if (user) {
332+
user[provider] = profile._json;
333+
user[provider].token = token;
334+
user[provider].tokenSecret = tokenSecret;
335+
user.save(function(err) {
336+
if (err) console.log(err);
337+
return done(err, user);
338+
});
339+
} else {
340+
return done(err, user);
341+
}
342+
});
343+
}
250344
};

app/models/user.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,12 @@ var UserSchema = new Schema({
7373
created: {
7474
type: Date,
7575
default: Date.now
76-
}
76+
},
77+
facebook: {},
78+
twitter: {},
79+
github: {},
80+
google: {},
81+
linkedin: {}
7782
});
7883

7984
/**

config/strategies/facebook.js

Lines changed: 14 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33
var passport = require('passport'),
44
FacebookStrategy = require('passport-facebook').Strategy,
55
User = require('mongoose').model('User'),
6-
config = require('../config');
6+
config = require('../config'),
7+
users = require('../../app/controllers/users');
78

89
module.exports = function() {
910
// Use facebook strategy
@@ -14,36 +15,18 @@ module.exports = function() {
1415
passReqToCallback: true
1516
},
1617
function(req, accessToken, refreshToken, profile, done) {
17-
if (req.user) {
18-
return done(new Error('User is already signed in'), req.user);
19-
} else {
20-
User.findOne({
21-
'provider': 'facebook',
22-
'providerData.id': profile.id
23-
}, function(err, user) {
24-
if (err) {
25-
return done(err);
26-
}
27-
if (!user) {
28-
User.findUniqueUsername(profile.username, null, function(availableUsername) {
29-
user = new User({
30-
firstName: profile.name.givenName,
31-
lastName: profile.name.familyName,
32-
displayName: profile.displayName,
33-
email: profile.emails[0].value,
34-
username: availableUsername,
35-
provider: 'facebook',
36-
providerData: profile._json
37-
});
38-
user.save(function(err) {
39-
return done(err, user);
40-
});
41-
});
42-
} else {
43-
return done(err, user);
44-
}
45-
});
46-
}
18+
19+
var providerData = {
20+
firstName: profile.name.givenName,
21+
lastName: profile.name.familyName,
22+
displayName: profile.displayName,
23+
provider: 'facebook',
24+
idKey: 'id',
25+
email: profile.emails[0].value,
26+
username: profile.username,
27+
};
28+
users.saveOrUpdate(req, accessToken, refreshToken, profile, done, providerData);
29+
4730
}
4831
));
4932
};

config/strategies/google.js

Lines changed: 13 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33
var passport = require('passport'),
44
GoogleStrategy = require('passport-google-oauth').OAuth2Strategy,
55
User = require('mongoose').model('User'),
6-
config = require('../config');
6+
config = require('../config'),
7+
users = require('../../app/controllers/users');
78

89
module.exports = function() {
910
// Use google strategy
@@ -14,35 +15,18 @@ module.exports = function() {
1415
passReqToCallback: true
1516
},
1617
function(req, accessToken, refreshToken, profile, done) {
17-
if (req.user) {
18-
return done(new Error('User is already signed in'), req.user);
19-
} else {
20-
User.findOne({
21-
'provider': 'google',
22-
'providerData.id': profile.id
23-
}, function(err, user) {
24-
if (!user) {
25-
var possibleUsername = profile.emails[0].value.split('@')[0];
2618

27-
User.findUniqueUsername(possibleUsername, null, function(availableUsername) {
28-
user = new User({
29-
firstName: profile.name.givenName,
30-
lastName: profile.name.familyName,
31-
displayName: profile.displayName,
32-
email: profile.emails[0].value,
33-
username: availableUsername,
34-
provider: 'google',
35-
providerData: profile._json
36-
});
37-
user.save(function(err) {
38-
return done(err, user);
39-
});
40-
});
41-
} else {
42-
return done(err, user);
43-
}
44-
});
45-
}
19+
var providerData = {
20+
firstName: profile.name.givenName,
21+
lastName: profile.name.familyName,
22+
displayName: profile.displayName,
23+
provider: 'google',
24+
idKey: 'id',
25+
email: profile.emails[0].value,
26+
username: profile.username
27+
};
28+
users.saveOrUpdate(req, accessToken, refreshToken, profile, done, providerData);
29+
4630
}
4731
));
4832
};

config/strategies/linkedin.js

Lines changed: 12 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33
var passport = require('passport'),
44
LinkedInStrategy = require('passport-linkedin').Strategy,
55
User = require('mongoose').model('User'),
6-
config = require('../config');
6+
config = require('../config'),
7+
users = require('../../app/controllers/users');
78

89
module.exports = function() {
910
// Use linkedin strategy
@@ -15,35 +16,17 @@ module.exports = function() {
1516
profileFields: ['id', 'first-name', 'last-name', 'email-address']
1617
},
1718
function(req, accessToken, refreshToken, profile, done) {
18-
if (req.user) {
19-
return done(new Error('User is already signed in'), req.user);
20-
} else {
21-
User.findOne({
22-
'provider': 'linkedin',
23-
'providerData.id': profile.id
24-
}, function(err, user) {
25-
if (!user) {
26-
var possibleUsername = profile.emails[0].value.split('@')[0];
2719

28-
User.findUniqueUsername(possibleUsername, null, function(availableUsername) {
29-
user = new User({
30-
firstName: profile.name.givenName,
31-
lastName: profile.name.familyName,
32-
displayName: profile.displayName,
33-
email: profile.emails[0].value,
34-
username: availableUsername,
35-
provider: 'linkedin',
36-
providerData: profile._json
37-
});
38-
user.save(function(err) {
39-
return done(err, user);
40-
});
41-
});
42-
} else {
43-
return done(err, user);
44-
}
45-
});
46-
}
20+
var providerData = {
21+
firstName: profile.name.givenName,
22+
lastName: profile.name.familyName,
23+
displayName: profile.displayName,
24+
provider: 'linkedin',
25+
idKey: 'id',
26+
username: profile.displayName,
27+
};
28+
users.saveOrUpdate(req, accessToken, refreshToken, profile, done, providerData);
29+
4730
}
4831
));
4932
};

config/strategies/twitter.js

Lines changed: 11 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33
var passport = require('passport'),
44
TwitterStrategy = require('passport-twitter').Strategy,
55
User = require('mongoose').model('User'),
6-
config = require('../config');
6+
config = require('../config'),
7+
users = require('../../app/controllers/users');
78

89
module.exports = function() {
910
// Use twitter strategy
@@ -14,33 +15,15 @@ module.exports = function() {
1415
passReqToCallback: true
1516
},
1617
function(req, token, tokenSecret, profile, done) {
17-
if (req.user) {
18-
return done(new Error('User is already signed in'), req.user);
19-
} else {
20-
User.findOne({
21-
'provider': 'twitter',
22-
'providerData.id_str': profile.id
23-
}, function(err, user) {
24-
if (err) {
25-
return done(err);
26-
}
27-
if (!user) {
28-
User.findUniqueUsername(profile.username, null, function(availableUsername) {
29-
user = new User({
30-
displayName: profile.displayName,
31-
username: availableUsername,
32-
provider: 'twitter',
33-
providerData: profile._json
34-
});
35-
user.save(function(err) {
36-
return done(err, user);
37-
});
38-
});
39-
} else {
40-
return done(err, user);
41-
}
42-
});
43-
}
18+
19+
var providerData = {
20+
displayName: profile.displayName,
21+
provider: 'twitter',
22+
idKey: 'id_str',
23+
username: profile.username,
24+
};
25+
26+
users.saveOrUpdate(req, token, tokenSecret, profile, done, providerData);
4427
}
4528
));
4629
};

0 commit comments

Comments
 (0)