Auth2FA/app/Presentation/Setup2fa/Setup2faPresenter.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.');
}
}
}