All files / src/middleware auth.ts

93.93% Statements 31/33
84.61% Branches 11/13
100% Functions 5/5
93.93% Lines 31/33

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73                7x 70x 70x     7x 70x   70x 7x 7x     63x 63x 63x         63x 59x   59x 2x 2x     57x 57x     4x 1x   3x             7x 63x     7x   7x 107x 6x     101x       7x 1x     7x      
import {Response, NextFunction} from 'express';
import jwt from 'jsonwebtoken';
import {config} from '../config/config';
import { CustomRequest } from 'types/customRequest';
import {unless} from 'express-unless';
import * as usersService from '../services/users_service';
 
 
const getTokenFromHeader = (req: CustomRequest): string | undefined => {
  const authHeader= (req.headers['authorization'] as string | undefined) ?? (req.headers['Authorization'] as string | undefined);
  return authHeader?.split(' ')[1];
}
 
const authenticateTokenHandler: any & { unless: typeof unless } = async (req: CustomRequest, res: Response, next: NextFunction, ignoreExpiration = false): Promise<void> => {
  const token = getTokenFromHeader(req);
 
  if (!token) {
    res.status(401).json({ message: 'Access token required' });
    return;
  }
 
  try {
    const isBlacklisted = await usersService.isAccessTokenBlacklisted(token);
    Iif (isBlacklisted) {
      res.status(403).json({ message: 'Token is blacklisted' });
      return;
    }
 
    const decoded = jwt.verify(token, config.token.access_token_secret(), { ignoreExpiration }) as jwt.JwtPayload;
    const user = await usersService.getUserById(decoded.userId);
 
    if (!user) {
      res.status(403).json({ message: 'Invalid token' });
      return;
    }
 
    req.user = user;
    next();
 
  } catch (err: any) {
    if (err.name === 'TokenExpiredError') {
      res.status(401).json({ message: 'Token expired' });
    } else {
      res.status(403).json({ message: 'Invalid token' });
    }
  }
};
 
 
// Middleware to authenticate token for all requests
const authenticateToken: any & { unless: typeof unless } = async (req: CustomRequest, res: Response, next: NextFunction): Promise<void> => {
  authenticateTokenHandler(req, res, next, false)
}
 
authenticateToken.unless = unless;
 
const authenticateTokenForParams: any & { unless: typeof unless } = async (req: CustomRequest, res: Response, next: NextFunction): Promise<void> => {
  if (Object.keys(req.query).length > 0) {
    authenticateTokenHandler(req, res, next, false)
  }
  else {
    next();
  }
}
 
const authenticateLogoutToken = async (req: CustomRequest, res: Response, next: NextFunction) => {
    authenticateTokenHandler(req, res, next, true)
}
 
authenticateLogoutToken.unless = unless;
 
export {authenticateToken, authenticateLogoutToken, authenticateTokenForParams};