// server/middleware/auth.ts import { defineEventHandler, useSession } from 'h3'; import prisma from '../utils/prisma'; import { getTodayDay, isBeforeDay } from '../utils/gameDay'; import { calculateDailyStreak } from '../utils/streak'; const ANONYMOUS_COOKIE_NAME = 'smurf-anonymous-session'; /** * Global server middleware to populate `event.context.user` for every incoming request. * * It first checks for a logged-in user session. If not found, it checks for an * anonymous user session cookie. It attaches the corresponding user object to * `event.context.user` if found. It does NOT block requests, allowing auth * checks to be handled by individual endpoints. */ export default defineEventHandler(async (event) => { // This middleware should not run on static assets or internal requests. const path = event.path || ''; if (path.startsWith('/_nuxt') || path.startsWith('/__nuxt_error')) { return; } // 1. Check for a logged-in user session const session = await useSession(event, { password: process.env.SESSION_PASSWORD!, }); const userId = session.data?.user?.id; if (userId) { try { const user = await prisma.user.findUnique({ where: { id: userId }, // Find any user by their ID first }); // A permanent user is identified by having an email address. if (user && user.email) { event.context.user = user; // Track daily visit and streak const today = getTodayDay(); const lastVisitDay = session.data.lastVisitDay as string | undefined; if (isBeforeDay(lastVisitDay, today)) { // It's a new day, calculate streak and record visit const updatedUser = await calculateDailyStreak(prisma, user.id); event.context.user = updatedUser; // Ensure context has the latest user data // Update the session to prevent re-running this today await session.update({ ...session.data, lastVisitDay: today, }); } return; // Found a logged-in user, no need to check for anonymous session } } catch (error) { console.error('Error in auth middleware:', error); } } // 2. If no logged-in user, check for an anonymous session const anonymousSessionId = getCookie(event, ANONYMOUS_COOKIE_NAME); if (anonymousSessionId) { try { const anonymousUser = await prisma.user.findUnique({ where: { anonymousSessionId: anonymousSessionId, isAnonymous: true }, }); if (anonymousUser) { event.context.user = anonymousUser; } } catch (error) { console.error('Error fetching anonymous user in auth middleware:', error); } } });