MONEI / Shopify-api-node

Node Shopify connector sponsored by MONEI
https://monei.com/shopify-payment-gateway/
MIT License
952 stars 280 forks source link

Context influences requests (Response code 401 (Unauthorized)) #385

Closed BjoernRave closed 4 years ago

BjoernRave commented 4 years ago

I am trying to create a public app.

When trying to create a product from inside my application it throws with : Response code 401 (Unauthorized)

However when I create a node script like this:

const Shopify = require('shopify-api-node')

const createProduct = async () => {
  const shopify = new Shopify({
    accessToken: ****,
    shopName: ****,
    apiVersion: '2020-04',
  })

  const res = await shopify.product.create({ title: 'Test' })
  console.log(res)
}

createProduct()

the product gets created successfully.

I tried to paste the exact same code in my application, but I still get the 401.

My application is built apollo-server-micro and running as an api route from next.js

If you need more info, I am happy to provide.

lpinca commented 4 years ago

Unless there is something, like a proxy, that intercepts the requests and changes them this is not possible.

BjoernRave commented 4 years ago

this is the error, that I get:

[3] HTTPError: Response code 401 (Unauthorized)
[3]     at onResponse (/Users/bjoern/projects/inventhora/main/node_modules/got/dist/source/as-promise/index.js:124:28)
[3]     at processTicksAndRejections (internal/process/task_queues.js:97:5) {
[3]   code: undefined,
[3]   timings: {
[3]     start: 1594129870674,
[3]     socket: 1594129870674,
[3]     lookup: 1594129870674,
[3]     connect: 1594129870697,
[3]     secureConnect: 1594129870716,
[3]     upload: 1594129870716,
[3]     response: 1594129870910,
[3]     end: 1594129870911,
[3]     error: undefined,
[3]     abort: undefined,
[3]     phases: {
[3]       wait: 0,
[3]       dns: 0,
[3]       tcp: 23,
[3]       tls: 19,
[3]       request: 0,
[3]       firstByte: 194,
[3]       download: 1,
[3]       total: 237
[3]     }
[3]   }
[3] }

I am unsure how to proceed. I am able to get the accessToken through Oauth. I store the accessToken and the store name and pass those to the constructor, I get the above error however

lpinca commented 4 years ago

Can you run npm ls agent-base from the root of your app and show the result? I think the issue is caused by an old version of the agent-base module that monkey patches https.request().

BjoernRave commented 4 years ago

sure this is the output:

├─┬ @graphql-codegen/cli@1.17.8
│ └─┬ @graphql-tools/prisma-loader@6.0.18
│   ├─┬ http-proxy-agent@4.0.1
│   │ └── agent-base@6.0.1 
│   └─┬ https-proxy-agent@5.0.0
│     └── agent-base@6.0.1 
├─┬ auth0@2.27.1
│ └─┬ rest-facade@1.13.0
│   └─┬ superagent-proxy@2.0.0
│     └─┬ proxy-agent@3.1.1
│       ├── agent-base@4.3.0 
│       ├─┬ http-proxy-agent@2.1.0
│       │ └── agent-base@4.3.0  deduped
│       ├─┬ https-proxy-agent@3.0.1
│       │ └── agent-base@4.3.0  deduped
│       ├─┬ pac-proxy-agent@3.0.1
│       │ ├── agent-base@4.3.0  deduped
│       │ └─┬ https-proxy-agent@3.0.1
│       │   └── agent-base@4.3.0  deduped
│       └─┬ socks-proxy-agent@4.0.2
│         └── agent-base@4.2.1 
├─┬ nexus-plugin-prisma@0.16.2-next.4
│ └─┬ @prisma/sdk@2.2.0
│   └─┬ @prisma/fetch-engine@2.2.0
│     └─┬ http-proxy-agent@4.0.1
│       └── agent-base@6.0.1 
├─┬ puppeteer@5.2.1
│ └─┬ https-proxy-agent@4.0.0
│   └── agent-base@5.1.1 
└─┬ puppeteer-core@5.2.1
  └─┬ https-proxy-agent@4.0.0
    └── agent-base@5.1.1 
lpinca commented 4 years ago

Yes, the problem is in agent-base@<=4. Version >= 5 is ok.

BjoernRave commented 4 years ago

okay, but what do I do now? Try to convince auth0 to update their dependencies?

lpinca commented 4 years ago

Ideally the issue should be fixed in proxy-agent but the project does not seem to be actively maintained. See https://github.com/TooTallNate/node-proxy-agent/issues/51

lpinca commented 4 years ago

@szmarczak can this be addressed in got? For example by checking if https.request() was replaced by agent-base? See https://github.com/MONEI/Shopify-api-node/issues/406#issuecomment-678069541 for a test case.

Edit: nvm this is not an option because agent-base@4.2.1 patches it unconditionally: https://github.com/TooTallNate/node-agent-base/blob/4.2.1/patch-core.js

lpinca commented 4 years ago

@BjoernRave this is a dirty workaround but it should work if you are not using the proxy functionality. In the module where you require auth0 for the first time do

const https = require('https');

const request = https.request;

const auth0 = require('auth0');

https.request = request;

Not sure if it breaks the auth0 module but it should not.

Edit: I'm confident it does not break auth0 if the proxy functionality is not used as per https://github.com/ngonzalvez/rest-facade/blob/v1.13.0/src/Client.js#L321-L323.

BjoernRave commented 4 years ago

@lpinca yea, that workaround works, thanks for that :)

raffi1300 commented 4 years ago
const https = require('https');

const request = https.request;

const auth0 = require('auth0');

https.request = request;

That worked for me. Thank you!

szmarczak commented 4 years ago

@lpinca I just checked and unfortunately there is no universal solution to check whether the http/https module was tampered or not. It's not possible to clear the require cache for native modules. The best I can suggest is if all Node.js native modules were read only.

lpinca commented 4 years ago

I'm closing this as the issue has been fixed in superagent-proxy@2.1.0.

BjoernRave commented 4 years ago

okay, auth0 also just made a new release which includes the updated dependency, will check it later today, but should be good now I guess: https://github.com/auth0/node-auth0/releases

lpinca commented 4 years ago

Yes, I ran npm ls agent-base after installing the latest version of auth0 and everything looks good. It should work without issues.

BjoernRave commented 4 years ago

can confirm, that it is working now