Skip to content

Commit 3146fb1

Browse files
committed
fix: avoid race condition in oauth callback and route protection
1 parent 91bbddf commit 3146fb1

File tree

1 file changed

+32
-0
lines changed

1 file changed

+32
-0
lines changed

packages/nextjs/src/server/middleware/asgardeoMiddleware.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,11 +140,43 @@ const asgardeoMiddleware = (
140140
return async (request: NextRequest): Promise<NextResponse> => {
141141
const resolvedOptions = typeof options === 'function' ? options(request) : options || {};
142142

143+
const url: URL = new URL(request.url);
144+
const hasCallbackParams: boolean = url.searchParams.has('code') && url.searchParams.has('state');
145+
146+
let isValidOAuthCallback: boolean = false;
147+
if (hasCallbackParams) {
148+
// OAuth callbacks should not contain error parameters that indicate failed auth
149+
const hasError: boolean = url.searchParams.has('error');
150+
151+
if (!hasError) {
152+
// Validate that there's a temporary session that initiated this OAuth flow
153+
const tempSessionToken: string | undefined = request.cookies.get(
154+
SessionManager.getTempSessionCookieName(),
155+
)?.value;
156+
if (tempSessionToken) {
157+
try {
158+
// Verify the temporary session exists and is valid
159+
await SessionManager.verifyTempSession(tempSessionToken);
160+
isValidOAuthCallback = true;
161+
} catch {
162+
// Invalid temp session - this is not a legitimate OAuth callback
163+
isValidOAuthCallback = false;
164+
}
165+
}
166+
}
167+
}
168+
143169
const sessionId = await getSessionIdFromRequestMiddleware(request);
144170
const isAuthenticated = await hasValidSession(request);
145171

146172
const asgardeo: AsgardeoMiddlewareContext = {
147173
protectRoute: async (options?: {redirect?: string}): Promise<NextResponse | void> => {
174+
// Skip protection if this is a validated OAuth callback - let the callback handler process it first
175+
// This prevents race conditions where middleware redirects before OAuth callback completes
176+
if (isValidOAuthCallback) {
177+
return;
178+
}
179+
148180
if (!isAuthenticated) {
149181
const referer = request.headers.get('referer');
150182
// TODO: Make this configurable or call the signIn() from here.

0 commit comments

Comments
 (0)