mirror of
https://github.com/sasjs/adapter.git
synced 2026-01-15 16:10:06 +00:00
test(RequestClient): specs for communicating with self-signed server
This commit is contained in:
@@ -41,17 +41,21 @@
|
|||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/axios": "^0.14.0",
|
"@types/axios": "^0.14.0",
|
||||||
|
"@types/express": "^4.17.13",
|
||||||
"@types/form-data": "^2.5.0",
|
"@types/form-data": "^2.5.0",
|
||||||
"@types/jest": "^27.0.1",
|
"@types/jest": "^27.0.1",
|
||||||
"@types/mime": "^2.0.3",
|
"@types/mime": "^2.0.3",
|
||||||
|
"@types/pem": "^1.9.6",
|
||||||
"@types/tough-cookie": "^4.0.1",
|
"@types/tough-cookie": "^4.0.1",
|
||||||
"copyfiles": "^2.4.1",
|
"copyfiles": "^2.4.1",
|
||||||
"cp": "^0.2.0",
|
"cp": "^0.2.0",
|
||||||
"dotenv": "^10.0.0",
|
"dotenv": "^10.0.0",
|
||||||
|
"express": "^4.17.1",
|
||||||
"jest": "^27.2.0",
|
"jest": "^27.2.0",
|
||||||
"jest-extended": "^0.11.5",
|
"jest-extended": "^0.11.5",
|
||||||
"node-polyfill-webpack-plugin": "^1.1.4",
|
"node-polyfill-webpack-plugin": "^1.1.4",
|
||||||
"path": "^0.12.7",
|
"path": "^0.12.7",
|
||||||
|
"pem": "^1.14.4",
|
||||||
"process": "^0.11.10",
|
"process": "^0.11.10",
|
||||||
"rimraf": "^3.0.2",
|
"rimraf": "^3.0.2",
|
||||||
"semantic-release": "^17.4.7",
|
"semantic-release": "^17.4.7",
|
||||||
|
|||||||
@@ -527,9 +527,12 @@ export class RequestClient implements HttpClient {
|
|||||||
? { rejectUnauthorized: !allowInsecure }
|
? { rejectUnauthorized: !allowInsecure }
|
||||||
: undefined
|
: undefined
|
||||||
|
|
||||||
if (httpsAgentConfig) {
|
if (httpsAgentConfig && https.Agent) {
|
||||||
const httpsAgent = new https.Agent(httpsAgentConfig)
|
const httpsAgent = new https.Agent(httpsAgentConfig)
|
||||||
this.httpClient = axios.create({ httpsAgent })
|
this.httpClient = axios.create({
|
||||||
|
baseURL: baseUrl,
|
||||||
|
httpsAgent
|
||||||
|
})
|
||||||
} else {
|
} else {
|
||||||
this.httpClient = axios.create({
|
this.httpClient = axios.create({
|
||||||
baseURL: baseUrl
|
baseURL: baseUrl
|
||||||
|
|||||||
163
src/test/RequestClient.spec.ts
Normal file
163
src/test/RequestClient.spec.ts
Normal file
@@ -0,0 +1,163 @@
|
|||||||
|
import * as pem from 'pem'
|
||||||
|
import * as http from 'http'
|
||||||
|
import * as https from 'https'
|
||||||
|
import { app, mockedAuthResponse } from './SAS_server_app'
|
||||||
|
import { ServerType } from '@sasjs/utils'
|
||||||
|
import SASjs from '../SASjs'
|
||||||
|
|
||||||
|
const PORT = 8000
|
||||||
|
const SERVER_URL = `https://localhost:${PORT}/`
|
||||||
|
|
||||||
|
describe('RequestClient', () => {
|
||||||
|
let server: http.Server
|
||||||
|
|
||||||
|
const adapter = new SASjs({
|
||||||
|
serverUrl: `http://localhost:${PORT}/`,
|
||||||
|
serverType: ServerType.SasViya
|
||||||
|
})
|
||||||
|
|
||||||
|
beforeAll(async () => {
|
||||||
|
await new Promise((resolve: any, reject: any) => {
|
||||||
|
server = app
|
||||||
|
.listen(PORT, () => resolve())
|
||||||
|
.on('error', (err: any) => reject(err))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
afterAll(() => {
|
||||||
|
server.close()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should response the POST method', async () => {
|
||||||
|
const authResponse = await adapter.getAccessToken(
|
||||||
|
'clientId',
|
||||||
|
'clientSecret',
|
||||||
|
'authCode'
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(authResponse.access_token).toBe(mockedAuthResponse.access_token)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should response the POST method with Unauthorized', async () => {
|
||||||
|
await expect(
|
||||||
|
adapter.getAccessToken('clientId', 'clientSecret', 'incorrect')
|
||||||
|
).rejects.toEqual(
|
||||||
|
new Error(
|
||||||
|
'Error while getting access tokenRequest failed with status code 401'
|
||||||
|
)
|
||||||
|
)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('RequestClient - Self Signed Server', () => {
|
||||||
|
let adapter: SASjs
|
||||||
|
|
||||||
|
let httpsServer: https.Server
|
||||||
|
let sslConfig: pem.CertificateCreationResult
|
||||||
|
|
||||||
|
beforeAll(async () => {
|
||||||
|
;({ httpsServer, keys: sslConfig } = await setupSelfSignedServer())
|
||||||
|
await new Promise((resolve: any, reject: any) => {
|
||||||
|
httpsServer
|
||||||
|
.listen(PORT, () => resolve())
|
||||||
|
.on('error', (err: any) => reject(err))
|
||||||
|
})
|
||||||
|
|
||||||
|
adapter = new SASjs({
|
||||||
|
serverUrl: SERVER_URL,
|
||||||
|
serverType: ServerType.SasViya,
|
||||||
|
httpsAgentConfiguration: {
|
||||||
|
selfSigned: { ca: [sslConfig.certificate] }
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
afterAll(() => {
|
||||||
|
httpsServer.close()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should throw error for not providing certificate', async () => {
|
||||||
|
const adapterWithoutCertificate = new SASjs({
|
||||||
|
serverUrl: SERVER_URL,
|
||||||
|
serverType: ServerType.SasViya
|
||||||
|
})
|
||||||
|
|
||||||
|
await expect(
|
||||||
|
adapterWithoutCertificate.getAccessToken(
|
||||||
|
'clientId',
|
||||||
|
'clientSecret',
|
||||||
|
'authCode'
|
||||||
|
)
|
||||||
|
).rejects.toEqual(
|
||||||
|
expect.objectContaining({
|
||||||
|
message: 'Error while getting access tokenself signed certificate'
|
||||||
|
})
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should response the POST method using insecure flag', async () => {
|
||||||
|
const adapterAllowInsecure = new SASjs({
|
||||||
|
serverUrl: SERVER_URL,
|
||||||
|
serverType: ServerType.SasViya,
|
||||||
|
httpsAgentConfiguration: {
|
||||||
|
allowInsecure: true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const authResponse = await adapterAllowInsecure.getAccessToken(
|
||||||
|
'clientId',
|
||||||
|
'clientSecret',
|
||||||
|
'authCode'
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(authResponse.access_token).toBe(mockedAuthResponse.access_token)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should response the POST method', async () => {
|
||||||
|
const authResponse = await adapter.getAccessToken(
|
||||||
|
'clientId',
|
||||||
|
'clientSecret',
|
||||||
|
'authCode'
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(authResponse.access_token).toBe(mockedAuthResponse.access_token)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should response the POST method with Unauthorized', async () => {
|
||||||
|
await expect(
|
||||||
|
adapter.getAccessToken('clientId', 'clientSecret', 'incorrect')
|
||||||
|
).rejects.toEqual(
|
||||||
|
new Error(
|
||||||
|
'Error while getting access tokenRequest failed with status code 401'
|
||||||
|
)
|
||||||
|
)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
const setupSelfSignedServer = async (): Promise<{
|
||||||
|
httpsServer: https.Server
|
||||||
|
keys: pem.CertificateCreationResult
|
||||||
|
}> => {
|
||||||
|
return await new Promise(async (resolve) => {
|
||||||
|
const keys = await createCertificate()
|
||||||
|
|
||||||
|
const httpsServer = https.createServer(
|
||||||
|
{ key: keys.clientKey, cert: keys.certificate },
|
||||||
|
app
|
||||||
|
)
|
||||||
|
|
||||||
|
resolve({ httpsServer, keys })
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const createCertificate = async (): Promise<pem.CertificateCreationResult> => {
|
||||||
|
return await new Promise((resolve, reject) => {
|
||||||
|
pem.createCertificate(
|
||||||
|
{ days: 1, selfSigned: true },
|
||||||
|
(error: any, keys: pem.CertificateCreationResult) => {
|
||||||
|
if (error) reject(false)
|
||||||
|
resolve(keys)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
38
src/test/SAS_server_app.ts
Normal file
38
src/test/SAS_server_app.ts
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
import express = require('express')
|
||||||
|
|
||||||
|
export const app = express()
|
||||||
|
|
||||||
|
export const mockedAuthResponse = {
|
||||||
|
access_token: 'access_token',
|
||||||
|
token_type: 'bearer',
|
||||||
|
id_token: 'id_token',
|
||||||
|
refresh_token: 'refresh_token',
|
||||||
|
expires_in: 43199,
|
||||||
|
scope: 'openid',
|
||||||
|
jti: 'jti'
|
||||||
|
}
|
||||||
|
|
||||||
|
app.get('/', function (req: any, res: any) {
|
||||||
|
res.send('Hello World')
|
||||||
|
})
|
||||||
|
|
||||||
|
app.post('/SASLogon/oauth/token', function (req: any, res: any) {
|
||||||
|
let valid = true
|
||||||
|
// capture the encoded form data
|
||||||
|
req.on('data', (data: any) => {
|
||||||
|
const resData = data.toString()
|
||||||
|
|
||||||
|
if (resData.includes('incorrect')) valid = false
|
||||||
|
})
|
||||||
|
|
||||||
|
// send a response when finished reading
|
||||||
|
// the encoded form data
|
||||||
|
req.on('end', () => {
|
||||||
|
if (valid) res.status(200).send(mockedAuthResponse)
|
||||||
|
else
|
||||||
|
res.status(401).send({
|
||||||
|
error: 'unauthorized',
|
||||||
|
error_description: 'Bad credentials'
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
Reference in New Issue
Block a user