| 37 | |
| 38 | |
| 39 | const ProtectedRoute = ({ children }) => { |
| 40 | const { user, loading } = useAuth(); |
| 41 | const location = window.location.pathname; |
| 42 | const search = window.location.search; // Preserve query params |
| 43 | |
| 44 | if (loading) return <div className="flex items-center justify-center min-h-screen bg-[#FFF8F0] font-bold text-xl">Loading...</div>; |
| 45 | if (!user) return <Navigate to={`/login${search}`} replace />; // Preserve ?error=... params |
| 46 | |
| 47 | // FORCE REDIRECT: Users with noreply emails MUST change their email |
| 48 | // BUT: Allow them to complete migration steps first (/set-password, /complete-profile) |
| 49 | // This ensures backend migration flow isn't disrupted |
| 50 | const isNoreplyEmail = user?.email?.includes('noreply.github.com'); |
| 51 | const allowedPagesForNoreply = ['/change-email', '/set-password', '/complete-profile']; |
| 52 | if (isNoreplyEmail && !allowedPagesForNoreply.includes(location)) { |
| 53 | return <Navigate to={`/change-email?email=${encodeURIComponent(user.email)}&required=true`} replace />; |
| 54 | } |
| 55 | |
| 56 | // SPECIAL: Allow access to /change-email for noreply users regardless of other checks |
| 57 | // This is critical for the noreply email fix - users need to change their email first |
| 58 | if (location === '/change-email') { |
| 59 | return children ? children : <Outlet />; |
| 60 | } |
| 61 | |
| 62 | // 1. Force Password Set Flow |
| 63 | if (user && !user.hasPassword) { |
| 64 | if (location !== '/set-password') { |
| 65 | return <Navigate to="/set-password" replace />; |
| 66 | } |
| 67 | } |
| 68 | |
| 69 | // 2. Prevent access to Set Password if already set |
| 70 | if (user && user.hasPassword && location === '/set-password') { |
| 71 | return <Navigate to="/dashboard" replace />; |
| 72 | } |
| 73 | |
| 74 | return children ? children : <Outlet />; |
| 75 | }; |
| 76 | |
| 77 | function App() { |
| 78 | return ( |