46 lines
1.6 KiB
Python
46 lines
1.6 KiB
Python
"""Scan-to-connect: the data and the QR a phone's camera opens."""
|
|
from __future__ import annotations
|
|
|
|
import io
|
|
|
|
from fastapi import APIRouter, Depends, Request
|
|
from fastapi.responses import Response
|
|
|
|
from ..auth import Ctx
|
|
from ..connect import build_base_urls, host_port
|
|
from ..deps import get_ctx
|
|
|
|
router = APIRouter()
|
|
|
|
|
|
@router.get("/v1/connect/info")
|
|
def connect_info(request: Request, ctx: Ctx = Depends(get_ctx)):
|
|
"""Admin: data for the "scan to connect" QR shown in the PWA settings tab."""
|
|
ctx.require_admin(request)
|
|
return {
|
|
"base_urls": build_base_urls(request),
|
|
"invite_code": ctx.cfg.invite_code,
|
|
}
|
|
|
|
|
|
@router.get("/v1/connect/qr")
|
|
def connect_qr(request: Request, ctx: Ctx = Depends(get_ctx), host: str | None = None):
|
|
"""Admin: the QR itself as SVG. `host` overrides the address (multi-NIC)."""
|
|
import segno
|
|
|
|
ctx.require_admin(request)
|
|
scheme = request.headers.get("x-forwarded-proto") or request.url.scheme
|
|
if host:
|
|
# explicit override replaces the address but keeps the deep-link path/port
|
|
_orig, port = host_port(request.headers.get("host"), scheme)
|
|
netloc = f"{host}:{port}" if port else host
|
|
base = f"{scheme}://{netloc}/app"
|
|
else:
|
|
bases = build_base_urls(request)
|
|
base = bases[0] if bases else "http://127.0.0.1:8000/app"
|
|
url = base + f"#invite={ctx.cfg.invite_code or ''}"
|
|
qr = segno.make(url, error="m")
|
|
buf = io.BytesIO()
|
|
qr.save(buf, kind="svg", scale=8, border=2, dark="#000000", light="#ffffff")
|
|
return Response(buf.getvalue(), media_type="image/svg+xml")
|