‪TYPO3CMS  ‪main
RedirectHandler.php
Go to the documentation of this file.
1 <?php
2 
3 declare(strict_types=1);
4 
5 /*
6  * This file is part of the TYPO3 CMS project.
7  *
8  * It is free software; you can redistribute it and/or modify it under
9  * the terms of the GNU General Public License, either version 2
10  * of the License, or any later version.
11  *
12  * For the full copyright and license information, please read the
13  * LICENSE.txt file that was distributed with this source code.
14  *
15  * The TYPO3 project - inspiring people to share!
16  */
17 
19 
26 
33 {
34  protected bool ‪$userIsLoggedIn = false;
35 
36  public function ‪__construct(
37  protected ‪RedirectModeHandler $redirectModeHandler,
38  protected ‪RedirectUrlValidator $redirectUrlValidator,
39  ‪Context $context
40  ) {
41  $this->userIsLoggedIn = (bool)$context->‪getPropertyFromAspect('frontend.user', 'isLoggedIn');
42  }
43 
47  public function ‪processRedirect(‪RequestInterface $request, string $loginType, ‪RedirectConfiguration $configuration, string $redirectModeReferrer): string
48  {
49  if ($this->‪isUserLoginFailedAndLoginErrorActive($configuration->‪getModes(), $loginType)) {
50  return $this->redirectModeHandler->redirectModeLoginError($request, $configuration->‪getPageOnLoginError());
51  }
52 
53  $redirectUrlList = [];
54  foreach ($configuration->‪getModes() as $redirectMode) {
55  $redirectUrl = '';
56 
57  $type = ‪LoginType::tryFrom($loginType);
58  if ($type === LoginType::LOGIN) {
59  $redirectUrl = $this->‪handleSuccessfulLogin($request, $redirectMode, $configuration->‪getPageOnLogin(), $configuration->‪getDomains(), $redirectModeReferrer);
60  } elseif ($type === ‪LoginType::LOGOUT) {
61  $redirectUrl = $this->‪handleSuccessfulLogout($request, $redirectMode, $configuration->‪getPageOnLogout());
62  }
63 
64  if ($redirectUrl !== '') {
65  $redirectUrlList[] = $redirectUrl;
66  }
67  }
68 
69  return $this->‪fetchReturnUrlFromList($redirectUrlList, $configuration->‪getFirstMode());
70  }
71 
75  protected function ‪getLogoutRedirectUrl(‪RequestInterface $request, array $redirectModes, int $redirectPageLogout = 0): string
76  {
77  if ($this->userIsLoggedIn && $this->‪isRedirectModeActive($redirectModes, ‪RedirectMode::LOGOUT)) {
78  return $this->redirectModeHandler->redirectModeLogout($request, $redirectPageLogout);
79  }
80  return $this->‪getGetpostRedirectUrl($request, $redirectModes);
81  }
82 
86  protected function ‪getGetpostRedirectUrl(‪RequestInterface $request, array $redirectModes): string
87  {
88  return $this->‪isRedirectModeActive($redirectModes, ‪RedirectMode::GETPOST)
89  ? $this->‪getRedirectUrlRequestParam($request)
90  : '';
91  }
92 
96  protected function ‪handleSuccessfulLogout(‪RequestInterface $request, string $redirectMode, int $redirectPageLogout): string
97  {
98  if ($redirectMode === ‪RedirectMode::LOGOUT) {
99  return $this->redirectModeHandler->redirectModeLogout($request, $redirectPageLogout);
100  }
101  return '';
102  }
103 
107  protected function ‪fetchReturnUrlFromList(array $redirectUrlList, string $redirectFirstMethod): string
108  {
109  if (count($redirectUrlList) === 0) {
110  return '';
111  }
112 
113  // Remove empty values, but keep "0" as value (that's why "strlen" is used as second parameter)
114  $redirectUrlList = array_filter($redirectUrlList, static function (string $value): bool {
115  return strlen($value) > 0;
116  });
117 
118  return $redirectFirstMethod
119  ? array_shift($redirectUrlList)
120  : array_pop($redirectUrlList);
121  }
122 
126  protected function ‪handleSuccessfulLogin(‪RequestInterface $request, string $redirectMode, int $redirectPageLogin = 0, string $domains = '', string $redirectModeReferrer = ''): string
127  {
128  if (!$this->userIsLoggedIn) {
129  return '';
130  }
131 
132  // Logintype is needed because the login-page wouldn't be accessible anymore after a login (would always redirect)
133  switch ($redirectMode) {
135  $redirectUrl = $this->redirectModeHandler->redirectModeGroupLogin($request);
136  break;
138  $redirectUrl = $this->redirectModeHandler->redirectModeUserLogin($request);
139  break;
141  $redirectUrl = $this->redirectModeHandler->redirectModeLogin($request, $redirectPageLogin);
142  break;
144  $redirectUrl = $this->‪getRedirectUrlRequestParam($request);
145  break;
147  $redirectUrl = $this->redirectModeHandler->redirectModeReferrer($request, $redirectModeReferrer);
148  break;
150  $redirectUrl = $this->redirectModeHandler->redirectModeReferrerDomains($request, $domains, $redirectModeReferrer);
151  break;
152  default:
153  $redirectUrl = '';
154  }
155 
156  return $redirectUrl;
157  }
158 
159  protected function ‪isUserLoginFailedAndLoginErrorActive(array $redirectModes, string $loginType): bool
160  {
161  return ‪LoginType::tryFrom($loginType) === LoginType::LOGIN
162  && !$this->userIsLoggedIn
163  && $this->‪isRedirectModeActive($redirectModes, ‪RedirectMode::LOGIN_ERROR);
164  }
165 
166  protected function ‪isRedirectModeActive(array $redirectModes, string $mode): bool
167  {
168  return in_array($mode, $redirectModes, true);
169  }
170 
174  public function ‪getLoginFormRedirectUrl(
175  ‪RequestInterface $request,
176  ‪RedirectConfiguration $configuration,
177  bool $redirectDisabled
178  ): string {
179  if (!$redirectDisabled) {
180  return $this->‪getGetpostRedirectUrl($request, $configuration->‪getModes());
181  }
182  return '';
183  }
184 
196  public function ‪getReferrerForLoginForm(‪RequestInterface $request, array $settings): string
197  {
198  // Early return, if redirectMode is not configured to respect the referrer
199  if (!$this->‪isReferrerRedirectEnabled($settings)) {
200  return '';
201  }
202 
203  // Early return, if redirectReferrer is not enabled in current context (e.g., after a password reset)
204  if (($request->getQueryParams()['tx_felogin_login']['redirectReferrer'] ?? '') === 'off') {
205  return '';
206  }
207 
208  $referrer = (string)(
209  $request->getParsedBody()['referer'] ??
210  $request->getQueryParams()['referer'] ??
211  $request->getServerParams()['HTTP_REFERER'] ??
212  ''
213  );
214 
215  // If the current request was initiated via sub-request, we use the URI of the original request as referrer
216  if ($originalRequest = $request->getAttribute('originalRequest', false)) {
217  $referrer = (string)$originalRequest->getUri();
218  }
219 
220  if ($this->redirectUrlValidator->isValid($request, $referrer)) {
221  return $referrer;
222  }
223 
224  return '';
225  }
226 
230  protected function ‪isReferrerRedirectEnabled(array $settings): bool
231  {
233  $configuredRedirectModes = ‪GeneralUtility::trimExplode(',', $settings['redirectMode'] ?? '');
234  return count(array_intersect($configuredRedirectModes, $referrerRedirectModes)) > 0;
235  }
236 
241  ‪RequestInterface $request,
242  ‪RedirectConfiguration $configuration,
243  int $redirectPageLogout,
244  bool $redirectDisabled
245  ): string {
246  if (!$redirectDisabled) {
247  return $this->‪getLogoutRedirectUrl($request, $configuration->‪getModes(), $redirectPageLogout);
248  }
249  return $this->‪getRedirectUrlRequestParam($request);
250  }
251 
255  private function ‪getRedirectUrlRequestParam(‪RequestInterface $request): string
256  {
257  // If config.typolinkLinkAccessRestrictedPages is set, the var is return_url
258  $returnUrlFromRequest = (string)($request->getParsedBody()['return_url'] ?? $request->getQueryParams()['return_url'] ?? null);
259  $redirectUrlFromRequest = (string)($request->getParsedBody()['redirect_url'] ?? $request->getQueryParams()['redirect_url'] ?? null);
260  $redirectUrl = $returnUrlFromRequest ?: $redirectUrlFromRequest;
261 
262  return $this->redirectUrlValidator->isValid($request, $redirectUrl) ? $redirectUrl : '';
263  }
264 }
‪TYPO3\CMS\FrontendLogin\Redirect\RedirectHandler\isReferrerRedirectEnabled
‪isReferrerRedirectEnabled(array $settings)
Definition: RedirectHandler.php:230
‪TYPO3\CMS\FrontendLogin\Redirect\RedirectModeHandler
Definition: RedirectModeHandler.php:33
‪TYPO3\CMS\FrontendLogin\Redirect\RedirectMode\REFERRER
‪const REFERRER
Definition: RedirectMode.php:33
‪TYPO3\CMS\FrontendLogin\Redirect\RedirectHandler\fetchReturnUrlFromList
‪fetchReturnUrlFromList(array $redirectUrlList, string $redirectFirstMethod)
Definition: RedirectHandler.php:107
‪TYPO3\CMS\Core\Authentication\LOGOUT
‪@ LOGOUT
Definition: LoginType.php:26
‪TYPO3\CMS\FrontendLogin\Configuration\RedirectConfiguration\getFirstMode
‪getFirstMode()
Definition: RedirectConfiguration.php:47
‪TYPO3\CMS\FrontendLogin\Redirect\RedirectHandler\getLogoutFormRedirectUrl
‪getLogoutFormRedirectUrl(RequestInterface $request, RedirectConfiguration $configuration, int $redirectPageLogout, bool $redirectDisabled)
Definition: RedirectHandler.php:240
‪TYPO3\CMS\FrontendLogin\Redirect\RedirectHandler\processRedirect
‪processRedirect(RequestInterface $request, string $loginType, RedirectConfiguration $configuration, string $redirectModeReferrer)
Definition: RedirectHandler.php:47
‪TYPO3\CMS\FrontendLogin\Redirect\RedirectMode\GETPOST
‪const GETPOST
Definition: RedirectMode.php:30
‪TYPO3\CMS\FrontendLogin\Configuration\RedirectConfiguration\getPageOnLoginError
‪getPageOnLoginError()
Definition: RedirectConfiguration.php:62
‪TYPO3\CMS\FrontendLogin\Configuration\RedirectConfiguration\getDomains
‪getDomains()
Definition: RedirectConfiguration.php:57
‪TYPO3\CMS\FrontendLogin\Redirect\RedirectHandler\isUserLoginFailedAndLoginErrorActive
‪isUserLoginFailedAndLoginErrorActive(array $redirectModes, string $loginType)
Definition: RedirectHandler.php:159
‪TYPO3\CMS\Core\Context\Context
Definition: Context.php:54
‪TYPO3\CMS\Frontend\Content\tryFrom
‪@ tryFrom
Definition: ContentSlideMode.php:27
‪TYPO3\CMS\FrontendLogin\Redirect\RedirectMode\GROUP_LOGIN
‪const GROUP_LOGIN
Definition: RedirectMode.php:32
‪TYPO3\CMS\FrontendLogin\Redirect\RedirectHandler\handleSuccessfulLogout
‪handleSuccessfulLogout(RequestInterface $request, string $redirectMode, int $redirectPageLogout)
Definition: RedirectHandler.php:96
‪TYPO3\CMS\FrontendLogin\Redirect\RedirectHandler\getGetpostRedirectUrl
‪getGetpostRedirectUrl(RequestInterface $request, array $redirectModes)
Definition: RedirectHandler.php:86
‪TYPO3\CMS\FrontendLogin\Redirect\RedirectHandler\isRedirectModeActive
‪isRedirectModeActive(array $redirectModes, string $mode)
Definition: RedirectHandler.php:166
‪TYPO3\CMS\FrontendLogin\Configuration\RedirectConfiguration\getModes
‪getModes()
Definition: RedirectConfiguration.php:42
‪TYPO3\CMS\Core\Context\Context\getPropertyFromAspect
‪getPropertyFromAspect(string $name, string $property, mixed $default=null)
Definition: Context.php:116
‪TYPO3\CMS\FrontendLogin\Redirect\RedirectHandler\getRedirectUrlRequestParam
‪getRedirectUrlRequestParam(RequestInterface $request)
Definition: RedirectHandler.php:255
‪TYPO3\CMS\FrontendLogin\Redirect\RedirectMode\USER_LOGIN
‪const USER_LOGIN
Definition: RedirectMode.php:31
‪TYPO3\CMS\Core\Authentication\LoginType
‪LoginType
Definition: LoginType.php:24
‪TYPO3\CMS\FrontendLogin\Redirect\RedirectHandler\__construct
‪__construct(protected RedirectModeHandler $redirectModeHandler, protected RedirectUrlValidator $redirectUrlValidator, Context $context)
Definition: RedirectHandler.php:36
‪TYPO3\CMS\FrontendLogin\Redirect
Definition: RedirectHandler.php:18
‪TYPO3\CMS\FrontendLogin\Redirect\RedirectMode\LOGOUT
‪const LOGOUT
Definition: RedirectMode.php:28
‪TYPO3\CMS\FrontendLogin\Redirect\RedirectMode\LOGIN
‪const LOGIN
Definition: RedirectMode.php:27
‪TYPO3\CMS\FrontendLogin\Redirect\RedirectMode\LOGIN_ERROR
‪const LOGIN_ERROR
Definition: RedirectMode.php:29
‪TYPO3\CMS\Extbase\Mvc\RequestInterface
Definition: RequestInterface.php:24
‪TYPO3\CMS\FrontendLogin\Redirect\RedirectHandler\getReferrerForLoginForm
‪getReferrerForLoginForm(RequestInterface $request, array $settings)
Definition: RedirectHandler.php:196
‪TYPO3\CMS\FrontendLogin\Redirect\RedirectHandler\getLoginFormRedirectUrl
‪getLoginFormRedirectUrl(RequestInterface $request, RedirectConfiguration $configuration, bool $redirectDisabled)
Definition: RedirectHandler.php:174
‪TYPO3\CMS\FrontendLogin\Configuration\RedirectConfiguration
Definition: RedirectConfiguration.php:28
‪TYPO3\CMS\FrontendLogin\Redirect\RedirectMode\REFERRER_DOMAINS
‪const REFERRER_DOMAINS
Definition: RedirectMode.php:34
‪TYPO3\CMS\FrontendLogin\Configuration\RedirectConfiguration\getPageOnLogout
‪getPageOnLogout()
Definition: RedirectConfiguration.php:67
‪TYPO3\CMS\FrontendLogin\Validation\RedirectUrlValidator
Definition: RedirectUrlValidator.php:35
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:52
‪TYPO3\CMS\FrontendLogin\Redirect\RedirectHandler\getLogoutRedirectUrl
‪getLogoutRedirectUrl(RequestInterface $request, array $redirectModes, int $redirectPageLogout=0)
Definition: RedirectHandler.php:75
‪TYPO3\CMS\FrontendLogin\Redirect\RedirectHandler
Definition: RedirectHandler.php:33
‪TYPO3\CMS\Core\Utility\GeneralUtility\trimExplode
‪static list< string > trimExplode(string $delim, string $string, bool $removeEmptyValues=false, int $limit=0)
Definition: GeneralUtility.php:822
‪TYPO3\CMS\FrontendLogin\Redirect\RedirectHandler\handleSuccessfulLogin
‪handleSuccessfulLogin(RequestInterface $request, string $redirectMode, int $redirectPageLogin=0, string $domains='', string $redirectModeReferrer='')
Definition: RedirectHandler.php:126
‪TYPO3\CMS\FrontendLogin\Configuration\RedirectConfiguration\getPageOnLogin
‪getPageOnLogin()
Definition: RedirectConfiguration.php:52
‪TYPO3\CMS\FrontendLogin\Redirect\RedirectHandler\$userIsLoggedIn
‪bool $userIsLoggedIn
Definition: RedirectHandler.php:34