'An authenticator was added to your account.', 'replacement_started'=>'An authenticator replacement was requested. Your existing authenticator remains active until replacement is confirmed.', 'replacement_started_recovery'=>'A single-use recovery code was used to request authenticator replacement. Your existing authenticator remains active until replacement is confirmed.', 'replaced'=>'Your authenticator was replaced. Old recovery codes and other sign-in sessions have been revoked.', 'recovery_used'=>'A single-use recovery code was used to authenticate your account.' ]; if(!isset($events[$event]))throw new LogicException('Unknown MFA notification event.'); $h=static fn($text)=>htmlspecialchars((string)$text,ENT_QUOTES,'UTF-8'); $body='
'.$h($events[$event]).'
Account: '.$h($account['user_email']).'
Time (UTC): '.$h(gmdate('Y-m-d H:i:s')).'
If you did not authorize this activity, contact your site administrator immediately and secure your account.
'; $ok=false; try{$ok=$this->deliver((string)$account['user_email'],self::APPLICATION_NAME.' - Account security notice',$body);} catch(Throwable $error){/* Keep secrets and provider diagnostics out of this event log. */} if(!$ok)error_log('MFA security notification failed user='.(int)$account['user_serial'].' event='.$event); return $ok; } protected function deliver(string $to,string $subject,string $body): bool {return (new Email())->sendEmail($to,$subject,$body);} public static function notice(): string { if(empty($_SESSION['mfa_notification_warning']))return ''; unset($_SESSION['mfa_notification_warning']); return 'Your security action succeeded, but its notification email could not be sent. Please contact support.
'; } }