@sap/jobs-client
Advanced tools
Comparing version 1.7.30 to 1.7.40
@@ -9,2 +9,8 @@ # Change Log | ||
## 1.7.40 - 2022-08-25 | ||
### Added | ||
- Dependency updates | ||
## 1.7.30 - 2022-05-11 | ||
@@ -11,0 +17,0 @@ |
module.exports = { | ||
BasicAuthRequest: require('./lib/BasicAuthRequest'), | ||
CookieRequest: require('./lib/CookieRequest'), | ||
CsrfTokenRequest: require('./lib/CsrfTokenRequest'), | ||
@@ -10,3 +11,3 @@ OAuthRequest: require('./lib/OAuthRequest'), | ||
RetryRequest: require('./lib/RetryRequest'), | ||
SetTimeout: require('./lib/SetTimeout') | ||
UnsupportedRedirectionError: require('./lib/UnsupportedRedirectionError') | ||
}; |
@@ -1,4 +0,4 @@ | ||
const PlainRequest = require('./PlainRequest'); | ||
const CookieRequest = require('./CookieRequest'); | ||
class CsrfTokenRequest extends PlainRequest { | ||
class CsrfTokenRequest extends CookieRequest { | ||
@@ -5,0 +5,0 @@ constructor(options) { |
@@ -11,3 +11,6 @@ const Url = require('url').URL; | ||
const _options = {}; | ||
const url = new Url(options.url); // url is required! | ||
_options._parsedURL = url; | ||
_options.url = options.url; | ||
@@ -22,7 +25,3 @@ _options.host = url.host; | ||
// console.log(options); | ||
// console.log(_options); | ||
if (options.qs) { | ||
// if (!_options.saerch) _options.search = new URLSearchParams({}).toString(); | ||
new URLSearchParams(options.qs).forEach((value, name) => { | ||
@@ -32,3 +31,2 @@ _options.searchParams.append(name, value); | ||
} | ||
// console.log(_options); | ||
@@ -73,11 +71,16 @@ if (!options.path) _options.path = `${url.pathname}${url.search}`; | ||
getURL() { | ||
return this.getOptions()._parsedURL; | ||
} | ||
_writeBody(request) { | ||
let body = null; | ||
if (this._options.body) { | ||
if (typeof this._options.body === 'string') { | ||
request.setHeader('content-type', 'text/plain'); | ||
request.write(this._options.body); | ||
body = this._options.body; | ||
} | ||
else if (typeof this._options.body === 'object' || typeof this._options.json === 'object') { | ||
request.setHeader('content-type', 'application/json'); | ||
request.write(JSON.stringify(this._options.body || this._options.json, null, 0)); | ||
body = JSON.stringify(this._options.body || this._options.json, null, 0); | ||
} | ||
@@ -87,8 +90,11 @@ } | ||
if (typeof this._options.form === 'object') { | ||
const content = new URLSearchParams(this._options.form).toString(); | ||
body = new URLSearchParams(this._options.form).toString(); | ||
request.setHeader('content-type', 'application/x-www-form-urlencoded'); | ||
request.setHeader('content-length', Buffer.byteLength(content)); | ||
request.write(content); | ||
} | ||
} | ||
if(body) { | ||
request.setHeader('content-length', Buffer.byteLength(body)); | ||
request.write(body); | ||
} | ||
} | ||
@@ -107,2 +113,4 @@ | ||
return new Promise((resolve, reject) => { | ||
let ended = false; | ||
const request = httpModule | ||
@@ -116,2 +124,3 @@ .request(this._options, (response) => { | ||
.on('end', () => { | ||
ended = true; | ||
clearTimeout(this._responseTimeout); | ||
@@ -131,5 +140,11 @@ const _response = { | ||
resolve(_response); | ||
}) | ||
.on('close', () => { | ||
if (!ended) { | ||
response.emit('end'); | ||
} | ||
}); | ||
}) | ||
.on('error', (error) => { | ||
ended = true; | ||
clearTimeout(this._responseTimeout); | ||
@@ -136,0 +151,0 @@ reject(error); |
const CsrfTokenRequest = require('./CsrfTokenRequest'); | ||
const Url = require('url').URL; | ||
const UnsupportedRedirectionError = require('./UnsupportedRedirectionError'); | ||
const requestOptionPropertiesBlacklist = ['path', 'pathname', 'host', 'hostname', 'search', 'searchParams', 'protocol', 'port', '_parsedURL']; | ||
const responseHeadersWhiteList = []; | ||
class RedirectedRequest extends CsrfTokenRequest { | ||
@@ -17,2 +23,3 @@ | ||
this._followHostForwarding = options.followHostForwarding === true; | ||
this._followRedirect = (options.followRedirect !== undefined) ? options.followRedirect : true; | ||
@@ -25,7 +32,7 @@ } | ||
if (!response.headers.location) { | ||
throw new Error('Header \'location\' missing on redirect'); | ||
throw new UnsupportedRedirectionError('Header \'location\' missing on redirect'); | ||
} | ||
return true; | ||
} else { | ||
throw new Error(`Status code of redirect '${response.statusCode}' not supported`); | ||
throw new UnsupportedRedirectionError(`Request was redirected and failed because of unsupported response status code: ${response.statusCode}'`); | ||
} | ||
@@ -37,30 +44,55 @@ } | ||
async _redirect(response) { | ||
this._currentRedirectCounter += 1; | ||
if (typeof this._followRedirect === 'function' && !this._followRedirect(response)) { | ||
throw new Error(`Following the redirect to location '${response.headers['location']}' is not allowed`); | ||
throw new UnsupportedRedirectionError(`Following the redirect to location '${response.headers['location']}' is not allowed`); | ||
} | ||
if (typeof this._followRedirect === 'number' && this._currentRedirectCounter > this._followRedirect) { | ||
throw new Error(`Maximum number of redirects reached (${this._followRedirect})`); | ||
throw new UnsupportedRedirectionError(`Maximum number of redirects reached (${this._followRedirect})`); | ||
} | ||
if (this._currentRedirectCounter > 10) throw new Error('Maximum Number of 10 redirects reached!'); | ||
if (this._currentRedirectCounter > 10) throw new UnsupportedRedirectionError('Maximum Number of 10 redirects reached!'); | ||
let redirectOptions = {}; | ||
if (response.headers) { | ||
redirectOptions.headers = response.headers; // e.g. csrf, authorization, custom, etc. | ||
const locationHeaderValue = response.headers && response.headers.location; | ||
if (!locationHeaderValue) { | ||
throw new UnsupportedRedirectionError(`redirect status ${response.statusCode} enforces a 'location' header which is not present in the response`); | ||
} | ||
redirectOptions.url = response.headers['location']; | ||
if (redirectOptions.headers.location) { | ||
delete redirectOptions.headers['location']; | ||
const redirectOptions = JSON.parse(JSON.stringify(this.getOptions()), (key, value) => { | ||
return requestOptionPropertiesBlacklist.includes(key) ? undefined : value; | ||
}); | ||
responseHeadersWhiteList.forEach((headerName) => { | ||
if (response.headers[headerName]) redirectOptions.headers[headerName] = response.headers[headerName]; | ||
}); | ||
let targetHost; | ||
try { | ||
// First try to use location as a valid url | ||
// Be aware: This allows url forwarding to another domain if the location header includes another domain | ||
// this is controlled by flag this._followHostForwarding | ||
const locationUrl = new Url(locationHeaderValue); | ||
redirectOptions.url = locationUrl.href; | ||
targetHost = locationUrl.host; | ||
} catch (error) { | ||
// If location is not an absolute url we try to use as relative url. | ||
// This could throw "Invalid Url" - error if the result would be still not a valid url | ||
const relativeUrl = new Url(locationHeaderValue, this.getOptions().url); | ||
redirectOptions.url = relativeUrl.href; | ||
targetHost = relativeUrl.host; | ||
} | ||
Object.assign(redirectOptions.headers, this._options.headers); | ||
if (this._followHostForwarding !== true) { | ||
const originHost = this.getURL().host; | ||
if (targetHost !== originHost) { | ||
throw new UnsupportedRedirectionError(`Invalid target host '${targetHost}' for redirection. Host forwarding on redirect in not allowed`); | ||
} | ||
} | ||
redirectOptions.followRedirect = this._followRedirect; | ||
redirectOptions.cookies = this._cookies; | ||
redirectOptions.followHostForwarding = this._followHostForwarding; | ||
redirectOptions.useCookies = this._useCookies; | ||
return await new RedirectedRequest(redirectOptions, this._currentRedirectCounter).execute(); | ||
@@ -85,3 +117,3 @@ } | ||
if (this._assertSupportedRedirect(response)) { | ||
return this._redirect(response); | ||
return await this._redirect(response); | ||
} | ||
@@ -88,0 +120,0 @@ } catch (error) { |
@@ -69,2 +69,3 @@ const BasicAuthRequest = require('./BasicAuthRequest'); | ||
* @param {number|boolean} [options.followRedirect=true] - Follow redirects or not. If a number is provided it follows all redirects until the amount of this number is reached. The absolute amount of redirects is 10. | ||
* @param {boolean} [options.followHostForwarding=false] - If following a redirect to another domain/host and this value is not true an error is thrown to prevent a redirection to another domain or host. | ||
* @param {object|boolean} [options.csrf] - If set, executes csrf token fetch. If set to true all values are using their defaults. | ||
@@ -92,2 +93,3 @@ * @param {assertCallback} [options.csrf.assert] - If set, expects returning a boolean. True will try to fetch csrf a token, false will not try to fetch a csrf token. | ||
} | ||
} | ||
@@ -94,0 +96,0 @@ |
{ | ||
"name": "@sap/jobs-client", | ||
"version": "1.7.30", | ||
"version": "1.7.40", | ||
"lockfileVersion": 1, | ||
@@ -8,4 +8,4 @@ "requires": true, | ||
"@sap/xsenv": { | ||
"version": "3.2.2", | ||
"integrity": "sha512-WG5cpftcRgLe4LtOXJpYYtYODRsVP0FimDnNOLvuFMxz2AG6I8A1ENpGkjPglkDBwKUI3/yDP1v01/JkTe7tBg==", | ||
"version": "3.3.2", | ||
"integrity": "sha1-VYJJmfd7uXSpkZ0v2tRXUbfxFjI=", | ||
"requires": { | ||
@@ -19,11 +19,11 @@ "debug": "4.3.3", | ||
"version": "1.0.0", | ||
"integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" | ||
"integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==" | ||
}, | ||
"clone": { | ||
"version": "2.1.2", | ||
"integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=" | ||
"integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==" | ||
}, | ||
"core-util-is": { | ||
"version": "1.0.2", | ||
"integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" | ||
"integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==" | ||
}, | ||
@@ -54,3 +54,3 @@ "debug": { | ||
"version": "1.10.0", | ||
"integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", | ||
"integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==", | ||
"requires": { | ||
@@ -57,0 +57,0 @@ "assert-plus": "^1.0.0", |
{ | ||
"name": "@sap/jobs-client", | ||
"description": "Node.js client library for job scheduler service in XS2", | ||
"version": "1.7.30", | ||
"version": "1.7.40", | ||
"repository": { | ||
@@ -11,10 +11,10 @@ "type": "git" | ||
"dependencies": { | ||
"@sap/xsenv": "3.2.2" | ||
"@sap/xsenv": "3.3.2" | ||
}, | ||
"devDependencies": { | ||
"eslint": "^8.14.0", | ||
"filter-node-package": "^3.0.0", | ||
"mocha": "^10.0.0", | ||
"nock": "^11.7.0", | ||
"nyc": "^15.1.0" | ||
"eslint": "8.16.0", | ||
"filter-node-package": "3.0.0", | ||
"mocha": "10.0.0", | ||
"nock": "13.2.4", | ||
"nyc": "15.1.0" | ||
}, | ||
@@ -26,6 +26,6 @@ "engines": { | ||
"test": "mocha --recursive test/", | ||
"cover": "nyc --reporter=html --reporter=text npm test", | ||
"lint": "node node_modules/eslint/bin/eslint.js --rulesdir eslint --max-warnings 0 --debug ./", | ||
"cover": "nyc --reporter=html --reporter=text --reporter=lcov --report-dir=.nyc_output npm test", | ||
"lint": "node node_modules/eslint/bin/eslint.js --rulesdir eslint --max-warnings 0 ./", | ||
"prepareRelease": "clean-packages && rm --recursive --force node_modules && npm install --production --no-save --no-package-lock", | ||
"mergeRequest": "rm -rfv ./lib/request && sleep 2 && mv -v \"./node_modules/@sap/request\" ./lib/ && sleep 2 && npm i ./lib/request && npm test" | ||
"mergeRequest": "echo moving request dependency to lib && rm -f ./lib/request/index.js && mv -v \"./node_modules/@sap/request/lib\" ./lib/request && mv \"./node_modules/@sap/request/index.js\" ./lib/request && npm rm @sap/request" | ||
}, | ||
@@ -32,0 +32,0 @@ "eslintConfig": { |
79376
20
1223
+ Added@sap/xsenv@3.3.2(transitive)
- Removed@sap/xsenv@3.2.2(transitive)
Updated@sap/xsenv@3.3.2