diff --git a/src/middleware.ts b/src/middleware.ts index 54f5d104d..f1204ccbd 100644 --- a/src/middleware.ts +++ b/src/middleware.ts @@ -1,8 +1,9 @@ // middleware.ts import type { NextRequest } from 'next/server' import { NextResponse } from 'next/server' +import { PEANUT_API_URL } from '@/constants/general.consts' -export function middleware(request: NextRequest) { +export async function middleware(request: NextRequest) { const { pathname } = request.nextUrl const maintenanceMode = false @@ -42,6 +43,50 @@ export function middleware(request: NextRequest) { const redirectUrl = `https://peanut.to/claim?&${promoList[fragment]}` return NextResponse.redirect(redirectUrl) } + // Handle QR redirect lookups + if (pathname.startsWith('/qr/')) { + const match = pathname.match(/^\/qr\/([^\/?#]+)/) + const code = match?.[1] + + console.log('[QR Redirect] Handling QR code:', code) + + if (code && PEANUT_API_URL) { + try { + const controller = new AbortController() + const timeoutId = setTimeout(() => controller.abort(), 3000) + + const lookupUrl = `${PEANUT_API_URL}/redirect/lookup?input=${encodeURIComponent(`qr/${code}`)}` + console.log('[QR Redirect] Looking up URL:', lookupUrl) + + const res = await fetch(lookupUrl, { + method: 'GET', + cache: 'no-store', // important to not cache this so the live update works fast (or should we?) + signal: controller.signal, + }) + + clearTimeout(timeoutId) + console.log('[QR Redirect] Response status:', res.status) + + if (res.status === 200) { + const data = await res.json().catch(() => null) + const targetUrl = data?.targetUrl + if (typeof targetUrl === 'string' && targetUrl.length > 0) { + console.log('[QR Redirect] Redirecting to:', targetUrl) + return NextResponse.redirect(new URL(targetUrl, request.url)) + } + console.log('[QR Redirect] Invalid target URL in response') + } + console.log('[QR Redirect] No redirect - falling through to normal routing') + // If 404 or any other status, fall through to normal routing + } catch (e) { + console.error('[QR Redirect] Error during redirect lookup:', e) + // Network error/timeout -> fall through to normal routing + } + } else { + console.log('[QR Redirect] Missing code or API base URL') + } + // If code missing or base missing, fall through + } // Set headers to disable caching for specified paths const response = NextResponse.next() @@ -82,5 +127,6 @@ export const config = { '/pay/:path*', '/p/:path*', '/link/:path*', + '/qr/:path*', ], }