diff --git a/lib/classes/TwoFactorAuth.php b/lib/classes/TwoFactorAuth.php index 70d05676b27b35e062211fd1b45c3551372ddfc9..6c04b8e1ad85deb289ceed4cfd486e60c2f744bf 100644 --- a/lib/classes/TwoFactorAuth.php +++ b/lib/classes/TwoFactorAuth.php @@ -16,6 +16,7 @@ final class TwoFactorAuth const SESSION_DATA = 'tfa/data'; const SESSION_CONFIRMATIONS = 'tfa/confirmations'; const SESSION_FAILED = 'tfa/failed'; + const SESSION_TOKEN_SENT = 'tfa/token-sent'; const COOKIE_KEY = 'tfa/authentication'; @@ -178,10 +179,11 @@ final class TwoFactorAuth */ public function confirm($action, $text, array $data = []): void { - if (isset($_SESSION[self::SESSION_CONFIRMATIONS]) + if ( + isset($_SESSION[self::SESSION_CONFIRMATIONS]) && is_array($_SESSION[self::SESSION_CONFIRMATIONS]) - && in_array($action, $_SESSION[self::SESSION_CONFIRMATIONS])) - { + && in_array($action, $_SESSION[self::SESSION_CONFIRMATIONS]) + ) { $_SESSION[self::SESSION_CONFIRMATIONS] = array_diff( $_SESSION[self::SESSION_CONFIRMATIONS], [$action] @@ -210,14 +212,21 @@ final class TwoFactorAuth ]); if ($this->secret->type === 'email') { - StudipMail::sendMessage( - $this->secret->user->email, - _('Ihr Zwei-Faktor-Token'), - sprintf( - _('Bitte geben Sie dieses Token ein: %s'), - $this->secret->getToken() - ) - ); + if ( + !isset($_SESSION[self::SESSION_TOKEN_SENT]) + || $_SESSION[self::SESSION_TOKEN_SENT] < time() + ) { + StudipMail::sendMessage( + $this->secret->user->email, + _('Ihr Zwei-Faktor-Token'), + sprintf( + _('Bitte geben Sie dieses Token ein: %s'), + $this->secret->getToken() + ) + ); + + $_SESSION[self::SESSION_TOKEN_SENT] = time() + TFASecret::getValidationDuration('email'); + } } PageLayout::setBodyElementId('tfa-confirmation-screen'); @@ -295,8 +304,9 @@ final class TwoFactorAuth if ($this->secret->validateToken($token)) { $_SESSION[self::SESSION_FAILED] = []; + unset($_SESSION[self::SESSION_TOKEN_SENT]); - if ($data['global'] ?: false) { + if ($data['global'] ?? false) { $this->registerSecretInSession(); if (Request::int('tfa-trusted')) { @@ -304,7 +314,7 @@ final class TwoFactorAuth } } - if ($data['confirm'] ?: false) { + if ($data['confirm'] ?? false) { if (!isset($_SESSION[self::SESSION_CONFIRMATIONS])) { $_SESSION[self::SESSION_CONFIRMATIONS] = []; }