Skip to content

[_]: feat/email validation when setting address up#73

Merged
xabg2 merged 2 commits into
masterfrom
feature/check-som-rules-of-user-address
Jul 16, 2026
Merged

[_]: feat/email validation when setting address up#73
xabg2 merged 2 commits into
masterfrom
feature/check-som-rules-of-user-address

Conversation

@xabg2

@xabg2 xabg2 commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Checking the address user before creating it so we can validate it follows some predefined standards, like:

  • 3 to 30 characters max
  • Lowercase letters, numbers, ., - and _
  • Start and end with a letter or number
  • Username must be available

@xabg2
xabg2 requested a review from jzunigax2 July 16, 2026 14:58
@xabg2 xabg2 self-assigned this Jul 16, 2026
@xabg2 xabg2 added the enhancement New feature or request label Jul 16, 2026
@coderabbitai

coderabbitai Bot commented Jul 16, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@xabg2, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 21 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

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.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: dab55151-4479-4524-a582-767450f54f5a

📥 Commits

Reviewing files that changed from the base of the PR and between 8c1ef3d and c83e6fd.

📒 Files selected for processing (8)
  • src/features/identity-setup/components/ConfirmChange.tsx
  • src/features/identity-setup/components/ConfirmPassword.tsx
  • src/features/identity-setup/components/UpdateEmail.tsx
  • src/features/identity-setup/hooks/emailAddressRules.test.ts
  • src/features/identity-setup/hooks/useUpdateEmail.ts
  • src/i18n/locales/es.json
  • src/i18n/locales/fr.json
  • src/i18n/locales/it.json
📝 Walkthrough

Walkthrough

Identity setup now uses shared, debounced email username validation with per-rule feedback, focus-aware rendering, and validity-gated form submission. Confirmation components also use form submit handlers, while localized validation guidance and error messages are updated.

Changes

Identity setup validation flow

Layer / File(s) Summary
Email validation contracts and debounce state
src/features/identity-setup/hooks/emailAddressRules.ts, src/features/identity-setup/hooks/*.test.ts
Defines length, charset, edge, and reserved-name rules, aggregate validity helpers, and tests for rule statuses and debounced validation behavior.
Update email validation UI
src/features/identity-setup/components/UpdateEmail.tsx, src/features/identity-setup/components/SelectMailInput.tsx, src/features/identity-setup/components/EmailAddressRulesPanel.tsx, src/i18n/locales/*.json, src/features/identity-setup/index.tsx
Connects validation and focus state to the email form, renders rule feedback, updates localized guidance, and reorganizes imports.
Confirmation form submission
src/features/identity-setup/components/ConfirmChange.tsx, src/features/identity-setup/components/ConfirmPassword.tsx
Replaces direct button click callbacks with prevented form submissions and submit buttons.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Suggested reviewers: jzunigax2

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title is clearly related to the main change: adding email validation during address setup.
Description check ✅ Passed The description matches the changeset and summarizes the new email address validation rules.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/check-som-rules-of-user-address

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Warning

CodeRabbit couldn't request changes on this pull request because it doesn't have sufficient GitHub permissions.

Please grant CodeRabbit Pull requests: Read and write permission and re-run the review.

👉 Steps to fix this

Actionable comments posted: 7

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/i18n/locales/en.json (1)

160-161: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Add the missing English username validation key.
src/i18n/locales/en.json is missing errors.identitySetup.usernameInvalid; es.json, fr.json, and it.json already have it.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/i18n/locales/en.json` around lines 160 - 161, Add the missing
errors.identitySetup.usernameInvalid translation key to the English locale,
matching the existing identitySetup structure and the corresponding validation
message used in the other locales.

Source: Path instructions

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/features/identity-setup/components/ConfirmPassword.tsx`:
- Around line 21-25: Replace React.FormEvent with
React.SubmitEvent<HTMLFormElement> in the handleSubmit form handlers for
ConfirmPassword.tsx and ConfirmChange.tsx, preserving their existing submission
behavior.

In `@src/features/identity-setup/components/SelectMailInput.tsx`:
- Around line 15-24: Extract the isFocused state and its related focus event
handling from SelectMailInput into a custom hook such as useSelectMailInput
under the feature’s hooks/ directory or alongside the component. Update
SelectMailInput to consume the hook and remain focused on rendering and prop
wiring.
- Line 46: Update the input element’s Tailwind class in SelectMailInput to use
outline-hidden instead of outline-none, preserving the existing styling and
accessibility behavior.

In `@src/features/identity-setup/components/UpdateEmail.tsx`:
- Around line 18-52: Extract the state, validation, and submission logic from
the UpdateEmail component into a useUpdateEmail custom hook, including domain,
focus state, descriptions, panel visibility, and the submit handler. Remove
handleFormKeyDown and handleConfirm; have the hook’s handleSubmit prevent
default, validate isValid, and call onNext directly. Keep UpdateEmail focused on
rendering the hook-provided values and handlers, with the form using only
onSubmit.

In `@src/features/identity-setup/hooks/emailAddressRules.test.ts`:
- Around line 14-34: Refactor every test in the file, including the length-rule
tests and other test cases, to follow Arrange–Act–Assert structure: set up
inputs and dependencies first, invoke ruleStatus in a separate Act section, then
perform assertions. Add blank lines separating each section while preserving all
existing test behavior and expectations.

In `@src/features/identity-setup/hooks/useEmailAddressValidation.test.ts`:
- Around line 6-8: Update the beforeEach setup in the email address validation
tests to call vi.restoreAllMocks() so mocks are reset before every test, while
preserving the existing fake-timer initialization.

In `@src/features/identity-setup/hooks/useEmailAddressValidation.ts`:
- Around line 25-27: Update the isValid calculation in the email validation hook
to return false whenever username differs from debouncedUsername, while
preserving the existing rules.every validation when both values are
synchronized. Include username in the relevant memo dependencies so rapid input
cannot submit based on stale validation.

---

Outside diff comments:
In `@src/i18n/locales/en.json`:
- Around line 160-161: Add the missing errors.identitySetup.usernameInvalid
translation key to the English locale, matching the existing identitySetup
structure and the corresponding validation message used in the other locales.
🪄 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: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 70f50da3-fe96-4647-b699-10daa649f619

📥 Commits

Reviewing files that changed from the base of the PR and between 0d747a9 and 8c1ef3d.

📒 Files selected for processing (14)
  • src/features/identity-setup/components/ConfirmChange.tsx
  • src/features/identity-setup/components/ConfirmPassword.tsx
  • src/features/identity-setup/components/EmailAddressRulesPanel.tsx
  • src/features/identity-setup/components/SelectMailInput.tsx
  • src/features/identity-setup/components/UpdateEmail.tsx
  • src/features/identity-setup/hooks/emailAddressRules.test.ts
  • src/features/identity-setup/hooks/emailAddressRules.ts
  • src/features/identity-setup/hooks/useEmailAddressValidation.test.ts
  • src/features/identity-setup/hooks/useEmailAddressValidation.ts
  • src/features/identity-setup/index.tsx
  • src/i18n/locales/en.json
  • src/i18n/locales/es.json
  • src/i18n/locales/fr.json
  • src/i18n/locales/it.json

Comment on lines +21 to +25
const handleSubmit = (e: React.FormEvent) => {
e.preventDefault();
onConfirmPassword();
};

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Prefer React.SubmitEvent over React.FormEvent for form submissions.

Both files type the form submission event as React.FormEvent. Based on learnings, FormEvent is deprecated in React 19.2+ in favor of SubmitEvent. Please update the event types for form handlers to React.SubmitEvent<HTMLFormElement>.

  • src/features/identity-setup/components/ConfirmPassword.tsx#L21-L25: change e: React.FormEvent to e: React.SubmitEvent<HTMLFormElement>.
  • src/features/identity-setup/components/ConfirmChange.tsx#L27-L32: change e: React.FormEvent to e: React.SubmitEvent<HTMLFormElement>.
📍 Affects 2 files
  • src/features/identity-setup/components/ConfirmPassword.tsx#L21-L25 (this comment)
  • src/features/identity-setup/components/ConfirmChange.tsx#L27-L32
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/features/identity-setup/components/ConfirmPassword.tsx` around lines 21 -
25, Replace React.FormEvent with React.SubmitEvent<HTMLFormElement> in the
handleSubmit form handlers for ConfirmPassword.tsx and ConfirmChange.tsx,
preserving their existing submission behavior.

Source: Learnings

Comment thread src/features/identity-setup/components/SelectMailInput.tsx
Comment thread src/features/identity-setup/components/SelectMailInput.tsx
Comment on lines +18 to +52
const { username, rules, isValid, validateAddress } = useEmailAddressValidation();
const [domain, setDomain] = useState<string>(activeDomains[0]?.domain ?? '');
const [usernameError, setUsernameError] = useState<string>('');
const [isUsernameFocused, setIsUsernameFocused] = useState(false);

const descriptions = translateArray('identitySetup.updateEmail.description', {
name: userFullName,
current_email: currentEmail,
});

const handleConfirm = () => {
if (!username.trim()) {
setUsernameError(translate('errors.identitySetup.usernameRequired'));
return;
}
if (!isValid) return;
onNext({ address: username, domain });
};

const handleSubmit = (e: React.SubmitEvent) => {
e.preventDefault();
handleConfirm();
};

const handleFormKeyDown = (e: React.KeyboardEvent<HTMLFormElement>) => {
if (e.key !== 'Enter' || (e.target as HTMLElement).tagName === 'BUTTON') return;

e.preventDefault();
handleConfirm();
};

const hasStartedTyping = rules.some((rule) => rule.status !== 'idle');
const isPanelVisible = isUsernameFocused || hasStartedTyping;

return (
<div className="flex flex-col gap-5 justify-center items-center">
<form
onSubmit={handleSubmit}
onKeyDown={handleFormKeyDown}
className="flex flex-col gap-5 justify-center items-center"
>

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win

Extract logic into a custom hook and remove redundant event handler.

As per path instructions, components must be "dumb" and only render; all state and event handlers should be extracted into a custom hook (e.g., useUpdateEmail).

Additionally, the handleFormKeyDown function is redundant. Since the input is within a <form> containing a <Button type="submit">, pressing the Enter key inside the input will natively trigger the onSubmit event. You can safely remove handleFormKeyDown and handleConfirm, moving the validation and submission logic directly into handleSubmit within your new hook.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/features/identity-setup/components/UpdateEmail.tsx` around lines 18 - 52,
Extract the state, validation, and submission logic from the UpdateEmail
component into a useUpdateEmail custom hook, including domain, focus state,
descriptions, panel visibility, and the submit handler. Remove handleFormKeyDown
and handleConfirm; have the hook’s handleSubmit prevent default, validate
isValid, and call onNext directly. Keep UpdateEmail focused on rendering the
hook-provided values and handlers, with the form using only onSubmit.

Source: Path instructions

Comment thread src/features/identity-setup/hooks/emailAddressRules.test.ts
Comment thread src/features/identity-setup/hooks/useEmailAddressValidation.test.ts
Comment on lines +25 to +27
const rules = useMemo(() => validateEmailAddress(debouncedUsername), [debouncedUsername]);
const isValid = useMemo(() => rules.every((rule) => isRuleStatusValid(rule.status)), [rules]);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🔴 Critical | ⚡ Quick win

Prevent submission of invalid input during debounce delay.

Currently, isValid evaluates debouncedUsername. If the user types rapidly and triggers the submit action before the debounce delay elapses, isValid may still return true based on the previous valid state. This allows the form to submit an unvalidated, potentially invalid username (TOCTOU flaw).

To prevent this, isValid should evaluate to false whenever username is out of sync with debouncedUsername.

🐛 Proposed fix
   const rules = useMemo(() => validateEmailAddress(debouncedUsername), [debouncedUsername]);
-  const isValid = useMemo(() => rules.every((rule) => isRuleStatusValid(rule.status)), [rules]);
+  const isSynchronized = username === debouncedUsername;
+  const isValid = useMemo(
+    () => isSynchronized && rules.every((rule) => isRuleStatusValid(rule.status)),
+    [rules, isSynchronized]
+  );
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const rules = useMemo(() => validateEmailAddress(debouncedUsername), [debouncedUsername]);
const isValid = useMemo(() => rules.every((rule) => isRuleStatusValid(rule.status)), [rules]);
const rules = useMemo(() => validateEmailAddress(debouncedUsername), [debouncedUsername]);
const isSynchronized = username === debouncedUsername;
const isValid = useMemo(
() => isSynchronized && rules.every((rule) => isRuleStatusValid(rule.status)),
[rules, isSynchronized]
);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/features/identity-setup/hooks/useEmailAddressValidation.ts` around lines
25 - 27, Update the isValid calculation in the email validation hook to return
false whenever username differs from debouncedUsername, while preserving the
existing rules.every validation when both values are synchronized. Include
username in the relevant memo dependencies so rapid input cannot submit based on
stale validation.

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jul 16, 2026

Copy link
Copy Markdown

Deploying mail-web with  Cloudflare Pages  Cloudflare Pages

Latest commit: c83e6fd
Status: ✅  Deploy successful!
Preview URL: https://50f0e63a.mail-web-ea0.pages.dev
Branch Preview URL: https://feature-check-som-rules-of-u.mail-web-ea0.pages.dev

View logs

@sonarqubecloud

Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
75.6% Coverage on New Code (required ≥ 80%)
B Reliability Rating on New Code (required ≥ A)

See analysis details on SonarQube Cloud

💡 Need a hand with PR review? Try Gitar by Sonar!

@xabg2
xabg2 merged commit 1cc5d27 into master Jul 16, 2026
5 of 6 checks passed
@xabg2
xabg2 deleted the feature/check-som-rules-of-user-address branch July 16, 2026 15:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants