Skip to content

Commit eb248d3

Browse files
committed
feat: improve VAPID config doc and type hints
1 parent a368e42 commit eb248d3

3 files changed

Lines changed: 34 additions & 10 deletions

File tree

README.md

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -144,11 +144,17 @@ use Minishlink\WebPush\WebPush;
144144
$endpoint = 'https://fcm.googleapis.com/fcm/send/abcdef...'; // Chrome
145145

146146
$auth = [
147-
'VAPID' => [
147+
'VAPID' => [ // Recommended.
148+
'subject' => 'mailto:me@website.com', // can be a mailto: or your website address
149+
'publicKey' => '~88 chars', // uncompressed public key P-256 encoded in Base64-URL
150+
'privateKey' => '~44 chars', // in fact the secret multiplier of the private key encoded in Base64-URL
151+
],
152+
'VAPID' => [ // Alternative 1.
148153
'subject' => 'mailto:me@website.com', // can be a mailto: or your website address
149-
'publicKey' => '~88 chars', // (recommended) uncompressed public key P-256 encoded in Base64-URL
150-
'privateKey' => '~44 chars', // (recommended) in fact the secret multiplier of the private key encoded in Base64-URL
151154
'pemFile' => 'path/to/pem', // if you have a PEM file and can link to it on your filesystem
155+
],
156+
'VAPID' => [ // Alternative 2.
157+
'subject' => 'mailto:me@website.com', // can be a mailto: or your website address
152158
'pem' => 'pemFileContent', // if you have a PEM file and want to hardcode its content
153159
],
154160
];

phpstan.neon

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ parameters:
33
paths:
44
- src
55
reportUnmatchedIgnoredErrors: false
6+
treatPhpDocTypesAsCertain: false
67
ignoreErrors:
78
- identifier: missingType.iterableValue
89
strictRules:

src/VAPID.php

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,30 @@
1818
use Jose\Component\Signature\JWSBuilder;
1919
use Jose\Component\Signature\Serializer\CompactSerializer;
2020

21+
/**
22+
* @phpstan-type VapidConfig array{
23+
* subject: string,
24+
* publicKey: string, // ~88 chars Base64URL
25+
* privateKey: string // ~44 chars Base64URL
26+
* }
27+
* @phpstan-type VapidPemFileConfig array{
28+
* subject: string,
29+
* pemFile: string // path/to/pem
30+
* }
31+
* @phpstan-type VapidPemConfig array{
32+
* subject: string,
33+
* pem: string // PEM file content
34+
* }
35+
* @phpstan-type InputVapidConfig VapidConfig|VapidPemFileConfig|VapidPemConfig
36+
*/
2137
class VAPID
2238
{
2339
private const PUBLIC_KEY_LENGTH = 65;
2440
private const PRIVATE_KEY_LENGTH = 32;
2541

2642
/**
43+
* @param InputVapidConfig $vapid
44+
* @return VapidConfig
2745
* @throws \ErrorException
2846
*/
2947
public static function validate(array $vapid): array
@@ -36,19 +54,19 @@ public static function validate(array $vapid): array
3654
$vapid['pem'] = file_get_contents($vapid['pemFile']);
3755

3856
if (!$vapid['pem']) {
39-
throw new \ErrorException('Error loading PEM file.');
57+
throw new \ErrorException('[VAPID] Error loading PEM file.');
4058
}
4159
}
4260

4361
if (isset($vapid['pem'])) {
4462
$jwk = JWKFactory::createFromKey($vapid['pem']);
4563
if ($jwk->get('kty') !== 'EC' || !$jwk->has('d') || !$jwk->has('x') || !$jwk->has('y')) {
46-
throw new \ErrorException('Invalid PEM data.');
64+
throw new \ErrorException('[VAPID] Invalid PEM data.');
4765
}
4866

4967
$binaryPublicKey = hex2bin(Utils::serializePublicKeyFromJWK($jwk));
5068
if (!$binaryPublicKey) {
51-
throw new \ErrorException('Failed to convert VAPID public key from hexadecimal to binary');
69+
throw new \ErrorException('[VAPID] Failed to convert VAPID public key from hexadecimal to binary.');
5270
}
5371
$vapid['publicKey'] = base64_encode($binaryPublicKey);
5472
$vapid['privateKey'] = base64_encode(str_pad(Base64Url::decode($jwk->get('d')), self::PRIVATE_KEY_LENGTH, '0', STR_PAD_LEFT));
@@ -113,7 +131,6 @@ public static function getVapidHeaders(
113131
'alg' => 'ES256',
114132
];
115133

116-
117134
try {
118135
$jwtPayload = json_encode(
119136
[
@@ -161,7 +178,7 @@ public static function getVapidHeaders(
161178
}
162179

163180
// @phpstan-ignore deadCode.unreachable
164-
throw new \ErrorException('This content encoding is not supported');
181+
throw new \ErrorException('This content encoding is not supported.');
165182
}
166183

167184
/**
@@ -176,12 +193,12 @@ public static function createVapidKeys(): array
176193

177194
$binaryPublicKey = hex2bin(Utils::serializePublicKeyFromJWK($jwk));
178195
if (!$binaryPublicKey) {
179-
throw new \ErrorException('Failed to convert VAPID public key from hexadecimal to binary');
196+
throw new \ErrorException('Failed to convert VAPID public key from hexadecimal to binary.');
180197
}
181198

182199
$binaryPrivateKey = hex2bin(str_pad(bin2hex(Base64Url::decode($jwk->get('d'))), 2 * self::PRIVATE_KEY_LENGTH, '0', STR_PAD_LEFT));
183200
if (!$binaryPrivateKey) {
184-
throw new \ErrorException('Failed to convert VAPID private key from hexadecimal to binary');
201+
throw new \ErrorException('Failed to convert VAPID private key from hexadecimal to binary.');
185202
}
186203

187204
return [

0 commit comments

Comments
 (0)