diff --git a/src/new/config/packages/scheb_2fa.yaml b/src/new/config/packages/scheb_2fa.yaml
index b5631aeba..c33448cc4 100644
--- a/src/new/config/packages/scheb_2fa.yaml
+++ b/src/new/config/packages/scheb_2fa.yaml
@@ -4,11 +4,11 @@ scheb_two_factor:
- Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken
- Symfony\Component\Security\Http\Authenticator\Token\PostAuthenticationToken
- # E-Mail-Code-Verfahren (Code geht an das separate 2FA-Feld des Benutzers)
+ # E-Mail-Code-Verfahren (Code geht an das separate 2FA-Feld des Benutzers).
+ # Absender + SMTP kommen über den eigenen Mailer aus den Systemeinstellungen.
email:
enabled: true
- sender_email: noreply@printshopcreator.de
- sender_name: PrintshopCreator
+ mailer: PSC\System\SettingsBundle\Mailer\InstanceAuthCodeMailer
digits: 6
# TOTP / Authenticator-App
diff --git a/src/new/src/PSC/Backend/DashboardBundle/Controller/TwoFactorController.php b/src/new/src/PSC/Backend/DashboardBundle/Controller/TwoFactorController.php
index 50ee612bd..081b92e27 100644
--- a/src/new/src/PSC/Backend/DashboardBundle/Controller/TwoFactorController.php
+++ b/src/new/src/PSC/Backend/DashboardBundle/Controller/TwoFactorController.php
@@ -4,6 +4,7 @@ namespace PSC\Backend\DashboardBundle\Controller;
use Doctrine\ORM\EntityManagerInterface;
use PSC\Shop\EntityBundle\Entity\Contact;
+use PSC\System\SettingsBundle\Service\Instance;
use Scheb\TwoFactorBundle\Security\TwoFactor\Provider\Totp\TotpAuthenticatorInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
@@ -22,6 +23,7 @@ class TwoFactorController extends AbstractController
public function __construct(
private readonly EntityManagerInterface $entityManager,
private readonly TotpAuthenticatorInterface $totpAuthenticator,
+ private readonly Instance $instanceService,
) {
}
@@ -47,6 +49,7 @@ class TwoFactorController extends AbstractController
'totpEnabled' => $user->isTotpAuthenticationEnabled(),
'pendingSecret' => $pendingSecret,
'qrContent' => $qrContent,
+ 'mailReady' => $this->instanceService->getInstance()->isMailReady(),
]);
}
@@ -63,6 +66,14 @@ class TwoFactorController extends AbstractController
$user = $this->getUser();
$enabled = (bool) $request->request->get('enabled');
+
+ // E-Mail-2FA setzt vollständige System-SMTP-Einstellungen voraus.
+ if ($enabled && !$this->instanceService->getInstance()->isMailReady()) {
+ $this->addFlash('error', 'E-Mail-2FA ist nicht verfügbar: Es sind keine vollständigen SMTP-/Absender-Einstellungen in den Systemeinstellungen hinterlegt.');
+
+ return $this->redirectToRoute('psc_backend_2fa_settings');
+ }
+
$user->setTwoFactorEmail($request->request->get('two_factor_email'));
$user->setTwoFactorEmailEnabled($enabled);
diff --git a/src/new/src/PSC/Backend/DashboardBundle/Resources/views/security/2fa.html.twig b/src/new/src/PSC/Backend/DashboardBundle/Resources/views/security/2fa.html.twig
index 0142084e8..ea2853f22 100644
--- a/src/new/src/PSC/Backend/DashboardBundle/Resources/views/security/2fa.html.twig
+++ b/src/new/src/PSC/Backend/DashboardBundle/Resources/views/security/2fa.html.twig
@@ -17,19 +17,24 @@
E-Mail-Code
Bei jedem Login wird ein Einmal-Code an die unten angegebene E-Mail-Adresse geschickt.
+ {% if not mailReady %}
+
+ E-Mail-2FA ist nicht verfügbar: Bitte zuerst SMTP-Zugangsdaten und eine Absender-E-Mail in den Systemeinstellungen hinterlegen.
+
+ {% endif %}
diff --git a/src/new/src/PSC/Shop/EntityBundle/Document/Instance.php b/src/new/src/PSC/Shop/EntityBundle/Document/Instance.php
index cf1ee4cfd..052f3903b 100755
--- a/src/new/src/PSC/Shop/EntityBundle/Document/Instance.php
+++ b/src/new/src/PSC/Shop/EntityBundle/Document/Instance.php
@@ -52,6 +52,12 @@ class Instance implements UserInterface
protected $smtpPassword;
#[Field(type: 'string')]
protected $smtpUsername;
+ /** Absender-E-Mail für System-Mails (z.B. 2FA-Code). */
+ #[Field(type: 'string')]
+ protected $smtpSenderEmail;
+ /** Absender-Name für System-Mails. */
+ #[Field(type: 'string')]
+ protected $smtpSenderName;
#[Field(type: 'string')]
protected null|string $numberPattern;
@@ -329,6 +335,37 @@ class Instance implements UserInterface
$this->smtpUsername = $smtpUsername;
}
+ public function getSmtpSenderEmail()
+ {
+ return $this->smtpSenderEmail;
+ }
+
+ public function setSmtpSenderEmail($smtpSenderEmail)
+ {
+ $this->smtpSenderEmail = $smtpSenderEmail;
+ }
+
+ public function getSmtpSenderName()
+ {
+ return $this->smtpSenderName;
+ }
+
+ public function setSmtpSenderName($smtpSenderName)
+ {
+ $this->smtpSenderName = $smtpSenderName;
+ }
+
+ /**
+ * Sind die System-SMTP-Einstellungen inkl. Absender vollständig hinterlegt?
+ * Grundlage dafür, ob die E-Mail-2FA genutzt werden kann.
+ */
+ public function isMailReady(): bool
+ {
+ return (bool) $this->smtpOwn
+ && (string) $this->smtpHost !== ''
+ && (string) $this->smtpSenderEmail !== '';
+ }
+
/**
* @return int
*/
diff --git a/src/new/src/PSC/System/SettingsBundle/Form/Backend/SettingsType.php b/src/new/src/PSC/System/SettingsBundle/Form/Backend/SettingsType.php
index 96d6543ef..1d39d8e56 100755
--- a/src/new/src/PSC/System/SettingsBundle/Form/Backend/SettingsType.php
+++ b/src/new/src/PSC/System/SettingsBundle/Form/Backend/SettingsType.php
@@ -88,6 +88,8 @@ class SettingsType extends AbstractType
->add('smtpHost', TextType::class, ['required' => false, 'label' => 'Host'])
->add('smtpUsername', TextType::class, ['required' => false, 'label' => 'Username'])
->add('smtpPassword', PasswordType::class, ['required' => false, 'label' => 'Password'])
+ ->add('smtpSenderEmail', TextType::class, ['required' => false, 'label' => 'Absender E-Mail'])
+ ->add('smtpSenderName', TextType::class, ['required' => false, 'label' => 'Absender Name'])
->add('extraSettings', TextareaType::class, ['required' => false, 'label' => 'Extra Einstellungen'])
->add('maintenanceMode', CheckboxType::class, ['required' => false, 'label' => 'Wartungsmodus'])
->add('maintenanceTitle', TextType::class, ['required' => false, 'label' => 'Wartung Titel'])
diff --git a/src/new/src/PSC/System/SettingsBundle/Mailer/InstanceAuthCodeMailer.php b/src/new/src/PSC/System/SettingsBundle/Mailer/InstanceAuthCodeMailer.php
new file mode 100644
index 000000000..f416bfba1
--- /dev/null
+++ b/src/new/src/PSC/System/SettingsBundle/Mailer/InstanceAuthCodeMailer.php
@@ -0,0 +1,48 @@
+getEmailAuthCode();
+ if ($authCode === null) {
+ return;
+ }
+
+ $instance = $this->instanceService->getInstance();
+
+ $message = new Email();
+ $message
+ ->to($user->getEmailAuthRecipient())
+ ->subject('Ihr Sicherheitscode')
+ ->text("Ihr Sicherheitscode lautet: " . $authCode);
+
+ $senderEmail = (string) $instance->getSmtpSenderEmail();
+ if ($senderEmail !== '') {
+ $senderName = (string) $instance->getSmtpSenderName();
+ $message->from($senderName !== '' ? new Address($senderEmail, $senderName) : new Address($senderEmail));
+ }
+
+ $this->mailer->send($message);
+ }
+}
diff --git a/src/new/src/PSC/System/SettingsBundle/Resources/views/backend/settings/index.html.twig b/src/new/src/PSC/System/SettingsBundle/Resources/views/backend/settings/index.html.twig
index f02b2b26a..211cae6f4 100755
--- a/src/new/src/PSC/System/SettingsBundle/Resources/views/backend/settings/index.html.twig
+++ b/src/new/src/PSC/System/SettingsBundle/Resources/views/backend/settings/index.html.twig
@@ -288,6 +288,29 @@
+
+
+
+
+
+
+ {{ form_widget(form.smtpSenderEmail) }}
+
+
+
+
+
+
+
+ {{ form_widget(form.smtpSenderName) }}
+
+
+
+