122 lines
3.4 KiB
PHP
122 lines
3.4 KiB
PHP
<?php
|
|
namespace App\Presentation\Setup2fa;
|
|
|
|
use App\Core\AppPresenter;
|
|
use App\Core\TwoFactorService;
|
|
use App\Model\UzivatelFacade;
|
|
use Nette;
|
|
use Nette\Application\UI\Form;
|
|
use Nette\Http\Session;
|
|
use Nette\Http\SessionSection;
|
|
use App\Model\Login\UserIdentity;
|
|
|
|
final class Setup2faPresenter extends AppPresenter
|
|
{
|
|
/** @persistent */
|
|
public string $backlink = '';
|
|
|
|
private SessionSection $twoFactorSession;
|
|
|
|
public function __construct(
|
|
private TwoFactorService $twoFactorService,
|
|
private UzivatelFacade $uzivatelFacade,
|
|
Session $session
|
|
) {
|
|
parent::__construct();
|
|
// Inicializace sekce pod unikátním názvem
|
|
$this->twoFactorSession = $session->getSection('TwoFactorSetup');
|
|
}
|
|
|
|
public function actionDefault(): void
|
|
{
|
|
/**
|
|
* Uživatelská identita = přihlášený user.
|
|
* @var UserIdentity
|
|
*/
|
|
$identity = $this->getUser()->getIdentity();
|
|
|
|
// Pokud už uživatel má 2FA aktivní (příznak v identitě)
|
|
if ($identity->twoFactor) {
|
|
//$this->flashMessage('Dvoufázové ověření již máte nastaveno.', 'info');
|
|
// Přesměrujte na profil, domovskou stránku, nebo na stránku pro zrušení 2FA
|
|
$this->redirect(':Disable2fa:');
|
|
}
|
|
}
|
|
|
|
public function renderDefault(): void
|
|
{
|
|
// Načtení secretu ze session
|
|
$tempSecret = $this->twoFactorSession->get('tempSecret');
|
|
|
|
// Pokud v session ještě není, vygenerujeme ho
|
|
if ($tempSecret === null) {
|
|
$tempSecret = $this->twoFactorService->generateSecret();
|
|
$this->twoFactorSession->set('tempSecret', $tempSecret);
|
|
}
|
|
|
|
/**
|
|
* Uživatelská identita = přihlášený user.
|
|
* @var UserIdentity
|
|
*/
|
|
$identity = $this->getUser()->getIdentity();
|
|
|
|
// Vygenerování QR kódu pro šablonu
|
|
$this->template->qrCodeUri = $this->twoFactorService->getQrCodeDataUri(
|
|
$tempSecret,
|
|
$identity->username
|
|
);
|
|
|
|
// PŘIDÁNO: Přímý odkaz pro mobilní aplikace
|
|
$this->template->otpAuthUri = $this->twoFactorService->getProvisioningUri($tempSecret, $identity->username);
|
|
|
|
//$this->template->secretKey = $tempSecret;
|
|
}
|
|
|
|
protected function createComponentVerifyForm(): Form
|
|
{
|
|
$form = new Form;
|
|
$form->addText('code', 'Ověřovací kód:')
|
|
->setRequired('Zadejte prosím 6místný kód z aplikace.')
|
|
->addRule($form::Pattern, 'Kód musí mít 6 číslic', '\d{6}')
|
|
->setHtmlAttribute('placeholder', '000 000')
|
|
->setHtmlAttribute('autocomplete', 'one-time-code');
|
|
|
|
$form->addSubmit('send', 'Aktivovat 2FA');
|
|
|
|
$form->onSuccess[] = $this->verifyFormSucceeded(...);
|
|
|
|
return $form;
|
|
}
|
|
|
|
public function verifyFormSucceeded(Form $form, \stdClass $data): void
|
|
{
|
|
$secret = $this->twoFactorSession->get('tempSecret');
|
|
|
|
if (!$secret) {
|
|
$this->flashMessage('Relace vypršela, zkuste stránku obnovit.', 'error');
|
|
$this->redirect('this');
|
|
}
|
|
|
|
if ($this->twoFactorService->verifyCode($secret, $data->code)) {
|
|
/**
|
|
* Uživatelská identita = přihlášený user.
|
|
* @var UserIdentity
|
|
*/
|
|
$identity = $this->getUser()->getIdentity();
|
|
|
|
// --- LOGIKA ULOŽENÍ DO DB ---
|
|
$this->uzivatelFacade->updateTOTPSecret($secret);
|
|
|
|
$this->twoFactorSession->remove(); // Po úspěchu smažeme dočasný klíč
|
|
|
|
// Aktualizace identity v session
|
|
$identity->twoFactor = true;
|
|
$identity->totpSecret = $secret;
|
|
|
|
$this->flashMessage('Dvoufázové ověření bylo úspěšně nastaveno.', 'success');
|
|
$this->redirect(':Home:');
|
|
} else {
|
|
$form->addError('Zadaný kód není správný. Zkontrolujte čas v telefonu.');
|
|
}
|
|
}
|
|
} |