diff --git a/package-lock.json b/package-lock.json index 09d3be5..a1296ff 100644 --- a/package-lock.json +++ b/package-lock.json @@ -937,11 +937,6 @@ "integrity": "sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0=", "dev": true }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" - }, "at-least-node": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", @@ -1352,14 +1347,6 @@ "integrity": "sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==", "dev": true }, - "combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "requires": { - "delayed-stream": "~1.0.0" - } - }, "commander": { "version": "6.2.1", "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz", @@ -1881,9 +1868,9 @@ "dev": true }, "data-uri-to-buffer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-3.0.1.tgz", - "integrity": "sha512-WboRycPNsVw3B3TL559F7kuBUM4d8CgMEvk6xEJlOp7OBPjt6G7z8WMWlD2rOFZLk6OYfFIUGsCOWzcQH9K2og==" + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.0.tgz", + "integrity": "sha512-Vr3mLBA8qWmcuschSLAOogKgQ/Jwxulv3RNE4FXnYWRGujzrRWQI4m12fQqRkwX06C0KanhLr4hK+GydchZsaA==" }, "dateformat": { "version": "3.0.3", @@ -1959,11 +1946,6 @@ "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==", "dev": true }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" - }, "depd": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", @@ -2632,9 +2614,13 @@ } }, "fetch-blob": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-2.1.2.tgz", - "integrity": "sha512-YKqtUDwqLyfyMnmbw8XD6Q8j9i/HggKtPEI+pZ1+8bvheBu78biSmNaXWusx1TauGqtUUGx/cBb1mKdq2rLYow==" + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.1.5.tgz", + "integrity": "sha512-N64ZpKqoLejlrwkIAnb9iLSA3Vx/kjgzpcDhygcqJ2KKjky8nCgUQ+dzXtbrLaWZGZNmNfQTsiQ0weZ1svglHg==", + "requires": { + "node-domexception": "^1.0.0", + "web-streams-polyfill": "^3.0.3" + } }, "figures": { "version": "3.2.0", @@ -2763,14 +2749,12 @@ "signal-exit": "^3.0.2" } }, - "form-data": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", - "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", + "formdata-polyfill": { + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", + "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==", "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" + "fetch-blob": "^3.1.2" } }, "forwarded": { @@ -2817,13 +2801,6 @@ "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", "dev": true }, - "fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, - "optional": true - }, "function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", @@ -4478,13 +4455,19 @@ "integrity": "sha512-ASCL5U13as7HhOExbT6OlWJJUV/lLzL2voOSP1UVehpRD8FbSrSDjfScK/KwAvVTI5AS6r4VwbOMlIqtvRidnA==", "dev": true }, + "node-domexception": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", + "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==" + }, "node-fetch": { - "version": "3.0.0-beta.9", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.0.0-beta.9.tgz", - "integrity": "sha512-RdbZCEynH2tH46+tj0ua9caUHVWrd/RHnRfvly2EVdqGmI3ndS1Vn/xjm5KuGejDt2RNDQsVRLPNd2QPwcewVg==", + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.2.3.tgz", + "integrity": "sha512-AXP18u4pidSZ1xYXRDPY/8jdv3RAozIt/WLNR/MBGZAz+xjtlr90RvCnsvHQRiXyWliZF/CpytExp32UU67/SA==", "requires": { - "data-uri-to-buffer": "^3.0.1", - "fetch-blob": "^2.1.1" + "data-uri-to-buffer": "^4.0.0", + "fetch-blob": "^3.1.4", + "formdata-polyfill": "^4.0.10" } }, "node-preload": { @@ -6490,6 +6473,11 @@ "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", "dev": true }, + "web-streams-polyfill": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.2.0.tgz", + "integrity": "sha512-EqPmREeOzttaLRm5HS7io98goBgZ7IVz79aDvqjD0kYXLtFZTc0T/U6wHTPKyIjb+MdN7DFIIX6hgdBEpWmfPA==" + }, "which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", diff --git a/package.json b/package.json index 81480cd..650bdf9 100644 --- a/package.json +++ b/package.json @@ -53,10 +53,9 @@ }, "dependencies": { "@jlguenego/asn.1": "^0.0.4", - "@types/node-fetch": "^2.5.7", "debug": "^4.3.1", "http-errors": "^1.8.0", - "node-fetch": "3.0.0-beta.9", + "node-fetch": "^3.2.3", "ntlm-parser": "^1.0.9" }, "devDependencies": { diff --git a/src/sso/client/AbstractHandler.ts b/src/sso/client/AbstractHandler.ts index f71f8a4..3d6d611 100644 --- a/src/sso/client/AbstractHandler.ts +++ b/src/sso/client/AbstractHandler.ts @@ -1,4 +1,4 @@ -import { RequestInit, Response } from 'node-fetch'; +import type { RequestInit, Response } from 'node-fetch'; import { ClientCookie } from './ClientCookie'; import { ClientInfo } from './ClientInfo'; diff --git a/src/sso/client/BasicHandler.ts b/src/sso/client/BasicHandler.ts index d78f947..d272a09 100644 --- a/src/sso/client/BasicHandler.ts +++ b/src/sso/client/BasicHandler.ts @@ -1,5 +1,6 @@ import dbg from 'debug'; -import fetch, { RequestInit, Response } from 'node-fetch'; +import type { RequestInit, Response } from 'node-fetch'; +import { loadNodeFetch } from '../loadNodeFetch'; import { AbstractHandler } from './AbstractHandler'; import { ClientCookie } from './ClientCookie'; @@ -25,6 +26,7 @@ export class BasicHandler extends AbstractHandler { }; clientCookie.restituteCookies(requestInit); debug('first requestInit.headers', requestInit.headers); + const { fetch } = await loadNodeFetch(); response = await fetch(resource, requestInit); debug('first response.headers', response.headers); clientCookie.saveCookies(response); diff --git a/src/sso/client/ClientCookie.ts b/src/sso/client/ClientCookie.ts index 77cd79c..34c2795 100644 --- a/src/sso/client/ClientCookie.ts +++ b/src/sso/client/ClientCookie.ts @@ -1,4 +1,4 @@ -import { RequestInit, Response } from 'node-fetch'; +import type { RequestInit, Response } from 'node-fetch'; import dbg from 'debug'; import { CookieList } from '../interfaces'; diff --git a/src/sso/client/DigestHandler.ts b/src/sso/client/DigestHandler.ts index c908f95..a6136b6 100644 --- a/src/sso/client/DigestHandler.ts +++ b/src/sso/client/DigestHandler.ts @@ -1,7 +1,8 @@ import dbg from 'debug'; -import fetch, { RequestInit, Response } from 'node-fetch'; +import type { RequestInit, Response } from 'node-fetch'; import { URL } from 'url'; import { Props } from '../../../lib/api'; +import { loadNodeFetch } from '../loadNodeFetch'; import { AbstractHandler } from './AbstractHandler'; import { ClientCookie } from './ClientCookie'; @@ -51,11 +52,11 @@ export class DigestHandler extends AbstractHandler { } debug('digestHeader: ', digestHeader); - const digestChallenge = (digestHeader.split(/, */).reduce((acc, prop) => { + const digestChallenge = digestHeader.split(/, */).reduce((acc, prop) => { const [key, value] = prop.split('='); acc[key] = value.replace(/^"?(.*?)"?$/, '$1'); return acc; - }, {} as Props) as unknown) as DigestChallenge; + }, {} as Props) as unknown as DigestChallenge; debug('digestChallenge: ', digestChallenge); const requestInit: RequestInit = { ...init }; @@ -104,11 +105,12 @@ export class DigestHandler extends AbstractHandler { Authorization: 'Digest ' + Object.keys(digestAnswer) - .map((k) => `${k}=${((digestAnswer as unknown) as Props)[k]}`) + .map((k) => `${k}=${(digestAnswer as unknown as Props)[k]}`) .join(', '), }; clientCookie.restituteCookies(requestInit); debug('first requestInit.headers', requestInit.headers); + const { fetch } = await loadNodeFetch(); response = await fetch(resource, requestInit); debug('first response.headers', response.headers); clientCookie.saveCookies(response); diff --git a/src/sso/client/NegotiateHandler.ts b/src/sso/client/NegotiateHandler.ts index 712e5cc..e51bfa5 100644 --- a/src/sso/client/NegotiateHandler.ts +++ b/src/sso/client/NegotiateHandler.ts @@ -1,5 +1,5 @@ import dbg from 'debug'; -import fetch, { RequestInit, Response } from 'node-fetch'; +import type { RequestInit, Response } from 'node-fetch'; import { negotiateParse } from '../msgParser'; import { @@ -12,6 +12,7 @@ import { ClientCookie } from './ClientCookie'; import { ClientInfo } from './ClientInfo'; import { AbstractHandler } from './AbstractHandler'; import { decode, encode, hexDump } from '../misc'; +import { loadNodeFetch } from '../loadNodeFetch'; const debug = dbg('node-expose-sspi:client'); @@ -118,6 +119,7 @@ export class NegotiateHandler extends AbstractHandler { }; clientCookie.restituteCookies(requestInit); debug('requestInit.headers', requestInit.headers); + const { fetch } = await loadNodeFetch(); response = await fetch(resource, requestInit); debug('response.status', response.status); debug('response.headers', response.headers); diff --git a/src/sso/loadNodeFetch.ts b/src/sso/loadNodeFetch.ts new file mode 100644 index 0000000..18f0668 --- /dev/null +++ b/src/sso/loadNodeFetch.ts @@ -0,0 +1,29 @@ +import type * as NodeFetchModule from 'node-fetch'; + +type NodeFetchInternal = typeof NodeFetchModule; + +export interface NodeFetch extends NodeFetchInternal { + fetch: NodeFetchInternal['default']; +} + +// Prevent transpiling `await import(...)` into a simple require call. +// This would not work because this library compiles to commonjs but node-fetch is a esm library by now. +// Wrapping the import expression into a string hides it from the typescript compiler, so the +// native import expression will be used. +// +// Note that a future typescript module target would fix this as well ("Node12"). +// +// See +// - https://github.com/microsoft/TypeScript/issues/43329#issuecomment-1008361973 +// - https://nodejs.org/docs/latest-v12.x/api/esm.html#esm_import_expressions +const internalLoader = new Function( + 'return import("node-fetch")' +) as () => Promise; + +export async function loadNodeFetch(): Promise { + const module = await internalLoader(); + return { + ...module, + fetch: module.default, + }; +}