let passport = require('passport') let LocalStrategy = require('passport-local').Strategy let crypto = require('crypto') // let fs = require('fs') let db = require('../db') export function route(app, serve_index){ passport.serializeUser(serializeUser) passport.deserializeUser(deserializeUser) passport.use(new LocalStrategy(verifyLocalUser)) app.get("/login", serve_index) app.get("/signup", serve_index) app.get("/logout", logout) app.put("/api/signup", checkIfUserExists, createUser, passport.authenticate("local"), login) app.put("/api/login", passport.authenticate("local"), login) app.put("/api/checkin", ensureAuthenticated, checkin ) } export function ensureAuthenticated(req, res, next) { if (!req.isAuthenticated()) { req.session.returnTo = req.path return res.redirect('/login') } next() } export function checkIfUserExists(req, res, next) { db.getUserByUsername(sanitizeName(req.body.username)).then((user) => { user ? res.json({ error: "user exists" }) : next() }) } export function sanitizeName(s) { return (s || "").replace(new RegExp("[^-_a-zA-Z0-9]", 'g'), "") } export function sanitizeUser(req_user) { // sanitize user object var user = JSON.parse(JSON.stringify(req_user)) delete user.password return user } export function createUser(req, res, next) { if (req.body.password !== req.body.password2) { return res.json({ error: "passwords don't match" }) } let data = { username: sanitizeName(req.body.username), realname: sanitize(req.body.realname), password: makePassword(username, req.body.password), firstseen: new Date(), lastseen: new Date(), // lastsession: util.now(), } db.createUser(data).then(() => next()) } export function login(req, res) { if (req.isAuthenticated()) { let returnTo = req.session.returnTo delete req.session.returnTo console.log(">> logged in", req.user.get('username')) return res.json({ status: "OK", user: sanitizeUser(req.user), returnTo: returnTo || "/index", }) } res.json({ error: 'bad credentials', }) } export function serializeUser(user, done) { done(null, user.id) } export function deserializeUser(id, done) { db.getUser(id).then(function(user){ done(! user, user) }) } export function makePassword(password) { let shasum = crypto.createHash('sha1') shasum.update(password) return shasum.digest('hex') } export function validPassword(user, password) { return user.get('password') === makePassword(password) } export function changePassword(req, res, next) { if (! req.body.oldpassword && ! req.body.newpassword) return next() if (req.body.newpassword !== req.body.newpassword2) { return res.send({ error: 'Passwords don\'t match.' }) } if (! validPassword(res.user, req.body.oldpassword)) { return res.send({ error: 'Password is incorrect.' }) } let username = req.user.get('username') let newPassword = makePassword(username, req.body.newpassword) res.user.set('password', newPassword) res.user.save().then(() => next()).catch(err => res.send({ error: err })) } export function changePasswordDangerously(req, res, next) { if (! req.body.password && ! req.body.newpassword) return next() if (req.body.newpassword !== req.body.newpassword2) { return res.send({ error: 'Passwords don\'t match.' }) } if (! validPassword(req.user, req.body.password)) { return res.send({ error: 'Password is incorrect.' }) } let username = res.user.get('username') let newPassword = makePassword(username, req.body.newpassword) res.user.set('password', newPassword) res.user.save().then(() => next()).catch(err => res.send({ error: err })) } export function verifyLocalUser(username, password, done) { // handle passwords!! db.getUserByUsername(username).then(function(user){ // if (err) { return done(err) } if (! user) { return done("no user") } // return done(null, user) if (! user || ! validPassword(user, password)) { return done(null, false, { error: { message: 'Bad username/password.' } }) } return done(null, user) }) } export function checkin(req, res) { res.json({ user: sanitizeUser(req.user) }) } export const logout = (req, res) => { req.logout() res.redirect('/') }