Files
epictravelexpeditions/api/includes/mailer.php
T
myron 0dfcfa2f7e Fix security gaps and dead code found in codebase review
- mailer.php: re-enable TLS certificate verification for CyberMail API
  calls (was CURLOPT_SSL_VERIFYPEER => false, exposing outbound mail
  traffic to MITM).
- .htaccess / api/.htaccess: block direct HTTP access to .git/, db/,
  and api/config.php via mod_rewrite [F] rules. Confirmed live that
  /.git/config, /.git/logs/HEAD, and /db/schema.sql were all directly
  downloadable (200 OK with real content) - .git exposure leaks the
  repo's embedded GitHub token and full history; schema.sql leaks the
  DB layout. Also drops the dead "/setup -> setup_password.php" rewrite,
  since that file was already deleted from production.
- index.php: remove the 'download' route, which required a
  api/download.php that has never existed in this repo - confirmed
  live that GET /api/download returns a fatal 500.
- functions.php / upload.php / testimonials.php: extract the
  duplicated image-upload validation/move logic (MIME check, size
  check, UUID rename, move_uploaded_file) into one handleImageUpload()
  helper used by both upload endpoints.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-04 14:21:19 -05:00

98 lines
5.1 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
/**
* Epic Travel Expeditions — CyberMail Mailer
*/
function sendgridSend(string $toEmail, string $toName, string $subject, string $htmlBody, string $textBody = ''): bool {
$apiKey = defined('CYBERMAIL_API_KEY') ? CYBERMAIL_API_KEY : '';
if (!$apiKey || strpos($apiKey, 'YOUR_KEY') !== false) {
error_log('[EpicTravel mailer] CYBERMAIL_API_KEY not configured');
return false;
}
$payload = [
'from' => defined('MAIL_FROM') ? MAIL_FROM : 'noreply@epictravelexpeditions.com',
'to' => $toEmail,
'subject' => $subject,
'html' => $htmlBody,
];
if ($textBody) $payload['text'] = $textBody;
$ch = curl_init('https://platform.cyberpersons.com/email/v1/send');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => json_encode($payload),
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . $apiKey,
'Content-Type: application/json',
],
CURLOPT_TIMEOUT => 20,
CURLOPT_SSL_VERIFYPEER => true,
CURLOPT_SSL_VERIFYHOST => 2,
]);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($httpCode === 202) return true;
error_log('[EpicTravel mailer] CyberMail HTTP ' . $httpCode . ' — ' . $response);
return false;
}
function sendContactAlert(string $name, string $email, string $message): bool {
$adminEmail = defined('ADMIN_EMAIL') ? ADMIN_EMAIL : 'admin@epictravelexpeditions.com';
$subject = "New Contact Form Submission from {$name}";
$html = '
<div style="max-width:600px;margin:0 auto;font-family:Arial,sans-serif;">
<div style="background:#1a3a6b;padding:24px;text-align:center;">
<h1 style="color:#fff;margin:0;font-size:22px;">Epic Travel Expeditions</h1>
<p style="color:rgba(255,255,255,.7);margin:4px 0 0;font-size:14px;">New Contact Form Message</p>
</div>
<div style="padding:28px;background:#fff;border:1px solid #e5e7eb;">
<table style="width:100%;border-collapse:collapse;">
<tr><td style="padding:8px 0;color:#6b7280;font-size:13px;width:80px;">Name</td>
<td style="padding:8px 0;font-weight:600;">' . htmlspecialchars($name) . '</td></tr>
<tr><td style="padding:8px 0;color:#6b7280;font-size:13px;">Email</td>
<td style="padding:8px 0;"><a href="mailto:' . htmlspecialchars($email) . '" style="color:#1a3a6b;">' . htmlspecialchars($email) . '</a></td></tr>
</table>
<div style="margin-top:20px;padding:16px;background:#f9fafb;border-radius:8px;border-left:4px solid #1a3a6b;">
<p style="margin:0;font-size:14px;color:#374151;line-height:1.6;">' . nl2br(htmlspecialchars($message)) . '</p>
</div>
<p style="margin-top:20px;font-size:13px;color:#9ca3af;">Submitted ' . date('F j, Y \a\t g:i A T') . '</p>
</div>
<div style="background:#f3f4f6;padding:16px;text-align:center;">
<p style="margin:0;font-size:12px;color:#9ca3af;">&copy; ' . date('Y') . ' Epic Travel Expeditions</p>
</div>
</div>';
return sendgridSend($adminEmail, 'Epic Travel Admin', $subject, $html,
"New contact from {$name} ({$email}):\n\n{$message}");
}
function sendContactConfirmation(string $toEmail, string $toName): bool {
$subject = "We received your message — Epic Travel Expeditions";
$html = '
<div style="max-width:600px;margin:0 auto;font-family:Arial,sans-serif;">
<div style="background:#1a3a6b;padding:24px;text-align:center;">
<h1 style="color:#fff;margin:0;font-size:22px;">Epic Travel Expeditions</h1>
</div>
<div style="padding:32px;background:#fff;">
<h2 style="margin-top:0;color:#1a3a6b;">Thanks for reaching out, ' . htmlspecialchars($toName) . '!</h2>
<p style="color:#374151;line-height:1.6;">We received your message and our team will get back to you within 12 business days.</p>
<p style="color:#374151;line-height:1.6;">In the meantime, feel free to browse our destinations and current travel specials:</p>
<div style="text-align:center;margin:28px 0;">
<a href="https://epictravelexpeditions.com" style="display:inline-block;background:#1a3a6b;color:#fff;padding:14px 28px;border-radius:8px;text-decoration:none;font-weight:bold;">Explore Destinations</a>
</div>
<p style="color:#374151;line-height:1.6;">Adventure awaits,<br><strong>The Epic Travel Team</strong></p>
</div>
<div style="background:#f3f4f6;padding:16px;text-align:center;">
<p style="margin:0;font-size:12px;color:#9ca3af;">&copy; ' . date('Y') . ' Epic Travel Expeditions</p>
</div>
</div>';
return sendgridSend($toEmail, $toName, $subject, $html,
"Hi {$toName},\n\nThanks for contacting Epic Travel Expeditions! We'll get back to you within 1-2 business days.\n\nAdventure awaits,\nThe Epic Travel Team");
}