Files
Critters/lib/mailer.php
T
pauljd 9805d5056d
pauljd/davidson-ci: Davidson CI / quality (push) Successful in 14s
pauljd/davidson-ci: Davidson CI / ai-review (push) Successful in 1m5s
issues identified by Davidson CI
2026-09-09 22:49:46 +01:00

109 lines
5.1 KiB
PHP

<?php
require_once __DIR__ . '/PHPMailer/src/Exception.php';
require_once __DIR__ . '/PHPMailer/src/PHPMailer.php';
require_once __DIR__ . '/PHPMailer/src/SMTP.php';
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception as PHPMailerException;
function configureAppMailer(): PHPMailer
{
$mail = new PHPMailer(true);
$mail->isSMTP();
$mail->Host = getenv('SMTP_HOST');
$mail->SMTPAuth = true;
$mail->Port = (int) getenv('SMTP_PORT');
$mail->SMTPSecure = $mail->Port === 465 ? PHPMailer::ENCRYPTION_SMTPS : PHPMailer::ENCRYPTION_STARTTLS;
$mail->Username = getenv('SMTP_USERNAME');
$mail->Password = getenv('SMTP_PASSWORD');
$mail->SMTPOptions = [
'ssl' => [
'cafile' => '/etc/ssl/certs/ca-certificates.crt',
'verify_peer' => true,
'verify_peer_name' => true,
],
];
$mail->setFrom(getenv('SMTP_FROM_EMAIL'), getenv('SMTP_FROM_NAME'));
$mail->isHTML(true);
return $mail;
}
function sendEmailVerificationEmail(string $toEmail, string $username, string $verifyLink): bool
{
try {
$mail = configureAppMailer();
$mail->addAddress($toEmail, $username);
$mail->Subject = 'Verify your email to start creating critters';
$safeUsername = htmlspecialchars($username, ENT_QUOTES, 'UTF-8');
$safeVerifyLink = htmlspecialchars($verifyLink, ENT_QUOTES, 'UTF-8');
$mail->Body = '
<div style="font-family: Arial, sans-serif; max-width: 480px; margin: 0 auto; padding: 32px 24px;">
<h1 style="color: #111827; font-size: 22px; margin-bottom: 8px;">Welcome, ' . $safeUsername . '! &#128062;</h1>
<p style="color: #4b5563; font-size: 15px; line-height: 1.6;">
Your OurApp account has been created. Verify your email to unlock your free credits and start creating unique, AI-generated critters &mdash; pick an adjective, animal, action, and location, and watch your imagination come to life.
</p>
<p style="margin-top: 24px;">
<a href="' . $safeVerifyLink . '" style="display: inline-block; background: linear-gradient(to right, #9333ea, #ec4899); color: #ffffff; text-decoration: none; font-weight: 600; padding: 12px 24px; border-radius: 9999px;">
Verify Email
</a>
</p>
<p style="color: #9ca3af; font-size: 13px; margin-top: 32px;">
If you didn&rsquo;t create this account, you can safely ignore this email.
</p>
</div>
';
$mail->AltBody = "Welcome, {$username}!\n\nYour OurApp account has been created. Verify your email to unlock your free credits and start creating unique, AI-generated critters:\n\n{$verifyLink}\n\nIf you didn't create this account, you can safely ignore this email.";
$mail->send();
return true;
} catch (PHPMailerException $e) {
error_log('Email verification email failed: ' . (isset($mail) ? $mail->ErrorInfo : $e->getMessage()));
return false;
}
}
function sendPasswordResetEmail(string $toEmail, string $username, string $resetLink): bool
{
try {
$mail = configureAppMailer();
$mail->addAddress($toEmail, $username);
$mail->Subject = 'Reset your OurApp password';
$safeUsername = htmlspecialchars($username, ENT_QUOTES, 'UTF-8');
$safeResetLink = htmlspecialchars($resetLink, ENT_QUOTES, 'UTF-8');
$mail->Body = '
<div style="font-family: Arial, sans-serif; max-width: 480px; margin: 0 auto; padding: 32px 24px;">
<h1 style="color: #111827; font-size: 22px; margin-bottom: 8px;">Reset your password</h1>
<p style="color: #4b5563; font-size: 15px; line-height: 1.6;">
Hi ' . $safeUsername . ', we received a request to reset your OurApp password. Click the button below to choose a new one. This link expires in 20 minutes.
</p>
<p style="margin-top: 24px;">
<a href="' . $safeResetLink . '" style="display: inline-block; background: linear-gradient(to right, #9333ea, #ec4899); color: #ffffff; text-decoration: none; font-weight: 600; padding: 12px 24px; border-radius: 9999px;">
Reset Password
</a>
</p>
<p style="color: #9ca3af; font-size: 13px; margin-top: 32px;">
If you didn&rsquo;t request a password reset, you can safely ignore this email &mdash; your password will not be changed.
</p>
</div>
';
$mail->AltBody = "Hi {$username},\n\nWe received a request to reset your OurApp password. Visit the link below to choose a new one. This link expires in 20 minutes.\n\n{$resetLink}\n\nIf you didn't request a password reset, you can safely ignore this email.";
$mail->send();
return true;
} catch (PHPMailerException $e) {
error_log('Password reset email failed: ' . (isset($mail) ? $mail->ErrorInfo : $e->getMessage()));
return false;
}
}