Munça da UI de inicio | escovagem semanal adicionada | quantidade de videos assistidos | todos os videos na nuvem | possibilidade de continuar o video de onde parou
This commit is contained in:
1
supabase/.temp/linked-project.json
Normal file
1
supabase/.temp/linked-project.json
Normal file
@@ -0,0 +1 @@
|
||||
{"ref":"mannjismlhlwaqqqnvog","name":"Check_Teeth_Kids","organization_id":"huurggiiridujjbkbayo","organization_slug":"huurggiiridujjbkbayo"}
|
||||
65
supabase/functions/delete-account/index.ts
Normal file
65
supabase/functions/delete-account/index.ts
Normal file
@@ -0,0 +1,65 @@
|
||||
// Edge Function: apaga TODA a conta do utilizador autenticado — linhas em
|
||||
// `children`/`profiles` e o próprio registo em `auth.users`. Isto é o que
|
||||
// falta para permitir criar uma nova conta com o mesmo e-mail depois de
|
||||
// "Apagar dados da conta": o app (client) nunca teve a service role key para
|
||||
// poder chamar `auth.admin.deleteUser`, por isso essa etapa faltava e o
|
||||
// e-mail continuava "ocupado" no Supabase Auth.
|
||||
//
|
||||
// Deploy (uma vez, com a Supabase CLI já autenticada):
|
||||
// supabase functions deploy delete-account --project-ref mannjismlhlwaqqqnvog
|
||||
//
|
||||
// SUPABASE_URL e SUPABASE_SERVICE_ROLE_KEY já ficam disponíveis
|
||||
// automaticamente dentro de toda Edge Function — não é preciso configurar
|
||||
// nenhum secret manualmente.
|
||||
|
||||
import { createClient } from 'https://esm.sh/@supabase/supabase-js@2';
|
||||
|
||||
const SUPABASE_URL = Deno.env.get('SUPABASE_URL')!;
|
||||
const SERVICE_ROLE_KEY = Deno.env.get('SUPABASE_SERVICE_ROLE_KEY')!;
|
||||
|
||||
Deno.serve(async (req) => {
|
||||
if (req.method !== 'POST') {
|
||||
return new Response(JSON.stringify({ error: 'Method not allowed' }), {
|
||||
status: 405,
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
});
|
||||
}
|
||||
|
||||
const authHeader = req.headers.get('Authorization') ?? '';
|
||||
const jwt = authHeader.replace('Bearer ', '').trim();
|
||||
if (!jwt) {
|
||||
return new Response(JSON.stringify({ error: 'Sessão em falta' }), {
|
||||
status: 401,
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
});
|
||||
}
|
||||
|
||||
const admin = createClient(SUPABASE_URL, SERVICE_ROLE_KEY);
|
||||
|
||||
// Valida o JWT do chamador e identifica o uid — nunca confiar num uid vindo
|
||||
// do corpo do pedido, sob pena de qualquer pessoa poder apagar outra conta.
|
||||
const { data: userData, error: userError } = await admin.auth.getUser(jwt);
|
||||
if (userError || !userData?.user) {
|
||||
return new Response(JSON.stringify({ error: 'Sessão inválida' }), {
|
||||
status: 401,
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
});
|
||||
}
|
||||
const uid = userData.user.id;
|
||||
|
||||
await admin.from('children').delete().eq('owner_id', uid);
|
||||
await admin.from('profiles').delete().eq('id', uid);
|
||||
|
||||
const { error: deleteUserError } = await admin.auth.admin.deleteUser(uid);
|
||||
if (deleteUserError) {
|
||||
return new Response(JSON.stringify({ error: deleteUserError.message }), {
|
||||
status: 500,
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
});
|
||||
}
|
||||
|
||||
return new Response(JSON.stringify({ ok: true }), {
|
||||
status: 200,
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user