Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 24 additions & 1 deletion src/beacon/components/providers/auth-provider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,12 @@ import authService from '@/services/api-service';
function AuthEffect({ children }: { children: ReactNode }) {
const { data: session, status } = useSession();
const [handoffProcessed, setHandoffProcessed] = useState(false);
const [isHandlingHandoff, setIsHandlingHandoff] = useState(() => {
if (typeof window !== 'undefined') {
return window.location.hash.includes('token=');
}
return false;
});
Comment thread
OlukaGibson marked this conversation as resolved.

useEffect(() => {
if (status === 'authenticated' && session) {
Expand All @@ -29,11 +35,15 @@ function AuthEffect({ children }: { children: ReactNode }) {
role: (rawUser as any).privilege || 'user',
});
}

if (isHandlingHandoff) {
setIsHandlingHandoff(false);
}
} else if (status === 'unauthenticated') {
authService.setToken(null);
authService.setUserData(null);
}
}, [session, status]);
}, [session, status, isHandlingHandoff]);

useEffect(() => {
if (handoffProcessed) return;
Expand All @@ -50,9 +60,22 @@ function AuthEffect({ children }: { children: ReactNode }) {
redirect: true,
callbackUrl: callbackUrl,
});
} else {
setIsHandlingHandoff(false);
}
}, [handoffProcessed]);

if (isHandlingHandoff || (status === 'unauthenticated' && typeof window !== 'undefined' && window.location.hash.includes('token='))) {
return (
<div className="flex flex-col items-center justify-center min-h-screen bg-gray-50">
<div className="w-16 h-16 border-4 border-blue-200 rounded-full mb-4 relative">
<div className="absolute top-0 left-0 w-16 h-16 border-4 border-blue-600 rounded-full border-t-transparent animate-spin"></div>
</div>
<div className="text-gray-900 text-xl font-semibold mb-2">Completing sign in...</div>
</div>
);
}

return <>{children}</>;
}

Expand Down
6 changes: 4 additions & 2 deletions src/beacon/middleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,11 @@ export default withAuth(
typeof token?.airqoExp === 'number' && Date.now() / 1000 > token.airqoExp;
const isAuthenticated = !!token && !isAirqoTokenExpired;
const isPublicRoute = PUBLIC_ROUTES.some(route => pathname.startsWith(route))
const isOAuthCallback = request.nextUrl.searchParams.has('success') || request.nextUrl.searchParams.has('token')

// Redirect unauthenticated users to login
if (!isAuthenticated && !isPublicRoute) {
// Redirect unauthenticated users to login, unless it's an OAuth callback
// (We need to let the client handle OAuth callbacks to preserve the URL hash fragment)
if (!isAuthenticated && !isPublicRoute && !isOAuthCallback) {
Comment thread
OlukaGibson marked this conversation as resolved.
const loginUrl = new URL('/login', request.url)
loginUrl.searchParams.set('from', pathname)
return NextResponse.redirect(loginUrl)
Expand Down
Loading