diff options
-rw-r--r-- | app/controllers/system.js | 184 | ||||
-rw-r--r-- | app/controllers/users.js | 96 | ||||
-rw-r--r-- | app/models/Access.js | 26 | ||||
-rw-r--r-- | app/models/Project.js | 18 | ||||
-rw-r--r-- | app/models/User.js | 40 | ||||
-rw-r--r-- | app/models/pPost.js | 33 | ||||
-rw-r--r-- | config/config.js | 38 | ||||
-rw-r--r-- | config/express.js | 6 | ||||
-rw-r--r-- | config/middlewares/authorization.js | 2 | ||||
-rw-r--r-- | config/passport.js | 8 | ||||
-rw-r--r-- | config/routes.js | 4 | ||||
-rw-r--r-- | server.js | 2 |
12 files changed, 275 insertions, 182 deletions
diff --git a/app/controllers/system.js b/app/controllers/system.js index 2fcb0fd..a09f517 100644 --- a/app/controllers/system.js +++ b/app/controllers/system.js @@ -2,6 +2,7 @@ /** * Module dependencies */ + var mongoose = require('mongoose') , env = process.env.NODE_ENV || 'development' , config = require('../../config/config.js')[env] @@ -21,115 +22,139 @@ Validator.prototype.error = function(msg) { } Validator.prototype.getErrors = function() { var returnThis = this._errors; - this._errors = ''; // need to reset errors between sessions because of object model + this._errors = ''; // need to reset errors between sessions because of object model that retains errors return returnThis; } + /** * Before the user log in * =============================================================== */ + +/** + * GET '/' + */ + exports.index = function(req, res) { - if (req.user !== undefined) { return res.redirect('/dashboard'); } - res.render('index', { title: 'Divid', user: req.user }); + if (req.user !== undefined) return res.redirect('/dashboard'); // if the user is logged in, redirect to dashboard + res.render('index', { + title: 'Divid' + , user:req.user + }); } +/** + * GET '/faq' + */ + exports.faq = function(req, res) { res.render('faq', { - title: 'faq', - user: req.user + title: 'FAQ' + , user: req.user }); } +/** + * GET '/contact' + */ + exports.contact = function(req, res) { res.render('contact', { - title: 'contact', - user: req.user + title: 'Kontakt' + , user: req.user }); } + /** * After the user has logged in * =============================================================== */ + +/** + * GET '/dashboard' + */ + exports.dashboard = function(req, res) { + // check if user is actually registered if (req.user.status < 3) { if (req.header('Referer') === undefined) { return res.status(403).render('error', { title: 403, text: 'Du har ikke tilgang til denne siden. Du må registrere deg først. Sjekk mailen din for å se invitekode.' }); } else { return res.redirect('back'); } } + // start by loading all the projects the current user has access to Access.loadUser(req.user._id, function(err, projects) { if (err) return res.status(500).render('error', { title: '500', text: 'En serverfeil oppstod', error: err.stack }); + var projectIDs = []; var pro = { project: [] }; + + // Time to initiate some projects so we can calculate how much the user owes / is owned projects.forEach(function(project) { - projectIDs.push(project.project._id); - pro.project[project.project._id] = { + projectIDs.push(project.project._id); // fills an array with all the project IDs + pro.project[project.project._id] = { // initiates an object for each project, where we can store some data total: 0 // total for project , user: 0 // what req-user has spent on project , users: 0 // number of users on project }; }); + + // loads all the users for the projects the current user has access to + // this is necessary so we can calculate what the user owes based on how many users each project has Access.loadProjects(projectIDs, function(err, participants) { if (err) return res.status(500).render('error', { title: '500', text: 'En serverfeil oppstod', error: err.stack }); + + // counts the users in each project participants.forEach(function(p) { pro.project[p.project].users++; }); + + // loads ALL posts for EVERY project the user has access to pPost.loadByProjects(projectIDs, function(err, posts) { if (err) return res.status(500).render('error', { title: '500', text: 'En serverfeil oppstod', error: err.stack }); - Access.loadProjects(projectIDs, function(err, participants) { - if (err) return res.status(500).render('error', { title: '500', text: 'En serverfeil oppstod', error: err.stack }); - - // FUN FUN FUN CALCULATIONS - - posts.forEach(function(p) { - if (String(p.user._id) === String(req.user._id)) pro.project[p.project._id].user += p.value; - pro.project[p.project._id].total += p.value; - }); - - res.render('dashboard', { - title: 'Dashboard' - , user: req.user - , projects: projects - , posts: posts - , participants: participants - , pro: pro - }); + + // FUN FUN FUN CALCULATIONS + posts.forEach(function(p) { + if (String(p.user._id) === String(req.user._id)) pro.project[p.project._id].user += p.value; + pro.project[p.project._id].total += p.value; + }); + + res.render('dashboard', { + title: 'Dashboard' + , user: req.user + , projects: projects + , posts: posts + , participants: participants + , pro: pro }); }); - /* res.render('dashboard', { - title: 'Dashboard', - user: req.user, - projects: projects - }); -*/ }); }); - -/* - Project.find(function(err, projects) { - if (err) return res.status(500).render('error', { title: '500', text: 'En serverfeil oppstod', error: err.stack }); - res.render('dashboard', { - title: 'Dashboad', - user: req.user, - projects: projects - }); - });*/ } +/** + * GET '/project/:short' + * :short = shortURL for project + */ exports.project = function(req, res) { + // loads the project based on the :short part of the url Project.loadShort(req.params.short, function(err, project) { if (err || !project) return res.status(500).render('error', { title: '500', text: 'En serverfeil oppstod', error: err }); + + //loads all users in project Access.loadProject(project._id, function(err, access) { if (err) return res.status(500).render('error', { title: '500', text: 'En serverfeil oppstod', error: err.stack }); + + // loads all posts in project pPost.loadProject(project._id, function(err, posts) { if (err) return res.status(500).render('error', { title: '500', text: 'En serverfeil oppstod', error: err.stack }); @@ -171,10 +196,12 @@ exports.project = function(req, res) { pro.user[i].diff = parseFloat(pro.user[i].total - pro.each).toFixed(2); if (pro.user[i].diff > 0) pro.otot += parseFloat(pro.user[i].diff); } + + // sets the coefficient if the user is owed money for (var i in pro.user) { if (pro.user[i].diff > 0) pro.user[i].coeff = pro.user[i].diff / pro.otot; } - console.log(pro); + res.render('project/project', { title: project.name , user: req.user @@ -186,35 +213,52 @@ exports.project = function(req, res) { }); }); }); - }); } +/** + * GET '/project/:short/participants' + * + * POST is in app/controllers/users.js + */ + exports.projectParticipants = function(req, res) { + // check if user is actually registered if (req.user.status < 3) { if (req.header('Referer') === undefined) { return res.status(403).render('error', { title: 403, text: 'Du har ikke tilgang til denne siden. Du må registrere deg først. Sjekk mailen din for å se invitekode.' }); } else { return res.redirect('back'); } } - res.render('project/participants', { title: 'Prosjektdeltakere', user: req.user }); + res.render('project/participants', { + title: 'Prosjektdeltakere' + , user: req.user + }); } +/** + * GET '/projet/:short/post' + */ + exports.projectPost = function(req, res) { - /** ################################### - * Need to check if user has access to this project!! - */ Project.loadShort(req.params.short, function(err, project) { if (err) return res.status(500).render('error', { title: '500', text: 'En serverfeil oppstod', error: err.stack }); req.project = project; - res.render('project/post', { title: 'Legg til utgift', user: req.user, req: req, project: project }); + res.render('project/post', { + title: 'Legg til utgift' + , user: req.user + , req: req + , project: project + }); }); +} - -} +/** + * POST '/project:short/post' + */ exports.postProjectPost = function(req, res) { @@ -245,6 +289,7 @@ exports.postProjectPost = function(req, res) { ppost.participants = sanitize(req.body.participants).escape(); ppost.value = sanitize(req.body.value).toInt(); // this will remove leading zeroes. '0123' => '123' ppost.when = new Date(sanitize(req.body.date).escape() + ' ' + sanitize(req.body.time).escape() + ':00'); + ppost.save(function(err) { if (err) return res.render('project/post', { title: 'Legg til utgift - en feil oppstod', user: req.user, req: req, project: project }); return res.redirect('/project/' + project.shortURL); @@ -252,15 +297,29 @@ exports.postProjectPost = function(req, res) { }); }); } + + +/** + * GET '/project/new' + */ + exports.newProject = function(req, res) { if (req.user.status < 3) { if (req.header('Referer') === undefined) { return res.status(403).render('error', { title: 403, text: 'Du har ikke tilgang til denne siden. Du må registrere deg først. Sjekk mailen din for å se invitekode.' }); } else { return res.redirect('back'); } } - res.render('project/newProject', { title: 'Nytt prosjekt', user: req.user }); + res.render('project/newProject', { + title: 'Nytt prosjekt' + , user: req.user + }); } + +/** + * POST '/project/new' + */ + exports.postNewProject = function(req, res) { if (req.user.status < 3) { if (req.header('Referer') === undefined) { return res.status(403).render('error', { title: 403, text: 'Du har ikke tilgang til denne siden. Du må registrere deg først. Sjekk mailen din for å se invitekode.' }); } @@ -282,7 +341,10 @@ exports.postNewProject = function(req, res) { access.save(function(err) { if (err) { console.log(err.errors); - return res.render('project/newProject', { title: 'Nytt prosjekt - en feil oppstod', user: req.user }); + return res.render('project/newProject', { + title: 'Nytt prosjekt - en feil oppstod' + , user: req.user + }); } return res.redirect('/dashboard'); }); @@ -291,18 +353,30 @@ exports.postNewProject = function(req, res) { } +/** + * GET '/project/:short/delete/:post' + */ + exports.deleteProjectPost = function(req, res) { + + //Locate project Project.findOne({ shortURL: req.params.short }).select('_id').exec(function(err, project) { if (err) return res.status(500).render('error', { title: '500', text: 'En serverfeil oppstod', error: err.stack }); + + //make sure you actually have access Access.findOne({project: project._id, user: req.user._id}, function(err, access) { if (err) return res.status(500).render('error', { title: '500', text: 'En serverfeil oppstod', error: err.stack }); if (!access) return res.status(403).render('error', { title: '403', text: 'Du har ikke tilgang til å gjøre dette' }); + pPost.load(req.params.post, function(err, post) { if (err || !post) return res.status(500).render('error', { title: '500', text: 'En serverfeil oppstod', error: err }); + if (post.user._id === req.user._id || access.permissions >= 6) { + + // delete! (only if access) pPost.remove({ _id: post._id }, function(err) { if (err) return res.status(500).render('error', { title: '500', text: 'En serverfeil oppstod', error: err.stack }); - console.log('deleted post ' + post._id); + return res.redirect('back'); }) } else { return res.status(403).render('error', { title: '403', text: 'Du har ikke tilgang til å gjøre dette' }); } diff --git a/app/controllers/users.js b/app/controllers/users.js index 237d359..d2569fa 100644 --- a/app/controllers/users.js +++ b/app/controllers/users.js @@ -26,8 +26,9 @@ Validator.prototype.getErrors = function() { /** - * Logout + * GET '/logout' */ + exports.logout = function(req, res) { req.logout(); res.redirect('/'); @@ -35,13 +36,20 @@ exports.logout = function(req, res) { /** - * Signin + * GET '/signin' * This is triggered when the user post to /login */ + exports.signin = function(req, res) { res.redirect('/dashboard'); } + +/** + * GET '/login/:hash' + * This is triggered when a user tries to log in using a unique link he got in the mail + */ + exports.randomLogin = function(req, res) { Access.findOne({ randomToken: req.params.hash }).populate('project', 'shortURL').exec(function(err, access) { if (err) return res.status(500).render('error', { title: '500', text: 'En serverfeil oppstod', error: err.stack }); @@ -52,15 +60,22 @@ exports.randomLogin = function(req, res) { /** - * Signup + * GET '/signup' */ + exports.signup = function(req, res) { - res.render('users/signup', { title: 'Registrer deg', invite: false }); + res.render('users/signup', { + title: 'Registrer deg' + , invite: false + }); } + /** - * Create users + * POST '/signup' + * This is when a user has posted his registration form */ + exports.create = function(req, res) { var user = new User(req.body); user.provider = 'local'; @@ -75,7 +90,7 @@ exports.create = function(req, res) { /** - * AuthCallback + * GET '/auth/facebook/callback' OR '/auth/twitter/callback' * This is what happends when a user has signed in using facebook/twitter */ @@ -88,7 +103,7 @@ exports.authCallback = function(req, res, next) { /** - * registerEmail + * GET '/registerEmail' * Will register the users email if they don't have already */ @@ -100,7 +115,7 @@ exports.registerEmail = function(req, res) { /** - * postRegisterEmail + * POST '/registerEmail' */ exports.postRegisterEmail = function(req, res) { @@ -118,6 +133,7 @@ exports.postRegisterEmail = function(req, res) { User.update({ _id: req.user._id }, { email: req.body.email, status: 3 }, function(err) { if (err) return res.status(500).render('error', { title: '500', text: 'En serverfeil oppstod', error: err.stack }); + return res.redirect('/dashboard'); }); }); @@ -125,25 +141,25 @@ exports.postRegisterEmail = function(req, res) { /** - * postProjectParticipants + * POST '/project/:short/participants' * This callback is in this file because it treats users. */ + exports.postProjectParticipants = function(req, res) { Project.loadShort(req.params.short, function(err, project) { if (err || !project) return res.status(500).render('error', { title: '500', text: 'En serverfeil oppstod', error: err.stack }); + // check if users has access Access.checkAccess(req.user._id, project._id, 3, function(err, access) { if (err || !access) return res.status(403).render('error', { title: '403', text: 'No sir! NO ACCESS FOR YOU', error: err || 'no access' }); // validate var emails = sanitize(req.body.emails).xss(); v.check(emails, 'You need to enter some emails to invite someone').notEmpty(); - //var emails = sanitize(req.body.emails).xss(); + emails = emails.split('\r\n'); emails.forEach(function(m) { // m = each mailaddress - if (m) { - v.check(m, m + ' is not a valid email').isEmail(); - } + if (m) v.check(m, m + ' is not a valid email').isEmail(); }); // error when validation fails @@ -156,34 +172,39 @@ exports.postProjectParticipants = function(req, res) { , server = email.server.connect(config.email) , message = { subject: 'You were invited to use Divid', - text: 'VIL DU BRUK DIVID?', + text: 'Ønsker du å bruke Divid?', // this text will be substituted later on from: 'Divid <divid@divid.no>', } + emails.forEach(function(mailAddress) { // loops through all the emails and sets up each user User.loadUser(mailAddress, function(err, user) { if (err) return res.status(500).render('error', { title: '500', text: 'En serverfeil oppstod', error: err.stack }); - if (!user) { //if the user doesn't exist, create one + + //if the user doesn't exist, create one + if (!user) { console.log('fant ingen brukere med den eposten. må invitere og stasj'); + var newUser = new User(); newUser.email = mailAddress; newUser.username = mailAddress; - newUser.name = mailAddress + ' <span class="muted">(ikke registrert)</span>'; + newUser.name = mailAddress + ' <span class="muted">(ikke registrert)</span>'; // this is what we call the user when he's not registered newUser.status = 1; newUser.password = newUser.generateRandomToken(32); newUser.randomToken = newUser.generateRandomToken(10, true); + newUser.save(function(err) { if (err) return res.render('project/participants', { title: 'Nytt prosjekt - en feil oppstod', loggedin: true }); console.log('made new user ' + newUser._id); + var access = new Access(); access.user = newUser._id; access.creator = req.user._id; access.project = project._id; access.randomToken = access.generateRandomToken(15); + access.save(function(err) { - if (err) { - console.log(err.errors); - return res.render('project/participants', { title: 'Nytt prosjekt - en feil oppstod', loggedin: true }); - } + if (err) return res.render('project/participants', { title: 'Nytt prosjekt - en feil oppstod', loggedin: true }); + console.log('made new access for user ' + newUser._id); message.to = newUser.email; message.text = 'Hei! Du har blitt invitert til å delta i et Divid-prosjekt! https://divid.no/invite/' + newUser.randomToken + '\n Du kan også gå direkte til prosjektet her: https://divid.no/login/' + access.randomToken; @@ -191,27 +212,29 @@ exports.postProjectParticipants = function(req, res) { }); }); - } else { // if the user exists, add him to the project + // if the user exists, add him to the project + } else { Access.checkAccess(user._id, project._id, 0, function(err, acc) { if (err) return res.render('project/participants', { title: 'Nytt prosjekt - en feil oppstod', loggedin: true }); - if (acc) { // if the user already has access to the project.. do nothing + + // if the user already has access to the project.. do nothing + if (acc) { console.log('user ' + user.email + ' already has access to project ' + project.name); } else { - console.log('fant en bruker. må lage ny access til han og si i fra.'); var access = new Access(); access.user = user._id; access.creator = req.user._id; access.project = project._id; message.text = 'Du ble lagt til projektet "' + project.name + '"'; + if (Number(user.status) < 3) { access.randomToken = access.generateRandomToken(15); message.text += '.\nDu kan få direkte tilgang til dette prosjektet her: https://divid.no/login/' + access.randomToken + ' \nDu kan bruke denne linken for å registrere deg, for å få tilgang til flere funksjoner: https://divid.no/invite/' + user.randomToken; } + access.save(function(err) { - if (err) { - console.log(err.errors); - return res.render('project/participants', { title: 'Nytt prosjekt - en feil oppstod', loggedin: true }); - } + if (err) return res.render('project/participants', { title: 'Nytt prosjekt - en feil oppstod', loggedin: true }); + console.log('made new access for user ' + user.username); message.to = user.email; server.send(message, function(err, message) { console.log(err || message);}); @@ -220,7 +243,7 @@ exports.postProjectParticipants = function(req, res) { }); } }); - }); + }); res.redirect('back'); }); @@ -229,7 +252,7 @@ exports.postProjectParticipants = function(req, res) { /** - * claimInvite + * GET '/invite/:randomToken' * So users can use their inviteEmail */ @@ -241,16 +264,18 @@ exports.claimInvite = function(req, res) { if (!user) return res.render('error', { title: 'This invite does not exist', text: 'Invitasjonen din er ugyldig' }); res.render('users/signup', { - invite: true, - title: 'Registrer deg!', - email: user.email } - ); + invite: true + , title: 'Registrer deg!' + , email: user.email + }); }); - - } +/** + * POST '/invite/:randomToken' + */ + exports.postClaimInvite = function(req, res) { User.findOne({ randomToken: sanitize(req.params.randomToken).escape(), status: 1 }, function(err, user) { @@ -270,6 +295,7 @@ exports.postClaimInvite = function(req, res) { user.provider = 'local'; user.status = 3; user.randomToken = ''; + user.save(function(err) { if (err) return res.render('signup', { errors: err.errors, user: user }); req.logIn(user, function(err) { diff --git a/app/models/Access.js b/app/models/Access.js index f4bee92..aa48340 100644 --- a/app/models/Access.js +++ b/app/models/Access.js @@ -19,13 +19,13 @@ var mongoose = require('mongoose') */ var AccessSchema = new Schema({ - user: { type: Schema.ObjectId, ref: 'User' }, - creator: { type: Schema.ObjectId, ref: 'User' }, - project: { type: Schema.ObjectId, ref: 'Project' }, - permissions: { type: Number, default: '3' }, - randomToken: { type: String }, - created: { type: Date, default: Date.now }, - updated: { type: Date, default: Date.now } + user: { type: Schema.ObjectId, ref: 'User' } + , creator: { type: Schema.ObjectId, ref: 'User' } + , project: { type: Schema.ObjectId, ref: 'Project' } + , permissions: { type: Number, default: '3' } + , randomToken: String + , created: { type: Date, default: Date.now } + , updated: { type: Date, default: Date.now } }); @@ -38,7 +38,6 @@ AccessSchema.methods = { * * @param {Number} length * @return {String} - * @api public */ generateRandomToken: function(length) { @@ -58,15 +57,15 @@ AccessSchema.statics = { /** * Load ALL accesses for a single user + * This will load all the persmissions a user has, and include info about the projects * * @param {ObjectId} id * @param {Function} callback - * @api private */ loadUser: function(id, callback) { this.find({ user: id }) - .populate('project') + .populate('project') // will joins the data from the project .sort({ 'created': -1 }) // sort by date .exec(callback); }, @@ -77,7 +76,6 @@ AccessSchema.statics = { * * @param {ObjectId} project * @param {Function} callback - * @api private */ loadProject: function(project, callback) { @@ -90,10 +88,11 @@ AccessSchema.statics = { /** * Load all users associated with several projects + * This is useful for the dashboard, where all the projects of a user is loaded. This way + * we can print the name of the participants in each project the user has access to. * - * @param {Arrau[ObjectId]} projects + * @param {Array[ObjectId]} projects * @param {Function} callback - * @api private */ loadProjects: function(projects, callback) { @@ -111,7 +110,6 @@ AccessSchema.statics = { * @param {ObjectId} project * @param {Number} permissisons * @param {Function} callback - * @api private */ checkAccess: function(user, project, permissions, callback) { diff --git a/app/models/Project.js b/app/models/Project.js index ba0e8e7..5f8e196 100644 --- a/app/models/Project.js +++ b/app/models/Project.js @@ -7,14 +7,14 @@ var mongoose = require('mongoose') , Schema = mongoose.Schema; var ProjectSchema = new Schema({ - user: { type: Schema.ObjectId, ref: 'User' }, - name: { type: String, default: '', trim: true }, - description: {type: String, default: '', trim: true }, - currency: { type: String, default: 'kr', trim: true }, - public: { type: String, default: 'invite-only' }, - created: { type: Date, default: Date.now }, - updated: { type: Date, default: Date.now }, - shortURL: { type: String, unique: true } + user: { type: Schema.ObjectId, ref: 'User' } + , name: { type: String, default: '', trim: true } + , description: { type: String, default: '', trim: true } + , currency: { type: String, default: 'kr', trim: true } + , public: { type: String, default: 'invite-only' } + , created: { type: Date, default: Date.now } + , updated: { type: Date, default: Date.now } + , shortURL: { type: String, unique: true } }); // the four validations below only apply if you are signing up traditionally @@ -25,6 +25,8 @@ ProjectSchema.path('name').validate(function(name) { }, 'Project name cannot be blank'); + +// This is a pre-save-hook. It runs every time an object is saved. ProjectSchema.pre('save', function(next) { if (this.shortURL !== undefined) return next(); var chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"; diff --git a/app/models/User.js b/app/models/User.js index 668b36f..c07a298 100644 --- a/app/models/User.js +++ b/app/models/User.js @@ -20,19 +20,19 @@ var mongoose = require('mongoose') */ var UserSchema = new Schema({ - name: String, - email: { type: String, unique: true }, - username: String, - provider: String, - hashed_password: String, - salt: String, - accessToken: String, - facebook: {}, - twitter: {}, - status: { type: Number, default: 2 }, - randomToken: String, - created: { type: Date, default: Date.now }, - updated: { type: Date, default: Date.now } + name: String + , email: { type: String, unique: true } + , username: String + , provider: String + , hashed_password: String + , salt: String + , accessToken: String + , facebook: {} + , twitter: {} + , status: { type: Number, default: 2 } + , randomToken: String + , created: { type: Date, default: Date.now } + , updated: { type: Date, default: Date.now } }); @@ -108,19 +108,19 @@ UserSchema.methods = { */ authenticate: function(plainText) { - return this.encryptPassword(plainText) === this.hashed_password; + return this.encryptPassword(plainText) === this.hashed_password; // will return true or false }, /** * Make salt + * This is used to make the password hash cryptographically stronger * * @return {String} - * @api public */ makeSalt: function() { - return Math.round((new Date().valueOf() * Math.random())) + ''; + return Math.round((new Date().valueOf() * Math.random())) + ''; // valueOf date and random number = random stuff! }, @@ -129,12 +129,12 @@ UserSchema.methods = { * * @param {String} password * @return {String} - * @api public */ encryptPassword: function(password) { if (!password) return ''; - return crypto.createHmac('sha1', this.salt).update(password).digest('hex'); + // if the user isn't registered, he has no salt. Therefore he can not log in. He has to use his email. + return crypto.createHmac('sha1', this.salt || Math.random() + Math.random()).update(password).digest('hex'); }, @@ -144,13 +144,12 @@ UserSchema.methods = { * @param {Number} length * @param {Boolean} noDate * @return {String} - * @api public */ generateRandomToken: function(length, noDate) { if (typeof(length) === undefined) length = 16; // default length of token var chars = '_-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890' - , token = noDate ? '' : new Date().getTime() + '_'; + , token = noDate ? '' : new Date().getTime() + '_'; // if noDate is provided as true, the random token will not start with a timestamp. for (var i = 0; i < length; i++) { var x = Math.floor(Math.random() * chars.length); token += chars.charAt(x); @@ -166,7 +165,6 @@ UserSchema.statics = { * * @param {String} email * @param {Function} callback - * @api private */ loadUser: function(email, callback) { diff --git a/app/models/pPost.js b/app/models/pPost.js index 1f53984..d138c8f 100644 --- a/app/models/pPost.js +++ b/app/models/pPost.js @@ -7,18 +7,18 @@ var mongoose = require('mongoose') , Schema = mongoose.Schema; var pPostSchema = new Schema({ - user: { type: Schema.ObjectId, ref: 'User' }, - for: { type: Schema.ObjectId, ref: 'User' }, - project: { type: Schema.ObjectId, ref: 'Project' }, - what: { type: String, default: '', trim: true }, - comment: { type: String, default: '', trim: true }, - participants: [], - value: { type: Number, defailt: 0 }, - file: { type: String, default: '', trim: true }, - currency: { type: String, default: 'kr', trim: true }, - created: { type: Date, default: Date.now }, - updated: { type: Date, default: Date.now }, - when: { type: Date, default: Date.now } + user: { type: Schema.ObjectId, ref: 'User' } + , for: { type: Schema.ObjectId, ref: 'User' } + , project: { type: Schema.ObjectId, ref: 'Project' } + , what: { type: String, default: '', trim: true } + , comment: { type: String, default: '', trim: true } + , participants: [] + , value: { type: Number, default: 0 } + , file: { type: String, default: '', trim: true } + , currency: { type: String, default: 'kr', trim: true } + , created: { type: Date, default: Date.now } + , updated: { type: Date, default: Date.now } + , when: { type: Date, default: Date.now } }); @@ -31,12 +31,11 @@ pPostSchema.statics = { * * @param {ObjectId} id * @param {Function} callback - * @api private */ load: function(id, callback) { this.findOne({ _id: id }) - .populate({ path: 'user', select: '_id, name'}) + .populate({ path: 'user', select: '_id, name'}) // include name of the user who posted it .exec(callback); }, @@ -46,23 +45,21 @@ pPostSchema.statics = { * * @param {ObjectId} project * @param {Function} callback - * @api private */ loadProject: function(project, callback) { this.find({ project: project }) - .populate('user') + .populate({ path: 'user', select: '_id, name'}) .sort({ 'when': -1, 'created': -1 }) .exec(callback); }, /** - * Find last ten posts belonging projects a user is part of, by project ids + * Find all posts that belongs to projects provided in an array * * @param {Array[ObjectId]} projects * @param {Function} callback - * @api private */ loadByProjects: function(projects, callback) { diff --git a/config/config.js b/config/config.js index 3637cf3..c7ff42a 100644 --- a/config/config.js +++ b/config/config.js @@ -4,26 +4,26 @@ var path = require('path') module.exports = { development: { - db: 'mongodb://localhost/Divid', - root: rootPath, - app: { + db: 'mongodb://localhost/Divid' + , root: rootPath + , app: { name: 'Divid' - }, - facebook: { - clientID: '504825706245603', - clientSecret: 'e5ea0faed85d8749cafd38732530ef35', - callbackURL: 'https://divid.no/auth/facebook/callback' - }, - twitter: { - clientID: 'tpCfKBUyAfogTpFxnb9w', - clientSecret: 'abzInK4Nu0IFUhyXl73O2XjlFLFlzmBtLmbXk6v8', - callbackURL: 'https://divid.no/auth/twitter/callback' - }, - email: { - server: 'localhost', - ssl: false - }, - sessionSecret: 'lsdrghoi4hgqio42nqf2uqi32f3bilu23fl23b', + } + , facebook: { + clientID: '504825706245603' + , clientSecret: 'e5ea0faed85d8749cafd38732530ef35' + , callbackURL: 'https://divid.no/auth/facebook/callback' + } + , twitter: { + clientID: 'tpCfKBUyAfogTpFxnb9w' + , clientSecret: 'abzInK4Nu0IFUhyXl73O2XjlFLFlzmBtLmbXk6v8' + , callbackURL: 'https://divid.no/auth/twitter/callback' + } + , email: { + server: 'localhost' + , ssl: false + } + , sessionSecret: 'lsdrghoi4hgqio42nqf2uqi32f3bilu23fl23b' } } diff --git a/config/express.js b/config/express.js index a281123..d9d4633 100644 --- a/config/express.js +++ b/config/express.js @@ -33,8 +33,8 @@ module.exports = function (app, config, passport) { app.use(express.session({ secret: config.sessionSecret })); // use passport session - app.use(passport.initialize()); - app.use(passport.session()); + app.use(passport.initialize()); // initializes passport, our login module + app.use(passport.session()); // With sessions! app.use(express.favicon(__dirname + '/public/favicon.ico')); @@ -43,6 +43,8 @@ module.exports = function (app, config, passport) { app.use(app.router); + // If no routes are triggered, we reach these babies: + app.use(function(err, req, res, next) { if (~err.message.indexOf('not found')) return next(); // treat like 404 diff --git a/config/middlewares/authorization.js b/config/middlewares/authorization.js index b881a3d..6726f8b 100644 --- a/config/middlewares/authorization.js +++ b/config/middlewares/authorization.js @@ -1,4 +1,4 @@ - +// AUTH Middleware. This is what checks if you are logged in. /* * Generic require login routing diff --git a/config/passport.js b/config/passport.js index e0be2d9..ae8d34a 100644 --- a/config/passport.js +++ b/config/passport.js @@ -37,7 +37,7 @@ module.exports = function (passport, config) { 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); + return done(null, user); // yay! }); })); @@ -48,7 +48,7 @@ module.exports = function (passport, config) { User.findOne({ _id: access.user }, function(err, user) { if (err) return done(err); if (!user) return done(null, false, { message: 'Unknown user' }); - return done(null, user); + return done(null, user); // yay! }); }); })); @@ -115,9 +115,5 @@ module.exports = function (passport, config) { })); - - - - } diff --git a/config/routes.js b/config/routes.js index 8ba83a9..8f5865a 100644 --- a/config/routes.js +++ b/config/routes.js @@ -32,7 +32,7 @@ module.exports = function(app, passport, auth) { app.get('/auth/twitter', passport.authenticate('twitter', { failureRedirect: '/' }), users.signin); app.get('/auth/twitter/callback', passport.authenticate('twitter', { failureRedirect: '/' }), users.authCallback); - app.get('/invite/:randomToken', users.claimInvite); + app.get('/invite/:randomToken', users.claimInvite); // :randomToken can be retrieved in 'req.params.randomToken' app.post('/invite/:randomToken', users.postClaimInvite); @@ -40,12 +40,12 @@ module.exports = function(app, passport, auth) { app.get('/login/:hash', passport.authenticate('hash', { failureRedirect: '/'}), users.randomLogin); + /** * REQUIRES LOGIN * ============================================================ */ - app.get('/dashboard', auth.requiresLogin, system.dashboard); app.get('/registerEmail', auth.requiresLogin, users.registerEmail); @@ -15,7 +15,7 @@ var express = require('express') var port = process.env.PORT || 8000 , env = process.env.NODE_ENV || 'development' - , config = require('./config/config')[env] + , config = require('./config/config')[env] // loads the config for the current environment , auth = require('./config/middlewares/authorization'); |