feat: server-side language preference — survives clear site data
Problem: language preference stored only in localStorage, lost on 'clear site data'. French users with browser lang=fr always got French UI even when profile was English. Solution: - Backend: add 'language' field to user profile (default 'fr') - Backend: PATCH /api/auth/me to update language preference - Frontend: initI18n() priority: server > localStorage > navigator > 'fr' - Frontend: initAuth() runs before initI18n() so server check works - Frontend: profile Save persists language to server via PATCH Verified: tabs show English after server profile set to 'en'
This commit is contained in:
@@ -242,10 +242,41 @@ async def get_me(current_user=Depends(require_auth)):
|
||||
"display_name": current_user["display_name"],
|
||||
"role": current_user["role"],
|
||||
"vaults": current_user["vaults"],
|
||||
"language": current_user.get("language", "fr"),
|
||||
"last_login": current_user.get("last_login"),
|
||||
}
|
||||
|
||||
|
||||
class UpdateMeRequest(BaseModel):
|
||||
"""Fields the user can update on their own profile."""
|
||||
display_name: Optional[str] = None
|
||||
language: Optional[str] = None
|
||||
|
||||
|
||||
@router.patch("/me")
|
||||
async def patch_me(req: UpdateMeRequest, current_user=Depends(require_auth)):
|
||||
"""Update current user's profile fields (display_name, language)."""
|
||||
from .user_store import update_user
|
||||
updates = {}
|
||||
if req.display_name is not None:
|
||||
updates["display_name"] = req.display_name
|
||||
if req.language is not None:
|
||||
if req.language not in ("fr", "en"):
|
||||
raise HTTPException(400, "language must be 'fr' or 'en'")
|
||||
updates["language"] = req.language
|
||||
if not updates:
|
||||
raise HTTPException(400, "No fields to update")
|
||||
updated = update_user(current_user["username"], updates)
|
||||
return {
|
||||
"username": updated["username"],
|
||||
"display_name": updated["display_name"],
|
||||
"role": updated["role"],
|
||||
"vaults": updated["vaults"],
|
||||
"language": updated.get("language", "fr"),
|
||||
"last_login": updated.get("last_login"),
|
||||
}
|
||||
|
||||
|
||||
@router.post("/change-password")
|
||||
async def change_password(
|
||||
req: ChangePasswordRequest,
|
||||
|
||||
@@ -88,6 +88,7 @@ def create_user(
|
||||
"role": role,
|
||||
"vaults": vaults or [],
|
||||
"active": True,
|
||||
"language": "fr", # default UI language
|
||||
"created_at": datetime.now(timezone.utc).isoformat(),
|
||||
"last_login": None,
|
||||
"failed_attempts": 0,
|
||||
|
||||
Reference in New Issue
Block a user