Finally got angular to work with express partial routes
This commit is contained in:
@ -1,179 +1,47 @@
|
|||||||
var passport = require('passport'),
|
var passport = require('passport'),
|
||||||
User = require('../models/User'),
|
|
||||||
crypto = require('crypto'),
|
|
||||||
LocalStrategy = require('passport-local').Strategy,
|
LocalStrategy = require('passport-local').Strategy,
|
||||||
TwitterStrategy = require('passport-twitter').Strategy,
|
User = require('../models/user');
|
||||||
FacebookStrategy = require('passport-facebook').Strategy,
|
|
||||||
GoogleStrategy = require('passport-google').Strategy,
|
|
||||||
LinkedInStrategy = require('passport-linkedin').Strategy,
|
|
||||||
userRoles = require('../../client/js/routingConfig').userRoles;
|
|
||||||
|
|
||||||
|
passport.serializeUser(function(user, done) {
|
||||||
|
done(null, user.id);
|
||||||
|
});
|
||||||
|
|
||||||
function findByUsername(username, callback) {
|
passport.deserializeUser(function(id, done) {
|
||||||
|
User.findById(id, function (err, user) {
|
||||||
|
done(err, user);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
passport.use(new LocalStrategy(function(username, password, done) {
|
||||||
User.findOne({ username: username }, function(err, user) {
|
User.findOne({ username: username }, function(err, user) {
|
||||||
if (user) callback(err, user);
|
if (err) { return done(err); }
|
||||||
});
|
if (!user) { return done(null, false, { message: 'Unknown user ' + username }); }
|
||||||
}
|
user.comparePassword(password, function(err, isMatch) {
|
||||||
|
if (err) return done(err);
|
||||||
function findOrCreateOauthUser(provider, providerId, callback) {
|
if(isMatch) {
|
||||||
User.findOne({ $where: provider + '===' + providerId }, function(err, user) {
|
|
||||||
if (user) return user;
|
|
||||||
user = {
|
|
||||||
username: provider + '_user',
|
|
||||||
role: userRoles.user,
|
|
||||||
provider: provider
|
|
||||||
};
|
|
||||||
user[provider] = providerId;
|
|
||||||
user.save(function(err) {
|
|
||||||
callback(err, user);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function findAll(callback) {
|
|
||||||
User.find(function(err, users) {
|
|
||||||
callback(err, users);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function findById(id, callback) {
|
|
||||||
User.findById(id, function(err, user) {
|
|
||||||
if (user) callback(err, user);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
|
|
||||||
register: function(req, res, next) {
|
|
||||||
findByUsername(req.body.username, function(err, user) {
|
|
||||||
if (user) return res.send(403, 'User already exists');
|
|
||||||
|
|
||||||
user = new User({
|
|
||||||
username: req.body.username,
|
|
||||||
password: req.body.password,
|
|
||||||
role: req.body.role
|
|
||||||
});
|
|
||||||
|
|
||||||
user.save(function(err) {
|
|
||||||
req.logIn(user, function(err) {
|
|
||||||
if (err) next(err);
|
|
||||||
else res.send(200, { role: user.role, username: user.username });
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
login: function(req, res, next) {
|
|
||||||
passport.authenticate('local', function(err, user) {
|
|
||||||
if (err) return next(err);
|
|
||||||
if (!user) return res.send(400);
|
|
||||||
req.logIn(user, function(err) {
|
|
||||||
if (err) return next(err);
|
|
||||||
if (req.body.rememberme) req.session.cookie.maxAge = 1000 * 60 * 60 * 24 * 7;
|
|
||||||
res.json(200, { role: user.role, username: user.username });
|
|
||||||
});
|
|
||||||
})(req, res, next);
|
|
||||||
},
|
|
||||||
|
|
||||||
logout: function(req, res) {
|
|
||||||
req.logout();
|
|
||||||
res.send(200);
|
|
||||||
},
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
localStrategy: new LocalStrategy(function(username, password, done) {
|
|
||||||
findByUsername(username, function(err, user) {
|
|
||||||
if (!user) {
|
|
||||||
done(null, false, { message: 'Username does not exist' });
|
|
||||||
} else if (user.password !== password) {
|
|
||||||
done(null, false, { message: 'Incorrect password' });
|
|
||||||
} else {
|
|
||||||
return done(null, user);
|
return done(null, user);
|
||||||
}
|
|
||||||
});
|
|
||||||
}),
|
|
||||||
|
|
||||||
twitterStrategy: function() {
|
|
||||||
if (!process.env.TWITTER_CONSUMER_KEY) throw new Error('A Twitter Consumer Key is required if you want to enable login via Twitter.');
|
|
||||||
if (!process.env.TWITTER_CONSUMER_SECRET) throw new Error('A Twitter Consumer Secret is required if you want to enable login via Twitter.');
|
|
||||||
|
|
||||||
return new TwitterStrategy({
|
|
||||||
consumerKey: process.env.TWITTER_CONSUMER_KEY,
|
|
||||||
consumerSecret: process.env.TWITTER_CONSUMER_SECRET,
|
|
||||||
callbackURL: process.env.TWITTER_CALLBACK_URL || 'http://localhost:8000/auth/twitter/callback'
|
|
||||||
},
|
|
||||||
function(token, tokenSecret, profile, done) {
|
|
||||||
findOrCreateOauthUser(profile.provider, profile.id, function(err, user) {
|
|
||||||
done(err, user);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
facebookStrategy: function() {
|
|
||||||
if (!process.env.FACEBOOK_APP_ID) throw new Error('A Facebook App ID is required if you want to enable login via Facebook.');
|
|
||||||
if (!process.env.FACEBOOK_APP_SECRET) throw new Error('A Facebook App Secret is required if you want to enable login via Facebook.');
|
|
||||||
|
|
||||||
return new FacebookStrategy({
|
|
||||||
clientID: process.env.FACEBOOK_APP_ID,
|
|
||||||
clientSecret: process.env.FACEBOOK_APP_SECRET,
|
|
||||||
callbackURL: process.env.FACEBOOK_CALLBACK_URL || "http://localhost:8000/auth/facebook/callback"
|
|
||||||
},
|
|
||||||
function(accessToken, refreshToken, profile, done) {
|
|
||||||
findOrCreateOauthUser(profile.provider, profile.id, function(err, user) {
|
|
||||||
done(err, user);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
googleStrategy: function() {
|
|
||||||
|
|
||||||
return new GoogleStrategy({
|
|
||||||
returnURL: process.env.GOOGLE_RETURN_URL || "http://localhost:8000/auth/google/return",
|
|
||||||
realm: process.env.GOOGLE_REALM || "http://localhost:8000/"
|
|
||||||
},
|
|
||||||
function(identifier, profile, done) {
|
|
||||||
findOrCreateOauthUser('google', identifier, function(err, user) {
|
|
||||||
done(err, user);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
linkedInStrategy: function() {
|
|
||||||
if (!process.env.LINKED_IN_KEY) throw new Error('A LinkedIn App Key is required if you want to enable login via LinkedIn.');
|
|
||||||
if (!process.env.LINKED_IN_SECRET) throw new Error('A LinkedIn App Secret is required if you want to enable login via LinkedIn.');
|
|
||||||
|
|
||||||
return new LinkedInStrategy({
|
|
||||||
consumerKey: process.env.LINKED_IN_KEY,
|
|
||||||
consumerSecret: process.env.LINKED_IN_SECRET,
|
|
||||||
callbackURL: process.env.LINKED_IN_CALLBACK_URL || "http://localhost:8000/auth/linkedin/callback"
|
|
||||||
},
|
|
||||||
function(token, tokenSecret, profile, done) {
|
|
||||||
findOrCreateOauthUser('linkedin', profile.id, function(err, user) {
|
|
||||||
done(err, user);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
serializeUser: function(user, done) {
|
|
||||||
done(null, user.id);
|
|
||||||
},
|
|
||||||
|
|
||||||
deserializeUser: function(id, done) {
|
|
||||||
findById(id, function(err, user) {
|
|
||||||
if (user) {
|
|
||||||
done(null, user);
|
|
||||||
} else {
|
} else {
|
||||||
done(null, false);
|
return done(null, false, { message: 'Invalid password' });
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
});
|
||||||
|
}));
|
||||||
|
|
||||||
|
// Simple route middleware to ensure user is authenticated. Otherwise send to login page.
|
||||||
|
exports.ensureAuthenticated = function ensureAuthenticated(req, res, next) {
|
||||||
|
if (req.isAuthenticated()) { return next(); }
|
||||||
|
res.redirect('/login');
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// Check for admin middleware, this is unrelated to passport.js
|
||||||
|
// You can delete this if you use different method to check for admins or don't need admins
|
||||||
|
exports.ensureAdmin = function ensureAdmin(req, res, next) {
|
||||||
|
return function(req, res, next) {
|
||||||
|
console.log(req.user);
|
||||||
|
if(req.user && req.user.admin === true)
|
||||||
|
next();
|
||||||
|
else
|
||||||
|
res.send(403);
|
||||||
|
};
|
||||||
};
|
};
|
@ -2,7 +2,7 @@ exports.index = function(req, res){
|
|||||||
res.render('index');
|
res.render('index');
|
||||||
};
|
};
|
||||||
|
|
||||||
exports.partial = function (req, res) {
|
exports.partials = function (req, res) {
|
||||||
var name = req.params.name;
|
var name = req.params.name;
|
||||||
res.render('partials/partial' + name);
|
res.render('partials/' + name);
|
||||||
};
|
};
|
50
controllers/users.js
Executable file → Normal file
50
controllers/users.js
Executable file → Normal file
@ -1,17 +1,33 @@
|
|||||||
//var _ = require('underscore')
|
var mongoose = require('mongoose');
|
||||||
// , User = require('../models/User.js')
|
var User = require('../models/user');
|
||||||
// , userRoles = require('../../client/js/routingConfig').userRoles;
|
|
||||||
//
|
exports.account = function(req, res) {
|
||||||
//module.exports = {
|
res.render('account', { user: req.user });
|
||||||
// index: function(req, res) {
|
};
|
||||||
// var users = User.findAll();
|
|
||||||
// _.each(users, function(user) {
|
exports.getlogin = function(req, res) {
|
||||||
// delete user.password;
|
res.render('partials/login', { user: req.user, message: req.session.messages });
|
||||||
// delete user.twitter;
|
};
|
||||||
// delete user.facebook;
|
|
||||||
// delete user.google;
|
exports.admin = function(req, res) {
|
||||||
// delete user.linkedin;
|
res.send('access granted admin!');
|
||||||
// });
|
};
|
||||||
// res.json(users);
|
|
||||||
// }
|
exports.postlogin = function(req, res, next) {
|
||||||
//};
|
passport.authenticate('local', function(err, user, info) {
|
||||||
|
if (err) { return next(err) }
|
||||||
|
if (!user) {
|
||||||
|
req.session.messages = [info.message];
|
||||||
|
return res.redirect('/login')
|
||||||
|
}
|
||||||
|
req.logIn(user, function(err) {
|
||||||
|
if (err) { return next(err); }
|
||||||
|
return res.redirect('/');
|
||||||
|
});
|
||||||
|
})(req, res, next);
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.logout = function(req, res) {
|
||||||
|
req.logout();
|
||||||
|
res.redirect('/');
|
||||||
|
};
|
34
models/user.js
Normal file
34
models/user.js
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
var mongoose = require('mongoose'),
|
||||||
|
bcrypt = require('bcrypt');
|
||||||
|
|
||||||
|
var userSchema = new mongoose.Schema({
|
||||||
|
username: { type: String, required: true, unique: true },
|
||||||
|
email: { type: String, required: true, unique: true },
|
||||||
|
password: { type: String, required: true},
|
||||||
|
admin: { type: Boolean, required: true }
|
||||||
|
});
|
||||||
|
|
||||||
|
userSchema.pre('save', function(next) {
|
||||||
|
var user = this;
|
||||||
|
|
||||||
|
if (!user.isModified('password')) return next();
|
||||||
|
|
||||||
|
bcrypt.genSalt(32, function(err, salt) {
|
||||||
|
if (err) return next(err);
|
||||||
|
|
||||||
|
bcrypt.hash(user.password, salt, function(err, hash) {
|
||||||
|
if (err) return next(err);
|
||||||
|
user.password = hash;
|
||||||
|
next();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
userSchema.methods.comparePassword = function(candidatePassword, cb) {
|
||||||
|
bcrypt.compare(candidatePassword, this.password, function(err, isMatch) {
|
||||||
|
if(err) return cb(err);
|
||||||
|
cb(null, isMatch);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = mongoose.model('User', userSchema);
|
@ -4,8 +4,18 @@
|
|||||||
// Declare app level module which depends on filters, and services
|
// Declare app level module which depends on filters, and services
|
||||||
angular.module('myApp', ['ngRoute', 'myApp.filters', 'myApp.services', 'myApp.directives']).
|
angular.module('myApp', ['ngRoute', 'myApp.filters', 'myApp.services', 'myApp.directives']).
|
||||||
config(['$routeProvider', '$locationProvider', function($routeProvider, $locationProvider) {
|
config(['$routeProvider', '$locationProvider', function($routeProvider, $locationProvider) {
|
||||||
$routeProvider.when('/view1', {templateUrl: 'partial/1', controller: MyCtrl1});
|
$routeProvider.when('/view1', {
|
||||||
$routeProvider.when('/view2', {templateUrl: 'partial/2', controller: MyCtrl2});
|
templateUrl: 'partials/partial1',
|
||||||
$routeProvider.otherwise({redirectTo: '/view1'});
|
controller: MyCtrl1
|
||||||
|
});
|
||||||
|
$routeProvider.when('/view2', {
|
||||||
|
templateUrl: 'partials/partial2',
|
||||||
|
controller: MyCtrl2
|
||||||
|
});
|
||||||
|
$routeProvider.when('/login', {
|
||||||
|
templateUrl: 'partials/login',
|
||||||
|
controller: MyCtrl3
|
||||||
|
});
|
||||||
|
$routeProvider.otherwise({ redirectTo: '/view1' });
|
||||||
$locationProvider.html5Mode(true);
|
$locationProvider.html5Mode(true);
|
||||||
}]);
|
}]);
|
@ -8,7 +8,7 @@ function AppCtrl($scope, $http) {
|
|||||||
$scope.name = data.name;
|
$scope.name = data.name;
|
||||||
}).
|
}).
|
||||||
error(function(data, status, headers, config) {
|
error(function(data, status, headers, config) {
|
||||||
$scope.name = 'Error!'
|
$scope.name = 'Error!';
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -19,3 +19,5 @@ MyCtrl1.$inject = [];
|
|||||||
function MyCtrl2() {
|
function MyCtrl2() {
|
||||||
}
|
}
|
||||||
MyCtrl2.$inject = [];
|
MyCtrl2.$inject = [];
|
||||||
|
function MyCtrl3() {}
|
||||||
|
MyCtrl3.$inject = [];
|
||||||
|
50
server.js
50
server.js
@ -5,46 +5,50 @@ var express = require('express'),
|
|||||||
mongoose = require('mongoose'),
|
mongoose = require('mongoose'),
|
||||||
passport = require('passport'),
|
passport = require('passport'),
|
||||||
|
|
||||||
index = require('./controllers'),
|
config = require('./config'),
|
||||||
api = require('./controllers/api');
|
|
||||||
|
|
||||||
|
// Load controllers
|
||||||
|
home = require('./controllers/home'),
|
||||||
|
api = require('./controllers/api'),
|
||||||
|
auth = require('./controllers/auth'),
|
||||||
|
users = require('./controllers/users');
|
||||||
|
|
||||||
|
// Connect to database
|
||||||
|
mongoose.connect(config.db, function(err, res) {
|
||||||
|
if (err) {
|
||||||
|
console.log ('Error connecting to database: ' + err);
|
||||||
|
} else {
|
||||||
|
console.log ('Successfully connected to database!');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
var db = module.exports = mongoose.connect('localhost');
|
|
||||||
var app = module.exports = express();
|
var app = module.exports = express();
|
||||||
|
|
||||||
app.set('port', process.env.PORT || 3000);
|
app.set('port', process.env.PORT || 3000);
|
||||||
app.set('views', __dirname + '/views');
|
app.set('views', __dirname + '/views');
|
||||||
app.set('view engine', 'jade');
|
app.set('view engine', 'jade');
|
||||||
app.use(express.favicon());
|
|
||||||
app.use(express.logger('dev'));
|
app.use(express.logger('dev'));
|
||||||
|
app.use(express.errorHandler());
|
||||||
|
app.use(express.favicon());
|
||||||
app.use(express.cookieParser());
|
app.use(express.cookieParser());
|
||||||
app.use(express.bodyParser());
|
app.use(express.bodyParser());
|
||||||
app.use(express.methodOverride());
|
app.use(express.methodOverride());
|
||||||
app.use(express.cookieSession({ secret: 'secret' }));
|
app.use(express.session({ secret: 'Bob-Alice' }));
|
||||||
app.use(passport.initialize());
|
app.use(passport.initialize());
|
||||||
app.use(passport.session());
|
app.use(passport.session());
|
||||||
app.use(express.static(path.join(__dirname, 'public')));
|
app.use(express.static(path.join(__dirname, 'public')));
|
||||||
app.use(app.router);
|
app.use(app.router);
|
||||||
|
|
||||||
|
// Routes
|
||||||
if (app.get('env') === 'development') {
|
app.get('/', home.index);
|
||||||
app.use(express.errorHandler());
|
app.get('/partials/:name', home.partials);
|
||||||
};
|
//app.get('/account', auth.ensureAuthenticated, users.account);
|
||||||
|
//app.get('/logout', users.logout);
|
||||||
|
//app.post('/login', users.postlogin);
|
||||||
/**
|
//app.get('/login', users.getlogin);
|
||||||
* API Routes
|
//app.get('/admin', auth.ensureAuthenticated, auth.ensureAdmin(), users.admin);
|
||||||
*/
|
//app.get('/api/name', api.name);
|
||||||
app.get('/', index.index);
|
app.get('*', home.index);
|
||||||
app.get('/partial/:name', index.partial);
|
|
||||||
|
|
||||||
|
|
||||||
// JSON API
|
|
||||||
app.get('/api/name', api.name);
|
|
||||||
|
|
||||||
// redirect all others to the index (HTML5 history)
|
|
||||||
app.get('*', index.index);
|
|
||||||
|
|
||||||
|
|
||||||
app.listen(app.get('port'), function() {
|
app.listen(app.get('port'), function() {
|
||||||
|
@ -13,7 +13,9 @@ block body
|
|||||||
li
|
li
|
||||||
a(href="view1") View1
|
a(href="view1") View1
|
||||||
li
|
li
|
||||||
a(href="view2") View2
|
a(href="view2") View2
|
||||||
|
li
|
||||||
|
a(href="login") login
|
||||||
.container
|
.container
|
||||||
div(ng-controller='AppCtrl')
|
div(ng-controller='AppCtrl')
|
||||||
.jumbotron
|
.jumbotron
|
||||||
|
12
views/partials/login.jade
Normal file
12
views/partials/login.jade
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
form(action='/login', method='post')
|
||||||
|
div
|
||||||
|
label Username:
|
||||||
|
input(type='text', name='username')
|
||||||
|
br
|
||||||
|
div
|
||||||
|
label Password:
|
||||||
|
input(type='password', name='password')
|
||||||
|
div
|
||||||
|
input(type='submit', value='Submit')
|
||||||
|
p
|
||||||
|
small Hint - bob:secret
|
Reference in New Issue
Block a user