@@ -413,14 +413,12 @@ export class AuthClient {
413413 }
414414 }
415415
416- /**
416+ /**
417417 * Proxy handler that routes to the appropriate proxy handler method
418418 * @param nextRequest The incoming NextRequest instance.
419419 * @returns A Promise that resolves to a NextResponse or undefined.
420420 */
421- async proxyHandler (
422- nextRequest : NextRequest ,
423- ) : Promise < NextResponse | void > {
421+ async proxyHandler ( nextRequest : NextRequest ) : Promise < NextResponse | void > {
424422 // Convert the incomming request to Auth0Request
425423 const auth0Req = new Auth0NextRequest ( nextRequest as NextRequest ) ;
426424 // Convert the incoming response to Auth0Response
@@ -485,7 +483,7 @@ export class AuthClient {
485483 nextRequest : NextRequest | NextApiRequest ,
486484 fallback ?: ( req : Auth0Request , res : Auth0Response ) => Promise < Auth0Response > ,
487485 nextResponse ?: NextApiResponse
488- ) : Promise < NextResponse | undefined > {
486+ ) : Promise < NextResponse | void > {
489487 // Convert the incomming request to Auth0Request
490488 const auth0Req = isRequest ( nextRequest )
491489 ? new Auth0NextRequest ( nextRequest as NextRequest )
@@ -554,14 +552,27 @@ export class AuthClient {
554552 }
555553
556554 /**
557- * Unwraps an Auth0Response by extracting the underlying NextResponse.
555+ * Unwraps an Auth0Response by extracting the underlying NextResponse, or calling `.end()` on the underlying NextApiResponse .
558556 * This utility simplifies the pattern of awaiting handler calls and accessing .res
557+ *
558+ * @param handler A function that returns a Promise resolving to an Auth0Response.
559+ * @returns A Promise that resolves to a NextResponse or void (in case of Pages Router usage).
559560 */
560561 async #unwrapHandler(
561562 handler : ( ) => Promise < Auth0Response >
562- ) : Promise < NextResponse > {
563+ ) : Promise < NextResponse | void > {
563564 const auth0Response = await handler ( ) ;
564- return auth0Response . res ;
565+ const response = auth0Response . res ;
566+ const canEndRequest =
567+ response && "end" in response && typeof response . end === "function" ;
568+
569+ // When the underlying response supports .end(), call it to finalize the response without returning the NextApiResponse instance.
570+ // NextResponse does not have .end(), instead we return the NextResponse instance.
571+ if ( canEndRequest ) {
572+ response . end ( ) ;
573+ } else {
574+ return response as NextResponse ;
575+ }
565576 }
566577
567578 async startInteractiveLogin (
@@ -806,14 +817,25 @@ export class AuthClient {
806817 auth0Req . getCookies ( ) ,
807818 state
808819 ) ;
820+
821+ const baseOnCallbackCtx : OnCallbackContext = {
822+ request : auth0Req . req ,
823+ response : isRequest ( auth0Req . req ) ? undefined : auth0Res . res
824+ } ;
825+
809826 if ( ! transactionStateCookie ) {
810- const errorRes = await this . onCallback ( new InvalidStateError ( ) , { } , null ) ;
827+ const errorRes = await this . onCallback (
828+ new InvalidStateError ( ) ,
829+ baseOnCallbackCtx ,
830+ null
831+ ) ;
811832 auth0Res . setResponse ( errorRes ) ;
812833 return auth0Res ;
813834 }
814835
815836 const transactionState = transactionStateCookie . payload ;
816837 const onCallbackCtx : OnCallbackContext = {
838+ ...baseOnCallbackCtx ,
817839 responseType : transactionState . responseType ,
818840 returnTo : transactionState . returnTo
819841 } ;
@@ -881,7 +903,7 @@ export class AuthClient {
881903 session
882904 ) ;
883905
884- auth0Res . setResponse ( res ) ;
906+ auth0Res . setResponse ( res ?? onCallbackCtx . response ) ;
885907 await this . transactionStore . delete ( auth0Res . getCookies ( ) , state ) ;
886908
887909 return auth0Res ;
@@ -1028,7 +1050,7 @@ export class AuthClient {
10281050 // if not then filter id_token claims with default rules
10291051 session = await this . finalizeSession ( session , oidcRes . id_token ) ;
10301052
1031- auth0Res . setResponse ( res ) ;
1053+ auth0Res . setResponse ( res ?? onCallbackCtx . response ) ;
10321054 await this . sessionStore . set (
10331055 auth0Req . getCookies ( ) ,
10341056 auth0Res . getCookies ( ) ,
@@ -1537,17 +1559,32 @@ export class AuthClient {
15371559 error : SdkError | null ,
15381560 ctx : OnCallbackContext
15391561 ) {
1540- if ( error ) {
1541- return new NextResponse ( error . message , {
1542- status : 500
1543- } ) ;
1544- }
1562+ const redirectUrl = createRouteUrl ( ctx . returnTo || "/" , this . appBaseUrl ) ;
15451563
1546- const res = NextResponse . redirect (
1547- createRouteUrl ( ctx . returnTo || "/" , this . appBaseUrl )
1548- ) ;
1564+ if ( ctx . request && isRequest ( ctx . request ) ) {
1565+ if ( error ) {
1566+ return new NextResponse ( error . message , {
1567+ status : 500
1568+ } ) ;
1569+ }
1570+
1571+ const res = NextResponse . redirect ( redirectUrl ) ;
15491572
1550- return res ;
1573+ return res ;
1574+ } else {
1575+ if ( error ) {
1576+ ctx . response ?. status ( 500 ) . send ( error . message ) ;
1577+ } else {
1578+ // We do not use ctx.response.redirect(), as that would call `res.end()` immediately.
1579+ // Even though that should be okay conceptually,
1580+ // it would require changing code to not set cookies after calling `onCallback()`,
1581+ // which is not in scope.
1582+
1583+ // This also means that anyone using a custom onCallback should not end the response themselves.
1584+ // If they would, the Set-Cookie headers set after onCallback would be ignored and the transaction cookie will not exist.
1585+ ctx . response ?. status ( 307 ) . setHeader ( "Location" , redirectUrl . toString ( ) ) ;
1586+ }
1587+ }
15511588 }
15521589
15531590 /**
@@ -1561,7 +1598,7 @@ export class AuthClient {
15611598 ) : Promise < Auth0Response > {
15621599 const response = await this . onCallback ( error , ctx , null ) ;
15631600
1564- auth0Res . setResponse ( response ) ;
1601+ auth0Res . setResponse ( response ?? ctx . response ) ;
15651602
15661603 // Clean up the transaction cookie on error to prevent accumulation
15671604 if ( state ) {
@@ -2953,4 +2990,4 @@ export async function buildConnectAccountErrorResponse(
29532990 null
29542991 ] ;
29552992 }
2956- }
2993+ }
0 commit comments