diff --git a/Code/Lib/Channel.php b/Code/Lib/Channel.php index 53f7e53a8..6ac121b2b 100644 --- a/Code/Lib/Channel.php +++ b/Code/Lib/Channel.php @@ -73,46 +73,6 @@ class Channel } } - public static function getVapidKey() - { - $private_key = openssl_pkey_new([ - 'private_key_type' => OPENSSL_KEYTYPE_EC, - 'curve_name' => 'prime256v1', - ]); - - $details = openssl_pkey_get_details($private_key); - $private_key_raw = $details['ec']['d']; - $public_key_raw = $details['ec']['x'] . $details['ec']['y']; - $auth_token = base64_encode(openssl_random_pseudo_bytes(16)); - - $vapid = [ - 'private_key' => rtrim(strtr(base64_encode($private_key_raw), '+/', '-_'), '='), - 'public_key' => rtrim(strtr(base64_encode($public_key_raw), '+/', '-_'), '='), - 'auth_token' => $auth_token, - ]; - - return json_encode($vapid); - } - - public static function getApplicationServerKey($vapid) - { - $publicKey = $vapid['public_key']; - $public_key_bytes = base64_decode($publicKey); - - // Check that the public key has the correct format - if (strlen($public_key_bytes) != 65 || ord($public_key_bytes[0]) != 4) { - // The public key has an incorrect format - // Handle the error here - } - - // Extract the x and y coordinates of the point - $x = substr($public_key_bytes, 1, 32); - $y = substr($public_key_bytes, 33, 32); - - // Pack the bytes of the public key in the correct order - $application_server_key = "\x04" . $x . $y; - return base64_encode($application_server_key); - } /** * @brief Create a system channel - which has no account attached. diff --git a/Code/Lib/System.php b/Code/Lib/System.php index f85e20a5e..7a7574081 100644 --- a/Code/Lib/System.php +++ b/Code/Lib/System.php @@ -136,4 +136,46 @@ class System return '0.0.0'; } + + public static function getVapidKey() + { + $private_key = openssl_pkey_new([ + 'private_key_type' => OPENSSL_KEYTYPE_EC, + 'curve_name' => 'prime256v1', + ]); + + $details = openssl_pkey_get_details($private_key); + $private_key_raw = $details['ec']['d']; + $public_key_raw = $details['ec']['x'] . $details['ec']['y']; + $auth_token = base64_encode(openssl_random_pseudo_bytes(16)); + + $vapid = [ + 'private_key' => rtrim(strtr(base64_encode($private_key_raw), '+/', '-_'), '='), + 'public_key' => rtrim(strtr(base64_encode($public_key_raw), '+/', '-_'), '='), + 'auth_token' => $auth_token, + ]; + + return json_encode($vapid); + } + + public static function getApplicationServerKey($vapid) + { + $publicKey = $vapid['public_key']; + $public_key_bytes = base64_decode($publicKey); + + // Check that the public key has the correct format + if (strlen($public_key_bytes) != 65 || ord($public_key_bytes[0]) != 4) { + // The public key has an incorrect format + // Handle the error here + } + + // Extract the x and y coordinates of the point + $x = substr($public_key_bytes, 1, 32); + $y = substr($public_key_bytes, 33, 32); + + // Pack the bytes of the public key in the correct order + $application_server_key = "\x04" . $x . $y; + return base64_encode($application_server_key); + } + } diff --git a/ServiceWorker.js b/ServiceWorker.js index 09d6137df..6aa5a55b6 100644 --- a/ServiceWorker.js +++ b/ServiceWorker.js @@ -7,3 +7,23 @@ self.addEventListener('fetch', function(e) { // nothing here yet }); + +self.addEventListener('push', function (event) { + if (!(self.Notification && self.Notification.permission === 'granted')) { + return; + } + + const sendNotification = body => { + // you could refresh a notification badge here with postMessage API + const title = ""; + + return self.registration.showNotification(title, { + body, + }); + }; + + if (event.data) { + const payload = event.data.json(); + event.waitUntil(sendNotification(payload.message)); + } +}); diff --git a/boot.php b/boot.php index efd3daecf..e0cf41777 100755 --- a/boot.php +++ b/boot.php @@ -909,6 +909,15 @@ function check_config() { check_cron_broken(); + // Ensure the site has a vapid (push-notification) keypair + $vapid = Config::Get('system','vapid'); + if (!$vapid) { + $vapid = System::getVapidKey(); + if ($vapid) { + Config::Set('system', 'vapid', $vapid); + } + } + } diff --git a/view/js/main.js b/view/js/main.js index b5f031973..2dc6c4709 100644 --- a/view/js/main.js +++ b/view/js/main.js @@ -32,6 +32,7 @@ let mode = ''; let update_url = ''; let update_mode = ''; let orgHeight = 0; +let serviceWorkerRegistration = false; $.ajaxPrefilter(function( options, original_Options, jqXHR ) { options.async = true; @@ -41,6 +42,7 @@ $.ajaxSetup({cache: false}); if ('serviceWorker' in navigator) { navigator.serviceWorker.register('/ServiceWorker.js', { scope: '/' }).then(function(registration) { console.log('Service worker registered. scope is', registration.scope); + serviceWorkerRegistration = registration; }).catch(function(error) { console.log('Service worker registration failed because ' + error); });