2017-04-11 19:38:07 -06:00
'use strict' ;
const slug = require ( 'slug' ) ,
xss = require ( 'xss' ) ,
2017-04-15 08:22:13 -06:00
mellt = require ( 'mellt' ) ,
2017-04-11 19:38:07 -06:00
mw = require ( '../middleware.js' ) ,
User = require ( '../models.js' ) . user ,
mail = require ( '../mail.js' ) ,
env = require ( '../env.js' ) ,
router = require ( 'express' ) . Router ( ) ;
2017-04-17 22:34:53 -06:00
// Validate email addresses
function validateEmail ( email ) {
var re = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/ ;
return re . test ( email ) ;
}
2017-04-11 19:38:07 -06:00
// Settings form
router . route ( '/' )
2017-04-13 16:53:18 -06:00
. all ( mw . ensureAuth , ( req , res , next ) => {
2017-04-11 19:38:07 -06:00
next ( ) ;
2017-04-13 16:53:18 -06:00
} )
2017-04-11 19:38:07 -06:00
// Get settings form
2017-04-14 20:10:52 -06:00
. get ( ( req , res ) => {
res . render ( 'settings' ) ;
2017-04-13 16:53:18 -06:00
} )
2017-04-11 19:38:07 -06:00
// Set new settings
2017-04-13 16:53:18 -06:00
. post ( ( req , res , next ) => {
2017-04-14 20:10:52 -06:00
2017-04-18 11:10:43 -06:00
function setSettings ( ) {
2017-04-18 11:03:24 -06:00
// Set values
req . user . name = xss ( req . body . name ) ;
req . user . slug = slug ( xss ( req . body . slug ) ) ;
req . user . settings = {
units : req . body . units ,
defaultMap : req . body . map ,
defaultZoom : req . body . zoom ,
showScale : ( req . body . showScale ) ? true : false ,
showSpeed : ( req . body . showSpeed ) ? true : false ,
showAlt : ( req . body . showAlt ) ? true : false ,
showStreetview : ( req . body . showStreet ) ? true : false
} ;
2017-04-18 11:10:43 -06:00
// Save user and send response
2017-04-18 11:03:24 -06:00
req . user . save ( )
. then ( ( ) => {
req . flash ( 'success' , 'Settings updated. ' ) ;
res . redirect ( '/settings' ) ;
} )
. catch ( ( err ) => {
mw . throwErr ( err , req ) ;
res . redirect ( '/settings' ) ;
} ) ;
2017-04-18 11:10:43 -06:00
}
// Validations
if ( req . body . slug === '' ) {
req . flash ( 'warning' , ` You must supply a slug. ` ) ;
res . redirect ( '/settings' ) ;
}
else if ( ! validateEmail ( req . body . email ) ) {
req . flash ( 'warning' , ` <u> ${ req . body . email } </u> is not a valid email address. ` ) ;
res . redirect ( '/settings' ) ;
}
else {
2017-04-18 11:03:24 -06:00
// Email changed
2017-04-18 01:08:57 -06:00
if ( req . user . email !== req . body . email ) {
req . user . newEmail = req . body . email ;
2017-04-18 11:10:43 -06:00
// Create token
2017-04-18 01:08:57 -06:00
req . user . createEmailToken ( ( err , token ) => {
if ( err ) {
mw . throwErr ( err , req ) ;
res . redirect ( req . session . next || '/settings' ) ;
}
// Send token to user by email
mail . send ( {
to : ` " ${ req . user . name } " < ${ req . body . email } > ` ,
from : mail . from ,
subject : 'Confirm your new email address for Tracman' ,
text : mail . text ( ` A request has been made to change your Tracman email address. If you did not initiate this request, please disregard it. \n \n To confirm your email, follow this link: \n ${ env . url } /settings/email/ ${ token } . ` ) ,
html : mail . html ( ` <p>A request has been made to change your Tracman email address. If you did not initiate this request, please disregard it. </p><p>To confirm your email, follow this link:<br><a href=" ${ env . url } /settings/email/ ${ token } "> ${ env . url } /settings/email/ ${ token } </a>. </p> ` )
} )
. then ( ( ) => {
2017-04-18 11:10:43 -06:00
req . flash ( 'warning' , ` An email has been sent to <u> ${ req . body . email } </u>. Check your inbox to confirm your new email address. ` ) ;
2017-04-18 11:03:24 -06:00
setSettings ( ) ;
2017-04-18 01:08:57 -06:00
} )
. catch ( ( err ) => {
mw . throwErr ( err , req ) ;
} ) ;
} ) ;
}
2017-04-18 11:03:24 -06:00
// Email not changed
2017-04-18 11:10:43 -06:00
else { setSettings ( ) ; }
2017-04-17 22:34:53 -06:00
}
2017-04-13 16:53:18 -06:00
} )
2017-04-11 19:38:07 -06:00
// Delete user account
2017-04-13 16:53:18 -06:00
. delete ( ( req , res , next ) => {
2017-04-14 20:10:52 -06:00
//TODO: Reenter password?
User . findByIdAndRemove ( req . user )
2017-04-18 01:08:57 -06:00
. then ( ( ) => {
2017-04-13 16:53:18 -06:00
req . flash ( 'success' , 'Your account has been deleted. ' ) ;
2017-04-12 11:41:27 -06:00
res . redirect ( '/' ) ;
2017-04-14 20:10:52 -06:00
} )
2017-04-18 01:08:57 -06:00
. catch ( ( err ) => {
2017-04-14 20:10:52 -06:00
mw . throwErr ( err , req ) ;
res . redirect ( '/settings' ) ;
} ) ;
2017-04-13 16:53:18 -06:00
} ) ;
2017-04-11 19:38:07 -06:00
2017-04-18 01:08:57 -06:00
// Confirm email address
router . get ( '/email/:token' , mw . ensureAuth , ( req , res , next ) => {
// Check token
if ( req . user . emailToken === req . params . token ) {
// Set new email
req . user . email = req . user . newEmail ;
2017-04-18 11:10:43 -06:00
req . user . save ( )
. then ( ( ) => {
2017-04-18 01:08:57 -06:00
// Delete token and newEmail
req . user . emailToken = undefined ;
req . user . newEmail = undefined ;
req . user . save ( ) ;
// Report success
req . flash ( 'success' , ` Your email has been set to <u> ${ req . user . email } </u>. ` ) ;
res . redirect ( '/settings' ) ;
} )
. catch ( ( err ) => {
mw . throwErr ( err , req ) ;
res . redirect ( req . session . next || '/settings' ) ;
} ) ;
}
// Invalid token
else {
req . flash ( 'danger' , 'Email confirmation token is invalid. ' ) ;
res . redirect ( '/settings' ) ;
}
} ) ;
2017-04-11 19:38:07 -06:00
// Set password
2017-04-14 20:10:52 -06:00
router . route ( '/password' )
2017-04-13 16:53:18 -06:00
. all ( mw . ensureAuth , ( req , res , next ) => {
2017-04-11 19:38:07 -06:00
next ( ) ;
2017-04-13 16:53:18 -06:00
} )
2017-04-12 11:41:27 -06:00
// Email user a token, proceed at /password/:token
2017-04-13 16:53:18 -06:00
. get ( ( req , res , next ) => {
2017-04-12 11:41:27 -06:00
// Create token for password change
2017-04-18 01:08:57 -06:00
req . user . createPassToken ( ( err , token ) => {
if ( err ) {
mw . throwErr ( err , req ) ;
res . redirect ( req . session . next || '/settings' ) ;
}
// 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 \n To change your password, follow this link: \n ${ env . url } /settings/password/ ${ token } . \n \n This request will expire in 1 hour. ` ) ,
html : mail . html ( ` <p>A request has been made to change your tracman password. If you did not initiate this request, please contact support at <a href="mailto:keith@tracman.org">keith@tracman.org</a>. </p><p>To change your password, follow this link:<br><a href=" ${ env . url } /settings/password/ ${ token } "> ${ env . url } /settings/password/ ${ token } </a>. </p><p>This request will expire in 1 hour. </p> ` )
} )
. then ( ( ) => {
// Alert user to check email.
req . flash ( 'success' , ` An email has been sent to <u> ${ req . user . email } </u>. Check your inbox to complete your password change. ` ) ;
res . redirect ( '/login#login' ) ;
2017-04-14 20:10:52 -06:00
} )
. catch ( ( err ) => {
2017-04-12 11:41:27 -06:00
mw . throwErr ( err , req ) ;
2017-04-18 01:08:57 -06:00
res . redirect ( '/login#login' ) ;
2017-04-12 11:41:27 -06:00
} ) ;
2017-04-18 01:08:57 -06:00
} ) ;
2017-04-13 16:53:18 -06:00
} ) ;
2017-04-12 11:41:27 -06:00
router . route ( '/password/:token' )
2017-04-13 16:53:18 -06:00
2017-04-12 11:41:27 -06:00
// Check token
2017-04-13 16:53:18 -06:00
. all ( ( req , res , next ) => {
2017-04-12 11:41:27 -06:00
User
. findOne ( { 'auth.passToken' : req . params . token } )
2017-04-18 01:08:57 -06:00
. where ( 'auth.passTokenExpires' ) . gt ( Date . now ( ) )
2017-04-13 16:59:46 -06:00
. then ( ( user ) => {
2017-04-12 11:41:27 -06:00
if ( ! user ) {
req . flash ( 'danger' , 'Password reset token is invalid or has expired. ' ) ;
res . redirect ( ( req . isAuthenticated ) ? '/settings' : '/login' ) ;
} else {
res . locals . passwordUser = user ;
next ( ) ;
}
2017-04-14 20:10:52 -06:00
} )
. catch ( ( err ) => {
mw . throwErr ( err , req ) ;
res . redirect ( '/password' ) ;
2017-04-12 11:41:27 -06:00
} ) ;
2017-04-13 16:53:18 -06:00
} )
2017-04-12 11:41:27 -06:00
// Show password change form
2017-04-13 16:53:18 -06:00
. get ( ( req , res ) => {
2017-04-12 11:41:27 -06:00
res . render ( 'password' ) ;
2017-04-13 16:53:18 -06:00
} )
2017-04-15 08:22:13 -06:00
// Set new password
2017-04-13 16:53:18 -06:00
. post ( ( req , res , next ) => {
2017-04-14 20:10:52 -06:00
2017-04-15 08:22:13 -06:00
// Validate password
let daysToCrack = mellt . CheckPassword ( req . body . password ) ;
if ( daysToCrack < 10 ) {
mw . throwErr ( new Error ( ` That password could be cracked in ${ daysToCrack } days! Come up with a more complex password that would take at least 10 days to crack. ` ) ) ;
res . redirect ( ` /settings/password/ ${ req . params . token } ` ) ;
2017-04-16 15:23:15 -06:00
}
else {
2017-04-15 08:22:13 -06:00
// Delete token
res . locals . passwordUser . auth . passToken = undefined ;
2017-04-18 01:08:57 -06:00
res . locals . passwordUser . auth . passTokenExpires = undefined ;
2017-04-15 08:22:13 -06:00
// Create hash
res . locals . passwordUser . generateHash ( req . body . password , ( err , hash ) => {
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' ) ;
} ) ;
}
} ) ;
}
2017-04-14 20:10:52 -06:00
2017-04-13 16:53:18 -06:00
} ) ;
2017-04-11 19:38:07 -06:00
// Tracman pro
2017-04-12 11:41:27 -06:00
router . route ( '/pro' )
2017-04-13 16:53:18 -06:00
. all ( mw . ensureAuth , ( req , res , next ) => {
2017-04-11 19:38:07 -06:00
next ( ) ;
2017-04-13 16:53:18 -06:00
} )
2017-04-11 19:38:07 -06:00
// Get info about pro
2017-04-13 16:53:18 -06:00
. get ( ( req , res , next ) => {
2017-04-12 11:41:27 -06:00
res . render ( 'pro' ) ;
2017-04-13 16:53:18 -06:00
} )
2017-04-11 19:38:07 -06:00
// Join Tracman pro
2017-04-13 16:53:18 -06:00
. post ( ( req , res ) => {
2017-04-12 11:41:27 -06:00
User . findByIdAndUpdate ( req . user . id ,
2017-04-14 20:10:52 -06:00
{ $set : { isPro : true } } )
. then ( ( user ) => {
req . flash ( 'success' , 'You have been signed up for pro. ' ) ;
2017-04-11 19:38:07 -06:00
res . redirect ( '/map' ) ;
2017-04-14 20:10:52 -06:00
} )
. catch ( ( err ) => {
mw . throwErr ( err , req ) ;
res . redirect ( '/pro' ) ;
} ) ;
2017-04-13 16:53:18 -06:00
} ) ;
2017-04-17 22:34:53 -06:00
module . exports = router ;