All files / src/middleware auth.ts

94.59% Statements 35/37
86.66% Branches 13/15
100% Functions 6/6
94.59% Lines 35/37

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 74 75 76 77 78 79 80 81                7x 70x 70x     7x 7x     7x 70x 70x   7x     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 getTokenFromQueryParams = (req: CustomRequest): string | undefined => {
  return req.query.accessToken as string;
}
 
const authenticateTokenHandler: any & { unless: typeof unless } = async (req: CustomRequest, res: Response, next: NextFunction, ignoreExpiration = false): Promise<void> => {
  let token = getTokenFromHeader(req);
  if (!token) {
    // If the token was not found in the headers, fall back to the query params.
    token = getTokenFromQueryParams(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};