bunqCommunity / bunqJSClient

A javascript SDK for the bunq API
MIT License
58 stars 23 forks source link

registerDevice fails with code 400 - The request signature is invalid #37

Closed michelepatrassi closed 5 years ago

michelepatrassi commented 5 years ago

Bug report

Here's the bulk of my code:

  generateRandomKey = () => {
    const key = forge.random.getBytesSync(16);
    return forge.util.bytesToHex(key);
  }

  setup = async () => {
    const permittedIps = [];
    const apiKey = 'API_KEY'; //change this
    const encriptionKey = this.generateRandomKey();
    const bunqJSClient = new BunqJSClient();

    bunqJSClient.setKeepAlive(false);

    // run the bunq application with our API key
    await bunqJSClient.run(apiKey, permittedIps, 'SANDBOX', encriptionKey);

    // install a new keypair
    await bunqJSClient.install();

    //  register this device
    await bunqJSClient.registerDevice();

    //  register a new session
    // await bunqJSClient.registerSession();
  }

The installation goes fine. When it goes to registerDevice, the server returns 400 with the error description "The request signature is invalid.".

If it can help to resolve the error I can host and provide the react-native app. It's a simple autogenerated native react app (https://facebook.github.io/react-native/docs/getting-started.html) with these dependencies:

  "dependencies": {
    "@bunq-community/bunq-js-client": "^0.36.2",
    "node-forge": "^0.7.6",
    "react": "16.6.3",
    "react-native": "0.57.8",
    "url": "^0.11.0"
  },
Crecket commented 5 years ago

I haven't tested for react native but what might be going on is that the User-Agent header is ignored/wrong. If it isn't or if it is overwritten somehow it will cause an invalid signature error.

You could test the code found here and check if the navigator object exists and if the navigator.userAgent value is correct.

For NodeJS it sets a custom header and for the browser it uses the navigator->userAgent value since setting a custom User-Agent header isn't allowed.

michelepatrassi commented 5 years ago

This is the value of navigator.userAgent:

"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36"

I don't get your last sentence: you're saying that I cannot set a custom header, but you're doing it for Node? 😄

By the way, do you still think that the header is the problem?

Crecket commented 5 years ago

To be more clear, browsers don't allow you to set certain headers when sending a HTTP request. User-Agent is one of those which is why for Node we set a custom header and for browsers we fallback to the navigator.userAgent value.

I was worried that in React Native that value might not be set or that the bunqJSClient might not detect it properly and attempt to set the custom User-Agent value. Which would then be ignored/overwritten by the React Native platform.

No idea if that's what is going on here with React Native though but that was my first guess.

DannyvanderJagt commented 5 years ago

Found the issue here. We're removing the User-Agent after we have set it when we think we are a browser. @Crecket Why do we do this, are browsers not allowed?

For React-Native: After disabling this part everything seems to work fine.

Crecket commented 5 years ago

When sending a request the browser will automatically set this value. When you try to set that User-Agent header value manually, it will throw an Refused to set unsafe header "User-Agent" error which happens in most major browsers.

The spec recently changed to allow setting that header but most browsers don't allow it yet including the Chromium version used by Electron. That is why we unset the custom User-Agent header from the Headers list after using it in the code sign section when the "navigator" object is defined.

Could you perhaps check if detecting React Native is possible and add an exception to that if statement to disable it if that is the case? Something like this perhaps. I can't simply straight up remove that line because it'll break support for running in the browser.

DannyvanderJagt commented 5 years ago

Thanks, I will shoot in a PR this afternoon.

Crecket commented 5 years ago

Published under 0.36.4