import { RequestHandler } from "express"; import { verify } from "jsonwebtoken"; import createError from "http-errors"; import { User } from "../entities/User"; import { createTokens } from "./createTokens"; export const isAuth: (st?: boolean) => RequestHandler<{}, any, any, {}> = ( shouldThrow = true ) => async (req, res, next) => { const accessToken = req.headers["access-token"]; if (!accessToken || typeof accessToken !== "string") { return next( !shouldThrow ? undefined : createError(401, "not authenticated") ); } try { const data = verify(accessToken, process.env.ACCESS_TOKEN_SECRET) as any; (req as any).userId = data.userId; return next(); } catch {} const refreshToken = req.headers["refresh-token"]; if (!refreshToken || typeof refreshToken !== "string") { return next( !shouldThrow ? undefined : createError(401, "not authenticated") ); } let data; try { data = verify(refreshToken, process.env.REFRESH_TOKEN_SECRET) as any; } catch { return next( !shouldThrow ? undefined : createError(401, "not authenticated") ); } const user = await User.findOne(data.userId); // token has been invalidated or user deleted if (!user || user.tokenVersion !== data.tokenVersion) { return next( !shouldThrow ? undefined : createError(401, "not authenticated") ); } const tokens = createTokens(user); res.setHeader("refresh-token", tokens.refreshToken); res.setHeader("access-token", tokens.accessToken); (req as any).userId = data.userId; next(); };