Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 27b265eaf5 | |||
| 3571bb6f6d | |||
| b037434e89 | |||
| ad14499df0 |
+12
-6
@@ -10373,21 +10373,26 @@ def my_borrowed_items():
|
||||
)
|
||||
|
||||
|
||||
@app.route('/api/push/vapid-key', methods=['GET'])
|
||||
def get_vapid_key():
|
||||
"""Returns the VAPID public key for web push subscriptions."""
|
||||
from Web.push_notifications import _get_vapid_public
|
||||
if not _get_vapid_public():
|
||||
return jsonify({'error': 'VAPID public key not configured'}), 500
|
||||
return jsonify({'publicKey': _get_vapid_public()})
|
||||
|
||||
@app.route('/notifications')
|
||||
def notifications_view():
|
||||
"""Notification center for users and admins."""
|
||||
from Web.push_notifications import _get_vapid_public
|
||||
if 'username' not in session:
|
||||
flash('Bitte melden Sie sich an, um Benachrichtigungen zu sehen.', 'error')
|
||||
return redirect(url_for('login'))
|
||||
|
||||
username = session['username']
|
||||
is_admin_user = False
|
||||
current_permissions = us.get_effective_permissions(session['username'])
|
||||
|
||||
if not current_permissions['actions'].get('can_manage_settings', False):
|
||||
is_admin_user = True
|
||||
else:
|
||||
is_admin_user = False
|
||||
|
||||
is_admin_user = current_permissions['actions'].get('can_manage_settings', False)
|
||||
|
||||
client = None
|
||||
try:
|
||||
@@ -10421,6 +10426,7 @@ def notifications_view():
|
||||
is_admin_user=is_admin_user,
|
||||
library_module_enabled=cfg.MODULES.is_enabled('library'),
|
||||
student_cards_module_enabled=cfg.MODULES.is_enabled('student_cards'),
|
||||
vapid_public_key=_get_vapid_public()
|
||||
)
|
||||
except Exception as exc:
|
||||
app.logger.error(f"Error loading notifications: {exc}")
|
||||
|
||||
@@ -300,7 +300,7 @@ def _match_student_cards(path):
|
||||
|
||||
def _match_mail(path):
|
||||
if not path: return False
|
||||
return path.startswith(('/'))
|
||||
return path.startswith(('/configure'))
|
||||
|
||||
# Register core modules into the pipeline
|
||||
MODULES.register('inventory', INVENTORY_MODULE_ENABLED, _match_inventory)
|
||||
|
||||
+34
-25
@@ -20,40 +20,49 @@ logger = logging.getLogger(__name__)
|
||||
# VAPID keys for push notifications
|
||||
VAPID_PUBLIC_KEY = os.getenv('VAPID_PUBLIC_KEY', '')
|
||||
VAPID_PRIVATE_KEY = os.getenv('VAPID_PRIVATE_KEY', '')
|
||||
VAPID_SUBJECT = os.getenv('VAPID_SUBJECT', f'mailto:admin@{os.getenv("SERVER_NAME", "localhost")}')
|
||||
VAPID_SUBJECT = os.getenv('VAPID_SUBJECT', f'mailto:support@invario-software.de')
|
||||
|
||||
# VAPID keys file paths
|
||||
VAPID_PRIVATE_PEM = os.path.join(os.path.dirname(__file__), 'vapid_private.pem')
|
||||
VAPID_PUBLIC_PEM = os.path.join(os.path.dirname(__file__), 'vapid_public.pem')
|
||||
|
||||
# Auto-generate VAPID keys if none are provided
|
||||
if not VAPID_PUBLIC_KEY or not VAPID_PRIVATE_KEY:
|
||||
try:
|
||||
from py_vapid import Vapid, b64urlencode
|
||||
from cryptography.hazmat.primitives import serialization
|
||||
|
||||
# Load or auto-generate VAPID keys
|
||||
try:
|
||||
from py_vapid import Vapid, b64urlencode
|
||||
from cryptography.hazmat.primitives import serialization
|
||||
|
||||
if not os.path.exists(VAPID_PRIVATE_PEM) or not os.path.exists(VAPID_PUBLIC_PEM):
|
||||
vapid = Vapid()
|
||||
if not os.path.exists(VAPID_PRIVATE_PEM):
|
||||
vapid.generate_keys()
|
||||
vapid.save_key(VAPID_PRIVATE_PEM)
|
||||
vapid.save_public_key(VAPID_PUBLIC_PEM)
|
||||
logger.info("Auto-generated new VAPID keys")
|
||||
else:
|
||||
vapid = Vapid.from_file(VAPID_PRIVATE_PEM)
|
||||
|
||||
raw_pub = vapid.public_key.public_bytes(
|
||||
serialization.Encoding.X962,
|
||||
serialization.PublicFormat.UncompressedPoint
|
||||
)
|
||||
|
||||
VAPID_PUBLIC_KEY = b64urlencode(raw_pub).decode('utf-8')
|
||||
VAPID_PRIVATE_KEY = VAPID_PRIVATE_PEM
|
||||
except Exception as e:
|
||||
logger.error(f'Could not load or generate VAPID keys: {e}')
|
||||
vapid.generate_keys()
|
||||
vapid.save_key(VAPID_PRIVATE_PEM)
|
||||
vapid.save_public_key(VAPID_PUBLIC_PEM)
|
||||
logger.info("Auto-generated new VAPID keys")
|
||||
else:
|
||||
vapid = Vapid.from_file(VAPID_PRIVATE_PEM)
|
||||
|
||||
# Extract public key in standard uncompressed point format encoded in URL-safe base64
|
||||
raw_pub = vapid.public_key.public_bytes(
|
||||
serialization.Encoding.X962,
|
||||
serialization.PublicFormat.UncompressedPoint
|
||||
)
|
||||
|
||||
VAPID_PUBLIC_KEY = b64urlencode(raw_pub).decode('utf-8')
|
||||
VAPID_PRIVATE_KEY = VAPID_PRIVATE_PEM # pywebpush accepts the file path to the private PEM
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f'Could not load or generate VAPID keys: {e}')
|
||||
VAPID_PUBLIC_KEY = os.getenv('VAPID_PUBLIC_KEY', '')
|
||||
VAPID_PRIVATE_KEY = os.getenv('VAPID_PRIVATE_KEY', '')
|
||||
|
||||
VAPID_SUBJECT = os.getenv('VAPID_SUBJECT', 'mailto:support@invario-software.de')
|
||||
|
||||
# Push service endpoint (typically Firebase or Web Push Service)
|
||||
FCM_API_KEY = os.getenv('FCM_API_KEY', '') # Firebase API key
|
||||
FCM_API_KEY = os.getenv('FCM_API_KEY', '')
|
||||
|
||||
|
||||
def _get_vapid_public():
|
||||
return VAPID_PUBLIC_KEY
|
||||
|
||||
def _get_username_hash(username):
|
||||
"""Generates a deterministic hash for database lookups."""
|
||||
if not username:
|
||||
|
||||
@@ -324,7 +324,7 @@ const pushNotificationManager = new PushNotificationManager();
|
||||
/**
|
||||
* Show notification subscription UI (typically in settings)
|
||||
*/
|
||||
function showPushNotificationSettings() {
|
||||
function showPushNotificationSettings(vapidPublicKey) {
|
||||
const container = document.getElementById('push-notification-settings');
|
||||
if (!container) return;
|
||||
|
||||
@@ -350,9 +350,9 @@ function showPushNotificationSettings() {
|
||||
|
||||
container.innerHTML = html;
|
||||
|
||||
// Set up button handler
|
||||
// Set up button handler and pass the VAPID public key to init()
|
||||
const toggleBtn = document.getElementById('toggle-push-btn');
|
||||
pushNotificationManager.init().then(() => {
|
||||
pushNotificationManager.init(vapidPublicKey).then(() => {
|
||||
updatePushStatus();
|
||||
});
|
||||
|
||||
|
||||
@@ -1371,8 +1371,8 @@
|
||||
await loadLibraryItems(); // Daten neu laden
|
||||
// renderTable(); // Ggf. Tabelle neu rendern
|
||||
} else {
|
||||
closeEditLibraryModal();
|
||||
await loadLibraryItems();
|
||||
closeEditLibraryModal();
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Update failed:', error);
|
||||
|
||||
@@ -89,7 +89,7 @@
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
if (typeof showPushNotificationSettings === 'function') {
|
||||
showPushNotificationSettings();
|
||||
showPushNotificationSettings('{{ vapid_public_key }}');
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user