FEATURE: Generate new VAPID keys when base_url changes

FEATURE: Generate new VAPID keys when base_url changes

This is useful when a backup is restored on a staging site or in a development environment. It also deletes all existing push subscriptions because they get invalid when the keys change.

diff --git a/config/initializers/100-push-notifications.rb b/config/initializers/100-push-notifications.rb
index ab8e44a..3375823 100644
--- a/config/initializers/100-push-notifications.rb
+++ b/config/initializers/100-push-notifications.rb
@@ -4,13 +4,25 @@ return if GlobalSetting.skip_db?
 
 require_dependency 'webpush'
 
-if SiteSetting.vapid_public_key.blank? || SiteSetting.vapid_private_key.blank? || SiteSetting.vapid_public_key_bytes.blank?
+def generate_vapid_key?
+  SiteSetting.vapid_public_key.blank? ||
+    SiteSetting.vapid_private_key.blank? ||
+    SiteSetting.vapid_public_key_bytes.blank? ||
+    SiteSetting.vapid_base_url != Discourse.base_url
+end
+
+SiteSetting.vapid_base_url = Discourse.base_url if SiteSetting.vapid_base_url.blank?
+
+if generate_vapid_key?
   vapid_key = Webpush.generate_key
   SiteSetting.vapid_public_key = vapid_key.public_key
   SiteSetting.vapid_private_key = vapid_key.private_key
-end
 
-SiteSetting.vapid_public_key_bytes = Base64.urlsafe_decode64(SiteSetting.vapid_public_key).bytes.join("|")
+  SiteSetting.vapid_public_key_bytes = Base64.urlsafe_decode64(SiteSetting.vapid_public_key).bytes.join("|")
+  SiteSetting.vapid_base_url = Discourse.base_url
+
+  PushSubscription.delete_all
+end
 
 DiscourseEvent.on(:user_logged_out) do |user|
   PushNotificationPusher.clear_subscriptions(user)
diff --git a/config/site_settings.yml b/config/site_settings.yml
index 4c68601..5535315 100644
--- a/config/site_settings.yml
+++ b/config/site_settings.yml
@@ -307,6 +307,9 @@ basic:
   vapid_private_key:
     default: ""
     hidden: true
+  vapid_base_url:
+    default: ""
+    hidden: true
 
 login:
   invite_only:

GitHub sha: 94607a2f

1 Like

FIX: Make initializer work on first db:migrate