diff --git a/surfsense_backend/app/users.py b/surfsense_backend/app/users.py index 54db06412..cf4039a4e 100644 --- a/surfsense_backend/app/users.py +++ b/surfsense_backend/app/users.py @@ -88,10 +88,16 @@ class CustomBearerTransport(BearerTransport): else: return JSONResponse(model_dump(bearer_response)) + async def get_login_failure_response(self) -> Response: + # 👇 This is the new part — gives a clear message instead of raw error code + return JSONResponse( + status_code=401, + content={"detail": "Wrong username or password"}, + ) + bearer_transport = CustomBearerTransport(tokenUrl="auth/jwt/login") - auth_backend = AuthenticationBackend( name="jwt", transport=bearer_transport, diff --git a/surfsense_web/app/login/LocalLoginForm.tsx b/surfsense_web/app/login/LocalLoginForm.tsx index 7cc50b28a..1873b1180 100644 --- a/surfsense_web/app/login/LocalLoginForm.tsx +++ b/surfsense_web/app/login/LocalLoginForm.tsx @@ -42,18 +42,22 @@ export function LocalLoginForm() { const data = await response.json(); if (!response.ok) { - throw new Error(data.detail || "Failed to login"); + // 👇 Instead of generic error, show backend’s message + setError(data.detail || "Wrong username or password"); + return; } router.push(`/auth/callback?token=${data.access_token}`); } catch (err) { - const errorMessage = err instanceof Error ? err.message : "An error occurred during login"; + const errorMessage = + err instanceof Error ? err.message : "An error occurred during login"; setError(errorMessage); } finally { setIsLoading(false); } }; + return (