Ported Mailer class from Hanyuu.

This commit is contained in:
flash 2019-12-03 20:09:18 +01:00
parent 7cfdfc6bd8
commit 2446789b7d
7 changed files with 109 additions and 127 deletions

View file

@ -0,0 +1,7 @@
Flashii.net E-mail Change
Hey %username%,
The e-mail address associated with your account has been changed from %email_previous% to %email_new% from IP address %ip_address%.
If you didn't do this yourself please contact us immediately <https://flashii.net/info.php/contact>.

View file

@ -0,0 +1,7 @@
Flashii.net Password Change
Hey %username%,
Your password has been changed from IP address %ip_address%.
If you didn't do this yourself please contact us immediately <https://flashii.net/info.php/contact>.

View file

@ -0,0 +1,7 @@
Flashii.net Password Recovery
Hey %username%,
You, or someone pretending to be you, has requested a password reset for your account.
Your verification code is: %token%

View file

@ -44,7 +44,6 @@ require_once 'src/emotes.php';
require_once 'src/general.php';
require_once 'src/git.php';
require_once 'src/integer.php';
require_once 'src/mail.php';
require_once 'src/manage.php';
require_once 'src/news.php';
require_once 'src/otp.php';
@ -101,6 +100,15 @@ DB::init(DB::buildDSN($dbConfig), $dbConfig['username'] ?? '', $dbConfig['passwo
]);
Config::init();
Mailer::init(Config::get('mail.method', Config::TYPE_STR), [
'host' => Config::get('mail.host', Config::TYPE_STR),
'port' => Config::get('mail.port', Config::TYPE_INT, 25),
'username' => Config::get('mail.username', Config::TYPE_STR),
'password' => Config::get('mail.password', Config::TYPE_STR),
'encryption' => Config::get('mail.encryption', Config::TYPE_STR),
'sender_name' => Config::get('mail.sender.name', Config::TYPE_STR),
'sender_addr' => Config::get('mail.sender.address', Config::TYPE_STR),
]);
mail_settings([
'method' => Config::get('mail.method', Config::TYPE_STR),
'host' => Config::get('mail.host', Config::TYPE_STR),

View file

@ -102,23 +102,17 @@ while($canResetPassword) {
throw new UnexpectedValueException('A verification code failed to insert.');
}
$messageBody = <<<MSG
Hey {$forgotUser['username']},
$recoveryMessage = Mailer::template('password-recovery', [
'username' => $forgotUser['username'],
'token' => $verificationCode,
]);
You, or someone pretending to be you, has requested a password reset for your account.
Your verification code is: {$verificationCode}
If you weren't the person who requested this reset, please send a reply to this e-mail.
MSG;
$message = mail_compose(
$recoveryMail = Mailer::sendMessage(
[$forgotUser['email'] => $forgotUser['username']],
'Flashii Password Reset',
$messageBody
$recoveryMessage['subject'], $recoveryMessage['message']
);
if(!mail_send($message)) {
if(!$recoveryMail) {
$notices[] = "Failed to send reset email, please contact the administrator.";
user_recovery_token_invalidate($forgotUser['user_id'], $verificationCode);
break;

72
src/Mailer.php Normal file
View file

@ -0,0 +1,72 @@
<?php
namespace Misuzu;
use InvalidArgumentException;
use Swift_Message;
use Swift_NullTransport;
use Swift_SmtpTransport;
class Mailer {
private const TEMPLATE_PATH = MSZ_ROOT . '/config/emails/%s.txt';
private static $mailer = null;
private static $mailerClass = '';
private static $mailerConfig = [];
public static function init(string $method, array $config): void {
self::$mailerClass = $method === 'smtp' ? Swift_SmtpTransport::class : Swift_NullTransport::class;
self::$mailerConfig = $config;
}
public static function getMailer() {
if(self::$mailer === null) {
self::$mailer = new self::$mailerClass;
if(self::$mailerClass === Swift_SmtpTransport::class) {
self::$mailer->setHost(self::$mailerConfig['host'] ?? '');
self::$mailer->setPort(self::$mailerConfig['port'] ?? 25);
self::$mailer->setUsername(self::$mailerConfig['username'] ?? '');
self::$mailer->setPassword(self::$mailerConfig['password'] ?? '');
self::$mailer->setEncryption(self::$mailerConfig['encryption'] ?? '');
}
}
return self::$mailer;
}
public static function sendMessage(array $to, string $subject, string $contents, bool $bcc = false): bool {
$message = new Swift_Message($subject);
$message->setFrom([
$config['sender_addr'] ?? 'sys@flashii.net' => $config['sender_name'] ?? 'Flashii',
]);
if($bcc)
$message->setBcc($to);
else
$message->setTo($to);
$message->setBody($contents);
return self::getMailer()->send($message);
}
public static function template(string $name, array $vars = []): array {
$path = sprintf(self::TEMPLATE_PATH, $name);
if(!is_file($path))
throw new InvalidArgumentException('Invalid e-mail template name.');
$tpl = file_get_contents($path);
// Normalise newlines
$tpl = str_replace("\n", "\r\n", str_replace("\r\n", "\n", $tpl));
foreach($vars as $key => $val)
$tpl = str_replace("%{$key}%", $val, $tpl);
[$subject, $message] = explode("\r\n\r\n", $tpl, 2);
return compact('subject', 'message');
}
}

View file

@ -1,113 +0,0 @@
<?php
define('MSZ_MAIL_NULL', Swift_NullTransport::class);
define('MSZ_MAIL_SMTP', Swift_SmtpTransport::class);
define('MSZ_MAIL_SENDMAIL', Swift_SendmailTransport::class);
define('MSZ_MAIL_METHODS', [
'null' => MSZ_MAIL_NULL,
'smtp' => MSZ_MAIL_SMTP,
'sendmail' => MSZ_MAIL_SENDMAIL,
]);
define('MSZ_MAIL_DEFAULT_SENDER_NAME', 'Misuzu System');
define('MSZ_MAIL_DEFAULT_SENDER_ADDRESS', 'sys@msz.lh');
function mail_settings($param = null) {
static $settings = [];
if(!empty($param)) {
if(is_array($param)) {
$settings = array_merge_recursive($settings, $param);
} elseif(is_string($param)) {
return $settings[$param] ?? null;
}
}
return $settings;
}
function mail_init_if_prepared(): bool {
return !empty(mail_instance()) || mail_init(mail_settings());
}
function mail_instance($newObject = null) {
static $object = null;
if(!empty($newObject)) {
$object = $newObject;
}
return $object;
}
function mail_init(array $options = []): bool {
if(!empty(mail_instance())) {
return true;
}
mail_settings($options);
$method = $options['method'] ?? '';
if(array_key_exists($method, MSZ_MAIL_METHODS)) {
$method = MSZ_MAIL_METHODS[$method];
}
if(!in_array($method, MSZ_MAIL_METHODS)) {
return false;
}
$transport = new $method;
switch($method) {
case MSZ_MAIL_SENDMAIL:
if(!empty($options['command'])) {
$transport->setCommand($options['command']);
}
break;
case MSZ_MAIL_SMTP:
$transport->setHost($options['host'] ?? '');
$transport->setPort(intval($options['port'] ?? 25));
if(!empty($options['encryption'])) {
$transport->setEncryption($options['encryption']);
}
if(!empty($options['username'])) {
$transport->setUsername($options['username']);
}
if(!empty($options['password'])) {
$transport->setPassword($options['password']);
}
break;
}
mail_instance($transport);
return true;
}
function mail_default_sender(): array {
return [
mail_settings('sender_email') ?? MSZ_MAIL_DEFAULT_SENDER_ADDRESS =>
mail_settings('sender_name') ?? MSZ_MAIL_DEFAULT_SENDER_NAME
];
}
function mail_send(Swift_Message $mail): int {
if(!mail_init_if_prepared()) {
return 0;
}
return mail_instance()->send($mail);
}
function mail_compose(
array $addressees,
string $subject,
string $body
): Swift_Message {
return (new Swift_Message($subject))
->setFrom(mail_default_sender())
->setTo($addressees)
->setBody($body);
}