import axios, { AxiosInstance } from 'axios' import { APIOptions } from './APIOptions' import { AccessTokenResponse } from './AccessTokenResponse' import { APIResponse } from './APIResponse' import * as jwt from 'jsonwebtoken' import * as moment from 'moment' // tslint:disable: no-console export class PrimeTrustAxiosInstance { private accessToken: string private expiresAt: moment.Moment private axiosInstance: AxiosInstance private constructor( private options: APIOptions, private getAccessToken: () => Promise> ) { } public static async newInstance( options: APIOptions, getAccessToken: () => Promise> ) { const instance = new PrimeTrustAxiosInstance(options, getAccessToken) await instance.initialize() return instance } public getAxiosInstance(): AxiosInstance { return this.axiosInstance } private async initialize() { await this.setAccessToken() this.axiosInstance = axios.create({ baseURL: `${this.options.baseUrl}`, // timeout: 1000, headers: { Authorization: `Bearer ${this.accessToken}`, }, }) this.axiosInstance.interceptors.request.use(async config => { config = await this.checkAccessToken(config) return config }) } private async checkAccessToken(config) { const expiryCheck = moment().add(60, 'seconds') if (!this.accessToken || expiryCheck.isAfter(this.expiresAt)) { // console.log('checkAccessToken: modifying axios instance') await this.initialize() config.headers.Authorization = `Bearer ${this.accessToken}` } return config } private async setAccessToken(): Promise> { // return { errors: ['foo'], status: 503} const { response, errors, status } = await this.getAccessToken() if (errors) { return { errors, status } } // console.log(response) const { token } = response this.accessToken = token // console.log(token) // console.log(jwt.decode(token, { complete: true })) const { exp } = jwt.decode(token) this.expiresAt = moment.unix(exp) return { response, status } } }