mirror of
https://github.com/taobataoma/meanTorrent.git
synced 2026-07-15 00:01:28 +02:00
Changed all the indents to the spaces(tab size 4)
This commit is contained in:
@@ -4,129 +4,129 @@
|
||||
* Module dependencies.
|
||||
*/
|
||||
var mongoose = require('mongoose'),
|
||||
Article = mongoose.model('Article'),
|
||||
_ = require('lodash');
|
||||
Article = mongoose.model('Article'),
|
||||
_ = require('lodash');
|
||||
|
||||
/**
|
||||
* Get the error message from error object
|
||||
*/
|
||||
var getErrorMessage = function(err) {
|
||||
var message = '';
|
||||
var message = '';
|
||||
|
||||
if (err.code) {
|
||||
switch (err.code) {
|
||||
case 11000:
|
||||
case 11001:
|
||||
message = 'Article already exists';
|
||||
break;
|
||||
default:
|
||||
message = 'Something went wrong';
|
||||
}
|
||||
} else {
|
||||
for (var errName in err.errors) {
|
||||
if (err.errors[errName].message) message = err.errors[errName].message;
|
||||
}
|
||||
}
|
||||
if (err.code) {
|
||||
switch (err.code) {
|
||||
case 11000:
|
||||
case 11001:
|
||||
message = 'Article already exists';
|
||||
break;
|
||||
default:
|
||||
message = 'Something went wrong';
|
||||
}
|
||||
} else {
|
||||
for (var errName in err.errors) {
|
||||
if (err.errors[errName].message) message = err.errors[errName].message;
|
||||
}
|
||||
}
|
||||
|
||||
return message;
|
||||
return message;
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a article
|
||||
*/
|
||||
exports.create = function(req, res) {
|
||||
var article = new Article(req.body);
|
||||
article.user = req.user;
|
||||
var article = new Article(req.body);
|
||||
article.user = req.user;
|
||||
|
||||
article.save(function(err) {
|
||||
if (err) {
|
||||
return res.send(400, {
|
||||
message: getErrorMessage(err)
|
||||
});
|
||||
} else {
|
||||
res.jsonp(article);
|
||||
}
|
||||
});
|
||||
article.save(function(err) {
|
||||
if (err) {
|
||||
return res.send(400, {
|
||||
message: getErrorMessage(err)
|
||||
});
|
||||
} else {
|
||||
res.jsonp(article);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Show the current article
|
||||
*/
|
||||
exports.read = function(req, res) {
|
||||
res.jsonp(req.article);
|
||||
res.jsonp(req.article);
|
||||
};
|
||||
|
||||
/**
|
||||
* Update a article
|
||||
*/
|
||||
exports.update = function(req, res) {
|
||||
var article = req.article;
|
||||
var article = req.article;
|
||||
|
||||
article = _.extend(article, req.body);
|
||||
article = _.extend(article, req.body);
|
||||
|
||||
article.save(function(err) {
|
||||
if (err) {
|
||||
return res.send(400, {
|
||||
message: getErrorMessage(err)
|
||||
});
|
||||
} else {
|
||||
res.jsonp(article);
|
||||
}
|
||||
});
|
||||
article.save(function(err) {
|
||||
if (err) {
|
||||
return res.send(400, {
|
||||
message: getErrorMessage(err)
|
||||
});
|
||||
} else {
|
||||
res.jsonp(article);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Delete an article
|
||||
*/
|
||||
exports.delete = function(req, res) {
|
||||
var article = req.article;
|
||||
var article = req.article;
|
||||
|
||||
article.remove(function(err) {
|
||||
if (err) {
|
||||
return res.send(400, {
|
||||
message: getErrorMessage(err)
|
||||
});
|
||||
} else {
|
||||
res.jsonp(article);
|
||||
}
|
||||
});
|
||||
article.remove(function(err) {
|
||||
if (err) {
|
||||
return res.send(400, {
|
||||
message: getErrorMessage(err)
|
||||
});
|
||||
} else {
|
||||
res.jsonp(article);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* List of Articles
|
||||
*/
|
||||
exports.list = function(req, res) {
|
||||
Article.find().sort('-created').populate('user', 'displayName').exec(function(err, articles) {
|
||||
if (err) {
|
||||
return res.send(400, {
|
||||
message: getErrorMessage(err)
|
||||
});
|
||||
} else {
|
||||
res.jsonp(articles);
|
||||
}
|
||||
});
|
||||
Article.find().sort('-created').populate('user', 'displayName').exec(function(err, articles) {
|
||||
if (err) {
|
||||
return res.send(400, {
|
||||
message: getErrorMessage(err)
|
||||
});
|
||||
} else {
|
||||
res.jsonp(articles);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Article middleware
|
||||
*/
|
||||
exports.articleByID = function(req, res, next, id) {
|
||||
Article.findById(id).populate('user', 'displayName').exec(function(err, article) {
|
||||
if (err) return next(err);
|
||||
if (!article) return next(new Error('Failed to load article ' + id));
|
||||
req.article = article;
|
||||
next();
|
||||
});
|
||||
Article.findById(id).populate('user', 'displayName').exec(function(err, article) {
|
||||
if (err) return next(err);
|
||||
if (!article) return next(new Error('Failed to load article ' + id));
|
||||
req.article = article;
|
||||
next();
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Article authorization middleware
|
||||
*/
|
||||
exports.hasAuthorization = function(req, res, next) {
|
||||
if (req.article.user.id !== req.user.id) {
|
||||
return res.send(403, {
|
||||
message: 'User is not authorized'
|
||||
});
|
||||
}
|
||||
next();
|
||||
};
|
||||
if (req.article.user.id !== req.user.id) {
|
||||
return res.send(403, {
|
||||
message: 'User is not authorized'
|
||||
});
|
||||
}
|
||||
next();
|
||||
};
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
* Module dependencies.
|
||||
*/
|
||||
exports.index = function(req, res) {
|
||||
res.render('index', {
|
||||
user: req.user || null
|
||||
});
|
||||
};
|
||||
res.render('index', {
|
||||
user: req.user || null
|
||||
});
|
||||
};
|
||||
|
||||
@@ -4,377 +4,377 @@
|
||||
* Module dependencies.
|
||||
*/
|
||||
var mongoose = require('mongoose'),
|
||||
passport = require('passport'),
|
||||
User = mongoose.model('User'),
|
||||
_ = require('lodash');
|
||||
passport = require('passport'),
|
||||
User = mongoose.model('User'),
|
||||
_ = require('lodash');
|
||||
|
||||
/**
|
||||
* Get the error message from error object
|
||||
*/
|
||||
var getErrorMessage = function(err) {
|
||||
var message = '';
|
||||
var message = '';
|
||||
|
||||
if (err.code) {
|
||||
switch (err.code) {
|
||||
case 11000:
|
||||
case 11001:
|
||||
message = 'Username already exists';
|
||||
break;
|
||||
default:
|
||||
message = 'Something went wrong';
|
||||
}
|
||||
} else {
|
||||
for (var errName in err.errors) {
|
||||
if (err.errors[errName].message) message = err.errors[errName].message;
|
||||
}
|
||||
}
|
||||
if (err.code) {
|
||||
switch (err.code) {
|
||||
case 11000:
|
||||
case 11001:
|
||||
message = 'Username already exists';
|
||||
break;
|
||||
default:
|
||||
message = 'Something went wrong';
|
||||
}
|
||||
} else {
|
||||
for (var errName in err.errors) {
|
||||
if (err.errors[errName].message) message = err.errors[errName].message;
|
||||
}
|
||||
}
|
||||
|
||||
return message;
|
||||
return message;
|
||||
};
|
||||
|
||||
/**
|
||||
* 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;
|
||||
// For security measurement we remove the roles from the req.body object
|
||||
delete req.body.roles;
|
||||
|
||||
// Add missing user fields
|
||||
user.provider = 'local';
|
||||
user.displayName = user.firstName + ' ' + user.lastName;
|
||||
// Init Variables
|
||||
var user = new User(req.body);
|
||||
var message = null;
|
||||
|
||||
// Then save the user
|
||||
user.save(function(err) {
|
||||
if (err) {
|
||||
return res.send(400, {
|
||||
message: getErrorMessage(err)
|
||||
});
|
||||
} else {
|
||||
// Remove sensitive data before login
|
||||
user.password = undefined;
|
||||
user.salt = undefined;
|
||||
// Add missing user fields
|
||||
user.provider = 'local';
|
||||
user.displayName = user.firstName + ' ' + user.lastName;
|
||||
|
||||
req.login(user, function(err) {
|
||||
if (err) {
|
||||
res.send(400, err);
|
||||
} else {
|
||||
res.jsonp(user);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
// Then save the user
|
||||
user.save(function(err) {
|
||||
if (err) {
|
||||
return res.send(400, {
|
||||
message: getErrorMessage(err)
|
||||
});
|
||||
} else {
|
||||
// Remove sensitive data before login
|
||||
user.password = undefined;
|
||||
user.salt = undefined;
|
||||
|
||||
req.login(user, function(err) {
|
||||
if (err) {
|
||||
res.send(400, err);
|
||||
} else {
|
||||
res.jsonp(user);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Signin after passport authentication
|
||||
*/
|
||||
exports.signin = function(req, res, next) {
|
||||
passport.authenticate('local', function(err, user, info) {
|
||||
if (err || !user) {
|
||||
res.send(400, info);
|
||||
} else {
|
||||
// Remove sensitive data before login
|
||||
user.password = undefined;
|
||||
user.salt = undefined;
|
||||
passport.authenticate('local', function(err, user, info) {
|
||||
if (err || !user) {
|
||||
res.send(400, info);
|
||||
} else {
|
||||
// Remove sensitive data before login
|
||||
user.password = undefined;
|
||||
user.salt = undefined;
|
||||
|
||||
req.login(user, function(err) {
|
||||
if (err) {
|
||||
res.send(400, err);
|
||||
} else {
|
||||
res.jsonp(user);
|
||||
}
|
||||
});
|
||||
}
|
||||
})(req, res, next);
|
||||
req.login(user, function(err) {
|
||||
if (err) {
|
||||
res.send(400, err);
|
||||
} else {
|
||||
res.jsonp(user);
|
||||
}
|
||||
});
|
||||
}
|
||||
})(req, res, next);
|
||||
};
|
||||
|
||||
/**
|
||||
* Update user details
|
||||
*/
|
||||
exports.update = function(req, res) {
|
||||
// Init Variables
|
||||
var user = req.user;
|
||||
var message = null;
|
||||
// Init Variables
|
||||
var user = req.user;
|
||||
var message = null;
|
||||
|
||||
// For security measurement we remove the roles from the req.body object
|
||||
delete req.body.roles;
|
||||
// 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;
|
||||
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.send(400, {
|
||||
message: getErrorMessage(err)
|
||||
});
|
||||
} else {
|
||||
req.login(user, function(err) {
|
||||
if (err) {
|
||||
res.send(400, err);
|
||||
} else {
|
||||
res.jsonp(user);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
} else {
|
||||
res.send(400, {
|
||||
message: 'User is not signed in'
|
||||
});
|
||||
}
|
||||
user.save(function(err) {
|
||||
if (err) {
|
||||
return res.send(400, {
|
||||
message: getErrorMessage(err)
|
||||
});
|
||||
} else {
|
||||
req.login(user, function(err) {
|
||||
if (err) {
|
||||
res.send(400, err);
|
||||
} else {
|
||||
res.jsonp(user);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
} else {
|
||||
res.send(400, {
|
||||
message: 'User is not signed in'
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Change Password
|
||||
*/
|
||||
exports.changePassword = function(req, res, next) {
|
||||
// Init Variables
|
||||
var passwordDetails = req.body;
|
||||
var message = null;
|
||||
// Init Variables
|
||||
var passwordDetails = req.body;
|
||||
var message = null;
|
||||
|
||||
if (req.user) {
|
||||
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;
|
||||
if (req.user) {
|
||||
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.send(400, {
|
||||
message: getErrorMessage(err)
|
||||
});
|
||||
} else {
|
||||
req.login(user, function(err) {
|
||||
if (err) {
|
||||
res.send(400, err);
|
||||
} else {
|
||||
res.send({
|
||||
message: 'Password changed successfully'
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
} else {
|
||||
res.send(400, {
|
||||
message: 'Passwords do not match'
|
||||
});
|
||||
}
|
||||
} else {
|
||||
res.send(400, {
|
||||
message: 'Current password is incorrect'
|
||||
});
|
||||
}
|
||||
} else {
|
||||
res.send(400, {
|
||||
message: 'User is not found'
|
||||
});
|
||||
}
|
||||
});
|
||||
} else {
|
||||
res.send(400, {
|
||||
message: 'User is not signed in'
|
||||
});
|
||||
}
|
||||
user.save(function(err) {
|
||||
if (err) {
|
||||
return res.send(400, {
|
||||
message: getErrorMessage(err)
|
||||
});
|
||||
} else {
|
||||
req.login(user, function(err) {
|
||||
if (err) {
|
||||
res.send(400, err);
|
||||
} else {
|
||||
res.send({
|
||||
message: 'Password changed successfully'
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
} else {
|
||||
res.send(400, {
|
||||
message: 'Passwords do not match'
|
||||
});
|
||||
}
|
||||
} else {
|
||||
res.send(400, {
|
||||
message: 'Current password is incorrect'
|
||||
});
|
||||
}
|
||||
} else {
|
||||
res.send(400, {
|
||||
message: 'User is not found'
|
||||
});
|
||||
}
|
||||
});
|
||||
} else {
|
||||
res.send(400, {
|
||||
message: 'User is not signed in'
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Signout
|
||||
*/
|
||||
exports.signout = function(req, res) {
|
||||
req.logout();
|
||||
res.redirect('/');
|
||||
req.logout();
|
||||
res.redirect('/');
|
||||
};
|
||||
|
||||
/**
|
||||
* Send User
|
||||
*/
|
||||
exports.me = function(req, res) {
|
||||
res.jsonp(req.user || null);
|
||||
res.jsonp(req.user || null);
|
||||
};
|
||||
|
||||
/**
|
||||
* 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 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);
|
||||
};
|
||||
return res.redirect(redirectURL || '/');
|
||||
});
|
||||
})(req, res, next);
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* 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();
|
||||
});
|
||||
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.send(401, {
|
||||
message: 'User is not logged in'
|
||||
});
|
||||
}
|
||||
if (!req.isAuthenticated()) {
|
||||
return res.send(401, {
|
||||
message: 'User is not logged in'
|
||||
});
|
||||
}
|
||||
|
||||
next();
|
||||
next();
|
||||
};
|
||||
|
||||
/**
|
||||
* User authorizations routing middleware
|
||||
*/
|
||||
exports.hasAuthorization = function(roles) {
|
||||
var _this = this;
|
||||
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.send(403, {
|
||||
message: 'User is not authorized'
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
return function(req, res, next) {
|
||||
_this.requiresLogin(req, res, function() {
|
||||
if (_.intersection(req.user.roles, roles).length) {
|
||||
return next();
|
||||
} else {
|
||||
return res.send(403, {
|
||||
message: 'User is not authorized'
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* 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;
|
||||
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 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 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]
|
||||
};
|
||||
// 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.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,
|
||||
provider: providerUserProfile.provider,
|
||||
providerData: providerUserProfile.providerData
|
||||
});
|
||||
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 {
|
||||
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;
|
||||
// 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
|
||||
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;
|
||||
|
||||
// Then tell mongoose that we've updated the additionalProvidersData field
|
||||
user.markModified('additionalProvidersData');
|
||||
// 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(err, user);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
// And save the user
|
||||
user.save(function(err) {
|
||||
return done(err, user, '/#!/settings/accounts');
|
||||
});
|
||||
} else {
|
||||
return done(err, user);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Remove OAuth provider
|
||||
*/
|
||||
exports.removeOAuthProvider = function(req, res, next) {
|
||||
var user = req.user;
|
||||
var provider = req.param('provider');
|
||||
var user = req.user;
|
||||
var provider = req.param('provider');
|
||||
|
||||
if (user && provider) {
|
||||
// Delete the additional provider
|
||||
if (user.additionalProvidersData[provider]) {
|
||||
delete user.additionalProvidersData[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');
|
||||
}
|
||||
// Then tell mongoose that we've updated the additionalProvidersData field
|
||||
user.markModified('additionalProvidersData');
|
||||
}
|
||||
|
||||
user.save(function(err) {
|
||||
if (err) {
|
||||
return res.send(400, {
|
||||
message: getErrorMessage(err)
|
||||
});
|
||||
} else {
|
||||
req.login(user, function(err) {
|
||||
if (err) {
|
||||
res.send(400, err);
|
||||
} else {
|
||||
res.jsonp(user);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
user.save(function(err) {
|
||||
if (err) {
|
||||
return res.send(400, {
|
||||
message: getErrorMessage(err)
|
||||
});
|
||||
} else {
|
||||
req.login(user, function(err) {
|
||||
if (err) {
|
||||
res.send(400, err);
|
||||
} else {
|
||||
res.jsonp(user);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
@@ -4,31 +4,31 @@
|
||||
* Module dependencies.
|
||||
*/
|
||||
var mongoose = require('mongoose'),
|
||||
Schema = mongoose.Schema;
|
||||
Schema = mongoose.Schema;
|
||||
|
||||
/**
|
||||
* Article Schema
|
||||
*/
|
||||
var ArticleSchema = new Schema({
|
||||
created: {
|
||||
type: Date,
|
||||
default: Date.now
|
||||
},
|
||||
title: {
|
||||
type: String,
|
||||
default: '',
|
||||
trim: true,
|
||||
required: 'Title cannot be blank'
|
||||
},
|
||||
content: {
|
||||
type: String,
|
||||
default: '',
|
||||
trim: true
|
||||
},
|
||||
user: {
|
||||
type: Schema.ObjectId,
|
||||
ref: 'User'
|
||||
}
|
||||
created: {
|
||||
type: Date,
|
||||
default: Date.now
|
||||
},
|
||||
title: {
|
||||
type: String,
|
||||
default: '',
|
||||
trim: true,
|
||||
required: 'Title cannot be blank'
|
||||
},
|
||||
content: {
|
||||
type: String,
|
||||
default: '',
|
||||
trim: true
|
||||
},
|
||||
user: {
|
||||
type: Schema.ObjectId,
|
||||
ref: 'User'
|
||||
}
|
||||
});
|
||||
|
||||
mongoose.model('Article', ArticleSchema);
|
||||
mongoose.model('Article', ArticleSchema);
|
||||
|
||||
@@ -4,136 +4,136 @@
|
||||
* Module dependencies.
|
||||
*/
|
||||
var mongoose = require('mongoose'),
|
||||
Schema = mongoose.Schema,
|
||||
crypto = require('crypto');
|
||||
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);
|
||||
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));
|
||||
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: true,
|
||||
required: 'Please fill in a username',
|
||||
trim: true
|
||||
},
|
||||
password: {
|
||||
type: String,
|
||||
default: '',
|
||||
validate: [validateLocalStrategyPassword, 'Password should be longer']
|
||||
},
|
||||
salt: {
|
||||
type: String
|
||||
},
|
||||
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
|
||||
}
|
||||
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: true,
|
||||
required: 'Please fill in a username',
|
||||
trim: true
|
||||
},
|
||||
password: {
|
||||
type: String,
|
||||
default: '',
|
||||
validate: [validateLocalStrategyPassword, 'Password should be longer']
|
||||
},
|
||||
salt: {
|
||||
type: String
|
||||
},
|
||||
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
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
if (this.password && this.password.length > 6) {
|
||||
this.salt = new Buffer(crypto.randomBytes(16).toString('base64'), 'base64');
|
||||
this.password = this.hashPassword(this.password);
|
||||
}
|
||||
|
||||
next();
|
||||
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;
|
||||
}
|
||||
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);
|
||||
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 || '');
|
||||
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);
|
||||
}
|
||||
});
|
||||
_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);
|
||||
mongoose.model('User', UserSchema);
|
||||
|
||||
@@ -4,19 +4,19 @@
|
||||
* Module dependencies.
|
||||
*/
|
||||
var users = require('../../app/controllers/users'),
|
||||
articles = require('../../app/controllers/articles');
|
||||
articles = require('../../app/controllers/articles');
|
||||
|
||||
module.exports = function(app) {
|
||||
// Article Routes
|
||||
app.route('/articles')
|
||||
.get(articles.list)
|
||||
.post(users.requiresLogin, articles.create);
|
||||
|
||||
app.route('/articles/:articleId')
|
||||
.get(articles.read)
|
||||
.put(users.requiresLogin, articles.hasAuthorization, articles.update)
|
||||
.delete(users.requiresLogin, articles.hasAuthorization, articles.delete);
|
||||
// Article Routes
|
||||
app.route('/articles')
|
||||
.get(articles.list)
|
||||
.post(users.requiresLogin, articles.create);
|
||||
|
||||
// Finish by binding the article middleware
|
||||
app.param('articleId', articles.articleByID);
|
||||
};
|
||||
app.route('/articles/:articleId')
|
||||
.get(articles.read)
|
||||
.put(users.requiresLogin, articles.hasAuthorization, articles.update)
|
||||
.delete(users.requiresLogin, articles.hasAuthorization, articles.delete);
|
||||
|
||||
// Finish by binding the article middleware
|
||||
app.param('articleId', articles.articleByID);
|
||||
};
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
'use strict';
|
||||
|
||||
module.exports = function(app) {
|
||||
// Root routing
|
||||
var core = require('../../app/controllers/core');
|
||||
app.route('/').get(core.index);
|
||||
};
|
||||
// Root routing
|
||||
var core = require('../../app/controllers/core');
|
||||
app.route('/').get(core.index);
|
||||
};
|
||||
|
||||
@@ -6,41 +6,41 @@
|
||||
var passport = require('passport');
|
||||
|
||||
module.exports = function(app) {
|
||||
// User Routes
|
||||
var users = require('../../app/controllers/users');
|
||||
app.route('/users/me').get(users.me);
|
||||
app.route('/users').put(users.update);
|
||||
app.route('/users/password').post(users.changePassword);
|
||||
app.route('/users/accounts').delete(users.removeOAuthProvider);
|
||||
// User Routes
|
||||
var users = require('../../app/controllers/users');
|
||||
app.route('/users/me').get(users.me);
|
||||
app.route('/users').put(users.update);
|
||||
app.route('/users/password').post(users.changePassword);
|
||||
app.route('/users/accounts').delete(users.removeOAuthProvider);
|
||||
|
||||
// Setting up the users api
|
||||
app.route('/auth/signup').post(users.signup);
|
||||
app.route('/auth/signin').post(users.signin);
|
||||
app.route('/auth/signout').get(users.signout);
|
||||
// Setting up the users api
|
||||
app.route('/auth/signup').post(users.signup);
|
||||
app.route('/auth/signin').post(users.signin);
|
||||
app.route('/auth/signout').get(users.signout);
|
||||
|
||||
// Setting the facebook oauth routes
|
||||
app.route('/auth/facebook').get(passport.authenticate('facebook', {
|
||||
scope: ['email']
|
||||
}));
|
||||
app.route('/auth/facebook/callback').get(users.oauthCallback('facebook'));
|
||||
// Setting the facebook oauth routes
|
||||
app.route('/auth/facebook').get(passport.authenticate('facebook', {
|
||||
scope: ['email']
|
||||
}));
|
||||
app.route('/auth/facebook/callback').get(users.oauthCallback('facebook'));
|
||||
|
||||
// Setting the twitter oauth routes
|
||||
app.route('/auth/twitter').get(passport.authenticate('twitter'));
|
||||
app.route('/auth/twitter/callback').get(users.oauthCallback('twitter'));
|
||||
// Setting the twitter oauth routes
|
||||
app.route('/auth/twitter').get(passport.authenticate('twitter'));
|
||||
app.route('/auth/twitter/callback').get(users.oauthCallback('twitter'));
|
||||
|
||||
// Setting the google oauth routes
|
||||
app.route('/auth/google').get(passport.authenticate('google', {
|
||||
scope: [
|
||||
'https://www.googleapis.com/auth/userinfo.profile',
|
||||
'https://www.googleapis.com/auth/userinfo.email'
|
||||
]
|
||||
}));
|
||||
app.route('/auth/google/callback').get(users.oauthCallback('google'));
|
||||
// Setting the google oauth routes
|
||||
app.route('/auth/google').get(passport.authenticate('google', {
|
||||
scope: [
|
||||
'https://www.googleapis.com/auth/userinfo.profile',
|
||||
'https://www.googleapis.com/auth/userinfo.email'
|
||||
]
|
||||
}));
|
||||
app.route('/auth/google/callback').get(users.oauthCallback('google'));
|
||||
|
||||
// Setting the linkedin oauth routes
|
||||
app.route('/auth/linkedin').get(passport.authenticate('linkedin'));
|
||||
app.route('/auth/linkedin/callback').get(users.oauthCallback('linkedin'));
|
||||
// Setting the linkedin oauth routes
|
||||
app.route('/auth/linkedin').get(passport.authenticate('linkedin'));
|
||||
app.route('/auth/linkedin/callback').get(users.oauthCallback('linkedin'));
|
||||
|
||||
// Finish by binding the user middleware
|
||||
app.param('userId', users.userByID);
|
||||
// Finish by binding the user middleware
|
||||
app.param('userId', users.userByID);
|
||||
};
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
* Module dependencies.
|
||||
*/
|
||||
var should = require('should'),
|
||||
mongoose = require('mongoose'),
|
||||
User = mongoose.model('User'),
|
||||
Article = mongoose.model('Article');
|
||||
mongoose = require('mongoose'),
|
||||
User = mongoose.model('User'),
|
||||
Article = mongoose.model('Article');
|
||||
|
||||
/**
|
||||
* Globals
|
||||
@@ -17,48 +17,48 @@ var user, article;
|
||||
* Unit tests
|
||||
*/
|
||||
describe('Article Model Unit Tests:', function() {
|
||||
beforeEach(function(done) {
|
||||
user = new User({
|
||||
firstName: 'Full',
|
||||
lastName: 'Name',
|
||||
displayName: 'Full Name',
|
||||
email: 'test@test.com',
|
||||
username: 'username',
|
||||
password: 'password'
|
||||
});
|
||||
beforeEach(function(done) {
|
||||
user = new User({
|
||||
firstName: 'Full',
|
||||
lastName: 'Name',
|
||||
displayName: 'Full Name',
|
||||
email: 'test@test.com',
|
||||
username: 'username',
|
||||
password: 'password'
|
||||
});
|
||||
|
||||
user.save(function() {
|
||||
article = new Article({
|
||||
title: 'Article Title',
|
||||
content: 'Article Content',
|
||||
user: user
|
||||
});
|
||||
user.save(function() {
|
||||
article = new Article({
|
||||
title: 'Article Title',
|
||||
content: 'Article Content',
|
||||
user: user
|
||||
});
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
describe('Method Save', function() {
|
||||
it('should be able to save without problems', function(done) {
|
||||
return article.save(function(err) {
|
||||
should.not.exist(err);
|
||||
done();
|
||||
});
|
||||
});
|
||||
describe('Method Save', function() {
|
||||
it('should be able to save without problems', function(done) {
|
||||
return article.save(function(err) {
|
||||
should.not.exist(err);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should be able to show an error when try to save without title', function(done) {
|
||||
article.title = '';
|
||||
it('should be able to show an error when try to save without title', function(done) {
|
||||
article.title = '';
|
||||
|
||||
return article.save(function(err) {
|
||||
should.exist(err);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
return article.save(function(err) {
|
||||
should.exist(err);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(function(done) {
|
||||
Article.remove().exec();
|
||||
User.remove().exec();
|
||||
done();
|
||||
});
|
||||
});
|
||||
afterEach(function(done) {
|
||||
Article.remove().exec();
|
||||
User.remove().exec();
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
* Module dependencies.
|
||||
*/
|
||||
var should = require('should'),
|
||||
mongoose = require('mongoose'),
|
||||
User = mongoose.model('User');
|
||||
mongoose = require('mongoose'),
|
||||
User = mongoose.model('User');
|
||||
|
||||
/**
|
||||
* Globals
|
||||
@@ -16,60 +16,60 @@ var user, user2;
|
||||
* Unit tests
|
||||
*/
|
||||
describe('User Model Unit Tests:', function() {
|
||||
before(function(done) {
|
||||
user = new User({
|
||||
firstName: 'Full',
|
||||
lastName: 'Name',
|
||||
displayName: 'Full Name',
|
||||
email: 'test@test.com',
|
||||
username: 'username',
|
||||
password: 'password',
|
||||
provider: 'local'
|
||||
});
|
||||
user2 = new User({
|
||||
firstName: 'Full',
|
||||
lastName: 'Name',
|
||||
displayName: 'Full Name',
|
||||
email: 'test@test.com',
|
||||
username: 'username',
|
||||
password: 'password',
|
||||
provider: 'local'
|
||||
});
|
||||
before(function(done) {
|
||||
user = new User({
|
||||
firstName: 'Full',
|
||||
lastName: 'Name',
|
||||
displayName: 'Full Name',
|
||||
email: 'test@test.com',
|
||||
username: 'username',
|
||||
password: 'password',
|
||||
provider: 'local'
|
||||
});
|
||||
user2 = new User({
|
||||
firstName: 'Full',
|
||||
lastName: 'Name',
|
||||
displayName: 'Full Name',
|
||||
email: 'test@test.com',
|
||||
username: 'username',
|
||||
password: 'password',
|
||||
provider: 'local'
|
||||
});
|
||||
|
||||
done();
|
||||
});
|
||||
done();
|
||||
});
|
||||
|
||||
describe('Method Save', function() {
|
||||
it('should begin with no users', function(done) {
|
||||
User.find({}, function(err, users) {
|
||||
users.should.have.length(0);
|
||||
done();
|
||||
});
|
||||
});
|
||||
describe('Method Save', function() {
|
||||
it('should begin with no users', function(done) {
|
||||
User.find({}, function(err, users) {
|
||||
users.should.have.length(0);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should be able to save whithout problems', function(done) {
|
||||
user.save(done);
|
||||
});
|
||||
it('should be able to save whithout problems', function(done) {
|
||||
user.save(done);
|
||||
});
|
||||
|
||||
it('should fail to save an existing user again', function(done) {
|
||||
user.save();
|
||||
return user2.save(function(err) {
|
||||
should.exist(err);
|
||||
done();
|
||||
});
|
||||
});
|
||||
it('should fail to save an existing user again', function(done) {
|
||||
user.save();
|
||||
return user2.save(function(err) {
|
||||
should.exist(err);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should be able to show an error when try to save without first name', function(done) {
|
||||
user.firstName = '';
|
||||
return user.save(function(err) {
|
||||
should.exist(err);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
it('should be able to show an error when try to save without first name', function(done) {
|
||||
user.firstName = '';
|
||||
return user.save(function(err) {
|
||||
should.exist(err);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
after(function(done) {
|
||||
User.remove().exec();
|
||||
done();
|
||||
});
|
||||
});
|
||||
after(function(done) {
|
||||
User.remove().exec();
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -34,7 +34,7 @@ module.exports.getGlobbedFiles = function(globPatterns, removeRoot) {
|
||||
});
|
||||
} else if (_.isString(globPatterns)) {
|
||||
if (urlRegex.test(globPatterns)) {
|
||||
output.push(globPatterns);
|
||||
output.push(globPatterns);
|
||||
} else {
|
||||
glob(globPatterns, {
|
||||
sync: true
|
||||
@@ -73,4 +73,4 @@ module.exports.getJavaScriptAssets = function(includeTests) {
|
||||
module.exports.getCSSAssets = function() {
|
||||
var output = this.getGlobbedFiles(this.assets.lib.css.concat(this.assets.css), 'public/');
|
||||
return output;
|
||||
};
|
||||
};
|
||||
|
||||
76
config/env/all.js
vendored
76
config/env/all.js
vendored
@@ -1,42 +1,42 @@
|
||||
'use strict';
|
||||
|
||||
module.exports = {
|
||||
app: {
|
||||
title: 'MEAN.JS',
|
||||
description: 'Full-Stack JavaScript with MongoDB, Express, AngularJS, and Node.js',
|
||||
keywords: 'mongodb, express, angularjs, node.js, mongoose, passport'
|
||||
},
|
||||
port: process.env.PORT || 3000,
|
||||
templateEngine: 'swig',
|
||||
sessionSecret: 'MEAN',
|
||||
sessionCollection: 'sessions',
|
||||
assets: {
|
||||
lib: {
|
||||
css: [
|
||||
'public/lib/bootstrap/dist/css/bootstrap.css',
|
||||
'public/lib/bootstrap/dist/css/bootstrap-theme.css',
|
||||
],
|
||||
js: [
|
||||
'public/lib/angular/angular.js',
|
||||
'public/lib/angular-resource/angular-resource.js',
|
||||
'public/lib/angular-animate/angular-animate.js',
|
||||
'public/lib/angular-ui-router/release/angular-ui-router.js',
|
||||
'public/lib/angular-ui-utils/ui-utils.js',
|
||||
'public/lib/angular-bootstrap/ui-bootstrap-tpls.js'
|
||||
]
|
||||
},
|
||||
css: [
|
||||
'public/modules/**/css/*.css'
|
||||
],
|
||||
js: [
|
||||
'public/config.js',
|
||||
'public/application.js',
|
||||
'public/modules/*/*.js',
|
||||
'public/modules/*/*[!tests]*/*.js'
|
||||
],
|
||||
tests: [
|
||||
'public/lib/angular-mocks/angular-mocks.js',
|
||||
'public/modules/*/tests/*.js'
|
||||
]
|
||||
}
|
||||
app: {
|
||||
title: 'MEAN.JS',
|
||||
description: 'Full-Stack JavaScript with MongoDB, Express, AngularJS, and Node.js',
|
||||
keywords: 'mongodb, express, angularjs, node.js, mongoose, passport'
|
||||
},
|
||||
port: process.env.PORT || 3000,
|
||||
templateEngine: 'swig',
|
||||
sessionSecret: 'MEAN',
|
||||
sessionCollection: 'sessions',
|
||||
assets: {
|
||||
lib: {
|
||||
css: [
|
||||
'public/lib/bootstrap/dist/css/bootstrap.css',
|
||||
'public/lib/bootstrap/dist/css/bootstrap-theme.css',
|
||||
],
|
||||
js: [
|
||||
'public/lib/angular/angular.js',
|
||||
'public/lib/angular-resource/angular-resource.js',
|
||||
'public/lib/angular-animate/angular-animate.js',
|
||||
'public/lib/angular-ui-router/release/angular-ui-router.js',
|
||||
'public/lib/angular-ui-utils/ui-utils.js',
|
||||
'public/lib/angular-bootstrap/ui-bootstrap-tpls.js'
|
||||
]
|
||||
},
|
||||
css: [
|
||||
'public/modules/**/css/*.css'
|
||||
],
|
||||
js: [
|
||||
'public/config.js',
|
||||
'public/application.js',
|
||||
'public/modules/*/*.js',
|
||||
'public/modules/*/*[!tests]*/*.js'
|
||||
],
|
||||
tests: [
|
||||
'public/lib/angular-mocks/angular-mocks.js',
|
||||
'public/modules/*/tests/*.js'
|
||||
]
|
||||
}
|
||||
};
|
||||
|
||||
48
config/env/development.js
vendored
48
config/env/development.js
vendored
@@ -1,28 +1,28 @@
|
||||
'use strict';
|
||||
|
||||
module.exports = {
|
||||
db: 'mongodb://localhost/mean-dev',
|
||||
app: {
|
||||
title: 'MEAN.JS - Development Environment'
|
||||
},
|
||||
facebook: {
|
||||
clientID: process.env.FACEBOOK_ID || 'APP_ID',
|
||||
clientSecret: process.env.FACEBOOK_SECRET || 'APP_SECRET',
|
||||
callbackURL: 'http://localhost:3000/auth/facebook/callback'
|
||||
},
|
||||
twitter: {
|
||||
clientID: process.env.TWITTER_KEY || 'CONSUMER_KEY',
|
||||
clientSecret: process.env.TWITTER_SECRET || 'CONSUMER_SECRET',
|
||||
callbackURL: 'http://localhost:3000/auth/twitter/callback'
|
||||
},
|
||||
google: {
|
||||
clientID: process.env.GOOGLE_ID || 'APP_ID',
|
||||
clientSecret: process.env.GOOGLE_SECRET || 'APP_SECRET',
|
||||
callbackURL: 'http://localhost:3000/auth/google/callback'
|
||||
},
|
||||
linkedin: {
|
||||
clientID: process.env.LINKEDIN_ID || 'APP_ID',
|
||||
clientSecret: process.env.LINKEDIN_SECRET || 'APP_SECRET',
|
||||
callbackURL: 'http://localhost:3000/auth/linkedin/callback'
|
||||
}
|
||||
db: 'mongodb://localhost/mean-dev',
|
||||
app: {
|
||||
title: 'MEAN.JS - Development Environment'
|
||||
},
|
||||
facebook: {
|
||||
clientID: process.env.FACEBOOK_ID || 'APP_ID',
|
||||
clientSecret: process.env.FACEBOOK_SECRET || 'APP_SECRET',
|
||||
callbackURL: 'http://localhost:3000/auth/facebook/callback'
|
||||
},
|
||||
twitter: {
|
||||
clientID: process.env.TWITTER_KEY || 'CONSUMER_KEY',
|
||||
clientSecret: process.env.TWITTER_SECRET || 'CONSUMER_SECRET',
|
||||
callbackURL: 'http://localhost:3000/auth/twitter/callback'
|
||||
},
|
||||
google: {
|
||||
clientID: process.env.GOOGLE_ID || 'APP_ID',
|
||||
clientSecret: process.env.GOOGLE_SECRET || 'APP_SECRET',
|
||||
callbackURL: 'http://localhost:3000/auth/google/callback'
|
||||
},
|
||||
linkedin: {
|
||||
clientID: process.env.LINKEDIN_ID || 'APP_ID',
|
||||
clientSecret: process.env.LINKEDIN_SECRET || 'APP_SECRET',
|
||||
callbackURL: 'http://localhost:3000/auth/linkedin/callback'
|
||||
}
|
||||
};
|
||||
|
||||
78
config/env/production.js
vendored
78
config/env/production.js
vendored
@@ -1,43 +1,43 @@
|
||||
'use strict';
|
||||
|
||||
module.exports = {
|
||||
db: process.env.MONGOHQ_URL || process.env.MONGOLAB_URI || 'mongodb://localhost/mean',
|
||||
assets: {
|
||||
lib: {
|
||||
css: [
|
||||
'public/lib/bootstrap/dist/css/bootstrap.min.css',
|
||||
'public/lib/bootstrap/dist/css/bootstrap-theme.min.css',
|
||||
],
|
||||
js: [
|
||||
'public/lib/angular/angular.min.js',
|
||||
'public/lib/angular-resource/angular-resource.min.js',
|
||||
'public/lib/angular-animate/angular-animate.min.js',
|
||||
'public/lib/angular-ui-router/release/angular-ui-router.min.js',
|
||||
'public/lib/angular-ui-utils/ui-utils.min.js',
|
||||
'public/lib/angular-bootstrap/ui-bootstrap-tpls.min.js'
|
||||
]
|
||||
},
|
||||
css: 'public/dist/application.min.css',
|
||||
js: 'public/dist/application.min.js'
|
||||
},
|
||||
facebook: {
|
||||
clientID: process.env.FACEBOOK_ID || 'APP_ID',
|
||||
clientSecret: process.env.FACEBOOK_SECRET || 'APP_SECRET',
|
||||
callbackURL: 'http://localhost:3000/auth/facebook/callback'
|
||||
},
|
||||
twitter: {
|
||||
clientID: process.env.TWITTER_KEY || 'CONSUMER_KEY',
|
||||
clientSecret: process.env.TWITTER_SECRET || 'CONSUMER_SECRET',
|
||||
callbackURL: 'http://localhost:3000/auth/twitter/callback'
|
||||
},
|
||||
google: {
|
||||
clientID: process.env.GOOGLE_ID || 'APP_ID',
|
||||
clientSecret: process.env.GOOGLE_SECRET || 'APP_SECRET',
|
||||
callbackURL: 'http://localhost:3000/auth/google/callback'
|
||||
},
|
||||
linkedin: {
|
||||
clientID: process.env.LINKEDIN_ID || 'APP_ID',
|
||||
clientSecret: process.env.LINKEDIN_SECRET || 'APP_SECRET',
|
||||
callbackURL: 'http://localhost:3000/auth/linkedin/callback'
|
||||
}
|
||||
db: process.env.MONGOHQ_URL || process.env.MONGOLAB_URI || 'mongodb://localhost/mean',
|
||||
assets: {
|
||||
lib: {
|
||||
css: [
|
||||
'public/lib/bootstrap/dist/css/bootstrap.min.css',
|
||||
'public/lib/bootstrap/dist/css/bootstrap-theme.min.css',
|
||||
],
|
||||
js: [
|
||||
'public/lib/angular/angular.min.js',
|
||||
'public/lib/angular-resource/angular-resource.min.js',
|
||||
'public/lib/angular-animate/angular-animate.min.js',
|
||||
'public/lib/angular-ui-router/release/angular-ui-router.min.js',
|
||||
'public/lib/angular-ui-utils/ui-utils.min.js',
|
||||
'public/lib/angular-bootstrap/ui-bootstrap-tpls.min.js'
|
||||
]
|
||||
},
|
||||
css: 'public/dist/application.min.css',
|
||||
js: 'public/dist/application.min.js'
|
||||
},
|
||||
facebook: {
|
||||
clientID: process.env.FACEBOOK_ID || 'APP_ID',
|
||||
clientSecret: process.env.FACEBOOK_SECRET || 'APP_SECRET',
|
||||
callbackURL: 'http://localhost:3000/auth/facebook/callback'
|
||||
},
|
||||
twitter: {
|
||||
clientID: process.env.TWITTER_KEY || 'CONSUMER_KEY',
|
||||
clientSecret: process.env.TWITTER_SECRET || 'CONSUMER_SECRET',
|
||||
callbackURL: 'http://localhost:3000/auth/twitter/callback'
|
||||
},
|
||||
google: {
|
||||
clientID: process.env.GOOGLE_ID || 'APP_ID',
|
||||
clientSecret: process.env.GOOGLE_SECRET || 'APP_SECRET',
|
||||
callbackURL: 'http://localhost:3000/auth/google/callback'
|
||||
},
|
||||
linkedin: {
|
||||
clientID: process.env.LINKEDIN_ID || 'APP_ID',
|
||||
clientSecret: process.env.LINKEDIN_SECRET || 'APP_SECRET',
|
||||
callbackURL: 'http://localhost:3000/auth/linkedin/callback'
|
||||
}
|
||||
};
|
||||
|
||||
50
config/env/test.js
vendored
50
config/env/test.js
vendored
@@ -1,29 +1,29 @@
|
||||
'use strict';
|
||||
|
||||
module.exports = {
|
||||
db: 'mongodb://localhost/mean-test',
|
||||
port: 3001,
|
||||
app: {
|
||||
title: 'MEAN.JS - Test Environment'
|
||||
},
|
||||
facebook: {
|
||||
clientID: process.env.FACEBOOK_ID || 'APP_ID',
|
||||
clientSecret: process.env.FACEBOOK_SECRET || 'APP_SECRET',
|
||||
callbackURL: 'http://localhost:3000/auth/facebook/callback'
|
||||
},
|
||||
twitter: {
|
||||
clientID: process.env.TWITTER_KEY || 'CONSUMER_KEY',
|
||||
clientSecret: process.env.TWITTER_SECRET || 'CONSUMER_SECRET',
|
||||
callbackURL: 'http://localhost:3000/auth/twitter/callback'
|
||||
},
|
||||
google: {
|
||||
clientID: process.env.GOOGLE_ID || 'APP_ID',
|
||||
clientSecret: process.env.GOOGLE_SECRET || 'APP_SECRET',
|
||||
callbackURL: 'http://localhost:3000/auth/google/callback'
|
||||
},
|
||||
linkedin: {
|
||||
clientID: process.env.LINKEDIN_ID || 'APP_ID',
|
||||
clientSecret: process.env.LINKEDIN_SECRET || 'APP_SECRET',
|
||||
callbackURL: 'http://localhost:3000/auth/linkedin/callback'
|
||||
}
|
||||
db: 'mongodb://localhost/mean-test',
|
||||
port: 3001,
|
||||
app: {
|
||||
title: 'MEAN.JS - Test Environment'
|
||||
},
|
||||
facebook: {
|
||||
clientID: process.env.FACEBOOK_ID || 'APP_ID',
|
||||
clientSecret: process.env.FACEBOOK_SECRET || 'APP_SECRET',
|
||||
callbackURL: 'http://localhost:3000/auth/facebook/callback'
|
||||
},
|
||||
twitter: {
|
||||
clientID: process.env.TWITTER_KEY || 'CONSUMER_KEY',
|
||||
clientSecret: process.env.TWITTER_SECRET || 'CONSUMER_SECRET',
|
||||
callbackURL: 'http://localhost:3000/auth/twitter/callback'
|
||||
},
|
||||
google: {
|
||||
clientID: process.env.GOOGLE_ID || 'APP_ID',
|
||||
clientSecret: process.env.GOOGLE_SECRET || 'APP_SECRET',
|
||||
callbackURL: 'http://localhost:3000/auth/google/callback'
|
||||
},
|
||||
linkedin: {
|
||||
clientID: process.env.LINKEDIN_ID || 'APP_ID',
|
||||
clientSecret: process.env.LINKEDIN_SECRET || 'APP_SECRET',
|
||||
callbackURL: 'http://localhost:3000/auth/linkedin/callback'
|
||||
}
|
||||
};
|
||||
|
||||
@@ -4,137 +4,137 @@
|
||||
* Module dependencies.
|
||||
*/
|
||||
var express = require('express'),
|
||||
morgan = require('morgan'),
|
||||
bodyParser = require('body-parser'),
|
||||
session = require('express-session'),
|
||||
compress = require('compression'),
|
||||
methodOverride = require('method-override'),
|
||||
cookieParser = require('cookie-parser'),
|
||||
helmet = require('helmet'),
|
||||
passport = require('passport'),
|
||||
mongoStore = require('connect-mongo')({
|
||||
session: session
|
||||
}),
|
||||
flash = require('connect-flash'),
|
||||
config = require('./config'),
|
||||
consolidate = require('consolidate'),
|
||||
path = require('path');
|
||||
morgan = require('morgan'),
|
||||
bodyParser = require('body-parser'),
|
||||
session = require('express-session'),
|
||||
compress = require('compression'),
|
||||
methodOverride = require('method-override'),
|
||||
cookieParser = require('cookie-parser'),
|
||||
helmet = require('helmet'),
|
||||
passport = require('passport'),
|
||||
mongoStore = require('connect-mongo')({
|
||||
session: session
|
||||
}),
|
||||
flash = require('connect-flash'),
|
||||
config = require('./config'),
|
||||
consolidate = require('consolidate'),
|
||||
path = require('path');
|
||||
|
||||
module.exports = function(db) {
|
||||
// Initialize express app
|
||||
var app = express();
|
||||
// Initialize express app
|
||||
var app = express();
|
||||
|
||||
// Globbing model files
|
||||
config.getGlobbedFiles('./app/models/**/*.js').forEach(function(modelPath) {
|
||||
require(path.resolve(modelPath));
|
||||
});
|
||||
// Globbing model files
|
||||
config.getGlobbedFiles('./app/models/**/*.js').forEach(function(modelPath) {
|
||||
require(path.resolve(modelPath));
|
||||
});
|
||||
|
||||
// Setting application local variables
|
||||
app.locals.title = config.app.title;
|
||||
app.locals.description = config.app.description;
|
||||
app.locals.keywords = config.app.keywords;
|
||||
app.locals.facebookAppId = config.facebook.clientID;
|
||||
app.locals.jsFiles = config.getJavaScriptAssets();
|
||||
app.locals.cssFiles = config.getCSSAssets();
|
||||
// Setting application local variables
|
||||
app.locals.title = config.app.title;
|
||||
app.locals.description = config.app.description;
|
||||
app.locals.keywords = config.app.keywords;
|
||||
app.locals.facebookAppId = config.facebook.clientID;
|
||||
app.locals.jsFiles = config.getJavaScriptAssets();
|
||||
app.locals.cssFiles = config.getCSSAssets();
|
||||
|
||||
// Passing the request url to environment locals
|
||||
app.use(function(req, res, next) {
|
||||
res.locals.url = req.protocol + ':// ' + req.headers.host + req.url;
|
||||
next();
|
||||
});
|
||||
// Passing the request url to environment locals
|
||||
app.use(function(req, res, next) {
|
||||
res.locals.url = req.protocol + ':// ' + req.headers.host + req.url;
|
||||
next();
|
||||
});
|
||||
|
||||
// Should be placed before express.static
|
||||
app.use(compress({
|
||||
filter: function(req, res) {
|
||||
return (/json|text|javascript|css/).test(res.getHeader('Content-Type'));
|
||||
},
|
||||
level: 9
|
||||
}));
|
||||
// Should be placed before express.static
|
||||
app.use(compress({
|
||||
filter: function(req, res) {
|
||||
return (/json|text|javascript|css/).test(res.getHeader('Content-Type'));
|
||||
},
|
||||
level: 9
|
||||
}));
|
||||
|
||||
// Showing stack errors
|
||||
app.set('showStackError', true);
|
||||
// Showing stack errors
|
||||
app.set('showStackError', true);
|
||||
|
||||
// Set swig as the template engine
|
||||
app.engine('server.view.html', consolidate[config.templateEngine]);
|
||||
// Set swig as the template engine
|
||||
app.engine('server.view.html', consolidate[config.templateEngine]);
|
||||
|
||||
// Set views path and view engine
|
||||
app.set('view engine', 'server.view.html');
|
||||
app.set('views', './app/views');
|
||||
// Set views path and view engine
|
||||
app.set('view engine', 'server.view.html');
|
||||
app.set('views', './app/views');
|
||||
|
||||
// Environment dependent middleware
|
||||
if (process.env.NODE_ENV === 'development') {
|
||||
// Enable logger (morgan)
|
||||
app.use(morgan('dev'));
|
||||
// Environment dependent middleware
|
||||
if (process.env.NODE_ENV === 'development') {
|
||||
// Enable logger (morgan)
|
||||
app.use(morgan('dev'));
|
||||
|
||||
// Disable views cache
|
||||
app.set('view cache', false);
|
||||
} else if (process.env.NODE_ENV === 'production') {
|
||||
app.locals.cache = 'memory';
|
||||
}
|
||||
// Disable views cache
|
||||
app.set('view cache', false);
|
||||
} else if (process.env.NODE_ENV === 'production') {
|
||||
app.locals.cache = 'memory';
|
||||
}
|
||||
|
||||
// Request body parsing middleware should be above methodOverride
|
||||
app.use(bodyParser.urlencoded());
|
||||
app.use(bodyParser.json());
|
||||
app.use(methodOverride());
|
||||
// Request body parsing middleware should be above methodOverride
|
||||
app.use(bodyParser.urlencoded());
|
||||
app.use(bodyParser.json());
|
||||
app.use(methodOverride());
|
||||
|
||||
// Enable jsonp
|
||||
app.enable('jsonp callback');
|
||||
// Enable jsonp
|
||||
app.enable('jsonp callback');
|
||||
|
||||
// CookieParser should be above session
|
||||
app.use(cookieParser());
|
||||
// CookieParser should be above session
|
||||
app.use(cookieParser());
|
||||
|
||||
// Express MongoDB session storage
|
||||
app.use(session({
|
||||
secret: config.sessionSecret,
|
||||
store: new mongoStore({
|
||||
db: db.connection.db,
|
||||
collection: config.sessionCollection
|
||||
})
|
||||
}));
|
||||
// Express MongoDB session storage
|
||||
app.use(session({
|
||||
secret: config.sessionSecret,
|
||||
store: new mongoStore({
|
||||
db: db.connection.db,
|
||||
collection: config.sessionCollection
|
||||
})
|
||||
}));
|
||||
|
||||
// use passport session
|
||||
app.use(passport.initialize());
|
||||
app.use(passport.session());
|
||||
// use passport session
|
||||
app.use(passport.initialize());
|
||||
app.use(passport.session());
|
||||
|
||||
// connect flash for flash messages
|
||||
app.use(flash());
|
||||
// connect flash for flash messages
|
||||
app.use(flash());
|
||||
|
||||
// Use helmet to secure Express headers
|
||||
app.use(helmet.xframe());
|
||||
app.use(helmet.iexss());
|
||||
app.use(helmet.contentTypeOptions());
|
||||
app.use(helmet.ienoopen());
|
||||
app.disable('x-powered-by');
|
||||
|
||||
// Setting the app router and static folder
|
||||
app.use(express.static(path.resolve('./public')));
|
||||
// Use helmet to secure Express headers
|
||||
app.use(helmet.xframe());
|
||||
app.use(helmet.iexss());
|
||||
app.use(helmet.contentTypeOptions());
|
||||
app.use(helmet.ienoopen());
|
||||
app.disable('x-powered-by');
|
||||
|
||||
// Globbing routing files
|
||||
config.getGlobbedFiles('./app/routes/**/*.js').forEach(function(routePath) {
|
||||
require(path.resolve(routePath))(app);
|
||||
});
|
||||
// Setting the app router and static folder
|
||||
app.use(express.static(path.resolve('./public')));
|
||||
|
||||
// Assume 'not found' in the error msgs is a 404. this is somewhat silly, but valid, you can do whatever you like, set properties, use instanceof etc.
|
||||
app.use(function(err, req, res, next) {
|
||||
// If the error object doesn't exists
|
||||
if (!err) return next();
|
||||
// Globbing routing files
|
||||
config.getGlobbedFiles('./app/routes/**/*.js').forEach(function(routePath) {
|
||||
require(path.resolve(routePath))(app);
|
||||
});
|
||||
|
||||
// Log it
|
||||
console.error(err.stack);
|
||||
// Assume 'not found' in the error msgs is a 404. this is somewhat silly, but valid, you can do whatever you like, set properties, use instanceof etc.
|
||||
app.use(function(err, req, res, next) {
|
||||
// If the error object doesn't exists
|
||||
if (!err) return next();
|
||||
|
||||
// Error page
|
||||
res.status(500).render('500', {
|
||||
error: err.stack
|
||||
});
|
||||
});
|
||||
// Log it
|
||||
console.error(err.stack);
|
||||
|
||||
// Assume 404 since no middleware responded
|
||||
app.use(function(req, res) {
|
||||
res.status(404).render('404', {
|
||||
url: req.originalUrl,
|
||||
error: 'Not Found'
|
||||
});
|
||||
});
|
||||
// Error page
|
||||
res.status(500).render('500', {
|
||||
error: err.stack
|
||||
});
|
||||
});
|
||||
|
||||
return app;
|
||||
// Assume 404 since no middleware responded
|
||||
app.use(function(req, res) {
|
||||
res.status(404).render('404', {
|
||||
url: req.originalUrl,
|
||||
error: 'Not Found'
|
||||
});
|
||||
});
|
||||
|
||||
return app;
|
||||
};
|
||||
|
||||
@@ -16,19 +16,19 @@ module.exports = function() {
|
||||
glob('./config/env/' + process.env.NODE_ENV + '.js', {
|
||||
sync: true
|
||||
}, function(err, environmentFiles) {
|
||||
console.log();
|
||||
if (!environmentFiles.length) {
|
||||
if(process.env.NODE_ENV) {
|
||||
console.log('\x1b[31m', 'No configuration file found for "' + process.env.NODE_ENV + '" environment using development instead');
|
||||
} else {
|
||||
console.log('\x1b[31m', 'NODE_ENV is not defined! Using default development environment');
|
||||
}
|
||||
console.log();
|
||||
if (!environmentFiles.length) {
|
||||
if (process.env.NODE_ENV) {
|
||||
console.log('\x1b[31m', 'No configuration file found for "' + process.env.NODE_ENV + '" environment using development instead');
|
||||
} else {
|
||||
console.log('\x1b[31m', 'NODE_ENV is not defined! Using default development environment');
|
||||
}
|
||||
|
||||
process.env.NODE_ENV = 'development';
|
||||
} else {
|
||||
console.log('\x1b[7m', 'Application loaded using the "' + process.env.NODE_ENV + '" environment configuration');
|
||||
}
|
||||
console.log('\x1b[0m');
|
||||
process.env.NODE_ENV = 'development';
|
||||
} else {
|
||||
console.log('\x1b[7m', 'Application loaded using the "' + process.env.NODE_ENV + '" environment configuration');
|
||||
}
|
||||
console.log('\x1b[0m');
|
||||
});
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,27 +1,27 @@
|
||||
'use strict';
|
||||
|
||||
var passport = require('passport'),
|
||||
User = require('mongoose').model('User'),
|
||||
path = require('path'),
|
||||
config = require('./config');
|
||||
User = require('mongoose').model('User'),
|
||||
path = require('path'),
|
||||
config = require('./config');
|
||||
|
||||
module.exports = function() {
|
||||
// Serialize sessions
|
||||
passport.serializeUser(function(user, done) {
|
||||
done(null, user.id);
|
||||
});
|
||||
// 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);
|
||||
});
|
||||
});
|
||||
// Deserialize sessions
|
||||
passport.deserializeUser(function(id, done) {
|
||||
User.findOne({
|
||||
_id: id
|
||||
}, '-salt -password', function(err, user) {
|
||||
done(err, user);
|
||||
});
|
||||
});
|
||||
|
||||
// Initialize strategies
|
||||
config.getGlobbedFiles('./config/strategies/**/*.js').forEach(function(strategy) {
|
||||
require(path.resolve(strategy))();
|
||||
});
|
||||
};
|
||||
// Initialize strategies
|
||||
config.getGlobbedFiles('./config/strategies/**/*.js').forEach(function(strategy) {
|
||||
require(path.resolve(strategy))();
|
||||
});
|
||||
};
|
||||
|
||||
@@ -4,39 +4,39 @@
|
||||
* Module dependencies.
|
||||
*/
|
||||
var passport = require('passport'),
|
||||
url = require('url'),
|
||||
FacebookStrategy = require('passport-facebook').Strategy,
|
||||
config = require('../config'),
|
||||
users = require('../../app/controllers/users');
|
||||
url = require('url'),
|
||||
FacebookStrategy = require('passport-facebook').Strategy,
|
||||
config = require('../config'),
|
||||
users = require('../../app/controllers/users');
|
||||
|
||||
module.exports = function() {
|
||||
// Use facebook strategy
|
||||
passport.use(new FacebookStrategy({
|
||||
clientID: config.facebook.clientID,
|
||||
clientSecret: config.facebook.clientSecret,
|
||||
callbackURL: config.facebook.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;
|
||||
// Use facebook strategy
|
||||
passport.use(new FacebookStrategy({
|
||||
clientID: config.facebook.clientID,
|
||||
clientSecret: config.facebook.clientSecret,
|
||||
callbackURL: config.facebook.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,
|
||||
provider: 'facebook',
|
||||
providerIdentifierField: 'id',
|
||||
providerData: providerData
|
||||
};
|
||||
// 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,
|
||||
provider: 'facebook',
|
||||
providerIdentifierField: 'id',
|
||||
providerData: providerData
|
||||
};
|
||||
|
||||
// Save the user OAuth profile
|
||||
users.saveOAuthUserProfile(req, providerUserProfile, done);
|
||||
}
|
||||
));
|
||||
// Save the user OAuth profile
|
||||
users.saveOAuthUserProfile(req, providerUserProfile, done);
|
||||
}
|
||||
));
|
||||
};
|
||||
|
||||
@@ -39,4 +39,4 @@ module.exports = function() {
|
||||
users.saveOAuthUserProfile(req, providerUserProfile, done);
|
||||
}
|
||||
));
|
||||
};
|
||||
};
|
||||
|
||||
@@ -4,40 +4,40 @@
|
||||
* Module dependencies.
|
||||
*/
|
||||
var passport = require('passport'),
|
||||
url = require('url'),
|
||||
LinkedInStrategy = require('passport-linkedin').Strategy,
|
||||
config = require('../config'),
|
||||
users = require('../../app/controllers/users');
|
||||
url = require('url'),
|
||||
LinkedInStrategy = require('passport-linkedin').Strategy,
|
||||
config = require('../config'),
|
||||
users = require('../../app/controllers/users');
|
||||
|
||||
module.exports = function() {
|
||||
// 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']
|
||||
},
|
||||
function(req, accessToken, refreshToken, profile, done) {
|
||||
// Set the provider data and include tokens
|
||||
var providerData = profile._json;
|
||||
providerData.accessToken = accessToken;
|
||||
providerData.refreshToken = refreshToken;
|
||||
// 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']
|
||||
},
|
||||
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,
|
||||
provider: 'linkedin',
|
||||
providerIdentifierField: 'id',
|
||||
providerData: providerData
|
||||
};
|
||||
// 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,
|
||||
provider: 'linkedin',
|
||||
providerIdentifierField: 'id',
|
||||
providerData: providerData
|
||||
};
|
||||
|
||||
// Save the user OAuth profile
|
||||
users.saveOAuthUserProfile(req, providerUserProfile, done);
|
||||
}
|
||||
));
|
||||
// Save the user OAuth profile
|
||||
users.saveOAuthUserProfile(req, providerUserProfile, done);
|
||||
}
|
||||
));
|
||||
};
|
||||
|
||||
@@ -4,35 +4,35 @@
|
||||
* Module dependencies.
|
||||
*/
|
||||
var passport = require('passport'),
|
||||
LocalStrategy = require('passport-local').Strategy,
|
||||
User = require('mongoose').model('User');
|
||||
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);
|
||||
});
|
||||
}
|
||||
));
|
||||
};
|
||||
// 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);
|
||||
});
|
||||
}
|
||||
));
|
||||
};
|
||||
|
||||
@@ -4,36 +4,36 @@
|
||||
* Module dependencies.
|
||||
*/
|
||||
var passport = require('passport'),
|
||||
url = require('url'),
|
||||
TwitterStrategy = require('passport-twitter').Strategy,
|
||||
config = require('../config'),
|
||||
users = require('../../app/controllers/users');
|
||||
url = require('url'),
|
||||
TwitterStrategy = require('passport-twitter').Strategy,
|
||||
config = require('../config'),
|
||||
users = require('../../app/controllers/users');
|
||||
|
||||
module.exports = function() {
|
||||
// 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;
|
||||
// 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,
|
||||
provider: 'twitter',
|
||||
providerIdentifierField: 'id_str',
|
||||
providerData: providerData
|
||||
};
|
||||
// Create the user OAuth profile
|
||||
var providerUserProfile = {
|
||||
displayName: profile.displayName,
|
||||
username: profile.username,
|
||||
provider: 'twitter',
|
||||
providerIdentifierField: 'id_str',
|
||||
providerData: providerData
|
||||
};
|
||||
|
||||
// Save the user OAuth profile
|
||||
users.saveOAuthUserProfile(req, providerUserProfile, done);
|
||||
}
|
||||
));
|
||||
// Save the user OAuth profile
|
||||
users.saveOAuthUserProfile(req, providerUserProfile, done);
|
||||
}
|
||||
));
|
||||
};
|
||||
|
||||
12
gruntfile.js
12
gruntfile.js
@@ -113,11 +113,11 @@ module.exports = function(grunt) {
|
||||
|
||||
// A Task for loading the configuration object
|
||||
grunt.task.registerTask('loadConfig', 'Task that loads the config into a grunt option.', function() {
|
||||
var init = require('./config/init')();
|
||||
var config = require('./config/config');
|
||||
var init = require('./config/init')();
|
||||
var config = require('./config/config');
|
||||
|
||||
grunt.config.set('applicationJavaScriptFiles', config.assets.js);
|
||||
grunt.config.set('applicationCSSFiles', config.assets.css);
|
||||
grunt.config.set('applicationJavaScriptFiles', config.assets.js);
|
||||
grunt.config.set('applicationCSSFiles', config.assets.css);
|
||||
});
|
||||
|
||||
// Default task(s).
|
||||
@@ -127,8 +127,8 @@ module.exports = function(grunt) {
|
||||
grunt.registerTask('lint', ['jshint', 'csslint']);
|
||||
|
||||
// Build task(s).
|
||||
grunt.registerTask('build', ['jshint', 'csslint', 'loadConfig' ,'uglify', 'cssmin']);
|
||||
grunt.registerTask('build', ['jshint', 'csslint', 'loadConfig', 'uglify', 'cssmin']);
|
||||
|
||||
// Test task.
|
||||
grunt.registerTask('test', ['env:test', 'mochaTest', 'karma:unit']);
|
||||
};
|
||||
};
|
||||
|
||||
@@ -7,46 +7,46 @@ var applicationConfiguration = require('./config/config');
|
||||
|
||||
// Karma configuration
|
||||
module.exports = function(config) {
|
||||
config.set({
|
||||
// Frameworks to use
|
||||
frameworks: ['jasmine'],
|
||||
config.set({
|
||||
// Frameworks to use
|
||||
frameworks: ['jasmine'],
|
||||
|
||||
// List of files / patterns to load in the browser
|
||||
files: applicationConfiguration.assets.lib.js.concat(applicationConfiguration.assets.js, applicationConfiguration.assets.tests),
|
||||
// List of files / patterns to load in the browser
|
||||
files: applicationConfiguration.assets.lib.js.concat(applicationConfiguration.assets.js, applicationConfiguration.assets.tests),
|
||||
|
||||
// Test results reporter to use
|
||||
// Possible values: 'dots', 'progress', 'junit', 'growl', 'coverage'
|
||||
//reporters: ['progress'],
|
||||
reporters: ['progress'],
|
||||
// Test results reporter to use
|
||||
// Possible values: 'dots', 'progress', 'junit', 'growl', 'coverage'
|
||||
//reporters: ['progress'],
|
||||
reporters: ['progress'],
|
||||
|
||||
// Web server port
|
||||
port: 9876,
|
||||
// Web server port
|
||||
port: 9876,
|
||||
|
||||
// Enable / disable colors in the output (reporters and logs)
|
||||
colors: true,
|
||||
// Enable / disable colors in the output (reporters and logs)
|
||||
colors: true,
|
||||
|
||||
// Level of logging
|
||||
// Possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
|
||||
logLevel: config.LOG_INFO,
|
||||
// Level of logging
|
||||
// Possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
|
||||
logLevel: config.LOG_INFO,
|
||||
|
||||
// Enable / disable watching file and executing tests whenever any file changes
|
||||
autoWatch: true,
|
||||
// Enable / disable watching file and executing tests whenever any file changes
|
||||
autoWatch: true,
|
||||
|
||||
// Start these browsers, currently available:
|
||||
// - Chrome
|
||||
// - ChromeCanary
|
||||
// - Firefox
|
||||
// - Opera
|
||||
// - Safari (only Mac)
|
||||
// - PhantomJS
|
||||
// - IE (only Windows)
|
||||
browsers: ['PhantomJS'],
|
||||
// Start these browsers, currently available:
|
||||
// - Chrome
|
||||
// - ChromeCanary
|
||||
// - Firefox
|
||||
// - Opera
|
||||
// - Safari (only Mac)
|
||||
// - PhantomJS
|
||||
// - IE (only Windows)
|
||||
browsers: ['PhantomJS'],
|
||||
|
||||
// If browser does not capture in given timeout [ms], kill it
|
||||
captureTimeout: 60000,
|
||||
// If browser does not capture in given timeout [ms], kill it
|
||||
captureTimeout: 60000,
|
||||
|
||||
// Continuous Integration mode
|
||||
// If true, it capture browsers, run tests and exit
|
||||
singleRun: true
|
||||
});
|
||||
// Continuous Integration mode
|
||||
// If true, it capture browsers, run tests and exit
|
||||
singleRun: true
|
||||
});
|
||||
};
|
||||
|
||||
@@ -5,16 +5,16 @@ angular.module(ApplicationConfiguration.applicationModuleName, ApplicationConfig
|
||||
|
||||
// Setting HTML5 Location Mode
|
||||
angular.module(ApplicationConfiguration.applicationModuleName).config(['$locationProvider',
|
||||
function($locationProvider) {
|
||||
$locationProvider.hashPrefix('!');
|
||||
}
|
||||
function($locationProvider) {
|
||||
$locationProvider.hashPrefix('!');
|
||||
}
|
||||
]);
|
||||
|
||||
//Then define the init function for starting up the application
|
||||
angular.element(document).ready(function() {
|
||||
//Fixing facebook bug with redirect
|
||||
if (window.location.hash === '#_=_') window.location.hash = '#!';
|
||||
//Fixing facebook bug with redirect
|
||||
if (window.location.hash === '#_=_') window.location.hash = '#!';
|
||||
|
||||
//Then init the app
|
||||
angular.bootstrap(document, [ApplicationConfiguration.applicationModuleName]);
|
||||
});
|
||||
//Then init the app
|
||||
angular.bootstrap(document, [ApplicationConfiguration.applicationModuleName]);
|
||||
});
|
||||
|
||||
@@ -2,22 +2,22 @@
|
||||
|
||||
// Init the application configuration module for AngularJS application
|
||||
var ApplicationConfiguration = (function() {
|
||||
// Init module configuration options
|
||||
var applicationModuleName = 'mean';
|
||||
var applicationModuleVendorDependencies = ['ngResource', 'ngAnimate', 'ui.router', 'ui.bootstrap', 'ui.utils'];
|
||||
// Init module configuration options
|
||||
var applicationModuleName = 'mean';
|
||||
var applicationModuleVendorDependencies = ['ngResource', 'ngAnimate', 'ui.router', 'ui.bootstrap', 'ui.utils'];
|
||||
|
||||
// Add a new vertical module
|
||||
var registerModule = function(moduleName) {
|
||||
// Create angular module
|
||||
angular.module(moduleName, []);
|
||||
// Add a new vertical module
|
||||
var registerModule = function(moduleName) {
|
||||
// Create angular module
|
||||
angular.module(moduleName, []);
|
||||
|
||||
// Add the module to the AngularJS configuration file
|
||||
angular.module(applicationModuleName).requires.push(moduleName);
|
||||
};
|
||||
// Add the module to the AngularJS configuration file
|
||||
angular.module(applicationModuleName).requires.push(moduleName);
|
||||
};
|
||||
|
||||
return {
|
||||
applicationModuleName: applicationModuleName,
|
||||
applicationModuleVendorDependencies: applicationModuleVendorDependencies,
|
||||
registerModule: registerModule
|
||||
};
|
||||
})();
|
||||
return {
|
||||
applicationModuleName: applicationModuleName,
|
||||
applicationModuleVendorDependencies: applicationModuleVendorDependencies,
|
||||
registerModule: registerModule
|
||||
};
|
||||
})();
|
||||
|
||||
246
public/dist/application.min.js
vendored
246
public/dist/application.min.js
vendored
File diff suppressed because one or more lines are too long
@@ -1,4 +1,4 @@
|
||||
'use strict';
|
||||
|
||||
// Use Applicaion configuration module to register a new module
|
||||
ApplicationConfiguration.registerModule('articles');
|
||||
ApplicationConfiguration.registerModule('articles');
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
|
||||
// Configuring the Articles module
|
||||
angular.module('articles').run(['Menus',
|
||||
function(Menus) {
|
||||
// Set top bar menu items
|
||||
Menus.addMenuItem('topbar', 'Articles', 'articles');
|
||||
Menus.addMenuItem('topbar', 'New Article', 'articles/create');
|
||||
}
|
||||
]);
|
||||
function(Menus) {
|
||||
// Set top bar menu items
|
||||
Menus.addMenuItem('topbar', 'Articles', 'articles');
|
||||
Menus.addMenuItem('topbar', 'New Article', 'articles/create');
|
||||
}
|
||||
]);
|
||||
|
||||
@@ -2,24 +2,24 @@
|
||||
|
||||
// Setting up route
|
||||
angular.module('articles').config(['$stateProvider',
|
||||
function($stateProvider) {
|
||||
// Articles state routing
|
||||
$stateProvider.
|
||||
state('listArticles', {
|
||||
url: '/articles',
|
||||
templateUrl: 'modules/articles/views/list-articles.client.view.html'
|
||||
}).
|
||||
state('createArticle', {
|
||||
url: '/articles/create',
|
||||
templateUrl: 'modules/articles/views/create-article.client.view.html'
|
||||
}).
|
||||
state('viewArticle', {
|
||||
url: '/articles/:articleId',
|
||||
templateUrl: 'modules/articles/views/view-article.client.view.html'
|
||||
}).
|
||||
state('editArticle', {
|
||||
url: '/articles/:articleId/edit',
|
||||
templateUrl: 'modules/articles/views/edit-article.client.view.html'
|
||||
});
|
||||
}
|
||||
]);
|
||||
function($stateProvider) {
|
||||
// Articles state routing
|
||||
$stateProvider.
|
||||
state('listArticles', {
|
||||
url: '/articles',
|
||||
templateUrl: 'modules/articles/views/list-articles.client.view.html'
|
||||
}).
|
||||
state('createArticle', {
|
||||
url: '/articles/create',
|
||||
templateUrl: 'modules/articles/views/create-article.client.view.html'
|
||||
}).
|
||||
state('viewArticle', {
|
||||
url: '/articles/:articleId',
|
||||
templateUrl: 'modules/articles/views/view-article.client.view.html'
|
||||
}).
|
||||
state('editArticle', {
|
||||
url: '/articles/:articleId/edit',
|
||||
templateUrl: 'modules/articles/views/edit-article.client.view.html'
|
||||
});
|
||||
}
|
||||
]);
|
||||
|
||||
@@ -1,58 +1,58 @@
|
||||
'use strict';
|
||||
|
||||
angular.module('articles').controller('ArticlesController', ['$scope', '$stateParams', '$location', 'Authentication', 'Articles',
|
||||
function($scope, $stateParams, $location, Authentication, Articles) {
|
||||
$scope.authentication = Authentication;
|
||||
function($scope, $stateParams, $location, Authentication, Articles) {
|
||||
$scope.authentication = Authentication;
|
||||
|
||||
$scope.create = function() {
|
||||
var article = new Articles({
|
||||
title: this.title,
|
||||
content: this.content
|
||||
});
|
||||
article.$save(function(response) {
|
||||
$location.path('articles/' + response._id);
|
||||
}, function(errorResponse) {
|
||||
$scope.error = errorResponse.data.message;
|
||||
});
|
||||
$scope.create = function() {
|
||||
var article = new Articles({
|
||||
title: this.title,
|
||||
content: this.content
|
||||
});
|
||||
article.$save(function(response) {
|
||||
$location.path('articles/' + response._id);
|
||||
}, function(errorResponse) {
|
||||
$scope.error = errorResponse.data.message;
|
||||
});
|
||||
|
||||
this.title = '';
|
||||
this.content = '';
|
||||
};
|
||||
this.title = '';
|
||||
this.content = '';
|
||||
};
|
||||
|
||||
$scope.remove = function(article) {
|
||||
if (article) {
|
||||
article.$remove();
|
||||
$scope.remove = function(article) {
|
||||
if (article) {
|
||||
article.$remove();
|
||||
|
||||
for (var i in $scope.articles) {
|
||||
if ($scope.articles[i] === article) {
|
||||
$scope.articles.splice(i, 1);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$scope.article.$remove(function() {
|
||||
$location.path('articles');
|
||||
});
|
||||
}
|
||||
};
|
||||
for (var i in $scope.articles) {
|
||||
if ($scope.articles[i] === article) {
|
||||
$scope.articles.splice(i, 1);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$scope.article.$remove(function() {
|
||||
$location.path('articles');
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
$scope.update = function() {
|
||||
var article = $scope.article;
|
||||
$scope.update = function() {
|
||||
var article = $scope.article;
|
||||
|
||||
article.$update(function() {
|
||||
$location.path('articles/' + article._id);
|
||||
}, function(errorResponse) {
|
||||
$scope.error = errorResponse.data.message;
|
||||
});
|
||||
};
|
||||
article.$update(function() {
|
||||
$location.path('articles/' + article._id);
|
||||
}, function(errorResponse) {
|
||||
$scope.error = errorResponse.data.message;
|
||||
});
|
||||
};
|
||||
|
||||
$scope.find = function() {
|
||||
$scope.articles = Articles.query();
|
||||
};
|
||||
$scope.find = function() {
|
||||
$scope.articles = Articles.query();
|
||||
};
|
||||
|
||||
$scope.findOne = function() {
|
||||
$scope.article = Articles.get({
|
||||
articleId: $stateParams.articleId
|
||||
});
|
||||
};
|
||||
}
|
||||
]);
|
||||
$scope.findOne = function() {
|
||||
$scope.article = Articles.get({
|
||||
articleId: $stateParams.articleId
|
||||
});
|
||||
};
|
||||
}
|
||||
]);
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
'use strict';
|
||||
|
||||
//Articles service used for communicating with the articles REST endpoints
|
||||
angular.module('articles').factory('Articles', ['$resource', function($resource) {
|
||||
return $resource('articles/:articleId', {
|
||||
articleId: '@_id'
|
||||
}, {
|
||||
update: {
|
||||
method: 'PUT'
|
||||
}
|
||||
});
|
||||
}]);
|
||||
angular.module('articles').factory('Articles', ['$resource',
|
||||
function($resource) {
|
||||
return $resource('articles/:articleId', {
|
||||
articleId: '@_id'
|
||||
}, {
|
||||
update: {
|
||||
method: 'PUT'
|
||||
}
|
||||
});
|
||||
}
|
||||
]);
|
||||
|
||||
@@ -1,170 +1,170 @@
|
||||
'use strict';
|
||||
|
||||
(function() {
|
||||
// Articles Controller Spec
|
||||
describe('ArticlesController', function() {
|
||||
// Initialize global variables
|
||||
var ArticlesController,
|
||||
scope,
|
||||
$httpBackend,
|
||||
$stateParams,
|
||||
$location;
|
||||
// Articles Controller Spec
|
||||
describe('ArticlesController', function() {
|
||||
// Initialize global variables
|
||||
var ArticlesController,
|
||||
scope,
|
||||
$httpBackend,
|
||||
$stateParams,
|
||||
$location;
|
||||
|
||||
// The $resource service augments the response object with methods for updating and deleting the resource.
|
||||
// If we were to use the standard toEqual matcher, our tests would fail because the test values would not match
|
||||
// the responses exactly. To solve the problem, we define a new toEqualData Jasmine matcher.
|
||||
// When the toEqualData matcher compares two objects, it takes only object properties into
|
||||
// account and ignores methods.
|
||||
beforeEach(function() {
|
||||
jasmine.addMatchers({
|
||||
toEqualData: function(util, customEqualityTesters) {
|
||||
return {
|
||||
compare: function(actual, expected) {
|
||||
return {
|
||||
pass: angular.equals(actual, expected)
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
});
|
||||
});
|
||||
// The $resource service augments the response object with methods for updating and deleting the resource.
|
||||
// If we were to use the standard toEqual matcher, our tests would fail because the test values would not match
|
||||
// the responses exactly. To solve the problem, we define a new toEqualData Jasmine matcher.
|
||||
// When the toEqualData matcher compares two objects, it takes only object properties into
|
||||
// account and ignores methods.
|
||||
beforeEach(function() {
|
||||
jasmine.addMatchers({
|
||||
toEqualData: function(util, customEqualityTesters) {
|
||||
return {
|
||||
compare: function(actual, expected) {
|
||||
return {
|
||||
pass: angular.equals(actual, expected)
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Then we can start by loading the main application module
|
||||
beforeEach(module(ApplicationConfiguration.applicationModuleName));
|
||||
// Then we can start by loading the main application module
|
||||
beforeEach(module(ApplicationConfiguration.applicationModuleName));
|
||||
|
||||
// The injector ignores leading and trailing underscores here (i.e. _$httpBackend_).
|
||||
// This allows us to inject a service but then attach it to a variable
|
||||
// with the same name as the service.
|
||||
beforeEach(inject(function($controller, $rootScope, _$location_, _$stateParams_, _$httpBackend_) {
|
||||
// Set a new global scope
|
||||
scope = $rootScope.$new();
|
||||
// The injector ignores leading and trailing underscores here (i.e. _$httpBackend_).
|
||||
// This allows us to inject a service but then attach it to a variable
|
||||
// with the same name as the service.
|
||||
beforeEach(inject(function($controller, $rootScope, _$location_, _$stateParams_, _$httpBackend_) {
|
||||
// Set a new global scope
|
||||
scope = $rootScope.$new();
|
||||
|
||||
// Point global variables to injected services
|
||||
$stateParams = _$stateParams_;
|
||||
$httpBackend = _$httpBackend_;
|
||||
$location = _$location_;
|
||||
// Point global variables to injected services
|
||||
$stateParams = _$stateParams_;
|
||||
$httpBackend = _$httpBackend_;
|
||||
$location = _$location_;
|
||||
|
||||
// Initialize the Articles controller.
|
||||
ArticlesController = $controller('ArticlesController', {
|
||||
$scope: scope
|
||||
});
|
||||
}));
|
||||
// Initialize the Articles controller.
|
||||
ArticlesController = $controller('ArticlesController', {
|
||||
$scope: scope
|
||||
});
|
||||
}));
|
||||
|
||||
it('$scope.find() should create an array with at least one article object fetched from XHR', inject(function(Articles) {
|
||||
// Create sample article using the Articles service
|
||||
var sampleArticle = new Articles({
|
||||
title: 'An Article about MEAN',
|
||||
content: 'MEAN rocks!'
|
||||
});
|
||||
it('$scope.find() should create an array with at least one article object fetched from XHR', inject(function(Articles) {
|
||||
// Create sample article using the Articles service
|
||||
var sampleArticle = new Articles({
|
||||
title: 'An Article about MEAN',
|
||||
content: 'MEAN rocks!'
|
||||
});
|
||||
|
||||
// Create a sample articles array that includes the new article
|
||||
var sampleArticles = [sampleArticle];
|
||||
// Create a sample articles array that includes the new article
|
||||
var sampleArticles = [sampleArticle];
|
||||
|
||||
// Set GET response
|
||||
$httpBackend.expectGET('articles').respond(sampleArticles);
|
||||
// Set GET response
|
||||
$httpBackend.expectGET('articles').respond(sampleArticles);
|
||||
|
||||
// Run controller functionality
|
||||
scope.find();
|
||||
$httpBackend.flush();
|
||||
// Run controller functionality
|
||||
scope.find();
|
||||
$httpBackend.flush();
|
||||
|
||||
// Test scope value
|
||||
expect(scope.articles).toEqualData(sampleArticles);
|
||||
}));
|
||||
// Test scope value
|
||||
expect(scope.articles).toEqualData(sampleArticles);
|
||||
}));
|
||||
|
||||
it('$scope.findOne() should create an array with one article object fetched from XHR using a articleId URL parameter', inject(function(Articles) {
|
||||
// Define a sample article object
|
||||
var sampleArticle = new Articles({
|
||||
title: 'An Article about MEAN',
|
||||
content: 'MEAN rocks!'
|
||||
});
|
||||
it('$scope.findOne() should create an array with one article object fetched from XHR using a articleId URL parameter', inject(function(Articles) {
|
||||
// Define a sample article object
|
||||
var sampleArticle = new Articles({
|
||||
title: 'An Article about MEAN',
|
||||
content: 'MEAN rocks!'
|
||||
});
|
||||
|
||||
// Set the URL parameter
|
||||
$stateParams.articleId = '525a8422f6d0f87f0e407a33';
|
||||
// Set the URL parameter
|
||||
$stateParams.articleId = '525a8422f6d0f87f0e407a33';
|
||||
|
||||
// Set GET response
|
||||
$httpBackend.expectGET(/articles\/([0-9a-fA-F]{24})$/).respond(sampleArticle);
|
||||
// Set GET response
|
||||
$httpBackend.expectGET(/articles\/([0-9a-fA-F]{24})$/).respond(sampleArticle);
|
||||
|
||||
// Run controller functionality
|
||||
scope.findOne();
|
||||
$httpBackend.flush();
|
||||
// Run controller functionality
|
||||
scope.findOne();
|
||||
$httpBackend.flush();
|
||||
|
||||
// Test scope value
|
||||
expect(scope.article).toEqualData(sampleArticle);
|
||||
}));
|
||||
// Test scope value
|
||||
expect(scope.article).toEqualData(sampleArticle);
|
||||
}));
|
||||
|
||||
it('$scope.create() with valid form data should send a POST request with the form input values and then locate to new object URL', inject(function(Articles) {
|
||||
// Create a sample article object
|
||||
var sampleArticlePostData = new Articles({
|
||||
title: 'An Article about MEAN',
|
||||
content: 'MEAN rocks!'
|
||||
});
|
||||
it('$scope.create() with valid form data should send a POST request with the form input values and then locate to new object URL', inject(function(Articles) {
|
||||
// Create a sample article object
|
||||
var sampleArticlePostData = new Articles({
|
||||
title: 'An Article about MEAN',
|
||||
content: 'MEAN rocks!'
|
||||
});
|
||||
|
||||
// Create a sample article response
|
||||
var sampleArticleResponse = new Articles({
|
||||
_id: '525cf20451979dea2c000001',
|
||||
title: 'An Article about MEAN',
|
||||
content: 'MEAN rocks!'
|
||||
});
|
||||
// Create a sample article response
|
||||
var sampleArticleResponse = new Articles({
|
||||
_id: '525cf20451979dea2c000001',
|
||||
title: 'An Article about MEAN',
|
||||
content: 'MEAN rocks!'
|
||||
});
|
||||
|
||||
// Fixture mock form input values
|
||||
scope.title = 'An Article about MEAN';
|
||||
scope.content = 'MEAN rocks!';
|
||||
// Fixture mock form input values
|
||||
scope.title = 'An Article about MEAN';
|
||||
scope.content = 'MEAN rocks!';
|
||||
|
||||
// Set POST response
|
||||
$httpBackend.expectPOST('articles', sampleArticlePostData).respond(sampleArticleResponse);
|
||||
// Set POST response
|
||||
$httpBackend.expectPOST('articles', sampleArticlePostData).respond(sampleArticleResponse);
|
||||
|
||||
// Run controller functionality
|
||||
scope.create();
|
||||
$httpBackend.flush();
|
||||
// Run controller functionality
|
||||
scope.create();
|
||||
$httpBackend.flush();
|
||||
|
||||
// Test form inputs are reset
|
||||
expect(scope.title).toEqual('');
|
||||
expect(scope.content).toEqual('');
|
||||
// Test form inputs are reset
|
||||
expect(scope.title).toEqual('');
|
||||
expect(scope.content).toEqual('');
|
||||
|
||||
// Test URL redirection after the article was created
|
||||
expect($location.path()).toBe('/articles/' + sampleArticleResponse._id);
|
||||
}));
|
||||
// Test URL redirection after the article was created
|
||||
expect($location.path()).toBe('/articles/' + sampleArticleResponse._id);
|
||||
}));
|
||||
|
||||
it('$scope.update() should update a valid article', inject(function(Articles) {
|
||||
// Define a sample article put data
|
||||
var sampleArticlePutData = new Articles({
|
||||
_id: '525cf20451979dea2c000001',
|
||||
title: 'An Article about MEAN',
|
||||
content: 'MEAN Rocks!'
|
||||
});
|
||||
it('$scope.update() should update a valid article', inject(function(Articles) {
|
||||
// Define a sample article put data
|
||||
var sampleArticlePutData = new Articles({
|
||||
_id: '525cf20451979dea2c000001',
|
||||
title: 'An Article about MEAN',
|
||||
content: 'MEAN Rocks!'
|
||||
});
|
||||
|
||||
// Mock article in scope
|
||||
scope.article = sampleArticlePutData;
|
||||
// Mock article in scope
|
||||
scope.article = sampleArticlePutData;
|
||||
|
||||
// Set PUT response
|
||||
$httpBackend.expectPUT(/articles\/([0-9a-fA-F]{24})$/).respond();
|
||||
// Set PUT response
|
||||
$httpBackend.expectPUT(/articles\/([0-9a-fA-F]{24})$/).respond();
|
||||
|
||||
// Run controller functionality
|
||||
scope.update();
|
||||
$httpBackend.flush();
|
||||
// Run controller functionality
|
||||
scope.update();
|
||||
$httpBackend.flush();
|
||||
|
||||
// Test URL location to new object
|
||||
expect($location.path()).toBe('/articles/' + sampleArticlePutData._id);
|
||||
}));
|
||||
// Test URL location to new object
|
||||
expect($location.path()).toBe('/articles/' + sampleArticlePutData._id);
|
||||
}));
|
||||
|
||||
it('$scope.remove() should send a DELETE request with a valid articleId and remove the article from the scope', inject(function(Articles) {
|
||||
// Create new article object
|
||||
var sampleArticle = new Articles({
|
||||
_id: '525a8422f6d0f87f0e407a33'
|
||||
});
|
||||
it('$scope.remove() should send a DELETE request with a valid articleId and remove the article from the scope', inject(function(Articles) {
|
||||
// Create new article object
|
||||
var sampleArticle = new Articles({
|
||||
_id: '525a8422f6d0f87f0e407a33'
|
||||
});
|
||||
|
||||
// Create new articles array and include the article
|
||||
scope.articles = [sampleArticle];
|
||||
// Create new articles array and include the article
|
||||
scope.articles = [sampleArticle];
|
||||
|
||||
// Set expected DELETE response
|
||||
$httpBackend.expectDELETE(/articles\/([0-9a-fA-F]{24})$/).respond(204);
|
||||
// Set expected DELETE response
|
||||
$httpBackend.expectDELETE(/articles\/([0-9a-fA-F]{24})$/).respond(204);
|
||||
|
||||
// Run controller functionality
|
||||
scope.remove(sampleArticle);
|
||||
$httpBackend.flush();
|
||||
// Run controller functionality
|
||||
scope.remove(sampleArticle);
|
||||
$httpBackend.flush();
|
||||
|
||||
// Test array after successful delete
|
||||
expect(scope.articles.length).toBe(0);
|
||||
}));
|
||||
});
|
||||
}());
|
||||
// Test array after successful delete
|
||||
expect(scope.articles.length).toBe(0);
|
||||
}));
|
||||
});
|
||||
}());
|
||||
|
||||
@@ -2,15 +2,15 @@
|
||||
|
||||
// Setting up route
|
||||
angular.module('core').config(['$stateProvider', '$urlRouterProvider',
|
||||
function($stateProvider, $urlRouterProvider) {
|
||||
// Redirect to home view when route not found
|
||||
$urlRouterProvider.otherwise('/');
|
||||
function($stateProvider, $urlRouterProvider) {
|
||||
// Redirect to home view when route not found
|
||||
$urlRouterProvider.otherwise('/');
|
||||
|
||||
// Home state routing
|
||||
$stateProvider.
|
||||
state('home', {
|
||||
url: '/',
|
||||
templateUrl: 'modules/core/views/home.client.view.html'
|
||||
});
|
||||
}
|
||||
]);
|
||||
// Home state routing
|
||||
$stateProvider.
|
||||
state('home', {
|
||||
url: '/',
|
||||
templateUrl: 'modules/core/views/home.client.view.html'
|
||||
});
|
||||
}
|
||||
]);
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
'use strict';
|
||||
|
||||
angular.module('core').controller('HeaderController', ['$scope', 'Authentication', 'Menus',
|
||||
function($scope, Authentication, Menus) {
|
||||
$scope.authentication = Authentication;
|
||||
$scope.isCollapsed = false;
|
||||
$scope.menu = Menus.getMenu('topbar');
|
||||
function($scope, Authentication, Menus) {
|
||||
$scope.authentication = Authentication;
|
||||
$scope.isCollapsed = false;
|
||||
$scope.menu = Menus.getMenu('topbar');
|
||||
|
||||
$scope.toggleCollapsibleMenu = function() {
|
||||
$scope.isCollapsed = !$scope.isCollapsed;
|
||||
};
|
||||
}
|
||||
]);
|
||||
$scope.toggleCollapsibleMenu = function() {
|
||||
$scope.isCollapsed = !$scope.isCollapsed;
|
||||
};
|
||||
}
|
||||
]);
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
'use strict';
|
||||
|
||||
angular.module('core').controller('HomeController', ['$scope', 'Authentication', function ($scope, Authentication) {
|
||||
$scope.authentication = Authentication;
|
||||
}]);
|
||||
angular.module('core').controller('HomeController', ['$scope', 'Authentication',
|
||||
function($scope, Authentication) {
|
||||
$scope.authentication = Authentication;
|
||||
}
|
||||
]);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
'use strict';
|
||||
|
||||
// Use Applicaion configuration module to register a new module
|
||||
ApplicationConfiguration.registerModule('core');
|
||||
ApplicationConfiguration.registerModule('core');
|
||||
|
||||
@@ -2,113 +2,114 @@
|
||||
|
||||
//Menu service used for managing menus
|
||||
angular.module('core').service('Menus', [
|
||||
function() {
|
||||
// Define a set of default roles
|
||||
this.defaultRoles = ['user'];
|
||||
|
||||
// Define the menus object
|
||||
this.menus = {};
|
||||
function() {
|
||||
// Define a set of default roles
|
||||
this.defaultRoles = ['user'];
|
||||
|
||||
// A private function for rendering decision
|
||||
var shouldRender = function(user) {
|
||||
if(user) {
|
||||
for (var userRoleIndex in user.roles) {
|
||||
for (var roleIndex in this.roles) {
|
||||
if(this.roles[roleIndex] === user.roles[userRoleIndex]) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return this.isPublic;
|
||||
}
|
||||
// Define the menus object
|
||||
this.menus = {};
|
||||
|
||||
return false;
|
||||
};
|
||||
// A private function for rendering decision
|
||||
var shouldRender = function(user) {
|
||||
if (user) {
|
||||
for (var userRoleIndex in user.roles) {
|
||||
for (var roleIndex in this.roles) {
|
||||
if (this.roles[roleIndex] === user.roles[userRoleIndex]) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return this.isPublic;
|
||||
}
|
||||
|
||||
// Validate menu existance
|
||||
this.validateMenuExistance = function(menuId) {
|
||||
if (menuId && menuId.length) {
|
||||
if (this.menus[menuId]) {
|
||||
return true;
|
||||
} else {
|
||||
throw new Error('Menu does not exists');
|
||||
}
|
||||
} else {
|
||||
throw new Error('MenuId was not provided');
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
return false;
|
||||
};
|
||||
// Validate menu existance
|
||||
this.validateMenuExistance = function(menuId) {
|
||||
if (menuId && menuId.length) {
|
||||
if (this.menus[menuId]) {
|
||||
return true;
|
||||
} else {
|
||||
throw new Error('Menu does not exists');
|
||||
}
|
||||
} else {
|
||||
throw new Error('MenuId was not provided');
|
||||
}
|
||||
|
||||
// Get the menu object by menu id
|
||||
this.getMenu = function(menuId) {
|
||||
// Validate that the menu exists
|
||||
this.validateMenuExistance(menuId);
|
||||
return false;
|
||||
};
|
||||
|
||||
// Return the menu object
|
||||
return this.menus[menuId];
|
||||
};
|
||||
// Get the menu object by menu id
|
||||
this.getMenu = function(menuId) {
|
||||
// Validate that the menu exists
|
||||
this.validateMenuExistance(menuId);
|
||||
|
||||
// Add new menu object by menu id
|
||||
this.addMenu = function(menuId, isPublic, roles) {
|
||||
// Create the new menu
|
||||
this.menus[menuId] = {
|
||||
isPublic: isPublic || false,
|
||||
roles: roles || this.defaultRoles,
|
||||
items: [],
|
||||
shouldRender: shouldRender
|
||||
};
|
||||
// Return the menu object
|
||||
return this.menus[menuId];
|
||||
};
|
||||
|
||||
// Return the menu object
|
||||
return this.menus[menuId];
|
||||
};
|
||||
// Add new menu object by menu id
|
||||
this.addMenu = function(menuId, isPublic, roles) {
|
||||
// Create the new menu
|
||||
this.menus[menuId] = {
|
||||
isPublic: isPublic || false,
|
||||
roles: roles || this.defaultRoles,
|
||||
items: [],
|
||||
shouldRender: shouldRender
|
||||
};
|
||||
|
||||
// Remove existing menu object by menu id
|
||||
this.removeMenu = function(menuId) {
|
||||
// Validate that the menu exists
|
||||
this.validateMenuExistance(menuId);
|
||||
// Return the menu object
|
||||
return this.menus[menuId];
|
||||
};
|
||||
|
||||
// Return the menu object
|
||||
delete this.menus[menuId];
|
||||
};
|
||||
// Remove existing menu object by menu id
|
||||
this.removeMenu = function(menuId) {
|
||||
// Validate that the menu exists
|
||||
this.validateMenuExistance(menuId);
|
||||
|
||||
// Add menu item object
|
||||
this.addMenuItem = function(menuId, menuItemTitle, menuItemURL, menuItemUIRoute, isPublic, roles) {
|
||||
// Validate that the menu exists
|
||||
this.validateMenuExistance(menuId);
|
||||
// Return the menu object
|
||||
delete this.menus[menuId];
|
||||
};
|
||||
|
||||
// Push new menu item
|
||||
this.menus[menuId].items.push({
|
||||
title: menuItemTitle,
|
||||
link: menuItemURL,
|
||||
uiRoute: menuItemUIRoute || ('/' + menuItemURL),
|
||||
isPublic: isPublic || this.menus[menuId].isPublic,
|
||||
roles: roles || this.defaultRoles,
|
||||
shouldRender: shouldRender
|
||||
});
|
||||
// Add menu item object
|
||||
this.addMenuItem = function(menuId, menuItemTitle, menuItemURL, menuItemUIRoute, isPublic, roles) {
|
||||
// Validate that the menu exists
|
||||
this.validateMenuExistance(menuId);
|
||||
|
||||
// Return the menu object
|
||||
return this.menus[menuId];
|
||||
};
|
||||
// Push new menu item
|
||||
this.menus[menuId].items.push({
|
||||
title: menuItemTitle,
|
||||
link: menuItemURL,
|
||||
uiRoute: menuItemUIRoute || ('/' + menuItemURL),
|
||||
isPublic: isPublic || this.menus[menuId].isPublic,
|
||||
roles: roles || this.defaultRoles,
|
||||
shouldRender: shouldRender
|
||||
});
|
||||
|
||||
// Remove existing menu object by menu id
|
||||
this.removeMenuItem = function(menuId, menuItemURL) {
|
||||
// Validate that the menu exists
|
||||
this.validateMenuExistance(menuId);
|
||||
// Return the menu object
|
||||
return this.menus[menuId];
|
||||
};
|
||||
|
||||
// Search for menu item to remove
|
||||
for (var itemIndex in this.menus[menuId].items) {
|
||||
if (this.menus[menuId].items[itemIndex].link === menuItemURL) {
|
||||
this.menus[menuId].items.splice(itemIndex, 1);
|
||||
}
|
||||
}
|
||||
// Remove existing menu object by menu id
|
||||
this.removeMenuItem = function(menuId, menuItemURL) {
|
||||
// Validate that the menu exists
|
||||
this.validateMenuExistance(menuId);
|
||||
|
||||
// Return the menu object
|
||||
return this.menus[menuId];
|
||||
};
|
||||
// Search for menu item to remove
|
||||
for (var itemIndex in this.menus[menuId].items) {
|
||||
if (this.menus[menuId].items[itemIndex].link === menuItemURL) {
|
||||
this.menus[menuId].items.splice(itemIndex, 1);
|
||||
}
|
||||
}
|
||||
|
||||
//Adding the topbar menu
|
||||
this.addMenu('topbar');
|
||||
}
|
||||
// Return the menu object
|
||||
return this.menus[menuId];
|
||||
};
|
||||
|
||||
//Adding the topbar menu
|
||||
this.addMenu('topbar');
|
||||
}
|
||||
]);
|
||||
|
||||
@@ -1,24 +1,24 @@
|
||||
'use strict';
|
||||
|
||||
(function() {
|
||||
describe('HeaderController', function() {
|
||||
//Initialize global variables
|
||||
var scope,
|
||||
HeaderController;
|
||||
describe('HeaderController', function() {
|
||||
//Initialize global variables
|
||||
var scope,
|
||||
HeaderController;
|
||||
|
||||
// Load the main application module
|
||||
beforeEach(module(ApplicationConfiguration.applicationModuleName));
|
||||
// Load the main application module
|
||||
beforeEach(module(ApplicationConfiguration.applicationModuleName));
|
||||
|
||||
beforeEach(inject(function($controller, $rootScope) {
|
||||
scope = $rootScope.$new();
|
||||
beforeEach(inject(function($controller, $rootScope) {
|
||||
scope = $rootScope.$new();
|
||||
|
||||
HeaderController = $controller('HeaderController', {
|
||||
$scope: scope
|
||||
});
|
||||
}));
|
||||
HeaderController = $controller('HeaderController', {
|
||||
$scope: scope
|
||||
});
|
||||
}));
|
||||
|
||||
it('should expose the authentication service', function() {
|
||||
expect(scope.authentication).toBeTruthy();
|
||||
});
|
||||
});
|
||||
})();
|
||||
it('should expose the authentication service', function() {
|
||||
expect(scope.authentication).toBeTruthy();
|
||||
});
|
||||
});
|
||||
})();
|
||||
|
||||
@@ -1,24 +1,24 @@
|
||||
'use strict';
|
||||
|
||||
(function() {
|
||||
describe('HomeController', function() {
|
||||
//Initialize global variables
|
||||
var scope,
|
||||
HomeController;
|
||||
describe('HomeController', function() {
|
||||
//Initialize global variables
|
||||
var scope,
|
||||
HomeController;
|
||||
|
||||
// Load the main application module
|
||||
beforeEach(module(ApplicationConfiguration.applicationModuleName));
|
||||
// Load the main application module
|
||||
beforeEach(module(ApplicationConfiguration.applicationModuleName));
|
||||
|
||||
beforeEach(inject(function($controller, $rootScope) {
|
||||
scope = $rootScope.$new();
|
||||
beforeEach(inject(function($controller, $rootScope) {
|
||||
scope = $rootScope.$new();
|
||||
|
||||
HomeController = $controller('HomeController', {
|
||||
$scope: scope
|
||||
});
|
||||
}));
|
||||
HomeController = $controller('HomeController', {
|
||||
$scope: scope
|
||||
});
|
||||
}));
|
||||
|
||||
it('should expose the authentication service', function() {
|
||||
expect(scope.authentication).toBeTruthy();
|
||||
});
|
||||
});
|
||||
})();
|
||||
it('should expose the authentication service', function() {
|
||||
expect(scope.authentication).toBeTruthy();
|
||||
});
|
||||
});
|
||||
})();
|
||||
|
||||
@@ -2,29 +2,29 @@
|
||||
|
||||
// Config HTTP Error Handling
|
||||
angular.module('users').config(['$httpProvider',
|
||||
function($httpProvider) {
|
||||
// Set the httpProvider "not authorized" interceptor
|
||||
$httpProvider.interceptors.push(['$q', '$location', 'Authentication',
|
||||
function($q, $location, Authentication) {
|
||||
return {
|
||||
responseError: function(rejection) {
|
||||
switch (rejection.status) {
|
||||
case 401:
|
||||
// Deauthenticate the global user
|
||||
Authentication.user = null;
|
||||
function($httpProvider) {
|
||||
// Set the httpProvider "not authorized" interceptor
|
||||
$httpProvider.interceptors.push(['$q', '$location', 'Authentication',
|
||||
function($q, $location, Authentication) {
|
||||
return {
|
||||
responseError: function(rejection) {
|
||||
switch (rejection.status) {
|
||||
case 401:
|
||||
// Deauthenticate the global user
|
||||
Authentication.user = null;
|
||||
|
||||
// Redirect to signin page
|
||||
$location.path('signin');
|
||||
break;
|
||||
case 403:
|
||||
// Add unauthorized behaviour
|
||||
break;
|
||||
}
|
||||
// Redirect to signin page
|
||||
$location.path('signin');
|
||||
break;
|
||||
case 403:
|
||||
// Add unauthorized behaviour
|
||||
break;
|
||||
}
|
||||
|
||||
return $q.reject(rejection);
|
||||
}
|
||||
};
|
||||
}
|
||||
]);
|
||||
}
|
||||
]);
|
||||
return $q.reject(rejection);
|
||||
}
|
||||
};
|
||||
}
|
||||
]);
|
||||
}
|
||||
]);
|
||||
|
||||
@@ -2,28 +2,28 @@
|
||||
|
||||
// Setting up route
|
||||
angular.module('users').config(['$stateProvider',
|
||||
function($stateProvider) {
|
||||
// Users state routing
|
||||
$stateProvider.
|
||||
state('profile', {
|
||||
url: '/settings/profile',
|
||||
templateUrl: 'modules/users/views/settings/edit-profile.client.view.html'
|
||||
}).
|
||||
state('password', {
|
||||
url: '/settings/password',
|
||||
templateUrl: 'modules/users/views/settings/change-password.client.view.html'
|
||||
}).
|
||||
state('accounts', {
|
||||
url: '/settings/accounts',
|
||||
templateUrl: 'modules/users/views/settings/social-accounts.client.view.html'
|
||||
}).
|
||||
state('signup', {
|
||||
url: '/signup',
|
||||
templateUrl: 'modules/users/views/signup.client.view.html'
|
||||
}).
|
||||
state('signin', {
|
||||
url: '/signin',
|
||||
templateUrl: 'modules/users/views/signin.client.view.html'
|
||||
});
|
||||
}
|
||||
]);
|
||||
function($stateProvider) {
|
||||
// Users state routing
|
||||
$stateProvider.
|
||||
state('profile', {
|
||||
url: '/settings/profile',
|
||||
templateUrl: 'modules/users/views/settings/edit-profile.client.view.html'
|
||||
}).
|
||||
state('password', {
|
||||
url: '/settings/password',
|
||||
templateUrl: 'modules/users/views/settings/change-password.client.view.html'
|
||||
}).
|
||||
state('accounts', {
|
||||
url: '/settings/accounts',
|
||||
templateUrl: 'modules/users/views/settings/social-accounts.client.view.html'
|
||||
}).
|
||||
state('signup', {
|
||||
url: '/signup',
|
||||
templateUrl: 'modules/users/views/signup.client.view.html'
|
||||
}).
|
||||
state('signin', {
|
||||
url: '/signin',
|
||||
templateUrl: 'modules/users/views/signin.client.view.html'
|
||||
});
|
||||
}
|
||||
]);
|
||||
|
||||
@@ -31,4 +31,4 @@ angular.module('users').controller('AuthenticationController', ['$scope', '$http
|
||||
});
|
||||
};
|
||||
}
|
||||
]);
|
||||
]);
|
||||
|
||||
@@ -1,67 +1,67 @@
|
||||
'use strict';
|
||||
|
||||
angular.module('users').controller('SettingsController', ['$scope', '$http', '$location', 'Users', 'Authentication',
|
||||
function($scope, $http, $location, Users, Authentication) {
|
||||
$scope.user = Authentication.user;
|
||||
function($scope, $http, $location, Users, Authentication) {
|
||||
$scope.user = Authentication.user;
|
||||
|
||||
// If user is not signed in then redirect back home
|
||||
if (!$scope.user) $location.path('/');
|
||||
// If user is not signed in then redirect back home
|
||||
if (!$scope.user) $location.path('/');
|
||||
|
||||
// Check if there are additional accounts
|
||||
$scope.hasConnectedAdditionalSocialAccounts = function(provider) {
|
||||
for (var i in $scope.user.additionalProvidersData) {
|
||||
return true;
|
||||
}
|
||||
// Check if there are additional accounts
|
||||
$scope.hasConnectedAdditionalSocialAccounts = function(provider) {
|
||||
for (var i in $scope.user.additionalProvidersData) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
// Check if provider is already in use with current user
|
||||
$scope.isConnectedSocialAccount = function(provider) {
|
||||
return $scope.user.provider === provider || ($scope.user.additionalProvidersData && $scope.user.additionalProvidersData[provider]);
|
||||
};
|
||||
return false;
|
||||
};
|
||||
|
||||
// Remove a user social account
|
||||
$scope.removeUserSocialAccount = function(provider) {
|
||||
$scope.success = $scope.error = null;
|
||||
// Check if provider is already in use with current user
|
||||
$scope.isConnectedSocialAccount = function(provider) {
|
||||
return $scope.user.provider === provider || ($scope.user.additionalProvidersData && $scope.user.additionalProvidersData[provider]);
|
||||
};
|
||||
|
||||
$http.delete('/users/accounts', {
|
||||
params: {
|
||||
provider: provider
|
||||
}
|
||||
}).success(function(response) {
|
||||
// If successful show success message and clear form
|
||||
$scope.success = true;
|
||||
$scope.user = Authentication.user = response;
|
||||
}).error(function(response) {
|
||||
$scope.error = response.message;
|
||||
});
|
||||
};
|
||||
// Remove a user social account
|
||||
$scope.removeUserSocialAccount = function(provider) {
|
||||
$scope.success = $scope.error = null;
|
||||
|
||||
// Update a user profile
|
||||
$scope.updateUserProfile = function() {
|
||||
$scope.success = $scope.error = null;
|
||||
var user = new Users($scope.user);
|
||||
$http.delete('/users/accounts', {
|
||||
params: {
|
||||
provider: provider
|
||||
}
|
||||
}).success(function(response) {
|
||||
// If successful show success message and clear form
|
||||
$scope.success = true;
|
||||
$scope.user = Authentication.user = response;
|
||||
}).error(function(response) {
|
||||
$scope.error = response.message;
|
||||
});
|
||||
};
|
||||
|
||||
user.$update(function(response) {
|
||||
$scope.success = true;
|
||||
Authentication.user = response;
|
||||
}, function(response) {
|
||||
$scope.error = response.data.message;
|
||||
});
|
||||
};
|
||||
// Update a user profile
|
||||
$scope.updateUserProfile = function() {
|
||||
$scope.success = $scope.error = null;
|
||||
var user = new Users($scope.user);
|
||||
|
||||
// Change user password
|
||||
$scope.changeUserPassword = function() {
|
||||
$scope.success = $scope.error = null;
|
||||
user.$update(function(response) {
|
||||
$scope.success = true;
|
||||
Authentication.user = response;
|
||||
}, function(response) {
|
||||
$scope.error = response.data.message;
|
||||
});
|
||||
};
|
||||
|
||||
$http.post('/users/password', $scope.passwordDetails).success(function(response) {
|
||||
// If successful show success message and clear form
|
||||
$scope.success = true;
|
||||
$scope.passwordDetails = null;
|
||||
}).error(function(response) {
|
||||
$scope.error = response.message;
|
||||
});
|
||||
};
|
||||
}
|
||||
]);
|
||||
// Change user password
|
||||
$scope.changeUserPassword = function() {
|
||||
$scope.success = $scope.error = null;
|
||||
|
||||
$http.post('/users/password', $scope.passwordDetails).success(function(response) {
|
||||
// If successful show success message and clear form
|
||||
$scope.success = true;
|
||||
$scope.passwordDetails = null;
|
||||
}).error(function(response) {
|
||||
$scope.error = response.message;
|
||||
});
|
||||
};
|
||||
}
|
||||
]);
|
||||
|
||||
@@ -2,13 +2,14 @@
|
||||
|
||||
// Authentication service for user variables
|
||||
angular.module('users').factory('Authentication', [
|
||||
function() {
|
||||
var _this = this;
|
||||
|
||||
_this._data = {
|
||||
user: window.user
|
||||
};
|
||||
function() {
|
||||
var _this = this;
|
||||
|
||||
return _this._data;
|
||||
}
|
||||
]);
|
||||
_this._data = {
|
||||
user: window.user
|
||||
};
|
||||
|
||||
return _this._data;
|
||||
}
|
||||
]);
|
||||
|
||||
@@ -2,11 +2,11 @@
|
||||
|
||||
// Users service used for communicating with the users REST endpoint
|
||||
angular.module('users').factory('Users', ['$resource',
|
||||
function($resource) {
|
||||
return $resource('users', {}, {
|
||||
update: {
|
||||
method: 'PUT'
|
||||
}
|
||||
});
|
||||
}
|
||||
]);
|
||||
function($resource) {
|
||||
return $resource('users', {}, {
|
||||
update: {
|
||||
method: 'PUT'
|
||||
}
|
||||
});
|
||||
}
|
||||
]);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
'use strict';
|
||||
|
||||
// Use Applicaion configuration module to register a new module
|
||||
ApplicationConfiguration.registerModule('users');
|
||||
ApplicationConfiguration.registerModule('users');
|
||||
|
||||
Reference in New Issue
Block a user