New 0.4 version

This commit is contained in:
Amos Haviv
2014-11-10 23:12:33 +02:00
parent ad870299c6
commit ab81d61bd3
153 changed files with 2603 additions and 2063 deletions

View File

@@ -0,0 +1,43 @@
'use strict';
/**
* Module dependencies.
*/
var passport = require('passport'),
url = require('url'),
FacebookStrategy = require('passport-facebook').Strategy,
users = require('../../controllers/users.server.controller');
module.exports = function(config) {
// Use facebook strategy
passport.use(new FacebookStrategy({
clientID: config.facebook.clientID,
clientSecret: config.facebook.clientSecret,
callbackURL: config.facebook.callbackURL,
profileFields: ['id', 'name', 'displayName', 'email', 'username', 'photos'],
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;
// Create the user OAuth profile
var providerUserProfile = {
firstName: profile.name.givenName,
lastName: profile.name.familyName,
displayName: profile.displayName,
email: profile.emails[0].value,
username: profile.username,
profileImageURL: (profile.photos && profile.photos.length) ? profile.photos[0].value : undefined,
provider: 'facebook',
providerIdentifierField: 'id',
providerData: providerData
};
// Save the user OAuth profile
users.saveOAuthUserProfile(req, providerUserProfile, done);
}
));
};

View File

@@ -0,0 +1,40 @@
'use strict';
/**
* Module dependencies.
*/
var passport = require('passport'),
url = require('url'),
GithubStrategy = require('passport-github').Strategy,
users = require('../../controllers/users.server.controller');
module.exports = function(config) {
// Use github strategy
passport.use(new GithubStrategy({
clientID: config.github.clientID,
clientSecret: config.github.clientSecret,
callbackURL: config.github.callbackURL,
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;
// Create the user OAuth profile
var providerUserProfile = {
displayName: profile.displayName,
email: profile.emails[0].value,
username: profile.username,
profileImageURL: (providerData.avatar_url) ? providerData.avatar_url : undefined,
provider: 'github',
providerIdentifierField: 'id',
providerData: providerData
};
// Save the user OAuth profile
users.saveOAuthUserProfile(req, providerUserProfile, done);
}
));
};

View File

@@ -0,0 +1,42 @@
'use strict';
/**
* Module dependencies.
*/
var passport = require('passport'),
url = require('url'),
GoogleStrategy = require('passport-google-oauth').OAuth2Strategy,
users = require('../../controllers/users.server.controller');
module.exports = function(config) {
// Use google strategy
passport.use(new GoogleStrategy({
clientID: config.google.clientID,
clientSecret: config.google.clientSecret,
callbackURL: config.google.callbackURL,
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;
// Create the user OAuth profile
var providerUserProfile = {
firstName: profile.name.givenName,
lastName: profile.name.familyName,
displayName: profile.displayName,
email: profile.emails[0].value,
username: profile.username,
profileImageURL: (providerData.picture) ? providerData.picture : undefined,
provider: 'google',
providerIdentifierField: 'id',
providerData: providerData
};
// Save the user OAuth profile
users.saveOAuthUserProfile(req, providerUserProfile, done);
}
));
};

View File

@@ -0,0 +1,43 @@
'use strict';
/**
* Module dependencies.
*/
var passport = require('passport'),
url = require('url'),
LinkedInStrategy = require('passport-linkedin').Strategy,
users = require('../../controllers/users.server.controller');
module.exports = function(config) {
// Use linkedin strategy
passport.use(new LinkedInStrategy({
consumerKey: config.linkedin.clientID,
consumerSecret: config.linkedin.clientSecret,
callbackURL: config.linkedin.callbackURL,
passReqToCallback: true,
profileFields: ['id', 'first-name', 'last-name', 'email-address', 'picture-url']
},
function(req, accessToken, refreshToken, profile, done) {
// 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,
email: profile.emails[0].value,
username: profile.username,
profileImageURL: (providerData.pictureUrl) ? providerData.pictureUrl : undefined,
provider: 'linkedin',
providerIdentifierField: 'id',
providerData: providerData
};
// Save the user OAuth profile
users.saveOAuthUserProfile(req, providerUserProfile, done);
}
));
};

View File

@@ -0,0 +1,38 @@
'use strict';
/**
* Module dependencies.
*/
var passport = require('passport'),
LocalStrategy = require('passport-local').Strategy,
User = require('mongoose').model('User');
module.exports = function() {
// Use local strategy
passport.use(new LocalStrategy({
usernameField: 'username',
passwordField: 'password'
},
function(username, password, done) {
User.findOne({
username: username
}, function(err, user) {
if (err) {
return done(err);
}
if (!user) {
return done(null, false, {
message: 'Unknown user'
});
}
if (!user.authenticate(password)) {
return done(null, false, {
message: 'Invalid password'
});
}
return done(null, user);
});
}
));
};

View File

@@ -0,0 +1,39 @@
'use strict';
/**
* Module dependencies.
*/
var passport = require('passport'),
url = require('url'),
TwitterStrategy = require('passport-twitter').Strategy,
users = require('../../controllers/users.server.controller');
module.exports = function(config) {
// Use twitter strategy
passport.use(new TwitterStrategy({
consumerKey: config.twitter.clientID,
consumerSecret: config.twitter.clientSecret,
callbackURL: config.twitter.callbackURL,
passReqToCallback: true
},
function(req, token, tokenSecret, profile, done) {
// Set the provider data and include tokens
var providerData = profile._json;
providerData.token = token;
providerData.tokenSecret = tokenSecret;
// Create the user OAuth profile
var providerUserProfile = {
displayName: profile.displayName,
username: profile.username,
profileImageURL: (profile.photos && profile.photos.length) ? profile.photos[0].value : undefined,
provider: 'twitter',
providerIdentifierField: 'id_str',
providerData: providerData
};
// Save the user OAuth profile
users.saveOAuthUserProfile(req, providerUserProfile, done);
}
));
};

View File

@@ -0,0 +1,34 @@
'use strict';
/**
* Module dependencies.
*/
var passport = require('passport'),
User = require('mongoose').model('User'),
path = require('path'),
config = require(path.resolve('./config/config'));
module.exports = function(app, db) {
// Serialize sessions
passport.serializeUser(function(user, done) {
done(null, user.id);
});
// Deserialize sessions
passport.deserializeUser(function(id, done) {
User.findOne({
_id: id
}, '-salt -password', function(err, user) {
done(err, user);
});
});
// Initialize strategies
config.utils.getGlobbedPaths(path.join(__dirname, './strategies/**/*.js')).forEach(function(strategy) {
require(path.resolve(strategy))(config);
});
// Add passport's middleware
app.use(passport.initialize());
app.use(passport.session());
};

View File

@@ -0,0 +1,16 @@
'use strict';
/**
* Module dependencies.
*/
var _ = require('lodash');
/**
* Extend user's controller
*/
module.exports = _.extend(
require('./users/users.authentication.server.controller'),
require('./users/users.authorization.server.controller'),
require('./users/users.password.server.controller'),
require('./users/users.profile.server.controller')
);

View File

@@ -0,0 +1,208 @@
'use strict';
/**
* Module dependencies.
*/
var _ = require('lodash'),
path = require('path'),
errorHandler = require(path.resolve('./modules/core/server/controllers/errors.server.controller')),
mongoose = require('mongoose'),
passport = require('passport'),
User = mongoose.model('User');
/**
* Signup
*/
exports.signup = function(req, res) {
// For security measurement we remove the roles from the req.body object
delete req.body.roles;
// Init Variables
var user = new User(req.body);
var message = null;
// Add missing user fields
user.provider = 'local';
user.displayName = user.firstName + ' ' + user.lastName;
// Then save the user
user.save(function(err) {
if (err) {
return res.status(400).send({
message: errorHandler.getErrorMessage(err)
});
} else {
// Remove sensitive data before login
user.password = undefined;
user.salt = undefined;
req.login(user, function(err) {
if (err) {
res.status(400).send(err);
} else {
res.json(user);
}
});
}
});
};
/**
* Signin after passport authentication
*/
exports.signin = function(req, res, next) {
passport.authenticate('local', function(err, user, info) {
if (err || !user) {
res.status(400).send(info);
} else {
// Remove sensitive data before login
user.password = undefined;
user.salt = undefined;
req.login(user, function(err) {
if (err) {
res.status(400).send(err);
} else {
res.json(user);
}
});
}
})(req, res, next);
};
/**
* Signout
*/
exports.signout = function(req, res) {
req.logout();
res.redirect('/');
};
/**
* OAuth callback
*/
exports.oauthCallback = function(strategy) {
return function(req, res, next) {
passport.authenticate(strategy, function(err, user, redirectURL) {
if (err || !user) {
return res.redirect('/#!/signin');
}
req.login(user, function(err) {
if (err) {
return res.redirect('/#!/signin');
}
return res.redirect(redirectURL || '/');
});
})(req, res, next);
};
};
/**
* Helper function to save or update a OAuth user profile
*/
exports.saveOAuthUserProfile = function(req, providerUserProfile, done) {
if (!req.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);
} else {
if (!user) {
var possibleUsername = providerUserProfile.username || ((providerUserProfile.email) ? providerUserProfile.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,
profileImageURL: providerUserProfile.profileImageURL,
provider: providerUserProfile.provider,
providerData: providerUserProfile.providerData
});
// And save the user
user.save(function(err) {
return done(err, user);
});
});
} else {
return done(err, user);
}
}
});
} else {
// User is already logged in, join the provider data to the existing user
var user = req.user;
// Check if user exists, is not signed in using this provider, and doesn't have that provider data already configured
if (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;
// Then tell mongoose that we've updated the additionalProvidersData field
user.markModified('additionalProvidersData');
// And save the user
user.save(function(err) {
return done(err, user, '/#!/settings/accounts');
});
} else {
return done(new Error('User is already connected using this provider'), 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 res.status(400).send({
message: errorHandler.getErrorMessage(err)
});
} else {
req.login(user, function(err) {
if (err) {
res.status(400).send(err);
} else {
res.json(user);
}
});
}
});
}
};

View File

@@ -0,0 +1,54 @@
'use strict';
/**
* Module dependencies.
*/
var _ = require('lodash'),
mongoose = require('mongoose'),
User = mongoose.model('User');
/**
* User middleware
*/
exports.userByID = function(req, res, next, id) {
User.findOne({
_id: id
}).exec(function(err, user) {
if (err) return next(err);
if (!user) return next(new Error('Failed to load User ' + id));
req.profile = user;
next();
});
};
/**
* Require login routing middleware
*/
exports.requiresLogin = function(req, res, next) {
if (!req.isAuthenticated()) {
return res.status(401).send({
message: 'User is not logged in'
});
}
next();
};
/**
* User authorizations routing middleware
*/
exports.hasAuthorization = function(roles) {
var _this = this;
return function(req, res, next) {
_this.requiresLogin(req, res, function() {
if (_.intersection(req.user.roles, roles).length) {
return next();
} else {
return res.status(403).send({
message: 'User is not authorized'
});
}
});
};
};

View File

@@ -0,0 +1,249 @@
'use strict';
/**
* Module dependencies.
*/
var _ = require('lodash'),
path = require('path'),
config = require(path.resolve('./config/config')),
errorHandler = require(path.resolve('./modules/core/server/controllers/errors.server.controller')),
mongoose = require('mongoose'),
passport = require('passport'),
User = mongoose.model('User'),
nodemailer = require('nodemailer'),
crypto = require('crypto'),
async = require('async'),
crypto = require('crypto');
/**
* Forgot for reset password (forgot POST)
*/
exports.forgot = function(req, res, next) {
async.waterfall([
// Generate random token
function(done) {
crypto.randomBytes(20, function(err, buffer) {
var token = buffer.toString('hex');
done(err, token);
});
},
// Lookup user by username
function(token, done) {
if (req.body.username) {
User.findOne({
username: req.body.username
}, '-salt -password', function(err, user) {
if (!user) {
return res.status(400).send({
message: 'No account with that username has been found'
});
} else if (user.provider !== 'local') {
return res.status(400).send({
message: 'It seems like you signed up using your ' + user.provider + ' account'
});
} else {
user.resetPasswordToken = token;
user.resetPasswordExpires = Date.now() + 3600000; // 1 hour
user.save(function(err) {
done(err, token, user);
});
}
});
} else {
return res.status(400).send({
message: 'Username field must not be blank'
});
}
},
function(token, user, done) {
res.render(path.resolve('modules/users/server/templates/reset-password-email'), {
name: user.displayName,
appName: config.app.title,
url: 'http://' + req.headers.host + '/api/auth/reset/' + token
}, function(err, emailHTML) {
done(err, emailHTML, user);
});
},
// If valid email, send reset email using service
function(emailHTML, user, done) {
var smtpTransport = nodemailer.createTransport(config.mailer.options);
var mailOptions = {
to: user.email,
from: config.mailer.from,
subject: 'Password Reset',
html: emailHTML
};
smtpTransport.sendMail(mailOptions, function(err) {
if (!err) {
res.send({
message: 'An email has been sent to ' + user.email + ' with further instructions.'
});
}
done(err);
});
}
], function(err) {
if (err) return next(err);
});
};
/**
* Reset password GET from email token
*/
exports.validateResetToken = function(req, res) {
User.findOne({
resetPasswordToken: req.params.token,
resetPasswordExpires: {
$gt: Date.now()
}
}, function(err, user) {
if (!user) {
return res.redirect('/#!/password/reset/invalid');
}
res.redirect('/#!/password/reset/' + req.params.token);
});
};
/**
* Reset password POST from email token
*/
exports.reset = function(req, res, next) {
// Init Variables
var passwordDetails = req.body;
var message = null;
async.waterfall([
function(done) {
User.findOne({
resetPasswordToken: req.params.token,
resetPasswordExpires: {
$gt: Date.now()
}
}, function(err, user) {
if (!err && user) {
if (passwordDetails.newPassword === passwordDetails.verifyPassword) {
user.password = passwordDetails.newPassword;
user.resetPasswordToken = undefined;
user.resetPasswordExpires = undefined;
user.save(function(err) {
if (err) {
return res.status(400).send({
message: errorHandler.getErrorMessage(err)
});
} else {
req.login(user, function(err) {
if (err) {
res.status(400).send(err);
} else {
// Return authenticated user
res.json(user);
done(err, user);
}
});
}
});
} else {
return res.status(400).send({
message: 'Passwords do not match'
});
}
} else {
return res.status(400).send({
message: 'Password reset token is invalid or has expired.'
});
}
});
},
function(user, done) {
res.render('modules/users/server/templates/reset-password-confirm-email', {
name: user.displayName,
appName: config.app.title
}, function(err, emailHTML) {
done(err, emailHTML, user);
});
},
// If valid email, send reset email using service
function(emailHTML, user, done) {
var smtpTransport = nodemailer.createTransport(config.mailer.options);
var mailOptions = {
to: user.email,
from: config.mailer.from,
subject: 'Your password has been changed',
html: emailHTML
};
smtpTransport.sendMail(mailOptions, function(err) {
done(err, 'done');
});
}
], function(err) {
if (err) return next(err);
});
};
/**
* Change Password
*/
exports.changePassword = function(req, res, next) {
// Init Variables
var passwordDetails = req.body;
var message = null;
if (req.user) {
if (passwordDetails.newPassword) {
User.findById(req.user.id, function(err, user) {
if (!err && user) {
if (user.authenticate(passwordDetails.currentPassword)) {
if (passwordDetails.newPassword === passwordDetails.verifyPassword) {
user.password = passwordDetails.newPassword;
user.save(function(err) {
if (err) {
return res.status(400).send({
message: errorHandler.getErrorMessage(err)
});
} else {
req.login(user, function(err) {
if (err) {
res.status(400).send(err);
} else {
res.send({
message: 'Password changed successfully'
});
}
});
}
});
} else {
res.status(400).send({
message: 'Passwords do not match'
});
}
} else {
res.status(400).send({
message: 'Current password is incorrect'
});
}
} else {
res.status(400).send({
message: 'User is not found'
});
}
});
} else {
res.status(400).send({
message: 'Please provide a new password'
});
}
} else {
res.status(400).send({
message: 'User is not signed in'
});
}
};

View File

@@ -0,0 +1,97 @@
'use strict';
/**
* Module dependencies.
*/
var _ = require('lodash'),
fs = require('fs'),
path = require('path'),
errorHandler = require(path.resolve('./modules/core/server/controllers/errors.server.controller')),
mongoose = require('mongoose'),
passport = require('passport'),
User = mongoose.model('User');
/**
* Update user details
*/
exports.update = function (req, res) {
// Init Variables
var user = req.user;
// For security measurement we remove the roles from the req.body object
delete req.body.roles;
if (user) {
// Merge existing user
user = _.extend(user, req.body);
user.updated = Date.now();
user.displayName = user.firstName + ' ' + user.lastName;
user.save(function (err) {
if (err) {
return res.status(400).send({
message: errorHandler.getErrorMessage(err)
});
} else {
req.login(user, function (err) {
if (err) {
res.status(400).send(err);
} else {
res.json(user);
}
});
}
});
} else {
res.status(400).send({
message: 'User is not signed in'
});
}
};
/**
* Update profile picture
*/
exports.changeProfilePicture = function (req, res) {
var user = req.user;
var message = null;
if (user) {
fs.writeFile('./modules/users/client/img/profile/uploads/' + req.files.file.name, req.files.file.buffer, function (uploadError) {
if (uploadError) {
return res.status(400).send({
message: 'Error occurred while uploading profile picture'
});
} else {
user.profileImageURL = 'modules/users/img/profile/uploads/' + req.files.file.name;
user.save(function (saveError) {
if (saveError) {
return res.status(400).send({
message: errorHandler.getErrorMessage(saveError)
});
} else {
req.login(user, function (err) {
if (err) {
res.status(400).send(err);
} else {
res.json(user);
}
});
}
});
}
});
} else {
res.status(400).send({
message: 'User is not signed in'
});
}
};
/**
* Send User
*/
exports.me = function (req, res) {
res.json(req.user || null);
};

View File

@@ -0,0 +1,150 @@
'use strict';
/**
* Module dependencies.
*/
var mongoose = require('mongoose'),
Schema = mongoose.Schema,
crypto = require('crypto');
/**
* A Validation function for local strategy properties
*/
var validateLocalStrategyProperty = function(property) {
return ((this.provider !== 'local' && !this.updated) || property.length);
};
/**
* A Validation function for local strategy password
*/
var validateLocalStrategyPassword = function(password) {
return (this.provider !== 'local' || (password && password.length > 6));
};
/**
* User Schema
*/
var UserSchema = new Schema({
firstName: {
type: String,
trim: true,
default: '',
validate: [validateLocalStrategyProperty, 'Please fill in your first name']
},
lastName: {
type: String,
trim: true,
default: '',
validate: [validateLocalStrategyProperty, 'Please fill in your last name']
},
displayName: {
type: String,
trim: true
},
email: {
type: String,
trim: true,
default: '',
validate: [validateLocalStrategyProperty, 'Please fill in your email'],
match: [/.+\@.+\..+/, 'Please fill a valid email address']
},
username: {
type: String,
unique: 'testing error message',
required: 'Please fill in a username',
trim: true
},
password: {
type: String,
default: '',
validate: [validateLocalStrategyPassword, 'Password should be longer']
},
salt: {
type: String
},
profileImageURL: {
type: String,
default: 'modules/users/img/profile/default.png'
},
provider: {
type: String,
required: 'Provider is required'
},
providerData: {},
additionalProvidersData: {},
roles: {
type: [{
type: String,
enum: ['user', 'admin']
}],
default: ['user']
},
updated: {
type: Date
},
created: {
type: Date,
default: Date.now
},
/* For reset password */
resetPasswordToken: {
type: String
},
resetPasswordExpires: {
type: Date
}
});
/**
* Hook a pre save method to hash the password
*/
UserSchema.pre('save', function(next) {
if (this.password && this.password.length > 6) {
this.salt = new Buffer(crypto.randomBytes(16).toString('base64'), 'base64');
this.password = this.hashPassword(this.password);
}
next();
});
/**
* Create instance method for hashing a password
*/
UserSchema.methods.hashPassword = function(password) {
if (this.salt && password) {
return crypto.pbkdf2Sync(password, this.salt, 10000, 64).toString('base64');
} else {
return password;
}
};
/**
* Create instance method for authenticating user
*/
UserSchema.methods.authenticate = function(password) {
return this.password === this.hashPassword(password);
};
/**
* Find possible not used username
*/
UserSchema.statics.findUniqueUsername = function(username, suffix, callback) {
var _this = this;
var possibleUsername = username + (suffix || '');
_this.findOne({
username: possibleUsername
}, function(err, user) {
if (!err) {
if (!user) {
callback(possibleUsername);
} else {
return _this.findUniqueUsername(username, (suffix || 0) + 1, callback);
}
} else {
callback(null);
}
});
};
mongoose.model('User', UserSchema);

View File

@@ -0,0 +1,53 @@
'use strict';
/**
* Module dependencies.
*/
var passport = require('passport');
module.exports = function(app) {
// User Routes
var users = require('../controllers/users.server.controller');
// Setting up the users password api
app.route('/api/auth/forgot').post(users.forgot);
app.route('/api/auth/reset/:token').get(users.validateResetToken);
app.route('/api/auth/reset/:token').post(users.reset);
// Setting up the users authentication api
app.route('/api/auth/signup').post(users.signup);
app.route('/api/auth/signin').post(users.signin);
app.route('/api/auth/signout').get(users.signout);
// Setting the facebook oauth routes
app.route('/api/auth/facebook').get(passport.authenticate('facebook', {
scope: ['email']
}));
app.route('/api/auth/facebook/callback').get(users.oauthCallback('facebook'));
// Setting the twitter oauth routes
app.route('/api/auth/twitter').get(passport.authenticate('twitter'));
app.route('/api/auth/twitter/callback').get(users.oauthCallback('twitter'));
// Setting the google oauth routes
app.route('/api/auth/google').get(passport.authenticate('google', {
scope: [
'https://www.googleapis.com/auth/userinfo.profile',
'https://www.googleapis.com/auth/userinfo.email'
]
}));
app.route('/api/auth/google/callback').get(users.oauthCallback('google'));
// Setting the linkedin oauth routes
app.route('/api/auth/linkedin').get(passport.authenticate('linkedin', {
scope: [
'r_basicprofile',
'r_emailaddress'
]
}));
app.route('/api/auth/linkedin/callback').get(users.oauthCallback('linkedin'));
// Setting the github oauth routes
app.route('/api/auth/github').get(passport.authenticate('github'));
app.route('/api/auth/github/callback').get(users.oauthCallback('github'));
};

View File

@@ -0,0 +1,21 @@
'use strict';
/**
* Module dependencies.
*/
var passport = require('passport');
module.exports = function(app) {
// User Routes
var users = require('../controllers/users.server.controller');
// Setting up the users profile api
app.route('/api/users/me').get(users.me);
app.route('/api/users').put(users.update);
app.route('/api/users/accounts').delete(users.removeOAuthProvider);
app.route('/api/users/password').post(users.changePassword);
app.route('/api/users/picture').post(users.changeProfilePicture);
// Finish by binding the user middleware
app.param('userId', users.userByID);
};

View File

@@ -0,0 +1,16 @@
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
</head>
<body>
<p>Dear {{name}},</p>
<p></p>
<p>This is a confirmation that the password for your account has just been changed</p>
<br>
<br>
<p>The {{appName}} Support Team</p>
</body>
</html>

View File

@@ -0,0 +1,22 @@
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
</head>
<body>
<p>Dear {{name}},</p>
<br>
<p>
You have requested to have your password reset for your account at {{appName}}
</p>
<p>Please visit this url to reset your password:</p>
<p>{{url}}</p>
<strong>If you didn't make this request, you can ignore this email.</strong>
<br>
<br>
<p>The {{appName}} Support Team</p>
</body>
</html>