rimiti/keldoc-js-sdk

View on GitHub
src/classes/common.js

Summary

Maintainability
C
1 day
Test Coverage
// @flow
import axios from 'axios';
import * as crypto from 'crypto-js';
import momentTimezone from 'moment-timezone';
import Validation from './validation';
import type {Config} from './types';
import {
  BadRequest,
  Unauthorized,
  OverQuota,
  NotFound,
  NotAcceptable,
  ValidationError,
  InternalError,
  UnknownError,
} from './exceptions';

export default class Common {
  validator: Validation;

  configuration: Config;

  headerContentType: string;

  headerDate: string;

  constructor(configuration: Config) {
    this.validator = new Validation();
    this.headerContentType = 'application/json';
    this.headerDate = '';
    this.configuration = configuration;
  }

  /**
   * @description Generate a token for each requests.
   * @returns {void}
   */
  generateHeader() {
    axios.defaults.headers = {
      Authorization: this.generateToken(this.configuration.credentials),
      Accept: 'application/vnd.keldoc-v1+json',
      'Content-Type': this.headerContentType,
      Date: this.headerDate,
    };
  }

  /**
   * @description Generate token from credentials.
   * @param credentials
   * @returns {string}
   */
  generateToken(credentials: {clientAccessKeyId: string, secretAccessKeyId: string}): string {
    this.headerDate = momentTimezone().tz('Europe/Paris').format();
    const message = `${this.headerDate},${this.headerContentType}`;
    const signature = crypto.enc.Base64.stringify(crypto.HmacSHA256(message, credentials.secretAccessKeyId));
    return `Bearer ${credentials.clientAccessKeyId}:${signature}`.replace(/[^A-Za-z0-9=:\s]/g, '');
  }

  /**
   * @description Runs GET request.
   * @param url
   * @param params
   * @return {Promise}
   */
  getRequest(url: string, params: any): Promise<any> {
    return new Promise((resolve, reject) => {
      this.generateHeader();
      axios.get(this.configuration.host + url, {params})
        .then((response: {}) => resolve(response))
        .catch((error) => reject(Common.httpStatus(error.response)));
    });
  }

  /**
   * @description Runs POST request.
   * @param url
   * @param body
   * @return {Promise}
   */
  postRequest(url: string, body: any): Promise<any> {
    return new Promise((resolve, reject) => {
      this.generateHeader();
      axios.post(this.configuration.host + url, body)
        .then((response: {}) => resolve(response))
        .catch((error) => reject(Common.httpStatus(error.response)));
    });
  }

  /**
   * @description Runs PUT request.
   * @param url
   * @param body
   * @return {Promise}
   */
  putRequest(url: string, body: any): Promise<any> {
    return new Promise((resolve, reject) => {
      this.generateHeader();
      axios.put(this.configuration.host + url, body)
        .then((response: {}) => resolve(response))
        .catch((error) => reject(Common.httpStatus(error.response)));
    });
  }

  /**
   * @description Runs DELETE request.
   * @param url
   * @return {Promise}
   */
  deleteRequest(url: string): Promise<any> {
    return new Promise((resolve, reject) => {
      this.generateHeader();
      axios.delete(this.configuration.host + url)
        .then((response: {}) => resolve(response))
        .catch((error) => reject(Common.httpStatus(error.response)));
    });
  }

  /**
   * @description Returns exception for non 2xx http codes.
   * @param response
   * @return {*}
   */
  static httpStatus(response: { status: number }): any {
    if (response.status === 400) return new BadRequest();
    if (response.status === 401) return new Unauthorized();
    if (response.status === 402) return new OverQuota();
    if (response.status === 404) return new NotFound();
    if (response.status === 406) return new NotAcceptable();
    if (response.status === 422) return new ValidationError();
    if (response.status === 500) return new InternalError();
    return new UnknownError();
  }
}