All files / lib/security security.ts

47.05% Statements 8/17
0% Branches 0/6
66.66% Functions 2/3
43.75% Lines 7/16

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 611x   1x 1x                                       1x                                                                 1x 2x 2x    
import 'reflect-metadata';
import { IncomingMessage } from 'http';
import { InvalidCredentialsError } from '../errors/errors';
import jwt from 'jsonwebtoken';
 
/**
 * @interface Security
 * @description An interface for security implementations.
 */
export interface Security {
  /**
   * @method authenticate
   * @description Authenticates a request.
   * @param {IncomingMessage} req - The request object.
   */
  authenticate(req: IncomingMessage): void;
}
 
/**
 * @class JWTSecurity
 * @description A security implementation that uses JWT tokens.
 * @implements Security
 */
export class JWTSecurity implements Security {
  /**
   * @method authenticate
   * @description Authenticates a request using a JWT token.
   * @param {IncomingMessage} req - The request object.
   */
  public authenticate(req: IncomingMessage): void {
    const authHeader = req.headers.authorization;
 
    if (!authHeader) {
      throw new InvalidCredentialsError();
    }
 
    const token = authHeader.split(' ')[1];
 
    if (!token) {
      throw new InvalidCredentialsError();
    }
 
    try {
      jwt.verify(token, process.env.JWT_SECRET || 'default-secret');
    } catch (error) {
      throw new InvalidCredentialsError();
    }
  }
}
 
/**
 * @decorator Security
 * @description A method decorator that applies a security implementation to a route.
 * @param {new () => Security} security - The security implementation to use.
 * @returns {MethodDecorator}
 */
export const Security = (security: new () => Security): MethodDecorator => {
  return (target, propertyKey, descriptor) => {
    Reflect.defineMetadata('security', security, target.constructor, propertyKey as string);
  };
};