All files common.ts

100% Statements 22/22
100% Branches 4/4
100% Functions 4/4
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 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 991x 1x 1x                                             1x           7x 7x     3x                           5x     2x     5x     3x       7x       5x             5x         5x   5x     12x       5x   5x   5x       5x      
import * as crypto from 'crypto';
import * as querystring from 'querystring';
import * as rp from 'request-promise';
 
declare const Buffer;
 
interface RequestOpts {
  json?: any;
  method: string;
  qs: any;
  body?: any;
  uri?: string;
}
 
interface Authentication {
  access_key: string;
  tonce: number;
  signature: string;
}
 
interface Keys {
  accessKey: string;
  secret: string;
}
 
export class Common {
  private uri: string;
  private api: string;
  private keys: Keys;
 
  constructor(accessKey?: string, secret?: string) {
    this.api = '/api/v2/';
    this.uri = `https://acx.io${this.api}`;
 
    if (accessKey && secret) {
      this.keys = { accessKey, secret };
    }
  }
 
  public async request(auth: boolean, method: string, path: string, qs?: any, body?: any): Promise<any> {
    const opts: RequestOpts = {
      uri: `${this.uri}${path}`,
      method: method,
      qs: qs,
      body: body,
      json: true,
    };
 
    if (auth) {
      const secureQs = this.generateAuthentication(this.keys.accessKey, this.keys.secret, method, path, qs);
 
      if (!opts.qs) {
        opts.qs = {};
      }
 
      opts.qs = Object.assign(opts.qs, secureQs);
 
      if (method === 'POST') { // Remove QS
        Object.keys(body).forEach(key => opts.qs[key] && delete opts.qs[key]);
      }
    }
 
    return rp(opts);
  }
 
  private generateAuthentication(accessKey: string, secret: string, method: string, path: string, qs: any): Authentication {
    const d = Date.now();
 
    const message = [
      method,
      `${this.api}${path}`,
    ];
 
    const signatureParams = Object.assign({
      access_key: accessKey,
      tonce: d,
    }, qs);
 
    const orderedSignatureParams = {};
 
    Object.keys(signatureParams).sort()
      .forEach(key => {
        if (signatureParams[key]) {
          orderedSignatureParams[key] = signatureParams[key];
        }
      });
 
    const stringQs = querystring.stringify(orderedSignatureParams);
 
    const param = message.join('|') + '|' + stringQs;
 
    const signature = crypto.createHmac('sha256', new Buffer(secret, 'utf8'))
      .update(param)
      .digest('hex');
 
    return Object.assign(signatureParams, { signature: signature });
  }
}