@@ -127,8 +127,12 @@ suite('sendNotification', function() {
127
127
128
128
function validateRequest ( request ) {
129
129
const options = request . requestOptions ;
130
+ const contentEncoding = ( options . extraOptions && options . extraOptions . contentEncoding )
131
+ || WebPushConstants . supportedContentEncodings . AES_GCM ;
130
132
const isGCM = options . subscription . endpoint
131
133
. indexOf ( 'https://android.googleapis.com/gcm' ) === 0 ;
134
+ const isFCM = options . subscription . endpoint
135
+ . indexOf ( 'https://fcm.googleapis.com/fcm' ) === 0 ;
132
136
133
137
assert . equal ( requestDetails . headers [ 'content-length' ] , requestBody . length , 'Check Content-Length header' ) ;
134
138
@@ -152,10 +156,10 @@ suite('sendNotification', function() {
152
156
return key . indexOf ( 'dh=' ) === 0 ;
153
157
} ) . substring ( 'dh=' . length ) ;
154
158
155
- assert . equal ( requestDetails . headers [ 'content-encoding' ] , options . extraOptions . contentEncoding , 'Check Content-Encoding header' ) ;
159
+ assert . equal ( requestDetails . headers [ 'content-encoding' ] , contentEncoding , 'Check Content-Encoding header' ) ;
156
160
157
161
const decrypted = ece . decrypt ( requestBody , {
158
- version : options . extraOptions . contentEncoding ,
162
+ version : contentEncoding ,
159
163
privateKey : userCurve ,
160
164
dh : appServerPublicKey ,
161
165
salt : salt ,
@@ -166,29 +170,39 @@ suite('sendNotification', function() {
166
170
}
167
171
168
172
if ( options . vapid ) {
169
- const keys = requestDetails . headers [ 'crypto-key' ] . split ( ';' ) ;
170
- const vapidKey = keys . find ( function ( key ) {
171
- return key . indexOf ( 'p256ecdsa=' ) === 0 ;
172
- } ) ;
173
+ let jwt ;
174
+ let vapidKey ;
175
+
176
+ if ( contentEncoding === WebPushConstants . supportedContentEncodings . AES_GCM ) {
177
+ const keys = requestDetails . headers [ 'crypto-key' ] . split ( ';' ) ;
178
+ const vapidKeyHeader = keys . find ( function ( key ) {
179
+ return key . indexOf ( 'p256ecdsa=' ) === 0 ;
180
+ } ) ;
173
181
174
- assert . equal ( vapidKey . indexOf ( 'p256ecdsa=' ) , 0 , 'Crypto-Key header correct' ) ;
175
- const appServerVapidPublicKey = urlBase64 . decode ( vapidKey . substring ( 'p256ecdsa=' . length ) ) ;
182
+ assert . equal ( vapidKeyHeader . indexOf ( 'p256ecdsa=' ) , 0 , 'Crypto-Key header correct' ) ;
183
+ vapidKey = vapidKeyHeader . substring ( 'p256ecdsa=' . length ) ;
184
+
185
+ const authorizationHeader = requestDetails . headers . authorization ;
186
+ assert . equal ( authorizationHeader . indexOf ( 'WebPush ' ) , 0 , 'Check VAPID Authorization header' ) ;
187
+ jwt = authorizationHeader . substring ( 'WebPush ' . length ) ;
188
+ } else if ( contentEncoding === WebPushConstants . supportedContentEncodings . AES_128_GCM ) {
189
+ const authorizationHeader = requestDetails . headers . authorization ;
190
+ assert . equal ( authorizationHeader . indexOf ( 'vapid t=' ) , 0 , 'Check VAPID Authorization header' ) ;
191
+ [ jwt , vapidKey ] = authorizationHeader . substring ( 'vapid t=' . length ) . split ( ', k=' ) ;
192
+ }
176
193
177
- assert ( appServerVapidPublicKey . equals ( vapidKeys . publicKey ) ) ;
194
+ assert . equal ( vapidKey , vapidKeys . publicKey ) ;
178
195
179
- const authorizationHeader = requestDetails . headers . authorization ;
180
- assert . equal ( authorizationHeader . indexOf ( 'WebPush ' ) , 0 , 'Check VAPID Authorization header' ) ;
181
- const jwt = authorizationHeader . substring ( 'WebPush ' . length ) ;
182
196
// assert(jws.verify(jwt, 'ES256', appServerVapidPublicKey)), 'JWT valid');
183
- const decoded = jws . decode ( jwt ) ;
184
- assert . equal ( decoded . header . typ , 'JWT' ) ;
185
- assert . equal ( decoded . header . alg , 'ES256' ) ;
186
- assert . equal ( decoded . payload . aud , 'https://127.0.0.1' ) ;
187
- assert ( decoded . payload . exp > Date . now ( ) / 1000 ) ;
188
- assert . equal ( decoded . payload . sub , 'mailto:[email protected] ' ) ;
197
+ const decoded = jws . decode ( jwt ) ;
198
+ assert . equal ( decoded . header . typ , 'JWT' ) ;
199
+ assert . equal ( decoded . header . alg , 'ES256' ) ;
200
+ assert . equal ( options . subscription . endpoint . startsWith ( decoded . payload . aud ) , true ) ;
201
+ assert ( decoded . payload . exp > Date . now ( ) / 1000 ) ;
202
+ assert . equal ( decoded . payload . sub , 'mailto:[email protected] ' ) ;
189
203
}
190
204
191
- if ( isGCM ) {
205
+ if ( isGCM || ( isFCM && ! options . vapid ) ) {
192
206
if ( typeof options . extraOptions !== 'undefined'
193
207
&& typeof options . extraOptions . gcmAPIKey !== 'undefined' ) {
194
208
assert . equal ( requestDetails . headers . authorization , 'key=' + options . extraOptions . gcmAPIKey , 'Check GCM Authorization header' ) ;
@@ -398,6 +412,102 @@ suite('sendNotification', function() {
398
412
subscription : {
399
413
}
400
414
}
415
+ } , {
416
+ testTitle : 'send/receive FCM' ,
417
+ requestOptions : {
418
+ subscription : {
419
+ endpoint : 'https://fcm.googleapis.com/fcm/send/someSubscriptionID'
420
+ }
421
+ }
422
+ } , {
423
+ testTitle : 'send/receive FCM and you want to use VAPID (aesgcm)' ,
424
+ requestOptions : {
425
+ subscription : {
426
+ endpoint : 'https://fcm.googleapis.com/fcm/send/someSubscriptionID' ,
427
+ keys : VALID_KEYS
428
+ } ,
429
+ extraOptions : {
430
+ vapidDetails : {
431
+ subject :
'mailto:[email protected] ' ,
432
+ privateKey : vapidKeys . privateKey ,
433
+ publicKey : vapidKeys . publicKey
434
+ } ,
435
+ contentEncoding : WebPushConstants . supportedContentEncodings . AES_GCM
436
+ } ,
437
+ vapid : true
438
+ }
439
+ } , {
440
+ testTitle : 'send/receive FCM and you want to use VAPID (aesgcm) (via global options)' ,
441
+ requestOptions : {
442
+ subscription : {
443
+ endpoint : 'https://fcm.googleapis.com/fcm/send/someSubscriptionID' ,
444
+ keys : VALID_KEYS
445
+ } ,
446
+ extraOptions : {
447
+ contentEncoding : WebPushConstants . supportedContentEncodings . AES_GCM
448
+ } ,
449
+ vapid : true
450
+ } ,
451
+ globalOptions : {
452
+ vapidDetails : {
453
+ subject :
'mailto:[email protected] ' ,
454
+ privateKey : vapidKeys . privateKey ,
455
+ publicKey : vapidKeys . publicKey
456
+ }
457
+ }
458
+ } , {
459
+ testTitle : 'send/receive FCM and you want to use VAPID (aes128gcm)' ,
460
+ requestOptions : {
461
+ subscription : {
462
+ endpoint : 'https://fcm.googleapis.com/fcm/send/someSubscriptionID' ,
463
+ keys : VALID_KEYS
464
+ } ,
465
+ extraOptions : {
466
+ vapidDetails : {
467
+ subject :
'mailto:[email protected] ' ,
468
+ privateKey : vapidKeys . privateKey ,
469
+ publicKey : vapidKeys . publicKey
470
+ } ,
471
+ contentEncoding : WebPushConstants . supportedContentEncodings . AES_128_GCM
472
+ } ,
473
+ vapid : true
474
+ }
475
+ } , {
476
+ testTitle : 'send/receive FCM and you want to use VAPID (aes128gcm) (via global options)' ,
477
+ requestOptions : {
478
+ subscription : {
479
+ endpoint : 'https://fcm.googleapis.com/fcm/send/someSubscriptionID' ,
480
+ keys : VALID_KEYS
481
+ } ,
482
+ extraOptions : {
483
+ contentEncoding : WebPushConstants . supportedContentEncodings . AES_128_GCM
484
+ } ,
485
+ vapid : true
486
+ } ,
487
+ globalOptions : {
488
+ vapidDetails : {
489
+ subject :
'mailto:[email protected] ' ,
490
+ privateKey : vapidKeys . privateKey ,
491
+ publicKey : vapidKeys . publicKey
492
+ }
493
+ }
494
+ } , {
495
+ testTitle : 'send/receive FCM and you don\'t want to use VAPID (when global options set)' ,
496
+ requestOptions : {
497
+ subscription : {
498
+ endpoint : 'https://fcm.googleapis.com/fcm/send/someSubscriptionID'
499
+ } ,
500
+ extraOptions : {
501
+ vapidDetails : null
502
+ }
503
+ } ,
504
+ globalOptions : {
505
+ vapidDetails : {
506
+ subject :
'mailto:[email protected] ' ,
507
+ privateKey : vapidKeys . privateKey ,
508
+ publicKey : vapidKeys . publicKey
509
+ }
510
+ }
401
511
} , {
402
512
testTitle : 'send/receive string with GCM' ,
403
513
requestOptions : {
@@ -465,8 +575,22 @@ suite('sendNotification', function() {
465
575
validGCMRequest . requestOptions . subscription . endpoint = 'https://android.googleapis.com/gcm/send/someSubscriptionID' ;
466
576
}
467
577
578
+ validGCMRequest . globalOptions = validGCMRequest . globalOptions || { } ;
579
+ if ( validGCMRequest . globalOptions . gcmAPIKey === undefined ) {
580
+ validGCMRequest . globalOptions . gcmAPIKey = 'my_gcm_key' ;
581
+ }
582
+
468
583
const webPush = require ( '../src/index' ) ;
469
- webPush . setGCMAPIKey ( 'my_gcm_key' ) ;
584
+ if ( validGCMRequest . globalOptions . gcmAPIKey ) {
585
+ webPush . setGCMAPIKey ( validGCMRequest . globalOptions . gcmAPIKey ) ;
586
+ }
587
+ if ( validGCMRequest . globalOptions . vapidDetails ) {
588
+ webPush . setVapidDetails (
589
+ validGCMRequest . globalOptions . vapidDetails . subject ,
590
+ validGCMRequest . globalOptions . vapidDetails . publicKey ,
591
+ validGCMRequest . globalOptions . vapidDetails . privateKey
592
+ ) ;
593
+ }
470
594
471
595
return webPush . sendNotification (
472
596
validGCMRequest . requestOptions . subscription ,
0 commit comments