Игорь Надеин 44488cb40e feat: Implement Web Push notifications with VAPID
- Split notification sending into separate WebSocket and Web Push channels
- Add Web Push support for offline users
- Configure VAPID keys for push authentication
- Add 'aud' field to VAPID claims for WNS compatibility
- Optimize subscription sync - only POST when endpoint changes
- Remove debug logs and minimize server logging
- Update Service Worker with improved error handling
- Add Service-Worker-Allowed header for proper scope

Web Push now works independently from WebSocket, enabling
notifications when browser is closed (requires HTTPS in production)
2026-01-06 07:48:04 +03:00

43 lines
2.1 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

from django.conf import settings
from django.conf.urls.static import static
from django.contrib import admin
from django.urls import include, path
from django.http import FileResponse
import os
def serve_service_worker(request):
"""Обслуживает Service Worker с правильным content-type и заголовками"""
sw_path = os.path.join(settings.BASE_DIR, 'sw.js')
try:
response = FileResponse(
open(sw_path, 'rb'),
content_type='application/javascript; charset=utf-8',
status=200
)
# Отключаем кэширование для sw.js (всегда получаем свежую версию)
response['Cache-Control'] = 'no-cache, no-store, must-revalidate'
response['Pragma'] = 'no-cache'
response['Expires'] = '0'
# Service-Worker-Allowed позволяет контролировать весь домен
response['Service-Worker-Allowed'] = '/'
return response
except Exception as e:
from django.http import HttpResponse
return HttpResponse(f"Service Worker not found: {e}", status=500)
urlpatterns = [
path("admin/", admin.site.urls),
path("auth/", include("employees.urls_front_auth", namespace="auth_front")),
path("documents/", include("documents.urls", namespace="documents")),
path("requests/", include("requests_app.urls", namespace="requests")),
path("employees/", include("employees.urls_front", namespace="employees")),
path("communications/", include("communications.urls", namespace="communications")),
path("notifications/", include("notifications.urls", namespace="notifications")),
path("search/", include("search.urls", namespace="search")),
path("finance/", include("finance.urls", namespace="finance")),
path("api/", include(("api.urls", "api"), namespace="api")),
# Service Worker должен быть в корне для правильного scope
path("sw.js", serve_service_worker, name="sw"),
path("", include("feed.urls_front", namespace="feed")),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)