155 lines
No EOL
5.4 KiB
TypeScript
155 lines
No EOL
5.4 KiB
TypeScript
// app/api/me/route.ts
|
|
export const dynamic = "force-dynamic";
|
|
import { NextResponse } from "next/server";
|
|
import { createRouteHandlerClient } from "@supabase/auth-helpers-nextjs";
|
|
import { cookies, headers } from "next/headers";
|
|
import { resolveActiveOrg } from "@/lib/resolveActiveOrg";
|
|
import { detectDemoModeFromHeaders } from "@/lib/demo-detector";
|
|
import { DEMO_USER, DEMO_ORGANIZATION } from "@/lib/demo-data";
|
|
|
|
/**
|
|
* API simplifiée /api/me
|
|
* Maintenant principalement utilisée pour les appels AJAX côté client
|
|
* Le layout utilise directement les appels Supabase côté serveur
|
|
*/
|
|
export async function GET() {
|
|
console.log("📊 [API ME] Début de la requête /api/me");
|
|
|
|
// 🎭 Vérification du mode démo en premier
|
|
const h = headers();
|
|
const isDemoMode = detectDemoModeFromHeaders(h);
|
|
|
|
if (isDemoMode) {
|
|
console.log("🎭 [API ME] Mode démo détecté - renvoi de données fictives");
|
|
|
|
return NextResponse.json({
|
|
user_id: DEMO_USER.id,
|
|
email: DEMO_USER.email,
|
|
display_name: DEMO_USER.display_name,
|
|
first_name: DEMO_USER.first_name,
|
|
active_org_id: DEMO_ORGANIZATION.id,
|
|
active_org_name: DEMO_ORGANIZATION.name,
|
|
active_org_api_name: DEMO_ORGANIZATION.api_name,
|
|
is_staff: false
|
|
});
|
|
}
|
|
|
|
try {
|
|
// Vérifier les cookies reçus
|
|
const cookiesStore = cookies();
|
|
const allCookies = cookiesStore.getAll();
|
|
const authCookies = allCookies.filter(c => c.name.includes('sb-') || c.name === 'access_token');
|
|
|
|
console.log("🍪 [API ME] Cookies d'authentification reçus:",
|
|
authCookies.map(c => ({ name: c.name, hasValue: !!c.value, valueStart: c.value?.substring(0, 10) }))
|
|
);
|
|
|
|
const sb = createRouteHandlerClient({ cookies });
|
|
|
|
console.log("🔍 [API ME] Tentative de récupération de l'utilisateur...");
|
|
const { data: { user }, error: userError } = await sb.auth.getUser();
|
|
|
|
if (userError) {
|
|
console.log("❌ [API ME] Erreur lors de la récupération de l'utilisateur:", userError);
|
|
}
|
|
|
|
console.log("👤 [API ME] Résultat utilisateur:", {
|
|
userExists: !!user,
|
|
userId: user?.id,
|
|
email: user?.email
|
|
});
|
|
|
|
if (!user) {
|
|
// Vérifier aussi la session
|
|
const { data: { session }, error: sessionError } = await sb.auth.getSession();
|
|
console.log("🔍 [API ME] Vérification de la session:", {
|
|
sessionExists: !!session,
|
|
sessionError: sessionError?.message,
|
|
accessToken: session?.access_token ? `${session.access_token.substring(0, 10)}...` : null
|
|
});
|
|
|
|
return NextResponse.json({ error: "unauthenticated" }, { status: 401 });
|
|
}
|
|
|
|
// Vérification staff (DB-first) and retrieve an active organization for staff when possible
|
|
let isStaff = false;
|
|
try {
|
|
const { data } = await sb
|
|
.from("staff_users")
|
|
.select("is_staff")
|
|
.eq("user_id", user.id)
|
|
.maybeSingle();
|
|
isStaff = !!data?.is_staff;
|
|
} catch (e) {
|
|
// fallback to token metadata
|
|
isStaff = user.user_metadata?.is_staff === true || user.user_metadata?.role === 'staff' || (Array.isArray(user.app_metadata?.roles) && user.app_metadata.roles.includes('staff'));
|
|
}
|
|
|
|
// Récupération organisation (centralisée)
|
|
let activeOrgId: string | null = null;
|
|
let orgName: string | null = null;
|
|
let orgApiName: string | null = null;
|
|
let orgEmail: string | null = null;
|
|
let orgSignerName: string | null = null;
|
|
let orgCode: string | null = null;
|
|
|
|
// Use resolveActiveOrg which trims and ignores invalid placeholder values
|
|
activeOrgId = await resolveActiveOrg(sb as any);
|
|
console.log("🏢 [API ME] activeOrgId résolu:", activeOrgId);
|
|
|
|
if (activeOrgId) {
|
|
try {
|
|
const { data } = await sb
|
|
.from("organizations")
|
|
.select("name, structure_api")
|
|
.eq("id", activeOrgId)
|
|
.maybeSingle();
|
|
orgName = data?.name ?? null;
|
|
orgApiName = data?.structure_api ?? null;
|
|
|
|
// Valeurs temporaires pour tester la signature électronique
|
|
// TODO: Ajouter ces colonnes à la table organizations en production
|
|
orgEmail = "paie@odentas.fr"; // Email temporaire
|
|
orgSignerName = "Renaud BREVIERE-ABRAHAM"; // Nom signataire temporaire
|
|
orgCode = "ODENTAS"; // Code client temporaire
|
|
} catch (e) {
|
|
// ignore lookup errors
|
|
}
|
|
}
|
|
|
|
const result = {
|
|
user: {
|
|
id: user.id,
|
|
email: user.email,
|
|
display_name: user.user_metadata?.display_name || user.user_metadata?.full_name || null,
|
|
first_name: user.user_metadata?.first_name || user.user_metadata?.display_name?.split(' ')[0] || null,
|
|
},
|
|
active_org_id: activeOrgId,
|
|
active_org_name: orgName,
|
|
active_org_api_name: orgApiName,
|
|
active_org_email: orgEmail,
|
|
active_org_signer_name: orgSignerName,
|
|
active_org_code: orgCode,
|
|
is_staff: isStaff,
|
|
};
|
|
|
|
console.log("✅ [API ME] Réponse générée:", {
|
|
userId: result.user.id,
|
|
orgId: result.active_org_id,
|
|
orgName: result.active_org_name,
|
|
isStaff: result.is_staff
|
|
});
|
|
|
|
return NextResponse.json(result);
|
|
} catch (e: any) {
|
|
console.log("💥 [API ME] Erreur critique:", {
|
|
message: e?.message,
|
|
stack: e?.stack?.split('\n')[0] // Première ligne de la stack
|
|
});
|
|
|
|
return NextResponse.json(
|
|
{ error: "server_error", message: e?.message || "unknown" },
|
|
{ status: 500 }
|
|
);
|
|
}
|
|
} |