var passport = require("passport"); var LocalStrategy = require("passport-local").Strategy; var useragent = require("express-useragent"); var crypto = require("crypto"); var crypt = require("unix-crypt-td-js"); var fs = require("fs"); var db = require("../db"); var util = require("./util"); var upload = require("./upload"); var middleware = require("./middleware"); var auth = (module.exports = { init: function () { passport.serializeUser(auth.serializeUser); passport.deserializeUser(auth.deserializeUser); passport.use(new LocalStrategy(auth.verifyLocalUser)); }, route: function (app) { app.get("/login", function (req, res) { res.render("pages/login", { title: "login", }); }); app.get("/signup", function (req, res) { res.render("pages/signup", { title: "signup", }); }); app.get("/logout", auth.logout); app.put( "/api/signup", auth.checkIfUserExists, auth.createUser, passport.authenticate("local"), auth.createMailboxes, auth.uploadDefaultAvatar, auth.login ); app.put("/api/login", passport.authenticate("local"), auth.login); app.put("/api/checkin", middleware.ensureAuthenticated, auth.checkin); }, checkIfUserExists: function (req, res, next) { var username = util.sanitizeName(req.body.username); db.getUserByUsername(username) .then((user) => { if (user) { console.log(user); return res.json({ error: "user exists" }); } next(); }) .catch((error) => { if (error.message === "EmptyResponse") { return next(); } next(error); }); }, createUser: function (req, res, next) { if (req.body.password !== req.body.password2) { return res.json({ error: "passwords don't match" }); } var username = util.sanitizeName(req.body.username); var data = { username: username, realname: util.sanitize(req.body.realname), password: auth.makePassword(username, req.body.password), grass: util.sanitizeName(req.body.grass), firstseen: util.now(), lastseen: util.now(), // lastsession: util.now(), }; db.createUser(data).then(() => next()); }, createMailboxes: function (req, res, next) { var username = req.user.get("username"); Promise.all([ db.createMailbox({ mbox: username + ".inbox", owner: username, editable: 0, }), db.createMailbox({ mbox: username + ".outbox", owner: username, editable: 0, }), db.createMailbox({ mbox: username + ".drafts", owner: username, editable: 1, }), ]).then(() => next()); }, uploadDefaultAvatar: function (req, res, next) { fs.readFile("public/assets/img/profile.jpg", (err, buf) => { if (err) throw err; var username = req.user.get("username"); upload.put({ file: { buffer: buf, size: buf.length, mimetype: "image/jpeg", }, dirname: "/bucky/profile/", filename: username + ".jpg", preserveFilename: true, success: (url) => { next(); }, }); }); }, login: function (req, res) { if (req.isAuthenticated()) { // let ua = useragent.parse(req.headers["user-agent"]); let { returnTo } = req.session; if ( !returnTo || returnTo.startsWith("/login") || returnTo.startsWith("/index") ) { // returnTo = ua.isMobile ? "/stream" : "/index"; returnTo = "/stream"; } delete req.session.returnTo; console.log(">> logged in", req.user.get("username")); return res.json({ status: "OK", user: util.sanitizeUser(req.user), returnTo, }); } res.json({ error: "bad credentials", }); }, serializeUser: function (user, done) { done(null, user.id); }, deserializeUser: function (id, done) { db.getUser(id).then(function (user) { done(!user, user); }); }, makePassword: function (username, password) { var salt = username.substr(0, 2); // lol return crypt(password, salt); // var shasum = crypto.createHash('sha1') // shasum.update(password) // return shasum.digest('hex'); }, validPassword: function (user, password) { return ( user.get("password") === auth.makePassword(user.get("username"), password) ); }, changePassword: function (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 (!auth.validPassword(res.user, req.body.oldpassword)) { return res.send({ error: "Password is incorrect." }); } var username = req.user.get("username"); var newPassword = auth.makePassword(username, req.body.newpassword); res.user.set("password", newPassword); res.user .save() .then(() => next()) .catch((err) => res.send({ error: err })); }, changePasswordDangerously: function (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 (!auth.validPassword(req.user, req.body.password)) { return res.send({ error: "Password is incorrect." }); } var username = res.user.get("username"); var newPassword = auth.makePassword(username, req.body.newpassword); res.user.set("password", newPassword); res.user .save() .then(() => next()) .catch((err) => res.send({ error: err })); }, verifyLocalUser: function (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 || !auth.validPassword(user, password)) { return done(null, false, { error: { message: "Bad username/password." }, }); } return done(null, user); }); }, checkin: function (req, res) { var user = util.sanitizeUser(req.user); res.json({ user: user }); }, logout: function (req, res) { req.logout(); res.redirect("/"); }, });