diff options
author | Dennis Eriksen <dennis.se@gmail.com> | 2013-04-29 03:39:15 +0200 |
---|---|---|
committer | Dennis Eriksen <dennis.se@gmail.com> | 2013-04-29 03:39:15 +0200 |
commit | fc50b5b7f18d02ffa8056dc1edbd3bd43e973493 (patch) | |
tree | e4646512634a42790bbddfec8b3d035bb2052cec | |
parent | added twitter authentication (diff) | |
download | Divid-fc50b5b7f18d02ffa8056dc1edbd3bd43e973493.tar.gz |
been cleaning a bit, moving stuff to where it belongs. signup and
signin works.
-rw-r--r-- | app.js | 22 | ||||
-rw-r--r-- | config/email-settings.js | 13 | ||||
-rw-r--r-- | config/express.js | 4 | ||||
-rw-r--r-- | config/middlewares/authorization.js | 13 | ||||
-rw-r--r-- | controllers/users.js | 62 | ||||
-rw-r--r-- | models/user.js | 128 | ||||
-rw-r--r-- | router.js | 44 | ||||
-rw-r--r-- | views/navbar.ejs | 4 | ||||
-rw-r--r-- | views/signup.ejs | 251 |
9 files changed, 242 insertions, 299 deletions
@@ -4,7 +4,7 @@ */ var express = require('express') - , path = require('path') + , fs = require('fs') , passport = require('passport'); @@ -13,10 +13,24 @@ var app = express(); // initiates express /** * App configuration */ -var port = process.env.PORT || 3000 +var port = process.env.PORT || 8000 , env = process.env.NODE_ENV || 'development' - , config = require('./config/config')[env]; + , config = require('./config/config')[env] + , auth = require('./config/middlewares/authorization') + , mongoose = require('mongoose'); +// Bootstrap db connection +mongoose.connect(config.db); + + +// Bootstrap models +var models_path = __dirname + '/models'; +fs.readdirSync(models_path).forEach( function(file) { + require(models_path + '/' + file); +}); + +// Bootstrap passport config +require('./config/passport')(passport, config); /** * Express @@ -29,7 +43,7 @@ require('./config/express')(app, config, passport); /** * Routes */ -require('./router')(app, config); +require('./router')(app, passport, auth); /** diff --git a/config/email-settings.js b/config/email-settings.js deleted file mode 100644 index 8bc9983..0000000 --- a/config/email-settings.js +++ /dev/null @@ -1,13 +0,0 @@ -/** - * Email settings - */ - -module.exports = { - - host: 'localhost', - user: 'divid', - password: '', - sender: 'Divid <divid@divid.no>' - -} - diff --git a/config/express.js b/config/express.js index 4afd827..eb10b20 100644 --- a/config/express.js +++ b/config/express.js @@ -48,11 +48,11 @@ module.exports = function (app, config, passport) { console.error(err.stack); - res.status(500).render('500', { error: err.stack }); // render page + res.status(500).render('error', { title: '500', text: 'En serverfeil oppstod', error: err.stack }); // render page }); app.use(function(req, res, next) { - res.status(404).render('404', { url: req.originalUrl, error: 'Not found' }); // render page + res.status(404).render('error', { title: '404', text: 'Fant ikke siden du så etter' }); // render page }); }); } diff --git a/config/middlewares/authorization.js b/config/middlewares/authorization.js new file mode 100644 index 0000000..440f085 --- /dev/null +++ b/config/middlewares/authorization.js @@ -0,0 +1,13 @@ + + +/* + * Generic require login routing + */ + +exports.requiresLogin = function(req, res, next) { + if (!req.isAuthenticated()) return res.redirect('/login'); + next(); +} + + + diff --git a/controllers/users.js b/controllers/users.js new file mode 100644 index 0000000..af454b5 --- /dev/null +++ b/controllers/users.js @@ -0,0 +1,62 @@ + +/** + * Module dependencies + */ + +var mongoose = require('mongoose') + , User = mongoose.model('User'); + +/** + * Login + */ + +exports.login = function(req, res) { + res.render('login', { + title: 'Login' + }); + +} + + +/** + * Logout + */ + +exports.logoug = function(req, res) { + req.logout(); + res.resirect('/test'); +} + + +/** + * Signin + */ + +exports.signin = function(req, res) {} + +/** + * Create users + */ + +exports.create = function(req, res) { + var user = new User(req.body); + user.provider = 'local'; + user.save(function(err) { + if (err) return res.render('/signup', { errors: err.errors, user: user }); + req.logIn(user, function(err) { + if (err) return next(err); + return res.redirect('/dashboard'); + }); + }); +} + + +/** + * AuthCallback + * This is what happends when a user has signed in using facebook/twitter + */ + +exports.authCallback = function(req, res, next) { + res.redirect('/dashboard'); +} + diff --git a/models/user.js b/models/user.js new file mode 100644 index 0000000..b61f7c9 --- /dev/null +++ b/models/user.js @@ -0,0 +1,128 @@ + +/** + * Module dependencies + */ + +var mongoose = require('mongoose') + , Schema = mongoose.Schema + , crypto =require('crypto') + , authTypes = ['facebook', 'twitter']; + + +/** + * User schema + */ + +var UserSchema = new Schema({ + name: String, + email: String, + username: String, + provider: String, + hashed_password: String, + salt: String, + facebook: {}, + twitter: {} +}); + +/** + * Virtuals + */ + +UserSchema + .virtual('password') + .set(function(password) { + this._password = password + this.salt = this.makeSalt() + this.hashed_password = this.encryptPassword(password) + }).get(function() { return this._password }); + +/** + * Validations + */ +var validatePrecenceOf = function (value) { + return value && value.length; +} + +// the four validations below only apply if you are signing up traditionally + +UserSchema.path('name').validate(function(name) { + // if you're authenticated by any of the oauth strategies (facebook, twitter), don't validate + if(authTypes.indexOf(this.provider) !== -1) return true; + return name.length; +}, 'Name cannot be blank'); + +UserSchema.path('email').validate(function(email) { + if(authTypes.indexOf(this.provider) !== -1) return true; + return email.length; +}, 'Email cannot be blank'); + +UserSchema.path('username').validate(function(username) { + if(authTypes.indexOf(this.provider) !== -1) return true; + return username.length; +}, 'Username cannot be blank'); + +UserSchema.path('hashed_password').validate(function(hashed_password) { + if(authTypes.indexOf(this.provider) !== -1) return true; + return hashed_password.length; +}, 'Password cannot be blank'); + +/** + * Pre-save hook + */ + +UserSchema.pre('save', function(next) { + if (!this.isNew) return next(); + + if(!validatePrecenceOf(this.password) + && authTypes.indexOf(this.provider) === -1) + next(new Error('Invalid password')); + else next(); +}); + + +/** + * Methods + */ + +UserSchema.methods = { + + /** + * Authenticate - check if passwords are the same + * + * @param {String} plainText + * @return {Bolean} + * @api public + */ + + authenticate: function(plainText) { + return this.encryptPassword(plainText) === this.hashed_password; + }, + + /** + * Make salt + * + * @return {String} + * @api public + */ + + makeSalt: function() { + return Math.round((new Date().valueOf() * Math.random())) + ''; + }, + + /** + * Encrypt password + * + * @param {String} password + * @return {String} + * @api public + */ + + encryptPassword: function(password) { + if (!password) return ''; + return crypto.createHmac('sha1', this.salt).update(password).digest('hex'); + } +} + +mongoose.model('User', UserSchema); + + @@ -1,18 +1,16 @@ -var passport = require('passport') - , mongodb = require('mongodb') - , mongoose = require('mongoose') - , bcrypt = require('bcrypt') - , SALT_WORK_FACTOR = 15; +var mongodb = require('mongodb') + , mongoose = require('mongoose'); +var users = require('./controllers/users'); // connects to mongodb -mongoose.connect('localhost', 'test'); +//mongoose.connect('localhost', 'test'); var db = mongoose.connection; db.on('error', console.error.bind(console, 'connection error:')); db.once('open', function callback(){ console.log('Connected to MongoDB'); }); - +/* // user scheme var userSchema = mongoose.Schema({ username: { type: String, required: true, unique: true }, @@ -76,6 +74,7 @@ usr.save(function(err) { // the user by ID when deserializing. // // Both serializer and deserializer edited for Remember Me functionality +/* passport.serializeUser( function(user, done) { var createAccessToken = function() { var token = user.generateRandomToken(); @@ -113,7 +112,7 @@ function ensureAuthenticated(req, res, next) { if (req.isAuthenticated()) return next(); res.redirect('/login'); } - +/* /* * ============================================================ * Routes @@ -122,7 +121,7 @@ function ensureAuthenticated(req, res, next) { -module.exports = function(app) { +module.exports = function(app, passport, auth) { /* * GET home page. * @@ -183,10 +182,11 @@ module.exports = function(app) { /* POST */ - app.post('/login', function(req, res, next) { + app.post('/login', users.signin);/* function(req, res, next) { passport.authenticate('local', function(err, user, info) { if (err) return next(err); if (!user) { + console.log('post/login'); console.log(info.message); req.session.messages = [info.message]; return res.redirect('/login'); @@ -196,7 +196,7 @@ module.exports = function(app) { return res.redirect('/dashboard'); }) })(req, res, next); - }); + });*/ // GET /auth/facebook // Use passport.authenticate() as route middleware to authenticate the @@ -217,9 +217,8 @@ module.exports = function(app) { console.log('/auth/facebook/callback --- ' + req.user.username); res.redirect('/dashboard'); }); - - - + app.get('/auth/twitter', passport.authenticate('twitter', { failureRedirect: '/login' }), users.signin); + app.get('/auth/twitter/callback', passport.authenticate('twitter', { failureRedirect: '/login' }), users.authCallback); /* * GET logout @@ -261,22 +260,7 @@ module.exports = function(app) { /* POST */ - app.post('/signup', function(req, res) { - AM.addNewAccount({ - name : req.param('name'), - email : req.param('email'), - user : req.param('user'), - pass : req.param('pass'), - country : req.param('country') - }, function(e) { - if (e) { - res.send(e, 400); - } else { - res.send('ok', 200); - } - }); - }); - + app.post('/signup', users.create); diff --git a/views/navbar.ejs b/views/navbar.ejs index aac3c2e..79cb55a 100644 --- a/views/navbar.ejs +++ b/views/navbar.ejs @@ -30,7 +30,9 @@ </label> </div> <div class="span5"> - <button type="submit" class="btn btn-inverse btn-small">Logg inn</button><a href="/auth/facebook">f</a> + <button type="submit" class="btn btn-inverse btn-small">Logg inn</button> + <a href="/auth/facebook">f</a> + <a href="/auth/twitter">t</a> </div> </div> </form> diff --git a/views/signup.ejs b/views/signup.ejs index b64845b..01a5831 100644 --- a/views/signup.ejs +++ b/views/signup.ejs @@ -22,265 +22,18 @@ <input id="email-tf" type="text" name="email" class="input-xlarge"> </div> </div> - <div id="clist-cg" class="control-group"> - <label for="country-list" class="control-label">Location</label> - <div class="controls"> - <select id="country-list" name="country"> - <option>Please select a country</option> - <option>Afghanistan</option> - <option>Albania</option> - <option>Algeria</option> - <option>American Samoa</option> - <option>Andorra</option> - <option>Angola</option> - <option>Anguilla</option> - <option>Antarctica</option> - <option>Antigua and Barbuda</option> - <option>Argentina</option> - <option>Armenia</option> - <option>Aruba</option> - <option>Australia</option> - <option>Austria</option> - <option>Azerbaijan</option> - <option>Bahamas</option> - <option>Bahrain</option> - <option>Bangladesh</option> - <option>Barbados</option> - <option>Belarus</option> - <option>Belgium</option> - <option>Belize</option> - <option>Benin</option> - <option>Bermuda</option> - <option>Bhutan</option> - <option>Bolivia</option> - <option>Bosnia and Herzegowina</option> - <option>Botswana</option> - <option>Bouvet Island</option> - <option>Brazil</option> - <option>British Indian Ocean Territory</option> - <option>Brunei Darussalam</option> - <option>Bulgaria</option> - <option>Burkina Faso</option> - <option>Burundi</option> - <option>Cambodia</option> - <option>Cameroon</option> - <option>Canada</option> - <option>Cape Verde</option> - <option>Cayman Islands</option> - <option>Central African Republic</option> - <option>Chad</option> - <option>Chile</option> - <option>China</option> - <option>Christmas Island</option> - <option>Cocos (Keeling) Islands</option> - <option>Colombia</option> - <option>Comoros</option> - <option>Congo</option> - <option>Congo, the Democratic Republic of the</option> - <option>Cook Islands</option> - <option>Costa Rica</option> - <option>Cote d'Ivoire</option> - <option>Croatia (Hrvatska)</option> - <option>Cuba</option> - <option>Cyprus</option> - <option>Czech Republic</option> - <option>Denmark</option> - <option>Djibouti</option> - <option>Dominica</option> - <option>Dominican Republic</option> - <option>East Timor</option> - <option>Ecuador</option> - <option>Egypt</option> - <option>El Salvador</option> - <option>Equatorial Guinea</option> - <option>Eritrea</option> - <option>Estonia</option> - <option>Ethiopia</option> - <option>Falkland Islands (Malvinas)</option> - <option>Faroe Islands</option> - <option>Fiji</option> - <option>Finland</option> - <option>France</option> - <option>France, Metropolitan</option> - <option>French Guiana</option> - <option>French Polynesia</option> - <option>French Southern Territories</option> - <option>Gabon</option> - <option>Gambia</option> - <option>Georgia</option> - <option>Germany</option> - <option>Ghana</option> - <option>Gibraltar</option> - <option>Greece</option> - <option>Greenland</option> - <option>Grenada</option> - <option>Guadeloupe</option> - <option>Guam</option> - <option>Guatemala</option> - <option>Guinea</option> - <option>Guinea-Bissau</option> - <option>Guyana</option> - <option>Haiti</option> - <option>Heard and Mc Donald Islands</option> - <option>Holy See (Vatican City State)</option> - <option>Honduras</option> - <option>Hong Kong</option> - <option>Hungary</option> - <option>Iceland</option> - <option>India</option> - <option>Indonesia</option> - <option>Iran (Islamic Republic of)</option> - <option>Iraq</option> - <option>Ireland</option> - <option>Israel</option> - <option>Italy</option> - <option>Jamaica</option> - <option>Japan</option> - <option>Jordan</option> - <option>Kazakhstan</option> - <option>Kenya</option> - <option>Kiribati</option> - <option>Korea, Democratic People's Republic of</option> - <option>Korea, Republic of</option> - <option>Kuwait</option> - <option>Kyrgyzstan</option> - <option>Lao People's Democratic Republic</option> - <option>Latvia</option> - <option>Lebanon</option> - <option>Lesotho</option> - <option>Liberia</option> - <option>Libyan Arab Jamahiriya</option> - <option>Liechtenstein</option> - <option>Lithuania</option> - <option>Luxembourg</option> - <option>Macau</option> - <option>Macedonia, The Former Yugoslav Republic of</option> - <option>Madagascar</option> - <option>Malawi</option> - <option>Malaysia</option> - <option>Maldives</option> - <option>Mali</option> - <option>Malta</option> - <option>Marshall Islands</option> - <option>Martinique</option> - <option>Mauritania</option> - <option>Mauritius</option> - <option>Mayotte</option> - <option>Mexico</option> - <option>Micronesia, Federated States of</option> - <option>Moldova, Republic of</option> - <option>Monaco</option> - <option>Mongolia</option> - <option>Montserrat</option> - <option>Morocco</option> - <option>Mozambique</option> - <option>Myanmar</option> - <option>Namibia</option> - <option>Nauru</option> - <option>Nepal</option> - <option>Netherlands</option> - <option>Netherlands Antilles</option> - <option>New Caledonia</option> - <option>New Zealand</option> - <option>Nicaragua</option> - <option>Niger</option> - <option>Nigeria</option> - <option>Niue</option> - <option>Norfolk Island</option> - <option>Northern Mariana Islands</option> - <option>Norway</option> - <option>Oman</option> - <option>Pakistan</option> - <option>Palau</option> - <option>Panama</option> - <option>Papua New Guinea</option> - <option>Paraguay</option> - <option>Peru</option> - <option>Philippines</option> - <option>Pitcairn</option> - <option>Poland</option> - <option>Portugal</option> - <option>Puerto Rico</option> - <option>Qatar</option> - <option>Reunion</option> - <option>Romania</option> - <option>Russian Federation</option> - <option>Rwanda</option> - <option>Saint Kitts and Nevis</option> - <option>Saint LUCIA</option> - <option>Saint Vincent and the Grenadines</option> - <option>Samoa</option> - <option>San Marino</option> - <option>Sao Tome and Principe</option> - <option>Saudi Arabia</option> - <option>Senegal</option> - <option>Seychelles</option> - <option>Sierra Leone</option> - <option>Singapore</option> - <option>Slovakia (Slovak Republic)</option> - <option>Slovenia</option> - <option>Solomon Islands</option> - <option>Somalia</option> - <option>South Africa</option> - <option>South Georgia and the South Sandwich Islands</option> - <option>Spain</option> - <option>Sri Lanka</option> - <option>St. Helena</option> - <option>St. Pierre and Miquelon</option> - <option>Sudan</option> - <option>Suriname</option> - <option>Svalbard and Jan Mayen Islands</option> - <option>Swaziland</option> - <option>Sweden</option> - <option>Switzerland</option> - <option>Syrian Arab Republic</option> - <option>Taiwan, Province of China</option> - <option>Tajikistan</option> - <option>Tanzania, United Republic of</option> - <option>Thailand</option> - <option>Togo</option> - <option>Tokelau</option> - <option>Tonga</option> - <option>Trinidad and Tobago</option> - <option>Tunisia</option> - <option>Turkey</option> - <option>Turkmenistan</option> - <option>Turks and Caicos Islands</option> - <option>Tuvalu</option> - <option>Uganda</option> - <option>Ukraine</option> - <option>United Arab Emirates</option> - <option>United Kingdom</option> - <option>United States</option> - <option>United States Minor Outlying Islands</option> - <option>Uruguay</option> - <option>Uzbekistan</option> - <option>Vanuatu</option> - <option>Venezuela</option> - <option>Viet Nam</option> - <option>Virgin Islands (British)</option> - <option>Virgin Islands (U.S.)</option> - <option>Wallis and Futuna Islands</option> - <option>Western Sahara</option> - <option>Yemen</option> - <option>Yugoslavia</option> - <option>Zambia</option> - <option>Zimbabwe</option> - </select> - </div> - </div> <hr> <p id="sub2" class="subheading"></p> <div id="user-cg" class="control-group"> <label for="user-tf" class="control-label">Username</label> <div class="controls"> - <input id="user-tf" type="text" name="user" class="input-xlarge disabled"> + <input id="user-tf" type="text" name="username" class="input-xlarge disabled"> </div> </div> <div id="pass-cg" class="control-group"> <label for="pass-tf" class="control-label">Password</label> <div class="controls"> - <input id="pass-tf" type="password" name="pass" value="" class="input-xlarge"> + <input id="pass-tf" type="password" name="password" value="" class="input-xlarge"> </div> </div> <div class="form-actions"> |