snowflakedb / snowflake-connector-nodejs

NodeJS driver
Apache License 2.0
121 stars 126 forks source link

SNOW-334890: External browser SSO authentication fails behind http proxy #159

Closed monti-python closed 2 years ago

monti-python commented 3 years ago

Please answer these questions before submitting your issue. Thanks!

  1. What version of NodeJS are you using (node --version and npm --version)? node: v14.16.0 / npm: 6.14.11

  2. What operating system and processor architecture are you using? OS Name: Microsoft Windows 10 Enterprise OS Version: 10.0.18363 N/A Build 18363

  3. What are the component versions in the environment (npm list)?

    snowflake-sdk@1.6.1 C:\Users\xxxxxx\repos\GH\snowflake-connector-nodejs
    +-- agent-base@2.1.1
    | +-- extend@3.0.2 deduped
    | `-- semver@5.0.3
    +-- asn1.js-rfc2560@5.0.1
    | `-- asn1.js-rfc5280@3.0.0 deduped
    +-- asn1.js-rfc5280@3.0.0
    | `-- asn1.js@5.4.1
    |   +-- bn.js@4.12.0
    |   +-- inherits@2.0.4
    |   +-- minimalistic-assert@1.0.1
    |   `-- safer-buffer@2.1.2
    +-- async@2.6.3
    | `-- lodash@4.17.21 deduped
    +-- axios@0.21.1
    | `-- follow-redirects@1.13.3
    +-- big-integer@1.6.48
    +-- bignumber.js@2.4.0
    +-- browser-request@0.3.3
    +-- debug@3.2.7
    | `-- ms@2.1.3
    +-- extend@3.0.2
    +-- https-proxy-agent@3.0.1
    | +-- agent-base@4.3.0
    | | `-- es6-promisify@5.0.0
    | |   `-- es6-promise@4.2.8
    | `-- debug@3.2.7 deduped
    +-- insert-module-globals@7.2.1
    | +-- acorn-node@1.8.2
    | | +-- acorn@7.4.1
    | | +-- acorn-walk@7.2.0
    | | `-- xtend@4.0.2 deduped
    | +-- combine-source-map@0.8.0
    | | +-- convert-source-map@1.1.3
    | | +-- inline-source-map@0.6.2
    | | | `-- source-map@0.5.7 deduped
    | | +-- lodash.memoize@3.0.4
    | | `-- source-map@0.5.7
    | +-- concat-stream@1.6.2
    | | +-- buffer-from@1.1.1
    | | +-- inherits@2.0.4 deduped
    | | +-- readable-stream@2.3.7
    | | | +-- core-util-is@1.0.2
    | | | +-- inherits@2.0.4 deduped
    | | | +-- isarray@1.0.0
    | | | +-- process-nextick-args@2.0.1
    | | | +-- safe-buffer@5.1.2
    | | | +-- string_decoder@1.1.1
    | | | | `-- safe-buffer@5.1.2 deduped
    | | | `-- util-deprecate@1.0.2 deduped
    | | `-- typedarray@0.0.6
    | +-- is-buffer@1.1.6
    | +-- JSONStream@1.3.5
    | | +-- jsonparse@1.3.1
    | | `-- through@2.3.8
    | +-- path-is-absolute@1.0.1
    | +-- process@0.11.10
    | +-- through2@2.0.5
    | | +-- readable-stream@2.3.7
    | | | +-- core-util-is@1.0.2 deduped
    | | | +-- inherits@2.0.4 deduped
    | | | +-- isarray@1.0.0 deduped
    | | | +-- process-nextick-args@2.0.1 deduped
    | | | +-- safe-buffer@5.1.2
    | | | +-- string_decoder@1.1.1
    | | | | `-- safe-buffer@5.1.2 deduped
    | | | `-- util-deprecate@1.0.2 deduped
    | | `-- xtend@4.0.2 deduped
    | +-- undeclared-identifiers@1.1.3
    | | +-- acorn-node@1.8.2 deduped
    | | +-- dash-ast@1.0.0
    | | +-- get-assigned-identifiers@1.2.0
    | | +-- simple-concat@1.0.1
    | | `-- xtend@4.0.2 deduped
    | `-- xtend@4.0.2
    +-- jsonwebtoken@8.5.1
    | +-- jws@3.2.2
    | | +-- jwa@1.4.1
    | | | +-- buffer-equal-constant-time@1.0.1
    | | | +-- ecdsa-sig-formatter@1.0.11
    | | | | `-- safe-buffer@5.2.1 deduped
    | | | `-- safe-buffer@5.2.1 deduped
    | | `-- safe-buffer@5.2.1 deduped
    | +-- lodash.includes@4.3.0
    | +-- lodash.isboolean@3.0.3
    | +-- lodash.isinteger@4.0.4
    | +-- lodash.isnumber@3.0.3
    | +-- lodash.isplainobject@4.0.6
    | +-- lodash.isstring@4.0.1
    | +-- lodash.once@4.1.1
    | +-- ms@2.1.3 deduped
    | `-- semver@5.7.1
    +-- lodash@4.17.21
    +-- mkdirp@1.0.4
    +-- mocha@7.2.0
    | +-- ansi-colors@3.2.3
    | +-- browser-stdout@1.3.1
    | +-- chokidar@3.3.0
    | | +-- anymatch@3.1.2
    | | | +-- normalize-path@3.0.0
    | | | `-- picomatch@2.2.2
    | | +-- braces@3.0.2
    | | | `-- fill-range@7.0.1
    | | |   `-- to-regex-range@5.0.1
    | | |     `-- is-number@7.0.0
    | | +-- UNMET OPTIONAL DEPENDENCY fsevents@2.1.3
    | | +-- glob-parent@5.1.2
    | | | `-- is-glob@4.0.1 deduped
    | | +-- is-binary-path@2.1.0
    | | | `-- binary-extensions@2.2.0
    | | +-- is-glob@4.0.1
    | | | `-- is-extglob@2.1.1
    | | +-- normalize-path@3.0.0
    | | `-- readdirp@3.2.0
    | |   `-- picomatch@2.2.2 deduped
    | +-- debug@3.2.6
    | | `-- ms@2.1.1 deduped
    | +-- diff@3.5.0
    | +-- escape-string-regexp@1.0.5
    | +-- find-up@3.0.0
    | | `-- locate-path@3.0.0
    | |   +-- p-locate@3.0.0
    | |   | `-- p-limit@2.3.0
    | |   |   `-- p-try@2.2.0
    | |   `-- path-exists@3.0.0
    | +-- glob@7.1.3
    | | +-- fs.realpath@1.0.0
    | | +-- inflight@1.0.6
    | | | +-- once@1.4.0 deduped
    | | | `-- wrappy@1.0.2
    | | +-- inherits@2.0.4 deduped
    | | +-- minimatch@3.0.4 deduped
    | | +-- once@1.4.0
    | | | `-- wrappy@1.0.2 deduped
    | | `-- path-is-absolute@1.0.1 deduped
    | +-- growl@1.10.5
    | +-- he@1.2.0
    | +-- js-yaml@3.13.1
    | | +-- argparse@1.0.10
    | | | `-- sprintf-js@1.0.3
    | | `-- esprima@4.0.1
    | +-- log-symbols@3.0.0
    | | `-- chalk@2.4.2
    | |   +-- ansi-styles@3.2.1
    | |   | `-- color-convert@1.9.3
    | |   |   `-- color-name@1.1.3
    | |   +-- escape-string-regexp@1.0.5 deduped
    | |   `-- supports-color@5.5.0
    | |     `-- has-flag@3.0.0 deduped
    | +-- minimatch@3.0.4
    | | `-- brace-expansion@1.1.11
    | |   +-- balanced-match@1.0.2
    | |   `-- concat-map@0.0.1
    | +-- mkdirp@0.5.5
    | | `-- minimist@1.2.5
    | +-- ms@2.1.1
    | +-- node-environment-flags@1.0.6
    | | +-- object.getownpropertydescriptors@2.1.2
    | | | +-- call-bind@1.0.2
    | | | | +-- function-bind@1.1.1 deduped
    | | | | `-- get-intrinsic@1.1.1
    | | | |   +-- function-bind@1.1.1 deduped
    | | | |   +-- has@1.0.3 deduped
    | | | |   `-- has-symbols@1.0.2 deduped
    | | | +-- define-properties@1.1.3 deduped
    | | | `-- es-abstract@1.18.0
    | | |   +-- call-bind@1.0.2 deduped
    | | |   +-- es-to-primitive@1.2.1
    | | |   | +-- is-callable@1.2.3 deduped
    | | |   | +-- is-date-object@1.0.2
    | | |   | `-- is-symbol@1.0.3
    | | |   |   `-- has-symbols@1.0.2 deduped
    | | |   +-- function-bind@1.1.1 deduped
    | | |   +-- get-intrinsic@1.1.1 deduped
    | | |   +-- has@1.0.3
    | | |   | `-- function-bind@1.1.1 deduped
    | | |   +-- has-symbols@1.0.2 deduped
    | | |   +-- is-callable@1.2.3
    | | |   +-- is-negative-zero@2.0.1
    | | |   +-- is-regex@1.1.2
    | | |   | +-- call-bind@1.0.2 deduped
    | | |   | `-- has-symbols@1.0.2 deduped
    | | |   +-- is-string@1.0.5
    | | |   +-- object-inspect@1.9.0
    | | |   +-- object-keys@1.1.1 deduped
    | | |   +-- object.assign@4.1.2
    | | |   | +-- call-bind@1.0.2 deduped
    | | |   | +-- define-properties@1.1.3 deduped
    | | |   | +-- has-symbols@1.0.2 deduped
    | | |   | `-- object-keys@1.1.1 deduped
    | | |   +-- string.prototype.trimend@1.0.4
    | | |   | +-- call-bind@1.0.2 deduped
    | | |   | `-- define-properties@1.1.3 deduped
    | | |   +-- string.prototype.trimstart@1.0.4
    | | |   | +-- call-bind@1.0.2 deduped
    | | |   | `-- define-properties@1.1.3 deduped
    | | |   `-- unbox-primitive@1.0.1
    | | |     +-- function-bind@1.1.1 deduped
    | | |     +-- has-bigints@1.0.1
    | | |     +-- has-symbols@1.0.2 deduped
    | | |     `-- which-boxed-primitive@1.0.2
    | | |       +-- is-bigint@1.0.1
    | | |       +-- is-boolean-object@1.1.0
    | | |       | `-- call-bind@1.0.2 deduped
    | | |       +-- is-number-object@1.0.4
    | | |       +-- is-string@1.0.5 deduped
    | | |       `-- is-symbol@1.0.3 deduped
    | | `-- semver@5.7.1
    | +-- object.assign@4.1.0
    | | +-- define-properties@1.1.3
    | | | `-- object-keys@1.1.1 deduped
    | | +-- function-bind@1.1.1
    | | +-- has-symbols@1.0.2
    | | `-- object-keys@1.1.1
    | +-- strip-json-comments@2.0.1
    | +-- supports-color@6.0.0
    | | `-- has-flag@3.0.0
    | +-- which@1.3.1
    | | `-- isexe@2.0.0
    | +-- wide-align@1.1.3
    | | `-- string-width@2.1.1
    | |   +-- is-fullwidth-code-point@2.0.0
    | |   `-- strip-ansi@4.0.0
    | |     `-- ansi-regex@3.0.0
    | +-- yargs@13.3.2
    | | +-- cliui@5.0.0
    | | | +-- string-width@3.1.0
    | | | | +-- emoji-regex@7.0.3 deduped
    | | | | +-- is-fullwidth-code-point@2.0.0 deduped
    | | | | `-- strip-ansi@5.2.0 deduped
    | | | +-- strip-ansi@5.2.0
    | | | | `-- ansi-regex@4.1.0
    | | | `-- wrap-ansi@5.1.0
    | | |   +-- ansi-styles@3.2.1 deduped
    | | |   +-- string-width@3.1.0
    | | |   | +-- emoji-regex@7.0.3 deduped
    | | |   | +-- is-fullwidth-code-point@2.0.0 deduped
    | | |   | `-- strip-ansi@5.2.0 deduped
    | | |   `-- strip-ansi@5.2.0
    | | |     `-- ansi-regex@4.1.0
    | | +-- find-up@3.0.0 deduped
    | | +-- get-caller-file@2.0.5
    | | +-- require-directory@2.1.1
    | | +-- require-main-filename@2.0.0
    | | +-- set-blocking@2.0.0
    | | +-- string-width@3.1.0
    | | | +-- emoji-regex@7.0.3
    | | | +-- is-fullwidth-code-point@2.0.0 deduped
    | | | `-- strip-ansi@5.2.0
    | | |   `-- ansi-regex@4.1.0
    | | +-- which-module@2.0.0
    | | +-- y18n@4.0.3
    | | `-- yargs-parser@13.1.2 deduped
    | +-- yargs-parser@13.1.2
    | | +-- camelcase@5.3.1
    | | `-- decamelize@1.2.0
    | `-- yargs-unparser@1.6.0
    |   +-- flat@4.1.1
    |   | `-- is-buffer@2.0.5
    |   +-- lodash@4.17.21 deduped
    |   `-- yargs@13.3.2 deduped
    +-- mock-require@3.0.3
    | +-- get-caller-file@1.0.3
    | `-- normalize-path@2.1.1
    |   `-- remove-trailing-separator@1.1.0
    +-- moment@2.29.1
    +-- moment-timezone@0.5.33
    | `-- moment@2.29.1 deduped
    +-- ocsp@1.2.0
    | +-- asn1.js@4.10.1
    | | +-- bn.js@4.12.0 deduped
    | | +-- inherits@2.0.4 deduped
    | | `-- minimalistic-assert@1.0.1 deduped
    | +-- asn1.js-rfc2560@4.0.6
    | | `-- asn1.js-rfc5280@2.0.1 deduped
    | +-- asn1.js-rfc5280@2.0.1
    | | `-- asn1.js@4.10.1 deduped
    | +-- async@1.5.2
    | `-- simple-lru-cache@0.0.2 deduped
    +-- open@7.4.2
    | +-- is-docker@2.2.0
    | `-- is-wsl@2.2.0
    |   `-- is-docker@2.2.0 deduped
    +-- request@2.88.2
    | +-- aws-sign2@0.7.0
    | +-- aws4@1.11.0
    | +-- caseless@0.12.0
    | +-- combined-stream@1.0.8
    | | `-- delayed-stream@1.0.0
    | +-- extend@3.0.2 deduped
    | +-- forever-agent@0.6.1
    | +-- form-data@2.3.3
    | | +-- asynckit@0.4.0
    | | +-- combined-stream@1.0.8 deduped
    | | `-- mime-types@2.1.30 deduped
    | +-- har-validator@5.1.5
    | | +-- ajv@6.12.6
    | | | +-- fast-deep-equal@3.1.3
    | | | +-- fast-json-stable-stringify@2.1.0
    | | | +-- json-schema-traverse@0.4.1
    | | | `-- uri-js@4.4.1
    | | |   `-- punycode@2.1.1 deduped
    | | `-- har-schema@2.0.0
    | +-- http-signature@1.2.0
    | | +-- assert-plus@1.0.0
    | | +-- jsprim@1.4.1
    | | | +-- assert-plus@1.0.0 deduped
    | | | +-- extsprintf@1.3.0
    | | | +-- json-schema@0.2.3
    | | | `-- verror@1.10.0
    | | |   +-- assert-plus@1.0.0 deduped
    | | |   +-- core-util-is@1.0.2 deduped
    | | |   `-- extsprintf@1.3.0 deduped
    | | `-- sshpk@1.16.1
    | |   +-- asn1@0.2.4
    | |   | `-- safer-buffer@2.1.2 deduped
    | |   +-- assert-plus@1.0.0 deduped
    | |   +-- bcrypt-pbkdf@1.0.2
    | |   | `-- tweetnacl@0.14.5 deduped
    | |   +-- dashdash@1.14.1
    | |   | `-- assert-plus@1.0.0 deduped
    | |   +-- ecc-jsbn@0.1.2
    | |   | +-- jsbn@0.1.1 deduped
    | |   | `-- safer-buffer@2.1.2 deduped
    | |   +-- getpass@0.1.7
    | |   | `-- assert-plus@1.0.0 deduped
    | |   +-- jsbn@0.1.1
    | |   +-- safer-buffer@2.1.2 deduped
    | |   `-- tweetnacl@0.14.5
    | +-- is-typedarray@1.0.0
    | +-- isstream@0.1.2
    | +-- json-stringify-safe@5.0.1
    | +-- mime-types@2.1.30
    | | `-- mime-db@1.47.0
    | +-- oauth-sign@0.9.0
    | +-- performance-now@2.1.0
    | +-- qs@6.5.2
    | +-- safe-buffer@5.2.1
    | +-- tough-cookie@2.5.0
    | | +-- psl@1.8.0
    | | `-- punycode@2.1.1
    | +-- tunnel-agent@0.6.0
    | | `-- safe-buffer@5.2.1 deduped
    | `-- uuid@3.4.0 deduped
    +-- requestretry@4.1.2
    | +-- extend@3.0.2 deduped
    | +-- lodash@4.17.21 deduped
    | `-- when@3.7.8
    +-- simple-lru-cache@0.0.2
    +-- uuid@3.4.0
    +-- vinyl-buffer@1.0.1
    | +-- bl@1.2.3
    | | +-- readable-stream@2.3.7
    | | | +-- core-util-is@1.0.2 deduped
    | | | +-- inherits@2.0.4 deduped
    | | | +-- isarray@1.0.0 deduped
    | | | +-- process-nextick-args@2.0.1 deduped
    | | | +-- safe-buffer@5.1.2
    | | | +-- string_decoder@1.1.1
    | | | | `-- safe-buffer@5.1.2
    | | | `-- util-deprecate@1.0.2 deduped
    | | `-- safe-buffer@5.2.1 deduped
    | `-- through2@2.0.5 deduped
    +-- vinyl-source-stream@1.1.2
    | +-- through2@2.0.5 deduped
    | `-- vinyl@0.4.6
    |   +-- clone@0.2.0
    |   `-- clone-stats@0.0.1
    `-- winston@3.3.3
    +-- @dabh/diagnostics@2.0.2
    | +-- colorspace@1.1.2
    | | +-- color@3.0.0
    | | | +-- color-convert@1.9.3 deduped
    | | | `-- color-string@1.5.5
    | | |   +-- color-name@1.1.3 deduped
    | | |   `-- simple-swizzle@0.2.2
    | | |     `-- is-arrayish@0.3.2
    | | `-- text-hex@1.0.0
    | +-- enabled@2.0.0
    | `-- kuler@2.0.0
    +-- async@3.2.0
    +-- is-stream@2.0.0
    +-- logform@2.2.0
    | +-- colors@1.4.0
    | +-- fast-safe-stringify@2.0.7
    | +-- fecha@4.2.1
    | +-- ms@2.1.3 deduped
    | `-- triple-beam@1.3.0 deduped
    +-- one-time@1.0.0
    | `-- fn.name@1.1.0
    +-- readable-stream@3.6.0
    | +-- inherits@2.0.4 deduped
    | +-- string_decoder@1.3.0
    | | `-- safe-buffer@5.2.1 deduped
    | `-- util-deprecate@1.0.2
    +-- stack-trace@0.0.10
    +-- triple-beam@1.3.0
    `-- winston-transport@4.4.0
    +-- readable-stream@2.3.7
    | +-- core-util-is@1.0.2 deduped
    | +-- inherits@2.0.4 deduped
    | +-- isarray@1.0.0 deduped
    | +-- process-nextick-args@2.0.1 deduped
    | +-- safe-buffer@5.1.2
    | +-- string_decoder@1.1.1
    | | `-- safe-buffer@5.1.2 deduped
    | `-- util-deprecate@1.0.2 deduped
    `-- triple-beam@1.3.0 deduped
  4. What did you do? If possible, provide a recipe for reproducing the error. A complete runnable program is good.

async function main_snowflake() {

  const snowflake = require('.');

  let connOptions = {
    account: 'xxxxx',
    database: 'db',
    warehouse: 'vwh',
    authenticator: 'EXTERNALBROWSER',
    username: 'MYUSER@CONTOSO.COM',
    proxyHost: 'localhost',
    proxyPort: 3128
  };
  const loggingOptions = {};

  const conn = snowflake.createConnection(connOptions, loggingOptions);
  // Here it returns Error 500 behind http proxy (corporate proxy)
  await conn.connectAsync(); 

  return conn;
}

main_snowflake();
  1. What did you expect to see?

The connection should be able to open a browser tab to authenticate using SSO

  1. What did you see instead?

It throws Error 500

  1. Add this to get standard output.
C:\Users\xxxxxx\AppData\Local\nodejs\node-v14.16.0-win-x64\node.exe .\main.js
(node:13028) UnhandledPromiseRejectionWarning: Error: Request failed with status code 500
    at createError (c:\Users\xxxxxx\repos\GH\snowflake-connector-nodejs\node_modules\axios\lib\core\createError.js:16:15)
    at settle (c:\Users\xxxxxx\repos\GH\snowflake-connector-nodejs\node_modules\axios\lib\core\settle.js:17:12)
    at IncomingMessage.handleStreamEnd (c:\Users\xxxxxx\repos\GH\snowflake-connector-nodejs\node_modules\axios\lib\adapters\http.js:260:11)
    at IncomingMessage.emit (events.js:327:22)
    at endReadableNT (internal/streams/readable.js:1327:12)
    at processTicksAndRejections (internal/process/task_queues.js:80:21)
(Use `node --trace-warnings ...` to show where the warning was created)
 <node_internals>/internal/process/warning.js
(node:13028) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 2)
 <node_internals>/internal/process/warning.js
(node:13028) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
 <node_internals>/internal/process/warning.js
monti-python commented 3 years ago

The problem is caused by axios and it is a know issue https://github.com/axios/axios/issues/3384, https://github.com/axios/axios/issues/2072.

The proposed solution is to use a custom agent. I was able to fix it using snowflake-sdk's own HttpProxyAgent. I made a PR (#160) with the change.