Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
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
60 changes: 39 additions & 21 deletions app/(site)/components/AuthForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ const AuthForm = () => {
},
});

const onSubmit: SubmitHandler<FieldValues> = (data) => {
const onSubmit: SubmitHandler<FieldValues> = async (data) => {
setIsLoading(true);

if (!data) {
Expand All @@ -56,33 +56,51 @@ const AuthForm = () => {
}

if (variant === "REGISTER") {
axios
.post("/api/register", data)
.then(() => {
signIn("credentials", data);
})
.catch((err) => {
console.log(err);
toast.error("Something went wrong!");
try {
await axios.post("/api/register", data);
const callback = await signIn("credentials", {
Copy link

@cubic-dev-ai cubic-dev-ai bot Sep 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ensure the LOGIN signIn call is wrapped in a try/finally (or handles rejection) so setIsLoading(false) always runs; otherwise a thrown error will leave the form stuck in a loading state.

Prompt for AI agents
Address the following comment on app/(site)/components/AuthForm.tsx at line 61:

<comment>Ensure the LOGIN signIn call is wrapped in a try/finally (or handles rejection) so setIsLoading(false) always runs; otherwise a thrown error will leave the form stuck in a loading state.</comment>

<file context>
@@ -56,33 +56,51 @@ const AuthForm = () =&gt; {
-          toast.error(&quot;Something went wrong!&quot;);
+      try {
+        await axios.post(&quot;/api/register&quot;, data);
+        const callback = await signIn(&quot;credentials&quot;, {
+          email: data.email,
+          password: data.password,
</file context>
Fix with Cubic

email: data.email,
password: data.password,
redirect: false,
});
}

if (variant === "LOGIN") {
signIn("credentials", {
...data,
redirect: false,
}).then((callback) => {
if (callback?.error) {
toast.error("Invalid credentials!");
}
if (callback?.ok && !callback?.error) {
toast.success("Logged in!");
toast.error(callback.error || "Invalid credentials!");
} else {
toast.success("Account created!");
router.push("/users");
}
});
} catch (err: any) {
if (err?.response?.status === 409) {
toast.error("Email already registered");
} else if (err?.response?.data) {
toast.error(typeof err.response.data === 'string' ? err.response.data : 'Registration failed');
Copy link

Copilot AI Sep 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The error handling logic for err.response.data is overly complex. Consider simplifying this by either extracting the error message consistently or using a more straightforward fallback approach.

Suggested change
toast.error(typeof err.response.data === 'string' ? err.response.data : 'Registration failed');
const errorMessage =
typeof err.response.data === 'string'
? err.response.data
: err.response.data.message
? err.response.data.message
: 'Registration failed';
toast.error(errorMessage);

Copilot uses AI. Check for mistakes.
Copy link

@cubic-dev-ai cubic-dev-ai bot Sep 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Avoid displaying raw server error messages to users; show a generic message instead to prevent leaking internal details.

Prompt for AI agents
Address the following comment on app/(site)/components/AuthForm.tsx at line 77:

<comment>Avoid displaying raw server error messages to users; show a generic message instead to prevent leaking internal details.</comment>

<file context>
@@ -56,33 +56,51 @@ const AuthForm = () =&gt; {
+        if (err?.response?.status === 409) {
+          toast.error(&quot;Email already registered&quot;);
+        } else if (err?.response?.data) {
+          toast.error(typeof err.response.data === &#39;string&#39; ? err.response.data : &#39;Registration failed&#39;);
+        } else {
+          toast.error(&quot;Something went wrong!&quot;);
</file context>
Suggested change
toast.error(typeof err.response.data === 'string' ? err.response.data : 'Registration failed');
toast.error("Registration failed");
Fix with Cubic

} else {
toast.error("Something went wrong!");
}
} finally {
setIsLoading(false);
}
return;
}

setIsLoading(false);
if (variant === "LOGIN") {
const callback = await signIn("credentials", {
email: data.email,
password: data.password,
redirect: false,
});

if (callback?.error) {
toast.error("Invalid credentials!");
}
if (callback?.ok && !callback?.error) {
toast.success("Logged in!");
router.push("/users");
}
setIsLoading(false);
Copy link

Copilot AI Sep 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The setIsLoading(false) call is duplicated across both REGISTER and LOGIN branches. Consider moving this to a single location or using a try/finally block to ensure it's always called.

Copilot uses AI. Check for mistakes.
return;
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Login Flow Fails to Reset Loading State

The LOGIN flow's signIn call lacks try-catch error handling. If signIn throws an exception, setIsLoading(false) isn't reached, leaving the form stuck in a loading state. This differs from the REGISTER flow, which correctly uses finally to reset the loading state.

Fix in Cursor Fix in Web

};

const socialAction = (action: string) => {
Expand Down
15 changes: 14 additions & 1 deletion app/api/register/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,15 @@ export async function POST(req: Request) {
return new NextResponse("Missing fields.", { status: 400 });
}

// Prevent duplicate accounts
const existingUser = await prisma.user.findUnique({
where: { email },
});

if (existingUser) {
return NextResponse.json({ error: "Email already registered" }, { status: 409 });
}

const hashedPassword = await bcrypt.hash(password, 12);

const user = await prisma.user.create({
Expand All @@ -32,8 +41,12 @@ export async function POST(req: Request) {
}

return NextResponse.json(user);
} catch (error) {
} catch (error: any) {
console.log("[REGISTRATION_ERROR]", error);
// Handle Prisma unique constraint error just in case of race condition
if (error?.code === "P2002") {
return NextResponse.json({ error: "Email already registered" }, { status: 409 });
}
return new NextResponse("Error while registering user.", { status: 500 });
}
}