fix(api/profile): send credentials cross-origin so Better-Auth updateUser works

fetchWithAuth called mana-auth's /api/v1/auth/profile without
credentials: 'include'. In production both hosts sit under *.mana.how
with the shared auth cookie, so the session rode along regardless —
but in dev (5173 → 3001) the cookie was dropped, and the server's
auth.api.updateUser threw because it couldn't identify the user.
serviceErrorHandler then masked it as a generic 500.

The failure was silent at the call site because syncAvatarToAuth()
wraps the POST in try/catch — but every face-ref primary claim logged
"[profile] syncing avatar to Better Auth failed" and left
auth.users.image out of sync. Surfaced now because wardrobe's new
inline face upload claims face-ref reliably.

Matches credentials: 'include' used everywhere in
packages/shared-auth/src/core/authService.ts.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Till JS 2026-04-23 23:16:43 +02:00
parent aeba23f772
commit 00ddd1e4ea

View file

@ -42,6 +42,13 @@ async function fetchWithAuth<T>(endpoint: string, options: RequestInit = {}): Pr
const response = await fetch(`${getManaAuthUrl()}${endpoint}`, {
...options,
// Better-Auth's /profile handler calls auth.api.updateUser, which
// identifies the user via the session cookie (not the JWT bearer).
// In dev the request is cross-origin (5173 → 3001); without
// `credentials: 'include'` the browser drops the cookie and the
// server throws "Internal server error" instead of updating.
// Matches the pattern used throughout packages/shared-auth.
credentials: 'include',
headers: {
'Content-Type': 'application/json',
...(token ? { Authorization: `Bearer ${token}` } : {}),