@@ -32,6 +32,44 @@ import { DEFAULT_CSP } from "../../../constants/csp";
3232// NOTE: Route segment configs (dynamic, revalidate, fetchCache) removed for Next.js 15.6+ compatibility
3333// With dynamicIO enabled, route handlers are dynamic by default
3434
35+ const gotoError = ( {
36+ request,
37+ title,
38+ error,
39+ } : {
40+ request : NextRequest ;
41+ title : string ;
42+ error : string ;
43+ } ) : NextResponse < unknown > => {
44+ const errorUrl = constructUrl ( request , "/error" ) ;
45+ errorUrl . searchParams . set ( "title" , title ) ;
46+ errorUrl . searchParams . set ( "error" , error ) ;
47+ return NextResponse . redirect ( errorUrl ) ;
48+ } ;
49+
50+ const getAuthRequestErrorMessage = ( error : unknown ) : string => {
51+ const code =
52+ error != null &&
53+ typeof error === "object" &&
54+ "code" in error &&
55+ typeof ( error as { code : unknown } ) . code === "number"
56+ ? ( error as { code : number } ) . code
57+ : undefined ;
58+
59+ switch ( code ) {
60+ case 5 : // NOT_FOUND
61+ return "Your login session has expired. Please return to the application and try signing in again." ;
62+ case 7 : // PERMISSION_DENIED
63+ return "You don't have permission to access this login request. Please contact your administrator." ;
64+ case 14 : // UNAVAILABLE
65+ return "The authentication service is temporarily unavailable. Please try again in a few moments." ;
66+ case 4 : // DEADLINE_EXCEEDED
67+ return "The authentication service took too long to respond. Please try again." ;
68+ default :
69+ return "Your login request could not be found or has expired. Please return to the application and try signing in again." ;
70+ }
71+ } ;
72+
3573const gotoAccounts = ( {
3674 request,
3775 requestId,
@@ -134,10 +172,29 @@ export async function GET(request: NextRequest) {
134172
135173 // continue with OIDC
136174 if ( requestId && requestId . startsWith ( "oidc_" ) ) {
137- const { authRequest } = await getAuthRequest ( {
138- serviceUrl,
139- authRequestId : requestId . replace ( "oidc_" , "" ) ,
140- } ) ;
175+ let authRequest ;
176+ try {
177+ ( { authRequest } = await getAuthRequest ( {
178+ serviceUrl,
179+ authRequestId : requestId . replace ( "oidc_" , "" ) ,
180+ } ) ) ;
181+ } catch ( error ) {
182+ console . error ( "Failed to get auth request:" , error ) ;
183+ return gotoError ( {
184+ request,
185+ title : "Login request expired" ,
186+ error : getAuthRequestErrorMessage ( error ) ,
187+ } ) ;
188+ }
189+
190+ if ( ! authRequest ) {
191+ return gotoError ( {
192+ request,
193+ title : "Login request not found" ,
194+ error :
195+ "Your login request could not be found. Please return to the application and try signing in again." ,
196+ } ) ;
197+ }
141198
142199 let organization = "" ;
143200 let suffix = "" ;
@@ -232,10 +289,12 @@ export async function GET(request: NextRequest) {
232289 } ) ;
233290
234291 if ( ! url ) {
235- return NextResponse . json (
236- { error : "Could not start IDP flow" } ,
237- { status : 500 } ,
238- ) ;
292+ return gotoError ( {
293+ request,
294+ title : "Sign-in unavailable" ,
295+ error :
296+ "We couldn't connect to your identity provider. Please try again or contact your administrator." ,
297+ } ) ;
239298 }
240299
241300 if ( url . startsWith ( "/" ) ) {
@@ -471,10 +530,12 @@ export async function GET(request: NextRequest) {
471530 } ) ;
472531
473532 if ( ! samlRequest ) {
474- return NextResponse . json (
475- { error : "No samlRequest found" } ,
476- { status : 400 } ,
477- ) ;
533+ return gotoError ( {
534+ request,
535+ title : "Login request not found" ,
536+ error :
537+ "Your SAML login request could not be found or has expired. Please return to the application and try signing in again." ,
538+ } ) ;
478539 }
479540
480541 let selectedSession = await findValidSession ( {
@@ -558,9 +619,11 @@ export async function GET(request: NextRequest) {
558619 }
559620 // Device Authorization does not need to start here as it is handled on the /device endpoint
560621 else {
561- return NextResponse . json (
562- { error : "No authRequest nor samlRequest provided" } ,
563- { status : 500 } ,
564- ) ;
622+ return gotoError ( {
623+ request,
624+ title : "No login request" ,
625+ error :
626+ "No authentication request was provided. Please start the sign-in process from your application." ,
627+ } ) ;
565628 }
566629}
0 commit comments