import { NextFunction, Request, Response, Router } from 'express' import passport from 'passport' import { Strategy as LocalStrategy } from 'passport-local' import validator from 'validator' import { config } from '../../../config' import { errors } from '../../../errors' import { logger } from '../../../logger' import { User } from '../../../models' import { urlencodedParser } from '../../utils' import { AuthMiddleware } from '../interface' const emailAuth = Router() export const EmailMiddleware: AuthMiddleware = { getMiddleware (): Router { passport.use(new LocalStrategy({ usernameField: 'email' }, function (email: string, password: string, done) { if (!validator.isEmail(email)) return done(null, false) User.findOne({ where: { email: email } }).then(function (user: User) { if (!user) return done(null, false) user.verifyPassword(password).then(verified => { if (verified) { return done(null, user) } else { logger.warn('invalid password given for %s', user.email) return done(null, false) } }) }).catch(function (err: Error) { logger.error(err) return done(err) }) })) if (config.allowEmailRegister) { emailAuth.post('/register', urlencodedParser, function (req: Request, res: Response, _: NextFunction) { if (!req.body.email || !req.body.password) { errors.errorBadRequest(res) return } if (!validator.isEmail(req.body.email)) { errors.errorBadRequest(res) return } User.findOrCreate({ where: { email: req.body.email }, defaults: { password: req.body.password } }).then(function ([user, created]: [User, boolean]) { if (user) { if (created) { logger.debug('user registered: ' + user.id) req.flash('info', "You've successfully registered, please signin.") return res.redirect(config.serverURL + '/') } else { logger.debug('user found: ' + user.id) req.flash('error', 'This email has been used, please try another one.') return res.redirect(config.serverURL + '/') } } req.flash('error', 'Failed to register your account, please try again.') return res.redirect(config.serverURL + '/') }).catch(function (err) { logger.error('auth callback failed: ' + err) errors.errorInternalError(res) }) }) } emailAuth.post('/login', urlencodedParser, function (req: Request, res: Response, next: NextFunction) { if (!req.body.email || !req.body.password) { errors.errorBadRequest(res) return } if (!validator.isEmail(req.body.email)) { errors.errorBadRequest(res) return } passport.authenticate('local', { successReturnToOrRedirect: config.serverURL + '/', failureRedirect: config.serverURL + '/', failureFlash: 'Invalid email or password.' })(req, res, next) }) return emailAuth } }