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): ?array { try { $totp = TOTP::create($this->account->otp_secret); if (!$totp->verify((string)$value, $this->getTimestamp(), $totp->getPeriod() - 1)) { return [E::TOTP_INCORRECT, []]; } } catch (RangeException) { return [E::TOTP_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; } }