From fc7f4f4b7a7128dde3c6cbd0309f67c1d7a95fd6 Mon Sep 17 00:00:00 2001 From: cpu Date: Wed, 26 Mar 2025 09:36:58 +0100 Subject: [PATCH] rewritten --- app.py | 35 +++++++++++++++++------------------ generate_vapid_keys.py | 14 ++++++-------- 2 files changed, 23 insertions(+), 26 deletions(-) diff --git a/app.py b/app.py index 82dc3dd..2f10324 100644 --- a/app.py +++ b/app.py @@ -73,21 +73,15 @@ class FlicButtonHandler: """Load and strictly validate VAPID private key.""" try: # Get and clean the key - env_key = os.getenv('VAPID_PRIVATE_KEY', '').strip().strip('"\'') + env_key = os.getenv('VAPID_PRIVATE_KEY', '').strip() - # Convert to clean PEM format - if '\\n' in env_key: - private_pem = env_key.replace('\\n', '\n') - else: - private_pem = env_key - - # Ensure proper PEM headers - if not private_pem.startswith('-----BEGIN PRIVATE KEY-----'): - private_pem = f"-----BEGIN PRIVATE KEY-----\n{private_pem}\n-----END PRIVATE KEY-----" - - # Strict validation + # Reconstruct PEM format if missing headers + if not env_key.startswith('-----BEGIN PRIVATE KEY-----'): + env_key = f"-----BEGIN PRIVATE KEY-----\n{env_key}\n-----END PRIVATE KEY-----" + + # Strict validation and key preparation key = serialization.load_pem_private_key( - private_pem.encode('utf-8'), + env_key.encode('utf-8'), password=None, backend=default_backend() ) @@ -124,14 +118,16 @@ class FlicButtonHandler: async def send_push_notification(self, subscription: Dict, message: str): try: - # Get endpoint base for aud claim + # Determine audience (aud) claim for VAPID endpoint = subscription['endpoint'] - aud = endpoint.split('/send')[0] if '/send' in endpoint else endpoint.split('/fcm/send')[0] + aud = (endpoint.split('/send')[0] if '/send' in endpoint + else endpoint.split('/fcm/send')[0]) logger.debug(f"Sending to: {endpoint[:50]}...") logger.debug(f"Using aud: {aud}") - webpush( + # Perform web push + result = webpush( subscription_info=subscription, data=message, vapid_private_key=self.vapid_private_key, @@ -145,6 +141,8 @@ class FlicButtonHandler: return True except Exception as e: logger.error(f"Push failed: {str(e)}") + logger.error(f"Endpoint details: {subscription['endpoint']}") + logger.error(f"Keys: {subscription.get('keys', 'No keys found')}") return False async def handle_button1(self): @@ -174,8 +172,9 @@ class FlicButtonHandler: success_count = 0 for subscription in self.subscriptions: try: - await self.send_push_notification(subscription, message) - success_count += 1 + success = await self.send_push_notification(subscription, message) + if success: + success_count += 1 except Exception as e: logger.error(f"Failed to send to {subscription['endpoint'][:30]}...: {str(e)}") diff --git a/generate_vapid_keys.py b/generate_vapid_keys.py index 43074f7..fa5ff2f 100644 --- a/generate_vapid_keys.py +++ b/generate_vapid_keys.py @@ -3,6 +3,7 @@ import os import base64 from cryptography.hazmat.primitives.asymmetric import ec from cryptography.hazmat.primitives import serialization +from cryptography.hazmat.backends import default_backend def generate_vapid_keys(): """ @@ -29,17 +30,17 @@ def generate_vapid_keys(): if need_new_keys: # Generate EC private key - private_key = ec.generate_private_key(ec.SECP256R1()) + private_key = ec.generate_private_key(ec.SECP256R1(), backend=default_backend()) - # Serialize private key to PEM format + # Serialize private key to PEM format, but keep it clean private_pem = private_key.private_bytes( encoding=serialization.Encoding.PEM, format=serialization.PrivateFormat.PKCS8, encryption_algorithm=serialization.NoEncryption() ).decode('utf-8') - # Format for .env file (replace newlines with \n) - env_private_key = private_pem.strip().replace('\n', '\\n') + # Clean up PEM formatting for .env file + private_pem_clean = private_pem.replace('-----BEGIN PRIVATE KEY-----\n', '').replace('\n-----END PRIVATE KEY-----\n', '').replace('\n', '') # Get public key public_key = private_key.public_key() @@ -49,15 +50,12 @@ def generate_vapid_keys(): ) # Store keys - env_vars['VAPID_PRIVATE_KEY'] = env_private_key # Single-line format + env_vars['VAPID_PRIVATE_KEY'] = private_pem_clean env_vars['VAPID_PUBLIC_KEY'] = base64.urlsafe_b64encode(public_key_bytes).decode('utf-8') print("New VAPID keys generated in .env-compatible format.") else: print("Existing VAPID keys found - no changes made.") - # Verify existing key format - if '-----BEGIN PRIVATE KEY-----' not in env_vars['VAPID_PRIVATE_KEY']: - print("Warning: Existing private key doesn't appear to be in PEM format!") # Ensure we have all required configuration variables with defaults if missing defaults = {