Skip to content

Commit

Permalink
auth can be customized per notification, close #58
Browse files Browse the repository at this point in the history
  • Loading branch information
Minishlink committed Nov 15, 2016
1 parent d914e9b commit 07bd808
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 10 deletions.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,9 @@ Your installation lacks some certificates.

You can also force using a client without peer verification.

### I lost my VAPID keys!
See [issue #58](https://github.com/web-push-libs/web-push-php/issues/58).

### I need to send notifications to native apps. (eg. APNS for iOS)
WebPush is for web apps.
You need something like [RMSPushNotificationsBundle](https://github.com/richsage/RMSPushNotificationsBundle) (Symfony).
Expand Down
18 changes: 16 additions & 2 deletions src/Notification.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,20 @@ class Notification
/** @var string */
private $userAuthToken;

/** @var array Options : TTL, urgency, topic * */
/** @var array Options : TTL, urgency, topic */
private $options;

public function __construct($endpoint, $payload, $userPublicKey, $userAuthToken, $options)
/** @var array Auth details : GCM, VAPID */
private $auth;

public function __construct($endpoint, $payload, $userPublicKey, $userAuthToken, $options, $auth)
{
$this->endpoint = $endpoint;
$this->payload = $payload;
$this->userPublicKey = $userPublicKey;
$this->userAuthToken = $userAuthToken;
$this->options = $options;
$this->auth = $auth;
}

/**
Expand Down Expand Up @@ -83,4 +87,14 @@ public function getOptions(array $defaultOptions = array())

return $options;
}

/**
* @param array $defaultAuth
*
* @return array
*/
public function getAuth(array $defaultAuth)
{
return count($this->auth) > 0 ? $this->auth : $defaultAuth;
}
}
3 changes: 1 addition & 2 deletions src/VAPID.php
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,6 @@ public static function getVapidHeaders($audience, $subject, $publicKey, $private
);
}


/**
* This method creates VAPID keys in case you would not be able to have a Linux bash.
* DO NOT create keys at each initialization! Save those keys and reuse them.
Expand All @@ -152,7 +151,7 @@ private static function getUncompressedKeys(PrivateKeyInterface $privateKeyObjec
{
$pointSerializer = new UncompressedPointSerializer(EccFactory::getAdapter());
$vapid['publicKey'] = base64_encode(hex2bin($pointSerializer->serialize($privateKeyObject->getPublicKey()->getPoint())));
$vapid['privateKey'] = base64_encode(hex2bin(str_pad(gmp_strval($privateKeyObject->getSecret(), 16), 2*self::PRIVATE_KEY_LENGTH, '0', STR_PAD_LEFT)));
$vapid['privateKey'] = base64_encode(hex2bin(str_pad(gmp_strval($privateKeyObject->getSecret(), 16), 2 * self::PRIVATE_KEY_LENGTH, '0', STR_PAD_LEFT)));

return $vapid;
}
Expand Down
18 changes: 12 additions & 6 deletions src/WebPush.php
Original file line number Diff line number Diff line change
Expand Up @@ -73,13 +73,14 @@ public function __construct(array $auth = array(), $defaultOptions = array(), $t
* @param string|null $userAuthToken
* @param bool $flush If you want to flush directly (usually when you send only one notification)
* @param array $options Array with several options tied to this notification. If not set, will use the default options that you can set in the WebPush object
* @param array $auth Use this auth details instead of what you provided when creating WebPush
*
* @return array|bool Return an array of information if $flush is set to true and the queued requests has failed.
* Else return true
*
* @throws \ErrorException
*/
public function sendNotification($endpoint, $payload = null, $userPublicKey = null, $userAuthToken = null, $flush = false, $options = array())
public function sendNotification($endpoint, $payload = null, $userPublicKey = null, $userAuthToken = null, $flush = false, $options = array(), $auth = array())
{
if (isset($payload)) {
if (Utils::safeStrlen($payload) > Encryption::MAX_PAYLOAD_LENGTH) {
Expand All @@ -89,7 +90,11 @@ public function sendNotification($endpoint, $payload = null, $userPublicKey = nu
$payload = Encryption::padPayload($payload, $this->automaticPadding);
}

$this->notifications[] = new Notification($endpoint, $payload, $userPublicKey, $userAuthToken, $options);
if (array_key_exists('VAPID', $auth)) {
$auth['VAPID'] = VAPID::validate($auth['VAPID']);
}

$this->notifications[] = new Notification($endpoint, $payload, $userPublicKey, $userAuthToken, $options, $auth);

if ($flush) {
$res = $this->flush();
Expand Down Expand Up @@ -180,6 +185,7 @@ private function prepareAndSend(array $notifications)
$userPublicKey = $notification->getUserPublicKey();
$userAuthToken = $notification->getUserAuthToken();
$options = $notification->getOptions($this->getDefaultOptions());
$auth = $notification->getAuth($this->auth);

if (isset($payload) && isset($userPublicKey) && isset($userAuthToken)) {
$encrypted = Encryption::encrypt($payload, $userPublicKey, $userAuthToken, $this->nativePayloadEncryptionSupport);
Expand Down Expand Up @@ -213,15 +219,15 @@ private function prepareAndSend(array $notifications)

// if GCM
if (substr($endpoint, 0, strlen(self::GCM_URL)) === self::GCM_URL) {
if (array_key_exists('GCM', $this->auth)) {
$headers['Authorization'] = 'key='.$this->auth['GCM'];
if (array_key_exists('GCM', $auth)) {
$headers['Authorization'] = 'key='.$auth['GCM'];
} else {
throw new \ErrorException('No GCM API Key specified.');
}
}
// if VAPID (GCM doesn't support it but FCM does)
elseif (array_key_exists('VAPID', $this->auth)) {
$vapid = $this->auth['VAPID'];
elseif (array_key_exists('VAPID', $auth)) {
$vapid = $auth['VAPID'];

$audience = parse_url($endpoint, PHP_URL_SCHEME).'://'.parse_url($endpoint, PHP_URL_HOST);

Expand Down

0 comments on commit 07bd808

Please sign in to comment.