fix: prevent empty login form submission

Fix isFormComplete derived always returning true for login mode. Now requires email and password to be non-empty before enabling Sign In button. Add early-return guard in handleSubmit to prevent sending empty credentials.
This commit is contained in:
2026-08-22 00:34:48 +01:00
parent 9170990340
commit 5deefa1205
+27 -20
View File
@@ -15,7 +15,7 @@
import * as languageCommon from '@zxcvbn-ts/language-common'; import * as languageCommon from '@zxcvbn-ts/language-common';
import * as languageEn from '@zxcvbn-ts/language-en'; import * as languageEn from '@zxcvbn-ts/language-en';
import { toast } from 'svelte-sonner'; import { toast } from 'svelte-sonner';
import { sanitizeText } from '$lib/utils/toast-safe'; import { extractErrorMessage, sanitizeText } from '$lib/utils/toast-safe';
// set up options so that feedback, dictionary etc. are included // set up options so that feedback, dictionary etc. are included
const zxcvbn = new ZxcvbnFactory({ const zxcvbn = new ZxcvbnFactory({
@@ -144,6 +144,12 @@
async function handleSubmit() { async function handleSubmit() {
if (isLogin) { if (isLogin) {
const email = formData.email.trim().toLowerCase();
if (!email || !formData.password) {
toast.error('Please enter your email and password.');
return;
}
// Login flow with loading toast // Login flow with loading toast
const loadingToast = toast.loading('Signing in...'); const loadingToast = toast.loading('Signing in...');
@@ -152,7 +158,7 @@
method: 'POST', method: 'POST',
headers: { 'Content-Type': 'application/json' }, headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ body: JSON.stringify({
email: formData.email.trim().toLowerCase(), email,
password: formData.password password: formData.password
}) })
}); });
@@ -179,7 +185,7 @@
toast.error('Invalid email or password.', { id: loadingToast }); toast.error('Invalid email or password.', { id: loadingToast });
} else { } else {
const text = await response.text(); const text = await response.text();
toast.error('Error: ' + sanitizeText(text), { id: loadingToast }); toast.error('Error: ' + sanitizeText(extractErrorMessage(text)), { id: loadingToast });
} }
} catch (err) { } catch (err) {
console.error(err); console.error(err);
@@ -213,7 +219,7 @@
toggleMode(); toggleMode();
} else { } else {
const text = await response.text(); const text = await response.text();
toast.error('Error: ' + sanitizeText(text), { id: loadingToast }); toast.error('Error: ' + sanitizeText(extractErrorMessage(text)), { id: loadingToast });
} }
} catch (err) { } catch (err) {
console.error(err); console.error(err);
@@ -248,22 +254,23 @@
// form completion check // form completion check
const isFormComplete = $derived( const isFormComplete = $derived(
isLogin || isLogin
(formData.firstName.trim() && ? formData.email.trim().length > 0 && formData.password.length > 0
formData.lastName.trim() && : (formData.firstName.trim() &&
formData.phone && formData.lastName.trim() &&
formData.dateOfBirth && formData.phone &&
formData.email && formData.dateOfBirth &&
formData.password && formData.email &&
formData.confirmPassword && formData.password &&
formData.password === formData.confirmPassword && formData.confirmPassword &&
passwordStrength && formData.password === formData.confirmPassword &&
formData.password.length >= 6 && passwordStrength &&
passwordStrength.score >= 2 && formData.password.length >= 6 &&
agreedToPolicy && passwordStrength.score >= 2 &&
!validationErrors.email && agreedToPolicy &&
!validationErrors.phone && !validationErrors.email &&
!validationErrors.dateOfBirth) !validationErrors.phone &&
!validationErrors.dateOfBirth)
); );
</script> </script>