Skip to content

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

Open
anshul23102 wants to merge 1 commit into
GitMetricsLab:mainfrom
anshul23102:fix/413-username-validation-mismatch
Open

fix: align frontend username validation with backend Zod schema#466
anshul23102 wants to merge 1 commit into
GitMetricsLab:mainfrom
anshul23102:fix/413-username-validation-mismatch

Conversation

@anshul23102
Copy link
Copy Markdown

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 ready!

Name Link
🔨 Latest commit 597bead
🔍 Latest deploy log https://app.netlify.com/projects/github-spy/deploys/6a12fa91925e460008785c97
😎 Deploy Preview https://deploy-preview-466--github-spy.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 23, 2026

Warning

Review limit reached

@anshul23102, we couldn't start this review because you've used your available PR reviews for now.

Your plan currently allows 1 review/hour. Refill in 59 minutes and 55 seconds.

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

⌛ How to resolve this issue?

After more review capacity refills, 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 have higher rate limits than trial, open-source, and free plans. In all cases, review capacity refills continuously over time.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: fc4f3aa6-ac98-4e8c-853b-c4cd20cb4f00

📥 Commits

Reviewing files that changed from the base of the PR and between 6c6bc3e and 597bead.

📒 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
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
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

1 participant