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

Commit

Permalink
merge upstream 0.2.3
Browse files Browse the repository at this point in the history
  • Loading branch information
revdave33 committed Apr 16, 2014
2 parents dbdb827 + c6a8a9b commit 114ce6a
Show file tree
Hide file tree
Showing 16 changed files with 269 additions and 124 deletions.
21 changes: 21 additions & 0 deletions LICENSE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
## License
(The MIT License)

Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
'Software'), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 changes: 21 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,28 @@ $ npm install -g bower
$ sudo npm install -g grunt-cli
```

## Downloading MEAN.JS
There are several ways you can get the MEAN.JS boilerplate:

### Yo Generator
The recommended way would be to use the [Official Yo Generator](http://meanjs.org/generator.html) which will generate the latest stable copy of the MEAN.JS boilerplate and supplies multiple sub-generators to ease your daily development cycles.

### Cloning The GitHub Repository
You can also use Git to directly clone the MEAN.JS repository:
```
$ git clone https://github.com/meanjs/mean.git meanjs
```
This will clone the latest version of the MEAN.JS repository to a **meanjs** folder.

### Downloading The Repository Zip File
Another way to use the MEAN.JS boilerplate is to download a zip copy from the [master branch on github](https://github.com/meanjs/mean/archive/master.zip). You can also do this using `wget` command:
```
$ wget https://github.com/meanjs/mean/archive/master.zip -O meanjs.zip; unzip meanjs.zip; rm meanjs.zip
```
Don't forget to rename **mean-master** after your project name.

## Quick Install
Once you've installed all the prerequisites, you're just a few steps away from starting to develop you MEAN application.
Once you've downloaded the boilerplate and installed all the prerequisites, you're just a few steps away from starting to develop you MEAN application.

The first thing you should do is install the Node.js dependencies. The boilerplate comes pre-bundled with a package.json file that contains the list of modules you need to start your application, to learn more about the modules installed visit the NPM & Package.json section.

Expand Down
169 changes: 94 additions & 75 deletions app/controllers/users.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ var mongoose = require('mongoose'),
User = mongoose.model('User'),
_ = require('lodash');

/**
* Get the error message from error object
*/
var getErrorMessage = function(err) {
var message = '';

Expand Down Expand Up @@ -153,7 +156,6 @@ exports.changePassword = function(req, res, next) {
});
}
});

} else {
res.send(400, {
message: 'Passwords do not match'
Expand Down Expand Up @@ -197,17 +199,16 @@ exports.me = function(req, res) {
*/
exports.oauthCallback = function(strategy) {
return function(req, res, next) {
passport.authenticate(strategy, function(err, user, email) {
passport.authenticate(strategy, function(err, user, redirectURL) {
if (err || !user) {
console.log(err);
return res.redirect('/#!/signin');
}
req.login(user, function(err) {
if (err) {
return res.redirect('/#!/signin');
}

return res.redirect('/');
return res.redirect(redirectURL || '/');
});
})(req, res, next);
};
Expand Down Expand Up @@ -250,94 +251,112 @@ exports.hasAuthorization = function(req, res, next) {
};

/**
* Helper function to save or update a user.
* When the user is logged in, it joins the user data to the existing one.
* Otherwise it creates a new user.
*
* @author Kentaro Wakayama
*
* @date 2014-04-09
*
* @param {Object} req This is the request object which contains the user when he is signed in.
* @param {String} token This is the accesstoken.
* @param {String} tokenSecret This is the refreshtoken.
* @param {Object} profile This is the user profile of the current provider.
* @param {Function} done Callback to supply Passport with the user that authenticated.
*
* @param {Object} providerData This Object contains all data which is specific for the provider
* @param {String} providerData.provider This is the passport provider name.
* @param {String} providerData.idKey This is the Key / Attribute name for saving / retrieving the provider id.
* @param {String} providerData.name This is the user's name.
* @param {String} [providerData.email] This is the user's email.
* @param {String} providerData.username This is the user's username.
*
* @return {[type]} [description]
* Helper function to save or update a OAuth user profile
*/
exports.saveOrUpdate = function(req, token, tokenSecret, profile, done, providerData) {
var provider = providerData.provider;
var idKey = providerData.idKey;
var searchProviderKey = provider + '.' + idKey;
var searchObject = {};
searchObject[searchProviderKey] = profile.id;

exports.saveOAuthUserProfile = function(req, providerUserProfile, done) {
if (!req.user) {
// no user active, this is a fresh login
User.findOne(searchObject, function(err, user) {
// Define a search query fields
var searchMainProviderIdentifierField = 'providerData.' + providerUserProfile.providerIdentifierField;
var searchAdditionalProviderIdentifierField = 'additionalProvidersData.' + providerUserProfile.provider + '.' + providerUserProfile.providerIdentifierField;

// Define main provider search query
var mainProviderSearchQuery = {};
mainProviderSearchQuery.provider = providerUserProfile.provider;
mainProviderSearchQuery[searchMainProviderIdentifierField] = providerUserProfile.providerData[providerUserProfile.providerIdentifierField];

// Define additional provider search query
var additionalProviderSearchQuery = {};
additionalProviderSearchQuery[searchAdditionalProviderIdentifierField] = providerUserProfile.providerData[providerUserProfile.providerIdentifierField];

// Define a search query to find existing user with current provider profile
var searchQuery = {
$or: [mainProviderSearchQuery, additionalProviderSearchQuery]
};

User.findOne(searchQuery, function(err, user) {
if (err) {
return done(err);
}
if (!user) {
} else {
if (!user) {
var possibleUsername = providerUserProfile.username || ((providerUserProfile.email) ? providerUserProfile.email.split('@')[0] : '');

var possibleUsername = '';
if (providerData.email) {
possibleUsername = providerData.email.split('@')[0];
User.findUniqueUsername(possibleUsername, null, function(availableUsername) {
user = new User({
firstName: providerUserProfile.firstName,
lastName: providerUserProfile.lastName,
username: availableUsername,
displayName: providerUserProfile.displayName,
email: providerUserProfile.email,
provider: providerUserProfile.provider,
providerData: providerUserProfile.providerData
});

// And save the user
user.save(function(err) {
return done(err, user);
});
});
} else {
possibleUsername = profile.username;
return done(err, user);
}
}
});
} else {
// User is already logged in, join the provider data to the existing user
User.findById(req.user.id, function(err, user) {
if (err) {
return done(err);
} else {
// Check if user exists, is not signed in using this provider, and doesn't have that provider data already configured
if (user && user.provider !== providerUserProfile.provider && (!user.additionalProvidersData || !user.additionalProvidersData[providerUserProfile.provider])) {
// Add the provider data to the additional provider data field
if (!user.additionalProvidersData) user.additionalProvidersData = {};
user.additionalProvidersData[providerUserProfile.provider] = providerUserProfile.providerData;

User.findUniqueUsername(possibleUsername, null, function(availableUsername) {
user = new User({
firstName: providerData.firstName,
lastName: providerData.lastName,
username: availableUsername,
displayName: providerData.displayName,
email: providerData.email,
provider: provider,
});
// Then tell mongoose that we've updated the additionalProvidersData field
user.markModified('additionalProvidersData');

user[provider] = profile._json;
user[provider].token = token;
user[provider].tokenSecret = tokenSecret;
// And save the user
user.save(function(err) {
if (err) console.log(err);
return done(err, user);
return done(err, user, '/#!/settings/accounts');
});
});
} else {
user[provider].token = token;
user[provider].tokenSecret = tokenSecret;
user.save(function(err) {
if (err) console.log(err);
} else {
return done(err, user);
});
}
}
});
} else {
// a user is already logged in, join the provider data to the existing user.
User.findById( req.user._id, function(err, user) {
}
};

/**
* Remove OAuth provider
*/
exports.removeOAuthProvider = function(req, res, next) {
var user = req.user;
var provider = req.param('provider');

if (user && provider) {
// Delete the additional provider
if (user.additionalProvidersData[provider]) {
delete user.additionalProvidersData[provider];

// Then tell mongoose that we've updated the additionalProvidersData field
user.markModified('additionalProvidersData');
}

user.save(function(err) {
if (err) {
return done(err);
}
if (user) {
user[provider] = profile._json;
user[provider].token = token;
user[provider].tokenSecret = tokenSecret;
user.save(function(err) {
if (err) console.log(err);
return done(err, user);
return res.send(400, {
message: getErrorMessage(err)
});
} else {
return done(err, user);
req.login(user, function(err) {
if (err) {
res.send(400, err);
} else {
res.jsonp(user);
}
});
}
});
}
Expand Down
8 changes: 2 additions & 6 deletions app/models/user.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,18 +67,14 @@ var UserSchema = new Schema({
required: 'Provider is required'
},
providerData: {},
additionalProvidersData: {},
updated: {
type: Date
},
created: {
type: Date,
default: Date.now
},
facebook: {},
twitter: {},
github: {},
google: {},
linkedin: {}
}
});

/**
Expand Down
1 change: 1 addition & 0 deletions app/routes/users.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ module.exports = function(app) {
app.get('/users/me', users.me);
app.put('/users', users.update);
app.post('/users/password', users.changePassword);
app.del('/users/accounts', users.removeOAuthProvider);

// Setting up the users api
app.post('/auth/signup', users.signup);
Expand Down
3 changes: 2 additions & 1 deletion config/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
var _ = require('lodash'),
utilities = require('./utilities');

// Look for a valid NODE_ENV variable and if one cannot be found load the development NODE_ENV
process.env.NODE_ENV = ~utilities.walk('./config/env', /(.*)\.js$/).map(function(file) {
return file.split('/').pop().slice(0, -3);
}).indexOf(process.env.NODE_ENV) ? process.env.NODE_ENV : 'development';
Expand All @@ -11,4 +12,4 @@ process.env.NODE_ENV = ~utilities.walk('./config/env', /(.*)\.js$/).map(function
module.exports = _.extend(
require('./env/all'),
require('./env/' + process.env.NODE_ENV) || {}
);
);
16 changes: 11 additions & 5 deletions config/strategies/facebook.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
var passport = require('passport'),
url = require('url'),
FacebookStrategy = require('passport-facebook').Strategy,
User = require('mongoose').model('User'),
config = require('../config'),
users = require('../../app/controllers/users');

Expand All @@ -16,18 +15,25 @@ module.exports = function() {
passReqToCallback: true
},
function(req, accessToken, refreshToken, profile, done) {
// Set the provider data and include tokens
var providerData = profile._json;
providerData.accessToken = accessToken;
providerData.refreshToken = refreshToken;

var providerData = {
// Create the user OAuth profile
var providerUserProfile = {
firstName: profile.name.givenName,
lastName: profile.name.familyName,
displayName: profile.displayName,
provider: 'facebook',
idKey: 'id',
email: profile.emails[0].value,
username: profile.username,
provider: 'facebook',
providerIdentifierField: 'id',
providerData: providerData
};
users.saveOrUpdate(req, accessToken, refreshToken, profile, done, providerData);

// Save the user OAuth profile
users.saveOAuthUserProfile(req, providerUserProfile, done);
}
));
};
20 changes: 13 additions & 7 deletions config/strategies/google.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
var passport = require('passport'),
url = require('url'),
GoogleStrategy = require('passport-google-oauth').OAuth2Strategy,
User = require('mongoose').model('User'),
config = require('../config'),
users = require('../../app/controllers/users');

Expand All @@ -16,18 +15,25 @@ module.exports = function() {
passReqToCallback: true
},
function(req, accessToken, refreshToken, profile, done) {

var providerData = {
// Set the provider data and include tokens
var providerData = profile._json;
providerData.accessToken = accessToken;
providerData.refreshToken = refreshToken;

// Create the user OAuth profile
var providerUserProfile = {
firstName: profile.name.givenName,
lastName: profile.name.familyName,
displayName: profile.displayName,
provider: 'google',
idKey: 'id',
email: profile.emails[0].value,
username: profile.username
username: profile.username,
provider: 'google',
providerIdentifierField: 'id',
providerData: providerData
};
users.saveOrUpdate(req, accessToken, refreshToken, profile, done, providerData);

// Save the user OAuth profile
users.saveOAuthUserProfile(req, providerUserProfile, done);
}
));
};
Loading

0 comments on commit 114ce6a

Please sign in to comment.