import { stringify } from 'querystring' ; import axios , { AxiosRequestConfig , AxiosResponse } from 'axios' ; import { logger } from 'flex-dev-utils' ; const csrfTokenRegex = new RegExp ( /name="CSRF"\svalue="(.*?)"/m ) ; const twVisitorCookieRegex = new RegExp ( /tw-visitor=(.*?);/m ) ; const identityCookieRegex = new RegExp ( /identity=(.*?);/m ) ; const serverIdentityCookieRegex = new RegExp ( /server-identity=(.*?);/m ) ; export interface ConsoleAuthOptions { email : string ; password : string ; } const SET_COOKIE = 'set-cookie' ; export enum Cookie { visitor = 'tw-visitor' , sIdentity = 'server-identity' , identity = 'identity' } export interface Cookies { [ Cookie . identity ] : string | undefined ; [ Cookie . sIdentity ] : string ; [ Cookie . visitor ] : string ; } /**
 * Defines interactions with Console API
 */ export class ConsoleAPI { private readonly baseUrl : string ; private readonly consoleAuthOptions : ConsoleAuthOptions ; param consoleBaseUrl param auth the  ConsoleAuthOptions constructor ( consoleBaseUrl , auth ) { this . baseUrl = consoleBaseUrl ; this . consoleAuthOptions = auth ; } param regex param response param matchName private static getValueFromResponse ( regex , response , matchName ) { const match = response . match ( regex ) ; if ( ! match || ! match [ 1 ] ) { logger . error ( response ) ; throw new Error ( `Response does not contain ${ matchName }` ) ; } return match [ 1 ] ; } param config private static async getResponse ( config ) { try { return axios ( config ) ; } catch ( e ) { logger . error ( `${ config . method }: ${ config . url } returned code ${ e . status }.` ) ; throw new Error ( e ) ; } } /**
     * Get required cookies (tw-visitor, identity, server-identity) to authenticate
     */ async getCookies ( ) { const loginResponse = await ConsoleAPI . getResponse ( { method : 'GET' , url : `${ this . baseUrl }/login` } ) ; const csrfToken = ConsoleAPI . getValueFromResponse ( new RegExp ( csrfTokenRegex ) , loginResponse . data , 'CSRF Token' ) ; const twVisitorCookie = ConsoleAPI . getValueFromResponse ( new RegExp ( twVisitorCookieRegex ) , loginResponse . headers ?. [ SET_COOKIE ] ?. join ( ) || '' , `${ Cookie . visitor } cookie` ) ; const loginPasswordResponse = await ConsoleAPI . getResponse ( { method : 'POST' , url : `${ this . baseUrl }/login/password` , withCredentials : true , maxRedirects : 0 , headers : { cookie : `${ Cookie . visitor }=${ twVisitorCookie }` , } , validateStatus : ( status ) : boolean => status === 302 , data : stringify ( { CSRF : csrfToken , email : this . consoleAuthOptions . email , password : this . consoleAuthOptions . password , } ) , } ) ; const loginPasswordCookies = loginPasswordResponse . headers ?. [ SET_COOKIE ] ?. join ( ) || '' ; const serverIdentityCookie = ConsoleAPI . getValueFromResponse ( new RegExp ( serverIdentityCookieRegex ) , loginPasswordCookies , `${ Cookie . sIdentity } cookie` ) ; let identityCookie ; try { identityCookie = ConsoleAPI . getValueFromResponse ( new RegExp ( identityCookieRegex ) , loginPasswordCookies , `${ Cookie . identity } cookie` ) ; } catch ( e ) { identityCookie = undefined ; } return { [ Cookie . identity ] : identityCookie , [ Cookie . sIdentity ] : serverIdentityCookie , [ Cookie . visitor ] : twVisitorCookie , } ; } }