@@ -127,8 +127,12 @@ suite('sendNotification', function() {
127127
128128 function validateRequest ( request ) {
129129 const options = request . requestOptions ;
130+ const contentEncoding = ( options . extraOptions && options . extraOptions . contentEncoding )
131+ || WebPushConstants . supportedContentEncodings . AES_GCM ;
130132 const isGCM = options . subscription . endpoint
131133 . indexOf ( 'https://android.googleapis.com/gcm' ) === 0 ;
134+ const isFCM = options . subscription . endpoint
135+ . indexOf ( 'https://fcm.googleapis.com/fcm' ) === 0 ;
132136
133137 assert . equal ( requestDetails . headers [ 'content-length' ] , requestBody . length , 'Check Content-Length header' ) ;
134138
@@ -152,10 +156,10 @@ suite('sendNotification', function() {
152156 return key . indexOf ( 'dh=' ) === 0 ;
153157 } ) . substring ( 'dh=' . length ) ;
154158
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' ) ;
156160
157161 const decrypted = ece . decrypt ( requestBody , {
158- version : options . extraOptions . contentEncoding ,
162+ version : contentEncoding ,
159163 privateKey : userCurve ,
160164 dh : appServerPublicKey ,
161165 salt : salt ,
@@ -166,29 +170,39 @@ suite('sendNotification', function() {
166170 }
167171
168172 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+ } ) ;
173181
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+ }
176193
177- assert ( appServerVapidPublicKey . equals ( vapidKeys . publicKey ) ) ;
194+ assert . equal ( vapidKey , vapidKeys . publicKey ) ;
178195
179- const authorizationHeader = requestDetails . headers . authorization ;
180- assert . equal ( authorizationHeader . indexOf ( 'WebPush ' ) , 0 , 'Check VAPID Authorization header' ) ;
181- const jwt = authorizationHeader . substring ( 'WebPush ' . length ) ;
182196 // 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] ' ) ; 189203 }
190204
191- if ( isGCM ) {
205+ if ( isGCM || ( isFCM && ! options . vapid ) ) {
192206 if ( typeof options . extraOptions !== 'undefined'
193207 && typeof options . extraOptions . gcmAPIKey !== 'undefined' ) {
194208 assert . equal ( requestDetails . headers . authorization , 'key=' + options . extraOptions . gcmAPIKey , 'Check GCM Authorization header' ) ;
@@ -398,6 +412,102 @@ suite('sendNotification', function() {
398412 subscription : {
399413 }
400414 }
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+ }
401511 } , {
402512 testTitle : 'send/receive string with GCM' ,
403513 requestOptions : {
@@ -465,8 +575,22 @@ suite('sendNotification', function() {
465575 validGCMRequest . requestOptions . subscription . endpoint = 'https://android.googleapis.com/gcm/send/someSubscriptionID' ;
466576 }
467577
578+ validGCMRequest . globalOptions = validGCMRequest . globalOptions || { } ;
579+ if ( validGCMRequest . globalOptions . gcmAPIKey === undefined ) {
580+ validGCMRequest . globalOptions . gcmAPIKey = 'my_gcm_key' ;
581+ }
582+
468583 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+ }
470594
471595 return webPush . sendNotification (
472596 validGCMRequest . requestOptions . subscription ,
0 commit comments