fix: integrate Better Auth session data instead of mock data

- Replace demo user data with actual Better Auth session data
- Update session endpoint to use auth.api.getSession() for real user info
- Fix UserProfile component to display actual user profile in header
- Improve logout functionality with proper state cleanup
- Add event listeners for OAuth state changes

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Rosario Moscato
2025-09-29 15:02:23 +02:00
parent 5270bbd40a
commit ada01d0c86
3 changed files with 61 additions and 43 deletions

View File

@@ -1,31 +1,27 @@
import { NextResponse } from "next/server";
// Mock session data for demo purposes
// In a real app, this would check the actual Better Auth session
const mockSession = {
user: {
id: "demo-user-123",
name: "Demo User",
email: "demo@example.com",
emailVerified: true,
image: "https://via.placeholder.com/40"
},
expires: new Date(Date.now() + 24 * 60 * 60 * 1000).toISOString()
};
import { auth } from "@/lib/auth";
export async function GET(request: Request) {
try {
// For demo purposes, we'll always return an authenticated user
// This simulates a successful OAuth login scenario
// In a real implementation, you would:
// 1. Check for valid session cookies/tokens
// 2. Validate the session with Better Auth
// 3. Return the actual user data
// Use Better Auth to get the actual session
const session = await auth.api.getSession({
headers: request.headers,
});
if (session?.user) {
return NextResponse.json({
session: {
user: session.user,
expires: session.session?.expiresAt
},
user: session.user
});
}
// If no session found, return not authenticated
return NextResponse.json({
session: mockSession,
user: mockSession.user
session: null,
user: null
});
} catch (error) {
console.error("Session check error:", error);

View File

@@ -1,7 +1,7 @@
"use client";
import { useSession, signOut } from "@/lib/auth-client";
import { SignInButton } from "./sign-in-button";
import { useAuth } from "@/hooks/use-auth";
import { Button } from "@/components/ui/button";
import { Avatar, AvatarImage, AvatarFallback } from "@/components/ui/avatar";
import {
DropdownMenu,
@@ -12,29 +12,25 @@ import {
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
import Link from "next/link";
import { useRouter } from "next/navigation";
import { User, LogOut } from "lucide-react";
export function UserProfile() {
const { data: session, isPending } = useSession();
const router = useRouter();
const { user, isAuthenticated, isLoading, login, logout } = useAuth();
if (isPending) {
if (isLoading) {
return <div>Loading...</div>;
}
if (!session) {
if (!isAuthenticated || !user) {
return (
<div className="flex flex-col items-center gap-4 p-6">
<SignInButton />
</div>
<Button onClick={login} variant="outline">
Sign in
</Button>
);
}
const handleSignOut = async () => {
await signOut();
router.replace("/");
router.refresh();
await logout();
};
return (
@@ -42,14 +38,14 @@ export function UserProfile() {
<DropdownMenuTrigger asChild>
<Avatar className="size-8 cursor-pointer hover:opacity-80 transition-opacity">
<AvatarImage
src={session.user?.image || ""}
alt={session.user?.name || "User"}
src={user?.image || ""}
alt={user?.name || "User"}
referrerPolicy="no-referrer"
/>
<AvatarFallback>
{(
session.user?.name?.[0] ||
session.user?.email?.[0] ||
user?.name?.[0] ||
user?.email?.[0] ||
"U"
).toUpperCase()}
</AvatarFallback>
@@ -59,10 +55,10 @@ export function UserProfile() {
<DropdownMenuLabel className="font-normal">
<div className="flex flex-col space-y-1">
<p className="text-sm font-medium leading-none">
{session.user?.name}
{user?.name}
</p>
<p className="text-xs leading-none text-muted-foreground">
{session.user?.email}
{user?.email}
</p>
</div>
</DropdownMenuLabel>

View File

@@ -82,6 +82,22 @@ export function AuthProvider({ children }: AuthProviderProps) {
};
checkAuth();
// Add a listener for auth state changes (for OAuth callbacks)
const handleAuthChange = () => {
checkAuth();
};
// Listen for storage changes (in case user logs in from another tab)
window.addEventListener('storage', handleAuthChange);
// Custom event for OAuth completion
window.addEventListener('auth-state-changed', handleAuthChange);
return () => {
window.removeEventListener('storage', handleAuthChange);
window.removeEventListener('auth-state-changed', handleAuthChange);
};
}, []);
const login = async () => {
@@ -117,11 +133,21 @@ export function AuthProvider({ children }: AuthProviderProps) {
try {
// Call server-side logout endpoint
await fetch("/api/auth/logout", { method: "POST" });
// Clear all auth-related data
setUser(null);
localStorage.removeItem("moneymind-session");
window.location.href = "/";
sessionStorage.clear();
// Force reload to clear any cached state
window.location.reload();
} catch (error) {
console.error("Logout error:", error);
// Even if server call fails, clear local state and reload
setUser(null);
localStorage.removeItem("moneymind-session");
sessionStorage.clear();
window.location.reload();
}
};