TYPO3 v15 dev-main snapshot ()

This commit is contained in:
2026-08-10 22:31:17 +02:00
commit 629541cb4c
86 changed files with 5360 additions and 0 deletions
@@ -0,0 +1,23 @@
<?php
declare(strict_types=1);
/*
* This file is part of the TYPO3 CMS project.
*
* It is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, either version 2
* of the License, or any later version.
*
* For the full copyright and license information, please read the
* LICENSE.txt file that was distributed with this source code.
*
* The TYPO3 project - inspiring people to share!
*/
namespace TYPO3\CMS\FrontendLogin\Configuration;
/**
* @internal this is a concrete TYPO3 implementation and solely used for EXT:felogin and not part of TYPO3's Core API.
*/
class IncompleteConfigurationException extends \Exception {}
@@ -0,0 +1,140 @@
<?php
declare(strict_types=1);
/*
* This file is part of the TYPO3 CMS project.
*
* It is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, either version 2
* of the License, or any later version.
*
* For the full copyright and license information, please read the
* LICENSE.txt file that was distributed with this source code.
*
* The TYPO3 project - inspiring people to share!
*/
namespace TYPO3\CMS\FrontendLogin\Configuration;
use Symfony\Component\Mime\Address;
use TYPO3\CMS\Core\Context\Context;
use TYPO3\CMS\Core\Crypto\HashAlgo;
use TYPO3\CMS\Core\Crypto\HashService;
use TYPO3\CMS\Core\Crypto\Random;
use TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface;
/**
* @internal this is a concrete TYPO3 implementation and solely used for EXT:felogin and not part of TYPO3's Core API.
*/
class RecoveryConfiguration
{
protected readonly string $forgotHash;
protected ?Address $replyTo = null;
protected Address $sender;
protected readonly array $settings;
protected string $mailTemplateName = '';
protected ?int $timestamp = null;
public function __construct(
protected readonly Context $context,
ConfigurationManagerInterface $configurationManager,
Random $random,
HashService $hashService
) {
$this->settings = $configurationManager->getConfiguration(ConfigurationManagerInterface::CONFIGURATION_TYPE_SETTINGS);
$this->forgotHash = $this->getLifeTimeTimestamp() . '|' . $this->generateHash($random, $hashService);
$this->resolveFromTypoScript();
}
/**
* Returns the forgot hash.
*/
public function getForgotHash(): string
{
return $this->forgotHash;
}
/**
* Returns email template name configured in TypoScript
*/
public function getMailTemplateName(): string
{
return $this->mailTemplateName;
}
/**
* Returns TTL timestamp of the forgot hash
*/
public function getLifeTimeTimestamp(): int
{
if ($this->timestamp === null) {
$lifetimeInHours = (int)($this->settings['forgotLinkHashValidTime'] ?? 0) ?: 12;
$currentTimestamp = $this->context->getPropertyFromAspect('date', 'timestamp');
$this->timestamp = $currentTimestamp + 3600 * $lifetimeInHours;
}
return $this->timestamp;
}
/**
* Returns reply-to address if configured otherwise null.
*/
public function getReplyTo(): ?Address
{
return $this->replyTo;
}
/**
* Returns the sender. Normally the current typo3 installation.
*/
public function getSender(): Address
{
return $this->sender;
}
protected function generateHash(Random $random, HashService $hashService): string
{
$randomString = $random->generateRandomHexString(16);
return $hashService->hmac($randomString, self::class, HashAlgo::SHA3_256);
}
protected function resolveFromTypoScript(): void
{
$fromAddress = ($this->settings['email_from'] ?? null) ?: $GLOBALS['TYPO3_CONF_VARS']['MAIL']['defaultMailFromAddress'];
if (empty($fromAddress)) {
throw new IncompleteConfigurationException(
'Either "$GLOBALS[\'TYPO3_CONF_VARS\'][\'MAIL\'][\'defaultMailFromAddress\']" or extension key "plugin.tx_felogin_login.settings.email_from" cannot be empty!',
1573825624
);
}
$fromName = ($this->settings['email_fromName'] ?? null) ?: $GLOBALS['TYPO3_CONF_VARS']['MAIL']['defaultMailFromName'];
if (empty($fromName)) {
throw new IncompleteConfigurationException(
'Either "$GLOBALS[\'TYPO3_CONF_VARS\'][\'MAIL\'][\'defaultMailFromName\']" or extension key "plugin.tx_felogin_login.settings.email_fromName" cannot be empty!',
1573825625
);
}
$this->sender = new Address($fromAddress, $fromName);
if (!empty($GLOBALS['TYPO3_CONF_VARS']['MAIL']['defaultMailReplyToAddress'])) {
if ($GLOBALS['TYPO3_CONF_VARS']['MAIL']['defaultMailReplyToName']) {
$this->replyTo = new Address(
$GLOBALS['TYPO3_CONF_VARS']['MAIL']['defaultMailReplyToAddress'],
$GLOBALS['TYPO3_CONF_VARS']['MAIL']['defaultMailReplyToName']
);
} else {
$this->replyTo = new Address(
$GLOBALS['TYPO3_CONF_VARS']['MAIL']['defaultMailReplyToAddress']
);
}
}
$this->mailTemplateName = (string)($this->settings['email']['templateName'] ?? '');
if (empty($this->mailTemplateName)) {
throw new IncompleteConfigurationException(
'Key "plugin.tx_felogin_login.settings.email.templateName" cannot be empty! Ensure that TypoScript is properly included.',
1584998393
);
}
}
}
@@ -0,0 +1,86 @@
<?php
declare(strict_types=1);
/*
* This file is part of the TYPO3 CMS project.
*
* It is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, either version 2
* of the License, or any later version.
*
* For the full copyright and license information, please read the
* LICENSE.txt file that was distributed with this source code.
*
* The TYPO3 project - inspiring people to share!
*/
namespace TYPO3\CMS\FrontendLogin\Configuration;
use TYPO3\CMS\Core\Utility\GeneralUtility;
/**
* A class that holds and manages all states relevant for handling redirects
*
* @internal this is a concrete TYPO3 implementation and solely used for EXT:felogin and not part of TYPO3's Core API.
*/
class RedirectConfiguration
{
protected array $modes;
public function __construct(
array|string|null $mode,
protected string $firstMode,
protected int $pageOnLogin,
protected string $domains,
protected int $pageOnLoginError,
protected int $pageOnLogout
) {
$this->modes = is_array($mode) ? $mode : GeneralUtility::trimExplode(',', $mode ?? '', true);
}
public function getModes(): array
{
return $this->modes;
}
public function getFirstMode(): string
{
return $this->firstMode;
}
public function getPageOnLogin(): int
{
return $this->pageOnLogin;
}
public function getDomains(): string
{
return $this->domains;
}
public function getPageOnLoginError(): int
{
return $this->pageOnLoginError;
}
public function getPageOnLogout(): int
{
return $this->pageOnLogout;
}
/**
* Factory when creating a configuration out of Extbase / plugin settings.
*/
public static function fromSettings(array $settings): self
{
return new RedirectConfiguration(
($settings['redirectMode'] ?? ''),
(string)($settings['redirectFirstMethod'] ?? ''),
(int)($settings['redirectPageLogin'] ?? 0),
(string)($settings['domains'] ?? ''),
(int)($settings['redirectPageLoginError'] ?? 0),
(int)($settings['redirectPageLogout'] ?? 0)
);
}
}