Skip to content

fix: align frontend username validation with backend Zod schema#466

Merged
mehul-m-prajapati merged 2 commits into
GitMetricsLab:mainfrom
anshul23102:fix/413-username-validation-mismatch
May 26, 2026
Merged

fix: align frontend username validation with backend Zod schema#466
mehul-m-prajapati merged 2 commits into
GitMetricsLab:mainfrom
anshul23102:fix/413-username-validation-mismatch

Conversation

@anshul23102
Copy link
Copy Markdown
Contributor

Fixes #413

Problem

The frontend signup form in src/pages/Signup/Signup.tsx validated usernames against /^[A-Za-z\s]+$/ (letters and spaces only). The backend Zod schema in backend/validators/authValidator.js accepts a completely different character set:

username: z.string()
  .min(3, "Username must be at least 3 characters long")
  .max(30, "Username must be at most 30 characters long")
  .regex(/^[a-zA-Z0-9_]+$/, "Username can only contain letters, numbers, and underscores")

This produced two failure modes:

Mode 1 -- valid usernames blocked at the frontend
Usernames like dev_user1 or john99 are accepted by the backend but were rejected by the frontend with the misleading error "Only letters are allowed". Users with common username patterns could not register at all.

Mode 2 -- invalid usernames accepted by the frontend, rejected by the backend
Usernames containing spaces (e.g. john doe) passed the frontend check but were rejected by the backend after the network request was made, surfacing as a confusing server-side error rather than an inline form error.

Mode 3 -- length constraints missing from the frontend
The backend enforces min(3) and max(30). The frontend had no length checks, so a 1 or 2-character username would pass client-side validation and produce a backend rejection instead of an immediate inline error.

Fix

src/pages/Signup/Signup.tsx

Added named module-level constants that document the backend rule and serve as a single place to update when the backend schema changes:

const USERNAME_REGEX = /^[a-zA-Z0-9_]+$/;
const USERNAME_MIN = 3;
const USERNAME_MAX = 30;
const USERNAME_ERROR = "Username can only contain letters, numbers, and underscores";

Updated both validation sites (handleChange for inline feedback and handleSubmit for pre-submit guard) to:

  • Check minimum length (3 characters)
  • Check maximum length (30 characters)
  • Test the corrected regex against the trimmed value
  • Use USERNAME_ERROR to match the backend error message exactly

The handleSubmit block now trims the username once into a local variable before the validation chain, removing repeated .trim() calls.

Testing

Input Before After
dev_user1 "Only letters are allowed" (blocked) accepted
john_doe "Only letters are allowed" (blocked) accepted
john doe accepted (then backend rejects) "Username can only contain letters, numbers, and underscores"
ab accepted (then backend rejects) "Username must be at least 3 characters long"
a * 31 accepted (then backend rejects) "Username must be at most 30 characters long"
alice accepted accepted

@netlify
Copy link
Copy Markdown

netlify Bot commented May 23, 2026

Deploy Preview for github-spy failed.

Name Link
🔨 Latest commit 4f54dbc
🔍 Latest deploy log https://app.netlify.com/projects/github-spy/deploys/6a15e2cad5c6d700082e22a6

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 23, 2026

Warning

Review limit reached

@mehul-m-prajapati, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 53 minutes and 18 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: f5caab01-45c9-455a-b595-85f7177392d7

📥 Commits

Reviewing files that changed from the base of the PR and between bcb002c and 4f54dbc.

📒 Files selected for processing (1)
  • src/pages/Signup/Signup.tsx
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@anshul23102
Copy link
Copy Markdown
Contributor Author

Hi @GitMetricsLab team, checking in on this one. The username validation mismatch was causing two real failure modes: usernames like dev_user1 or john99 were blocked at the frontend with "Only letters are allowed" even though the backend happily accepts them, and usernames with spaces passed the frontend but then hit a confusing server-side rejection. The fix aligns the frontend regex and length constraints with the backend Zod schema so both sides agree on what a valid username looks like. Happy to revise anything.

Fixes GitMetricsLab#413

The frontend signup form validated usernames against /^[A-Za-z\s]+$/, which
only accepted plain letters and spaces. The backend Zod schema in
backend/validators/authValidator.js accepts letters, digits, and underscores
(/^[a-zA-Z0-9_]+$/) and enforces a minimum length of 3 and a maximum of 30.
These two rulesets directly contradicted each other in two ways:

1. Valid usernames containing digits or underscores (e.g. dev_user1, john99)
   were blocked by the frontend with the misleading error "Only letters are
   allowed", even though the backend would accept them.

2. Usernames containing spaces (e.g. "john doe") passed the frontend check
   but were rejected by the backend, producing a confusing server-side error
   after the network request was already made.

Additionally, the frontend had no length checks, so a one-character username
would pass client-side validation but be rejected by the backend's min(3)
rule.

Changes in src/pages/Signup/Signup.tsx:

Added named module-level constants (USERNAME_REGEX, USERNAME_MIN, USERNAME_MAX,
USERNAME_ERROR) that document the backend rule and serve as a single source to
update when the backend changes. The comment references the validator file
explicitly to make the coupling visible to future maintainers.

Updated the username validation block in handleChange and handleSubmit to:
  - Check min length (3 characters) with a clear error message
  - Check max length (30 characters) with a clear error message
  - Test the corrected regex /^[a-zA-Z0-9_]+$/ against the trimmed value
  - Use USERNAME_ERROR as the error message to match the backend exactly

The handleSubmit block now trims the username once into a local variable
before the ternary chain, avoiding repeated .trim() calls.

No other validation logic was modified.
@anshul23102 anshul23102 force-pushed the fix/413-username-validation-mismatch branch from 7d4806b to 597bead Compare May 24, 2026 13:18
@mehul-m-prajapati mehul-m-prajapati merged commit 6f83e96 into GitMetricsLab:main May 26, 2026
2 of 6 checks passed
@github-actions
Copy link
Copy Markdown

🎉🎉 Thank you for your contribution! Your PR #466 has been merged! 🎉🎉

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] Frontend username validation in Signup.tsx rejects valid usernames containing numbers and underscores

2 participants