forked from VolkisAI/codespring-boilerplate
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmiddleware.ts
More file actions
82 lines (67 loc) · 3.16 KB
/
middleware.ts
File metadata and controls
82 lines (67 loc) · 3.16 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
import { clerkMiddleware, createRouteMatcher } from "@clerk/nextjs/server";
import { NextResponse } from "next/server";
const isProtectedRoute = createRouteMatcher(["/dashboard(.*)"]);
// This handles both payment provider use cases from whop-setup.md and stripe-setup.md
export default clerkMiddleware(async (auth, req) => {
// Skip auth for webhook endpoints
if (req.nextUrl.pathname.startsWith('/api/whop/webhooks')) {
console.log("Skipping Clerk auth for Whop webhook endpoint");
return NextResponse.next();
}
// Check for problematic URLs that might cause 431 errors
// This covers both Clerk handshake params and payment provider redirects
if (
req.nextUrl.search && (
req.nextUrl.search.includes('__clerk_handshake') ||
req.nextUrl.search.includes('payment_intent') ||
req.nextUrl.search.includes('checkout_id') ||
req.nextUrl.search.includes('ref=') ||
req.nextUrl.search.includes('client_reference_id=')
)
) {
// The URL contains parameters that might cause 431 errors
// Instead of just letting it pass through, redirect to a clean URL
// This prevents the accumulation of large cookies
// Extract the base URL path without query parameters
const cleanUrl = req.nextUrl.pathname;
// Create a new URL object based on the current request
const url = new URL(cleanUrl, req.url);
// Important: Add a small cache-busting parameter to ensure the browser doesn't use cached data
// This helps avoid cookie-related issues without adding significant query string size
url.searchParams.set('cb', Date.now().toString().slice(-4));
console.log(`Redirecting from problematic URL with large parameters to clean URL: ${url.toString()}`);
// Return a redirect response to the clean URL
return NextResponse.redirect(url);
}
// Special handling for frictionless payment flow
// If a user has just completed signup after payment and is authenticated,
// redirect them to the dashboard instead of keeping them on the signup page
if (req.nextUrl.pathname.startsWith('/signup') && req.nextUrl.search.includes('payment=success')) {
const { userId } = auth();
// If user is authenticated and on signup page with payment=success, they should go to dashboard
if (userId) {
console.log("Frictionless payment user authenticated, redirecting to dashboard");
const dashboardUrl = new URL('/dashboard', req.url);
dashboardUrl.searchParams.set('payment', 'success');
dashboardUrl.searchParams.set('cb', Date.now().toString().slice(-4));
return NextResponse.redirect(dashboardUrl);
}
}
const { userId, redirectToSignIn } = auth();
// Standard route protection logic
if (!userId && isProtectedRoute(req)) {
// Return to dashboard after login instead of /login to avoid redirect loops
return redirectToSignIn({ returnBackUrl: req.nextUrl.pathname });
}
if (userId && isProtectedRoute(req)) {
return NextResponse.next();
}
return NextResponse.next();
});
export const config = {
matcher: [
// Match all routes except for these:
"/((?!api/whop/webhooks|_next/static|_next/image|favicon.ico).*)",
"/"
]
};