94 lines
4.7 KiB
TypeScript
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;
|
|
}
|
|
}
|