intuit / oauth-jsclient

Intuit's NodeJS OAuth client provides a set of methods to make it easier to work with OAuth2.0 and Open ID
https://developer.intuit.com/
Apache License 2.0
119 stars 153 forks source link

4.1.0 broke Refresh function #158

Closed elvinvibecartons closed 3 months ago

elvinvibecartons commented 4 months ago

Specifically, if calling refresh() or refreshusingtoken(), it will throw an error that authResponse in oAuthClient.JS does not have a getJson() method. Downgrading to 4.0.0 pre Axios fixes the issue

rajeshgupta723 commented 4 months ago

Hi @elvinvibecartons I downloaded the oauth-jsclient-4.1.0.tar.gz from https://github.com/intuit/oauth-jsclient/releases location and tested, and verified that refresh() is working fine as expected. Would you please re-verify this at your end and feel free to raise a PR to fix anything you may see. Thanks!

elvinvibecartons commented 4 months ago

I re-upgraded via NPM to 4.1.0, clean install. Issue persists, same code works fine in 4.0.0. I added some logging around the line in question in OAuthClient.js. The line that is throwing the error is line 227: const json = (authResponse && authResponse.getJson()) || res; TypeError: authResponse.getJson is not a function [0] at /workspaces/VCInternal/node_modules/intuit-oauth/src/OAuthClient.js:227:50 [0] at process.processTicksAndRejections (node:internal/process/task_queues:95:5) [0] at async refreshusingIOauth (file:///workspaces/VCInternal/qbo.mjs:104:30)

Specifically, it seems the authResponse object has changed from 4.0.0 to 4.1.0. I called refresh twice using the same codebase, one with 4.0.0 and one with 4.1.0. I inserted logging right before line 227 to get the authResponse object as returned.

Here's 4.0.0, it's an AuthResponse object: AuthResponse { [0] token: Token { [0] realmId: , [0] token_type: 'bearer', [0] access_token: , [0] expires_in: 3600, [0] x_refresh_token_expires_in: 8726400, [0] id_token: '', [0] latency: 60000, [0] createdAt: 1709978115305 [0] }, [0] response: Response { [0] Url: Url { [0] protocol: 'https:', [0] slashes: true, [0] auth: null, [0] host: 'oauth.platform.intuit.com', [0] port: null, [0] hostname: 'oauth.platform.intuit.com', [0] hash: null, [0] search: null, [0] query: [Object: null prototype] {}, [0] pathname: '/oauth2/v1/tokens/bearer', [0] path: '/oauth2/v1/tokens/bearer', [0] href: 'https://oauth.platform.intuit.com/oauth2/v1/tokens/bearer' [0] }, [0] rawHeaders: [ [0] 'Date', [0] 'Sat, 09 Mar 2024 19:30:42 GMT', [0] 'Content-Type', [0] 'application/json;charset=utf-8', [0] 'Content-Length', [0] '1028', [0] 'Connection', [0] 'keep-alive', [0] 'x-spanid', [0] '24bc94cc-d57e-8201-dc09-cd7a445a714b', [0] 'x-amzn-trace-id', [0] 'Root=1-65ecb8e2-000893ab481987024cbff103', [0] 'X-Content-Type-Options', [0] 'nosniff', [0] 'Server', [0] 'istio-envoy', [0] 'Cache-Control', [0] 'no-cache, no-store', [0] 'Pragma', [0] 'no-cache', [0] 'X-Frame-Options', [0] 'SAMEORIGIN', [0] 'X-XSS-Protection', [0] '1; mode=block', [0] 'x-envoy-upstream-service-time', [0] '23', [0] 'Strict-Transport-Security', [0] 'max-age=31536000', [0] 'intuit_tid', [0] 'x-request-id', [0] ], [0] body: '{}', [0] status: 200, [0] statusText: 'OK' [0] }, [0] body: '{"}', [0] json: { [0] access_token: [0] refresh_token: ' [0] x_refresh_token_expires_in: 8691873, [0] token_type: 'bearer', [0] expires_in: 3600 [0] }, [0] intuit_tid: [0] }

Here's 4.1.0, the authResponse object is now an Axios response object: `[0] { [0] token: Token { [0] realmId: '', [0] token_type: 'bearer', [0] access_token: '', [0] refresh_token: '', [0] expires_in: 3600, [0] x_refresh_token_expires_in: 8726400, [0] id_token: '', [0] latency: 60000, [0] createdAt: 1709978115305 [0] }, [0] response: { [0] status: 200, [0] statusText: 'OK', [0] headers: Object [AxiosHeaders] { [0] date: 'Sat, 09 Mar 2024 19:35:05 GMT', [0] 'content-type': 'application/json;charset=utf-8', [0] 'content-length': '1028', [0] connection: 'keep-alive', [0] 'x-spanid': 'ab94a64e-c579-c3ef-fcc0-52b49e3f1d2f', [0] 'x-amzn-trace-id': 'Root=1-65ecb9e9-7889d0902271fbab155c9a0e', [0] 'x-content-type-options': 'nosniff', [0] server: 'istio-envoy', [0] 'cache-control': 'no-cache, no-store', [0] pragma: 'no-cache', [0] 'x-frame-options': 'SAMEORIGIN', [0] 'x-xss-protection': '1; mode=block', [0] 'x-envoy-upstream-service-time': '18', [0] 'strict-transport-security': 'max-age=31536000', [0] intuit_tid: '', [0] 'x-request-id': ' [0] }, [0] config: { [0] transitional: [Object], [0] adapter: [Array], [0] transformRequest: [Array], [0] transformResponse: [Array], [0] timeout: 0, [0] xsrfCookieName: 'XSRF-TOKEN', [0] xsrfHeaderName: 'X-XSRF-TOKEN', [0] maxContentLength: -1, [0] maxBodyLength: -1, [0] env: [Object], [0] validateStatus: [Function: validateStatus], [0] headers: [Object [AxiosHeaders]], [0] url: 'https://oauth.platform.intuit.com/oauth2/v1/tokens/bearer', [0] data: 'grant_type=refresh_token&refresh_token=', [0] method: 'post' [0] }, [0] request: ClientRequest { [0] _events: [Object: null prototype], [0] _eventsCount: 7, [0] _maxListeners: undefined, [0] outputData: [], [0] outputSize: 0, [0] writable: true, [0] destroyed: true, [0] _last: false, [0] chunkedEncoding: false, [0] shouldKeepAlive: true, [0] maxRequestsOnConnectionReached: false, [0] _defaultKeepAlive: true, [0] useChunkedEncodingByDefault: true, [0] sendDate: false, [0] _removedConnection: false, [0] _removedContLen: false, [0] _removedTE: false, [0] strictContentLength: false, [0] _contentLength: '89', [0] _hasBody: true, [0] _trailer: '', [0] finished: true, [0] _headerSent: true, [0] _closed: true, [0] socket: [TLSSocket], [0] _header: 'POST /oauth2/v1/tokens/bearer HTTP/1.1\r\n' + [0] 'Accept: application/json\r\n' + [0] 'Content-Type: application/x-www-form-urlencoded\r\n' + [0] 'Authorization: Basic ' + [0] 'User-Agent: Intuit-OAuthClient-JS_4.1.0_Linux_6.2.0-1019-azure_linux\r\n' + [0] 'Content-Length: 89\r\n' + [0] 'Accept-Encoding: gzip, compress, deflate, br\r\n' + [0] 'Host: oauth.platform.intuit.com\r\n' + [0] 'Connection: keep-alive\r\n' + [0] '\r\n', [0] _keepAliveTimeout: 0, [0] _onPendingData: [Function: nop], [0] agent: [Agent], [0] socketPath: undefined, [0] method: 'POST', [0] maxHeaderSize: undefined, [0] insecureHTTPParser: undefined, [0] joinDuplicateHeaders: undefined, [0] path: '/oauth2/v1/tokens/bearer', [0] _ended: true, [0] res: [IncomingMessage], [0] aborted: false, [0] timeoutCb: null, [0] upgradeOrConnect: false, [0] parser: null, [0] maxHeadersCount: null, [0] reusedSocket: false, [0] host: 'oauth.platform.intuit.com', [0] protocol: 'https:', [0] _redirectable: [Writable],

[0] [Symbol(kOutHeaders)]: [Object: null prototype],

[0] }, [0] data: { [0] x_refresh_token_expires_in: 8691610, [0] access_token: '', [0] refresh_token: '', [0] token_type: 'bearer', [0] expires_in: 3600 [0] } [0] }, [0] body: { [0] x_refresh_token_expires_in: 8691610, [0] access_token: '', [0] refresh_token: '', [0] token_type: 'bearer', [0] expires_in: 3600 [0] }, [0] json: { [0] x_refresh_token_expires_in: 8691610, [0] access_token: '', [0] refresh_token: '', [0] token_type: 'bearer', [0] expires_in: 3600 [0] }, [0] intuit_tid: '' [0] }`

GabrielSuttner commented 4 months ago

I'm having the same issue.

GabrielSuttner commented 4 months ago

I downgraded from 4.1.0 to 4.0.0 and it worked fine.

rajeshgupta723 commented 4 months ago

Thank you @elvinvibecartons and @GabrielSuttner , will check this again and get this fixed as early as possible.

laurentjacob commented 4 months ago

I think these two lines: https://github.com/intuit/oauth-jsclient/blob/master/src/OAuthClient.js#L268-L269 should be

      const { response, ...authResponse } = res.json ? res : null; // request => response
      const json = (authResponse && authResponse.json) || res; // getJson() => json

Idem for the refresh method. At least, that's what is being used for the createToken method and they all resolve the same thing, i.e. this.getTokenRequest() https://github.com/intuit/oauth-jsclient/blob/master/src/OAuthClient.js#L185-L186

phil-situmorang commented 4 months ago

Specifically, if calling refresh() or refreshusingtoken(), it will throw an error that authResponse in oAuthClient.JS does not have a getJson() method. Downgrading to 4.0.0 pre Axios fixes the issue

Thank you! I spend a few hours to find that bug and after that I thought - "^" in package.json and their "Minor" updates, oh yeah oh yearh.

rajeshgupta723 commented 4 months ago

Thank you @laurentjacob , I've created a new branch from the master, called release-4.1.1 and raised this PR: https://github.com/intuit/oauth-jsclient/pull/160

Please verify if this fixes the issue. If all looks good, will merge this PR into master later this week. Thanks

amadeogallardo commented 4 months ago

Same issue:

QuickBooks token already invalid or expired. TypeError: authResponse.getJson is not a function at node_modules\intuit-oauth\src\OAuthClient.js:227:50

ysageev commented 4 months ago

Just want to confirm that I am having the same problem and am delighted you are working on it!

🙏

rajeshgupta723 commented 3 months ago

Thanks everyone, the latest npm package has been released: https://www.npmjs.com/package/intuit-oauth/v/4.1.1