Fix: Slot reservation only after successful email validation

- Move email validation before slot reservation in backend
- Remove duplicate frontend email validation
- Slots are no longer blocked by failed booking attempts
- Clean up unused email error UI components
- Ensure slots remain available if email validation fails
This commit is contained in:
2025-10-02 13:39:13 +02:00
parent 73cf733c5f
commit 5baa231d3c
5 changed files with 64 additions and 48 deletions

View File

@@ -3,15 +3,17 @@
// Privacy-focused, no data storage, completely free
type EmailValidationResult = {
valid: boolean;
email: string;
domain?: string;
disposable?: boolean;
role?: boolean;
typo?: boolean;
suggestion?: string;
mx?: boolean;
error?: string;
validations: {
syntax: boolean;
domain_exists: boolean;
mx_records: boolean;
mailbox_exists: boolean;
is_disposable: boolean;
is_role_based: boolean;
};
score: number;
status: string;
};
/**
@@ -25,7 +27,7 @@ export async function validateEmail(email: string): Promise<{
}> {
try {
// Call Rapid Email Validator API
const response = await fetch(`https://rapid-email-verifier.fly.dev/verify/${encodeURIComponent(email)}`, {
const response = await fetch(`https://rapid-email-verifier.fly.dev/api/validate?email=${encodeURIComponent(email)}`, {
method: 'GET',
headers: {
'Accept': 'application/json',
@@ -33,15 +35,18 @@ export async function validateEmail(email: string): Promise<{
});
if (!response.ok) {
console.warn(`Email validation API error: ${response.status}`);
// If API is down, allow the email (fallback to Zod validation only)
return { valid: true };
console.error(`Email validation API error: ${response.status}`);
// If API is down, reject the email with error message
return {
valid: false,
reason: 'E-Mail-Validierung ist derzeit nicht verfügbar. Bitte überprüfe deine E-Mail-Adresse und versuche es erneut.'
};
}
const data: EmailValidationResult = await response.json();
// Check if email is disposable/temporary
if (data.disposable) {
if (data.validations.is_disposable) {
return {
valid: false,
reason: 'Temporäre oder Wegwerf-E-Mail-Adressen sind nicht erlaubt. Bitte verwende eine echte E-Mail-Adresse.',
@@ -49,20 +54,26 @@ export async function validateEmail(email: string): Promise<{
}
// Check if MX records exist (deliverable)
if (data.mx === false) {
if (!data.validations.mx_records) {
return {
valid: false,
reason: 'Diese E-Mail-Adresse kann keine E-Mails empfangen. Bitte überprüfe deine E-Mail-Adresse.',
};
}
// Check if email is generally valid
if (!data.valid) {
const suggestion = data.suggestion ? ` Meintest du vielleicht: ${data.suggestion}?` : '';
// Check if domain exists
if (!data.validations.domain_exists) {
return {
valid: false,
reason: `Ungültige E-Mail-Adresse.${suggestion}`,
suggestion: data.suggestion,
reason: 'Die E-Mail-Domain existiert nicht. Bitte überprüfe deine E-Mail-Adresse.',
};
}
// Check if email syntax is valid
if (!data.validations.syntax) {
return {
valid: false,
reason: 'Ungültige E-Mail-Adresse. Bitte überprüfe die Schreibweise.',
};
}
@@ -71,9 +82,11 @@ export async function validateEmail(email: string): Promise<{
} catch (error) {
console.error('Email validation error:', error);
// If validation fails, allow the email (fallback to Zod validation only)
// This ensures the booking system continues to work even if the API is down
return { valid: true };
// If validation fails, reject the email with error message
return {
valid: false,
reason: 'E-Mail-Validierung ist derzeit nicht verfügbar. Bitte überprüfe deine E-Mail-Adresse und versuche es erneut.'
};
}
}