Skip to content

fix: enforce consistent password validation across all flows#785

Merged
Israeltheminer merged 3 commits into
mainfrom
fix/consistent-password-validation
Mar 13, 2026
Merged

fix: enforce consistent password validation across all flows#785
Israeltheminer merged 3 commits into
mainfrom
fix/consistent-password-validation

Conversation

@Israeltheminer
Copy link
Copy Markdown
Collaborator

@Israeltheminer Israeltheminer commented Mar 13, 2026

Summary

Fixes #784

  • Password validation rules were inconsistent across different user creation and password management flows
  • Created a shared password validation module (lib/shared/schemas/password.ts) with all 5 rules: min 8 chars, lowercase, uppercase, number, special character
  • Applied the same validation to all flows: sign-up, add member, edit member, change password, set password
  • Added backend validation in set_member_password and update_user_password Convex functions
  • Added usePasswordValidation hook for consistent ValidationCheckList display across all forms

Before

Flow Min 8 Lowercase Uppercase Number Special char
Sign-up
Add Member (admin)
Edit Member (admin)
Change Password ✓ (only)
Set Password ✓ (only)
Backend

After

All flows enforce all 5 rules consistently, both on frontend (Zod schemas) and backend.

Test plan

  • 21 unit tests for shared password validation (all pass)
  • Verify sign-up form shows all 5 validation checks and enforces them
  • Verify Add Member dialog shows all 5 validation checks
  • Verify Edit Member dialog shows validation checks when "Update password" is checked
  • Verify Change Password form shows all 5 validation checks
  • Verify Set Password form shows all 5 validation checks
  • Verify backend rejects weak passwords in set_member_password
  • Verify backend rejects weak passwords in update_user_password

Summary by CodeRabbit

  • New Features

    • Real-time password validation checklist (length, lowercase, uppercase, number, special character) in account settings, member management, and sign-up flows.
    • Centralized, localized schema-driven password validation for consistent messages and behavior across forms.
    • Server-side password validation added to reject invalid passwords early.
  • Tests

    • Added comprehensive password validation test suite covering rules and schema behavior.

Password rules (8+ chars, lowercase, uppercase, number, special char)
were only fully enforced on sign-up. Add Member, Edit Member, Change
Password, and Set Password forms had weaker or no validation.

- Create shared password schema (lib/shared/schemas/password.ts)
- Add usePasswordValidation hook for consistent UI display
- Update all 5 frontend forms to use shared schema + ValidationCheckList
- Add backend validation in set_member_password and update_user_password
- Add missing specialChar translation key for changePassword requirements
Copy link
Copy Markdown

@greptile-apps greptile-apps Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your free trial has ended. If you'd like to continue receiving code reviews, you can add a payment method here.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Mar 13, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 34d67dbe-a242-49d5-9eea-bbf7dbcdd61e

📥 Commits

Reviewing files that changed from the base of the PR and between 3e4103e and 92e4084.

📒 Files selected for processing (5)
  • services/platform/app/features/settings/organization/components/member-edit-dialog.tsx
  • services/platform/convex/users/set_member_password.ts
  • services/platform/convex/users/update_user_password.ts
  • services/platform/lib/shared/schemas/password.test.ts
  • services/platform/lib/shared/schemas/password.ts

📝 Walkthrough

Walkthrough

This PR centralizes password validation by adding a shared password schema module and a usePasswordValidation hook, replacing inline password rules with Zod-based schemas across sign-up, account settings, and member management forms. It adds runtime password validation UI (ValidationCheckList) driven by the hook, updates server-side Convex handlers to validate passwords before hashing, introduces unit tests for password rules, and adds a translation key for the special-character requirement. Public component and function signatures were not changed.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'fix: enforce consistent password validation across all flows' accurately describes the main objective of the PR: unifying password validation rules across multiple forms and flows.
Linked Issues check ✅ Passed The PR addresses all core requirements from issue #784: shared password schema with 5 rules [minLength, lowercase, uppercase, number, specialChar], applied across sign-up/add-member/edit-member/change-password/set-password flows, consistent UI via ValidationCheckList, and backend validation in Convex functions.
Out of Scope Changes check ✅ Passed All changes directly support the stated objective of enforcing consistent password validation: schema utilities, hook for validation UI, form integrations, backend checks, translations, and tests. No unrelated modifications detected.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/consistent-password-validation
📝 Coding Plan
  • Generate coding plan for human review comments

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

@Israeltheminer
Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Mar 13, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@services/platform/app/features/settings/organization/components/member-edit-dialog.tsx`:
- Around line 73-80: The password schema created by createOptionalPasswordSchema
is always validated even when updatePassword is false, causing hidden/invalid
passwords to block submission; update the form so password is only
required/validated when updatePassword is true—either (A) modify the Zod schema
for the member-edit-dialog form to use .superRefine() on the parent object to
conditionally require/validate password based on the sibling updatePassword flag
(reference: createOptionalPasswordSchema, updatePassword, password), or (B) when
the updatePassword checkbox toggles off call react-hook-form's
resetField('password') or unregister('password') to remove validation/state for
password so it no longer blocks submit.

In `@services/platform/convex/users/set_member_password.ts`:
- Around line 92-96: The password validity check
(isPasswordValid(args.newPassword)) currently runs after several adapter/DB
reads; move this check to immediately after successful authentication in the
setMemberPassword (or set_member_password) handler so we fail fast for invalid
input and avoid unnecessary adapter queries. Concretely, after verifying auth
(the block that validates the caller/session) and before any
adapter.get/adapter.query calls, add the existing isPasswordValid condition and
throw the same Error if it fails; keep the exact error message and use
args.newPassword as before.

In `@services/platform/convex/users/update_user_password.ts`:
- Around line 24-30: Move the authentication call before performing password
validation to avoid leaking password-policy info to unauthenticated clients:
call authComponent.getAuth(createAuth, ctx) (and destructure { auth, headers })
prior to invoking isPasswordValid(args.newPassword), and only throw the password
policy Error after successful authentication; update the function containing
these symbols (isPasswordValid, authComponent.getAuth, createAuth, ctx) so auth
is obtained first, then validate the password and throw the existing error if
invalid.

In `@services/platform/lib/shared/schemas/password.test.ts`:
- Around line 154-162: The tests 'rejects an invalid non-empty password' and
'rejects password missing only special char' only assert result.success is
false; update both cases to also assert the validation error message so
optional-schema mapping is correct—after calling schema.safeParse('weak') and
schema.safeParse('Abcdefg1') inspect result.error (e.g.
result.error.errors[0].message) and assert it equals the expected password
validation message used by your schema (the same message other tests expect),
ensuring the wrong error-message mapping for optional passwords is caught;
reference schema.safeParse and the two test names when making the change.

In `@services/platform/lib/shared/schemas/password.ts`:
- Around line 67-73: The optional password .refine currently always reports
messages.minLength for any failure; update the refine on the password schema to
return an appropriate complexity message instead of the static minLength one —
i.e., change the error payload used in the .refine that calls
isPasswordValid(val) from messages.minLength to a specific complexity message
(e.g., messages.passwordComplexity) or determine the correct message from
isPasswordValid, so that failures for uppercase/number/special-char surface the
proper error; reference the .refine call and the isPasswordValid function when
making this change.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 0c4fe145-17d4-4243-802c-b8d0fb309ada

📥 Commits

Reviewing files that changed from the base of the PR and between 48459c8 and 3e4103e.

📒 Files selected for processing (10)
  • services/platform/app/features/settings/account/components/account-form.tsx
  • services/platform/app/features/settings/organization/components/member-add-dialog.tsx
  • services/platform/app/features/settings/organization/components/member-edit-dialog.tsx
  • services/platform/app/hooks/use-password-validation.ts
  • services/platform/app/routes/_auth/sign-up.tsx
  • services/platform/convex/users/set_member_password.ts
  • services/platform/convex/users/update_user_password.ts
  • services/platform/lib/shared/schemas/password.test.ts
  • services/platform/lib/shared/schemas/password.ts
  • services/platform/messages/en.json

Comment thread services/platform/convex/users/set_member_password.ts Outdated
Comment thread services/platform/convex/users/update_user_password.ts Outdated
Comment thread services/platform/lib/shared/schemas/password.test.ts Outdated
Comment thread services/platform/lib/shared/schemas/password.ts Outdated
- Use superRefine in createOptionalPasswordSchema for specific error messages
- Reset password field when edit member checkbox is toggled off
- Move password validation after auth check to prevent policy probing
- Move validation before DB reads in set_member_password for fail-fast
- Add error message assertions in optional schema tests
@Israeltheminer
Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Mar 13, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@Israeltheminer Israeltheminer merged commit 2083ba0 into main Mar 13, 2026
16 checks passed
@Israeltheminer Israeltheminer deleted the fix/consistent-password-validation branch March 13, 2026 17:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bug: Inconsistent password complexity rules across the platform

1 participant