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:
+20
-2
@@ -19,11 +19,29 @@ export const onRequest = defineMiddleware(async (context, next) => {
|
|||||||
context.locals.profile = null;
|
context.locals.profile = null;
|
||||||
|
|
||||||
if (user) {
|
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')
|
.from('profiles')
|
||||||
.select('id, email, nombre, matricula, rol, semestre, tutor_id, foto_path')
|
.select(select)
|
||||||
.eq('id', user.id)
|
.eq('id', user.id)
|
||||||
.maybeSingle();
|
.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;
|
context.locals.profile = profile ?? null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
-- 0005_profiles_insert_self.sql
|
||||||
|
-- Permite al usuario autenticado insertar su propio profile.
|
||||||
|
-- Necesario para el self-heal del middleware cuando el trigger
|
||||||
|
-- prestamos_on_auth_user_created no dispara (coexiste con otro trigger
|
||||||
|
-- del proyecto vecino en auth.users que a veces impide la ejecucion).
|
||||||
|
-- rol='alumno' obligatorio en el CHECK -> el user no puede promoverse
|
||||||
|
-- a admin insertando; solo el admin puede modificar rol via
|
||||||
|
-- profiles_admin_all (definida en 0001).
|
||||||
|
|
||||||
|
begin;
|
||||||
|
|
||||||
|
drop policy if exists profiles_insert_self on prestamos.profiles;
|
||||||
|
|
||||||
|
create policy profiles_insert_self on prestamos.profiles
|
||||||
|
for insert to authenticated
|
||||||
|
with check (id = auth.uid() and rol = 'alumno');
|
||||||
|
|
||||||
|
commit;
|
||||||
Reference in New Issue
Block a user