| 
						
						
							
								
							
						
						
					 | 
				
				 | 
				
					@ -22,8 +22,37 @@ BROWSER visits a website which has a SERVICE. | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					The SERVICE asks BROWSER for its permission to subscribe to messages coming | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					from the SERVICE. | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					The BROWSER receives a data structure from SERVICE called a VAPID (Voluntary | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					Application Server Identification). | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					Provide context and obtain explicit permission before prompting for notification permission: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					It is recommended to set up to a two-step opt-in process where the user is first presented | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					with a pre-permission dialog box that explains what the notifications are for and why they | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					are useful. This may help reduce the possibility of users clicking "don't allow. | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					In Typescript, we can activate a browser's permission dialogue in this manner: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					function askPermission(): Promise<NotificationPermission> { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  return new Promise(function(resolve, reject) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    const permissionResult = Notification.requestPermission(function(result) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      resolve(result); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    }); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    if (permissionResult) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      permissionResult.then(resolve, reject); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  }).then(function(permissionResult) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    if (permissionResult !== 'granted') { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      throw new Error("We weren't granted permission."); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    return permissionResult; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  }); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					If the user grants permission, the client application registers a service worker using | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					the ServiceWorkerRegistration API. | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					<Add Service Worker Notes> | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					In the next step, BROWSER requests a data structure from SERVICE called a VAPID (Voluntary | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					Application Server Identification) which is the public key from a key-pair. | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					The VAPID is a specification used to identify the application server (i.e. the SERVICE | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					server) that is sending push messages to a push service. It's an authentication | 
				
			
			
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
				 | 
				
					@ -34,8 +63,55 @@ decrypting the messages coming from the SERVICE. | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					If the BROWSER accepts and grants permission to subscribe to receiving from the | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					SERVICE Web Push messages, then the BROWSER makes a subscription request to | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					PROVIDER which creates and stores a special URL for that BROWSER. The | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					PROVIDER sends this URL back to the BROWSER. The BROWSER will then use that | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					PROVIDER which creates and stores a special URL for that BROWSER. | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					const applicationServerKey = urlBase64ToUint8Array('BEl62iUYgUivxIkv69yViEuiBIa-Ib9-SkvMeAtA3LFgDzkrxZJjSgSnfckjBJuBkr3qBUYIHBQFLXYp5Nksh8U'); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					const options: PushSubscriptionOptions = { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  userVisibleOnly: true, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  applicationServerKey: applicationServerKey | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					}; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					registration.pushManager.subscribe(options) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  .then(function(subscription) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    console.log('Push subscription successful:', subscription); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  }) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  .catch(function(error) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    console.error('Push subscription failed:', error); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  }); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					In this example, the `applicationServerKey` variable contains the VAPID public key, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					which is converted to a Uint8Array using the `urlBase64ToUint8Array()` function from the | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					convert-vapid-public-key package. The options object is of type PushSubscriptionOptions, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					which includes the `userVisibleOnly` and `applicationServerKey` (ie VAPID public key) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					properties. The subscribe() method returns a `Promise` that resolves to a `PushSubscription` | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					object containing details of the subscription, such as the endpoint URL and the public key. | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					The VAPID (Voluntary Application Server Identification) key provides more security and | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					authenticity for web push notifications in the following ways: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    Identifying the Application Server: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					     | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        The VAPID key is used to identify the application server that is sending the push notifications. | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        This ensures that the push notifications are authentic and not sent by a malicious third party. | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    Encrypting the Messages: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					     | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        The VAPID key is used to sign the push notifications sent by the application server, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						ensuring that they are not tampered with during transmission. This provides an additional | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						layer of security and authenticity for the push notifications. | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					Adding Contact Information: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    The VAPID key allows a web application to add contact information to the push messages sent to the browser push service. | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    This enables the push service to contact the application server in case of need or provide additional debug information about the push messages. | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					Improving Delivery Rates: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    Using the VAPID key can help improve the overall performance of web push notifications, specifically improving delivery rates. | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    By streamlining the delivery process, the chance of delivery errors along the way is lessened. | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					The PROVIDER sends this URL back to the BROWSER. The BROWSER will then use that | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					URL to check for incoming messages by way of a special software named a "service | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					worker". The BROWSER also sends this URL back to SERVICE which will use that | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					URL to send messages to the BROWSER via the PROVIDER. | 
				
			
			
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
				 | 
				
					@ -53,6 +129,7 @@ mobile application (in our case a PWA) must be added to the Home Screen and | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					permissions must be explicitly granted that allow the application to receive push | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					notifications. Further, with an iOS device the user must enable wake on notification to | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					have their device light-up when it receives a notification (https://support.apple.com/enus/HT208081). | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					So what about #4? - The INTERMEDIARY. Well, It is possible under very special | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					circumstances to create your own Web Push PROVIDER. The only case I've found so | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					far relates to making an Android Custom ROM. (An Android Custom ROM is a | 
				
			
			
		
	
	
		
			
				
					| 
						
							
								
							
						
						
						
					 | 
				
				 | 
				
					
  |