diff --git a/apps/nextjs/src/app/api/auth/[...nextauth]/route.ts b/apps/nextjs/src/app/api/auth/[...nextauth]/route.ts index 22ddf2c..cb1269c 100644 --- a/apps/nextjs/src/app/api/auth/[...nextauth]/route.ts +++ b/apps/nextjs/src/app/api/auth/[...nextauth]/route.ts @@ -25,9 +25,46 @@ function rewriteRequestUrlInDevelopment(req: NextRequest) { return new NextRequest(newURL, req); } -export const POST = async (_req: NextRequest) => { +async function handleExpoSigninCallback(req: NextRequest, redirectURL: string) { + cookies().delete(EXPO_COOKIE_NAME); + + // Run original handler, then extract the session token from the response + // Send it back via a query param in the Expo deep link. The Expo app + // will then get that and set it in the session storage. + const authResponse = await handlers.POST(req); + const setCookie = authResponse.headers + .getSetCookie() + .find((cookie) => AUTH_COOKIE_PATTERN.test(cookie)); + const match = setCookie?.match(AUTH_COOKIE_PATTERN)?.[1]; + + if (!match) + throw new Error( + "Unable to find session cookie: " + + JSON.stringify(authResponse.headers.getSetCookie()), + ); + + const url = new URL(redirectURL); + url.searchParams.set("session_token", match); + + return NextResponse.redirect(url); +} + +export const POST = async ( + _req: NextRequest, + props: { params: { nextauth: string[] } }, +) => { // First step must be to correct the request URL. const req = rewriteRequestUrlInDevelopment(_req); + + const nextauthAction = props.params.nextauth[0]; + const isExpoCallback = cookies().get(EXPO_COOKIE_NAME); + + // callback handler required separately in the POST handler + // since Apple sends a POST request instead of a GET + if (nextauthAction === "callback" && !!isExpoCallback) { + return handleExpoSigninCallback(req, isExpoCallback.value); + } + return handlers.POST(req); }; @@ -54,26 +91,7 @@ export const GET = async ( } if (nextauthAction === "callback" && !!isExpoCallback) { - cookies().delete(EXPO_COOKIE_NAME); - - // Run original handler, then extract the session token from the response - // Send it back via a query param in the Expo deep link. The Expo app - // will then get that and set it in the session storage. - const authResponse = await handlers.GET(req); - const setCookie = authResponse.headers - .getSetCookie() - .find((cookie) => AUTH_COOKIE_PATTERN.test(cookie)); - const match = setCookie?.match(AUTH_COOKIE_PATTERN)?.[1]; - - if (!match) - throw new Error( - "Unable to find session cookie: " + - JSON.stringify(authResponse.headers.getSetCookie()), - ); - - const url = new URL(isExpoCallback.value); - url.searchParams.set("session_token", match); - return NextResponse.redirect(url); + return handleExpoSigninCallback(req, isExpoCallback.value); } // Every other request just calls the default handler