account === null) { $this->account = Yii::$app->user->identity; } if (!$this->account instanceof Account) { throw new InvalidConfigException('account should be instance of ' . Account::class); } if (empty($this->account->otp_secret)) { throw new InvalidConfigException('account should have not empty otp_secret'); } } protected function validateValue($value) { try { $totp = TOTP::create($this->account->otp_secret); if (!$totp->verify((string)$value, $this->getTimestamp(), $this->window)) { return [E::OTP_TOKEN_INCORRECT, []]; } } catch (RangeException $e) { return [E::OTP_TOKEN_INCORRECT, []]; } return null; } private function getTimestamp(): ?int { $timestamp = $this->timestamp; if (is_callable($timestamp)) { $timestamp = call_user_func($this->timestamp); } if ($timestamp === null) { return null; } return (int)$timestamp; } }