Giter Club home page Giter Club logo

web-push-php's Introduction

WebPush

Web Push library for PHP

Build Status

WebPush can be used to send push messages to endpoints as described in the Web Push protocol.

This push message is then received by the browser, which can then create a notification using the service worker and the Notifications API.

Requirements

PHP 8.1+ and the following extensions:

  • bcmath and/or gmp (optional but better for performance)
  • mbstring
  • curl
  • openssl (with elliptic curve support)

There is no support and maintenance for older PHP versions, however you are free to use the following compatible versions:

  • PHP 5.6 or HHVM: v1.x
  • PHP 7.0: v2.x
  • PHP 7.1: v3.x-v5.x
  • PHP 7.2: v6.x
  • PHP 7.3 7.4: v7.x
  • PHP 8.0 / Openssl without elliptic curve support: v8.x

This README is only compatible with the latest version. Each version of the library has a git tag where the corresponding README can be read.

Installation

Use composer to download and install the library and its dependencies.

composer require minishlink/web-push

Usage

Example

A complete example with html+JS frontend and php backend using web-push-php can be found here: Minishlink/web-push-php-example

Send Push Message

<?php

use Minishlink\WebPush\WebPush;
use Minishlink\WebPush\Subscription;

// store the client-side `PushSubscription` object (calling `.toJSON` on it) as-is and then create a WebPush\Subscription from it
$subscription = Subscription::create(json_decode($clientSidePushSubscriptionJSON, true));

// array of notifications
$notifications = [
    [
        'subscription' => $subscription,
        'payload' => '{"message":"Hello World!"}',
    ], [
          // current PushSubscription format (browsers might change this in the future)
          'subscription' => Subscription::create([
              "endpoint" => "https://example.com/other/endpoint/of/another/vendor/abcdef...",
              "keys" => [
                  'p256dh' => '(stringOf88Chars)',
                  'auth' => '(stringOf24Chars)'
              ],
          ]),
          'payload' => '{"message":"Hello World!"}',
    ], [
        // old Firefox PushSubscription format
        'subscription' => Subscription::create([
            'endpoint' => 'https://updates.push.services.mozilla.com/push/abc...', // Firefox 43+,
            'publicKey' => 'BPcMbnWQL5GOYX/5LKZXT6sLmHiMsJSiEvIFvfcDvX7IZ9qqtq68onpTPEYmyxSQNiH7UD/98AUcQ12kBoxz/0s=', // base 64 encoded, should be 88 chars
            'authToken' => 'CxVX6QsVToEGEcjfYPqXQw==', // base 64 encoded, should be 24 chars
        ]),
        'payload' => 'hello !',
    ], [
        // old Chrome PushSubscription format
        'subscription' => Subscription::create([
            'endpoint' => 'https://fcm.googleapis.com/fcm/send/abcdef...',
        ]),
        'payload' => null,
    ], [
        // old PushSubscription format
        'subscription' => Subscription::create([
            'endpoint' => 'https://example.com/other/endpoint/of/another/vendor/abcdef...',
            'publicKey' => '(stringOf88Chars)',
            'authToken' => '(stringOf24Chars)',
            'contentEncoding' => 'aesgcm', // one of PushManager.supportedContentEncodings
        ]),
        'payload' => '{"message":"test"}',
    ]
];

$webPush = new WebPush();

// send multiple notifications with payload
foreach ($notifications as $notification) {
    $webPush->queueNotification(
        $notification['subscription'],
        $notification['payload'] // optional (defaults null)
    );
}

/**
 * Check sent results
 * @var MessageSentReport $report
 */
foreach ($webPush->flush() as $report) {
    $endpoint = $report->getRequest()->getUri()->__toString();

    if ($report->isSuccess()) {
        echo "[v] Message sent successfully for subscription {$endpoint}.";
    } else {
        echo "[x] Message failed to sent for subscription {$endpoint}: {$report->getReason()}";
    }
}

/**
 * send one notification and flush directly
 * @var MessageSentReport $report
 */
$report = $webPush->sendOneNotification(
    $notifications[0]['subscription'],
    $notifications[0]['payload'], // optional (defaults null)
);

Authentication (VAPID)

Browsers need to verify your identity. A standard called VAPID can authenticate you for all browsers. You'll need to create and provide a public and private key for your server. These keys must be safely stored and should not change.

You can specify your authentication details when instantiating WebPush. The keys can be passed directly (recommended), or you can load a PEM file or its content:

<?php

use Minishlink\WebPush\WebPush;

$endpoint = 'https://fcm.googleapis.com/fcm/send/abcdef...'; // Chrome

$auth = [
    'VAPID' => [
        'subject' => 'mailto:[email protected]', // can be a mailto: or your website address
        'publicKey' => '~88 chars', // (recommended) uncompressed public key P-256 encoded in Base64-URL
        'privateKey' => '~44 chars', // (recommended) in fact the secret multiplier of the private key encoded in Base64-URL
        'pemFile' => 'path/to/pem', // if you have a PEM file and can link to it on your filesystem
        'pem' => 'pemFileContent', // if you have a PEM file and want to hardcode its content
    ],
];

$webPush = new WebPush($auth);
$webPush->queueNotification(...);

In order to generate the uncompressed public and secret key, encoded in Base64, enter the following in your Linux bash:

$ openssl ecparam -genkey -name prime256v1 -out private_key.pem
$ openssl ec -in private_key.pem -pubout -outform DER|tail -c 65|base64|tr -d '=' |tr '/+' '_-' >> public_key.txt
$ openssl ec -in private_key.pem -outform DER|tail -c +8|head -c 32|base64|tr -d '=' |tr '/+' '_-' >> private_key.txt

If you can't access a Linux bash, you can print the output of the createVapidKeys function:

var_dump(VAPID::createVapidKeys()); // store the keys afterwards

On the client-side, don't forget to subscribe with the VAPID public key as the applicationServerKey: (urlBase64ToUint8Array source here)

serviceWorkerRegistration.pushManager.subscribe({
    userVisibleOnly: true,
    applicationServerKey: urlBase64ToUint8Array(vapidPublicKey)
})

Reusing VAPID headers

VAPID headers make use of a JSON Web Token (JWT) to verify your identity. That token payload includes the protocol and hostname of the endpoint included in the subscription and an expiration timestamp (usually between 12-24h), and it's signed using your public and private key. Given that, two notifications sent to the same push service will use the same token, so you can reuse them for the same flush session to boost performance using:

$webPush->setReuseVAPIDHeaders(true);

Notifications and default options

Each notification can have a specific Time To Live, urgency, and topic. The WebPush standard states that urgency is optional but some users reports that Safari throws errors when it is not specified. This might be fixed in the future. You can change the default options with setDefaultOptions() or in the constructor:

<?php

use Minishlink\WebPush\WebPush;

$defaultOptions = [
    'TTL' => 300, // defaults to 4 weeks
    'urgency' => 'normal', // protocol defaults to "normal". (very-low, low, normal, or high)
    'topic' => 'newEvent', // not defined by default. Max. 32 characters from the URL or filename-safe Base64 characters sets
    'batchSize' => 200, // defaults to 1000
];

// for every notification
$webPush = new WebPush([], $defaultOptions);
$webPush->setDefaultOptions($defaultOptions);

// or for one notification
$webPush->sendOneNotification($subscription, $payload, ['TTL' => 5000]);

TTL

Time To Live (TTL, in seconds) is how long a push message is retained by the push service (eg. Mozilla) in case the user browser is not yet accessible (eg. is not connected). You may want to use a very long time for important notifications. The default TTL is 4 weeks. However, if you send multiple nonessential notifications, set a TTL of 0: the push notification will be delivered only if the user is currently connected. For other cases, you should use a minimum of one day if your users have multiple time zones, and if they don't several hours will suffice.

urgency

Urgency can be either "very-low", "low", "normal", or "high". If the browser vendor has implemented this feature, it will save battery life on mobile devices (cf. protocol).

topic

This string will make the vendor show to the user only the last notification of this topic (cf. protocol).

batchSize

If you send tens of thousands notifications at a time, you may get memory overflows due to how endpoints are called in Guzzle. In order to fix this, WebPush sends notifications in batches. The default size is 1000. Depending on your server configuration (memory), you may want to decrease this number. Do this while instantiating WebPush or calling setDefaultOptions. Or, if you want to customize this for a specific flush, give it as a parameter : $webPush->flush($batchSize).

Server errors

You can see what the browser vendor's server sends back in case it encountered an error (push subscription expiration, wrong parameters...).

<?php

/** @var \Minishlink\WebPush\MessageSentReport $report */
foreach ($webPush->flush() as $report) {
    $endpoint = $report->getEndpoint();

    if ($report->isSuccess()) {
        echo "[v] Message sent successfully for subscription {$endpoint}.";
    } else {
        echo "[x] Message failed to sent for subscription {$endpoint}: {$report->getReason()}";

        // also available (to get more info)

        /** @var \Psr\Http\Message\RequestInterface $requestToPushService */
        $requestToPushService = $report->getRequest();

        /** @var \Psr\Http\Message\ResponseInterface $responseOfPushService */
        $responseOfPushService = $report->getResponse();

        /** @var string $failReason */
        $failReason = $report->getReason();

        /** @var bool $isTheEndpointWrongOrExpired */
        $isTheEndpointWrongOrExpired = $report->isSubscriptionExpired();
    }
}

PLEASE NOTE: You can only iterate once over the \Generator object.

Firefox errors are listed in the autopush documentation.

Payload length, security, and performance

Payloads are encrypted by the library. The maximum payload length is theoretically 4078 bytes (or ASCII characters). For compatibility reasons (archived) though, your payload should be less than 3052 bytes long.

The library pads the payload by default. This is more secure but it decreases performance for both your server and your user's device.

Why is it more secure?

When you encrypt a string of a certain length, the resulting string will always have the same length, no matter how many times you encrypt the initial string. This can make attackers guess the content of the payload. In order to circumvent this, this library adds some null padding to the initial payload, so that all the input of the encryption process will have the same length. This way, all the output of the encryption process will also have the same length and attackers won't be able to guess the content of your payload.

Why does it decrease performance?

Encrypting more bytes takes more runtime on your server, and also slows down the user's device with decryption. Moreover, sending and receiving the packet will take more time. It's also not very friendly with users who have limited data plans.

How can I disable or customize automatic padding?

You can customize automatic padding in order to better fit your needs.

Here are some ideas of settings:

  • (default) Encryption::MAX_COMPATIBILITY_PAYLOAD_LENGTH (2820 bytes) for compatibility purposes with Firefox for Android (See #108)
  • Encryption::MAX_PAYLOAD_LENGTH (4078 bytes) for maximum security
  • false for maximum performance
  • If you know your payloads will not exceed X bytes, then set it to X for the best balance between security and performance.
<?php

use Minishlink\WebPush\WebPush;

$webPush = new WebPush();
$webPush->setAutomaticPadding(false); // disable automatic padding
$webPush->setAutomaticPadding(512); // enable automatic padding to 512 bytes (you should make sure that your payload is less than 512 bytes, or else an attacker could guess the content)
$webPush->setAutomaticPadding(true); // enable automatic padding to default maximum compatibility length

Customizing the HTTP client

WebPush uses Guzzle. It will use the most appropriate client it finds, and most of the time it will be MultiCurl, which allows to send multiple notifications in parallel.

You can customize the default request options and timeout when instantiating WebPush:

<?php

use Minishlink\WebPush\WebPush;

$timeout = 20; // seconds
$clientOptions = [
    \GuzzleHttp\RequestOptions::ALLOW_REDIRECTS => false,
]; // see \GuzzleHttp\RequestOptions
$webPush = new WebPush([], [], $timeout, $clientOptions);

Common questions (FAQ)

Is there any plugin/bundle/extension for my favorite PHP framework?

The following are available:

Feel free to add your own!

What about security?

Payload is encrypted according to the Message Encryption for Web Push standard, using the user public key and authentication secret that you can get by following the Web Push API specification.

Internally, WebPush uses the WebToken framework and OpenSSL to handle encryption keys generation and encryption.

How do I scale?

Here are some ideas:

  1. Make sure MultiCurl is available on your server
  2. Find the right balance for your needs between security and performance (see above)
  3. Find the right batch size (set it in defaultOptions or as parameter to flush())
  4. Use flushPooled() instead of flush(). The former uses concurrent requests, accelerating the process and often doubling the speed of the requests.

How to solve "SSL certificate problem: unable to get local issuer certificate"?

Your installation lacks some certificates.

  1. Download cacert.pem.
  2. Edit your php.ini: after [curl], type curl.cainfo = /path/to/cacert.pem.

You can also force using a client without peer verification.

How to solve "Class 'Minishlink\WebPush\WebPush' not found"

Make sure to require Composer's autoloader.

require __DIR__ . '/path/to/vendor/autoload.php';

I get authentication errors when sending notifications

Make sure to have database fields that are large enough for the length of the data you are storing (#233). For the endpoint, users have reported that the URL length does not exceed 500 characters, but this can evolve so you can set it to the 2048 characters limit of most browsers.

I lost my VAPID keys!

See issue #58.

I'm using Google Cloud Messaging (GCM), how do I use this library?

This service does not exist anymore. It has been superseded by Google's Firebase Cloud Messaging (FCM) on May 29, 2019.

I'm using Firebase Cloud Messaging (FCM), how do I use this library?

This library does not support Firebase Cloud Messaging (FCM). Old Chrome subscriptions (prior 2018 and VAPID) do use Legacy HTTP protocol by Firebase Cloud Messaging (FCM) which is deprecated since 2023 and will stop working in June 2024. The support for this outdated subscription is removed.

Please do not be confused as Legacy HTTP protocol and Web Push with VAPID use the identical endpoint URL:

https://fcm.googleapis.com/fcm/send

Web Push with VAPID will remain available at this URL. No further action is currently required.

How to send data?

The browser vendors do not allow to send data using the Push API without creating a notification. Use some alternative APIs like WebSocket/WebTransport or Background Synchronization.

I need to send notifications to native apps. (eg. APNS for iOS)

WebPush is for web apps. You need something like RMSPushNotificationsBundle (Symfony).

This is PHP... I need Javascript!

This library was inspired by the Node.js web-push-libs/web-push library.

Reference

Examples, Notes and Overviews

Internet Engineering Task Force (IETF)

  • Generic Event Delivery Using HTTP Push RFC8030
  • Message Encryption for Web Push RFC8291
  • Voluntary Application Server Identification (VAPID) for Web Push RFC8292

W3C

License

MIT

web-push-php's People

Contributors

baer95 avatar bpolaszek avatar br0ken- avatar chrisdeeming avatar cyperghost avatar dependabot[bot] avatar fkiriakos07 avatar gugu7264 avatar ivanwitzke avatar javiermarinros avatar joostdebruijn avatar kingdutch avatar maglnet avatar marc1706 avatar marcovtwout avatar marcvdm avatar martijnb92 avatar minishlink avatar mpw-wwu avatar reedy avatar rotzbua avatar rwngallego avatar smujaddid avatar spahi4 avatar spomky avatar staabm avatar steffenweber avatar stephanvierkant avatar t1gor avatar the-hasanov avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

web-push-php's Issues

Seems that notifications to Chrome users (VAPID) not displayed

Seems that notifications to Chrome users (VAPID) not displayed.

Yesterday worked, today i saw no... For Mozilla users working

Endpoint: https://fcm.googleapis.com/fcm/send/cU3-U7QeGDA:APA91bE-rgiMCsGkZw6Dnfp2OQn3plXwGj81ckr0c4K3g0h5hVB2XdnnkTRw9OnfVpAuRG8Xd_sp3tM5RHtVypWPUyY-utAy2GhlsZyjQnBYnIDf2owcTVeKSqTtgoSEfdG_omh4r_Sp

$r = $webPush->sendNotification(...)

and $r is bool(true)

Is there a way to debug why are not displayed?

Sometime ago I had same problem and I changed TTL to 3600 to solve.

Some idea?

Error if I not specify 'GCM' => 'MY_GCM_API_KEY'

I generated private_key.pem with openssql 32 bit:

openssl ecparam -genkey -name prime256v1 -out private_key.pem

I defined

$auth = array(
  'VAPID' => array(
     'subject' => 'mailto:[email protected]',
      'pemFile' => DATA_DIR.'cert/private_key.pem'
     ),
);
$client = new \Buzz\Client\MultiCurl();
$client->setOption(CURLOPT_CAINFO, DATA_DIR.'cert/cacert.pem');
$webPush = new WebPush($auth, array('TTL'=>3600), null, $client);

Before I had here just 'GCM' =>'....' and working, but i removed in idea that it is deprecated and optional.

I get this error:

PHP Fatal error: Uncaught exception 'ErrorException' with message 'No GCM API Key specified.' in .....\vendor\minishlink\web-push\src\WebPush.php:219
Stack trace:
#0 .....\vendor\minishlink\web-push\src\WebPush.php(129): Minishlink\WebPush\WebPush->prepareAndSend(Array)
#1 ....\wpn.class.php(335): Minishlink\WebPush\WebPush->flush()
#2 ....\batch_wpn.php(17): wpn->pushNotifications(Array)
#3 {main}
thrown in ...\vendor\minishlink\web-push\src\WebPush.php on line 219

Fatal error: Uncaught exception 'ErrorException' with message 'No GCM API Key specified.' in ...\vendor\minishlink\web-push\src\WebPush.php on line 219

ErrorException: No GCM API Key specified. in ....\vendor\minishlink\web-push\src\WebPush.php on line 219

Call Stack:
0.0003 123320 1. {main}() ....\batch\batch_wpn.php:0
0.0877 4076528 2. wpn->pushNotifications() .....\batch\batch_wpn.php:17
0.4306 5531840 3. Minishlink\WebPush\WebPush->flush() ......\wpn.class.php:335
0.4306 5532032 4. Minishlink\WebPush\WebPush->prepareAndSend() .....\vendor\minishlink\web-push\src\WebPush.php:129

Incompatibility with symfony 3

I was unable to install it due to the following error :
Problem 1

- minishlink/web-push v1.0 requires mdanter/ecc ^0.3.0 -> satisfiable by mdanter/ecc[v0.3.0, v0.3.1].
- minishlink/web-push v1.0.1 requires mdanter/ecc ^0.3.0 -> satisfiable by mdanter/ecc[v0.3.0, v0.3.1].
- mdanter/ecc v0.3.1 requires symfony/console ~2.6 -> satisfiable by symfony/console[2.6.x-dev, 2.7.x-dev, 2.8.x-dev, v2.6.0, v2.6.0-BETA1, v2.6.0-BETA2, v2.6.1, v2.6.10, v2.6.11,
 v2.6.12, v2.6.13, v2.6.2, v2.6.3, v2.6.4, v2.6.5, v2.6.6, v2.6.7, v2.6.8, v2.6.9, v2.7.0, v2.7.0-BETA1, v2.7.0-BETA2, v2.7.1, v2.7.10, v2.7.11, v2.7.12, v2.7.13, v2.7.14, v2.7.15, v2
.7.2, v2.7.3, v2.7.4, v2.7.5, v2.7.6, v2.7.7, v2.7.8, v2.7.9, v2.8.0, v2.8.0-BETA1, v2.8.1, v2.8.2, v2.8.3, v2.8.4, v2.8.5, v2.8.6, v2.8.7, v2.8.8] but these conflict with your requir
ements or minimum-stability.
- mdanter/ecc v0.3.0 requires symfony/console ~2.6 -> satisfiable by symfony/console[2.6.x-dev, 2.7.x-dev, 2.8.x-dev, v2.6.0, v2.6.0-BETA1, v2.6.0-BETA2, v2.6.1, v2.6.10, v2.6.11,
 v2.6.12, v2.6.13, v2.6.2, v2.6.3, v2.6.4, v2.6.5, v2.6.6, v2.6.7, v2.6.8, v2.6.9, v2.7.0, v2.7.0-BETA1, v2.7.0-BETA2, v2.7.1, v2.7.10, v2.7.11, v2.7.12, v2.7.13, v2.7.14, v2.7.15, v2
.7.2, v2.7.3, v2.7.4, v2.7.5, v2.7.6, v2.7.7, v2.7.8, v2.7.9, v2.8.0, v2.8.0-BETA1, v2.8.1, v2.8.2, v2.8.3, v2.8.4, v2.8.5, v2.8.6, v2.8.7, v2.8.8] but these conflict with your requir
ements or minimum-stability.
- Installation request for minishlink/web-push ^1.0 -> satisfiable by minishlink/web-push[v1.0, v1.0.1].

Use OpenSSL PHP binding when PHP bug #67304 is fixed, instead of jose

Payload encryption with OpenSSL should have better performance than with jose.

See the PHP bug #67304.

This fix should be backward compatible with old versions of PHP in which the PHP bug is not fixed.

If you want to help: (thanks!)

  • vote for the PHP bug in the above linked page
  • or contribute to php/php-src in order to fix the bugs

Feature request: Make TTL optional property of Notification

Time-To-Live is defined in WebPush instance. It is currently not possible to define different TTLs for different notifications without instantiating new WebPush objects.

It would be great to be able to set an individual TTL for a notification.

MultiCurl Exceptions not thrown/caught

Hey, when the browser client is MultiCurl, it's really difficult to debug. Neither MultiCurl is throwing any exceptions, nor WebPush is catching any.
Not sure what is the proper way to do the same.
Any help would be appreciated.

Thanks.

I can send notif to FF, but for Chrome no

This is the answer of sending to 3 chrome users :

array(4) {
  ["success"]=>
  bool(false)
  ["statusCode"]=>
  int(400)
  ["headers"]=>
  array(13) {
    [0]=>
    string(32) "HTTP/1.1 400 InvalidTtlParameter"
    [1]=>
    string(38) "Content-Type: text/html; charset=UTF-8"
    [2]=>
    string(35) "Date: Fri, 04 Nov 2016 10:30:54 GMT"
    [3]=>
    string(38) "Expires: Fri, 04 Nov 2016 10:30:54 GMT"
    [4]=>
    string(33) "Cache-Control: private, max-age=0"
    [5]=>
    string(31) "X-Content-Type-Options: nosniff"
    [6]=>
    string(27) "X-Frame-Options: SAMEORIGIN"
    [7]=>
    string(31) "X-XSS-Protection: 1; mode=block"
    [8]=>
    string(11) "Server: GSE"
    [9]=>
    string(46) "Alt-Svc: quic=":443"; ma=2592000; v="36,35,34""
    [10]=>
    string(19) "Accept-Ranges: none"
    [11]=>
    string(21) "Vary: Accept-Encoding"
    [12]=>
    string(26) "Transfer-Encoding: chunked"
  }
  ["content"]=>
  string(161) "<HTML>
<HEAD>
<TITLE>InvalidTtlParameter</TITLE>
</HEAD>
<BODY BGCOLOR="#FFFFFF" TEXT="#000000">
<H1>InvalidTtlParameter</H1>
<H2>Error 400</H2>
</BODY>
</HTML>
"
}
array(4) {
  ["success"]=>
  bool(false)
  ["statusCode"]=>
  int(400)
  ["headers"]=>
  array(13) {
    [0]=>
    string(32) "HTTP/1.1 400 InvalidTtlParameter"
    [1]=>
    string(38) "Content-Type: text/html; charset=UTF-8"
    [2]=>
    string(35) "Date: Fri, 04 Nov 2016 10:30:55 GMT"
    [3]=>
    string(38) "Expires: Fri, 04 Nov 2016 10:30:55 GMT"
    [4]=>
    string(33) "Cache-Control: private, max-age=0"
    [5]=>
    string(31) "X-Content-Type-Options: nosniff"
    [6]=>
    string(27) "X-Frame-Options: SAMEORIGIN"
    [7]=>
    string(31) "X-XSS-Protection: 1; mode=block"
    [8]=>
    string(11) "Server: GSE"
    [9]=>
    string(46) "Alt-Svc: quic=":443"; ma=2592000; v="36,35,34""
    [10]=>
    string(19) "Accept-Ranges: none"
    [11]=>
    string(21) "Vary: Accept-Encoding"
    [12]=>
    string(26) "Transfer-Encoding: chunked"
  }
  ["content"]=>
  string(161) "<HTML>
<HEAD>
<TITLE>InvalidTtlParameter</TITLE>
</HEAD>
<BODY BGCOLOR="#FFFFFF" TEXT="#000000">
<H1>InvalidTtlParameter</H1>
<H2>Error 400</H2>
</BODY>
</HTML>
"
}
array(4) {
  ["success"]=>
  bool(false)
  ["statusCode"]=>
  int(400)
  ["headers"]=>
  array(13) {
    [0]=>
    string(37) "HTTP/1.1 400 UnauthorizedRegistration"
    [1]=>
    string(38) "Content-Type: text/html; charset=UTF-8"
    [2]=>
    string(35) "Date: Fri, 04 Nov 2016 10:30:56 GMT"
    [3]=>
    string(38) "Expires: Fri, 04 Nov 2016 10:30:56 GMT"
    [4]=>
    string(33) "Cache-Control: private, max-age=0"
    [5]=>
    string(31) "X-Content-Type-Options: nosniff"
    [6]=>
    string(27) "X-Frame-Options: SAMEORIGIN"
    [7]=>
    string(31) "X-XSS-Protection: 1; mode=block"
    [8]=>
    string(11) "Server: GSE"
    [9]=>
    string(46) "Alt-Svc: quic=":443"; ma=2592000; v="36,35,34""
    [10]=>
    string(19) "Accept-Ranges: none"
    [11]=>
    string(21) "Vary: Accept-Encoding"
    [12]=>
    string(26) "Transfer-Encoding: chunked"
  }
  ["content"]=>
  string(171) "<HTML>
<HEAD>
<TITLE>UnauthorizedRegistration</TITLE>
</HEAD>
<BODY BGCOLOR="#FFFFFF" TEXT="#000000">
<H1>UnauthorizedRegistration</H1>
<H2>Error 400</H2>
</BODY>
</HTML>
"
}

I use:

require_once LIB_DIR . 'vendor/autoload.php';
$client = new \Buzz\Client\MultiCurl();
$client->setOption(CURLOPT_CAINFO, DATA_DIR.'cert/cacert.pem');
$webPush = new WebPush($this->apiKeys, null, null, $client);
....
while(..) {
  $r = $webPush->sendNotification(
		$dao_wpn_user->wpn_user_endpoint,
		json_encode($notif_list),
		$dao_wpn_user->wpn_user_key_pub,
		$dao_wpn_user->wpn_user_key_auth,
		true
  );
  debug($r);
}
...

Please if you have a suggestion?
Thank you

Flush doesn't return anything

Hi,

can you help me please

I installed the library by composer, but this simple code doesnt'work.

'myapi',); $webPush = new WebPush($apiKeys); $webPush->sendNotification($endpoint, null, null, null, true); $res = array( 'success' => false, 'statusCode' => $responseStatusCode, 'headers' => $responseHeaders, 'content' => $responseContent, // you may have more infos here 'expired' => $isTheEndpointWrongOrExpired,); ?>

The result of the page is this.

Notice: Undefined variable: responseStatusCode in C:\xampp\htdocs\test-push\invia_notifiche.php on line 17
Notice: Undefined variable: responseHeaders in C:\xampp\htdocs\test-push\invia_notifiche.php on line 18
Notice: Undefined variable: responseContent in C:\xampp\htdocs\test-push\invia_notifiche.php on line 19
Notice: Undefined variable: isTheEndpointWrongOrExpired in C:\xampp\htdocs\test-push\invia_notifiche.php on line 20

I'm working on it for 3 days without any results. PHP version 5.6.12
I do not understand what is the problem...for you?

ps: sorry for my bad English

composer still delivers v1.0.1

Hello,

I tried to update to v1.3 today, but composer require minishlink/web-push and composer update still result in the installation / in maintaining of v1.0.1

Thanks

Firefox on Android not working

Hello.

web-push-php not working for Firefox on Android. For Firefox on Desktop all working.

example without vapid:

$webPush = new Minishlink\WebPush\WebPush();
$result = $webPush->sendNotification(
    'https://updates.push.services.mozilla.com/wpush/v1/gAAAAABYNX0F_-z03mY2cPTxDhnaTtloaaCR8Uf1HDvuyxso14jo3fJVd7GUDjqyMwThrmKHsQJYhb3WyGN-OMpxPcdcl68stMzDVUbiiuWsQfFRPwyCl4u1p6IhQ1JD2wDi0rQJc8Lu',
    '{"title":"title","body":"body","icon":"/favicon.ico","uri":"\/"}',
    'BCwyI3k8mhF/6xSqMhjolS+HxUFRDf6xNhm4+2wwCMAHwjCyAHkv1uq3kAQKi5y3DoJMUEYfMr3L6VQiElmaI6k=',
    'y22TWVKVHGRz6AFp0ybBdA==',
    true
);

result without vapid:

array (
  'success' => false,
  'endpoint' => 'https://updates.push.services.mozilla.com/wpush/v1/gAAAAABYNX0F_-z03mY2cPTxDhnaTtloaaCR8Uf1HDvuyxso14jo3fJVd7GUDjqyMwThrmKHsQJYhb3WyGN-OMpxPcdcl68stMzDVUbiiuWsQfFRPwyCl4u1p6IhQ1JD2wDi0rQJc8Lu',
  'statusCode' => 413,
  'headers' => 
  array (
    0 => 'HTTP/1.1 413 Request Entity Too Large',
    1 => 'Access-Control-Allow-Headers: content-encoding,encryption,crypto-key,ttl,encryption-key,content-type,authorization',
    2 => 'Access-Control-Allow-Methods: POST',
    3 => 'Access-Control-Allow-Origin: *',
    4 => 'Access-Control-Expose-Headers: location,www-authenticate',
    5 => 'Content-Type: application/json',
    6 => 'Date: Wed, 23 Nov 2016 11:51:11 GMT',
    7 => 'Content-Length: 270',
    8 => 'Connection: keep-alive',
  ),
  'content' => '{"errno": 104, "message": "This message is intended for a constrained device and is limited to 3070 bytes. Converted buffer too long by 1366 bytes", "code": 413, "more_info": "http://autopush.readthedocs.io/en/latest/http.html#error-codes", "error": "Payload Too Large"}',
  'expired' => false,
)

example with vapid:

$webPush = new Minishlink\WebPush\WebPush(array (
  'VAPID' =>
  array (
    'subject' => 'mailto:[email protected]',
    'publicKey' => 'BKLEYumnBJcixlp80yrha1Ic8UffdM1FZeOmQvTu/8JTueDS7c3vdAawINeQ88oAmpPMwMvn8qsqhbH5TVDRSDY=',
    'privateKey' => '9q+dAHTOvtKAmaiIUih4kpxhB+1DRFm/v7kUOB9hDus=',
  ),
));
$result = $webPush->sendNotification(
    'https://updates.push.services.mozilla.com/wpush/v2/gAAAAABYNXHS_TLCbunVKuMYcXH_k3KTbzdUgqZQw0HHpMZnGZ2zD3g2JrWNlOdUWcwYrLqzouml7F-tFMsrAihKmw49y2WIRe9b43uMe43QSFq-ugUX5T3WctqufDrTlGMzFa-d8OW_EsjQxGXrz93d7G8T4bLhGqrBVSJawT3jTRbbDKb3sV8',
    '{"title":"title","body":"body","icon":"/favicon.ico","uri":"\/"}',
    'BM/8r/zjQr5CWDM4dp/woA7mUWBV0fUfxaCcnq8X7U+rIWm8dNbmRXZ1GRLtau4qslFIaUJExQl7DYEnscqCljI=',
    '++2SVwj4Ps/fLp8/PWSQOQ==',
    true
);

result with vapid:

array (
  'success' => false,
  'endpoint' => 'https://updates.push.services.mozilla.com/wpush/v2/gAAAAABYNXHS_TLCbunVKuMYcXH_k3KTbzdUgqZQw0HHpMZnGZ2zD3g2JrWNlOdUWcwYrLqzouml7F-tFMsrAihKmw49y2WIRe9b43uMe43QSFq-ugUX5T3WctqufDrTlGMzFa-d8OW_EsjQxGXrz93d7G8T4bLhGqrBVSJawT3jTRbbDKb3sV8',
  'statusCode' => 413,
  'headers' => 
  array (
    0 => 'HTTP/1.1 413 Request Entity Too Large',
    1 => 'Access-Control-Allow-Headers: content-encoding,encryption,crypto-key,ttl,encryption-key,content-type,authorization',
    2 => 'Access-Control-Allow-Methods: POST',
    3 => 'Access-Control-Allow-Origin: *',
    4 => 'Access-Control-Expose-Headers: location,www-authenticate',
    5 => 'Content-Type: application/json',
    6 => 'Date: Wed, 23 Nov 2016 11:56:11 GMT',
    7 => 'Content-Length: 270',
    8 => 'Connection: keep-alive',
  ),
  'content' => '{"errno": 104, "message": "This message is intended for a constrained device and is limited to 3070 bytes. Converted buffer too long by 1366 bytes", "code": 413, "more_info": "http://autopush.readthedocs.io/en/latest/http.html#error-codes", "error": "Payload Too Large"}',
  'expired' => false,
)

I checked on the same device https://gauntface.github.io/simple-push-demo/. This demo working for Firefox on Android.

My payload very small.

What is the problem?

Unable to send notification with GCM

Getting the following response:

{"success":false,"statusCode":null,"headers":[],"content":null}

I've followed your examples and also added the GCM key when initiating the class. Not sure what's wrong?

Edit; I've succeeded in sending a notification without payload using just curl and this GCM key. But I want to pass a payload using this library

Problem 1 Problem 1 - The requested package minishlink/web-push No version set (parsed as 1.0.0)

Hi, can you help me please:

When i try install the lib with composer appear the error:

Installation failed, reverting ./composer.json to its original content.

C:\xpto>composer require minishlink/web-push
Using version ^1.1 for minishlink/web-push
./composer.json has been updated
Loading composer repositories with package information
Updating dependencies (including require-dev)
Your requirements could not be resolved to an installable set of packages.

Problem 1
- The requested package minishlink/web-push No version set (parsed as 1.0.0)
is satisfiable by minishlink/web-push[No version set (parsed as 1.0.0)] but the
se conflict with your requirements or minimum-stability.

Installation failed, reverting ./composer.json to its original content.

my coomposer.json is:

{

"name": "minishlink/web-push",
"type": "library",
"description": "Web Push library for PHP",
"keywords": ["push", "notifications", "web", "WebPush", "Push API"],
"homepage": "https://github.com/Minishlink/web-push",
"license": "MIT",
"authors": [
{
"name": "Louis Lagrange",
"email": "[email protected]",
"homepage": "https://github.com/Minishlink"
}
],
"require": {
"php": ">=5.6",
"kriswallsmith/buzz": ">=0.6",
"mdanter/ecc": "^0.4.0",
"lib-openssl": "",
"spomky-labs/base64url": "^1.0",
"spomky-labs/php-aes-gcm": "^1.0"
},
"require-dev": {
"phpunit/phpunit": "4.8.
"
},
"autoload": {
"psr-4" : {
"Minishlink\WebPush" : "src"
}
}
}

thanks

Generator point has x and y out of range

I implemented webpush with our own curl implementation but I get the following exception: Generator point has x and y out of range. Any idea how this happens?
note we are using v1.0.0 on php5.5

custom call:

$payload = $notification->getAndroidGCMPayload();
$payload['icon'] = str_replace('http', 'https', $payload['icon']);
$payload['data'] = array('url' => $payload['url']);
//the check() does padPayload($payload, true)
$payload = Core_Services_PushNotification_Payload::check(json_encode($payload));

$encryptionKeys = $notification->get('additionalData');
$encrypted = Core_Services_PushNotification_Payload::encrypt($payload, $encryptionKeys['p256dh'], $encryptionKeys['auth']);

$request = new Core_Util_HttpRequest($this->_pushDetails['GCM-sendhost'].'/'.$notification->getRecipient());
$request->setReturnType(Core_Util_HttpRequest::$HTTP_REQUEST_RETURN_CONTENT_ARRAY);
$requestOptions = Core_Services_PushNotification_Payload::getHttpHeaders($encrypted, $this->_pushDetails['GCM-key']);
$response = $request->post($encrypted['cipherText'], array(), $requestOptions);

stack trace:

Mdanter\Ecc\Crypto\Key\PublicKey->__construct() @ /production/lib/composer/mdanter/ecc/src/Crypto/Key/PrivateKey.php:72
 Mdanter\Ecc\Crypto\Key\PrivateKey->getPublicKey() @ /production/lib/composer/minishlink/web-push/src/Encryption.php:55
  Minishlink\WebPush\Encryption::encrypt() @ /production/lib/framework/Core/Services/PushNotification/Payload.php:30
   Core_Services_PushNotification_Payload::encrypt() @ /production/lib/framework/Core/Services/PushNotification/Android.php:130

Encryption takes too much time and consumes too much CPU

I am trying to send a bulk push notification to my users. When it tries to encrypt parameters for each individual user it takes almost a second to prepare it (44 seconds for 50 users) - i just checked node.js library for encryption but it takes milliseconds to encrypt user credentials.

i am using php 7.0

is this advanced math libraries take too much time to calculate encrypted payload? did you make any benchmark test?

Use OpenSSL PHP binding when PHP bug #61204 is fixed, instead of phpecc

Generating a public/private key pair and computing the shared secret with OpenSSL should have better performance than with phpecc.

See the PHP bug #61204.

This fix should be backward compatible with old versions of PHP in which the PHP bug is not fixed.

If you want to help: (thanks!)

  • vote for the PHP bug in the above linked page
  • or contribute to php/php-src in order to fix the bugs

Firefox Push Issue

Hey, I'm not sure if you've encountered this or aware of this issue.

But it seems like I need to send 2 Notifications in order for Firefox to work properly, I am not sure why this happening or how to solve it.

Chrome seems to work out of the box.

Now, an really funny think I've noticed.

If both Chrome and Firefox are open, the notification in Firefox comes just normal.

What could be the cause of this ? Is it something you've noticed or maybe something goes wrong.

I've tested this theory like 7 times

If change VAPID keys and in DB already have users registered with other keys, than practically these users are like losts?

If change VAPID keys (generated by VAPID::createVapidKeys()) and in DB already have users registered with other keys, than practically these users are like losts?

In this case I saw that user can unregister, but notification push not working.

Maybe better to store somewhere VAPID pub, priv keys and associate with regisitered users in DB.

In this case, maybe method $webPush->sendNotification() need a new param to rewrite VAPID keys if exists.

It's true ?

Catching endpoint errors?

Hello,

First of all, thanks for the great library :)

My question is: From time to time, there will be endpoints invalidated without them triggering a subscription change (because a browser got uninstalled, cookies cleared etc.) When this happens and you try to send a message to the endpoint, the affected endpoint should respond with an error, so that the push provider has a way to know that the endpoint is invalidated (otherwise you would start to collect dead endpoints as time goes on). Does this library pass these errors back and if yes, how can I catch them?

Thanks

ServiceWorkers Cookbook style Examples

While this library looks good, I have found it a bit difficult to work with. I thought I had everything working but my addEventListener in my service worker never seems to be called for a push event.

By any chance could you create, or link to, an examples from the ServiceWorkers Cookbook using this library instead of server.js? Or at least something we can deploy and run to see the code working?

Keep getting error "Invalid data: only uncompressed keys are supported."

I still keep getting this error with following data:

"endpoint" => "https://android.googleapis.com/gcm/send/cac8N_o868s:APA91bFMSexnK7z429f_ABkxarUQ3lYm3cKzvBburlpqB7-qGkb64XwtNEzTQHVgBVMjqUN2hI9g-vAlIE-Gqr9dYe5WgOgZlBH1Zzij9gjSO5kZRNf06jT58R-cfSAn1Y4SlQkackC0"
"payload" => "Новый выпуск на канале 666"
"userPublicKey" => "Jy+hckShoOJsPu2npeIFOQ=="
"userAuthToken" => "BBs9epoFIW+grT88yz9D3MSjPTf5VTjR7iQeDh83Up2Q2DERKifH/q6A3WTSl2bB7xtg0my/5keTyMEqwFyTkWc="

what am i doing wrong?

GCM Payload sending error.

First of all thank you for sweet library! But here is some troubles with payload:

       $p256dh = 'BOqfOoMNLxRM0mKrE/WUP3CWF5hIqP9fBvwmjXm1eCFeuztev53xKbXs6m76jl1BTnznHCa4abieKVInHw+2HbA=';
        $auth   = 'fbkbiIno4NIwYZRWc0GXHA==';
        $webPush = new WebPush($apiKeys);
        $message = '{data: "hello"}';
        $res = $webPush->sendNotification($endPoint, $message, $p256dh, $auth, true);

Response:

Catchable fatal error: Argument 2 passed to Mdanter\Ecc\Primitives\CurveParameters::__construct() must be an instance of GMP, resource given, called in /var/www/test.karinagold.ru/push2/vendor/mdanter/ecc/src/Curves/NistCurve.php on line 136 and defined in /var/www/test.karinagold.ru/push2/vendor/mdanter/ecc/src/Primitives/CurveParameters.php on line 39
Call Stack
#   Time    Memory  Function    Location
1   0.1001  240016  {main}( )   .../applu.php:0
2   0.1026  283376  send( ???, ??? )    .../applu.php:109
3   0.1035  340104  Minishlink\WebPush\WebPush->sendNotification( ???, ???, ???, ???, ??? ) .../applu.php:35
4   0.1037  352216  Minishlink\WebPush\WebPush->flush( )    .../WebPush.php:99
5   0.1037  352616  Minishlink\WebPush\WebPush->prepareAndSend( ???, ??? )  .../WebPush.php:142
6   0.1037  353744  Minishlink\WebPush\Encryption::encrypt( ???, ???, ???, ??? )    .../WebPush.php:195
7   0.1043  392688  Mdanter\Ecc\Curves\NistCurve->generator256( ??? )   .../Encryption.php:50
8   0.1043  392824  Mdanter\Ecc\Curves\NistCurve->curve256( )   .../NistCurve.php:149
9   0.1044  397792  Mdanter\Ecc\Primitives\CurveParameters->__construct( ???, ???, ???, ??? )   .../NistCurve.php:136

same error with

        $message = 'hello';
        $res = $webPush->sendNotification($endPoint, $message, $p256dh, $auth, true);

But when sending null payload like:

$res = $webPush->sendNotification($endPoint, null, $p256dh, $auth, true);

Notification receives without any problems...

Can u help me with that? Thanks once again!

Response body missing when sending push notification failed

When sending a push notification failed, the push server returns valuable information why it failed.

I suggest to extend the block

                $return[] = array(
                    'success' => false,
                    'statusCode' => $response->getStatusCode(),
                    'headers' => $response->getHeaders(),
                );

to

                $return[] = array(
                    'success' => false,
                    'statusCode' => $response->getStatusCode(),
                    'headers' => $response->getHeaders(),
                    'content' => $response->getContent()
                );

Class 'Minishlink\WebPush\WebPush' not found

Hello,

i installed composer after that

/opt/plesk/php/5.4/bin/php composer.phar require minishlink/web-push

But now i get this error:
Class 'Minishlink\WebPush\WebPush' not found

Web Push and all other needed libraries are installed correct, it think

-bash-4.1$ /opt/plesk/php/5.4/bin/php composer.phar show
beberlei/assert v2.5.1 Thin assertion library for input validation in business models.
fgrosse/phpasn1 1.3.2 A PHP Framework that allows you to encode and decode arbitrary ASN.1 structures using the ITU-T X.690...
kriswallsmith/buzz v0.15 Lightweight HTTP client
mdanter/ecc v0.3.1 PHP Elliptic Curve Cryptography library
minishlink/web-push v1.0.1 Web Push library for PHP
spomky-labs/base64url v1.0.2 Base 64 URL Safe Encoding/decoding PHP Library
spomky-labs/php-aes-gcm v1.0.0 AES GCM (Galois Counter Mode) PHP implementation.
symfony/console v2.8.7 Symfony Console Component
symfony/polyfill-mbstring v1.2.0 Symfony polyfill for the Mbstring extension

when i call the php script in the shell i get this error

-bash-4.1$ /opt/plesk/php/5.4/bin/php data/push_chrome.php PHP Fatal error: Class 'Minishlink\WebPush\WebPush' not found in /var/www/vhosts/domain.com/httpdocs/data/push_chrome.php on line 19

here the script

<?php
use Minishlink\WebPush\WebPush;

// array of notifications
$notifications = array(
    array(
        'endpoint' => 'https://android.googleapis.com/gcm/send/ffDRXoP7u.....',
        'payload' => 'A Test!',
        'userPublicKey' => ''*************',', // base 64 encoded, should be 88 chars
        'userAuthToken' => ''*************',', // base 64 encoded, should be 24 chars
    )
);

$apiKeys = array(
    'GCM' => '*************',
);      
$webPush = new WebPush($apiKeys);

// send one notification and flush directly
$webPush->sendNotification(
    $notifications[0]['endpoint'],
    $notifications[0]['payload'], // optional (defaults null)
    $notifications[0]['userPublicKey'], // optional (defaults null)
    $notifications[0]['userAuthToken'], // optional (defaults null)
    true // optional (defaults false)
);

?>

Thanks for your help

Kevin

web-push-libs/web-push-php + License

cc @Minishlink @marco-c

Just wondering how you both saw this repo vs the web-push-libs repo working together, looks like this repo has a couple more fixes than the web-push-libs version, @Minishlink would you be willing to move the project full time over to web-pushlibs?

You should have full admin rights over the repo and can lock down the master branch so only PR's you're happy with land etc.

Is there any chance you'd be willing to change the license to something like Apache 2, MIT or MPL? Main reason being it should enable some developers to clearly identify what the the restrictions are for the license.

Would either of you be able to enable issues on https://github.com/web-push-libs/web-push-php ?

Cheers,
Matt

composer require minishlink/web-push on Laravel 5

Using version ^1.0 for minishlink/web-push
./composer.json has been updated
Loading composer repositories with package information
Updating dependencies (including require-dev)
Your requirements could not be resolved to an installable set of packages.

Problem 1
- Installation request for symfony/console (locked at v3.0.6) -> satisfiable by symfony/console[v3.0.6].
- minishlink/web-push v1.0 requires mdanter/ecc ^0.3.0 -> satisfiable by mdanter/ecc[v0.3.0].
- minishlink/web-push v1.0.1 requires mdanter/ecc ^0.3.0 -> satisfiable by mdanter/ecc[v0.3.0].
- Conclusion: don't install mdanter/ecc v0.3.0
- Installation request for minishlink/web-push ^1.0 -> satisfiable by minishlink/web-push[v1.0, v1.0.1].

Installation failed, reverting ./composer.json to its original content.

Request did not validate Invalid bearer token: Auth expired

Hi @Minishlink !

The library is great, but i found myself stuck with a problem, suddenly the endpoint (Firefox) keeps on responding me with this:

[content] => {"errno": 109, "message": "Request did not validate Invalid bearer token: Auth expired", "code": 401, "more_info": "http://autopush.readthedocs.io/en/latest/http.html#error-codes", "error": "Unauthorized"}
[expired] =>

I don't really know what is going on (as this is my first time with VAPID auth logics), i've updated your library to the latest version, the VAPID pair is correctly implemented both on client and server side, and i really can't wrap my head around this issue. I've tried to change client and refresh the key pair, but nothing.

Please note that it's just the VAPID auth header that it's causing the issue, a normal tickle with no payload (and no need for VAPID) it's absolutely fine.

Do you have any suggestions on what could cause this issue?

Invalid client public key length.

Hello!
When attempting to send a notification I get the following exception from the encryption attempt.
https://github.com/Minishlink/web-push/blob/master/src/Encryption.php#L142
I get p256dh key:
btoa(String.fromCharCode.apply(null, new Uint8Array(subscription.getKey('p256dh'))))
its value:
BB/zlk+wuo74gm04WvYbTxup2t1oJ7biSoDSmujcQr7GhcGHB16h4xh8QNOpC0PG6eQFmpl6nenrvmbLNAhsHoc=
p256dh key I also get just like you:
https://github.com/Minishlink/physbook/blob/d6855ca8f485556ab2ee5c047688fbf745367045/app/Resources/public/js/app.js#L268

After (https://github.com/Minishlink/web-push/blob/master/src/Encryption.php#L44)
Base64Url::decode('BB/zlk+wuo74gm04WvYbTxup2t1oJ7biSoDSmujcQr7GhcGHB16h4xh8QNOpC0PG6eQFmpl6nenrvmbLNAhsHoc=')
strlen($clientPublicKey) = 46

Is there anything else I can try?

VAPID. Warning: hex2bin(): Hexadecimal input string must have an even length

Hello.

VAPID sometimes does not work.

hex2bin return false and warning.

My solution:

$privateKeyObject = EccFactory::getNistCurves()->generator256()->createPrivateKey();
$hex = gmp_strval($privateKeyObject->getSecret(), 16);
if (strlen($hex) % 2 != 0) {
    $hex = '0'.$hex;
}
$vapid['privateKey'] = base64_encode(hex2bin($hex));

Runtime exception with Mdanter ECC library

'https://android.googleapis.com/gcm/send/dpGMEh3K2cg:APA91bGrPuUlu9b-WPngdR9b0IXyw2cC7PZJ8u3-5VU21P6nhwSlvw9MSk8omOIzZeMLOcqxrjO-rEEAKZAeMNdF6VQMHIcz-m8ZeemgqwI-LraL9M0D37L2RjzYRiYxhvqotfVSRJS1', // Chrome 'payload' => 'Hello', 'userPublicKey' => 'BCXxO8IhPp_PVjnfx7TugJA3gYdQd3jZUzfcinsjiLjtCL_uJf_2Y9fK8HYkAp2ot6FXs5q7ZFOzdiNlttThpdA=', 'userAuthToken' => 'gMDKYYtTeHKG-8nGKN1xzQ==', ) ); $apiKeys = array( 'GCM' => 'AIzaSyDoqTxHy2cw2bxLAE7lwTrImgzKyfZJKaQ', ); $webPush = new WebPush($apiKeys); // send multiple notifications with payload foreach ($notifications as $notification) { $webPush->sendNotification( $notification['endpoint'], $notification['payload'], // optional (defaults null) $notification['userPublicKey'], // optional (defaults null) $notification['userAuthToken'] // optional (defaults null) ); } $webPush->flush(); ?>

I get this output:

PHP Fatal error: Uncaught exception 'RuntimeException' with message 'Curve curve(-3, 41058363725152142129326129780047268409114441015993725554835256314039467401291, 115792089210356248762697446949407573530086143415290314195533631308867097853951) does not contain point (67038273347490662382185575485487379440402771158004031264493575046428765755, 116935489649439228016838975285237332447812780727018558127038228236318709568)' in /var/www/vendor/mdanter/ecc/src/Primitives/Point.php:100
Stack trace:
#0 /var/www/vendor/mdanter/ecc/src/Primitives/CurveFp.php(111): Mdanter\Ecc\Primitives\Point->__construct(Object(Mdanter\Ecc\Math\Gmp), Object(Mdanter\Ecc\Curves\NamedCurveFp), '670382733474906...', '116935489649439...', NULL)
#1 /var/www/vendor/mdanter/ecc/src/Serializer/Point/UncompressedPointSerializer.php(76): Mdanter\Ecc\Primitives\CurveFp->getPoint('670382733474906...', '116935489649439...')
#2 /var/www/vendor/minish in /var/www/vendor/mdanter/ecc/src/Primitives/Point.php on line 100

Not sure if this is an issue with this library or the ECC library.

Question - Structure/Layout to using this Library?

Hello,

I just want to double check the layout design to using this library, sorry if this question is a bit basic. It's because of the lack of information out there on encrypted web push.

Is this the correct usage structure for this library:

  1. JS to reg sw
  2. JS to get p256dh and auth and endpoint
  3. Save encryption details to server php pdo
  4. Load encryption details from server
  5. Put details into this encryption library (server 2 this library to send messages???)
  6. The details will go to sw automatically, so you just need to create a waituntil listener in sw for it to listen to this encryption library
  7. Msg goes out to users from the saved list stored in the server

Thanks look forward to your answer, as very keen to try this library out and connect it up to my sw scripts.

Laravel framework?

It is really working good when tested it . But I want to set it up in laravel. Is better way to using in laravel?

ios handling

would be great if you could spent some words in the readme on how to handle ios in regards to pushing notifications from a web-app to the enduser.

possible at all? any alternative approaches to achieve the same goal with different api/lib?

How to run your tests?

I'm a complete PHP noob, so not sure how you run your tests, but would like to add some integration tests to this project but not sure how you're currently testing this, any tips?

Payload data empty when getting push notification

Hello there!,

I am sending push notification payload data to GCM endpoint and I am getting notification to corresponding browser but my payload data is empty in service workers JS.

Any ideas are appreciated, Thank you!

Needs to have identifier along with expired flag in response when push notification failed

Thanks for adding "expired" flag in response. But there is small problem. If i have to send notification to 10 subscribers having chrome & firefox endpoints, this expired flag couldn't help to recognize which endpoint from them actually dead or expired as library makes queue of endpoints according to server type & returns the result according to server type queue. This makes expired flag unusable as we don't know which endpoint is expired due to server based queue logic.
So there is need of identifier like subscription id or endpoint in response to identify which endpoint is actually dead. If we send notification to single subscriber at time then there is not need of it.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.