setOmitted()->setRequired()->addRule(self::PROTECTION, $errorMessage); $this->monitor(Presenter::class, function (Presenter $presenter) : void { if (!$this->session) { $this->session = $presenter->getSession(); $this->session->start(); } }); $this->monitor(\Packetery\Nette\Forms\Form::class, function (\Packetery\Nette\Forms\Form $form) : void { if (!$this->session && !$form instanceof \Packetery\Nette\Application\UI\Form) { $this->session = new \Packetery\Nette\Http\Session($form->httpRequest, new \Packetery\Nette\Http\Response()); $this->session->start(); } }); } /** * @return static * @internal */ public function setValue($value) { return $this; } public function loadHttpData() : void { $this->value = $this->getHttpData(\Packetery\Nette\Forms\Form::DATA_TEXT); } public function getToken() : string { if (!$this->session) { throw new \Packetery\Nette\InvalidStateException('Session initialization error'); } $session = $this->session->getSection(self::class); if (!isset($session->token)) { $session->token = \Packetery\Nette\Utils\Random::generate(); } return $session->token ^ $this->session->getId(); } private function generateToken(string $random = null) : string { if ($random === null) { $random = \Packetery\Nette\Utils\Random::generate(10); } return $random . \base64_encode(\sha1($this->getToken() . $random, \true)); } public function getControl() : \Packetery\Nette\Utils\Html { return parent::getControl()->value($this->generateToken()); } /** @internal */ public static function validateCsrf(self $control) : bool { $value = (string) $control->getValue(); return $control->generateToken(\substr($value, 0, 10)) === $value; } }