/**
  * Check if your recovery access can match with expected recovery access.
  *
  * @param RecoveryAccess $yourRecoveryAccess     Your recovery access.
  * @param RecoveryAccess $expectedRecoveryAccess Expected recovery access.
  *
  * @return Result
  */
 public function check($yourRecoveryAccess, $expectedRecoveryAccess)
 {
     // Check token.
     if ($yourRecoveryAccess->token !== $expectedRecoveryAccess->token) {
         return new Result(false, 'token.invalid', ['received' => $yourRecoveryAccess->token, 'expected' => $expectedRecoveryAccess->token]);
     }
     // Check timestamp.
     if ($this->validity !== null) {
         $validityDelta = $this->validity * 3600;
         $validityDifference = $yourRecoveryAccess->timestamp - ($expectedRecoveryAccess->timestamp + $validityDelta);
         if ($validityDifference >= 0) {
             return new Result(false, 'timestamp.expired', ['received' => $yourRecoveryAccess->timestamp, 'expiredAt' => $expectedRecoveryAccess->timestamp + $validityDelta, 'difference' => $validityDifference]);
         }
     }
     // Check if your recovery access uses the recovery password.
     if (password_verify($yourRecoveryAccess->password, $expectedRecoveryAccess->getHash())) {
         return new Result(true, 'success', ['recovered' => true]);
     }
     // Check if your recovery access uses the original password (when it is setted).
     if ($this->originalPassword && password_verify($yourRecoveryAccess->password, $this->originalPassword)) {
         return new Result(true, 'success', ['recovered' => false]);
     }
     // Mark password as incorrect.
     return new Result(false, 'password.incorrect');
 }
 /**
  * Data provider.
  */
 public function dataCheck()
 {
     $accessOriginal = new RecoveryAccess('aaabbb', 'token', 0);
     $accessOriginalRehashed = new RecoveryAccess('aaabbb', 'token', 0);
     $accessPasswordOne = new RecoveryAccess('123456', 'token', 0);
     $accessPasswordOneRehashed = new RecoveryAccess('123456', 'token', 0);
     $accessPasswordOnePrehashed = new RecoveryAccess(null, 'token', 0, $accessPasswordOneRehashed->getHash());
     $accessPasswordTwo = new RecoveryAccess('abcdef', 'token', 0);
     $checkerDefault = new RecoveryCheck();
     $checkerDefault->setValidity(24);
     $checkerDefault->setOriginalPassword($accessOriginal);
     $checkerWithOriginalPlain = clone $checkerDefault;
     $checkerWithOriginalPlain->setOriginalPassword('aaabbb');
     return [[$checkerDefault, new RecoveryAccess(null, 1), new RecoveryAccess(null, 0), 'token.invalid', ['received' => '1', 'expected' => '0']], [$checkerDefault, new RecoveryAccess(null, 'sameToken', 186401), new RecoveryAccess(null, 'sameToken', 100000), 'timestamp.expired', ['received' => 186401, 'expiredAt' => 186400, 'difference' => 1]], [$checkerDefault, $accessPasswordOne, $accessPasswordTwo, 'password.incorrect'], [$checkerDefault, $accessPasswordOne, $accessPasswordOne, 'success', ['recovered' => true]], [$checkerDefault, $accessPasswordOneRehashed, $accessPasswordOne, 'success', ['recovered' => true]], [$checkerDefault, $accessPasswordOneRehashed, $accessPasswordOnePrehashed, 'success', ['recovered' => true]], [$checkerDefault, $accessOriginalRehashed, $accessPasswordOne, 'success', ['recovered' => false]], [$checkerWithOriginalPlain, $accessOriginalRehashed, $accessPasswordOne, 'success', ['recovered' => false]]];
 }
 /**
  * Test getHash method.
  *
  * @covers Rentalhost\VanillaRecovery\RecoveryAccess::getHash
  */
 public function testGetHash()
 {
     $recoveryAccess = RecoveryAccess::generate('');
     static::assertNull($recoveryAccess->getHash());
     $recoveryAccess = RecoveryAccess::generate();
     static::assertNotNull($recoveryAccess->getHash());
 }