diff --git a/lib/supabase/client.ts b/lib/supabase/client.ts index e0b695b..42413c2 100644 --- a/lib/supabase/client.ts +++ b/lib/supabase/client.ts @@ -1,9 +1,9 @@ -import { createBrowserClient } from "@supabase/ssr"; +import { createClient as createSupabaseClient } from "@supabase/supabase-js"; import type { Database } from "@/types/database.types"; // Client Supabase côté navigateur (composants client) export const createClient = () => - createBrowserClient( + createSupabaseClient( process.env.NEXT_PUBLIC_SUPABASE_URL!, process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY! ); diff --git a/lib/supabase/server.ts b/lib/supabase/server.ts index 0fe5634..e61c15b 100644 --- a/lib/supabase/server.ts +++ b/lib/supabase/server.ts @@ -1,36 +1,72 @@ -import { createServerClient } from "@supabase/ssr"; import { createClient as createSupabaseClient } from "@supabase/supabase-js"; import { cookies } from "next/headers"; import type { Database } from "@/types/database.types"; // Client Supabase côté serveur (Server Components, Route Handlers) +// Lit le token d'auth depuis les cookies pour maintenir la session export const createClient = async () => { const cookieStore = await cookies(); - return createServerClient( + // Récupérer le token d'accès depuis les cookies Supabase + const accessToken = cookieStore.get("sb-access-token")?.value + || cookieStore.get(`sb-${new URL(process.env.NEXT_PUBLIC_SUPABASE_URL!).hostname.split(".")[0]}-auth-token`)?.value; + + const client = createSupabaseClient( process.env.NEXT_PUBLIC_SUPABASE_URL!, process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!, { - cookies: { - getAll() { - return cookieStore.getAll(); - }, - setAll(cookiesToSet) { - try { - cookiesToSet.forEach(({ name, value, options }) => - cookieStore.set(name, value, options) - ); - } catch { - // Ignore en Server Component (lecture seule) - } - }, + global: { + headers: accessToken ? { Authorization: `Bearer ${accessToken}` } : {}, }, } ); + + // Essayer de restaurer la session depuis les cookies + const allCookies = cookieStore.getAll(); + + // Chercher le cookie de session complet (format chunked ou simple) + const projectRef = new URL(process.env.NEXT_PUBLIC_SUPABASE_URL!).hostname.split(".")[0]; + const authCookieName = `sb-${projectRef}-auth-token`; + + // Reassembler les chunks si nécessaire + let sessionData: string | null = null; + const baseCookie = allCookies.find(c => c.name === authCookieName); + if (baseCookie) { + sessionData = baseCookie.value; + } else { + // Chercher les chunks (sb-xxx-auth-token.0, sb-xxx-auth-token.1, etc.) + const chunks: string[] = []; + for (let i = 0; i < 10; i++) { + const chunk = allCookies.find(c => c.name === `${authCookieName}.${i}`); + if (chunk) { + chunks.push(chunk.value); + } else { + break; + } + } + if (chunks.length > 0) { + sessionData = chunks.join(""); + } + } + + if (sessionData) { + try { + const parsed = JSON.parse(sessionData); + if (parsed?.access_token && parsed?.refresh_token) { + await client.auth.setSession({ + access_token: parsed.access_token, + refresh_token: parsed.refresh_token, + }); + } + } catch { + // Cookie invalide, on continue sans session + } + } + + return client; }; // Client admin avec service role (webhooks, opérations admin) -// Utilise @supabase/supabase-js directement (pas besoin de cookies) export const createAdminClient = () => { return createSupabaseClient( process.env.NEXT_PUBLIC_SUPABASE_URL!, diff --git a/next.config.ts b/next.config.ts index fafd533..cb651cd 100644 --- a/next.config.ts +++ b/next.config.ts @@ -1,7 +1,5 @@ import type { NextConfig } from "next"; -const nextConfig: NextConfig = { - serverExternalPackages: ["@supabase/ssr"], -}; +const nextConfig: NextConfig = {}; export default nextConfig; diff --git a/package-lock.json b/package-lock.json index 58c0463..159005b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,6 @@ "version": "0.1.0", "dependencies": { "@stripe/stripe-js": "^8.7.0", - "@supabase/ssr": "^0.8.0", "@supabase/supabase-js": "^2.95.3", "clsx": "^2.1.1", "next": "^15.5.12", @@ -1086,18 +1085,6 @@ "node": ">=20.0.0" } }, - "node_modules/@supabase/ssr": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@supabase/ssr/-/ssr-0.8.0.tgz", - "integrity": "sha512-/PKk8kNFSs8QvvJ2vOww1mF5/c5W8y42duYtXvkOSe+yZKRgTTZywYG2l41pjhNomqESZCpZtXuWmYjFRMV+dw==", - "license": "MIT", - "dependencies": { - "cookie": "^1.0.2" - }, - "peerDependencies": { - "@supabase/supabase-js": "^2.76.1" - } - }, "node_modules/@supabase/storage-js": { "version": "2.95.3", "resolved": "https://registry.npmjs.org/@supabase/storage-js/-/storage-js-2.95.3.tgz", @@ -2496,19 +2483,6 @@ "dev": true, "license": "MIT" }, - "node_modules/cookie": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.1.1.tgz", - "integrity": "sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==", - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } - }, "node_modules/cross-spawn": { "version": "7.0.6", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", diff --git a/package.json b/package.json index 0614490..5d32a8f 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,6 @@ }, "dependencies": { "@stripe/stripe-js": "^8.7.0", - "@supabase/ssr": "^0.8.0", "@supabase/supabase-js": "^2.95.3", "clsx": "^2.1.1", "next": "^15.5.12",