fix: remove @supabase/ssr entirely to fix MIDDLEWARE_INVOCATION_FAILED
@supabase/ssr uses __dirname internally which crashes in Vercel's Edge runtime, causing MIDDLEWARE_INVOCATION_FAILED even without a middleware file. Replaced with @supabase/supabase-js directly: - Server client: manual cookie-based session restoration - Browser client: direct createClient from supabase-js - Admin client: already using supabase-js https://claude.ai/code/session_01H2aRGDaKgarPvhay2HxN6Y
This commit is contained in:
@@ -1,9 +1,9 @@
|
|||||||
import { createBrowserClient } from "@supabase/ssr";
|
import { createClient as createSupabaseClient } from "@supabase/supabase-js";
|
||||||
import type { Database } from "@/types/database.types";
|
import type { Database } from "@/types/database.types";
|
||||||
|
|
||||||
// Client Supabase côté navigateur (composants client)
|
// Client Supabase côté navigateur (composants client)
|
||||||
export const createClient = () =>
|
export const createClient = () =>
|
||||||
createBrowserClient<Database>(
|
createSupabaseClient<Database>(
|
||||||
process.env.NEXT_PUBLIC_SUPABASE_URL!,
|
process.env.NEXT_PUBLIC_SUPABASE_URL!,
|
||||||
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!
|
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,36 +1,72 @@
|
|||||||
import { createServerClient } from "@supabase/ssr";
|
|
||||||
import { createClient as createSupabaseClient } from "@supabase/supabase-js";
|
import { createClient as createSupabaseClient } from "@supabase/supabase-js";
|
||||||
import { cookies } from "next/headers";
|
import { cookies } from "next/headers";
|
||||||
import type { Database } from "@/types/database.types";
|
import type { Database } from "@/types/database.types";
|
||||||
|
|
||||||
// Client Supabase côté serveur (Server Components, Route Handlers)
|
// 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 () => {
|
export const createClient = async () => {
|
||||||
const cookieStore = await cookies();
|
const cookieStore = await cookies();
|
||||||
|
|
||||||
return createServerClient<Database>(
|
// 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<Database>(
|
||||||
process.env.NEXT_PUBLIC_SUPABASE_URL!,
|
process.env.NEXT_PUBLIC_SUPABASE_URL!,
|
||||||
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
|
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
|
||||||
{
|
{
|
||||||
cookies: {
|
global: {
|
||||||
getAll() {
|
headers: accessToken ? { Authorization: `Bearer ${accessToken}` } : {},
|
||||||
return cookieStore.getAll();
|
|
||||||
},
|
},
|
||||||
setAll(cookiesToSet) {
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// 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 {
|
try {
|
||||||
cookiesToSet.forEach(({ name, value, options }) =>
|
const parsed = JSON.parse(sessionData);
|
||||||
cookieStore.set(name, value, options)
|
if (parsed?.access_token && parsed?.refresh_token) {
|
||||||
);
|
await client.auth.setSession({
|
||||||
|
access_token: parsed.access_token,
|
||||||
|
refresh_token: parsed.refresh_token,
|
||||||
|
});
|
||||||
|
}
|
||||||
} catch {
|
} catch {
|
||||||
// Ignore en Server Component (lecture seule)
|
// Cookie invalide, on continue sans session
|
||||||
}
|
}
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
);
|
|
||||||
|
return client;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Client admin avec service role (webhooks, opérations admin)
|
// Client admin avec service role (webhooks, opérations admin)
|
||||||
// Utilise @supabase/supabase-js directement (pas besoin de cookies)
|
|
||||||
export const createAdminClient = () => {
|
export const createAdminClient = () => {
|
||||||
return createSupabaseClient<Database>(
|
return createSupabaseClient<Database>(
|
||||||
process.env.NEXT_PUBLIC_SUPABASE_URL!,
|
process.env.NEXT_PUBLIC_SUPABASE_URL!,
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
import type { NextConfig } from "next";
|
import type { NextConfig } from "next";
|
||||||
|
|
||||||
const nextConfig: NextConfig = {
|
const nextConfig: NextConfig = {};
|
||||||
serverExternalPackages: ["@supabase/ssr"],
|
|
||||||
};
|
|
||||||
|
|
||||||
export default nextConfig;
|
export default nextConfig;
|
||||||
|
|||||||
26
package-lock.json
generated
26
package-lock.json
generated
@@ -9,7 +9,6 @@
|
|||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@stripe/stripe-js": "^8.7.0",
|
"@stripe/stripe-js": "^8.7.0",
|
||||||
"@supabase/ssr": "^0.8.0",
|
|
||||||
"@supabase/supabase-js": "^2.95.3",
|
"@supabase/supabase-js": "^2.95.3",
|
||||||
"clsx": "^2.1.1",
|
"clsx": "^2.1.1",
|
||||||
"next": "^15.5.12",
|
"next": "^15.5.12",
|
||||||
@@ -1086,18 +1085,6 @@
|
|||||||
"node": ">=20.0.0"
|
"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": {
|
"node_modules/@supabase/storage-js": {
|
||||||
"version": "2.95.3",
|
"version": "2.95.3",
|
||||||
"resolved": "https://registry.npmjs.org/@supabase/storage-js/-/storage-js-2.95.3.tgz",
|
"resolved": "https://registry.npmjs.org/@supabase/storage-js/-/storage-js-2.95.3.tgz",
|
||||||
@@ -2496,19 +2483,6 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"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": {
|
"node_modules/cross-spawn": {
|
||||||
"version": "7.0.6",
|
"version": "7.0.6",
|
||||||
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
|
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
|
||||||
|
|||||||
@@ -10,7 +10,6 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@stripe/stripe-js": "^8.7.0",
|
"@stripe/stripe-js": "^8.7.0",
|
||||||
"@supabase/ssr": "^0.8.0",
|
|
||||||
"@supabase/supabase-js": "^2.95.3",
|
"@supabase/supabase-js": "^2.95.3",
|
||||||
"clsx": "^2.1.1",
|
"clsx": "^2.1.1",
|
||||||
"next": "^15.5.12",
|
"next": "^15.5.12",
|
||||||
|
|||||||
Reference in New Issue
Block a user