Fix: self-heal del profile en middleware + backfill de users existentes

El trigger prestamos_on_auth_user_created coexiste con otro trigger del
proyecto vecino en auth.users y no siempre dispara. Consecuencia:
usuarios que hacían login vía OAuth entraban con user pero sin profile,
y la app los trataba como "no logueado".

- Middleware: si hay user y no hay profile (email @uabc.edu.mx), upsert
  del profile con datos del OAuth (nombre desde user_metadata.full_name).
- Migración 0005: policy RLS profiles_insert_self con check
  (id=auth.uid() and rol='alumno') — impide escalación a admin desde el
  self-heal.
- Backfill manual ejecutado en prod para los 8 users @uabc.edu.mx que
  ya existían en auth.users pero no tenían profile.
This commit is contained in:
2026-08-24 09:36:16 -07:00
parent d0f01ea18c
commit bcecdbb184
2 changed files with 38 additions and 2 deletions
+20 -2
View File
@@ -19,11 +19,29 @@ export const onRequest = defineMiddleware(async (context, next) => {
context.locals.profile = null;
if (user) {
const { data: profile } = await supabase
const select = 'id, email, nombre, matricula, rol, semestre, tutor_id, foto_path';
let { data: profile } = await supabase
.from('profiles')
.select('id, email, nombre, matricula, rol, semestre, tutor_id, foto_path')
.select(select)
.eq('id', user.id)
.maybeSingle();
// Self-heal: el trigger prestamos_on_auth_user_created coexiste con otro
// trigger del proyecto vecino en auth.users y no siempre dispara. Si el
// user existe pero no hay profile, lo creamos aquí con los datos del OAuth.
if (!profile && user.email?.toLowerCase().endsWith(UABC_DOMAIN)) {
const nombre =
(user.user_metadata?.full_name as string | undefined) ??
(user.user_metadata?.name as string | undefined) ??
null;
const { data: creado } = await supabase
.from('profiles')
.upsert({ id: user.id, email: user.email, nombre }, { onConflict: 'id' })
.select(select)
.maybeSingle();
profile = creado ?? null;
}
context.locals.profile = profile ?? null;
}