Refactor login flow with reset token support
All checks were successful
Automated Container Build / build-and-push (push) Successful in 1m6s

This commit is contained in:
Elijah 2026-07-12 07:53:48 -07:00
parent f0548bcc6e
commit 95af276d2e
11 changed files with 679 additions and 226 deletions

50
src/proxy.ts Normal file
View file

@ -0,0 +1,50 @@
import { NextRequest, NextResponse } from "next/server";
import { getIronSession } from "iron-session";
import type { SessionData } from "@/lib/auth";
import { prisma } from "@/lib/db";
const sessionOptions = {
password:
process.env.SESSION_SECRET ||
"dev-session-secret-change-in-production-must-be-32-chars",
cookieName: "study-app-session",
};
const publicPaths = ["/login", "/api/auth", "/shared"];
export async function proxy(request: NextRequest) {
const { pathname } = request.nextUrl;
if (publicPaths.some((path) => pathname.startsWith(path))) {
return NextResponse.next();
}
if (
pathname.startsWith("/_next") ||
pathname.startsWith("/favicon") ||
pathname.includes(".")
) {
return NextResponse.next();
}
const response = NextResponse.next();
const session = await getIronSession<SessionData>(request, response, sessionOptions);
const generationSetting = await prisma.setting.findUnique({
where: { key: "auth_session_generation" },
});
const currentGeneration = Number.parseInt(generationSetting?.value ?? "1", 10);
if (
!session.isAuthenticated ||
session.sessionGeneration !== currentGeneration
) {
session.destroy();
return NextResponse.redirect(new URL("/login", request.url));
}
return response;
}
export const config = {
matcher: ["/((?!_next/static|_next/image|favicon.ico).*)"],
};