From aae25a0959cf8f3e9c9cae18913e2663ca1cb9eb Mon Sep 17 00:00:00 2001 From: DJP Date: Tue, 14 Apr 2026 13:00:01 -0400 Subject: [PATCH] Fix SSO redirect URI to include basePath via redirectProxyUrl Auth.js route matching needs basePath="/api/auth" (Next.js strips /hp-prod-tracker from the internal request). But the OAuth redirect_uri sent to Microsoft must include the full external path. Uses redirectProxyUrl to explicitly set the callback URL to {AUTH_URL}/api/auth/callback/microsoft-entra-id, which includes the /hp-prod-tracker basePath. Pins basePath="/api/auth" so AUTH_URL's pathname doesn't override route matching. Co-Authored-By: Claude Opus 4.6 --- src/lib/auth.ts | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/lib/auth.ts b/src/lib/auth.ts index 20cc9ab..f90bc66 100644 --- a/src/lib/auth.ts +++ b/src/lib/auth.ts @@ -4,7 +4,18 @@ import { PrismaAdapter } from "@auth/prisma-adapter"; import { prisma } from "@/lib/prisma"; import type { Role } from "@/generated/prisma/client"; +// Build the OAuth redirect proxy URL so the callback includes the Next.js +// basePath (/hp-prod-tracker). Auth.js route matching uses basePath="/api/auth" +// (without the prefix), but the redirect_uri sent to Microsoft must include it. +const redirectProxyUrl = process.env.AUTH_URL + ? `${process.env.AUTH_URL}/api/auth` + : undefined; + export const { handlers, auth, signIn, signOut } = NextAuth({ + // Explicit basePath prevents AUTH_URL's pathname from overriding it. + // Next.js strips the /hp-prod-tracker prefix before Auth.js sees the request, + // so internally routes must match /api/auth/*. + basePath: "/api/auth", adapter: PrismaAdapter(prisma), providers: [ MicrosoftEntraID({ @@ -14,6 +25,8 @@ export const { handlers, auth, signIn, signOut } = NextAuth({ // Safe for Entra ID — Microsoft verifies organizational emails. // Required to link SSO accounts to pre-seeded User records by email match. allowDangerousEmailAccountLinking: true, + // Include the Next.js basePath in the OAuth redirect URI + redirectProxyUrl, }), ], session: {