fix(auth): map logto string ID to supabase UUID via email to prevent 400 bad request

This commit is contained in:
2026-08-18 11:19:00 +00:00
parent 50d563c0fd
commit dd7d1c41dd
+50 -15
View File
@@ -21,20 +21,49 @@ import {
requestPasswordReset, requestPasswordReset,
} from '@/lib/logto/client'; } from '@/lib/logto/client';
// Sincroniza user Logto com profiles Supabase // Sincroniza user Logto com profiles Supabase e retorna o UUID real do Supabase
async function syncUserToProfile(user: LogtoUser): Promise<void> { async function syncUserToProfile(user: LogtoUser): Promise<string> {
if (!user?.sub) return; if (!user?.sub) return user.sub;
const email = user.email || `${user.username || 'user'}@logto.local`;
try { try {
await supabase.from('profiles').upsert( // 1. Tenta buscar o perfil existente pelo email
{ const { data: existing } = await supabase
id: user.sub, .from('profiles')
full_name: user.name || user.email || user.username || 'Usuário', .select('id')
email: user.email || null, .eq('email', email)
}, .maybeSingle();
{ onConflict: 'id', ignoreDuplicates: false }
); let profileId = existing?.id;
// 2. Se existe, atualizamos o nome e retornamos o UUID
if (profileId) {
const name = user.name || user.username;
if (name) {
await supabase.from('profiles').update({
full_name: name,
}).eq('id', profileId);
}
return profileId;
}
// 3. Se não existir, criamos um novo com um UUID gerado
profileId = crypto.randomUUID();
const { error: insertError } = await supabase.from('profiles').insert({
id: profileId,
email: email,
full_name: user.name || user.username || 'Usuário Logto',
});
if (insertError) {
console.warn('Erro ao inserir novo profile no Supabase:', insertError);
return user.sub;
}
return profileId;
} catch (err) { } catch (err) {
console.warn('Erro ao sincronizar profile Supabase:', err); console.warn('Erro ao sincronizar profile Supabase:', err);
return user.sub;
} }
} }
@@ -69,9 +98,12 @@ export function AuthProvider({ children }: { children: ReactNode }) {
setLoading(true); setLoading(true);
handleCallback().then((ok) => { handleCallback().then((ok) => {
if (ok) { if (ok) {
logtoGetUser().then((u) => { logtoGetUser().then(async (u) => {
if (u) {
const profileId = await syncUserToProfile(u);
u.id = profileId;
}
setUser(u); setUser(u);
if (u) syncUserToProfile(u);
}); });
} }
setAuthInitialized(true); setAuthInitialized(true);
@@ -80,9 +112,12 @@ export function AuthProvider({ children }: { children: ReactNode }) {
} else { } else {
setAuthInitialized(true); setAuthInitialized(true);
if (isAuthenticated()) { if (isAuthenticated()) {
logtoGetUser().then((u) => { logtoGetUser().then(async (u) => {
if (u) {
const profileId = await syncUserToProfile(u);
u.id = profileId;
}
setUser(u); setUser(u);
if (u) syncUserToProfile(u);
setLoading(false); setLoading(false);
}); });
} else { } else {