Pending course, rest ready for launch
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
"use client";
|
||||
|
||||
import { createBrowserClient } from "@supabase/ssr";
|
||||
import { FormEvent, useState } from "react";
|
||||
import { FormEvent, useEffect, useState } from "react";
|
||||
import Link from "next/link";
|
||||
import { useRouter } from "next/navigation";
|
||||
|
||||
@@ -9,17 +9,24 @@ type LoginFormProps = {
|
||||
redirectTo: string;
|
||||
role?: string;
|
||||
showForgot?: boolean;
|
||||
skipAuthedRedirect?: boolean;
|
||||
};
|
||||
|
||||
// Helper to prevent open redirect vulnerabilities
|
||||
const normalizeRedirect = (redirectTo: string) => {
|
||||
if (redirectTo.startsWith("/") && !redirectTo.startsWith("//")) {
|
||||
return redirectTo;
|
||||
if (!redirectTo.startsWith("/") || redirectTo.startsWith("//")) {
|
||||
return "/courses";
|
||||
}
|
||||
return "/home"; // Default fallback
|
||||
|
||||
// Never redirect back into auth routes after successful login.
|
||||
if (redirectTo.startsWith("/auth/")) {
|
||||
return "/courses";
|
||||
}
|
||||
|
||||
return redirectTo;
|
||||
};
|
||||
|
||||
export default function LoginForm({ redirectTo, role, showForgot }: LoginFormProps) {
|
||||
export default function LoginForm({ redirectTo, role, showForgot, skipAuthedRedirect }: LoginFormProps) {
|
||||
const router = useRouter();
|
||||
const safeRedirect = normalizeRedirect(redirectTo);
|
||||
const isTeacher = role === "teacher";
|
||||
@@ -30,6 +37,23 @@ export default function LoginForm({ redirectTo, role, showForgot }: LoginFormPro
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
const [loading, setLoading] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
if (skipAuthedRedirect) {
|
||||
return;
|
||||
}
|
||||
|
||||
const supabase = createBrowserClient(
|
||||
process.env.NEXT_PUBLIC_SUPABASE_URL!,
|
||||
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
|
||||
);
|
||||
|
||||
supabase.auth.getUser().then(({ data }) => {
|
||||
if (data.user) {
|
||||
router.replace(safeRedirect);
|
||||
}
|
||||
});
|
||||
}, [router, safeRedirect, skipAuthedRedirect]);
|
||||
|
||||
// Construct the "Forgot Password" link to preserve context
|
||||
const forgotHref = `/auth/login?redirectTo=${encodeURIComponent(safeRedirect)}${isTeacher ? "&role=teacher" : ""
|
||||
}&forgot=1`;
|
||||
@@ -62,8 +86,9 @@ export default function LoginForm({ redirectTo, role, showForgot }: LoginFormPro
|
||||
// so they see the new cookie immediately.
|
||||
router.refresh();
|
||||
|
||||
// 4. Navigate to the protected page
|
||||
router.push(safeRedirect);
|
||||
// 4. Navigate to the protected page and release button state.
|
||||
setLoading(false);
|
||||
router.replace(safeRedirect);
|
||||
};
|
||||
|
||||
return (
|
||||
@@ -149,4 +174,4 @@ export default function LoginForm({ redirectTo, role, showForgot }: LoginFormPro
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user