Refines the admin ban page with better dialog state management and feedback during ban/unban actions. Adds a product cloning feature to the products dashboard and updates the product table to support cloning. Improves error handling in ChatDetail for authentication errors, and enhances middleware to handle auth check timeouts and network errors more gracefully. Also updates BanUserCard to validate user ID and ensure correct request formatting.
107 lines
3.9 KiB
TypeScript
107 lines
3.9 KiB
TypeScript
import { NextResponse } from "next/server";
|
|
import type { NextRequest } from "next/server";
|
|
|
|
export async function middleware(req: NextRequest) {
|
|
const pathname = new URL(req.url).pathname;
|
|
|
|
// Skip auth check for password reset page
|
|
if (pathname.startsWith('/auth/reset-password')) {
|
|
return NextResponse.next();
|
|
}
|
|
|
|
// Check for auth token in cookies
|
|
const token = req.cookies.get("Authorization")?.value;
|
|
|
|
// Debug info about all cookies
|
|
const allCookies = req.cookies.getAll();
|
|
console.log("Middleware: All cookies:", allCookies.map(c => c.name).join(', '));
|
|
|
|
if (!token) {
|
|
// Try to get from Authorization header as fallback
|
|
const authHeader = req.headers.get('Authorization');
|
|
|
|
if (authHeader?.startsWith('Bearer ')) {
|
|
console.log("Middleware: Token found in Authorization header");
|
|
// Continue with validation using header auth
|
|
// The authCheckUrl will handle extracting the token from header
|
|
} else {
|
|
console.log("Middleware: No token found in cookies or headers, redirecting to login...");
|
|
return NextResponse.redirect(new URL("/auth/login", req.url));
|
|
}
|
|
} else {
|
|
console.log("Middleware: Token found in cookies, validating...");
|
|
}
|
|
|
|
try {
|
|
// Always use localhost for internal container communication
|
|
const authCheckUrl = "http://localhost:3000/api/auth/check";
|
|
|
|
console.log(`Using internal auth check URL: ${authCheckUrl}`);
|
|
|
|
// Clone headers to avoid modifying the original request
|
|
const headers = new Headers(req.headers);
|
|
|
|
// If token is in cookie, ensure it's also in Authorization header
|
|
if (token && !headers.has('Authorization')) {
|
|
headers.set('Authorization', `Bearer ${token}`);
|
|
}
|
|
|
|
let res: Response;
|
|
try {
|
|
res = await fetch(authCheckUrl, {
|
|
method: "GET",
|
|
headers,
|
|
credentials: 'include',
|
|
signal: AbortSignal.timeout(15000), // 15 second timeout (increased for slower connections)
|
|
});
|
|
} catch (fetchError) {
|
|
// Handle timeout or network errors gracefully
|
|
console.error("Middleware: Auth check request failed:", fetchError);
|
|
|
|
// If it's a timeout or network error, don't redirect - let the request proceed
|
|
// The page will handle auth errors client-side
|
|
if (fetchError instanceof Error && fetchError.name === 'TimeoutError') {
|
|
console.log("Middleware: Auth check timed out, allowing request to proceed");
|
|
return NextResponse.next();
|
|
}
|
|
|
|
// For other network errors, redirect to login
|
|
return NextResponse.redirect(new URL("/auth/login", req.url));
|
|
}
|
|
|
|
console.log(`Middleware: Auth check responded with status ${res.status}`);
|
|
|
|
if (!res.ok) {
|
|
console.log(`Middleware: Auth check failed with status ${res.status}, redirecting to login`);
|
|
return NextResponse.redirect(new URL("/auth/login", req.url));
|
|
}
|
|
|
|
console.log("Middleware: Auth check successful");
|
|
|
|
// Admin-only protection for /dashboard/admin routes
|
|
// Clone the response before reading it to avoid consuming the body
|
|
if (pathname.startsWith('/dashboard/admin')) {
|
|
try {
|
|
const clonedRes = res.clone();
|
|
const user = await clonedRes.json();
|
|
const username = user?.vendor?.username;
|
|
if (username !== 'admin1') {
|
|
console.log("Middleware: Non-admin attempted to access /dashboard/admin, redirecting");
|
|
return NextResponse.redirect(new URL("/dashboard", req.url));
|
|
}
|
|
} catch (e) {
|
|
console.log("Middleware: Failed to parse user for admin check, redirecting to login");
|
|
return NextResponse.redirect(new URL("/auth/login", req.url));
|
|
}
|
|
}
|
|
} catch (error) {
|
|
console.error("Authentication validation failed:", error);
|
|
return NextResponse.redirect(new URL("/auth/login", req.url));
|
|
}
|
|
|
|
return NextResponse.next();
|
|
}
|
|
|
|
export const config = {
|
|
matcher: ["/dashboard/:path*", "/auth/reset-password/:path*"],
|
|
}; |