fix(frontend): validate Full Name and Work Email on Get Started form - #4045
Conversation
|
Someone is attempting to deploy a commit to the ritesh Team on Vercel. A member of the Team first needs to authorize it. |
📝 WalkthroughWalkthroughAdmin signup now validates full names and work emails during step one. Invalid values display validation errors and prevent navigation to the next step. ChangesAdmin signup validation
Estimated code review effort: 2 (Simple) | ~10 minutes Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches 💡 1🛠️ Fix failing CI checks 💡
🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 5
🤖 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 `@Frontend/src/pages/AdminSignup.jsx`:
- Around line 67-68: Update the Full Name validation in the name-checking logic
to restrict separators to literal spaces instead of \s, including both
repeated-spacing and boundary-punctuation checks. Preserve acceptance of
letters, hyphens, and apostrophes while rejecting tabs, line breaks, and other
whitespace characters.
- Around line 104-113: Ensure the form submission handler handleSubmit applies
the fullName and email validation before calling signup, including when users
return to earlier steps and submit with Enter. Reuse the existing validation
logic from nextStep or route non-final submissions through nextStep, while
preserving the current agreement checks and final-step signup behavior.
- Around line 104-113: Enforce server-side validation before user/profile
creation in the admin signup backend flow, rather than relying on the client
validators in AdminSignup.jsx. Add checks for full_name and email before
supabase.auth.signUp or the corresponding profile insert, rejecting empty or
invalid values and preventing any record from being created; reuse the existing
Edge Function/database trigger entry point and validation conventions.
- Around line 65-74: Update validateFullName and validateEmail so trimmed-empty
input returns the appropriate required-field error instead of null, or ensure
nextStep performs required checks against trimmed values. Preserve existing
format validation for non-empty values and prevent whitespace-only names or
emails from advancing the form.
- Around line 72-75: Update validateEmail to reject local parts that start or
end with a dot or contain consecutive dots, and validate each domain label so
labels cannot start or end with a hyphen or contain consecutive dots. Preserve
the existing empty-input behavior and valid local@domain.tld acceptance while
ensuring nextStep receives null only for structurally valid addresses.
🪄 Autofix
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: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: a5ca4173-ec9c-444e-b6c4-47aeb6242997
📒 Files selected for processing (1)
Frontend/src/pages/AdminSignup.jsx
| if (!name || !name.trim()) return null; | ||
| if (name.trim().length < 2) return 'Full Name must be at least 2 characters long.'; | ||
| if (!/^[\p{L}\s'-]+$/u.test(name)) return 'Full Name can only contain letters, spaces, hyphens, and apostrophes.'; | ||
| if (/\s{2,}|^['\s-]|['\s-]$/.test(name)) return 'Full Name contains invalid spacing or punctuation.'; | ||
| return null; | ||
| }; | ||
|
|
||
| const validateEmail = (email) => { | ||
| if (!email || !email.trim()) return null; | ||
| if (!/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/.test(email)) return 'Please enter a valid work email (e.g. name@company.com).'; |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
Reject whitespace-only values.
validateFullName and validateEmail return null when .trim() is empty. The required check in nextStep tests the untrimmed values, so " " passes and the form advances without an error. This violates the requirement to reject invalid Full Name and Work Email values.
Return a required-field error for trimmed-empty values, or trim the values in the required check.
Suggested fix
const validateFullName = (name) => {
- if (!name || !name.trim()) return null;
+ if (!name || !name.trim()) return 'Full Name is required.';
if (name.trim().length < 2) return 'Full Name must be at least 2 characters long.';
if (!/^[\p{L}\s'-]+$/u.test(name)) return 'Full Name can only contain letters, spaces, hyphens, and apostrophes.';
if (/\s{2,}|^['\s-]|['\s-]$/.test(name)) return 'Full Name contains invalid spacing or punctuation.';
return null;
};
const validateEmail = (email) => {
- if (!email || !email.trim()) return null;
+ if (!email || !email.trim()) return 'Work Email is required.';
if (!/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/.test(email)) return 'Please enter a valid work email (e.g. name@company.com).';
return null;
};📝 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.
| if (!name || !name.trim()) return null; | |
| if (name.trim().length < 2) return 'Full Name must be at least 2 characters long.'; | |
| if (!/^[\p{L}\s'-]+$/u.test(name)) return 'Full Name can only contain letters, spaces, hyphens, and apostrophes.'; | |
| if (/\s{2,}|^['\s-]|['\s-]$/.test(name)) return 'Full Name contains invalid spacing or punctuation.'; | |
| return null; | |
| }; | |
| const validateEmail = (email) => { | |
| if (!email || !email.trim()) return null; | |
| if (!/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/.test(email)) return 'Please enter a valid work email (e.g. name@company.com).'; | |
| if (!name || !name.trim()) return 'Full Name is required.'; | |
| if (name.trim().length < 2) return 'Full Name must be at least 2 characters long.'; | |
| if (!/^[\p{L}\s'-]+$/u.test(name)) return 'Full Name can only contain letters, spaces, hyphens, and apostrophes.'; | |
| if (/\s{2,}|^['\s-]|['\s-]$/.test(name)) return 'Full Name contains invalid spacing or punctuation.'; | |
| return null; | |
| }; | |
| const validateEmail = (email) => { | |
| if (!email || !email.trim()) return 'Work Email is required.'; | |
| if (!/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/.test(email)) return 'Please enter a valid work email (e.g. name@company.com).'; |
🤖 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 `@Frontend/src/pages/AdminSignup.jsx` around lines 65 - 74, Update
validateFullName and validateEmail so trimmed-empty input returns the
appropriate required-field error instead of null, or ensure nextStep performs
required checks against trimmed values. Preserve existing format validation for
non-empty values and prevent whitespace-only names or emails from advancing the
form.
| if (!/^[\p{L}\s'-]+$/u.test(name)) return 'Full Name can only contain letters, spaces, hyphens, and apostrophes.'; | ||
| if (/\s{2,}|^['\s-]|['\s-]$/.test(name)) return 'Full Name contains invalid spacing or punctuation.'; |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Restrict Full Name separators to spaces.
The \s character class accepts tabs, line breaks, and other whitespace. A value such as "Grace\tHopper" passes the allowed-character check because the spacing rule only rejects repeated whitespace or boundary punctuation. Use a literal space or explicitly define the accepted Unicode separators.
Suggested fix
- if (!/^[\p{L}\s'-]+$/u.test(name)) return 'Full Name can only contain letters, spaces, hyphens, and apostrophes.';
- if (/\s{2,}|^['\s-]|['\s-]$/.test(name)) return 'Full Name contains invalid spacing or punctuation.';
+ if (!/^[\p{L} '-]+$/u.test(name)) return 'Full Name can only contain letters, spaces, hyphens, and apostrophes.';
+ if (/ {2,}|^[' -]|[' -]$/.test(name)) return 'Full Name contains invalid spacing or punctuation.';📝 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.
| if (!/^[\p{L}\s'-]+$/u.test(name)) return 'Full Name can only contain letters, spaces, hyphens, and apostrophes.'; | |
| if (/\s{2,}|^['\s-]|['\s-]$/.test(name)) return 'Full Name contains invalid spacing or punctuation.'; | |
| if (!/^[\p{L} '-]+$/u.test(name)) return 'Full Name can only contain letters, spaces, hyphens, and apostrophes.'; | |
| if (/ {2,}|^[' -]|[' -]$/.test(name)) return 'Full Name contains invalid spacing or punctuation.'; |
🤖 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 `@Frontend/src/pages/AdminSignup.jsx` around lines 67 - 68, Update the Full
Name validation in the name-checking logic to restrict separators to literal
spaces instead of \s, including both repeated-spacing and boundary-punctuation
checks. Preserve acceptance of letters, hyphens, and apostrophes while rejecting
tabs, line breaks, and other whitespace characters.
| const validateEmail = (email) => { | ||
| if (!email || !email.trim()) return null; | ||
| if (!/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/.test(email)) return 'Please enter a valid work email (e.g. name@company.com).'; | ||
| return null; |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
Reject malformed dot and hyphen placement in email addresses.
The current pattern accepts .alice@example.com, alice..smith@example.com, alice@-example.com, and alice@example..com. These values do not match a valid local@domain.tld format, but nextStep accepts them. Add local-part dot rules and validate each domain label.
Suggested structured validation
const validateEmail = (email) => {
if (!email || !email.trim()) return null;
- if (!/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/.test(email)) return 'Please enter a valid work email (e.g. name@company.com).';
+ const parts = email.split("@");
+ const [local, domain] = parts;
+ const labels = domain?.split(".") ?? [];
+ const isValid =
+ parts.length === 2 &&
+ /^[a-zA-Z0-9._%+-]+$/.test(local) &&
+ !local.startsWith(".") &&
+ !local.endsWith(".") &&
+ !local.includes("..") &&
+ labels.length >= 2 &&
+ labels.every((label) => /^[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?$/.test(label)) &&
+ /^[a-zA-Z]{2,}$/.test(labels[labels.length - 1]);
+ if (!isValid) return 'Please enter a valid work email (e.g. name@company.com).';
return null;
};📝 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.
| const validateEmail = (email) => { | |
| if (!email || !email.trim()) return null; | |
| if (!/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/.test(email)) return 'Please enter a valid work email (e.g. name@company.com).'; | |
| return null; | |
| const validateEmail = (email) => { | |
| if (!email || !email.trim()) return null; | |
| const parts = email.split("@"); | |
| const [local, domain] = parts; | |
| const labels = domain?.split(".") ?? []; | |
| const isValid = | |
| parts.length === 2 && | |
| /^[a-zA-Z0-9._%+-]+$/.test(local) && | |
| !local.startsWith(".") && | |
| !local.endsWith(".") && | |
| !local.includes("..") && | |
| labels.length >= 2 && | |
| labels.every((label) => /^[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?$/.test(label)) && | |
| /^[a-zA-Z]{2,}$/.test(labels[labels.length - 1]); | |
| if (!isValid) return 'Please enter a valid work email (e.g. name@company.com).'; | |
| return null; | |
| }; |
🤖 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 `@Frontend/src/pages/AdminSignup.jsx` around lines 72 - 75, Update
validateEmail to reject local parts that start or end with a dot or contain
consecutive dots, and validate each domain label so labels cannot start or end
with a hyphen or contain consecutive dots. Preserve the existing empty-input
behavior and valid local@domain.tld acceptance while ensuring nextStep receives
null only for structurally valid addresses.
| const nameError = validateFullName(formData.fullName); | ||
| if (nameError) { | ||
| setError(nameError); | ||
| return; | ||
| } | ||
| const emailError = validateEmail(formData.email); | ||
| if (emailError) { | ||
| setError(emailError); | ||
| return; | ||
| } |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
Guard the form submission path, not only nextStep.
The new checks run only in nextStep, but the form still submits through handleSubmit on every step. A user can complete step three, return to step one, change fullName or email, and press Enter. Because the agreement flags remain checked, handleSubmit can call signup without running these validators.
Route non-final submissions through nextStep, or extract shared step validators and call them from both handlers.
Suggested fix
const handleSubmit = async (e) => {
e.preventDefault();
+ if (step !== 3) {
+ nextStep();
+ return;
+ }
if (!formData.agreedToTerms || !formData.isAuthorized) {
setError("You must agree to the terms and authorize company registration.");
return;🧰 Tools
🪛 ast-grep (0.45.0)
[warning] 105-105: Avoid using the initial state variable in setState
Context: setError(nameError)
Note: [CWE-710] Improper Adherence to Coding Standards. Security best practice.
(setstate-same-var)
[warning] 110-110: Avoid using the initial state variable in setState
Context: setError(emailError)
Note: [CWE-710] Improper Adherence to Coding Standards. Security best practice.
(setstate-same-var)
🤖 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 `@Frontend/src/pages/AdminSignup.jsx` around lines 104 - 113, Ensure the form
submission handler handleSubmit applies the fullName and email validation before
calling signup, including when users return to earlier steps and submit with
Enter. Reuse the existing validation logic from nextStep or route non-final
submissions through nextStep, while preserving the current agreement checks and
final-step signup behavior.
🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Locate the signup implementation and downstream handlers.
while IFS= read -r file; do
rg -n -C 8 '\bsignup\b|auth\.signUp|fullName|email' "$file" || true
done < <(fd -t f -i 'authStore' .)
rg -n -C 6 \
'auth\.signUp|signUp\s*\(|fullName|full_name|email|profiles|admin' \
--glob '*.js' \
--glob '*.jsx' \
--glob '*.ts' \
--glob '*.tsx' \
--glob '*.sql' \
. || true
# Expected: server-side validation rejects invalid names and emails before persistence.Repository: riteshbonthalakoti/HELPDESK.AI
Length of output: 220
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "## files matching auth/admin signup"
git ls-files | rg -n 'AdminSignup|App\.jsx|auth|signup|AuthStore|supabase|schema|profiles|admin' || true
echo
echo "## AdminSignup relevant lines"
if [ -f Frontend/src/pages/AdminSignup.jsx ]; then
nl -ba Frontend/src/pages/AdminSignup.jsx | sed -n '1,220p'
fi
echo
echo "## App signup route lines"
if [ -f Frontend/src/App.jsx ]; then
nl -ba Frontend/src/App.jsx | sed -n '1,220p'
fi
echo
echo "## target identifiers in tracked files"
python3 - <<'PY'
import subprocess
files = subprocess.check_output(['git','ls-files'], text=True).splitlines()
terms = ['signup','signUp','auth.signUp','fullName','full_name','email','profiles','admin']
for term in terms:
matches = []
for f,fname in zip(files,files):
if fname.endswith(('.js','.jsx','.ts','.tsx','.sql','.json','.env*','.md'))):
try:
text = open(f,'r',errors='ignore').read()
except Exception:
continue
if term in text:
matches.append(fname)
print(f"\n# {term}")
for m in matches[:200]:
print(m)
PYRepository: riteshbonthalakoti/HELPDESK.AI
Length of output: 2899
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "## frontend lines"
for f in Frontend/src/pages/AdminSignup.jsx Frontend/src/App.jsx Frontend/src/store/authStore.js Frontend/src/store/adminStore.js Frontend/src/lib/supabaseClient.js; do
if [ -f "$f" ]; then
echo "--- $f"
awk '{printf "%6d\t%s\n", NR, $0}' "$f" | sed -n '1,240p'
fi
done
echo
echo "## backend/auth/relevant lines"
for f in supabase/functions/ai-proxy/index.ts supabase/functions/email-notifier/index.ts supabase/functions/send-user-approval-email/index.ts supabase/migrations/20260330231301_knowledge_base.sql supabase/migrations/20260330231302_webhook-trigger.sql supabase/migrations/20260331000000_resolve_vault_sync.sql supabase/migrations/20260331000001_sync_vault.sql; do
if [ -f "$f" ]; then
echo "--- $f"
awk '{printf "%6d\t%s\n", NR, $0}' "$f" | sed -n '1,220p'
fi
done
echo
echo "## search exact identifiers"
python3 - <<'PY'
import subprocess, re
files = subprocess.check_output(['git','ls-files'], text=True).splitlines()
terms = [r'\bsignup\b', r'/admin-signup', r'\bauth\.signUp\b', r'\bsignUp\s*\(', r'\bfullName\b', r'\bfull_name\b', r'\bemail\b', r'\bprofiles\b', r'\badmin\b']
for term in terms:
print(f"\n# {term}")
pat = re.compile(term)
count = 0
for f in files:
if f.endswith(('.js','.jsx','.ts','.tsx','.sql','.json','.env','.md'))):
try:
text = open(f,'r',errors='ignore').read()
except Exception:
continue
for i,line in enumerate(text.splitlines(),1):
if pat.search(line):
print(f"{f}:{i}:{line.strip()}")
count += 1
print(f"totalCount={count}")
PYRepository: riteshbonthalakoti/HELPDESK.AI
Length of output: 50386
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "## supabase migration files list"
git ls-files supabase/migrations | awk '{printf "%6d\t%s\n", NR, $0}' | sed -n '1,120p'
echo
echo "## migrations containing profiles/auth hooks/email validation"
for f in $(git ls-files supabase/migrations); do
if rg -q 'CREATE TABLE "profiles"|FULL NAME|full_name|user_details|auth\.users|security\s+definer|check\(|is_email|email' "$f"; then
echo "--- $f"
rg -n -C 5 'profiles|full_name|security\s+definer|check\(|is_email|email|admin|role' "$f" || true
fi
done
echo
echo "## Supabase Edge functions signup/profile handling"
git ls-files supabase/functions | while read -r f; do
if rg -q 'auth\.signUp|insert\(|profiles|full_name|send-user-approval|approval|after.*auth' "$f" 2>/dev/null; then
echo "--- $f"
rg -n -C 4 'auth\.signUp|insert\(|profiles|full_name|send-user-approval|approval|after.*auth|RECORD' "$f" || true
fi
done
echo
echo "## exact targeted references (limited)"
python3 - <<'PY'
import subprocess, re
files = subprocess.check_output(['git','ls-files'], text=True).splitlines()
terms=[
r'\bsignup\b', r'/admin-signup', r'\bauth\.signUp\b',
r'auth\.signUp\s*\(',
r'\bfullName\b', r'\bfull_name\b',
r'\bemail\b', r'profiles',
r'(create\s+trigger|CREATE\s+TRIGGER|security\s+definer|RECORD\.full_name|record\.full_name|new\.full_name|old\.full_name)',
]
for term in terms:
print(f"\n# {term}")
pat=re.compile(term, re.I)
for f in files:
if f.endswith(('.js','.jsx','.ts','.tsx','.sql','.json','.env','.md')) and (f.startswith('Frontend/src') or f.startswith('supabase') or f.startswith('backend')):
try: text=open(f,errors='ignore').read()
except Exception: continue
try: lines=text.splitlines()
except Exception: continue
for i,line in enumerate(lines,1):
if pat.search(line) and not f.endswith(('.tmp','.lock','package-lock.json')):
print(f"{f}:{i}:{line.strip()}")
PYRepository: riteshbonthalakoti/HELPDESK.AI
Length of output: 50386
Reject invalid admin signup values server-side.
AdminSignup.jsx only skips the client-side validator when full Name is empty, then authStore.js still calls supabase.auth.signUp and passes fullName as auth metadata. Add an Edge Function/database trigger check for full_name and email before creating the user/profile so bypasses cannot create invalid records.
🧰 Tools
🪛 ast-grep (0.45.0)
[warning] 105-105: Avoid using the initial state variable in setState
Context: setError(nameError)
Note: [CWE-710] Improper Adherence to Coding Standards. Security best practice.
(setstate-same-var)
[warning] 110-110: Avoid using the initial state variable in setState
Context: setError(emailError)
Note: [CWE-710] Improper Adherence to Coding Standards. Security best practice.
(setstate-same-var)
🤖 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 `@Frontend/src/pages/AdminSignup.jsx` around lines 104 - 113, Enforce
server-side validation before user/profile creation in the admin signup backend
flow, rather than relying on the client validators in AdminSignup.jsx. Add
checks for full_name and email before supabase.auth.signUp or the corresponding
profile insert, rejecting empty or invalid values and preventing any record from
being created; reuse the existing Edge Function/database trigger entry point and
validation conventions.
Closes #4031
Summary
The Get Started (admin signup) form's Personal Information step accepted invalid values: the Full Name field allowed numbers/special characters (e.g. \�12d!) and the Work Email field accepted incomplete addresses like \�bc@a.
Changes
extStep\ flow so invalid values block progression and show a clear error message.
Summary by CodeRabbit