Skip to content

fix(ui-react): make recovery email validation case-insensitive#5897

Merged
otavio merged 2 commits intomasterfrom
fix/ui-react/recovery-email-case-insensitive-validation
Feb 26, 2026
Merged

fix(ui-react): make recovery email validation case-insensitive#5897
otavio merged 2 commits intomasterfrom
fix/ui-react/recovery-email-case-insensitive-validation

Conversation

@luizhf42
Copy link
Member

@luizhf42 luizhf42 commented Feb 26, 2026

Summary

  • Fix case-sensitive equality check in validateRecoveryEmail that allowed setting a recovery email identical to the primary email when using different casing (e.g., User@Example.com vs user@example.com)
  • Extract validateRecoveryEmail into pages/profile/validate.ts, following the same pattern as the setup page
  • Add unit tests covering empty input, invalid format, exact match, case-insensitive match, and valid distinct email

Motivation

The UI was performing a strict equality check (===), which meant mixed-case duplicates bypassed client-side validation and only got caught by the API. This aligns the UI with the backend's case-insensitive behavior.

Testing

  1. Go to profile settings and set a recovery email matching the primary email with different casing — validation should reject it
  2. Run npx vitest run apps/admin/src/pages/profile/__tests__/validate.test.ts — all 6 tests should pass

@luizhf42 luizhf42 requested a review from a team as a code owner February 26, 2026 13:01
@luizhf42 luizhf42 self-assigned this Feb 26, 2026
@github-actions
Copy link

github-actions bot commented Feb 26, 2026

Claude finished @luizhf42's task in 3m 56s —— View job


Code Review Complete

Reviewed 1 file across code quality, security, testing, language patterns, and architecture. 1 inline suggestion posted (medium severity).

The core fix is correct — .toLowerCase() on both sides of the comparison aligns the UI validation with the backend's strings.EqualFold behavior in api/services/user.go. The parameter rename (v/primaryrecoveryEmail/primaryEmail) is a welcome readability improvement.

Additional notes

  • Validation guard edge case (pre-existing, not introduced by this PR): The recovery email validation at line 162 only runs when recoveryEmail !== currentRecoveryEmail. If a user changes the primary email to match an existing recovery email (case-insensitively), the recovery field won't show a client-side error because the guard prevents re-validation. The server catches this, so it's not a bug — just a minor UX gap where the user would see a generic 400 error instead of a field-level message. Could be addressed in a follow-up by also triggering validation when the primary email changes.

  • Same bug exists in the old Vue UI: ui/src/components/Setting/SettingProfile.vue line 298 uses a case-sensitive value !== email.value check via Yup. If the Vue UI is still in active use, it would benefit from the same fix.


If you've addressed the feedback and want a new review, tag @shellhub-io/admin and a team member can trigger it.

@luizhf42 luizhf42 added kind/bug Something isn't working area/ui labels Feb 26, 2026
@otavio
Copy link
Member

otavio commented Feb 26, 2026

@claude Let's open an issue for the edge case for the React UI, but we are not going to add the Vue one because it is being duplicated; instead, we are going to focus on the new UI being developed.

@github-actions
Copy link

github-actions bot commented Feb 26, 2026

Claude finished @otavio's task in 47s —— View job


Opened Issue for Recovery Email Validation Edge Case

  • Gather context
  • Understand request: Create a GitHub issue for the React UI validation guard edge case (skip Vue UI)
  • Create GitHub issue → shellhub-io/shellhub#5904

Created fix(ui-react): re-validate recovery email when primary email changes tracking the edge case where changing the primary email to a value that case-insensitively matches the existing recovery email doesn't surface a field-level validation error. The Vue UI was intentionally excluded since it's being replaced by the new React UI.

@otavio
Copy link
Member

otavio commented Feb 26, 2026

/review

@github-actions
Copy link

github-actions bot commented Feb 26, 2026

Claude finished @otavio's task in 3m 37s —— View job


Code Review Complete

Reviewed 3 files across code quality, security, testing, language patterns, and architecture — no issues found. The code looks good as-is.

The .toLowerCase() fix correctly aligns the UI with the backend's strings.EqualFold behavior. The extraction into profile/validate.ts follows the established setup/validate.ts pattern, parameter naming (recoveryEmail/primaryEmail) improves readability over the original (v/primary), and the test suite covers all 4 branches (empty, invalid format, case-insensitive match in both directions, valid distinct email).


If you push additional changes and want a new review, tag @shellhub-io/admin and a team member can trigger it.

@otavio otavio merged commit 753da29 into master Feb 26, 2026
21 checks passed
@otavio otavio deleted the fix/ui-react/recovery-email-case-insensitive-validation branch February 26, 2026 22:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/ui kind/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants