feat: Implement a 15-minute rate limit per email for contact form submissions.
This commit is contained in:
@@ -27,9 +27,24 @@ const Contact = () => {
|
||||
|
||||
const handleSubmit = async (e: React.FormEvent) => {
|
||||
e.preventDefault();
|
||||
// Vérification du délai de 15 minutes par email
|
||||
const storageKey = `lastMessageTime_${formData.email}`;
|
||||
const lastMessageTime = localStorage.getItem(storageKey);
|
||||
|
||||
if (lastMessageTime) {
|
||||
const timeSinceLastMessage = Date.now() - parseInt(lastMessageTime, 10);
|
||||
const fifteenMinutes = 15 * 60 * 1000;
|
||||
|
||||
if (timeSinceLastMessage < fifteenMinutes) {
|
||||
const remainingMinutes = Math.ceil((fifteenMinutes - timeSinceLastMessage) / 60000);
|
||||
setError(`Veuillez attendre ${remainingMinutes} minutes avant d'envoyer un nouveau message avec cette adresse email.`);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
setIsSubmitting(true);
|
||||
setError(null);
|
||||
|
||||
|
||||
try {
|
||||
const contactData: ContactFormData = {
|
||||
name: formData.name,
|
||||
@@ -37,13 +52,14 @@ const Contact = () => {
|
||||
subject: formData.subject,
|
||||
message: formData.message
|
||||
};
|
||||
|
||||
|
||||
const result = await sendContactEmail(contactData);
|
||||
|
||||
|
||||
if (result.success) {
|
||||
localStorage.setItem(`lastMessageTime_${formData.email}`, Date.now().toString());
|
||||
setIsSubmitted(true);
|
||||
setFormData({ name: '', email: '', subject: '', message: '' });
|
||||
|
||||
|
||||
// Reset du message de succès après 5 secondes
|
||||
setTimeout(() => {
|
||||
setIsSubmitted(false);
|
||||
@@ -51,7 +67,7 @@ const Contact = () => {
|
||||
} else {
|
||||
setError(result.message);
|
||||
}
|
||||
|
||||
|
||||
} catch (err) {
|
||||
const errorMessage = err instanceof Error ? err.message : 'Une erreur est survenue lors de l\'envoi du message.';
|
||||
setError(errorMessage);
|
||||
@@ -72,7 +88,7 @@ const Contact = () => {
|
||||
{
|
||||
icon: <Phone size={24} />,
|
||||
title: "Téléphone",
|
||||
content: "+32 455 19 47 62",
|
||||
content: "+32 455 19 47 62",
|
||||
link: "tel:+32455194762",
|
||||
color: "#34A853"
|
||||
},
|
||||
@@ -176,7 +192,7 @@ const Contact = () => {
|
||||
}}
|
||||
viewport={{ once: true }}
|
||||
>
|
||||
<div
|
||||
<div
|
||||
className="contact-icon"
|
||||
style={{ backgroundColor: `${contact.color}20`, color: contact.color }}
|
||||
>
|
||||
@@ -210,7 +226,7 @@ const Contact = () => {
|
||||
}}
|
||||
viewport={{ once: true }}
|
||||
>
|
||||
<div
|
||||
<div
|
||||
className="social-icon"
|
||||
style={{ backgroundColor: `${social.color}20`, color: social.color }}
|
||||
>
|
||||
@@ -226,7 +242,7 @@ const Contact = () => {
|
||||
{/* Formulaire de contact */}
|
||||
<motion.div className="contact-form-container" variants={itemVariants}>
|
||||
<h3>{t('contact.sendMessage')}</h3>
|
||||
|
||||
|
||||
{isSubmitted && (
|
||||
<motion.div
|
||||
className="success-message"
|
||||
@@ -238,7 +254,7 @@ const Contact = () => {
|
||||
{t('contact.success')}
|
||||
</motion.div>
|
||||
)}
|
||||
|
||||
|
||||
{error && (
|
||||
<motion.div
|
||||
className="error-message"
|
||||
@@ -253,7 +269,7 @@ const Contact = () => {
|
||||
|
||||
<form onSubmit={handleSubmit} className="contact-form">
|
||||
<div className="form-row">
|
||||
<motion.div
|
||||
<motion.div
|
||||
className="form-group"
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
whileInView={{ opacity: 1, y: 0 }}
|
||||
@@ -272,7 +288,7 @@ const Contact = () => {
|
||||
/>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
<motion.div
|
||||
className="form-group"
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
whileInView={{ opacity: 1, y: 0 }}
|
||||
@@ -292,7 +308,7 @@ const Contact = () => {
|
||||
</motion.div>
|
||||
</div>
|
||||
|
||||
<motion.div
|
||||
<motion.div
|
||||
className="form-group"
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
whileInView={{ opacity: 1, y: 0 }}
|
||||
@@ -311,7 +327,7 @@ const Contact = () => {
|
||||
/>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
<motion.div
|
||||
className="form-group"
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
whileInView={{ opacity: 1, y: 0 }}
|
||||
|
||||
Reference in New Issue
Block a user