espace-paie-odentas/lib/resolveActiveOrg.ts

94 lines
4.7 KiB
TypeScript

import { headers } from "next/headers";
import { createRouteHandlerClient } from "@supabase/auth-helpers-nextjs";
/**
* Resolve active organization for the current request.
* Behavior:
* - If header x-active-org-id exists, return it.
* - If cookie active_org_id exists, return it.
* - If session indicates staff and no cookie/header, return null (staff global access).
* - For non-staff users, attempt to resolve via organization_members and return that org id or null.
*/
export async function resolveActiveOrg(reqSupabaseClient?: ReturnType<typeof createRouteHandlerClient>) {
const hdrRaw = headers().get("x-active-org-id");
const hdr = hdrRaw && String(hdrRaw).trim();
console.log("🔍 [resolveActiveOrg] Header x-active-org-id:", hdr);
if (hdr && hdr !== 'unknown' && hdr !== 'null' && hdr !== 'undefined' && hdr !== '') return hdr;
// Ignorer temporairement le cookie pour forcer la recherche DB
// const cookieRaw = cookies().get("active_org_id")?.value;
// const cookie = cookieRaw && String(cookieRaw).trim();
const cookie = undefined; // Force DB lookup
console.log("🔍 [resolveActiveOrg] Cookie active_org_id (ignored):", cookie);
if (cookie && cookie !== 'unknown' && cookie !== 'null' && cookie !== 'undefined' && cookie !== '') {
console.log("🔍 [resolveActiveOrg] Retour depuis cookie:", cookie);
return cookie;
}
console.log("🔍 [resolveActiveOrg] reqSupabaseClient provided:", !!reqSupabaseClient);
if (!reqSupabaseClient) {
console.log("🔍 [resolveActiveOrg] No Supabase client, returning null");
return null;
}
try {
console.log("🔍 [resolveActiveOrg] Tentative getUser...");
const { data: { user }, error: userError } = await reqSupabaseClient.auth.getUser();
console.log("🔍 [resolveActiveOrg] User obtenu:", !!user, user?.id, userError?.message);
if (!user) return null;
let isStaff = false;
console.log("🔍 [resolveActiveOrg] Vérification staff...");
try {
const { data: staffRow } = await reqSupabaseClient.from('staff_users').select('is_staff').eq('user_id', user.id).maybeSingle();
const s = staffRow as { is_staff?: boolean } | null;
isStaff = !!s?.is_staff;
console.log("🔍 [resolveActiveOrg] Résultat staff_users:", { staffRow, isStaff });
} catch (staffError) {
console.log("🔍 [resolveActiveOrg] Erreur lors de la vérification staff:", staffError);
const userMeta = user?.user_metadata || {};
const appMeta = user?.app_metadata || {};
isStaff = Boolean((userMeta.is_staff === true || userMeta.role === 'staff') || (Array.isArray(appMeta.roles) && appMeta.roles.includes('staff')));
console.log("🔍 [resolveActiveOrg] Fallback metadata staff:", { userMeta, appMeta, isStaff });
}
console.log("🔍 [resolveActiveOrg] User isStaff:", isStaff);
if (isStaff) {
console.log("🔍 [resolveActiveOrg] User is staff, returning null");
return null;
}
// otherwise resolve via organization_members
try {
console.log("🔍 [resolveActiveOrg] Recherche dans organization_members pour user_id:", user.id);
const { data: member, error: memberError } = await reqSupabaseClient.from('organization_members').select('organization:organizations(id)').eq('user_id', user.id).eq('revoked', false).maybeSingle();
console.log("🔍 [resolveActiveOrg] Résultat organization_members:", { member, memberError });
const org = (member as { organization?: { id: string } } | null)?.organization;
const orgId = org?.id ?? null;
console.log("🔍 [resolveActiveOrg] orgId extrait:", orgId);
if (orgId) {
return orgId;
}
// Si aucune organisation trouvée pour un utilisateur non-staff,
// essayons de trouver une organisation par défaut SEULEMENT en dernier recours
console.log("🔍 [resolveActiveOrg] Pas d'org trouvée, recherche organisation par défaut");
const { data: defaultOrg } = await reqSupabaseClient.from('organizations').select('id').limit(1).maybeSingle();
const defaultOrgId = (defaultOrg as { id?: string } | null)?.id ?? null;
console.log("🔍 [resolveActiveOrg] Organisation par défaut:", defaultOrgId);
return defaultOrgId;
} catch {
console.log("🔍 [resolveActiveOrg] Erreur lors de la recherche organization_members:");
// En cas d'erreur, essayons quand même de retourner une organisation par défaut
try {
const { data: defaultOrg } = await reqSupabaseClient.from('organizations').select('id').limit(1).maybeSingle();
return (defaultOrg as { id?: string } | null)?.id ?? null;
} catch {
return null;
}
}
} catch {
return null;
}
}