fix(auth): align the client password rule with the server — Closes #270 - #486
Merged
SRV30 merged 1 commit intoAug 10, 2026
Merged
Conversation
|
@SakethSumanBathini is attempting to deploy a commit to the srv30's projects Team on Vercel. A member of the Team first needs to authorize it. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #270
The two rules disagree
Client, in three separate files:
/[!@#$%^&*(),.?":{}|<>]/Server,
server/validators/authSchemas.js:13:The client's allow-list is narrower. Thirteen characters the API accepts are rejected by the browser:
The underscore and the hyphen are the ones that matter — both are common in real passwords, and a password manager will happily generate either.
Why it is worse than a cosmetic mismatch
The client does not just hint.
Signup.jsx:34blocks submission:So a user typing
My_Pass1is stopped, and told their password is not complex enough — when the server would have accepted it. There is nothing on screen to suggest which character is the problem, because the checklist item just says "Special character" and stays unticked.It was in three files, not one
Signup.jsx,ResetPassword.jsxandUpdatePassword.jsxeach carried their own copy of the same five rules. All three had the narrow version, so the bug appears at signup, at password reset, and at password change.That duplication is also how the drift happened: the server rule changed and three copies did not follow.
The change
One shared module,
client/src/utils/passwordRequirements.js, imported by all three. The special-character rule now matches the server exactly:Written as a negated class rather than a longer allow-list deliberately. An allow-list has to be kept in step with the server by hand, which is the thing that failed here. A negated class is the same expression the server uses, so the two cannot disagree without someone changing both.
The label is now
Special character (e.g. ! @ # _ - ?)— the previous "Special character" gave no clue that_counted, and the examples include the two characters that were being rejected.The other four rules are unchanged.
Verified
Client and server agree on every case:
NoSpecial1is the control — a password with no special character is still refused by both, so this loosens the rule to match the server rather than removing it.All four files parse under esbuild.
One thing I could not verify
npm run buildfails on this repository, on a clean checkout ofmainas well as on this branch:@stripe/stripe-jsis imported but is not inclient/package.json. I confirmed this by stashing my changes and buildingmain— the failure is identical, so it is unrelated to this PR, but it does mean I could not get a full build to pass. Worth its own issue.