googlearchive / web-push-encryption

[Deprecated] Encryption Utilities for Web Push protocol
Apache License 2.0
84 stars 23 forks source link

push not sending #56

Open FallDi opened 8 years ago

FallDi commented 8 years ago

my script is very simple

var webpush = require('web-push-encryption');
webpush.setGCMAPIKey('AIzaSyBuJ2cYQTm1_........');

var subscription = {
  endpoint: "https://android.googleapis.com/gcm/send/eFYgleqGaxQ:APA91bEsz0UJC-C8AsHvemQ…uEUh0zSRiN3C_62QTxb7LZY51zfMY_d3CHqhQ8GSSxJEnkKJLwesNL3QD_CahvrsqBR_W_YUZz",
  keys: {
    p256dh: "BIzynOEufyNOXxLGMFuC9bTYdKTKYuiHjTKq9aotLNfmRxz4J-RkaCRS3cD_GjtluAjG_k_VlK1HFrFZKHL47BE=",
    auth: "yLM9KWWh5rHkyhcoWfbKzA=="
  }
};
var payload = new Buffer('Hello, World!', 'utf8');

var res = webpush.sendWebPush(payload, subscription).then(function(response) {
        console.log(response);
}).catch(function (err) {
        console.log(err);
});

In response i got

{ code: 'expired-subscription',
  statusCode: 400,
  statusMessage: 'UnauthorizedRegistration',
  body: '<HTML>\n<HEAD>\n<TITLE>UnauthorizedRegistration</TITLE>\n</HEAD>\n<BODY BGCOLOR="#FFFFFF" TEXT="#000000">\n<H1>UnauthorizedRegistration</H1>\n<H2>Error 400</H2>\n</BODY>\n</HTML>\n' }

Root cause: payload must be json and also http response header must contains Content-type:application/json

jamsterdam29 commented 8 years ago

@FallDi did find a solution/reason to this issue? I am experiencing the same error.

FallDi commented 8 years ago

I make following changes in file https://github.com/GoogleChrome/web-push-encryption/blob/master/src/push.js

const endpoint = subscription.endpoint.replace(GCM_URL, TEMP_GCM_URL); ----> const endpoint = subscription.endpoint;

and

if (endpoint.indexOf(TEMP_GCM_URL) !== -1) {
    if (gcmAuthToken) {
      headers.Authorization = `key=${gcmAuthToken}`;
    } else {
      throw new Error('GCM requires an Auth Token parameter');
    }
  }

convert to

headers.Authorization = `key=${gcmAuthToken}`;
headers["Content-Type"] = "application/json";
samthor commented 7 years ago

Are you sure your subscription isn't out of date? Can you ensure that the subscription you pass in is recently created by client-side code?

FallDi commented 7 years ago

yep of course. When i change code - push received successfully for same subscription. It 100% reproduced for any subscription problem in request forming. Also gcm-http.googleapis.com do not support binary request body. Please see https://developers.google.com/web/updates/2016/03/web-push-encryption

Web Push
Phew! Now that you have an encrypted payload, you just need to make a relatively simple HTTP POST request to the endpoint specified by the user’s subscription.

You need to set three headers.

Encryption: salt=<SALT>
Crypto-Key: dh=<PUBLICKEY>
Content-Encoding: aesgcm
<SALT> and <PUBLICKEY> are the salt and server public key used in the encryption, encoded as URL-safe Base64.

When using the Web Push protocol, the body of the POST is then just the raw bytes of the encrypted message. However, until Chrome and Google Cloud Messaging support the protocol, you can easily include the data in your existing JSON payload as follows.

{
    "registration_ids": [ "…" ],
    "raw_data": "BIXzEKOFquzVlr/1tS1bhmobZ…"
}
The value of the rawData property must be the base64 encoded representation of the encrypted message.
gauntface commented 7 years ago

I'd suggest using this library instead, it's getting more attention than this repo: github.com/web-push-libs/web-push

spock123 commented 7 years ago

@gauntface same error with that library as well. ..

gauntface commented 7 years ago

Please raise an issue on that library. This one is now deprecated