From 05ada7e55a7460c6e60a71a4d4fd76390c0c23b5 Mon Sep 17 00:00:00 2001 From: FleetAdmiralJakob Date: Sat, 11 May 2024 12:50:16 +0200 Subject: [PATCH] fix: errors not shown on signup page Fixed it by making the API Route Handler compatible with HTTP/2 --- src/app/(auth)/sign-up/signup-form.tsx | 15 +++++++++--- src/app/api/sign-up/route.ts | 34 +++++++++++++++++++------- 2 files changed, 37 insertions(+), 12 deletions(-) diff --git a/src/app/(auth)/sign-up/signup-form.tsx b/src/app/(auth)/sign-up/signup-form.tsx index c5dc1f48..8567e669 100644 --- a/src/app/(auth)/sign-up/signup-form.tsx +++ b/src/app/(auth)/sign-up/signup-form.tsx @@ -2,7 +2,7 @@ import { zodResolver } from "@hookform/resolvers/zod"; import { useForm } from "react-hook-form"; -import { type z } from "zod"; +import { z } from "zod"; import { Button } from "~/components/ui/button"; import { @@ -23,6 +23,11 @@ import { cn } from "~/lib/utils"; import { useConvexAuth, useMutation } from "convex/react"; import { api } from "../../../../convex/_generated/api"; +const signUpResponseSchema = z.object({ + message: z.string(), + statusText: z.string().optional(), +}); + export function SignUpForm() { const [formIsLoading, setFormIsLoading] = React.useState(false); const [signUpComplete, setSignUpComplete] = React.useState(false); @@ -70,7 +75,11 @@ export function SignUpForm() { body: JSON.stringify(values), }); - if (response.statusText === "username_is_taken") { + const parsedResponseBody = signUpResponseSchema.safeParse( + await response.json(), + ); + + if (parsedResponseBody.data?.statusText === "username_is_taken") { form.setError("username", { message: "Username + ID is already taken. Please choose another.", }); @@ -79,7 +88,7 @@ export function SignUpForm() { return; } - if (response.statusText === "form_password_pwned") { + if (parsedResponseBody.data?.statusText === "form_password_pwned") { form.setError("password", { message: "Password is insecure or has been found in an online data breach. For account safety, please use a different password.", diff --git a/src/app/api/sign-up/route.ts b/src/app/api/sign-up/route.ts index 5b1884e6..9129f55f 100644 --- a/src/app/api/sign-up/route.ts +++ b/src/app/api/sign-up/route.ts @@ -7,7 +7,10 @@ export async function POST(request: Request) { const unparsedSignUpHeaders = (await request.json()) as FormSchema; const parsedSignUpHeaders = formSchema.safeParse(unparsedSignUpHeaders); if (!parsedSignUpHeaders.success) { - return new Response(parsedSignUpHeaders.error.message, { status: 400 }); + return Response.json( + { message: parsedSignUpHeaders.error.message }, + { status: 400 }, + ); } try { @@ -21,20 +24,33 @@ export async function POST(request: Request) { } catch (e) { if (isClerkAPIResponseError(e)) { if (e.errors.some((error) => error.code === "form_identifier_exists")) { - return new Response( - "Failed to create an account. Username already exists.", - { status: 400, statusText: "username_is_taken" }, + return Response.json( + { + message: "Failed to create an account. Username already exists.", + statusText: "username_is_taken", + }, + { status: 400 }, ); } if (e.errors.some((error) => error.code === "form_password_pwned")) { - return new Response( - "Failed to create an account. Password has been found in an online data breach.", - { status: 400, statusText: "form_password_pwned" }, + return Response.json( + { + message: + "Failed to create an account. Password has been found in an online data breach.", + statusText: "form_password_pwned", + }, + { status: 400 }, ); } } - return new Response("Failed to create an account", { status: 400 }); + return Response.json( + { message: "Failed to create an account" }, + { status: 400 }, + ); } - return new Response("User created successfully", { status: 200 }); + return Response.json( + { message: "User created successfully" }, + { status: 200 }, + ); }