import crypto = require('crypto'); import jwt = require('jsonwebtoken'); export interface AuthMiddlewareConfig { serialize(user): any; deserialize(user): any; } export function authMiddleware(config: AuthMiddlewareConfig) { return function authMiddleware(req, res, next) { req.login = async function login(user) { const serial = await config.serialize(user); req.session.authToken = jwt.sign({ serial }, process.env.auth_secret, { expiresIn: '5m' }); req.session.refreshToken = jwt.sign({ serial }, process.env.auth_secret, { expiresIn: '24m' }); req.user = user; } req.logout = function logout() { delete req.session.authToken; delete req.session.refreshToken; delete req.user; } // Check if refresh token is valid if (req.session.refreshToken) { let refreshToken; try { refreshToken = jwt.verify(req.session.refreshToken, process.env.auth_secret); } catch (e) { // Refresh token is invalid, log out return req.logout().then(() => next()); } // Refresh token is valid, check if auth token is valid try { jwt.verify(req.session.authToken, process.env.auth_secret); } catch (e) { // Auth token expired, regenerate const data = jwt.sign({ serial: refreshToken.serial }, process.env.auth_secret); req.session.authToken = data; } // Auth token is valid return config.deserialize(refreshToken.serial).then(user => { if (!user) { req.logout(); return next(); } req.user = user; next(); }).catch(err => { req.logout(); console.log(err); next(); }); } next(); } }