|
# retoor <retoor@molodetz.nl>
|
|
|
|
import logging
|
|
from fastapi import APIRouter, Request
|
|
from fastapi.responses import FileResponse, JSONResponse
|
|
from devplacepy import push
|
|
from devplacepy.config import STATIC_DIR
|
|
from devplacepy.utils import require_user_api
|
|
|
|
logger = logging.getLogger(__name__)
|
|
router = APIRouter()
|
|
|
|
WELCOME_PAYLOAD = {
|
|
"title": "DevPlace",
|
|
"message": "Push notifications enabled.",
|
|
"icon": "/static/apple-touch-icon.png",
|
|
"url": "/notifications",
|
|
}
|
|
|
|
|
|
@router.get("/push.json")
|
|
async def push_public_key() -> JSONResponse:
|
|
return JSONResponse({"publicKey": push.public_key_standard_b64()})
|
|
|
|
|
|
@router.post("/push.json")
|
|
async def push_register(request: Request) -> JSONResponse:
|
|
user = require_user_api(request)
|
|
try:
|
|
body = await request.json()
|
|
except ValueError:
|
|
return JSONResponse({"error": "Invalid JSON"}, status_code=400)
|
|
|
|
keys = body.get("keys") if isinstance(body, dict) else None
|
|
if not (isinstance(keys, dict) and body.get("endpoint") and keys.get("p256dh") and keys.get("auth")):
|
|
return JSONResponse({"error": "Invalid request"}, status_code=400)
|
|
|
|
_, created = await push.register(
|
|
user_uid=user["uid"],
|
|
endpoint=body["endpoint"],
|
|
key_auth=keys["auth"],
|
|
key_p256dh=keys["p256dh"],
|
|
)
|
|
|
|
if created:
|
|
try:
|
|
await push.notify_user(user["uid"], WELCOME_PAYLOAD)
|
|
except Exception as exc:
|
|
logger.warning("Welcome push failed for %s: %s", user["uid"], exc)
|
|
|
|
return JSONResponse({"registered": True})
|
|
|
|
|
|
@router.get("/service-worker.js")
|
|
async def service_worker() -> FileResponse:
|
|
return FileResponse(
|
|
STATIC_DIR / "service-worker.js",
|
|
media_type="application/javascript",
|
|
headers={"Service-Worker-Allowed": "/", "Cache-Control": "no-cache"},
|
|
)
|
|
|
|
|
|
@router.get("/manifest.json")
|
|
async def manifest() -> FileResponse:
|
|
return FileResponse(STATIC_DIR / "manifest.json", media_type="application/manifest+json")
|