From ffa829bfac120b8e70eaffdd19ed5f5fc4fc14cb Mon Sep 17 00:00:00 2001 From: Keith Irwin Date: Fri, 28 Apr 2017 05:11:39 -0400 Subject: [PATCH 1/5] Bumped version to 0.6.1 --- README.md | 4 +++- package.json | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 1daafb0..f5215a2 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # []Tracman -###### v 0.6.0 +###### v 0.6.1 node.js application to display a sharable map with user's location. @@ -42,6 +42,8 @@ Tracman will be updated according to [this branching model](http://nvie.com/post ## Changelog +#### v0.6.1 + #### v0.6.0 * [#32](https://github.com/Tracman-org/Server/issues/32), [#57](https://github.com/Tracman-org/Server/issues/57), [#58](https://github.com/Tracman-org/Server/issues/58), [#60](https://github.com/Tracman-org/Server/issues/60) Added more login options diff --git a/package.json b/package.json index bf76c38..dcf5881 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "tracman", - "version": "0.6.0", + "version": "0.6.1", "description": "Tracks user's GPS location", "main": "server.js", "dependencies": { From 49c6a105a75b4807ba254d40318bb2691720621e Mon Sep 17 00:00:00 2001 From: Keith Irwin Date: Fri, 28 Apr 2017 14:15:20 -0400 Subject: [PATCH 2/5] Removed logging --- config/models.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/config/models.js b/config/models.js index 9edb081..4701f2e 100644 --- a/config/models.js +++ b/config/models.js @@ -79,7 +79,7 @@ const userSchema = new mongoose.Schema({ // Reuse old token, resetting clock if ( user.auth.passTokenExpires >= Date.now() ){ - console.log(`Reusing old password token...`); + //console.log(`Reusing old password token...`); user.auth.passTokenExpires = Date.now() + 3600000; // 1 hour user.save() .then( ()=>{ @@ -92,7 +92,7 @@ const userSchema = new mongoose.Schema({ // Create new token else { - console.log(`Creating new password token...`); + //console.log(`Creating new password token...`); crypto.randomBytes(16, (err,buf)=>{ if (err){ return next(err,null,null); } if (buf) { From 0f338b0d6f845bf9f00276f44af9c8efbda10039 Mon Sep 17 00:00:00 2001 From: Keith Irwin Date: Fri, 28 Apr 2017 14:21:10 -0400 Subject: [PATCH 3/5] #77 Better error handling after password creation --- config/routes/auth.js | 45 +++++++++++++++++++++++--------------- config/routes/settings.js | 46 ++++++++++++++++++++------------------- 2 files changed, 52 insertions(+), 39 deletions(-) diff --git a/config/routes/auth.js b/config/routes/auth.js index f028cde..3536257 100644 --- a/config/routes/auth.js +++ b/config/routes/auth.js @@ -5,6 +5,7 @@ const mail = require('../mail.js'), User = require('../models.js').user, crypto = require('crypto'), + moment = require('moment'), env = require('../env/env.js'); module.exports = (app, passport) => { @@ -61,26 +62,36 @@ module.exports = (app, passport) => { function sendToken(user){ // Create a password token - user.createPassToken((err,token)=>{ - if (err){ mw.throwErr(err,req); } - - // Email the instructions to continue - mail.send({ - from: mail.from, - to: `<${user.email}>`, - subject: 'Complete your Tracman registration', - text: mail.text(`Welcome to Tracman! \n\nTo complete your registration, follow this link and set your password:\n${env.url}/settings/password/${token}`), - html: mail.html(`

Welcome to Tracman!

To complete your registration, follow this link and set your password:
${env.url}/settings/password/${token}

`) - }) - .then(()=>{ - req.flash('success', `An email has been sent to ${user.email}. Check your inbox to complete your registration. `); - res.redirect('/login'); - }) - .catch((err)=>{ + user.createPassToken((err,token,expires)=>{ + if (err){ mw.throwErr(err,req); res.redirect('/login#signup'); - }); + } + else { + + // Figure out expiration time + let expirationTimeString = (req.query.tz)? + moment(expires).utcOffset(req.query.tz).toDate().toLocaleTimeString(req.acceptsLanguages[0]): + moment(expires).toDate().toLocaleTimeString(req.acceptsLanguages[0])+" UTC"; + // Email the instructions to continue + mail.send({ + from: mail.from, + to: `<${user.email}>`, + subject: 'Complete your Tracman registration', + text: mail.text(`Welcome to Tracman! \n\nTo complete your registration, follow this link and set your password:\n${env.url}/settings/password/${token}\n\nThis link will expire at ${expirationTimeString}. `), + html: mail.html(`

Welcome to Tracman!

To complete your registration, follow this link and set your password:
${env.url}/settings/password/${token}

This link will expire at ${expirationTimeString}.

`) + }) + .then(()=>{ + req.flash('success', `An email has been sent to ${user.email}. Check your inbox and follow the link to complete your registration. (Your registration link will expire in one hour). `); + res.redirect('/login'); + }) + .catch((err)=>{ + mw.throwErr(err,req); + res.redirect('/login#signup'); + }); + + } }); } diff --git a/config/routes/settings.js b/config/routes/settings.js index ad5d147..09d6f0b 100644 --- a/config/routes/settings.js +++ b/config/routes/settings.js @@ -232,30 +232,32 @@ router.route('/password') mw.throwErr(err,req); res.redirect((req.user)?'/settings':'/login'); } + else { - // Figure out expiration time - let expirationTimeString = (req.query.tz)? - moment(expires).utcOffset(req.query.tz).toDate().toLocaleTimeString(req.acceptsLanguages[0]): - moment(expires).toDate().toLocaleTimeString(req.acceptsLanguages[0])+" UTC"; - - // Confirm password change request by email. - mail.send({ - to: mail.to(req.user), - from: mail.from, - subject: 'Request to change your Tracman password', - text: mail.text(`A request has been made to change your tracman password. If you did not initiate this request, please contact support at keith@tracman.org. \n\nTo change your password, follow this link:\n${env.url}/settings/password/${token}. \n\nThis request will expire at ${expirationTimeString}. `), - html: mail.html(`

A request has been made to change your tracman password. If you did not initiate this request, please contact support at keith@tracman.org.

To change your password, follow this link:
${env.url}/settings/password/${token}.

This request will expire at ${expirationTimeString}.

`) - }) - .then( ()=>{ - // Alert user to check email. - req.flash('success',`An link has been sent to ${req.user.email}. Click on the link to complete your password change. This link will expire in one hour (${expirationTimeString}). `); - res.redirect((req.user)?'/settings':'/login'); - }) - .catch( (err)=>{ - mw.throwErr(err,req); - res.redirect((req.user)?'/settings':'/login'); - }); + // Figure out expiration time + let expirationTimeString = (req.query.tz)? + moment(expires).utcOffset(req.query.tz).toDate().toLocaleTimeString(req.acceptsLanguages[0]): + moment(expires).toDate().toLocaleTimeString(req.acceptsLanguages[0])+" UTC"; + + // Confirm password change request by email. + mail.send({ + to: mail.to(req.user), + from: mail.from, + subject: 'Request to change your Tracman password', + text: mail.text(`A request has been made to change your tracman password. If you did not initiate this request, please contact support at keith@tracman.org. \n\nTo change your password, follow this link:\n${env.url}/settings/password/${token}. \n\nThis request will expire at ${expirationTimeString}. `), + html: mail.html(`

A request has been made to change your tracman password. If you did not initiate this request, please contact support at keith@tracman.org.

To change your password, follow this link:
${env.url}/settings/password/${token}.

This request will expire at ${expirationTimeString}.

`) + }) + .then( ()=>{ + // Alert user to check email. + req.flash('success',`An link has been sent to ${req.user.email}. Click on the link to complete your password change. This link will expire in one hour (${expirationTimeString}). `); + res.redirect((req.user)?'/settings':'/login'); + }) + .catch( (err)=>{ + mw.throwErr(err,req); + res.redirect((req.user)?'/settings':'/login'); + }); + } }); } ); From 6758d0a7a12cfc88478f8802c7d229dd31bece1e Mon Sep 17 00:00:00 2001 From: Keith Irwin Date: Fri, 28 Apr 2017 15:37:22 -0400 Subject: [PATCH 4/5] #77 Fixed 500 after setting password, updated packages --- README.md | 3 +++ config/models.js | 31 ++++++++++++++++++++++--------- config/routes/settings.js | 33 +++++++++++++-------------------- package.json | 7 ++----- server.js | 4 +--- 5 files changed, 41 insertions(+), 37 deletions(-) diff --git a/README.md b/README.md index f5215a2..26c5718 100644 --- a/README.md +++ b/README.md @@ -44,6 +44,9 @@ Tracman will be updated according to [this branching model](http://nvie.com/post #### v0.6.1 +* [#77](https://github.com/Tracman-org/Server/issues/77) Fixed 500 after password change, swapped `bcrypt` for `bcrypt-nodejs` +* Removed extraneous packages + #### v0.6.0 * [#32](https://github.com/Tracman-org/Server/issues/32), [#57](https://github.com/Tracman-org/Server/issues/57), [#58](https://github.com/Tracman-org/Server/issues/58), [#60](https://github.com/Tracman-org/Server/issues/60) Added more login options diff --git a/config/models.js b/config/models.js index 4701f2e..9fa6895 100644 --- a/config/models.js +++ b/config/models.js @@ -2,7 +2,7 @@ const mongoose = require('mongoose'), unique = require('mongoose-unique-validator'), - bcrypt = require('bcrypt-nodejs'), + bcrypt = require('bcrypt'), crypto = require('crypto'); const userSchema = new mongoose.Schema({ @@ -111,18 +111,31 @@ const userSchema = new mongoose.Schema({ }; - // Generate hash for new password - userSchema.methods.generateHash = function(password,next){ - // next(err,hash); - bcrypt.genSalt(8) - .then( (salt)=>{ - bcrypt.hash(password, salt, null, next); - }) - .catch( (err)=>{ return next(err,null); }); + // Generate hash for new password and save it to the database + userSchema.methods.generateHashedPassword = function(password,next){ + // next(err); + + // Delete token + this.auth.passToken = undefined; + this.auth.passTokenExpires = undefined; + + // Generate hash + bcrypt.genSalt(8, (err,salt)=>{ + if (err){ return next(err); } + bcrypt.hash(password, salt, (err,hash)=>{ + if (err){ return next(err); } + this.auth.password = hash; + this.save(); + next(); + }); + }); + }; // Check for valid password userSchema.methods.validPassword = function(password,next){ + // next(err,res); + // res = true/false bcrypt.compare(password, this.auth.password, next); }; diff --git a/config/routes/settings.js b/config/routes/settings.js index 09d6f0b..bd985ea 100644 --- a/config/routes/settings.js +++ b/config/routes/settings.js @@ -301,31 +301,24 @@ router.route('/password/:token') else { - // Delete token - res.locals.passwordUser.auth.passToken = undefined; - res.locals.passwordUser.auth.passTokenExpires = undefined; - - // Create hash - res.locals.passwordUser.generateHash( req.body.password, (err,hash)=>{ + // Create hashed password and save to db + res.locals.passwordUser.generateHashedPassword( req.body.password, (err)=>{ if (err){ mw.throwErr(err,req); res.redirect(`/password/${req.params.token}`); } - else { - - // Save new password to db - res.locals.passwordUser.auth.password = hash; - res.locals.passwordUser.save() - .then( ()=>{ - req.flash('success', 'Password set. You can use it to log in now. '); - res.redirect('/login#login'); - }) - .catch( (err)=>{ - mw.throwErr(err,req); - res.redirect('/login#signup'); - }); - + + // User changed password + else if (req.user) { + req.flash('success', 'Your password has been changed. '); + res.redirect('/settings'); } + // New user created password + else { + req.flash('success', 'Password set. You can use it to log in now. '); + res.redirect('/login#login'); + } + } ); } diff --git a/package.json b/package.json index dcf5881..dcfb6e0 100644 --- a/package.json +++ b/package.json @@ -4,22 +4,19 @@ "description": "Tracks user's GPS location", "main": "server.js", "dependencies": { - "bcrypt-nodejs": "0.0.3", + "bcrypt": "^1.0.2", "body-parser": "^1.17.1", - "connect-flash": "^0.1.1", "connect-flash-plus": "^0.2.1", "cookie-parser": "^1.4.1", "cookie-session": "^2.0.0-alpha.1", "express": "^4.15.2", "express-validator": "^3.1.3", - "firebase": "^3.7.2", "kerberos": "0.0.17", "mellt": "^1.0.0", "moment": "^2.12.0", - "mongodb": "^2.1.4", + "mongodb": "^2.2.26", "mongoose": "^4.9.0", "mongoose-unique-validator": "^1.0.5", - "node-jose": "^0.8.0", "nodemailer": "^3.1.8", "nunjucks": "^2.3.0", "passport": "^0.3.2", diff --git a/server.js b/server.js index 40b33c9..49722c0 100755 --- a/server.js +++ b/server.js @@ -143,9 +143,7 @@ const // Development handlers else { app.use( (err,req,res,next)=>{ - if (err.status!==404) { - console.error(`❌ ${err.stack}`); - } + if (err.status!==404) { console.error(`❌ ${err.stack}`); } if (res.headersSent) { return next(err); } res.status(err.status||500); res.render('error', { From 4c5e18b6c1edd76af5bd5de0f3ed911ca3d2ae1b Mon Sep 17 00:00:00 2001 From: Keith Irwin Date: Fri, 28 Apr 2017 15:41:09 -0400 Subject: [PATCH 5/5] Added changelog, updated readme --- CHANGELOG.md | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++++ README.md | 49 +++++++++------------------------------------- 2 files changed, 64 insertions(+), 40 deletions(-) create mode 100644 CHANGELOG.md diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..e55744d --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,55 @@ +# Tracman Server Changelog +###### v 0.6.1 + +#### v0.6.1 + +* [#77](https://github.com/Tracman-org/Server/issues/77) Fixed 500 after password change, swapped `bcrypt` for `bcrypt-nodejs` +* Removed extraneous packages + +#### v0.6.0 + +* [#32](https://github.com/Tracman-org/Server/issues/32), [#57](https://github.com/Tracman-org/Server/issues/57), [#58](https://github.com/Tracman-org/Server/issues/58), [#60](https://github.com/Tracman-org/Server/issues/60) Added more login options +* [#50](https://github.com/Tracman-org/Server/issues/50) Replaced some callbacks with promises +* Minified static files +* [#51](https://github.com/Tracman-org/Server/issues/51), [#52](https://github.com/Tracman-org/Server/issues/52) Added settings validations +* [#54](https://github.com/Tracman-org/Server/issues/54), [#55](https://github.com/Tracman-org/Server/issues/55) Made map work better +* [#61](https://github.com/Tracman-org/Server/issues/61) New MongoDB security +* [#62](https://github.com/Tracman-org/Server/issues/62) Fixed error handling + +#### v0.5.1 + +* Fixed broken controls + +#### v0.5.0 + +* Updated libraries +* Fixed recognition of attached clients [#34](https://github.com/Tracman-org/Server/issues/21) +* Moved socket.io code to own file. +* Many minor fixes + +#### v0.4.3 + +* Fixed memory store [#21](https://github.com/Tracman-org/Server/issues/21) + +#### v0.4.2 + +* Fixed Streetview covering buttons +* Fixed error when viewing map of nonexistant user + +#### v0.4.1 + +* Users can view/change email address +* Added linked accounts to admin + +#### v0.4.0 + +* Opened registration +* Replaced 'Imperial' with 'Standard' +* Bug fixes + +#### v0.3.0 + +* Unified map and dashboard UI +* Security updates +* New admin UI +* \ No newline at end of file diff --git a/README.md b/README.md index 26c5718..7101417 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,7 @@ node.js application to display a sharable map with user's location. + ## Installation ```sh @@ -15,11 +16,12 @@ A good method is to simply copy the sample configuration and point `config/env/e ```sh $ cp config/env/sample.js config/env/my-config.js -$ echo "module.exports = require('./my-config.js');" > config/env/env.js +$ printf "'use strict';\n\nmodule.exports = require('./my-config.js');" > config/env/env.js ``` Then edit `config/env/my-config.js` to match your local environment. + ## Usage Run Tracman with npm: @@ -36,12 +38,16 @@ $ npm run nodemon Nodemon will automatically minify files and restart the app when you make changes. Check out the `nodemon.json` configuration. + ## Contributing Tracman will be updated according to [this branching model](http://nvie.com/posts/a-successful-git-branching-model)... more or less. If you know anything about programming Android, [the Tracman android app](https://github.com/Tracman-org/Android) is more desperate for help. + ## Changelog +[view full changelog](CHANGELOG.md) + #### v0.6.1 * [#77](https://github.com/Tracman-org/Server/issues/77) Fixed 500 after password change, swapped `bcrypt` for `bcrypt-nodejs` @@ -57,47 +63,10 @@ Tracman will be updated according to [this branching model](http://nvie.com/post * [#61](https://github.com/Tracman-org/Server/issues/61) New MongoDB security * [#62](https://github.com/Tracman-org/Server/issues/62) Fixed error handling -#### v0.5.1 - -* Fixed broken controls - -#### v0.5.0 - -* Updated libraries -* Fixed recognition of attached clients [#34](https://github.com/Tracman-org/Server/issues/21) -* Moved socket.io code to own file. -* Many minor fixes - -#### v0.4.3 - -* Fixed memory store [#21](https://github.com/Tracman-org/Server/issues/21) - -#### v0.4.2 - -* Fixed Streetview covering buttons -* Fixed error when viewing map of nonexistant user - -#### v0.4.1 - -* Users can view/change email address -* Added linked accounts to admin - -#### v0.4.0 - -* Opened registration -* Replaced 'Imperial' with 'Standard' -* Bug fixes - -#### v0.3.0 - -* Unified map and dashboard UI -* Security updates -* New admin UI - ## License -###### see [LICENSE.md](https://github.com/Tracman-org/Server/blob/master/LICENSE.md) +[view full license](LICENSE.md) Tracman: GPS tracking service in node.js Copyright © 2017 [Keith Irwin](https://keithirwin.us/) @@ -106,4 +75,4 @@ This program is free software: you can redistribute it and/or modify it under th This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. -You should have received a copy of the GNU General Public License along with this program. If not, see <[http://www.gnu.org/licenses/](http://www.gnu.org/licenses/)>. \ No newline at end of file +You should have received a copy of the GNU General Public License along with this program. If not, see <[http://www.gnu.org/licenses/](http://www.gnu.org/licenses/)>.