Skip to content

Commit 1190ca4

Browse files
committed
Address minor reviewer comments
1 parent 880b736 commit 1190ca4

2 files changed

Lines changed: 23 additions & 10 deletions

File tree

frontend/app/api/auth/password-reset/confirm/route.ts

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,19 +25,34 @@ const schema = z.object({
2525
`Password must be at most ${PASSWORD_MAX_LEN} characters`
2626
)
2727
.regex(/[A-Z]/, 'Password must contain at least one capital letter')
28-
.regex(/[^A-Za-z0-9]/, 'Password must contain at least one special character')
28+
.regex(
29+
/[^A-Za-z0-9]/,
30+
'Password must contain at least one special character'
31+
)
2932
.regex(PASSWORD_POLICY_REGEX, 'Password does not meet the required policy'),
3033
});
3134

35+
function firstFieldErrorMessage(
36+
fieldErrors: Record<string, string[] | undefined>
37+
): string | null {
38+
for (const key of Object.keys(fieldErrors)) {
39+
const msgs = fieldErrors[key];
40+
if (Array.isArray(msgs) && msgs.length > 0 && msgs[0]) {
41+
return msgs[0];
42+
}
43+
}
44+
return null;
45+
}
46+
3247
export async function POST(req: Request) {
3348
const body = await req.json().catch(() => null);
3449
const parsed = schema.safeParse(body);
3550

3651
if (!parsed.success) {
37-
return NextResponse.json(
38-
{ error: parsed.error.flatten().fieldErrors },
39-
{ status: 400 }
40-
);
52+
const flattened = parsed.error.flatten().fieldErrors;
53+
const firstMsg =
54+
firstFieldErrorMessage(flattened) ?? 'Invalid request';
55+
return NextResponse.json({ error: firstMsg }, { status: 400 });
4156
}
4257

4358
const { token, password } = parsed.data;

frontend/components/auth/SignupForm.tsx

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,13 +36,11 @@ export function SignupForm({ locale, returnTo }: SignupFormProps) {
3636
const [verificationRequired, setVerificationRequired] = useState(false);
3737
const [email, setEmail] = useState('');
3838

39-
// Live values
4039
const [nameValue, setNameValue] = useState('');
4140
const [emailValueLive, setEmailValueLive] = useState('');
4241
const [passwordValue, setPasswordValue] = useState('');
4342
const [confirmPasswordValue, setConfirmPasswordValue] = useState('');
4443

45-
// Touched flags (show messages only after blur)
4644
const [nameTouched, setNameTouched] = useState(false);
4745
const [emailTouched, setEmailTouched] = useState(false);
4846
const [passwordTouched, setPasswordTouched] = useState(false);
@@ -94,7 +92,7 @@ export function SignupForm({ locale, returnTo }: SignupFormProps) {
9492
const emailErrorText = useMemo(() => {
9593
if (!emailTouched) return null;
9694

97-
if (!emailTrimmed) return null;
95+
if (!emailTrimmed) return "Email is required";
9896

9997
if (emailTrimmed.length > EMAIL_MAX_LEN) {
10098
return `Email must not exceed ${EMAIL_MAX_LEN} characters.`;
@@ -117,7 +115,7 @@ export function SignupForm({ locale, returnTo }: SignupFormProps) {
117115

118116
const confirmPolicyErrorText =
119117
confirmPasswordTouched && !confirmPasswordPolicyOk
120-
? `Repeat password must meet requirements: ${passwordRequirementsText}`
118+
? `Password must meet requirements: ${passwordRequirementsText}`
121119
: null;
122120

123121
const mismatchErrorText =
@@ -282,7 +280,7 @@ export function SignupForm({ locale, returnTo }: SignupFormProps) {
282280
<PasswordField
283281
id="confirmPassword"
284282
name="confirmPassword"
285-
placeholder="Repeat password"
283+
placeholder="Confirm password"
286284
autoComplete="new-password"
287285
minLength={PASSWORD_MIN_LEN}
288286
maxLength={PASSWORD_MAX_LEN}

0 commit comments

Comments
 (0)