23 Commits

Author SHA1 Message Date
1af2e37a7f Merge pull request 'fix: add logging to debug auth issues' (#88) from develop into main
Reviewed-on: #88
2026-03-22 12:03:34 +01:00
5a9848fd5f Merge pull request 'develop' (#87) from develop into main
Reviewed-on: #87
2026-03-22 11:54:20 +01:00
712badb69d Merge pull request 'Release: MFA, JWKS auth, run ownership, and dependency updates' (#79) from develop into main
Reviewed-on: #79
2026-03-22 11:42:58 +01:00
c40dd38c99 Merge pull request 'update beans and postgres mount path' (#73) from develop into main
Reviewed-on: #73
2026-03-21 12:52:48 +01:00
98121d9954 Merge pull request 'Release: fix TypeScript build errors blocking deploy' (#72) from develop into main
Reviewed-on: #72
2026-03-21 12:27:49 +01:00
f340f8fd0d Merge pull request 'Release: auth system, admin RBAC, and production Supabase setup' (#70) from develop into main
Reviewed-on: #70
2026-03-21 12:21:07 +01:00
d2fa9e46df Merge pull request 'develop' (#56) from develop into main
Reviewed-on: #56
2026-03-20 20:02:22 +01:00
f770e4a785 Merge pull request 'develop' (#45) from develop into main
Reviewed-on: #45
2026-03-20 15:16:00 +01:00
013a45ab56 Merge pull request 'Allow multiple games per region in Custom genlocke' (#34) from develop into main
Reviewed-on: #34
2026-03-17 13:35:27 +01:00
321b940398 Merge pull request 'Fix FK violations when pruning stale routes' (#32) from develop into main
Reviewed-on: #32
2026-02-21 17:56:57 +01:00
e21a8acc60 Merge pull request 'Housekeeping: archive beans, add seed pruning' (#31) from develop into main
Reviewed-on: #31
2026-02-21 17:46:57 +01:00
f15e530130 Merge pull request 'Release: test infrastructure, rules overhaul, and design refresh' (#30) from develop into main
Reviewed-on: #30
2026-02-21 16:58:14 +01:00
e533a3404e Merge pull request 'develop' (#25) from develop into main
Reviewed-on: TheFurya/nuzlocke-tracker#25
2026-02-16 21:19:57 +01:00
a944da2204 Merge pull request 'develop' (#24) from develop into main
Reviewed-on: TheFurya/nuzlocke-tracker#24
2026-02-14 11:05:17 +01:00
012cfb96cd Merge pull request 'develop' (#21) from develop into main
Reviewed-on: TheFurya/nuzlocke-tracker#21
2026-02-14 10:01:41 +01:00
e3e015852c Merge pull request 'develop' (#19) from develop into main
Reviewed-on: TheFurya/nuzlocke-tracker#19
2026-02-13 09:32:47 +01:00
59b4f7f28c Merge pull request 'Complete Game Data Cleanup epic' (#16) from develop into main
Reviewed-on: TheFurya/nuzlocke-tracker#16
2026-02-11 15:34:25 +01:00
e212251da8 Merge pull request 'Fix route ordering' (#15) from develop into main
Reviewed-on: TheFurya/nuzlocke-tracker#15
2026-02-11 15:24:11 +01:00
f49c8cee85 Merge pull request 'Remove old Go fetch-pokeapi tool, update README for import-pokedb (#13)' (#14) from develop into main
Reviewed-on: TheFurya/nuzlocke-tracker#14
2026-02-11 13:57:09 +01:00
b34f1083a3 Merge pull request 'Update README.md' (#12) from develop into main
Reviewed-on: TheFurya/nuzlocke-tracker#12
2026-02-11 13:49:04 +01:00
b85668c233 Merge pull request 'Update bean' (#11) from develop into main
Reviewed-on: TheFurya/nuzlocke-tracker#11
2026-02-11 13:43:16 +01:00
45cbff7672 Merge pull request 'Fix webp sprites not loading in production nginx' (#10) from develop into main
Reviewed-on: TheFurya/nuzlocke-tracker#10
2026-02-11 13:25:14 +01:00
51b47dbfb0 Merge pull request 'develop' (#9) from develop into main
Reviewed-on: TheFurya/nuzlocke-tracker#9
2026-02-11 13:05:12 +01:00
4 changed files with 12 additions and 68 deletions

View File

@@ -1,10 +1,6 @@
import urllib.request from fastapi import APIRouter
from fastapi import APIRouter, Request
from sqlalchemy import text 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 from app.core.database import async_session
router = APIRouter(tags=["health"]) router = APIRouter(tags=["health"])
@@ -27,45 +23,3 @@ async def health_check():
async def root(): async def root():
"""Root endpoint.""" """Root endpoint."""
return {"message": "Nuzlocke Tracker API", "docs": "/docs"} 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,21 +26,11 @@ class AuthUser:
role: str | None = None 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: def _get_jwks_client() -> PyJWKClient | None:
"""Get or create a cached JWKS client.""" """Get or create a cached JWKS client."""
global _jwks_client global _jwks_client
if _jwks_client is None and settings.supabase_url: if _jwks_client is None and settings.supabase_url:
jwks_url = _build_jwks_url(settings.supabase_url) jwks_url = f"{settings.supabase_url.rstrip('/')}/.well-known/jwks.json"
_jwks_client = PyJWKClient(jwks_url, cache_jwk_set=True, lifespan=300) _jwks_client = PyJWKClient(jwks_url, cache_jwk_set=True, lifespan=300)
return _jwks_client return _jwks_client
@@ -90,7 +80,7 @@ def _verify_jwt(token: str) -> dict | None:
except PyJWKSetError as e: except PyJWKSetError as e:
logger.warning("JWKS set error: %s", e) logger.warning("JWKS set error: %s", e)
else: else:
logger.warning("No JWKS client available (SUPABASE_URL not set?)") logger.debug("No JWKS client available (SUPABASE_URL not set?)")
return _verify_jwt_hs256(token) return _verify_jwt_hs256(token)

View File

@@ -17,7 +17,7 @@
"react": "19.2.4", "react": "19.2.4",
"react-dom": "19.2.4", "react-dom": "19.2.4",
"react-markdown": "^10.1.0", "react-markdown": "^10.1.0",
"react-router-dom": "7.14.0", "react-router-dom": "7.13.1",
"remark-gfm": "^4.0.1", "remark-gfm": "^4.0.1",
"sonner": "2.0.7" "sonner": "2.0.7"
}, },
@@ -4385,9 +4385,9 @@
} }
}, },
"node_modules/react-router": { "node_modules/react-router": {
"version": "7.14.0", "version": "7.13.1",
"resolved": "https://registry.npmjs.org/react-router/-/react-router-7.14.0.tgz", "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.13.1.tgz",
"integrity": "sha512-m/xR9N4LQLmAS0ZhkY2nkPA1N7gQ5TUVa5n8TgANuDTARbn1gt+zLPXEm7W0XDTbrQ2AJSJKhoa6yx1D8BcpxQ==", "integrity": "sha512-td+xP4X2/6BJvZoX6xw++A2DdEi++YypA69bJUV5oVvqf6/9/9nNlD70YO1e9d3MyamJEBQFEzk6mbfDYbqrSA==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"cookie": "^1.0.1", "cookie": "^1.0.1",
@@ -4407,12 +4407,12 @@
} }
}, },
"node_modules/react-router-dom": { "node_modules/react-router-dom": {
"version": "7.14.0", "version": "7.13.1",
"resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.14.0.tgz", "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.13.1.tgz",
"integrity": "sha512-2G3ajSVSZMEtmTjIklRWlNvo8wICEpLihfD/0YMDxbWK2UyP5EGfnoIn9AIQGnF3G/FX0MRbHXdFcD+rL1ZreQ==", "integrity": "sha512-UJnV3Rxc5TgUPJt2KJpo1Jpy0OKQr0AjgbZzBFjaPJcFOb2Y8jA5H3LT8HUJAiRLlWrEXWHbF1Z4SCZaQjWDHw==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"react-router": "7.14.0" "react-router": "7.13.1"
}, },
"engines": { "engines": {
"node": ">=20.0.0" "node": ">=20.0.0"

View File

@@ -25,7 +25,7 @@
"react": "19.2.4", "react": "19.2.4",
"react-dom": "19.2.4", "react-dom": "19.2.4",
"react-markdown": "^10.1.0", "react-markdown": "^10.1.0",
"react-router-dom": "7.14.0", "react-router-dom": "7.13.1",
"remark-gfm": "^4.0.1", "remark-gfm": "^4.0.1",
"sonner": "2.0.7" "sonner": "2.0.7"
}, },