All files / src/utils security.utils.ts

100% Statements 21/21
100% Branches 8/8
100% Functions 3/3
100% Lines 21/21

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 759x         9x 9x 9x     9x     9x         9x     9x                         32x 32x   3x   29x                       13x 13x 2x 2x 1x       13x 1x           12x 3x              
import {
  HttpError,
  HttpStatus,
  MicroserviceRequest
} from "@waytrade/microservice-core";
import Cookie from "cookie";
import crypto from "crypto";
import jwt from "jsonwebtoken";
 
/** Secret used signing JWT tokens. */
const JWT_SECRET = crypto.randomBytes(64).toString("hex");
 
/** Lifetime of a JWT Bearer token in seconds. */
const JWT_TOKEN_LIFETIME = 60 * 60 * 48; // 48h
 
/**
 * Collection of security-related helper functions.
 */
export class SecurityUtils {
  /** Create a JWT token. */
  static createJWT(): string {
    return jwt.sign(
      {
        exp: Math.floor(Date.now() / 1000) + JWT_TOKEN_LIFETIME,
      },
      JWT_SECRET,
    );
  }
 
  /*
   * Verify that authorization headers contains a valid JWT token, signed
   * by this service instance.
   */
  static vefiyBearer(token: string): boolean {
    try {
      jwt.verify(token.substr("Bearer ".length), JWT_SECRET);
    } catch (e) {
      return false;
    }
    return true;
  }
 
  /**
   * Verify that authorization headers contains a valid JWT token, signed
   * by this service instance.
   *
   * @throws a HttpError if failed.
   */
  static ensureAuthorization(request: MicroserviceRequest): void {
    // get the bearer token from request headers
 
    let bearerToken = request.headers.get("authorization");
    if (!bearerToken) {
      const cookie = request.headers.get("cookie");
      if (cookie) {
        bearerToken = Cookie.parse(cookie).authorization;
      }
    }
 
    if (!bearerToken) {
      throw new HttpError(
        HttpStatus.UNAUTHORIZED,
        "Missing authorization header",
      );
    }
 
    if (!this.vefiyBearer(bearerToken)) {
      throw new HttpError(
        HttpStatus.UNAUTHORIZED,
        "Invalid bearer token",
      );
    }
  }
}