diff --git a/src/app/EventLog.php b/src/app/EventLog.php
--- a/src/app/EventLog.php
+++ b/src/app/EventLog.php
@@ -25,6 +25,7 @@
     public const TYPE_SUSPENDED = 1;
     public const TYPE_UNSUSPENDED = 2;
     public const TYPE_COMMENT = 3;
+    public const TYPE_MAILSENT = 4;
 
     /** @var array<int, string> The attributes that are mass assignable */
     protected $fillable = [
@@ -104,6 +105,8 @@
             return \trans('app.event-unsuspended');
         case self::TYPE_COMMENT:
             return \trans('app.event-comment');
+        case self::TYPE_MAILSENT:
+            return \trans('app.event-mailsent');
         default:
             return null;
         }
diff --git a/src/app/Mail/DegradedAccountReminder.php b/src/app/Mail/DegradedAccountReminder.php
--- a/src/app/Mail/DegradedAccountReminder.php
+++ b/src/app/Mail/DegradedAccountReminder.php
@@ -6,27 +6,18 @@
 use App\User;
 use App\Utils;
 use App\Wallet;
-use Illuminate\Bus\Queueable;
-use Illuminate\Mail\Mailable;
-use Illuminate\Queue\SerializesModels;
 
 class DegradedAccountReminder extends Mailable
 {
-    use Queueable;
-    use SerializesModels;
-
     /** @var \App\Wallet A wallet with a negative balance */
     protected $wallet;
 
-    /** @var \App\User A wallet controller to whom the email is being sent */
-    protected $user;
-
 
     /**
      * Create a new message instance.
      *
      * @param \App\Wallet $wallet A wallet
-     * @param \App\User   $user   An email recipient
+     * @param \App\User   $user   A wallet controller to whom the email is being sent
      *
      * @return void
      */
diff --git a/src/app/Mail/Helper.php b/src/app/Mail/Helper.php
--- a/src/app/Mail/Helper.php
+++ b/src/app/Mail/Helper.php
@@ -2,8 +2,8 @@
 
 namespace App\Mail;
 
+use App\EventLog;
 use App\Tenant;
-use Illuminate\Mail\Mailable;
 use Illuminate\Support\Facades\Mail;
 
 class Helper
@@ -11,8 +11,8 @@
     /**
      * Render the mail template.
      *
-     * @param \Illuminate\Mail\Mailable $mail The mailable object
-     * @param string $type Output format ('html' or 'text')
+     * @param Mailable $mail The mailable object
+     * @param string   $type Output format ('html' or 'text')
      *
      * @return string HTML or Plain Text output
      */
@@ -25,7 +25,9 @@
             $mailer = \Illuminate\Container\Container::getInstance()->make('mailer');
 
             return $mailer->render(['text' => $mail->textView], $mail->buildViewData());
-        } elseif ($type != 'html') {
+        }
+
+        if ($type != 'html') {
             throw new \Exception("Unsupported output format");
         }
 
@@ -44,25 +46,19 @@
      */
     public static function sendMail(Mailable $mail, $tenantId = null, array $params = []): void
     {
-        $class = explode("\\", get_class($mail));
-        $class = end($class);
-
-        $getRecipients = function () use ($params) {
-            $recipients = [];
-
-            // For now we do not support addresses + names, only addresses
-            foreach (['to', 'cc'] as $idx) {
-                if (!empty($params[$idx])) {
-                    if (is_array($params[$idx])) {
-                        $recipients = array_merge($recipients, $params[$idx]);
-                    } else {
-                        $recipients[] = $params[$idx];
-                    }
+        $class = class_basename(get_class($mail));
+        $recipients = [];
+
+        // For now we do not support addresses + names, only addresses
+        foreach (['to', 'cc'] as $idx) {
+            if (!empty($params[$idx])) {
+                if (is_array($params[$idx])) {
+                    $recipients = array_merge($recipients, $params[$idx]);
+                } else {
+                    $recipients[] = $params[$idx];
                 }
             }
-
-            return implode(', ', $recipients);
-        };
+        }
 
         try {
             if (!empty($params['to'])) {
@@ -88,12 +84,13 @@
 
             Mail::send($mail);
 
-            $msg = sprintf("[%s] Sent mail to %s%s", $class, $getRecipients(), $params['add'] ?? '');
-
-            \Log::info($msg);
+            if ($user = $mail->getUser()) {
+                $comment = "[{$class}] " . $mail->getSubject();
+                EventLog::createFor($user, EventLog::TYPE_MAILSENT, $comment, ['recipients' => $recipients]);
+            }
         } catch (\Exception $e) {
             $format = "[%s] Failed to send mail to %s%s: %s";
-            $msg = sprintf($format, $class, $getRecipients(), $params['add'] ?? '', $e->getMessage());
+            $msg = sprintf($format, $class, implode(', ', $recipients), $params['add'] ?? '', $e->getMessage());
 
             \Log::error($msg);
             throw $e;
diff --git a/src/app/Mail/Mailable.php b/src/app/Mail/Mailable.php
new file mode 100644
--- /dev/null
+++ b/src/app/Mail/Mailable.php
@@ -0,0 +1,55 @@
+<?php
+
+namespace App\Mail;
+
+use App\Tenant;
+use Illuminate\Bus\Queueable;
+use Illuminate\Mail\Mailable as IMailable;
+use Illuminate\Queue\SerializesModels;
+
+class Mailable extends IMailable
+{
+    use Queueable;
+    use SerializesModels;
+
+    /** @var ?\App\User User context */
+    protected $user;
+
+
+    /**
+     * Returns the user object of an email main recipient.
+     *
+     * @return ?\App\User User object if set
+     */
+    public function getUser(): ?\App\User
+    {
+        return $this->user;
+    }
+
+    /**
+     * Returns the mail subject.
+     *
+     * @return string Mail subject
+     */
+    public function getSubject(): string
+    {
+        if ($this->subject) {
+            return $this->subject;
+        }
+
+        // Subject property is not available before build() method was called
+        // i.e. before Mail::send().
+        // It's also not available when using Mail::fake().
+        // This is essentially why we have getSubject() method.
+
+        $class = class_basename(static::class);
+
+        if ($this->user) {
+            $appName = Tenant::getConfig($this->user->tenant_id, 'app.name');
+        } else {
+            $appName = \config('app.name');
+        }
+
+        return \trans('mail.' . strtolower($class) . '-subject', ['site' => $appName]);
+    }
+}
diff --git a/src/app/Mail/NegativeBalance.php b/src/app/Mail/NegativeBalance.php
--- a/src/app/Mail/NegativeBalance.php
+++ b/src/app/Mail/NegativeBalance.php
@@ -6,27 +6,18 @@
 use App\User;
 use App\Utils;
 use App\Wallet;
-use Illuminate\Bus\Queueable;
-use Illuminate\Mail\Mailable;
-use Illuminate\Queue\SerializesModels;
 
 class NegativeBalance extends Mailable
 {
-    use Queueable;
-    use SerializesModels;
-
     /** @var \App\Wallet A wallet with a negative balance */
     protected $wallet;
 
-    /** @var \App\User A wallet controller to whom the email is being sent */
-    protected $user;
-
 
     /**
      * Create a new message instance.
      *
      * @param \App\Wallet $wallet A wallet
-     * @param \App\User   $user   An email recipient
+     * @param \App\User   $user   A wallet controller to whom the email is being sent
      *
      * @return void
      */
diff --git a/src/app/Mail/NegativeBalanceDegraded.php b/src/app/Mail/NegativeBalanceDegraded.php
--- a/src/app/Mail/NegativeBalanceDegraded.php
+++ b/src/app/Mail/NegativeBalanceDegraded.php
@@ -7,27 +7,18 @@
 use App\User;
 use App\Utils;
 use App\Wallet;
-use Illuminate\Bus\Queueable;
-use Illuminate\Mail\Mailable;
-use Illuminate\Queue\SerializesModels;
 
 class NegativeBalanceDegraded extends Mailable
 {
-    use Queueable;
-    use SerializesModels;
-
     /** @var \App\Wallet A wallet with a negative balance */
     protected $wallet;
 
-    /** @var \App\User A wallet controller to whom the email is being sent */
-    protected $user;
-
 
     /**
      * Create a new message instance.
      *
      * @param \App\Wallet $wallet A wallet
-     * @param \App\User   $user   An email recipient
+     * @param \App\User   $user   A wallet controller to whom the email is being sent
      *
      * @return void
      */
diff --git a/src/app/Mail/NegativeBalanceReminderDegrade.php b/src/app/Mail/NegativeBalanceReminderDegrade.php
--- a/src/app/Mail/NegativeBalanceReminderDegrade.php
+++ b/src/app/Mail/NegativeBalanceReminderDegrade.php
@@ -7,27 +7,18 @@
 use App\User;
 use App\Utils;
 use App\Wallet;
-use Illuminate\Bus\Queueable;
-use Illuminate\Mail\Mailable;
-use Illuminate\Queue\SerializesModels;
 
 class NegativeBalanceReminderDegrade extends Mailable
 {
-    use Queueable;
-    use SerializesModels;
-
     /** @var \App\Wallet A wallet with a negative balance */
     protected $wallet;
 
-    /** @var \App\User A wallet controller to whom the email is being sent */
-    protected $user;
-
 
     /**
      * Create a new message instance.
      *
      * @param \App\Wallet $wallet A wallet
-     * @param \App\User   $user   An email recipient
+     * @param \App\User   $user   A wallet controller to whom the email is being sent
      *
      * @return void
      */
@@ -48,7 +39,7 @@
         $supportUrl = Tenant::getConfig($this->user->tenant_id, 'app.support_url');
         $threshold = WalletCheck::threshold($this->wallet, WalletCheck::THRESHOLD_DEGRADE);
 
-        $subject = \trans('mail.negativebalancereminder-subject', ['site' => $appName]);
+        $subject = \trans('mail.negativebalancereminderdegrade-subject', ['site' => $appName]);
 
         $this->view('emails.html.negative_balance_reminder_degrade')
             ->text('emails.plain.negative_balance_reminder_degrade')
diff --git a/src/app/Mail/PasswordExpirationReminder.php b/src/app/Mail/PasswordExpirationReminder.php
--- a/src/app/Mail/PasswordExpirationReminder.php
+++ b/src/app/Mail/PasswordExpirationReminder.php
@@ -5,19 +5,9 @@
 use App\Tenant;
 use App\User;
 use App\Utils;
-use Illuminate\Bus\Queueable;
-use Illuminate\Mail\Mailable;
-use Illuminate\Queue\SerializesModels;
-use Illuminate\Support\Str;
 
 class PasswordExpirationReminder extends Mailable
 {
-    use Queueable;
-    use SerializesModels;
-
-    /** @var \App\User The user object */
-    protected $user;
-
     /** @var string Password expiration date */
     protected $expiresOn;
 
@@ -78,4 +68,25 @@
 
         return Helper::render($mail, $type);
     }
+
+    /**
+     * Returns the mail subject.
+     *
+     * @return string Mail subject
+     */
+    public function getSubject(): string
+    {
+        if ($this->subject) {
+            return $this->subject;
+        }
+
+        $appName = Tenant::getConfig($this->user->tenant_id, 'app.name');
+
+        $params = [
+            'site' => $appName,
+            'date' => $this->expiresOn,
+        ];
+
+        return \trans('mail.passwordexpiration-subject', $params);
+    }
 }
diff --git a/src/app/Mail/PasswordReset.php b/src/app/Mail/PasswordReset.php
--- a/src/app/Mail/PasswordReset.php
+++ b/src/app/Mail/PasswordReset.php
@@ -6,16 +6,10 @@
 use App\User;
 use App\Utils;
 use App\VerificationCode;
-use Illuminate\Bus\Queueable;
-use Illuminate\Mail\Mailable;
-use Illuminate\Queue\SerializesModels;
 use Illuminate\Support\Str;
 
 class PasswordReset extends Mailable
 {
-    use Queueable;
-    use SerializesModels;
-
     /** @var \App\VerificationCode A verification code object */
     protected $code;
 
@@ -30,6 +24,7 @@
     public function __construct(VerificationCode $code)
     {
         $this->code = $code;
+        $this->user = $this->code->user;
     }
 
     /**
@@ -39,11 +34,11 @@
      */
     public function build()
     {
-        $appName = Tenant::getConfig($this->code->user->tenant_id, 'app.name');
+        $appName = Tenant::getConfig($this->user->tenant_id, 'app.name');
 
         $href = Utils::serviceUrl(
             sprintf('/password-reset/%s-%s', $this->code->short_code, $this->code->code),
-            $this->code->user->tenant_id
+            $this->user->tenant_id
         );
 
         $this->view('emails.html.password_reset')
@@ -54,7 +49,7 @@
                     'code' => $this->code->code,
                     'short_code' => $this->code->short_code,
                     'link' => sprintf('<a href="%s">%s</a>', $href, $href),
-                    'username' => $this->code->user->name(true)
+                    'username' => $this->user->name(true)
             ]);
 
         return $this;
diff --git a/src/app/Mail/PaymentFailure.php b/src/app/Mail/PaymentFailure.php
--- a/src/app/Mail/PaymentFailure.php
+++ b/src/app/Mail/PaymentFailure.php
@@ -6,27 +6,18 @@
 use App\Tenant;
 use App\User;
 use App\Utils;
-use Illuminate\Bus\Queueable;
-use Illuminate\Mail\Mailable;
-use Illuminate\Queue\SerializesModels;
 
 class PaymentFailure extends Mailable
 {
-    use Queueable;
-    use SerializesModels;
-
     /** @var \App\Payment A payment operation */
     protected $payment;
 
-    /** @var \App\User A wallet controller to whom the email is being send */
-    protected $user;
-
 
     /**
      * Create a new message instance.
      *
      * @param \App\Payment $payment A payment operation
-     * @param \App\User    $user    An email recipient
+     * @param \App\User    $user    A wallet controller to whom the email is being sent
      *
      * @return void
      */
diff --git a/src/app/Mail/PaymentMandateDisabled.php b/src/app/Mail/PaymentMandateDisabled.php
--- a/src/app/Mail/PaymentMandateDisabled.php
+++ b/src/app/Mail/PaymentMandateDisabled.php
@@ -6,27 +6,18 @@
 use App\User;
 use App\Utils;
 use App\Wallet;
-use Illuminate\Bus\Queueable;
-use Illuminate\Mail\Mailable;
-use Illuminate\Queue\SerializesModels;
 
 class PaymentMandateDisabled extends Mailable
 {
-    use Queueable;
-    use SerializesModels;
-
     /** @var \App\Wallet A wallet for which the mandate has been disabled */
     protected $wallet;
 
-    /** @var \App\User A wallet controller to whom the email is being send */
-    protected $user;
-
 
     /**
      * Create a new message instance.
      *
      * @param \App\Wallet $wallet A wallet that has been charged
-     * @param \App\User   $user   An email recipient
+     * @param \App\User   $user   A wallet controller to whom the email is being sent
      *
      * @return void
      */
diff --git a/src/app/Mail/PaymentSuccess.php b/src/app/Mail/PaymentSuccess.php
--- a/src/app/Mail/PaymentSuccess.php
+++ b/src/app/Mail/PaymentSuccess.php
@@ -6,27 +6,18 @@
 use App\Tenant;
 use App\User;
 use App\Utils;
-use Illuminate\Bus\Queueable;
-use Illuminate\Mail\Mailable;
-use Illuminate\Queue\SerializesModels;
 
 class PaymentSuccess extends Mailable
 {
-    use Queueable;
-    use SerializesModels;
-
     /** @var \App\Payment A payment operation */
     protected $payment;
 
-    /** @var \App\User A wallet controller to whom the email is being send */
-    protected $user;
-
 
     /**
      * Create a new message instance.
      *
      * @param \App\Payment $payment A payment operation
-     * @param \App\User    $user    An email recipient
+     * @param \App\User    $user    A wallet controller to whom the email is being sent
      *
      * @return void
      */
diff --git a/src/app/Mail/SignupInvitation.php b/src/app/Mail/SignupInvitation.php
--- a/src/app/Mail/SignupInvitation.php
+++ b/src/app/Mail/SignupInvitation.php
@@ -5,16 +5,10 @@
 use App\SignupInvitation as SI;
 use App\Tenant;
 use App\Utils;
-use Illuminate\Bus\Queueable;
-use Illuminate\Mail\Mailable;
-use Illuminate\Queue\SerializesModels;
 use Illuminate\Support\Str;
 
 class SignupInvitation extends Mailable
 {
-    use Queueable;
-    use SerializesModels;
-
     /** @var \App\SignupInvitation A signup invitation object */
     protected $invitation;
 
diff --git a/src/app/Mail/SignupVerification.php b/src/app/Mail/SignupVerification.php
--- a/src/app/Mail/SignupVerification.php
+++ b/src/app/Mail/SignupVerification.php
@@ -4,16 +4,10 @@
 
 use App\SignupCode;
 use App\Utils;
-use Illuminate\Bus\Queueable;
-use Illuminate\Mail\Mailable;
-use Illuminate\Queue\SerializesModels;
 use Illuminate\Support\Str;
 
 class SignupVerification extends Mailable
 {
-    use Queueable;
-    use SerializesModels;
-
     /** @var SignupCode A signup verification code object */
     protected $code;
 
@@ -47,9 +41,9 @@
         }
         $username = trim($username);
 
-        $this->view('emails.html.signup_code')
-            ->text('emails.plain.signup_code')
-            ->subject(\trans('mail.signupcode-subject', ['site' => \config('app.name')]))
+        $this->view('emails.html.signup_verification')
+            ->text('emails.plain.signup_verification')
+            ->subject(\trans('mail.signupverification-subject', ['site' => \config('app.name')]))
             ->with([
                     'site' => \config('app.name'),
                     'username' => $username ?: 'User',
diff --git a/src/app/Mail/TrialEnd.php b/src/app/Mail/TrialEnd.php
--- a/src/app/Mail/TrialEnd.php
+++ b/src/app/Mail/TrialEnd.php
@@ -5,29 +5,19 @@
 use App\Tenant;
 use App\User;
 use App\Utils;
-use Illuminate\Bus\Queueable;
-use Illuminate\Mail\Mailable;
-use Illuminate\Queue\SerializesModels;
 
 class TrialEnd extends Mailable
 {
-    use Queueable;
-    use SerializesModels;
-
-    /** @var \App\User An account owner (account) */
-    protected $account;
-
-
     /**
      * Create a new message instance.
      *
-     * @param \App\User $account An account owner (account)
+     * @param \App\User $user An account owner
      *
      * @return void
      */
-    public function __construct(User $account)
+    public function __construct(User $user)
     {
-        $this->account = $account;
+        $this->user = $user;
     }
 
     /**
@@ -37,9 +27,9 @@
      */
     public function build()
     {
-        $appName = Tenant::getConfig($this->account->tenant_id, 'app.name');
-        $paymentUrl = Tenant::getConfig($this->account->tenant_id, 'app.kb.payment_system');
-        $supportUrl = Tenant::getConfig($this->account->tenant_id, 'app.support_url');
+        $appName = Tenant::getConfig($this->user->tenant_id, 'app.name');
+        $paymentUrl = Tenant::getConfig($this->user->tenant_id, 'app.kb.payment_system');
+        $supportUrl = Tenant::getConfig($this->user->tenant_id, 'app.support_url');
 
         $subject = \trans('mail.trialend-subject', ['site' => $appName]);
 
@@ -49,9 +39,9 @@
             ->with([
                     'site' => $appName,
                     'subject' => $subject,
-                    'username' => $this->account->name(true),
+                    'username' => $this->user->name(true),
                     'paymentUrl' => $paymentUrl,
-                    'supportUrl' => Utils::serviceUrl($supportUrl, $this->account->tenant_id),
+                    'supportUrl' => Utils::serviceUrl($supportUrl, $this->user->tenant_id),
             ]);
 
         return $this;
diff --git a/src/resources/lang/en/app.php b/src/resources/lang/en/app.php
--- a/src/resources/lang/en/app.php
+++ b/src/resources/lang/en/app.php
@@ -26,6 +26,7 @@
     'event-suspended' => 'Suspended',
     'event-unsuspended' => 'Unsuspended',
     'event-comment' => 'Commented',
+    'event-mailsent' => 'Mail Sent',
 
     'mandate-delete-success' => 'The auto-payment has been removed.',
     'mandate-update-success' => 'The auto-payment has been updated.',
diff --git a/src/resources/lang/en/mail.php b/src/resources/lang/en/mail.php
--- a/src/resources/lang/en/mail.php
+++ b/src/resources/lang/en/mail.php
@@ -32,10 +32,10 @@
         . "Consider setting up an automatic payment to avoid messages like this in the future.",
     'negativebalance-body-ext' => "Settle up to keep your account running:",
 
-    'negativebalancereminder-subject' => ":site Payment Reminder",
-    'negativebalancereminder-body' => "It has probably skipped your attention that you are behind on paying for your :site account. "
+    'negativebalancereminderdegrade-subject' => ":site Payment Reminder",
+    'negativebalancereminderdegrade-body' => "It has probably skipped your attention that you are behind on paying for your :site account. "
         . "Consider setting up an automatic payment to avoid messages like this in the future.",
-    'negativebalancereminder-body-ext' => "Settle up to keep your account running:",
+    'negativebalancereminderdegrade-body-ext' => "Settle up to keep your account running:",
 
     'negativebalancereminderdegrade-body-warning' => "Please, be aware that your account will be degraded "
         . "if your account balance is not settled by :date.",
@@ -78,9 +78,9 @@
     'support' => "Special circumstances? Something is wrong with a charge?\n"
         . ":site Support is here to help.",
 
-    'signupcode-subject' => ":site Registration",
-    'signupcode-body1' => "This is your verification code for the :site registration process:",
-    'signupcode-body2' => "You can also click the link below to continue the registration process:",
+    'signupverification-subject' => ":site Registration",
+    'signupverification-body1' => "This is your verification code for the :site registration process:",
+    'signupverification-body2' => "You can also click the link below to continue the registration process:",
 
     'signupinvitation-subject' => ":site Invitation",
     'signupinvitation-header' => "Hi,",
diff --git a/src/resources/lang/fr/mail.php b/src/resources/lang/fr/mail.php
--- a/src/resources/lang/fr/mail.php
+++ b/src/resources/lang/fr/mail.php
@@ -32,10 +32,10 @@
         . " Veillez à mettre en place un auto-paiement pour éviter de tel avertissement comme celui-ci dans le future.",
     'negativebalance-body-ext' => "Régler votre compte pour le maintenir en fontion:",
 
-    'negativebalancereminder-subject' => ":site Rappel de Paiement",
-    'negativebalancereminder-body' => "Vous n'avez peut-être pas rendu compte que vous êtes en retard avec votre paiement pour :site compte."
+    'negativebalancereminderdegrade-subject' => ":site Rappel de Paiement",
+    'negativebalancereminderdegrade-body' => "Vous n'avez peut-être pas rendu compte que vous êtes en retard avec votre paiement pour :site compte."
         . " Veillez à mettre en place un auto-paiement pour éviter de tel avertissement comme celui-ci dans le future.",
-    'negativebalancereminder-body-ext' => "Régler votre compte pour le maintenir en fontion:",
+    'negativebalancereminderdegrade-body-ext' => "Régler votre compte pour le maintenir en fontion:",
 
     'negativebalancereminderdegrade-body-warning' => "Veuillez noter que votre compte sera dégradé"
         . " si le solde de votre compte n'est pas réglé avant le :date.",
@@ -75,9 +75,9 @@
     'support' => "Cas particulier? Il y a un probléme avec une charge?\n"
         . ":site Le support reste à votre disposition.",
 
-    'signupcode-subject' => ":site Enregistrement",
-    'signupcode-body1' => "Voici votre code de vérification pour le :site registration process:",
-    'signupcode-body2' => "Vous pouvez également continuer avec le processus d'enregistrement en cliquant sur le lien ci-dessous:",
+    'signupverification-subject' => ":site Enregistrement",
+    'signupverification-body1' => "Voici votre code de vérification pour le :site registration process:",
+    'signupverification-body2' => "Vous pouvez également continuer avec le processus d'enregistrement en cliquant sur le lien ci-dessous:",
 
     'signupinvitation-subject' => ":site Invitation",
     'signupinvitation-header' => "Salut,",
diff --git a/src/resources/views/emails/html/negative_balance_reminder_degrade.blade.php b/src/resources/views/emails/html/negative_balance_reminder_degrade.blade.php
--- a/src/resources/views/emails/html/negative_balance_reminder_degrade.blade.php
+++ b/src/resources/views/emails/html/negative_balance_reminder_degrade.blade.php
@@ -6,8 +6,8 @@
     <body>
         <p>{{ __('mail.header', ['name' => $username]) }}</p>
 
-        <p>{{ __('mail.negativebalancereminder-body', ['site' => $site]) }}</p>
-        <p>{{ __('mail.negativebalancereminder-body-ext', ['site' => $site]) }}</p>
+        <p>{{ __('mail.negativebalancereminderdegrade-body', ['site' => $site]) }}</p>
+        <p>{{ __('mail.negativebalancereminderdegrade-body-ext', ['site' => $site]) }}</p>
         <p><a href="{{ $walletUrl }}">{{ $walletUrl }}</a></p>
         <p><b>{{ __('mail.negativebalancereminderdegrade-body-warning', ['site' => $site, 'date' => $date]) }}</b></p>
 
diff --git a/src/resources/views/emails/html/signup_code.blade.php b/src/resources/views/emails/html/signup_verification.blade.php
rename from src/resources/views/emails/html/signup_code.blade.php
rename to src/resources/views/emails/html/signup_verification.blade.php
--- a/src/resources/views/emails/html/signup_code.blade.php
+++ b/src/resources/views/emails/html/signup_verification.blade.php
@@ -6,11 +6,11 @@
     <body>
         <p>{{ __('mail.header', ['name' => $username]) }}</p>
 
-        <p>{{ __('mail.signupcode-body1', ['site' => $site]) }}</p>
+        <p>{{ __('mail.signupverification-body1', ['site' => $site]) }}</p>
 
         <p><strong>{!! $short_code !!}</strong></p>
 
-        <p>{{ __('mail.signupcode-body2') }}</p>
+        <p>{{ __('mail.signupverification-body2') }}</p>
 
         <p><a href="{!! $href !!}">{!! $href !!}</a></p>
 
diff --git a/src/resources/views/emails/plain/negative_balance_reminder_degrade.blade.php b/src/resources/views/emails/plain/negative_balance_reminder_degrade.blade.php
--- a/src/resources/views/emails/plain/negative_balance_reminder_degrade.blade.php
+++ b/src/resources/views/emails/plain/negative_balance_reminder_degrade.blade.php
@@ -1,8 +1,8 @@
 {!! __('mail.header', ['name' => $username]) !!}
 
-{!! __('mail.negativebalancereminder-body', ['site' => $site]) !!}
+{!! __('mail.negativebalancereminderdegrade-body', ['site' => $site]) !!}
 
-{!! __('mail.negativebalancereminder-body-ext', ['site' => $site]) !!}
+{!! __('mail.negativebalancereminderdegrade-body-ext', ['site' => $site]) !!}
 
 {!! $walletUrl !!}
 
diff --git a/src/resources/views/emails/plain/signup_code.blade.php b/src/resources/views/emails/plain/signup_verification.blade.php
rename from src/resources/views/emails/plain/signup_code.blade.php
rename to src/resources/views/emails/plain/signup_verification.blade.php
--- a/src/resources/views/emails/plain/signup_code.blade.php
+++ b/src/resources/views/emails/plain/signup_verification.blade.php
@@ -1,10 +1,10 @@
 {!! __('mail.header', ['name' => $username]) !!}
 
-{!! __('mail.signupcode-body1', ['site' => $site]) !!}
+{!! __('mail.signupverification-body1', ['site' => $site]) !!}
 
 {!! $short_code !!}
 
-{!! __('mail.signupcode-body2') !!}
+{!! __('mail.signupverification-body2') !!}
 
 {!! $href !!}
 
diff --git a/src/tests/Unit/Mail/DegradedAccountReminderTest.php b/src/tests/Unit/Mail/DegradedAccountReminderTest.php
--- a/src/tests/Unit/Mail/DegradedAccountReminderTest.php
+++ b/src/tests/Unit/Mail/DegradedAccountReminderTest.php
@@ -39,4 +39,19 @@
         $this->assertTrue(strpos($plain, "your account is a free account") > 0);
         $this->assertTrue(strpos($plain, "$appName Team") > 0);
     }
+
+    /**
+     * Test getSubject() and getUser()
+     */
+    public function testGetSubjectAndUser(): void
+    {
+        $user = $this->getTestUser('ned@kolab.org');
+        $wallet = $user->wallets->first();
+        $appName = $user->tenant->title;
+
+        $mail = new DegradedAccountReminder($wallet, $user);
+
+        $this->assertSame("$appName Reminder: Your account is free", $mail->getSubject());
+        $this->assertSame($user, $mail->getUser());
+    }
 }
diff --git a/src/tests/Unit/Mail/HelperTest.php b/src/tests/Unit/Mail/HelperTest.php
--- a/src/tests/Unit/Mail/HelperTest.php
+++ b/src/tests/Unit/Mail/HelperTest.php
@@ -2,6 +2,7 @@
 
 namespace Tests\Unit\Mail;
 
+use App\EventLog;
 use App\Mail\Helper;
 use App\User;
 use Illuminate\Support\Facades\Mail;
@@ -36,6 +37,7 @@
      */
     public function testSendMail(): void
     {
+        EventLog::truncate();
         Mail::fake();
 
         $tenant = \App\Tenant::whereNotIn('id', [1])->first();
@@ -90,7 +92,20 @@
                 && $mail->hasReplyTo('replyto@test.com', 'replyto name');
         });
 
-        // TODO: Test somehow log entries, maybe with timacdonald/log-fake package
+        // No EventLog entries up to this point
+        $this->assertSame(0, EventLog::count());
+
+        // Assert EventLog entry
+        $user = $this->getTestUser('mail-helper-test@kolabnow.com');
+        $mail = new \App\Mail\TrialEnd($user);
+
+        Helper::sendMail($mail, $tenant->id, ['to' => 'to@test.com', 'cc' => 'cc@test.com']);
+
+        $event = EventLog::where('object_id', $user->id)->where('object_type', User::class)->first();
+        $this->assertSame(EventLog::TYPE_MAILSENT, $event->type);
+        $this->assertSame(['recipients' => ['to@test.com', 'cc@test.com']], $event->data);
+        $this->assertSame("[TrialEnd] Kolab Now: Your trial phase has ended", $event->comment);
+
         // TODO: Test somehow exception case
     }
 
diff --git a/src/tests/Unit/Mail/NegativeBalanceDegradedTest.php b/src/tests/Unit/Mail/NegativeBalanceDegradedTest.php
--- a/src/tests/Unit/Mail/NegativeBalanceDegradedTest.php
+++ b/src/tests/Unit/Mail/NegativeBalanceDegradedTest.php
@@ -52,4 +52,19 @@
         $this->assertTrue(strpos($plain, "$appName Support") > 0);
         $this->assertTrue(strpos($plain, "$appName Team") > 0);
     }
+
+    /**
+     * Test getSubject() and getUser()
+     */
+    public function testGetSubjectAndUser(): void
+    {
+        $user = $this->getTestUser('ned@kolab.org');
+        $wallet = $user->wallets->first();
+        $appName = $user->tenant->title;
+
+        $mail = new NegativeBalanceDegraded($wallet, $user);
+
+        $this->assertSame("$appName Account Degraded", $mail->getSubject());
+        $this->assertSame($user, $mail->getUser());
+    }
 }
diff --git a/src/tests/Unit/Mail/NegativeBalanceReminderDegradeTest.php b/src/tests/Unit/Mail/NegativeBalanceReminderDegradeTest.php
--- a/src/tests/Unit/Mail/NegativeBalanceReminderDegradeTest.php
+++ b/src/tests/Unit/Mail/NegativeBalanceReminderDegradeTest.php
@@ -58,4 +58,19 @@
         $this->assertTrue(strpos($plain, "$appName Support") > 0);
         $this->assertTrue(strpos($plain, "$appName Team") > 0);
     }
+
+    /**
+     * Test getSubject() and getUser()
+     */
+    public function testGetSubjectAndUser(): void
+    {
+        $user = $this->getTestUser('ned@kolab.org');
+        $wallet = $user->wallets->first();
+        $appName = $user->tenant->title;
+
+        $mail = new NegativeBalanceReminderDegrade($wallet, $user);
+
+        $this->assertSame("$appName Payment Reminder", $mail->getSubject());
+        $this->assertSame($user, $mail->getUser());
+    }
 }
diff --git a/src/tests/Unit/Mail/NegativeBalanceTest.php b/src/tests/Unit/Mail/NegativeBalanceTest.php
--- a/src/tests/Unit/Mail/NegativeBalanceTest.php
+++ b/src/tests/Unit/Mail/NegativeBalanceTest.php
@@ -49,4 +49,19 @@
         $this->assertTrue(strpos($plain, "$appName Support") > 0);
         $this->assertTrue(strpos($plain, "$appName Team") > 0);
     }
+
+    /**
+     * Test getSubject() and getUser()
+     */
+    public function testGetSubjectAndUser(): void
+    {
+        $user = new User();
+        $wallet = new Wallet();
+        $appName = \config('app.name');
+
+        $mail = new NegativeBalance($wallet, $user);
+
+        $this->assertSame("$appName Payment Required", $mail->getSubject());
+        $this->assertSame($user, $mail->getUser());
+    }
 }
diff --git a/src/tests/Unit/Mail/PasswordExpirationReminderTest.php b/src/tests/Unit/Mail/PasswordExpirationReminderTest.php
--- a/src/tests/Unit/Mail/PasswordExpirationReminderTest.php
+++ b/src/tests/Unit/Mail/PasswordExpirationReminderTest.php
@@ -40,4 +40,19 @@
         $this->assertTrue(strpos($plain, $link) > 0);
         $this->assertTrue(strpos($plain, $expiresOn) > 0);
     }
+
+    /**
+     * Test getSubject() and getUser()
+     */
+    public function testGetSubjectAndUser(): void
+    {
+        $user = new User(['name' => 'User Name']);
+        $appName = \config('app.name');
+        $expiresOn = now()->copy()->addDays(7)->toDateString();
+
+        $mail = new PasswordExpirationReminder($user, $expiresOn);
+
+        $this->assertSame("$appName password expires on $expiresOn", $mail->getSubject());
+        $this->assertSame($user, $mail->getUser());
+    }
 }
diff --git a/src/tests/Unit/Mail/PasswordResetTest.php b/src/tests/Unit/Mail/PasswordResetTest.php
--- a/src/tests/Unit/Mail/PasswordResetTest.php
+++ b/src/tests/Unit/Mail/PasswordResetTest.php
@@ -45,4 +45,26 @@
         $this->assertStringStartsWith("Dear " . $code->user->name(true), $plain);
         $this->assertTrue(strpos($plain, $link) > 0);
     }
+
+    /**
+     * Test getSubject() and getUser()
+     */
+    public function testGetSubjectAndUser(): void
+    {
+        $appName = \config('app.name');
+        $code = new VerificationCode([
+                'user_id' => 123456789,
+                'mode' => 'password-reset',
+                'code' => 'code',
+                'short_code' => 'short-code',
+        ]);
+
+        // @phpstan-ignore-next-line
+        $code->user = new User(['name' => 'User Name']);
+
+        $mail = new PasswordReset($code);
+
+        $this->assertSame("$appName Password Reset", $mail->getSubject());
+        $this->assertSame($code->user, $mail->getUser());
+    }
 }
diff --git a/src/tests/Unit/Mail/PaymentFailureTest.php b/src/tests/Unit/Mail/PaymentFailureTest.php
--- a/src/tests/Unit/Mail/PaymentFailureTest.php
+++ b/src/tests/Unit/Mail/PaymentFailureTest.php
@@ -48,4 +48,21 @@
         $this->assertTrue(strpos($plain, "Something went wrong with auto-payment for your $appName account") > 0);
         $this->assertTrue(strpos($plain, "$appName Team") > 0);
     }
+
+    /**
+     * Test getSubject() and getUser()
+     */
+    public function testGetSubjectAndUser(): void
+    {
+        $user = new User();
+        $user->id = 1234;
+        $payment = new Payment();
+        $payment->amount = 123;
+        $appName = \config('app.name');
+
+        $mail = new PaymentFailure($payment, $user);
+
+        $this->assertSame("$appName Payment Failed", $mail->getSubject());
+        $this->assertSame($user, $mail->getUser());
+    }
 }
diff --git a/src/tests/Unit/Mail/PaymentMandateDisabledTest.php b/src/tests/Unit/Mail/PaymentMandateDisabledTest.php
--- a/src/tests/Unit/Mail/PaymentMandateDisabledTest.php
+++ b/src/tests/Unit/Mail/PaymentMandateDisabledTest.php
@@ -47,4 +47,20 @@
         $this->assertTrue(strpos($plain, "Your $appName account balance") > 0);
         $this->assertTrue(strpos($plain, "$appName Team") > 0);
     }
+
+    /**
+     * Test getSubject() and getUser()
+     */
+    public function testGetSubjectAndUser(): void
+    {
+        $user = new User();
+        $user->id = 1234;
+        $wallet = new Wallet();
+        $appName = \config('app.name');
+
+        $mail = new PaymentMandateDisabled($wallet, $user);
+
+        $this->assertSame("$appName Auto-payment Problem", $mail->getSubject());
+        $this->assertSame($user, $mail->getUser());
+    }
 }
diff --git a/src/tests/Unit/Mail/PaymentSuccessTest.php b/src/tests/Unit/Mail/PaymentSuccessTest.php
--- a/src/tests/Unit/Mail/PaymentSuccessTest.php
+++ b/src/tests/Unit/Mail/PaymentSuccessTest.php
@@ -48,4 +48,21 @@
         $this->assertTrue(strpos($plain, "The auto-payment for your $appName account") > 0);
         $this->assertTrue(strpos($plain, "$appName Team") > 0);
     }
+
+    /**
+     * Test getSubject() and getUser()
+     */
+    public function testGetSubjectAndUser(): void
+    {
+        $user = new User();
+        $user->id = 1234;
+        $payment = new Payment();
+        $payment->amount = 123;
+        $appName = \config('app.name');
+
+        $mail = new PaymentSuccess($payment, $user);
+
+        $this->assertSame("$appName Payment Succeeded", $mail->getSubject());
+        $this->assertSame($user, $mail->getUser());
+    }
 }
diff --git a/src/tests/Unit/Mail/SignupInvitationTest.php b/src/tests/Unit/Mail/SignupInvitationTest.php
--- a/src/tests/Unit/Mail/SignupInvitationTest.php
+++ b/src/tests/Unit/Mail/SignupInvitationTest.php
@@ -38,4 +38,21 @@
         $this->assertTrue(strpos($plain, "invited to join $appName") > 0);
         $this->assertTrue(strpos($plain, $url) > 0);
     }
+
+    /**
+     * Test getSubject() and getUser()
+     */
+    public function testGetSubjectAndUser(): void
+    {
+        $appName = \config('app.name');
+        $invitation = new SI([
+                'id' => 'abc',
+                'email' => 'test@email',
+        ]);
+
+        $mail = new SignupInvitation($invitation);
+
+        $this->assertSame("$appName Invitation", $mail->getSubject());
+        $this->assertSame(null, $mail->getUser());
+    }
 }
diff --git a/src/tests/Unit/Mail/SignupVerificationTest.php b/src/tests/Unit/Mail/SignupVerificationTest.php
--- a/src/tests/Unit/Mail/SignupVerificationTest.php
+++ b/src/tests/Unit/Mail/SignupVerificationTest.php
@@ -40,4 +40,24 @@
         $this->assertStringStartsWith('Dear First Last', $plain);
         $this->assertTrue(strpos($plain, $url) > 0);
     }
+
+    /**
+     * Test getSubject() and getUser()
+     */
+    public function testGetSubjectAndUser(): void
+    {
+        $appName = \config('app.name');
+        $code = new SignupCode([
+                'code' => 'code',
+                'short_code' => 'short-code',
+                'email' => 'test@email',
+                'first_name' => 'First',
+                'last_name' => 'Last',
+        ]);
+
+        $mail = new SignupVerification($code);
+
+        $this->assertSame("$appName Registration", $mail->getSubject());
+        $this->assertSame(null, $mail->getUser());
+    }
 }
diff --git a/src/tests/Unit/Mail/TrialEndTest.php b/src/tests/Unit/Mail/TrialEndTest.php
--- a/src/tests/Unit/Mail/TrialEndTest.php
+++ b/src/tests/Unit/Mail/TrialEndTest.php
@@ -46,4 +46,18 @@
         $this->assertTrue(strpos($plain, "30 days of free $appName trial") > 0);
         $this->assertTrue(strpos($plain, "$appName Team") > 0);
     }
+
+    /**
+     * Test getSubject() and getUser()
+     */
+    public function testGetSubjectAndUser(): void
+    {
+        $user = new User();
+        $appName = \config('app.name');
+
+        $mail = new TrialEnd($user);
+
+        $this->assertSame("$appName: Your trial phase has ended", $mail->getSubject());
+        $this->assertSame($user, $mail->getUser());
+    }
 }