Files
casadoc/public/userportal/api/_mail.php
T
2026-08-07 14:05:49 +03:00

77 lines
2.7 KiB
PHP

<?php
// SMTP delivery via PHPMailer (already a project dependency).
require_once __DIR__ . '/../../../vendor/autoload.php';
use Dotenv\Dotenv;
use PHPMailer\PHPMailer\PHPMailer;
Dotenv::createImmutable([dirname(__DIR__, 2), dirname(__DIR__, 3)])->safeLoad();
/** Treats an empty value and the literal "null" from .env as "not set". */
function mail_env(string $key, string $default = ''): string
{
$value = (string) ($_ENV[$key] ?? getenv($key) ?: '');
return ($value === '' || $value === 'null') ? $default : $value;
}
/** Never surfaces the SMTP error to the caller: it can leak host and credentials. */
function send_mail(string $to, string $subject, string $html): bool
{
$mail = new PHPMailer(true);
try {
$mail->isSMTP();
$mail->Host = mail_env('MAIL_HOST', 'localhost');
$mail->Port = (int) mail_env('MAIL_PORT', '587');
$mail->SMTPAuth = true;
$mail->Username = mail_env('MAIL_USERNAME');
$mail->Password = mail_env('MAIL_PASSWORD');
$mail->SMTPSecure = mail_env('MAIL_ENCRYPTION', PHPMailer::ENCRYPTION_STARTTLS);
$mail->CharSet = 'UTF-8';
// Default is 300s: an unreachable SMTP would otherwise stall registration.
$mail->Timeout = 10;
$mail->setFrom(
mail_env('MAIL_FROM_ADDRESS', 'noreply@casadoc.app'),
mail_env('MAIL_FROM_NAME', 'CasaDoc')
);
$mail->addAddress($to);
$mail->isHTML(true);
$mail->Subject = $subject;
$mail->Body = $html;
$mail->send();
return true;
} catch (Throwable $e) {
// Without the connection details a failure is indistinguishable from a
// wrong recipient address. The password is never logged.
error_log(sprintf(
'mail failed to %s via %s@%s:%s (%s): %s',
$to,
mail_env('MAIL_USERNAME'),
mail_env('MAIL_HOST', 'localhost'),
mail_env('MAIL_PORT', '587'),
mail_env('MAIL_ENCRYPTION', 'none'),
$mail->ErrorInfo ?: $e->getMessage()
));
return false;
}
}
function send_code_mail(string $to, string $code, bool $isReset = false): bool
{
$subject = $isReset ? 'CasaDoc password reset code' : 'CasaDoc verification code';
$intro = $isReset
? 'Use this code to reset your CasaDoc password:'
: 'Use this code to confirm your e-mail address:';
$html = '<p>' . $intro . '</p>'
. '<p style="font-size:28px;font-weight:bold;letter-spacing:4px">' . htmlspecialchars($code) . '</p>'
. '<p>The code expires in 15 minutes. If you did not request it, ignore this e-mail.</p>';
return send_mail($to, $subject, $html);
}