diff --git a/app/Model/Facade/DatabazeFacade.php b/app/Model/Facade/DatabazeFacade.php
index 836856b..a537783 100644
--- a/app/Model/Facade/DatabazeFacade.php
+++ b/app/Model/Facade/DatabazeFacade.php
@@ -307,6 +307,40 @@ class DatabazeFacade
);
}
+ /**
+ * Změna přihlašovacího jména (e-mailu) přihlášeného uživatele.
+ */
+ public function changeOwnEmail(int $loginId, string $email): string
+ {
+ $this->updateUserCredentials($loginId, $email, null);
+
+ return mb_strtolower(trim($email));
+ }
+
+ /**
+ * Změna hesla. Původní heslo musí sedět s uloženým hashem.
+ */
+ public function changeOwnPassword(int $loginId, string $currentPassword, string $newPassword): void
+ {
+ $row = $this->masterDb->fetch(
+ 'SELECT HESLO_HASH FROM dbo.LOGIN WHERE ID = ? AND AKTIVNI = 1',
+ $loginId
+ );
+ $hash = $row !== null ? (string) ($row->HESLO_HASH ?? '') : '';
+ if ($hash === '' || !$this->passwords->verify($currentPassword, $hash)) {
+ throw new \InvalidArgumentException('Původní heslo není správné.');
+ }
+ if (mb_strlen($newPassword) < 6) {
+ throw new \InvalidArgumentException('Heslo musí mít alespoň 6 znaků.');
+ }
+
+ $this->masterDb->query(
+ 'UPDATE dbo.LOGIN SET HESLO_HASH = ? WHERE ID = ?',
+ $this->passwords->hash($newPassword),
+ $loginId
+ );
+ }
+
public function findLoginIdForFirma(string $database, int $firmaId, ?string $server = null): ?int
{
$server ??= $this->tenantServer;
diff --git a/app/UI/@layout.latte b/app/UI/@layout.latte
index 7ef271d..80780c2 100644
--- a/app/UI/@layout.latte
+++ b/app/UI/@layout.latte
@@ -25,7 +25,7 @@
{* naše vlastní styly *}
-
+
@@ -77,10 +77,11 @@
{if $user->isLoggedIn()}
- {* Přihlášený uživatel *}
-
- {$user->identity->jmeno ?: $user->identity->email}
-
+ {* Přihlášený uživatel — ikona / jméno → Nastavení *}
+
+
+ {$user->identity->jmeno ?: $user->identity->email}
+
Odhlásit
diff --git a/app/UI/Nastaveni/NastaveniPresenter.php b/app/UI/Nastaveni/NastaveniPresenter.php
index fc2278c..e3ec660 100644
--- a/app/UI/Nastaveni/NastaveniPresenter.php
+++ b/app/UI/Nastaveni/NastaveniPresenter.php
@@ -3,14 +3,17 @@
namespace App\UI\Nastaveni;
use App\Model\Faktura\FakturaCislovani;
+use App\Model\Facade\DatabazeFacade;
use App\Model\Facade\FakturaFacade;
use App\UI\BasePresenter;
use Nette\Application\UI\Form;
+use Nette\Security\SimpleIdentity;
class NastaveniPresenter extends BasePresenter
{
public function __construct(
- private FakturaFacade $fakturaFacade
+ private FakturaFacade $fakturaFacade,
+ private DatabazeFacade $databazeFacade,
) {
parent::__construct();
}
@@ -29,6 +32,14 @@ class NastaveniPresenter extends BasePresenter
'obdobi' => $nastaveni['obdobi'],
'splatnost' => $nastaveni['splatnostDny'],
]);
+
+ $login = $this->databazeFacade->getById((int) $this->getUser()->getId());
+ $email = $login !== null
+ ? (string) $login->EMAIL
+ : (string) ($this->getUser()->getIdentity()->email ?? '');
+ $this['jmenoForm']->setDefaults([
+ 'email' => $email,
+ ]);
}
public function renderDefault(): void
@@ -36,6 +47,9 @@ class NastaveniPresenter extends BasePresenter
$firmaId = (int) $this->getUser()->getIdentity()->firma_id;
$dalsi = $this->fakturaFacade->getNextCislo($firmaId);
$this->template->prikladCisla = $dalsi['cislo'];
+
+ $hesloForm = $this['hesloForm'];
+ $this->template->otevritHesloModal = $hesloForm->isSubmitted() && !$hesloForm->isSuccess();
}
protected function createComponentNastaveniForm(): Form
@@ -79,4 +93,87 @@ class NastaveniPresenter extends BasePresenter
$this->flashMessage('Nastavení faktur bylo uloženo.', 'success');
$this->redirect('this');
}
+
+ protected function createComponentJmenoForm(): Form
+ {
+ $form = new Form;
+
+ $form->addText('email', 'Uživatelské jméno:')
+ ->setHtmlType('email')
+ ->setHtmlAttribute('autocomplete', 'username')
+ ->setRequired('Zadejte uživatelské jméno.')
+ ->addRule(Form::Email, 'Zadejte platný e-mail.')
+ ->addRule(Form::MaxLength, 'Uživatelské jméno může mít nejvýše 100 znaků.', 100);
+
+ $form->addSubmit('save', 'Uložit jméno');
+ $form->onSuccess[] = [$this, 'jmenoFormSucceeded'];
+
+ return $form;
+ }
+
+ public function jmenoFormSucceeded(Form $form, \stdClass $data): void
+ {
+ try {
+ $email = $this->databazeFacade->changeOwnEmail(
+ (int) $this->getUser()->getId(),
+ (string) $data->email
+ );
+ } catch (\InvalidArgumentException $e) {
+ $form->addError($e->getMessage());
+ return;
+ }
+
+ $this->replaceIdentityEmail($email);
+ $this->flashMessage('Uživatelské jméno bylo uloženo.', 'success');
+ $this->redirect('this');
+ }
+
+ protected function createComponentHesloForm(): Form
+ {
+ $form = new Form;
+
+ $form->addPassword('current', 'Původní heslo:')
+ ->setHtmlAttribute('autocomplete', 'current-password')
+ ->setRequired('Zadejte původní heslo.');
+
+ $form->addPassword('password', 'Nové heslo:')
+ ->setHtmlAttribute('autocomplete', 'new-password')
+ ->setRequired('Zadejte nové heslo.')
+ ->addRule(Form::MinLength, 'Heslo musí mít alespoň 6 znaků.', 6);
+
+ $form->addPassword('passwordVerify', 'Nové heslo znovu:')
+ ->setHtmlAttribute('autocomplete', 'new-password')
+ ->setRequired('Zadejte nové heslo znovu.')
+ ->addRule(Form::Equal, 'Hesla se neshodují.', $form['password']);
+
+ $form->addSubmit('save', 'Uložit heslo');
+ $form->onSuccess[] = [$this, 'hesloFormSucceeded'];
+
+ return $form;
+ }
+
+ public function hesloFormSucceeded(Form $form, \stdClass $data): void
+ {
+ try {
+ $this->databazeFacade->changeOwnPassword(
+ (int) $this->getUser()->getId(),
+ (string) $data->current,
+ (string) $data->password
+ );
+ } catch (\InvalidArgumentException $e) {
+ $form['current']->addError($e->getMessage());
+ return;
+ }
+
+ $this->flashMessage('Heslo bylo změněno.', 'success');
+ $this->redirect('this');
+ }
+
+ private function replaceIdentityEmail(string $email): void
+ {
+ $identity = $this->getUser()->getIdentity();
+ $data = $identity->getData();
+ $data['email'] = $email;
+ $this->getUser()->login(new SimpleIdentity($identity->getId(), $identity->getRoles(), $data));
+ }
}
diff --git a/app/UI/Nastaveni/default.latte b/app/UI/Nastaveni/default.latte
index 1ae2972..84325ad 100644
--- a/app/UI/Nastaveni/default.latte
+++ b/app/UI/Nastaveni/default.latte
@@ -53,7 +53,99 @@
+
+