From 08b53fb3495214a34b806bbf07238958b223151d Mon Sep 17 00:00:00 2001
From: Alexander Makarov <sam@rmcreative.ru>
Date: Tue, 30 Sep 2014 02:26:24 +0400
Subject: [PATCH] Fixes #5088: new password reset token is now generated only if previous one was already used or expired

---
 apps/advanced/common/models/User.php                       | 23 ++++++++++++++++++-----
 apps/advanced/frontend/models/PasswordResetRequestForm.php |  5 ++++-
 2 files changed, 22 insertions(+), 6 deletions(-)

diff --git a/apps/advanced/common/models/User.php b/apps/advanced/common/models/User.php
index 4854b76..ace9324 100644
--- a/apps/advanced/common/models/User.php
+++ b/apps/advanced/common/models/User.php
@@ -95,11 +95,7 @@ class User extends ActiveRecord implements IdentityInterface
      */
     public static function findByPasswordResetToken($token)
     {
-        $expire = Yii::$app->params['user.passwordResetTokenExpire'];
-        $parts = explode('_', $token);
-        $timestamp = (int) end($parts);
-        if ($timestamp + $expire < time()) {
-            // token expired
+        if (!static::isPasswordResetTokenValid($token)) {
             return null;
         }
 
@@ -110,6 +106,23 @@ class User extends ActiveRecord implements IdentityInterface
     }
 
     /**
+     * Finds out if password reset token is valid
+     *
+     * @param string $token password reset token
+     * @return boolean
+     */
+    public static function isPasswordResetTokenValid($token)
+    {
+        if (empty($token)) {
+            return false;
+        }
+        $expire = Yii::$app->params['user.passwordResetTokenExpire'];
+        $parts = explode('_', $token);
+        $timestamp = (int) end($parts);
+        return $timestamp + $expire >= time();
+    }
+
+    /**
      * @inheritdoc
      */
     public function getId()
diff --git a/apps/advanced/frontend/models/PasswordResetRequestForm.php b/apps/advanced/frontend/models/PasswordResetRequestForm.php
index b89b7bc..df01013 100644
--- a/apps/advanced/frontend/models/PasswordResetRequestForm.php
+++ b/apps/advanced/frontend/models/PasswordResetRequestForm.php
@@ -42,7 +42,10 @@ class PasswordResetRequestForm extends Model
         ]);
 
         if ($user) {
-            $user->generatePasswordResetToken();
+            if (!User::isPasswordResetTokenValid($user->password_reset_token)) {
+                $user->generatePasswordResetToken();
+            }
+
             if ($user->save()) {
                 return \Yii::$app->mailer->compose('passwordResetToken', ['user' => $user])
                     ->setFrom([\Yii::$app->params['supportEmail'] => \Yii::$app->name . ' robot'])
--
libgit2 0.27.1