feat: integrate feedback module
This commit is contained in:
66
proxy.ts
Normal file
66
proxy.ts
Normal file
@@ -0,0 +1,66 @@
|
||||
import createMiddleware from 'next-intl/middleware';
|
||||
import { NextResponse, NextRequest } from 'next/server';
|
||||
|
||||
// Create the internationalization middleware
|
||||
const intlMiddleware = createMiddleware({
|
||||
// A list of all locales that are supported
|
||||
locales: ['en', 'de'],
|
||||
|
||||
// Used when no locale matches
|
||||
defaultLocale: 'en',
|
||||
});
|
||||
|
||||
export default function middleware(request: NextRequest) {
|
||||
const { method, url, headers } = request;
|
||||
|
||||
// Build header object for logging
|
||||
const headerObj: Record<string, string> = {};
|
||||
headers.forEach((value, key) => {
|
||||
headerObj[key] = value;
|
||||
});
|
||||
|
||||
// Defensive URL correction for internal container leakage (0.0.0.0, klz-app, localhost)
|
||||
// This prevents hydration mismatches and host poisoning in generated links/metadata.
|
||||
const urlObj = new URL(url);
|
||||
const internalHosts = ['0.0.0.0', 'klz-app', 'localhost', '127.0.0.1'];
|
||||
|
||||
let effectiveRequest = request;
|
||||
if (internalHosts.includes(urlObj.hostname)) {
|
||||
const proto = headers.get('x-forwarded-proto') || 'https';
|
||||
// Prioritize x-forwarded-host (passed by Traefik) over the local Host header
|
||||
const hostHeader =
|
||||
headers.get('x-forwarded-host') || headers.get('host') || 'testing.klz-cables.com';
|
||||
const [publicHostname] = hostHeader.split(':');
|
||||
|
||||
urlObj.protocol = proto;
|
||||
// urlObj.hostname = publicHostname; // Don't rewrite hostname yet as it breaks internal fetches in dev
|
||||
// urlObj.port = ''; // DON'T clear internal port (3000) anymore
|
||||
|
||||
effectiveRequest = new NextRequest(urlObj, {
|
||||
headers: request.headers,
|
||||
method: request.method,
|
||||
body: request.body,
|
||||
});
|
||||
|
||||
console.log(
|
||||
`🛡️ Middleware: Fixed internal URL leak: ${url} -> ${urlObj.toString()} | Proto: ${proto} | Host: ${hostHeader}`,
|
||||
);
|
||||
}
|
||||
|
||||
try {
|
||||
// Apply internationalization middleware
|
||||
const response = intlMiddleware(effectiveRequest);
|
||||
return response;
|
||||
} catch (error) {
|
||||
console.error(
|
||||
`Request failed: method=${method} url=${url} headers=${JSON.stringify(headerObj)}`,
|
||||
error,
|
||||
);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
export const config = {
|
||||
// Match only internationalized pathnames
|
||||
matcher: ['/((?!api|_next|_vercel|stats|errors|health|.*\\..*).*)', '/', '/(de|en)/:path*'],
|
||||
};
|
||||
Reference in New Issue
Block a user