From e3e630c211a637a155b6d3bec0dba7288c1947c6 Mon Sep 17 00:00:00 2001 From: NotII <46204250+NotII@users.noreply.github.com> Date: Sun, 23 Mar 2025 22:14:05 +0000 Subject: [PATCH] fix --- app/api/auth/check/route.ts | 45 ++++++++++-- app/auth/login/page.tsx | 136 +++--------------------------------- middleware.ts | 15 +++- 3 files changed, 61 insertions(+), 135 deletions(-) diff --git a/app/api/auth/check/route.ts b/app/api/auth/check/route.ts index 6766ee2..0a6fe99 100644 --- a/app/api/auth/check/route.ts +++ b/app/api/auth/check/route.ts @@ -2,17 +2,29 @@ import { NextRequest, NextResponse } from 'next/server'; export async function GET(req: NextRequest) { try { - const token = req.cookies.get('Authorization')?.value; + // Check for Authorization in headers first, then fall back to cookies + let token = req.headers.get('Authorization')?.replace('Bearer ', ''); + + // If not in headers, check cookies + if (!token) { + token = req.cookies.get('Authorization')?.value; + console.log('Auth check: Token from cookies'); + } else { + console.log('Auth check: Token from headers'); + } if (!token) { + console.log('Auth check failed: No Authorization token found'); return NextResponse.json( { error: 'No authorization token found' }, { status: 401 } ); } + console.log('Auth check: Token found -', token.substring(0, 15) + '...'); + const apiUrl = process.env.SERVER_API_URL || 'https://internal-api.inboxi.ng/api'; - console.log(`Server auth check calling: ${apiUrl}/auth/me`); + console.log(`Auth check: Calling external API: ${apiUrl}/auth/me`); const res = await fetch(`${apiUrl}/auth/me`, { method: 'GET', @@ -20,24 +32,45 @@ export async function GET(req: NextRequest) { 'Content-Type': 'application/json', 'Authorization': `Bearer ${token}` }, - // This is a server component, so we can use Node.js options if needed - // (though we'll avoid for compatibility) + cache: 'no-store' }); + console.log('Auth check: External API response status:', res.status); + if (!res.ok) { + try { + const errorData = await res.json(); + console.log('Auth check failed:', { + status: res.status, + statusText: res.statusText, + body: errorData + }); + } catch { + const errorText = await res.text().catch(() => 'No response body'); + console.log('Auth check failed:', { + status: res.status, + statusText: res.statusText, + body: errorText + }); + } + return NextResponse.json( - { error: 'Authentication failed' }, + { error: 'Authentication failed', details: res.statusText }, { status: res.status } ); } const data = await res.json(); + console.log('Auth check succeeded:', { userId: data._id || 'unknown' }); return NextResponse.json(data); } catch (error) { console.error('Auth check error:', error); return NextResponse.json( - { error: 'Failed to validate authentication' }, + { + error: 'Failed to validate authentication', + details: error instanceof Error ? error.message : String(error) + }, { status: 500 } ); } diff --git a/app/auth/login/page.tsx b/app/auth/login/page.tsx index f99bc86..9b8fc7f 100644 --- a/app/auth/login/page.tsx +++ b/app/auth/login/page.tsx @@ -1,13 +1,9 @@ -"use client"; -import { fetchData } from "@/lib/data-service"; -import { clientFetch } from "@/lib/client-utils"; +"use client" import { useState, useEffect } from "react"; -import { useRouter } from "next/navigation"; -import Image from "next/image"; +import { useRouter, useSearchParams } from "next/navigation"; import Link from "next/link"; import { Button } from "@/components/ui/button"; -import { Checkbox } from "@/components/ui/checkbox"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { toast } from "sonner"; @@ -16,18 +12,9 @@ export default function LoginPage() { const [username, setUsername] = useState(""); const [password, setPassword] = useState(""); const [isLoading, setIsLoading] = useState(false); - const [isRedirecting, setIsRedirecting] = useState(false); - const [authStatus, setAuthStatus] = useState<{ - loading: boolean; - progress: number; - message: string; - }>({ - loading: false, - progress: 0, - message: "Preparing your session..." - }); - const [error, setError] = useState(""); const router = useRouter(); + const searchParams = useSearchParams(); + const redirectUrl = searchParams.get("redirectUrl") || "/dashboard"; // Check if already logged in useEffect(() => { @@ -41,116 +28,37 @@ export default function LoginPage() { } }, [router]); - // Function to verify authentication and prepare navigation - const prepareNavigation = async (token: string) => { - try { - setAuthStatus(prev => ({ - ...prev, - loading: true, - message: "Verifying your credentials..." - })); - - // Step 1: Verify token is valid by making a simple auth check - // This ensures we don't redirect with an invalid token - await clientFetch("/auth/me", { - headers: { Authorization: `Bearer ${token}` } - }); - - setAuthStatus(prev => ({ - ...prev, - progress: 50, - message: "Authentication successful!" - })); - - // Slight delay to show success message - await new Promise(resolve => setTimeout(resolve, 300)); - - setAuthStatus(prev => ({ - ...prev, - progress: 100, - message: "Redirecting to dashboard..." - })); - - // Tell Next.js to prefetch the dashboard page - // This helps with faster page load but doesn't affect server data fetching - router.prefetch('/dashboard'); - - // Short delay to show completion - await new Promise(resolve => setTimeout(resolve, 500)); - - // Redirect to dashboard - router.push("/dashboard"); - - // Fallback redirect if router.push fails - setTimeout(() => { - window.location.href = "/dashboard"; - }, 1000); - - } catch (error) { - console.error("Authentication verification error:", error); - - // Even if verification fails, still try to redirect - // The dashboard will handle invalid auth - setAuthStatus(prev => ({ - ...prev, - progress: 100, - message: "Authentication issue, redirecting anyway..." - })); - - toast.warning("Authentication issue detected", { - description: "You may need to log in again if the dashboard doesn't load." - }); - - // Still redirect - setTimeout(() => { - router.push("/dashboard"); - // Ultimate fallback - setTimeout(() => { - window.location.href = "/dashboard"; - }, 1000); - }, 500); - } - }; - async function handleLogin(e: React.FormEvent) { e.preventDefault(); - - if (isLoading || isRedirecting) return; - setIsLoading(true); try { - const response = await fetch(`/api/auth/login`, { + // Using fetch directly with the proxy path + const response = await fetch("/api/auth/login", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ username, password }), - credentials: "include", }); const data = await response.json(); if (response.ok && data.token) { - // Set redirecting state to prevent multiple redirect attempts - setIsRedirecting(true); - // Store the token in both cookie and localStorage for redundancy document.cookie = `Authorization=${data.token}; path=/; Secure; SameSite=Strict; max-age=604800`; localStorage.setItem("Authorization", data.token); - // Show toast before redirect toast.success("Login successful"); - // Now verify auth and handle redirect - await prepareNavigation(data.token); + // Redirect to dashboard or the original redirect URL + router.push(redirectUrl); } else { - // Handle HTTP error responses (including 401) + // Handle HTTP error responses const errorMessage = data.error || "Invalid credentials"; toast.error("Login Failed", { description: errorMessage, }); } } catch (error) { - // This will now only catch network errors or JSON parsing errors toast.error("Connection Error", { description: "Unable to connect to the server. Please check your internet connection and try again.", }); @@ -160,30 +68,6 @@ export default function LoginPage() { } } - // If already redirecting, show loading state with progress - if (isRedirecting) { - return ( -
-
-

Logging in

-

{authStatus.message}

- - {/* Progress bar */} -
-
-
- -
-
-
-
-
- ); - } - return (
@@ -222,7 +106,7 @@ export default function LoginPage() {
- diff --git a/middleware.ts b/middleware.ts index bee9248..30baafd 100644 --- a/middleware.ts +++ b/middleware.ts @@ -5,31 +5,40 @@ export async function middleware(req: NextRequest) { const token = req.cookies.get("Authorization")?.value; if (!token) { - console.log("No token found, redirecting to login..."); + console.log("Middleware: No token found, redirecting to login..."); return NextResponse.redirect(new URL("/auth/login", req.url)); } + console.log("Middleware: Token found, validating..."); + try { // Use our internal API route that handles the auth check server-side // This avoids SSL issues as it's a same-origin request const origin = req.nextUrl.origin; const authCheckUrl = `${origin}/api/auth/check`; - console.log(`Using internal auth check URL: ${authCheckUrl}`); + console.log(`Middleware: Using internal auth check URL: ${authCheckUrl}`); const res = await fetch(authCheckUrl, { method: "GET", headers: { "Content-Type": "application/json", + // Explicitly pass the token in headers as well + "Authorization": `Bearer ${token}` }, credentials: 'include', }); + 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, proceeding to dashboard"); } catch (error) { - console.error("Authentication validation failed:", error); + console.error("Middleware: Authentication validation failed:", error); return NextResponse.redirect(new URL("/auth/login", req.url)); }