var _ = require('lodash'); var async = require('async'); var crypto = require('crypto'); var nodemailer = require('nodemailer'); var passport = require('passport'); var User = require('../models/user'); var secure = require('../config/secure'); /********** GET / Login **************/ exports.getLogin = function (req, res) { if (req.user) { return res.redirect('/'); } res.render('account/login', { title: 'Login' }); }; /********** User GET / User URL **************/ exports.getUserURL = function (req, res) { if (req.params.username) { User.find({ username: req.params.username }, function (err, username) { console.log('%s', User.username); console.log(req.originalUrl); console.log(req.baseUrl); console.log(req.path); if (!username) { res.render('404', { url: req.url, error: '404 Not found' }); return; } var username = req.params.username; res.render('account/user', { title: username.User, url: username.User }); }); }; }; /********** POST / Login **************/ exports.postLogin = function(req, res, next) { req.assert('email', 'Email is not valid').isEmail(); req.assert('password', 'Password cannot be blank').notEmpty(); var errors = req.validationErrors(); if (errors) { req.flash('errors', errors); return res.redirect('/login'); } passport.authenticate('local', function(err, user, info) { if (err) { return next(err); } if (!user) { req.flash('errors', { msg: info.message }); return res.redirect('/login'); } req.logIn(user, function(err) { if (err) { return next(err); } req.flash('success', { msg: 'Success! You are logged in.' }); res.redirect(req.session.returnTo || '/'); }); })(req, res, next); }; /********** GET / Logout **************/ exports.logout = function(req, res) { req.logout(); res.redirect('/'); }; /********** GET / Register **************/ exports.getSignup = function(req, res) { if (req.user) { return res.redirect('/'); } res.render('account/register', { title: 'Register' }); }; /********** POST / Register **************/ exports.postSignup = function(req, res, next) { req.assert('email', 'Email is not valid').isEmail(); req.assert('password', 'Password must be at least 6 characters long').len(6); req.assert('confirmPassword', 'Passwords do not match').equals(req.body.password); var errors = req.validationErrors(); if (errors) { req.flash('errors', errors); return res.redirect('/register'); } var user = new User({ email: req.body.email, password: req.body.password }); User.findOne({ email: req.body.email }, function(err, existingUser) { if (existingUser) { req.flash('errors', { msg: 'Account with that email address already exists.' }); return res.redirect('/register'); } user.save(function(err) { if (err) { return next(err); } req.logIn(user, function(err) { if (err) { return next(err); } res.redirect('/'); }); }); }); }; /********** GET / Account **************/ exports.getAccount = function(req, res) { res.render('account/profile', { title: 'Account Management' }); }; /********** POST / Account **************/ exports.postUpdateProfile = function(req, res, next) { User.findById(req.user.id, function(err, user) { if (err) { return next(err); } user.email = req.body.email || ''; user.profile.name = req.body.name || ''; user.profile.username = req.body.username || ''; user.profile.gender = req.body.gender || ''; user.profile.location = req.body.location || ''; user.profile.website = req.body.website || ''; user.profile.bio = req.body.bio || ''; user.save(function(err) { if (err) { return next(err); } req.flash('success', { msg: 'Profile information updated.' }); res.redirect('/account'); }); }); }; /********** POST / Account / Password **************/ exports.postUpdatePassword = function(req, res, next) { req.assert('password', 'Password must be at least 4 characters long').len(4); req.assert('confirmPassword', 'Passwords do not match').equals(req.body.password); var errors = req.validationErrors(); if (errors) { req.flash('errors', errors); return res.redirect('/account'); } User.findById(req.user.id, function(err, user) { if (err) { return next(err); } user.password = req.body.password; user.save(function(err) { if (err) { return next(err); } req.flash('success', { msg: 'Password has been changed.' }); res.redirect('/account'); }); }); }; /********** POST / Account / Delete **************/ exports.postDeleteAccount = function(req, res, next) { User.remove({ _id: req.user.id }, function(err) { if (err) { return next(err); } req.logout(); req.flash('info', { msg: 'Your account has been deleted.' }); res.redirect('/'); }); }; /********** POST / Account / Oauth **************/ exports.getOauthUnlink = function(req, res, next) { var provider = req.params.provider; User.findById(req.user.id, function(err, user) { if (err) { return next(err); } user[provider] = undefined; user.tokens = _.reject(user.tokens, function(token) { return token.kind === provider; }); user.save(function(err) { if (err) return next(err); req.flash('info', { msg: provider + ' account has been unlinked.' }); res.redirect('/account'); }); }); }; /********** GET / Password / :Token **************/ exports.getReset = function(req, res) { if (req.isAuthenticated()) { return res.redirect('/'); } User .findOne({ resetPasswordToken: req.params.token }) .where('resetPasswordExpires').gt(Date.now()) .exec(function(err, user) { if (err) { return next(err); } if (!user) { req.flash('errors', { msg: 'Password reset token is invalid or has expired.' }); return res.redirect('/forgot'); } res.render('account/reset', { title: 'Password Reset' }); }); }; /********** POST / Password / :Token **************/ exports.postReset = function(req, res, next) { req.assert('password', 'Password must be at least 4 characters long.').len(4); req.assert('confirm', 'Passwords must match.').equals(req.body.password); var errors = req.validationErrors(); if (errors) { req.flash('errors', errors); return res.redirect('back'); } async.waterfall([ function(done) { User .findOne({ resetPasswordToken: req.params.token }) .where('resetPasswordExpires').gt(Date.now()) .exec(function(err, user) { if (err) { return next(err); } if (!user) { req.flash('errors', { msg: 'Password reset token is invalid or has expired.' }); return res.redirect('back'); } user.password = req.body.password; user.resetPasswordToken = undefined; user.resetPasswordExpires = undefined; user.save(function(err) { if (err) { return next(err); } req.logIn(user, function(err) { done(err, user); }); }); }); }, function(user, done) { var transporter = nodemailer.createTransport({ service: 'Mandrill', auth: { user: secrets.mandrill.user, pass: secrets.mandrill.password } }); var mailOptions = { to: user.email, from: 'admin@juryd.com', subject: 'Your Juryd password has been changed', text: 'Hello,\n\n' + 'This is a confirmation that the password for your account ' + user.email + ' has just been changed.\n' }; transporter.sendMail(mailOptions, function(err) { req.flash('success', { msg: 'Success! Your password has been changed.' }); done(err); }); } ], function(err) { if (err) { return next(err); } res.redirect('/'); }); }; /********** GET / Password / Forgot **************/ exports.getForgot = function(req, res) { if (req.isAuthenticated()) { return res.redirect('/'); } res.render('account/forgot', { title: 'Forgot Password' }); }; /********** Post / Password / Forgot / Email **************/ exports.postForgot = function(req, res, next) { req.assert('email', 'Please enter a valid email address.').isEmail(); var errors = req.validationErrors(); if (errors) { req.flash('errors', errors); return res.redirect('/forgot'); } async.waterfall([ function(done) { crypto.randomBytes(16, function(err, buf) { var token = buf.toString('hex'); done(err, token); }); }, function(token, done) { User.findOne({ email: req.body.email.toLowerCase() }, function(err, user) { if (!user) { req.flash('errors', { msg: 'No account with that email address exists.' }); return res.redirect('/forgot'); } user.resetPasswordToken = token; user.resetPasswordExpires = Date.now() + 3600000; // 1 hour user.save(function(err) { done(err, token, user); }); }); }, function(token, user, done) { var transporter = nodemailer.createTransport({ service: 'Mandrill', auth: { user: secrets.mandrill.user, pass: secrets.mandrill.password } }); var mailOptions = { to: user.email, from: 'admin@juryd.com', subject: 'Juryd - Reset your password', text: 'You are receiving this email because you (or someone else) have requested the reset of the password for your account.\n\n' + 'Please click on the following link, or paste this into your browser to complete the process:\n\n' + 'http://' + req.headers.host + '/reset/' + token + '\n\n' + 'If you did not request this, please ignore this email and your password will remain unchanged.\n' }; transporter.sendMail(mailOptions, function(err) { req.flash('info', { msg: 'An e-mail has been sent to ' + user.email + ' with further instructions.' }); done(err, 'done'); }); } ], function(err) { if (err) { return next(err); } res.redirect('/forgot'); }); };