diff --git a/backend/middleware/validation.js b/backend/middleware/validation.js index 6e5530c..8235b6f 100644 --- a/backend/middleware/validation.js +++ b/backend/middleware/validation.js @@ -81,7 +81,7 @@ const validateRegistration = [ .withMessage("Password must be between 8 and 128 characters") .matches(passwordStrengthRegex) .withMessage( - "Password must contain at least one uppercase letter, one lowercase letter, one number, and one special character" + "Password does not meet requirements" ) .custom((value) => { if (commonPasswords.includes(value.toLowerCase())) { @@ -275,7 +275,7 @@ const validateResetPassword = [ .withMessage("Password must be between 8 and 128 characters") .matches(passwordStrengthRegex) .withMessage( - "Password must contain at least one uppercase letter, one lowercase letter, one number, and one special character" + "Password does not meet requirements" ) .custom((value) => { if (commonPasswords.includes(value.toLowerCase())) { diff --git a/backend/routes/auth.js b/backend/routes/auth.js index 974fc48..1077fab 100644 --- a/backend/routes/auth.js +++ b/backend/routes/auth.js @@ -206,8 +206,7 @@ router.post( if (!user) { return res.status(401).json({ - error: - "Unable to log in. Please check your email and password, or create an account.", + error: "Please check your email and password, or create an account.", }); } @@ -226,8 +225,7 @@ router.post( // Increment login attempts await user.incLoginAttempts(); return res.status(401).json({ - error: - "Unable to log in. Please check your email and password, or create an account.", + error: "Please check your email and password, or create an account.", }); } diff --git a/frontend/public/index.html b/frontend/public/index.html index e39260a..fe060ef 100644 --- a/frontend/public/index.html +++ b/frontend/public/index.html @@ -10,7 +10,7 @@ content="Village Share - Life is too expensive. Rent or borrow from your neighbors" /> - Village Share - Community Rental Marketplace + Village Share = ({ const handleEmailSubmit = async (e: React.FormEvent) => { e.preventDefault(); - setLoading(true); setError(""); + // Custom validation to match app's error styling + if (mode === "signup") { + if (!firstName.trim()) { + setError("Please enter your first name"); + return; + } + if (!lastName.trim()) { + setError("Please enter your last name"); + return; + } + } + + const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; + if (!email.trim()) { + setError("Please enter your email address"); + return; + } + if (!emailRegex.test(email)) { + setError("Please enter a valid email address"); + return; + } + + setLoading(true); + try { if (mode === "login") { await login(email, password); @@ -132,7 +155,10 @@ const AuthModal: React.FC = ({ // Don't call onHide() - keep modal context for verification } } catch (err: any) { - setError(err.response?.data?.error || "An error occurred"); + // Show first specific validation error if available, otherwise generic error + const details = err.response?.data?.details; + const specificError = details?.[0]?.message; + setError(specificError || err.response?.data?.error || "An error occurred"); } finally { setLoading(false); } @@ -202,7 +228,6 @@ const AuthModal: React.FC = ({ className="form-control" value={firstName} onChange={(e) => setFirstName(e.target.value)} - required />
@@ -212,7 +237,6 @@ const AuthModal: React.FC = ({ className="form-control" value={lastName} onChange={(e) => setLastName(e.target.value)} - required />
@@ -222,11 +246,12 @@ const AuthModal: React.FC = ({
setEmail(e.target.value)} - required + placeholder="name@example.com" + autoComplete="email" />
@@ -298,6 +323,7 @@ const AuthModal: React.FC = ({ className="text-primary text-decoration-none" onClick={(e) => { e.preventDefault(); + setError(""); setMode(mode === "login" ? "signup" : "login"); }} > diff --git a/frontend/src/components/ForgotPasswordModal.tsx b/frontend/src/components/ForgotPasswordModal.tsx index 2936dfe..2b2aa19 100644 --- a/frontend/src/components/ForgotPasswordModal.tsx +++ b/frontend/src/components/ForgotPasswordModal.tsx @@ -25,9 +25,21 @@ const ForgotPasswordModal: React.FC = ({ const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); - setLoading(true); setError(""); + // Custom email validation to match app's error styling + const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; + if (!email.trim()) { + setError("Please enter your email address"); + return; + } + if (!emailRegex.test(email)) { + setError("Please enter a valid email address"); + return; + } + + setLoading(true); + try { await authAPI.forgotPassword(email); setSuccess(true); @@ -124,12 +136,12 @@ const ForgotPasswordModal: React.FC = ({
setEmail(e.target.value)} placeholder="your@email.com" - required + autoComplete="email" />