import passport from 'passport' import { Strategy as LocalStrategy } from 'passport-local' import crypto from 'crypto' import db from '../db' const { user: userModel } = db.models export function route(app, serve_index){ app.use(passport.initialize()) app.use(passport.session()) 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, login) app.put("/api/login", passport.authenticate("local"), login) app.put("/api/checkin", ensureAPIAuthenticated, checkin) } export function ensureAuthenticated(req, res, next) { if (!req.isAuthenticated()) { if (req.session) req.session.returnTo = req.path return res.redirect('/login') } next() } export function ensureAPIAuthenticated(req, res, next) { if (!req.isAuthenticated()) { return res.send(500) } next() } export function getUserByUsername(username) { return userModel.show(sanitizeName(username), 'username') } export function checkIfUserExists(req, res, next) { getUserByUsername(req.body.username) .then((user) => { console.log('gotta user?', !!user); user ? res.json({ error: "user exists" }) : next() }).catch(err => { console.error('error', err) }) } export function sanitizeName(s) { return (s || "").replace(new RegExp('[^-_a-zA-Z0-9]', 'g'), "") } export function sanitizeUser(req_user) { // sanitize user object let user = JSON.parse(JSON.stringify(req_user)) try { user.profile = JSON.parse(user.profile) } catch (e) { console.error('error decoding profile') user.profile = {} } delete user.password return user } export function createUser(req, res, next) { const { username, password, password2 } = req.body if (password !== password2) { return res.json({ error: "passwords don't match" }) } let data = { username: sanitizeName(username), realname: sanitizeName(username), password: makePassword(password), lastseen: new Date(), level: 0, profile: {}, } userModel.create(data) .then(user => { console.log('created userrrrr', user) req.login(user, err => { console.log(err) err ? next(err) : next() }) }) .catch(err => { res.json({ error }) }) } export function login(req, res) { console.log(req.user) if (req.isAuthenticated()) { let returnTo = req.session.returnTo delete req.session.returnTo console.log(">> logged in", req.user.username) return res.json({ status: "OK", user: sanitizeUser(req.user), returnTo: returnTo || "/", }) } res.json({ error: 'bad credentials', }) } export function serializeUser(user, done) { done(null, user.id) } export function deserializeUser(id, done) { userModel.show(id).then(user => { done(!user, user) }).catch(done) } export function makePassword(password) { let shasum = crypto.createHash('sha1') shasum.update(password) return shasum.digest('hex') } export function validPassword(user, password) { return user.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.username let newPassword = makePassword(req.body.newpassword) res.user.password = newPassword res.user.save() .then(next) .catch(err => res.send({ error: err })) } export function verifyLocalUser(username, password, done) { // handle passwords!! getUserByUsername(username) .then(user => { console.log(user) // if (err) { return done(err) } if (! user) { return done("no user") } if (! user || !validPassword(user, password)) { return done(null, false, { error: { message: 'Bad username/password.' } }) } return done(null, user) }) } export function checkin(req, res) { console.log(req.user) res.json({ user: sanitizeUser(req.user) }) } export const logout = (req, res) => { req.logout() res.redirect('/') }