diff --git a/content/plan.md b/content/plan.md index 12842e4..77076ab 100755 --- a/content/plan.md +++ b/content/plan.md @@ -27,7 +27,7 @@ disableComments = true - **Обсуждение деталей:** [Telegram чат "Полёты БВС"](https://t.me/polet_bvs) ### Важная информация -- **Время выезда:** обычно рано утром, 5-6 утра из Москвы, иногда раньше в зависимости от удалённости локации +- **Время выезда:** обычно рано утром, в зависимости от удалённости локации - **Email:** проверьте папку "Нежелательные" - ответ может попасть туда {{< rawhtml >}} diff --git a/forms/forms_helper.php b/forms/forms_helper.php index 54e86e3..623d6f3 100755 --- a/forms/forms_helper.php +++ b/forms/forms_helper.php @@ -52,11 +52,72 @@ function get_forms_settings() { 'save_json' => getenv('FORMS_SAVE_JSON') === 'true', 'notifications' => getenv('FORMS_NOTIFICATIONS') === 'true', 'telegram_bot_token' => getenv('TELEGRAM_BOT_TOKEN'), - 'telegram_chat_id' => getenv('TELEGRAM_ADMIN_CHAT_ID'), + 'telegram_chat_ids' => array_filter(array_map('trim', explode(',', getenv('TELEGRAM_ADMIN_CHAT_ID') ?: ''))), 'encryption_key' => getenv('FORMS_ENCRYPTION_KEY') ?: 'default_key_change_me' ]; } +/** + * Проверка email на заблокированные домены + * + * @param string $email Email адрес для проверки + * @return bool true если домен заблокирован, false если разрешён + */ +function is_blocked_email_domain($email) { + $blocked_domains = [ + '.ua', // Украина + '.fr', // Франция (спам) + '.cn', // Китай + '.com.cn', + '.net.cn', + '.org.cn', + '.gov.cn', + '.edu.cn', + '.ac.cn' + ]; + + $email_parts = explode('@', strtolower($email)); + if (count($email_parts) !== 2) { + return false; + } + + $domain = $email_parts[1]; + + foreach ($blocked_domains as $blocked) { + if ($domain === ltrim($blocked, '.') || + substr($domain, -strlen($blocked)) === $blocked) { + error_log("Заблокирован email с доменом: $domain (правило: $blocked) от IP: " . ($_SERVER['REMOTE_ADDR'] ?? 'unknown')); + return true; + } + } + + return false; +} + +/** + * Расширенная валидация email + * + * @param string $email Email для валидации + * @return array ['valid' => bool, 'error' => string] + */ +function validate_email_extended($email) { + if (!filter_var($email, FILTER_VALIDATE_EMAIL)) { + return [ + 'valid' => false, + 'error' => 'Некорректный формат email адреса.' + ]; + } + + if (is_blocked_email_domain($email)) { + return [ + 'valid' => false, + 'error' => 'К сожалению, регистрация с этого домена временно недоступна.' + ]; + } + + return ['valid' => true, 'error' => '']; +} + /** * Простое шифрование данных для безопасного хранения * Совместимо с Python Crypto.Cipher.AES + unpad @@ -153,22 +214,22 @@ function save_application_to_json($form_data, $form_type) { */ function send_telegram_notification($form_data, $form_type) { $settings = get_forms_settings(); - + if (!$settings['send_telegram'] || !$settings['notifications']) { return true; // Отправка отключена } - - if (empty($settings['telegram_bot_token']) || empty($settings['telegram_chat_id'])) { + + if (empty($settings['telegram_bot_token']) || empty($settings['telegram_chat_ids'])) { error_log("Telegram настройки не настроены"); return false; } - + // Подготавливаем сообщение $message = "🔔 *Новая заявка*\n\n"; $message .= "📝 *Тип:* " . ($form_type === 'plan' ? 'Заявка на поездку' : 'Вопрос') . "\n"; $message .= "👤 *Имя:* " . $form_data['name'] . "\n"; $message .= "📧 *Email:* " . $form_data['email'] . "\n"; - + if ($form_type === 'plan') { $message .= "📱 *Телефон:* " . ($form_data['phone'] ?: 'не указан') . "\n"; $message .= "✈️ *Поездка:* " . ($form_data['trip_period'] ?: 'не выбрана') . "\n"; @@ -183,39 +244,51 @@ function send_telegram_notification($form_data, $form_type) { $message .= "💬 *Тема:* " . $form_data['subject'] . "\n"; $message .= "📝 *Сообщение:* " . substr($form_data['message'], 0, 200) . "...\n"; } - + $message .= "\n⏰ *Время:* " . date('Y-m-d H:i:s'); - - // Отправляем сообщение + + // Отправляем сообщение всем администраторам $url = "https://api.telegram.org/bot" . $settings['telegram_bot_token'] . "/sendMessage"; - $data = [ - 'chat_id' => $settings['telegram_chat_id'], - 'text' => $message, - 'parse_mode' => 'Markdown' - ]; - - $context = stream_context_create([ - 'http' => [ - 'method' => 'POST', - 'header' => 'Content-Type: application/x-www-form-urlencoded', - 'content' => http_build_query($data) - ] - ]); - - try { - $result = file_get_contents($url, false, $context); - $response = json_decode($result, true); - - if ($response && $response['ok']) { - return true; - } else { - error_log("Ошибка отправки в Telegram: " . $result); - return false; + $all_sent = true; + $sent_count = 0; + + foreach ($settings['telegram_chat_ids'] as $chat_id) { + $data = [ + 'chat_id' => $chat_id, + 'text' => $message, + 'parse_mode' => 'Markdown' + ]; + + $context = stream_context_create([ + 'http' => [ + 'method' => 'POST', + 'header' => 'Content-Type: application/x-www-form-urlencoded', + 'content' => http_build_query($data) + ] + ]); + + try { + $result = file_get_contents($url, false, $context); + $response = json_decode($result, true); + + if ($response && $response['ok']) { + $sent_count++; + } else { + error_log("Ошибка отправки в Telegram (chat_id: $chat_id): " . $result); + $all_sent = false; + } + } catch (Exception $e) { + error_log("Исключение при отправке в Telegram (chat_id: $chat_id): " . $e->getMessage()); + $all_sent = false; } - } catch (Exception $e) { - error_log("Исключение при отправке в Telegram: " . $e->getMessage()); - return false; } + + if ($sent_count > 0) { + error_log("Уведомление отправлено $sent_count админам из " . count($settings['telegram_chat_ids'])); + return true; + } + + return false; } /** diff --git a/forms/send_ask.php b/forms/send_ask.php index 9bd663e..f337127 100755 --- a/forms/send_ask.php +++ b/forms/send_ask.php @@ -18,9 +18,14 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') { $error = "Имя, тема и сообщение обязательны для заполнения."; } elseif (empty($email) && empty($telegram)) { $error = "Укажите email или Telegram ник (одно из двух обязательно)."; - } elseif (!empty($email) && !filter_var($email, FILTER_VALIDATE_EMAIL)) { - $error = "Некорректный email адрес."; - } else { + } elseif (!empty($email)) { + $email_validation = validate_email_extended($email); + if (!$email_validation['valid']) { + $error = $email_validation['error']; + } + } + + if (empty($error)) { // Подготавливаем данные заявки $form_data = [ 'name' => $name, @@ -36,28 +41,8 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') { // 1. Отправка email (если включено) if ($settings['send_email']) { - $to = getenv('FORMS_MAIN_EMAIL') ?: "sleeptrip@mail.ru"; - $email_subject = "Вопрос с сайта: " . $subject; - $email_body = "Новый вопрос с сайта:\n\n"; - $email_body .= "Имя: " . $name . "\n"; - $email_body .= "Email: " . ($email ?: 'не указан') . "\n"; - $email_body .= "Telegram: " . ($telegram ?: 'не указан') . "\n"; - $email_body .= "Телефон: " . ($phone ?: 'не указан') . "\n"; - $email_body .= "Тема: " . $subject . "\n\n"; - $email_body .= "Сообщение:\n" . $message . "\n\n"; - $email_body .= "---\n"; - $email_body .= "Отправлено с: " . $_SERVER['HTTP_HOST'] . "\n"; - $email_body .= "Дата: " . date('Y-m-d H:i:s') . "\n"; - - $from_email = getenv('FORMS_FROM_EMAIL') ?: 'noreply@sleeptrip.ru'; - $headers = "From: " . $from_email . "\r\n"; - if (!empty($email)) { - $headers .= "Reply-To: " . $email . "\r\n"; - } - $headers .= "X-Mailer: PHP/" . phpversion(); - $headers .= "Content-Type: text/plain; charset=UTF-8\r\n"; - - if (mail($to, $email_subject, $email_body, $headers)) { + $email_sent = send_email_notification($form_data, 'ask'); + if ($email_sent) { $success_messages[] = "Email отправлен"; } else { $error_messages[] = "Ошибка отправки email"; diff --git a/forms/send_plan.php b/forms/send_plan.php index 38b3837..bfff2cb 100755 --- a/forms/send_plan.php +++ b/forms/send_plan.php @@ -22,11 +22,20 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') { $error = "Обязательное поле: Телефон."; } elseif (empty($email) && empty($telegram)) { $error = "Укажите email или Telegram ник (одно из двух обязательно)."; - } elseif (!empty($email) && !filter_var($email, FILTER_VALIDATE_EMAIL)) { - $error = "Некорректный email адрес."; - } elseif ($consent !== 'agree') { + } elseif (!empty($email)) { + $email_validation = validate_email_extended($email); + if (!$email_validation['valid']) { + $error = $email_validation['error']; + } + } + + // Проверка согласия + if (empty($error) && $consent !== 'agree') { $error = "Для отправки заявки необходимо согласие на обработку персональных данных."; - } elseif (!empty($bvs_file) && $bvs_file['error'] !== UPLOAD_ERR_NO_FILE) { + } + + // Проверка загруженного файла + if (empty($error) && !empty($bvs_file) && $bvs_file['error'] !== UPLOAD_ERR_NO_FILE) { // Проверка загруженного файла if ($bvs_file['error'] !== UPLOAD_ERR_OK) { $error = "Ошибка при загрузке файла. Попробуйте еще раз.";