]> littlesong.place Git - littlesongplace.git/commitdiff
Use VAPID keys for push notifications
authorChris Fulljames <christianfulljames@gmail.com>
Fri, 23 May 2025 10:50:38 +0000 (06:50 -0400)
committerChris Fulljames <christianfulljames@gmail.com>
Sat, 23 Aug 2025 11:30:17 +0000 (07:30 -0400)
src/littlesongplace/datadir.py
src/littlesongplace/push_notifications.py
src/littlesongplace/static/service.js

index 1d98c52f7b33224ca6658e2f3e1e3ae026b8b699..27d5254465316b7c14b1ab9df216634c4fc7bd94 100644 (file)
@@ -28,3 +28,6 @@ def get_user_images_path(userid):
 def get_app_log_path():
     return _data_dir / "app.log"
 
+def get_vapid_private_key_path():
+    return _data_dir / "vapid-private.key"
+
index 5c4c51e71eeb59855ceed14a3db7099a7f43c939..1dd87c8ee7c0feb05f4382e665b8c5009e2e1038 100644 (file)
@@ -4,7 +4,7 @@ import threading
 import pywebpush
 from flask import Blueprint, current_app, g, request
 
-from . import auth, db
+from . import auth, datadir, db
 
 bp = Blueprint("push-notifications", __name__, url_prefix="/push-notifications")
 
@@ -63,14 +63,25 @@ def notify(userids, title, body):
 def _do_push(app, userids, title, body):
     data = {"title": title, "body": body}
     data_str = json.dumps(data)
+
+    private_key_path = datadir.get_vapid_private_key_path()
+    claims = {"sub": "mailto:littlesongplace@gmail.com"}
+    private_key = None
+    if private_key_path.exists():
+        with open(private_key_path, "r") as private_key_file:
+            private_key = private_key_file.read().strip()
+
     sent_notifications = 0
     with app.app_context():
         for userid in userids:
             subs = get_user_subscriptions(userid)
             for subid, sub in subs:
                 try:
-                    # TODO: Use VAPID keys
-                    pywebpush.webpush(sub, data_str)
+                    if private_key:
+                        pywebpush.webpush(sub, data_str, vapid_private_key=private_key, vapid_claims=claims)
+                    else:
+                        pywebpush.webpush(sub, data_str)
+
                     sent_notifications += 1
                 except pywebpush.WebPushException as ex:
                     if ex.response.status_code == 410:  # Subscription deleted
index fc2590333b6dbd892341e6d3512c43ce567a32d3..17bee8da553d4aa7668e48b58088b3c8636bd11f 100644 (file)
@@ -1,9 +1,13 @@
+const vapid_public_key = "BLsO37LostwqKch7SFr5Df0MexEoBOcujdMRY7wJurRPc_MGdz9rAkMrqs_dil4qSFxVbVyAA3FqLEPSL-WRNZs";
+
 self.addEventListener("activate", async () => {
     try {
-        // TODO: Use VAPID key
-        const options = {};
+        // Subscribe via browser's push service
+        const options = {userVisibleOnly: true, applicationServerKey: vapid_public_key};
         const subscription = await self.registration.pushManager.subscribe(options);
         console.log(JSON.stringify(subscription));
+
+        // Register subscription with LSP server
         const response = await fetch(
             "/push-notifications/subscribe", {
                 method: "post",
@@ -16,7 +20,6 @@ self.addEventListener("activate", async () => {
     catch (err) {
         console.log("Error while activating service:", err);
     }
-
 });
 
 self.addEventListener("push", (event) => {