3 Commits

Author SHA1 Message Date
Renovate Bot
d9fa4ad5e5 chore(deps): update dependency typescript to v6
All checks were successful
CI / backend-tests (pull_request) Successful in 29s
CI / frontend-tests (pull_request) Successful in 29s
2026-03-23 17:04:52 +00:00
d8fec0e5d7 fix:add debugging endpoint for auth issues
All checks were successful
CI / backend-tests (push) Successful in 30s
CI / frontend-tests (push) Successful in 28s
2026-03-22 12:15:25 +01:00
c9b09b8250 fix: fix supabase auth url
All checks were successful
CI / backend-tests (push) Successful in 30s
CI / frontend-tests (push) Successful in 30s
2026-03-22 12:10:03 +01:00
4 changed files with 64 additions and 8 deletions

View File

@@ -1,6 +1,10 @@
from fastapi import APIRouter
import urllib.request
from fastapi import APIRouter, Request
from sqlalchemy import text
from app.core.auth import _build_jwks_url, _extract_token, _get_jwks_client
from app.core.config import settings
from app.core.database import async_session
router = APIRouter(tags=["health"])
@@ -23,3 +27,45 @@ async def health_check():
async def root():
"""Root endpoint."""
return {"message": "Nuzlocke Tracker API", "docs": "/docs"}
@router.get("/auth-debug")
async def auth_debug(request: Request):
"""Temporary diagnostic endpoint for auth debugging."""
result: dict = {}
# Config
result["supabase_url"] = settings.supabase_url
result["has_jwt_secret"] = bool(settings.supabase_jwt_secret)
result["jwks_url"] = (
_build_jwks_url(settings.supabase_url) if settings.supabase_url else None
)
# JWKS fetch
jwks_url = result["jwks_url"]
if jwks_url:
try:
with urllib.request.urlopen(jwks_url, timeout=5) as resp:
result["jwks_status"] = resp.status
result["jwks_body"] = resp.read().decode()
except Exception as e:
result["jwks_fetch_error"] = str(e)
# JWKS client
client = _get_jwks_client()
result["jwks_client_exists"] = client is not None
# Token info (header only, no secrets)
token = _extract_token(request)
if token:
import jwt
try:
header = jwt.get_unverified_header(token)
result["token_header"] = header
except Exception as e:
result["token_header_error"] = str(e)
else:
result["token"] = "not provided"
return result

View File

@@ -26,11 +26,21 @@ class AuthUser:
role: str | None = None
def _build_jwks_url(base_url: str) -> str:
"""Build the JWKS URL, adding /auth/v1 prefix for Supabase Cloud."""
base = base_url.rstrip("/")
if "/auth/v1" in base:
return f"{base}/.well-known/jwks.json"
# Supabase Cloud URLs need the /auth/v1 prefix;
# local GoTrue serves JWKS at root but uses HS256 fallback anyway.
return f"{base}/auth/v1/.well-known/jwks.json"
def _get_jwks_client() -> PyJWKClient | None:
"""Get or create a cached JWKS client."""
global _jwks_client
if _jwks_client is None and settings.supabase_url:
jwks_url = f"{settings.supabase_url.rstrip('/')}/.well-known/jwks.json"
jwks_url = _build_jwks_url(settings.supabase_url)
_jwks_client = PyJWKClient(jwks_url, cache_jwk_set=True, lifespan=300)
return _jwks_client
@@ -80,7 +90,7 @@ def _verify_jwt(token: str) -> dict | None:
except PyJWKSetError as e:
logger.warning("JWKS set error: %s", e)
else:
logger.debug("No JWKS client available (SUPABASE_URL not set?)")
logger.warning("No JWKS client available (SUPABASE_URL not set?)")
return _verify_jwt_hs256(token)

View File

@@ -36,7 +36,7 @@
"oxfmt": "0.41.0",
"oxlint": "1.56.0",
"tailwindcss": "4.2.2",
"typescript": "5.9.3",
"typescript": "6.0.2",
"vite": "8.0.1",
"vitest": "4.1.0"
}
@@ -4828,9 +4828,9 @@
"license": "0BSD"
},
"node_modules/typescript": {
"version": "5.9.3",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz",
"integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-6.0.2.tgz",
"integrity": "sha512-bGdAIrZ0wiGDo5l8c++HWtbaNCWTS4UTv7RaTH/ThVIgjkveJt83m74bBHMJkuCbslY8ixgLBVZJIOiQlQTjfQ==",
"dev": true,
"license": "Apache-2.0",
"bin": {

View File

@@ -44,7 +44,7 @@
"oxfmt": "0.41.0",
"oxlint": "1.56.0",
"tailwindcss": "4.2.2",
"typescript": "5.9.3",
"typescript": "6.0.2",
"vite": "8.0.1",
"vitest": "4.1.0"
}