fix(auth): resolve middleware Edge Runtime + layout redirect loop
Two bugs: 1. auth.ts imported postgres (Node.js TCP) which crashes in Edge Runtime, causing Auth.js to silently fall back to redirecting all requests to login. Fix: split into auth.config.ts (Edge-safe, no DB) used by middleware, and auth.ts (full, with DB) used by server components. 2. /agent/layout.tsx applied to /agent/login, so unauthenticated login page visits redirected to themselves in an infinite loop. Fix: moved dashboard + layout into (protected) route group so login page has no auth layout. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
44
teressa-copeland-homes/src/lib/auth.config.ts
Normal file
44
teressa-copeland-homes/src/lib/auth.config.ts
Normal file
@@ -0,0 +1,44 @@
|
||||
import type { NextAuthConfig } from "next-auth";
|
||||
|
||||
/**
|
||||
* Edge-compatible auth config — no DB imports.
|
||||
* Used by middleware.ts (Edge Runtime).
|
||||
* Full auth.ts adds the Credentials provider with DB access.
|
||||
*/
|
||||
export const authConfig = {
|
||||
session: {
|
||||
strategy: "jwt",
|
||||
maxAge: 7 * 24 * 60 * 60,
|
||||
updateAge: 24 * 60 * 60,
|
||||
},
|
||||
pages: {
|
||||
signIn: "/agent/login",
|
||||
},
|
||||
providers: [], // Providers added in auth.ts — not needed for middleware JWT check
|
||||
callbacks: {
|
||||
authorized({ auth, request: { nextUrl } }) {
|
||||
const isLoggedIn = !!auth?.user;
|
||||
const isLoginPage = nextUrl.pathname === "/agent/login";
|
||||
const isAgentRoute = nextUrl.pathname.startsWith("/agent");
|
||||
|
||||
if (isLoginPage) {
|
||||
if (isLoggedIn) return Response.redirect(new URL("/agent/dashboard", nextUrl.origin));
|
||||
return true; // Always allow unauthenticated access to login page
|
||||
}
|
||||
|
||||
if (isAgentRoute) {
|
||||
return isLoggedIn; // Redirect unauthenticated users to login
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
jwt({ token, user }) {
|
||||
if (user) token.id = user.id;
|
||||
return token;
|
||||
},
|
||||
session({ session, token }) {
|
||||
session.user.id = token.id as string;
|
||||
return session;
|
||||
},
|
||||
},
|
||||
} satisfies NextAuthConfig;
|
||||
@@ -5,6 +5,7 @@ import { users } from "@/lib/db/schema";
|
||||
import { eq } from "drizzle-orm";
|
||||
import bcrypt from "bcryptjs";
|
||||
import { z } from "zod";
|
||||
import { authConfig } from "./auth.config";
|
||||
|
||||
const loginSchema = z.object({
|
||||
email: z.string().email(),
|
||||
@@ -12,14 +13,7 @@ const loginSchema = z.object({
|
||||
});
|
||||
|
||||
export const { handlers, auth, signIn, signOut } = NextAuth({
|
||||
session: {
|
||||
strategy: "jwt",
|
||||
maxAge: 7 * 24 * 60 * 60, // 7 days — rolling session per user decision
|
||||
updateAge: 24 * 60 * 60, // Refresh cookie once per day (not every request)
|
||||
},
|
||||
pages: {
|
||||
signIn: "/agent/login", // Custom login page — per user decision
|
||||
},
|
||||
...authConfig,
|
||||
providers: [
|
||||
Credentials({
|
||||
async authorize(credentials) {
|
||||
@@ -44,14 +38,4 @@ export const { handlers, auth, signIn, signOut } = NextAuth({
|
||||
},
|
||||
}),
|
||||
],
|
||||
callbacks: {
|
||||
jwt({ token, user }) {
|
||||
if (user) token.id = user.id;
|
||||
return token;
|
||||
},
|
||||
session({ session, token }) {
|
||||
session.user.id = token.id as string;
|
||||
return session;
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user