From 6ff8eece7b35654a1e31265ffa3b6dd63ee21a3f Mon Sep 17 00:00:00 2001 From: Saad Jutt Date: Thu, 7 Oct 2021 13:45:50 +0500 Subject: [PATCH] chore: removed httpsAgent type + clean up --- src/SAS9ApiClient.ts | 9 ++-- src/SASjs.ts | 11 ++-- src/job-execution/Sas9JobExecutor.ts | 9 ++-- src/job-execution/fixit.txt | 15 ++++++ src/request/RequestClient.ts | 31 ++++------- src/request/Sas9RequestClient.ts | 6 +-- src/test/RequestClient.spec.ts | 14 +---- src/test/serverUtils.ts | 77 ---------------------------- src/types/HttpsAgent.ts | 10 ---- src/types/SASjsConfig.ts | 6 ++- src/types/index.ts | 1 - 11 files changed, 46 insertions(+), 143 deletions(-) create mode 100644 src/job-execution/fixit.txt delete mode 100644 src/test/serverUtils.ts delete mode 100644 src/types/HttpsAgent.ts diff --git a/src/SAS9ApiClient.ts b/src/SAS9ApiClient.ts index 6a66caf..b3f31a0 100644 --- a/src/SAS9ApiClient.ts +++ b/src/SAS9ApiClient.ts @@ -1,7 +1,7 @@ +import * as https from 'https' import { generateTimestamp } from '@sasjs/utils/time' import * as NodeFormData from 'form-data' import { Sas9RequestClient } from './request/Sas9RequestClient' -import { HttpsAgent } from './types/HttpsAgent' import { isUrl } from './utils' /** @@ -14,13 +14,10 @@ export class SAS9ApiClient { constructor( private serverUrl: string, private jobsPath: string, - httpsAgentConfiguration?: HttpsAgent + httpsAgentOptions?: https.AgentOptions ) { if (serverUrl) isUrl(serverUrl) - this.requestClient = new Sas9RequestClient( - serverUrl, - httpsAgentConfiguration - ) + this.requestClient = new Sas9RequestClient(serverUrl, httpsAgentOptions) } /** diff --git a/src/SASjs.ts b/src/SASjs.ts index d5f7853..dc2a034 100644 --- a/src/SASjs.ts +++ b/src/SASjs.ts @@ -36,7 +36,6 @@ const defaultConfig: SASjsConfig = { debug: false, contextName: 'SAS Job Execution compute context', useComputeApi: null, - httpsAgentConfiguration: {}, loginMechanism: LoginMechanism.Default } @@ -792,7 +791,7 @@ export default class SASjs { sasApiClient = new SAS9ApiClient( serverUrl, this.jobsPath, - this.sasjsConfig.httpsAgentConfiguration + this.sasjsConfig.httpsAgentOptions ) } } else { @@ -951,12 +950,12 @@ export default class SASjs { if (!this.requestClient) { this.requestClient = new RequestClient( this.sasjsConfig.serverUrl, - this.sasjsConfig.httpsAgentConfiguration + this.sasjsConfig.httpsAgentOptions ) } else { this.requestClient.setConfig( this.sasjsConfig.serverUrl, - this.sasjsConfig.httpsAgentConfiguration + this.sasjsConfig.httpsAgentOptions ) } @@ -995,7 +994,7 @@ export default class SASjs { this.sas9ApiClient = new SAS9ApiClient( this.sasjsConfig.serverUrl, this.jobsPath, - this.sasjsConfig.httpsAgentConfiguration + this.sasjsConfig.httpsAgentOptions ) } @@ -1018,7 +1017,7 @@ export default class SASjs { this.sasjsConfig.serverUrl, this.sasjsConfig.serverType!, this.jobsPath, - this.sasjsConfig.httpsAgentConfiguration + this.sasjsConfig.httpsAgentOptions ) this.computeJobExecutor = new ComputeJobExecutor( diff --git a/src/job-execution/Sas9JobExecutor.ts b/src/job-execution/Sas9JobExecutor.ts index b4fb549..7325bdf 100644 --- a/src/job-execution/Sas9JobExecutor.ts +++ b/src/job-execution/Sas9JobExecutor.ts @@ -1,10 +1,10 @@ +import * as https from 'https' import { ServerType } from '@sasjs/utils/types' import * as NodeFormData from 'form-data' import { ErrorResponse } from '../types/errors' import { convertToCSV, isRelativePath } from '../utils' import { BaseJobExecutor } from './JobExecutor' import { Sas9RequestClient } from '../request/Sas9RequestClient' -import { HttpsAgent } from '../types/HttpsAgent' /** * Job executor for SAS9 servers for use in Node.js environments. @@ -18,13 +18,10 @@ export class Sas9JobExecutor extends BaseJobExecutor { serverUrl: string, serverType: ServerType, private jobsPath: string, - httpsAgentConfiguration: HttpsAgent + httpsAgentOptions?: https.AgentOptions ) { super(serverUrl, serverType) - this.requestClient = new Sas9RequestClient( - serverUrl, - httpsAgentConfiguration - ) + this.requestClient = new Sas9RequestClient(serverUrl, httpsAgentOptions) } async execute(sasJob: string, data: any, config: any) { diff --git a/src/job-execution/fixit.txt b/src/job-execution/fixit.txt new file mode 100644 index 0000000..8ff967a --- /dev/null +++ b/src/job-execution/fixit.txt @@ -0,0 +1,15 @@ +>> self signed certificate in certificate chain + + + + const { key, cert } = serverCert + const httpsServer = https.createServer( + { + key, + cert, + ca: rootCaCert.cert, + requestCert: true, + rejectUnauthorized: false + }, + app + ) \ No newline at end of file diff --git a/src/request/RequestClient.ts b/src/request/RequestClient.ts index c65cf0e..1392599 100644 --- a/src/request/RequestClient.ts +++ b/src/request/RequestClient.ts @@ -1,4 +1,5 @@ import { AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios' +import * as https from 'https' import { CsrfToken } from '..' import { isAuthorizeFormRequired, isLogInRequired } from '../auth' import { @@ -17,7 +18,6 @@ import { parseSourceCode, createAxiosInstance } from '../utils' -import { HttpsAgent } from '../types/HttpsAgent' export interface HttpClient { get( @@ -59,12 +59,15 @@ export class RequestClient implements HttpClient { protected fileUploadCsrfToken: CsrfToken | undefined protected httpClient!: AxiosInstance - constructor(protected baseUrl: string, httpsAgentConfiguration?: HttpsAgent) { - this.createHttpClient(baseUrl, httpsAgentConfiguration) + constructor( + protected baseUrl: string, + httpsAgentOptions?: https.AgentOptions + ) { + this.createHttpClient(baseUrl, httpsAgentOptions) } - public setConfig(baseUrl: string, httpsAgentConfiguration?: HttpsAgent) { - this.createHttpClient(baseUrl, httpsAgentConfiguration) + public setConfig(baseUrl: string, httpsAgentOptions?: https.AgentOptions) { + this.createHttpClient(baseUrl, httpsAgentOptions) } public getCsrfToken(type: 'general' | 'file' = 'general') { @@ -518,24 +521,12 @@ export class RequestClient implements HttpClient { private createHttpClient( baseUrl: string, - httpsAgentConfiguration: HttpsAgent = {} + httpsAgentOptions?: https.AgentOptions ) { - const https = require('https') - const { selfSigned, clientCA, allowInsecure } = httpsAgentConfiguration - - const httpsAgentOptions = selfSigned - ? { ca: selfSigned.ca } - : clientCA - ? { key: clientCA.key, cert: clientCA.cert, requestCert: true } - : allowInsecure - ? { rejectUnauthorized: !allowInsecure } + const httpsAgent = httpsAgentOptions + ? new https.Agent(httpsAgentOptions) : undefined - const httpsAgent = - httpsAgentOptions && https.Agent - ? new https.Agent(httpsAgentOptions) - : undefined - this.httpClient = createAxiosInstance(baseUrl, httpsAgent) this.httpClient.defaults.validateStatus = (status) => diff --git a/src/request/Sas9RequestClient.ts b/src/request/Sas9RequestClient.ts index 9f7fe2b..f5575c5 100644 --- a/src/request/Sas9RequestClient.ts +++ b/src/request/Sas9RequestClient.ts @@ -1,17 +1,17 @@ +import * as https from 'https' import { AxiosRequestConfig } from 'axios' import axiosCookieJarSupport from 'axios-cookiejar-support' import * as tough from 'tough-cookie' import { prefixMessage } from '@sasjs/utils/error' import { RequestClient, throwIfError } from './RequestClient' -import { HttpsAgent } from '../types/HttpsAgent' /** * Specific request client for SAS9 in Node.js environments. * Handles redirects and cookie management. */ export class Sas9RequestClient extends RequestClient { - constructor(baseUrl: string, httpsAgentConfiguration?: HttpsAgent) { - super(baseUrl, httpsAgentConfiguration) + constructor(baseUrl: string, httpsAgentOptions?: https.AgentOptions) { + super(baseUrl, httpsAgentOptions) this.httpClient.defaults.maxRedirects = 0 this.httpClient.defaults.validateStatus = (status) => status >= 200 && status < 303 diff --git a/src/test/RequestClient.spec.ts b/src/test/RequestClient.spec.ts index d74397a..961043c 100644 --- a/src/test/RequestClient.spec.ts +++ b/src/test/RequestClient.spec.ts @@ -5,12 +5,6 @@ import { app, mockedAuthResponse } from './SAS_server_app' import { ServerType } from '@sasjs/utils' import SASjs from '../SASjs' import * as axiosModules from '../utils/createAxiosInstance' -import { - clientCert, - createCertificates, - rootCaCert, - serverCert -} from './serverUtils' const axiosActual = jest.requireActual('axios') @@ -84,9 +78,7 @@ describe('RequestClient - Self Signed Server', () => { adapter = new SASjs({ serverUrl: SERVER_URL, serverType: ServerType.SasViya, - httpsAgentConfiguration: { - selfSigned: { ca: [sslConfig.certificate] } - } + httpsAgentOptions: { ca: [sslConfig.certificate] } }) }) @@ -115,9 +107,7 @@ describe('RequestClient - Self Signed Server', () => { const adapterAllowInsecure = new SASjs({ serverUrl: SERVER_URL, serverType: ServerType.SasViya, - httpsAgentConfiguration: { - allowInsecure: true - } + httpsAgentOptions: { rejectUnauthorized: false } }) const authResponse = await adapterAllowInsecure.getAccessToken( diff --git a/src/test/serverUtils.ts b/src/test/serverUtils.ts deleted file mode 100644 index 91fe35e..0000000 --- a/src/test/serverUtils.ts +++ /dev/null @@ -1,77 +0,0 @@ -var https = require('https') -var { Cert } = require('selfsigned-ca') - -// Root CA certificate used to sign other certificates. -// argument(s) point to .crt and .key file paths - ./selfsigned.root-ca.crt & ./selfsigned.root-ca.key -export const rootCaCert = new Cert('selfsigned.root-ca') -// The certificate generated for use in the HTTP server. It is signed by the CA certificate. -// That way you can create any amount of certificates and they will be all trusted as long -// as the Root CA certificate is trusted (installed to device's keychain). -// argument(s) point to .crt and .key file paths - ./selfsigned.localhost.crt & ./selfsigned.localhost.key -export const serverCert = new Cert(`selfsigned.localhost`) -export const clientCert = new Cert(`selfsigned.client`) - -// .then(startHttpsServer) -// .then(() => console.log('certificates ready, server listening')) -// .catch(console.error) - -export async function createCertificates() { - // await createRootCertificate() - console.log('creating server certificate') - createServerCertificate() - console.log('server certificate created & stored') -} - -function startHttpsServer() { - var server = https.createServer(serverCert, (req: any, res: any) => { - res.writeHead(200) - res.end('hello world\n') - }) - server.listen(443) -} - -async function loadRootCertificate() { - await rootCaCert.load() - if (!(await rootCaCert.isInstalled())) { - // Make sure the CA is installed to device's keychain so that all server certificates - // signed by the CA are automatically trusted and green. - await rootCaCert.install() - } -} - -async function createRootCertificate() { - console.log('createRootCertificate') - // Couldn't load existing root CA certificate. Generate new one. - rootCaCert.createRootCa({ - subject: { - commonName: 'My Trusted Certificate Authority' - } - }) - console.log('rootCaCert', rootCaCert) - // console.log('createRootCertificate saving') - // await rootCaCert.save() - // console.log('createRootCertificate saved') - // Install the newly created CA to device's keychain so that all server certificates - // signed by the CA are automatically trusted and green. - // await rootCaCert.install() - // console.log('createRootCertificate installed') -} - -async function createServerCertificate() { - var serverCertOptions = { - subject: { - commonName: 'localhost' - }, - extensions: [ - { - name: 'subjectAltName', - altNames: [ - { type: 2, value: 'localhost' }, // DNS - { type: 7, ip: '127.0.0.1' } // IP - ] - } - ] - } - serverCert.create(serverCertOptions, rootCaCert) - await serverCert.save() -} diff --git a/src/types/HttpsAgent.ts b/src/types/HttpsAgent.ts deleted file mode 100644 index 5932599..0000000 --- a/src/types/HttpsAgent.ts +++ /dev/null @@ -1,10 +0,0 @@ -export interface HttpsAgent { - selfSigned?: { - ca: string[] - } - clientCA?: { - key: string - cert: string - } - allowInsecure?: boolean -} diff --git a/src/types/SASjsConfig.ts b/src/types/SASjsConfig.ts index 5fb6dad..2a8f64c 100644 --- a/src/types/SASjsConfig.ts +++ b/src/types/SASjsConfig.ts @@ -1,5 +1,5 @@ +import * as https from 'https' import { ServerType } from '@sasjs/utils/types' -import { HttpsAgent } from './HttpsAgent' /** * Specifies the configuration for the SASjs instance - eg where and how to @@ -59,7 +59,9 @@ export class SASjsConfig { * When set to `true`, the adapter will allow requests to SAS servers that use a self-signed SSL certificate. * Changing this setting is not recommended. */ - httpsAgentConfiguration: HttpsAgent = {} + + httpsAgentOptions?: https.AgentOptions + /** * Supported login mechanisms are - Redirected and Default */ diff --git a/src/types/index.ts b/src/types/index.ts index 3998768..2303619 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -2,7 +2,6 @@ export * from './Context' export * from './CsrfToken' export * from './Folder' export * from './File' -export * from './HttpsAgent' export * from './Job' export * from './JobDefinition' export * from './JobResult'