‪TYPO3CMS  9.5
FrontendLoginController.php
Go to the documentation of this file.
1 <?php
3 
4 /*
5  * This file is part of the TYPO3 CMS project.
6  *
7  * It is free software; you can redistribute it and/or modify it under
8  * the terms of the GNU General Public License, either version 2
9  * of the License, or any later version.
10  *
11  * For the full copyright and license information, please read the
12  * LICENSE.txt file that was distributed with this source code.
13  *
14  * The TYPO3 project - inspiring people to share!
15  */
16 
17 use Psr\Log\LoggerAwareInterface;
18 use Psr\Log\LoggerAwareTrait;
31 
37 class ‪FrontendLoginController extends ‪AbstractPlugin implements LoggerAwareInterface
38 {
39  use LoggerAwareTrait;
40 
46  public ‪$prefixId = 'tx_felogin_pi1';
47 
53  public ‪$extKey = 'felogin';
54 
58  public ‪$pi_checkCHash = false;
59 
63  public ‪$pi_USER_INT_obj = true;
64 
70  protected ‪$userIsLoggedIn;
71 
77  protected ‪$template;
78 
84  protected ‪$redirectUrl;
85 
91  protected ‪$noRedirect = false;
92 
98  protected ‪$logintype;
99 
101  protected ‪$siteFinder;
102 
108  public ‪$spid;
109 
115  public ‪$referer;
116 
125  public function ‪main($content, ‪$conf)
126  {
127  $this->siteFinder = GeneralUtility::makeInstance(SiteFinder::class);
128 
129  // Loading TypoScript array into object variable:
130  $this->conf = ‪$conf;
131  // Loading default pivars
132  $this->‪pi_setPiVarDefaults();
133  // Loading language-labels
134  $this->‪pi_loadLL('EXT:felogin/Resources/Private/Language/locallang.xlf');
135  // Init FlexForm configuration for plugin:
136  $this->‪pi_initPIflexForm();
138  // Get storage PIDs:
139  if ((bool)(‪$GLOBALS['TYPO3_CONF_VARS']['FE']['checkFeUserPid'] ?? false) === false) {
140  $this->spid = 0;
141  } elseif ($this->conf['storagePid']) {
142  if ((int)$this->conf['recursive']) {
143  $this->spid = $this->‪pi_getPidList($this->conf['storagePid'], (int)$this->conf['recursive']);
144  } else {
145  $this->spid = $this->conf['storagePid'];
146  }
147  } else {
148  throw new \RuntimeException('No storage folder (option storagePid) for frontend users given.', 1450904202);
149  }
150  // GPvars:
151  $this->logintype = GeneralUtility::_GP('logintype');
152  $this->referer = $this->‪validateRedirectUrl(GeneralUtility::_GP('referer'));
153  $this->noRedirect = $this->piVars['noredirect'] || $this->conf['redirectDisable'];
154  // If config.typolinkLinkAccessRestrictedPages is set, the var is return_url
155  $returnUrl = GeneralUtility::_GP('return_url');
156  if ($returnUrl) {
157  $this->redirectUrl = $returnUrl;
158  } else {
159  $this->redirectUrl = GeneralUtility::_GP('redirect_url');
160  }
161  $this->redirectUrl = $this->‪validateRedirectUrl($this->redirectUrl);
162  // Get Template
163  $templateFile = $this->conf['templateFile'] ?: 'EXT:felogin/Resources/Private/Templates/FrontendLogin.html';
164  ‪$template = GeneralUtility::getFileAbsFileName($templateFile);
165  if (‪$template !== '' && file_exists(‪$template)) {
166  $this->template = file_get_contents(‪$template);
167  }
168  // Is user logged in?
169  $this->userIsLoggedIn = GeneralUtility::makeInstance(Context::class)->getPropertyFromAspect('frontend.user', 'isLoggedIn');
170  // Redirect
171  if ($this->conf['redirectMode'] && !$this->conf['redirectDisable'] && !$this->noRedirect) {
173  if (!empty(‪$redirectUrl)) {
174  $this->redirectUrl = $this->conf['redirectFirstMethod'] ? array_shift(‪$redirectUrl) : array_pop(‪$redirectUrl);
175  } else {
176  $this->redirectUrl = '';
177  }
178  }
179  // What to display
180  $content = '';
181  if ($this->piVars['forgot'] && $this->conf['showForgotPasswordLink']) {
182  $content .= $this->‪showForgot();
183  } elseif ($this->piVars['forgothash']) {
184  $content .= $this->‪changePassword();
185  } else {
186  if ($this->userIsLoggedIn && !$this->logintype) {
187  $content .= $this->‪showLogout();
188  } else {
189  $content .= $this->‪showLogin();
190  }
191  }
192  // Process the redirect
193  if (($this->logintype === ‪LoginType::LOGIN || $this->logintype === ‪LoginType::LOGOUT) && $this->redirectUrl && !$this->noRedirect) {
194  if (!$this->frontendController->fe_user->isCookieSet() && $this->userIsLoggedIn) {
195  $content .= $this->cObj->stdWrap($this->‪pi_getLL('cookie_warning'), $this->conf['cookieWarning_stdWrap.']);
196  } else {
197  // Add hook for extra processing before redirect
198  $_params = [
199  'loginType' => ‪$this->logintype,
200  'redirectUrl' => &‪$this->redirectUrl
201  ];
202  foreach (‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['felogin']['beforeRedirect'] ?? [] as $_funcRef) {
203  if ($_funcRef) {
204  GeneralUtility::callUserFunction($_funcRef, $_params, $this);
205  }
206  }
208  }
209  }
210  // Adds hook for processing of extra item markers / special
211  foreach (‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['felogin']['postProcContent'] ?? [] as $_funcRef) {
212  $_params = [
213  'content' => $content
214  ];
215  $content = GeneralUtility::callUserFunction($_funcRef, $_params, $this);
216  }
217  return $this->conf['wrapContentInBaseClass'] ? $this->‪pi_wrapInBaseClass($content) : $content;
218  }
219 
225  protected function ‪showForgot()
226  {
227  $subpart = $this->templateService->getSubpart($this->template, '###TEMPLATE_FORGOT###');
228  $subpartArray = ($linkpartArray = []);
229  $postData = GeneralUtility::_POST($this->prefixId);
230  if ($postData['forgot_email']) {
231  // Get hashes for compare
232  $postedHash = $postData['forgot_hash'];
233  $hashData = $this->frontendController->fe_user->getKey('ses', 'forgot_hash');
234  if ($postedHash === $hashData['forgot_hash']) {
235  $userTable = $this->frontendController->fe_user->user_table;
236  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable($userTable);
237  $queryBuilder->setRestrictions(GeneralUtility::makeInstance(FrontendRestrictionContainer::class));
238  $constraints = [
239  $queryBuilder->expr()->orX(
240  $queryBuilder->expr()->eq(
241  'email',
242  $queryBuilder->createNamedParameter($this->piVars['forgot_email'], \PDO::PARAM_STR)
243  ),
244  $queryBuilder->expr()->eq(
245  'username',
246  $queryBuilder->createNamedParameter($this->piVars['forgot_email'], \PDO::PARAM_STR)
247  )
248  )
249  ];
250 
251  if ((bool)(‪$GLOBALS['TYPO3_CONF_VARS']['FE']['checkFeUserPid'] ?? false)) {
252  $constraints[] = $queryBuilder->expr()->in(
253  'pid',
254  $queryBuilder->createNamedParameter(
255  GeneralUtility::intExplode(',', $this->spid),
256  Connection::PARAM_INT_ARRAY
257  )
258  );
259  }
260 
261  $row = $queryBuilder
262  ->select('*')
263  ->from($userTable)
264  ->where(...$constraints)
265  ->execute()
266  ->fetch();
267 
268  $error = null;
269  if ($row) {
270  // Generate an email with the hashed link
271  $error = $this->‪generateAndSendHash($row);
272  } elseif ($this->conf['exposeNonexistentUserInForgotPasswordDialog']) {
273  $error = $this->‪pi_getLL('ll_forgot_reset_message_error');
274  }
275  // Generate message
276  if ($error) {
277  $markerArray['###STATUS_MESSAGE###'] = $this->cObj->stdWrap($error, $this->conf['forgotErrorMessage_stdWrap.']);
278  } else {
279  $markerArray['###STATUS_MESSAGE###'] = $this->cObj->stdWrap(
280  $this->‪pi_getLL('ll_forgot_reset_message_emailSent'),
281  $this->conf['forgotResetMessageEmailSentMessage_stdWrap.']
282  );
283  }
284  $subpartArray['###FORGOT_FORM###'] = '';
285  } else {
286  // Wrong email
287  $markerArray['###STATUS_MESSAGE###'] = $this->‪getDisplayText('forgot_reset_message', $this->conf['forgotMessage_stdWrap.']);
288  $markerArray['###BACKLINK_LOGIN###'] = '';
289  }
290  } else {
291  $markerArray['###STATUS_MESSAGE###'] = $this->‪getDisplayText('forgot_reset_message', $this->conf['forgotMessage_stdWrap.']);
292  $markerArray['###BACKLINK_LOGIN###'] = '';
293  }
294  $markerArray['###BACKLINK_LOGIN###'] = $this->‪getPageLink(htmlspecialchars($this->‪pi_getLL('ll_forgot_header_backToLogin')), []);
295  $markerArray['###STATUS_HEADER###'] = $this->‪getDisplayText('forgot_header', $this->conf['forgotHeader_stdWrap.']);
296  $markerArray['###LEGEND###'] = htmlspecialchars($this->‪pi_getLL('legend', $this->‪pi_getLL('reset_password')));
297  $markerArray['###ACTION_URI###'] = $this->‪getPageLink('', [$this->prefixId . '[forgot]' => 1], true);
298  $markerArray['###EMAIL_LABEL###'] = htmlspecialchars($this->‪pi_getLL('your_email'));
299  $markerArray['###FORGOT_PASSWORD_ENTEREMAIL###'] = htmlspecialchars($this->‪pi_getLL('forgot_password_enterEmail'));
300  $markerArray['###FORGOT_EMAIL###'] = $this->prefixId . '[forgot_email]';
301  $markerArray['###SEND_PASSWORD###'] = htmlspecialchars($this->‪pi_getLL('reset_password'));
302  $markerArray['###DATA_LABEL###'] = htmlspecialchars($this->‪pi_getLL('ll_enter_your_data'));
303  $markerArray = array_merge($markerArray, $this->‪getUserFieldMarkers());
304  // Generate hash
305  $hash = md5($this->‪generatePassword(3));
306  $markerArray['###FORGOTHASH###'] = $hash;
307  // Set hash in feuser session
308  $this->frontendController->fe_user->setKey('ses', 'forgot_hash', ['forgot_hash' => $hash]);
309  return $this->templateService->substituteMarkerArrayCached($subpart, $markerArray, $subpartArray, $linkpartArray);
310  }
311 
318  protected function ‪changePassword()
319  {
320  $subpartArray = ($linkpartArray = []);
321  $done = false;
322  $minLength = (int)$this->conf['newPasswordMinLength'] ?: 6;
323  $subpart = $this->templateService->getSubpart($this->template, '###TEMPLATE_CHANGEPASSWORD###');
324  $markerArray['###STATUS_HEADER###'] = $this->‪getDisplayText('change_password_header', $this->conf['changePasswordHeader_stdWrap.']);
325  $markerArray['###STATUS_MESSAGE###'] = sprintf($this->‪getDisplayText(
326  'change_password_message',
327  $this->conf['changePasswordMessage_stdWrap.']
328  ), $minLength);
329 
330  $markerArray['###BACKLINK_LOGIN###'] = '';
331  $uid = $this->piVars['user'];
332  $piHash = $this->piVars['forgothash'];
333  $hash = explode('|', rawurldecode($piHash));
334  if ((int)$uid === 0) {
335  $markerArray['###STATUS_MESSAGE###'] = $this->‪getDisplayText(
336  'change_password_notvalid_message',
337  $this->conf['changePasswordNotValidMessage_stdWrap.']
338  );
339  $subpartArray['###CHANGEPASSWORD_FORM###'] = '';
340  } else {
341  $user = $this->‪pi_getRecord('fe_users', (int)$uid);
342  $userHash = $user['felogin_forgotHash'];
343  $compareHash = explode('|', $userHash);
344  if (!$compareHash || !$compareHash[1] || $compareHash[0] < time() || !hash_equals($compareHash[0], $hash[0])) {
345  $hashEquals = false;
346  } elseif (strlen($compareHash[1]) === 40) {
347  $hashEquals = hash_equals($compareHash[1], GeneralUtility::hmac((string)$hash[1]));
348  } else {
349  // backward-compatibility for previous MD5 hashes
350  $hashEquals = hash_equals($compareHash[1], md5($hash[1]));
351  }
352  if (!$hashEquals) {
353  $markerArray['###STATUS_MESSAGE###'] = $this->‪getDisplayText(
354  'change_password_notvalid_message',
355  $this->conf['changePasswordNotValidMessage_stdWrap.']
356  );
357  $subpartArray['###CHANGEPASSWORD_FORM###'] = '';
358  } else {
359  // All is fine, continue with new password
360  $postData = GeneralUtility::_POST($this->prefixId);
361  if (isset($postData['changepasswordsubmit'])) {
362  if (strlen($postData['password1']) < $minLength) {
363  $markerArray['###STATUS_MESSAGE###'] = sprintf(
364  $this->‪getDisplayText(
365  'change_password_tooshort_message',
366  $this->conf['changePasswordTooShortMessage_stdWrap.']
367  ),
368  $minLength
369  );
370  } elseif ($postData['password1'] != $postData['password2']) {
371  $markerArray['###STATUS_MESSAGE###'] = sprintf(
372  $this->‪getDisplayText(
373  'change_password_notequal_message',
374  $this->conf['changePasswordNotEqualMessage_stdWrap.']
375  ),
376  $minLength
377  );
378  } else {
379  // Hash password using configured salted passwords hash mechanism for FE
380  $hashInstance = GeneralUtility::makeInstance(PasswordHashFactory::class)->getDefaultHashInstance('FE');
381  $newPass = $hashInstance->getHashedPassword($postData['password1']);
382 
383  // Call a hook for further password processing
384  if (‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['felogin']['password_changed']) {
385  $_params = [
386  'user' => $user,
387  'newPassword' => $newPass,
388  'newPasswordUnencrypted' => $postData['password1']
389  ];
390  foreach (‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['felogin']['password_changed'] as $_funcRef) {
391  if ($_funcRef) {
392  GeneralUtility::callUserFunction($_funcRef, $_params, $this);
393  }
394  }
395  $newPass = $_params['newPassword'];
396  }
397 
398  // Save new password and clear DB-hash
399  $userTable = $this->frontendController->fe_user->user_table;
400  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable($userTable);
401  $queryBuilder->getRestrictions()->removeAll();
402  $queryBuilder->update($userTable)
403  ->set('password', $newPass)
404  ->set('felogin_forgotHash', '')
405  ->set('tstamp', (int)‪$GLOBALS['EXEC_TIME'])
406  ->where(
407  $queryBuilder->expr()->eq(
408  'uid',
409  $queryBuilder->createNamedParameter($user['uid'], \PDO::PARAM_INT)
410  )
411  )
412  ->execute();
413  $this->‪invalidateUserSessions((int)$user['uid']);
414 
415  $markerArray['###STATUS_MESSAGE###'] = $this->‪getDisplayText(
416  'change_password_done_message',
417  $this->conf['changePasswordDoneMessage_stdWrap.']
418  );
419  $done = true;
420  $subpartArray['###CHANGEPASSWORD_FORM###'] = '';
421  $markerArray['###BACKLINK_LOGIN###'] = $this->‪getPageLink(
422  htmlspecialchars($this->‪pi_getLL('ll_forgot_header_backToLogin')),
423  [$this->prefixId . '[redirectReferrer]' => 'off']
424  );
425  }
426  }
427  if (!$done) {
428  // Change password form
429  $markerArray['###ACTION_URI###'] = $this->‪getPageLink('', [
430  $this->prefixId . '[user]' => $user['uid'],
431  $this->prefixId . '[forgothash]' => $piHash
432  ], true);
433  $markerArray['###LEGEND###'] = htmlspecialchars($this->‪pi_getLL('change_password'));
434  $markerArray['###NEWPASSWORD1_LABEL###'] = htmlspecialchars($this->‪pi_getLL('newpassword_label1'));
435  $markerArray['###NEWPASSWORD2_LABEL###'] = htmlspecialchars($this->‪pi_getLL('newpassword_label2'));
436  $markerArray['###NEWPASSWORD1###'] = $this->prefixId . '[password1]';
437  $markerArray['###NEWPASSWORD2###'] = $this->prefixId . '[password2]';
438  $markerArray['###STORAGE_PID###'] = ‪$this->spid;
439  $markerArray['###SEND_PASSWORD###'] = htmlspecialchars($this->‪pi_getLL('change_password'));
440  $markerArray['###FORGOTHASH###'] = $piHash;
441  }
442  }
443  }
444  return $this->templateService->substituteMarkerArrayCached($subpart, $markerArray, $subpartArray, $linkpartArray);
445  }
446 
453  protected function ‪generateAndSendHash($user)
454  {
455  $hours = (int)$this->conf['forgotLinkHashValidTime'] > 0 ? (int)$this->conf['forgotLinkHashValidTime'] : 24;
456  $validEnd = time() + 3600 * $hours;
457  $validEndString = date($this->conf['dateFormat'], $validEnd);
458  $hash = md5(GeneralUtility::makeInstance(Random::class)->generateRandomBytes(64));
459  $randHash = $validEnd . '|' . $hash;
460  $randHashDB = $validEnd . '|' . GeneralUtility::hmac($hash);
461 
462  // Write hash to DB
463  $userTable = $this->frontendController->fe_user->user_table;
464  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable($userTable);
465  $queryBuilder->getRestrictions()->removeAll();
466  $queryBuilder->update($userTable)
467  ->set('felogin_forgotHash', $randHashDB)
468  ->where(
469  $queryBuilder->expr()->eq(
470  'uid',
471  $queryBuilder->createNamedParameter($user['uid'], \PDO::PARAM_INT)
472  )
473  )
474  ->execute();
475 
476  // Send hashlink to user
477  $this->conf['linkPrefix'] = -1;
478  $isAbsRefPrefix = !empty($this->frontendController->absRefPrefix);
479  $isBaseURL = !empty($this->frontendController->baseUrl);
480  $isFeloginBaseURL = !empty($this->conf['feloginBaseURL']);
481  $link = $this->‪pi_getPageLink($this->frontendController->id, '', [
482  $this->prefixId . '[user]' => $user['uid'],
483  $this->prefixId . '[forgothash]' => $randHash
484  ]);
485  // Prefix link if necessary
486  if ($isFeloginBaseURL) {
487  // First priority, use specific base URL
488  // "absRefPrefix" must be removed first, otherwise URL will be prepended twice
489  if ($isAbsRefPrefix) {
490  $link = substr($link, strlen($this->frontendController->absRefPrefix));
491  }
492  $link = $this->conf['feloginBaseURL'] . $link;
493  } elseif ($isAbsRefPrefix) {
494  // Second priority
495  // absRefPrefix must not necessarily contain a hostname and URL scheme, so add it if needed
496  $link = GeneralUtility::locationHeaderUrl($link);
497  } elseif ($isBaseURL) {
498  // Third priority
499  // Add the global base URL to the link
500  $link = $this->frontendController->baseUrlWrap($link);
501  } else {
502  // No prefix is set, return the error
503  return $this->‪pi_getLL('ll_change_password_nolinkprefix_message');
504  }
505  $msg = sprintf($this->‪pi_getLL('ll_forgot_validate_reset_password'), $user['username'], $link, $validEndString);
506  // Add hook for extra processing of mail message
507  $params = [
508  'message' => &$msg,
509  'user' => &$user
510  ];
511  foreach (‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['felogin']['forgotPasswordMail'] ?? [] as $reference) {
512  if ($reference) {
513  GeneralUtility::callUserFunction($reference, $params, $this);
514  }
515  }
516  if ($user['email']) {
517  $this->cObj->sendNotifyEmail($msg, $user['email'], '', $this->conf['email_from'], $this->conf['email_fromName'], $this->conf['replyTo']);
518  }
519 
520  return '';
521  }
522 
528  protected function ‪showLogout()
529  {
530  $subpart = $this->templateService->getSubpart($this->template, '###TEMPLATE_LOGOUT###');
531  $subpartArray = ($linkpartArray = []);
532  $markerArray['###STATUS_HEADER###'] = $this->‪getDisplayText('status_header', $this->conf['logoutHeader_stdWrap.']);
533  $markerArray['###STATUS_MESSAGE###'] = $this->‪getDisplayText('status_message', $this->conf['logoutMessage_stdWrap.']);
534  $this->cObj->stdWrap($this->‪flexFormValue('message', 's_status'), $this->conf['logoutMessage_stdWrap.']);
535  $markerArray['###LEGEND###'] = htmlspecialchars($this->‪pi_getLL('logout'));
536  $markerArray['###ACTION_URI###'] = $this->‪getPageLink('', [], true);
537  $markerArray['###LOGOUT_LABEL###'] = htmlspecialchars($this->‪pi_getLL('logout'));
538  $markerArray['###NAME###'] = htmlspecialchars($this->frontendController->fe_user->user['name']);
539  $markerArray['###STORAGE_PID###'] = ‪$this->spid;
540  $markerArray['###USERNAME###'] = htmlspecialchars($this->frontendController->fe_user->user['username']);
541  $markerArray['###USERNAME_LABEL###'] = htmlspecialchars($this->‪pi_getLL('username'));
542  $markerArray['###NOREDIRECT###'] = $this->noRedirect ? '1' : '0';
543  $markerArray['###PREFIXID###'] = ‪$this->prefixId;
544  $markerArray = array_merge($markerArray, $this->‪getUserFieldMarkers());
545  if ($this->redirectUrl) {
546  // Use redirectUrl for action tag because of possible access restricted pages
547  $markerArray['###ACTION_URI###'] = htmlspecialchars($this->redirectUrl);
548  $this->redirectUrl = '';
549  }
550  return $this->templateService->substituteMarkerArrayCached($subpart, $markerArray, $subpartArray, $linkpartArray);
551  }
552 
558  protected function ‪showLogin()
559  {
560  $subpart = $this->templateService->getSubpart($this->template, '###TEMPLATE_LOGIN###');
561  $subpartArray = ($linkpartArray = ($markerArray = []));
562  $gpRedirectUrl = '';
563  $markerArray['###LEGEND###'] = htmlspecialchars($this->‪pi_getLL('oLabel_header_welcome'));
564  if ($this->logintype === ‪LoginType::LOGIN) {
565  if ($this->userIsLoggedIn) {
566  // login success
567  $markerArray['###STATUS_HEADER###'] = $this->‪getDisplayText('success_header', $this->conf['successHeader_stdWrap.']);
568  $markerArray['###STATUS_MESSAGE###'] = $this->‪getDisplayText('success_message', $this->conf['successMessage_stdWrap.']);
569  $markerArray = array_merge($markerArray, $this->‪getUserFieldMarkers());
570  $subpartArray['###LOGIN_FORM###'] = '';
571  // Hook for general actions after after login has been confirmed (by Thomas Danzl <thomas@danzl.org>)
572  foreach (‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['felogin']['login_confirmed'] ?? [] as $_funcRef) {
573  $_params = [];
574  if ($_funcRef) {
575  GeneralUtility::callUserFunction($_funcRef, $_params, $this);
576  }
577  }
578  // show logout form directly
579  if ($this->conf['showLogoutFormAfterLogin']) {
580  $this->redirectUrl = '';
581  return $this->‪showLogout();
582  }
583  } else {
584  // Hook for general actions on login error
585  $params = [];
586  foreach (‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['felogin']['login_error'] ?? [] as $funcRef) {
587  if ($funcRef) {
588  GeneralUtility::callUserFunction($funcRef, $params, $this);
589  }
590  }
591  // login error
592  $markerArray['###STATUS_HEADER###'] = $this->‪getDisplayText('error_header', $this->conf['errorHeader_stdWrap.']);
593  $markerArray['###STATUS_MESSAGE###'] = $this->‪getDisplayText('error_message', $this->conf['errorMessage_stdWrap.']);
594  $gpRedirectUrl = GeneralUtility::_GP('redirect_url');
595  }
596  } else {
597  if ($this->logintype === ‪LoginType::LOGOUT) {
598  // login form after logout
599  $markerArray['###STATUS_HEADER###'] = $this->‪getDisplayText('logout_header', $this->conf['logoutHeader_stdWrap.']);
600  $markerArray['###STATUS_MESSAGE###'] = $this->‪getDisplayText('logout_message', $this->conf['logoutMessage_stdWrap.']);
601  } else {
602  // login form
603  $markerArray['###STATUS_HEADER###'] = $this->‪getDisplayText('welcome_header', $this->conf['welcomeHeader_stdWrap.']);
604  $markerArray['###STATUS_MESSAGE###'] = $this->‪getDisplayText('welcome_message', $this->conf['welcomeMessage_stdWrap.']);
605  }
606  }
607 
608  // This hook allows to call User JS functions.
609  // The methods should also set the required JS functions to get included
610  $onSubmit = '';
611  $extraHidden = '';
612  $onSubmitAr = [];
613  $extraHiddenAr = [];
614  // Check for referer redirect method. if present, save referer in form field
615  if (GeneralUtility::inList($this->conf['redirectMode'], 'referer') || GeneralUtility::inList($this->conf['redirectMode'], 'refererDomains')) {
616  ‪$referer = $this->referer ? $this->referer : GeneralUtility::getIndpEnv('HTTP_REFERER');
617  if (‪$referer) {
618  $extraHiddenAr[] = '<input type="hidden" name="referer" value="' . htmlspecialchars(‪$referer) . '" />';
619  if ($this->piVars['redirectReferrer'] === 'off') {
620  $extraHiddenAr[] = '<input type="hidden" name="' . $this->prefixId . '[redirectReferrer]" value="off" />';
621  }
622  }
623  }
624  $_params = [];
625  foreach (‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['felogin']['loginFormOnSubmitFuncs'] ?? [] as $funcRef) {
626  list($onSub, $hid) = GeneralUtility::callUserFunction($funcRef, $_params, $this);
627  $onSubmitAr[] = $onSub;
628  $extraHiddenAr[] = $hid;
629  }
630  if (!empty($onSubmitAr)) {
631  $onSubmit = implode('; ', $onSubmitAr) . '; return true;';
632  }
633  if (!empty($extraHiddenAr)) {
634  $extraHidden = implode(LF, $extraHiddenAr);
635  }
636  if (!$gpRedirectUrl && $this->redirectUrl) {
637  $gpRedirectUrl = ‪$this->redirectUrl;
638  }
639  // Login form
640  $markerArray['###ACTION_URI###'] = $this->‪getPageLink('', [], true);
641  // Used by kb_md5fepw extension...
642  $markerArray['###EXTRA_HIDDEN###'] = $extraHidden;
643  $markerArray['###LEGEND###'] = htmlspecialchars($this->‪pi_getLL('login'));
644  $markerArray['###LOGIN_LABEL###'] = htmlspecialchars($this->‪pi_getLL('login'));
645  // Used by kb_md5fepw extension...
646  $markerArray['###ON_SUBMIT###'] = $onSubmit;
647  $markerArray['###PASSWORD_LABEL###'] = htmlspecialchars($this->‪pi_getLL('password'));
648  $markerArray['###STORAGE_PID###'] = ‪$this->spid;
649  $markerArray['###USERNAME_LABEL###'] = htmlspecialchars($this->‪pi_getLL('username'));
650  $markerArray['###REDIRECT_URL###'] = htmlspecialchars($gpRedirectUrl);
651  $markerArray['###NOREDIRECT###'] = $this->noRedirect ? '1' : '0';
652  $markerArray['###PREFIXID###'] = ‪$this->prefixId;
653  $markerArray = array_merge($markerArray, $this->‪getUserFieldMarkers());
654  if ($this->conf['showForgotPasswordLink']) {
655  $linkpartArray['###FORGOT_PASSWORD_LINK###'] = explode('|', $this->‪getPageLink('|', [$this->prefixId . '[forgot]' => 1]));
656  $markerArray['###FORGOT_PASSWORD###'] = htmlspecialchars($this->‪pi_getLL('ll_forgot_header'));
657  } else {
658  $subpartArray['###FORGOTP_VALID###'] = '';
659  }
660  // The permanent login checkbox should only be shown if permalogin is not deactivated (-1),
661  // not forced to be always active (2) and lifetime is greater than 0
662  $permalogin = (int)‪$GLOBALS['TYPO3_CONF_VARS']['FE']['permalogin'];
663  if (
664  $this->conf['showPermaLogin']
665  && ($permalogin === 0 || $permalogin === 1)
666  && ‪$GLOBALS['TYPO3_CONF_VARS']['FE']['lifetime'] > 0
667  ) {
668  $markerArray['###PERMALOGIN###'] = htmlspecialchars($this->‪pi_getLL('permalogin'));
669  if ($permalogin === 1) {
670  $markerArray['###PERMALOGIN_HIDDENFIELD_ATTRIBUTES###'] = 'disabled="disabled"';
671  $markerArray['###PERMALOGIN_CHECKBOX_ATTRIBUTES###'] = 'checked="checked"';
672  } else {
673  $markerArray['###PERMALOGIN_HIDDENFIELD_ATTRIBUTES###'] = '';
674  $markerArray['###PERMALOGIN_CHECKBOX_ATTRIBUTES###'] = '';
675  }
676  } else {
677  $subpartArray['###PERMALOGIN_VALID###'] = '';
678  }
679  return $this->templateService->substituteMarkerArrayCached($subpart, $markerArray, $subpartArray, $linkpartArray);
680  }
681 
687  protected function ‪processRedirect()
688  {
689  $redirect_url = [];
690  if ($this->conf['redirectMode']) {
691  $redirectMethods = GeneralUtility::trimExplode(',', $this->conf['redirectMode'], true);
692  foreach ($redirectMethods as $redirMethod) {
693  if ($this->userIsLoggedIn && $this->logintype === ‪LoginType::LOGIN) {
694  // Logintype is needed because the login-page wouldn't be accessible anymore after a login (would always redirect)
695  switch ($redirMethod) {
696  case 'groupLogin':
697  // taken from dkd_redirect_at_login written by Ingmar Schlecht; database-field changed
698  $groupData = $this->frontendController->fe_user->groupData;
699  if (!empty($groupData['uid'])) {
700 
701  // take the first group with a redirect page
702  $userGroupTable = $this->frontendController->fe_user->usergroup_table;
703  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable($userGroupTable);
704  $queryBuilder->getRestrictions()->removeAll();
705  $row = $queryBuilder
706  ->select('felogin_redirectPid')
707  ->from($userGroupTable)
708  ->where(
709  $queryBuilder->expr()->neq(
710  'felogin_redirectPid',
711  $queryBuilder->createNamedParameter('', \PDO::PARAM_STR)
712  ),
713  $queryBuilder->expr()->in(
714  'uid',
715  $queryBuilder->createNamedParameter(
716  $groupData['uid'],
717  Connection::PARAM_INT_ARRAY
718  )
719  )
720  )
721  ->execute()
722  ->fetch();
723 
724  if ($row) {
725  $redirect_url[] = $this->‪pi_getPageLink($row['felogin_redirectPid']);
726  }
727  }
728  break;
729  case 'userLogin':
730 
731  $userTable = $this->frontendController->fe_user->user_table;
732  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable($userTable);
733  $queryBuilder->getRestrictions()->removeAll();
734  $row = $queryBuilder
735  ->select('felogin_redirectPid')
736  ->from($userTable)
737  ->where(
738  $queryBuilder->expr()->neq(
739  'felogin_redirectPid',
740  $queryBuilder->createNamedParameter('', \PDO::PARAM_STR)
741  ),
742  $queryBuilder->expr()->eq(
743  $this->frontendController->fe_user->userid_column,
744  $queryBuilder->createNamedParameter(
745  $this->frontendController->fe_user->user['uid'],
746  \PDO::PARAM_INT
747  )
748  )
749  )
750  ->execute()
751  ->fetch();
752 
753  if ($row) {
754  $redirect_url[] = $this->‪pi_getPageLink($row['felogin_redirectPid']);
755  }
756 
757  break;
758  case 'login':
759  if ($this->conf['redirectPageLogin']) {
760  $redirect_url[] = $this->‪pi_getPageLink((int)$this->conf['redirectPageLogin']);
761  }
762  break;
763  case 'getpost':
764  $redirect_url[] = ‪$this->redirectUrl;
765  break;
766  case 'referer':
767  // Avoid redirect when logging in after changing password
768  if ($this->piVars['redirectReferrer'] !== 'off') {
769  // Avoid forced logout, when trying to login immediately after a logout
770  $redirect_url[] = preg_replace('/[&?]logintype=[a-z]+/', '', $this->referer);
771  }
772  break;
773  case 'refererDomains':
774  // Auto redirect.
775  // Feature to redirect to the page where the user came from (HTTP_REFERER).
776  // Allowed domains to redirect to, can be configured with plugin.tx_felogin_pi1.domains
777  // Thanks to plan2.net / Martin Kutschker for implementing this feature.
778  // also avoid redirect when logging in after changing password
779  if (isset($this->conf['domains']) && $this->conf['domains']
780  && (!isset($this->piVars['redirectReferrer']) || $this->piVars['redirectReferrer'] !== 'off')
781  ) {
782  $url = ‪$this->referer;
783  // Is referring url allowed to redirect?
784  $match = [];
785  if (preg_match('#^http://([[:alnum:]._-]+)/#', $url, $match)) {
786  $redirect_domain = $match[1];
787  $found = false;
788  foreach (GeneralUtility::trimExplode(',', $this->conf['domains'], true) as $d) {
789  if (preg_match('/(?:^|\\.)' . $d . '$/', $redirect_domain)) {
790  $found = true;
791  break;
792  }
793  }
794  if (!$found) {
795  $url = '';
796  }
797  }
798  // Avoid forced logout, when trying to login immediately after a logout
799  if ($url) {
800  $redirect_url[] = preg_replace('/[&?]logintype=[a-z]+/', '', $url);
801  }
802  }
803  break;
804  }
805  } elseif ($this->logintype === ‪LoginType::LOGIN) {
806  // after login-error
807  switch ($redirMethod) {
808  case 'loginError':
809  if ($this->conf['redirectPageLoginError']) {
810  $redirect_url[] = $this->‪pi_getPageLink((int)$this->conf['redirectPageLoginError']);
811  }
812  break;
813  }
814  } elseif ($this->logintype == '' && $redirMethod === 'login' && $this->conf['redirectPageLogin']) {
815  // If login and page not accessible
816  $this->cObj->typoLink('', [
817  'parameter' => $this->conf['redirectPageLogin'],
818  'linkAccessRestrictedPages' => true
819  ]);
820  $redirect_url[] = $this->cObj->lastTypoLinkUrl;
821  } elseif ($this->logintype == '' && $redirMethod === 'logout' && $this->conf['redirectPageLogout'] && $this->userIsLoggedIn) {
822  // If logout and page not accessible
823  $redirect_url[] = $this->‪pi_getPageLink((int)$this->conf['redirectPageLogout']);
824  } elseif ($this->logintype === ‪LoginType::LOGOUT) {
825  // after logout
826  // Hook for general actions after after logout has been confirmed
827  foreach (‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['felogin']['logout_confirmed'] ?? [] as $_funcRef) {
828  $_params = [];
829  if ($_funcRef) {
830  GeneralUtility::callUserFunction($_funcRef, $_params, $this);
831  }
832  }
833  switch ($redirMethod) {
834  case 'logout':
835  if ($this->conf['redirectPageLogout']) {
836  $redirect_url[] = $this->‪pi_getPageLink((int)$this->conf['redirectPageLogout']);
837  }
838  break;
839  }
840  } else {
841  // not logged in
842  // Placeholder for maybe future options
843  switch ($redirMethod) {
844  case 'getpost':
845  // Preserve the get/post value
846  $redirect_url[] = ‪$this->redirectUrl;
847  break;
848  }
849  }
850  }
851  }
852  // Remove empty values, but keep "0" as value (that's why "strlen" is used as second parameter)
853  if (!empty($redirect_url)) {
854  return array_filter($redirect_url, 'strlen');
855  }
856  return [];
857  }
858 
862  protected function ‪mergeflexFormValuesIntoConf()
863  {
864  $flex = [];
865  if ($this->‪flexFormValue('showForgotPassword', 'sDEF')) {
866  $flex['showForgotPasswordLink'] = $this->‪flexFormValue('showForgotPassword', 'sDEF');
867  }
868  if ($this->‪flexFormValue('showPermaLogin', 'sDEF')) {
869  $flex['showPermaLogin'] = $this->‪flexFormValue('showPermaLogin', 'sDEF');
870  }
871  if ($this->‪flexFormValue('showLogoutFormAfterLogin', 'sDEF')) {
872  $flex['showLogoutFormAfterLogin'] = $this->‪flexFormValue('showLogoutFormAfterLogin', 'sDEF');
873  }
874  if ($this->‪flexFormValue('pages', 'sDEF')) {
875  $flex['pages'] = $this->‪flexFormValue('pages', 'sDEF');
876  }
877  if ($this->‪flexFormValue('recursive', 'sDEF')) {
878  $flex['recursive'] = $this->‪flexFormValue('recursive', 'sDEF');
879  }
880  if ($this->‪flexFormValue('redirectMode', 's_redirect')) {
881  $flex['redirectMode'] = $this->‪flexFormValue('redirectMode', 's_redirect');
882  }
883  if ($this->‪flexFormValue('redirectFirstMethod', 's_redirect')) {
884  $flex['redirectFirstMethod'] = $this->‪flexFormValue('redirectFirstMethod', 's_redirect');
885  }
886  if ($this->‪flexFormValue('redirectDisable', 's_redirect')) {
887  $flex['redirectDisable'] = $this->‪flexFormValue('redirectDisable', 's_redirect');
888  }
889  if ($this->‪flexFormValue('redirectPageLogin', 's_redirect')) {
890  $flex['redirectPageLogin'] = $this->‪flexFormValue('redirectPageLogin', 's_redirect');
891  }
892  if ($this->‪flexFormValue('redirectPageLoginError', 's_redirect')) {
893  $flex['redirectPageLoginError'] = $this->‪flexFormValue('redirectPageLoginError', 's_redirect');
894  }
895  if ($this->‪flexFormValue('redirectPageLogout', 's_redirect')) {
896  $flex['redirectPageLogout'] = $this->‪flexFormValue('redirectPageLogout', 's_redirect');
897  }
898  $pid = $flex['pages'] ? $this->‪pi_getPidList($flex['pages'], $flex['recursive']) : 0;
899  if ($pid > 0) {
900  $flex['storagePid'] = $pid;
901  }
902  $this->conf = array_merge($this->conf, $flex);
903  }
904 
912  protected function ‪flexFormValue($var, $sheet)
913  {
914  return $this->‪pi_getFFvalue($this->cObj->data['pi_flexform'], $var, $sheet);
915  }
916 
925  protected function ‪getPageLink($label, ‪$piVars, $returnUrl = false)
926  {
927  $additionalParams = is_array(‪$piVars) && !empty(‪$piVars) ? ‪$piVars : [];
928  // Should GETvars be preserved?
929  if ($this->conf['preserveGETvars']) {
930  $additionalParams = array_merge_recursive($additionalParams, $this->‪getPreserveGetVars());
931  }
932  $this->conf['linkConfig.']['parameter'] = $this->frontendController->id;
933  if (!empty($additionalParams)) {
934  $this->conf['linkConfig.']['additionalParams'] = ‪HttpUtility::buildQueryString($additionalParams, '&');
935  }
936  if ($returnUrl) {
937  return htmlspecialchars($this->cObj->typoLink_URL($this->conf['linkConfig.']));
938  }
939  return $this->cObj->typoLink($label, $this->conf['linkConfig.']);
940  }
941 
950  protected function ‪getPreserveGetVars()
951  {
952  $getVars = GeneralUtility::_GET();
953  unset(
954  $getVars['id'],
955  $getVars['no_cache'],
956  $getVars['logintype'],
957  $getVars['redirect_url'],
958  $getVars['cHash'],
959  $getVars[$this->prefixId]
960  );
961  if ($this->conf['preserveGETvars'] === 'all') {
962  $preserveQueryParts = $getVars;
963  } else {
964  $preserveQueryStringProperties = GeneralUtility::trimExplode(',', $this->conf['preserveGETvars']);
965  $preserveQueryParts = [];
966  parse_str(implode('=1&', $preserveQueryStringProperties) . '=1', $preserveQueryParts);
967  $preserveQueryParts = ‪\TYPO3\CMS\Core\Utility\ArrayUtility::intersectRecursive($getVars, $preserveQueryParts);
968  }
969  return $preserveQueryParts;
970  }
971 
977  protected function ‪generatePassword($len)
978  {
979  $pass = '';
980  while ($len--) {
981  $char = rand(0, 35);
982  if ($char < 10) {
983  $pass .= '' . $char;
984  } else {
985  $pass .= chr($char - 10 + 97);
986  }
987  }
988  return $pass;
989  }
990 
998  protected function ‪getDisplayText($label, $stdWrapArray = [])
999  {
1000  $text = $this->‪flexFormValue($label, 's_messages') ? $this->cObj->stdWrap($this->‪flexFormValue($label, 's_messages'), $stdWrapArray) : $this->cObj->stdWrap($this->‪pi_getLL('ll_' . $label), $stdWrapArray);
1001  $replace = $this->‪getUserFieldMarkers();
1002  return strtr($text, $replace);
1003  }
1004 
1010  protected function ‪getUserFieldMarkers()
1011  {
1012  $marker = [];
1013  // replace markers with fe_user data
1014  if ($this->frontendController->fe_user->user) {
1015  // All fields of fe_user will be replaced, scheme is ###FEUSER_FIELDNAME###
1016  foreach ($this->frontendController->fe_user->user as $field => $value) {
1017  ‪$conf = $this->conf['userfields.'][$field . '.'] ?? [];
1018  ‪$conf = array_replace_recursive(['htmlSpecialChars' => '1'], ‪$conf);
1019  $marker['###FEUSER_' . strtoupper($field) . '###'] = $this->cObj->stdWrap($value, ‪$conf);
1020  }
1021  // Add ###USER### for compatibility
1022  $marker['###USER###'] = $marker['###FEUSER_USERNAME###'];
1023  }
1024  return $marker;
1025  }
1026 
1033  protected function ‪validateRedirectUrl($url)
1034  {
1035  $url = strval($url);
1036  if ($url === '') {
1037  return '';
1038  }
1039  // Validate the URL:
1040  if ($this->‪isRelativeUrl($url) || $this->‪isInCurrentDomain($url) || $this->‪isInLocalDomain($url)) {
1041  return $url;
1042  }
1043  // URL is not allowed
1044  $this->logger->warning('Url "' . $url . '" for redirect was not accepted!');
1045  return '';
1046  }
1047 
1055  protected function ‪isInCurrentDomain($url)
1056  {
1057  $urlWithoutSchema = preg_replace('#^https?://#', '', $url);
1058  $siteUrlWithoutSchema = preg_replace('#^https?://#', '', GeneralUtility::getIndpEnv('TYPO3_SITE_URL'));
1059  return strpos($urlWithoutSchema . '/', GeneralUtility::getIndpEnv('HTTP_HOST') . '/') === 0
1060  && strpos($urlWithoutSchema, $siteUrlWithoutSchema) === 0;
1061  }
1062 
1070  protected function ‪isInLocalDomain($url)
1071  {
1072  $result = false;
1073  if (GeneralUtility::isValidUrl($url)) {
1074  $parsedUrl = parse_url($url);
1075  if ($parsedUrl['scheme'] === 'http' || $parsedUrl['scheme'] === 'https') {
1076  $host = $parsedUrl['host'];
1077 
1078  // check sites first
1079  $sites = $this->siteFinder->getAllSites();
1080  foreach ($sites as $site) {
1081  if ($site->getBase()->getHost() === $host) {
1082  return true;
1083  }
1084  }
1085 
1086  // continue with sys_domain records
1087  // Removes the last path segment and slash sequences like /// (if given):
1088  $path = preg_replace('#/+[^/]*$#', '', $parsedUrl['path'] ?? '');
1089 
1090  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('sys_domain');
1091  $queryBuilder->setRestrictions(GeneralUtility::makeInstance(FrontendRestrictionContainer::class));
1092  $localDomains = $queryBuilder->select('domainName')
1093  ->from('sys_domain')
1094  ->execute()
1095  ->fetchAll();
1096 
1097  if (is_array($localDomains)) {
1098  foreach ($localDomains as $localDomain) {
1099  // strip trailing slashes (if given)
1100  $domainName = rtrim($localDomain['domainName'], '/');
1101  if (GeneralUtility::isFirstPartOfStr($host . $path . '/', $domainName . '/')) {
1102  $result = true;
1103  break;
1104  }
1105  }
1106  }
1107  }
1108  }
1109 
1110  return $result;
1111  }
1112 
1120  protected function ‪isRelativeUrl($url)
1121  {
1122  $url = GeneralUtility::sanitizeLocalUrl($url);
1123  if (!empty($url)) {
1124  $parsedUrl = @parse_url($url);
1125  if ($parsedUrl !== false && !isset($parsedUrl['scheme']) && !isset($parsedUrl['host'])) {
1126  // If the relative URL starts with a slash, we need to check if it's within the current site path
1127  return $parsedUrl['path'][0] !== '/' || GeneralUtility::isFirstPartOfStr($parsedUrl['path'], GeneralUtility::getIndpEnv('TYPO3_SITE_PATH'));
1128  }
1129  }
1130  return false;
1131  }
1132 
1138  protected function ‪invalidateUserSessions(int $userId)
1139  {
1140  $sessionManager = GeneralUtility::makeInstance(SessionManager::class);
1141  $sessionBackend = $sessionManager->getSessionBackend('FE');
1142  $sessionManager->invalidateAllSessionsByUserId($sessionBackend, $userId, $this->frontendController->fe_user);
1143  }
1144 }
‪TYPO3\CMS\Felogin\Controller\FrontendLoginController\main
‪string main($content, $conf)
Definition: FrontendLoginController.php:113
‪TYPO3\CMS\Felogin\Controller\FrontendLoginController\$siteFinder
‪SiteFinder $siteFinder
Definition: FrontendLoginController.php:91
‪TYPO3\CMS\Felogin\Controller\FrontendLoginController\flexFormValue
‪string flexFormValue($var, $sheet)
Definition: FrontendLoginController.php:900
‪TYPO3\CMS\Felogin\Controller\FrontendLoginController\$template
‪string $template
Definition: FrontendLoginController.php:71
‪TYPO3\CMS\Core\Crypto\PasswordHashing\PasswordHashFactory
Definition: PasswordHashFactory.php:25
‪TYPO3\CMS\Felogin\Controller\FrontendLoginController\mergeflexFormValuesIntoConf
‪mergeflexFormValuesIntoConf()
Definition: FrontendLoginController.php:850
‪TYPO3\CMS\Felogin\Controller\FrontendLoginController\showLogin
‪string showLogin()
Definition: FrontendLoginController.php:546
‪TYPO3\CMS\Felogin\Controller\FrontendLoginController\generatePassword
‪string generatePassword($len)
Definition: FrontendLoginController.php:965
‪TYPO3\CMS\Felogin\Controller\FrontendLoginController\showForgot
‪string showForgot()
Definition: FrontendLoginController.php:213
‪TYPO3\CMS\Felogin\Controller\FrontendLoginController\$extKey
‪string $extKey
Definition: FrontendLoginController.php:51
‪TYPO3\CMS\Frontend\Plugin\AbstractPlugin\pi_getPidList
‪string pi_getPidList($pid_list, $recursive=0)
Definition: AbstractPlugin.php:1147
‪TYPO3\CMS\Felogin\Controller\FrontendLoginController
Definition: FrontendLoginController.php:38
‪TYPO3\CMS\Frontend\Plugin\AbstractPlugin\pi_getLL
‪string pi_getLL($key, $alternativeLabel='')
Definition: AbstractPlugin.php:912
‪TYPO3\CMS\Felogin\Controller\FrontendLoginController\$redirectUrl
‪string $redirectUrl
Definition: FrontendLoginController.php:77
‪TYPO3\CMS\Frontend\Plugin\AbstractPlugin\pi_initPIflexForm
‪pi_initPIflexForm($field='pi_flexform')
Definition: AbstractPlugin.php:1327
‪TYPO3\CMS\Felogin\Controller\FrontendLoginController\isInCurrentDomain
‪bool isInCurrentDomain($url)
Definition: FrontendLoginController.php:1043
‪TYPO3\CMS\Frontend\Plugin\AbstractPlugin
Definition: AbstractPlugin.php:42
‪TYPO3\CMS\Core\Site\SiteFinder
Definition: SiteFinder.php:31
‪TYPO3\CMS\Core\Session\SessionManager
Definition: SessionManager.php:37
‪TYPO3\CMS\Felogin\Controller\FrontendLoginController\getUserFieldMarkers
‪array getUserFieldMarkers()
Definition: FrontendLoginController.php:998
‪TYPO3\CMS\Felogin\Controller\FrontendLoginController\isRelativeUrl
‪bool isRelativeUrl($url)
Definition: FrontendLoginController.php:1108
‪TYPO3\CMS\Frontend\Plugin\AbstractPlugin\$conf
‪array $conf
Definition: AbstractPlugin.php:189
‪TYPO3\CMS\Felogin\Controller\FrontendLoginController\generateAndSendHash
‪string generateAndSendHash($user)
Definition: FrontendLoginController.php:441
‪TYPO3\CMS\Felogin\Controller\FrontendLoginController\$logintype
‪string $logintype
Definition: FrontendLoginController.php:89
‪TYPO3\CMS\Felogin\Controller\FrontendLoginController\processRedirect
‪array processRedirect()
Definition: FrontendLoginController.php:675
‪TYPO3\CMS\Core\Authentication\LoginType
Definition: LoginType.php:25
‪TYPO3\CMS\Core\Context\Context
Definition: Context.php:49
‪TYPO3\CMS\Felogin\Controller\FrontendLoginController\isInLocalDomain
‪bool isInLocalDomain($url)
Definition: FrontendLoginController.php:1058
‪TYPO3\CMS\Felogin\Controller\FrontendLoginController\validateRedirectUrl
‪string validateRedirectUrl($url)
Definition: FrontendLoginController.php:1021
‪TYPO3\CMS\Felogin\Controller\FrontendLoginController\$userIsLoggedIn
‪bool $userIsLoggedIn
Definition: FrontendLoginController.php:65
‪TYPO3\CMS\Felogin\Controller\FrontendLoginController\$spid
‪string $spid
Definition: FrontendLoginController.php:97
‪TYPO3\CMS\Frontend\Plugin\AbstractPlugin\$piVars
‪array $piVars
Definition: AbstractPlugin.php:73
‪TYPO3\CMS\Frontend\Plugin\AbstractPlugin\pi_wrapInBaseClass
‪string pi_wrapInBaseClass($str)
Definition: AbstractPlugin.php:804
‪TYPO3\CMS\Frontend\Plugin\AbstractPlugin\pi_getPageLink
‪string pi_getPageLink($id, $target='', $urlParameters=[])
Definition: AbstractPlugin.php:328
‪TYPO3\CMS\Frontend\Plugin\AbstractPlugin\pi_setPiVarDefaults
‪pi_setPiVarDefaults()
Definition: AbstractPlugin.php:299
‪TYPO3\CMS\Felogin\Controller\FrontendLoginController\$pi_USER_INT_obj
‪bool $pi_USER_INT_obj
Definition: FrontendLoginController.php:59
‪TYPO3\CMS\Core\Utility\HttpUtility\buildQueryString
‪static string buildQueryString(array $parameters, string $prependCharacter='', bool $skipEmptyParameters=false)
Definition: HttpUtility.php:160
‪TYPO3\CMS\Felogin\Controller\FrontendLoginController\$referer
‪string $referer
Definition: FrontendLoginController.php:103
‪TYPO3\CMS\Frontend\Plugin\AbstractPlugin\pi_getFFvalue
‪string null pi_getFFvalue($T3FlexForm_array, $fieldName, $sheet='sDEF', $lang='lDEF', $value='vDEF')
Definition: AbstractPlugin.php:1348
‪TYPO3\CMS\Felogin\Controller\FrontendLoginController\invalidateUserSessions
‪invalidateUserSessions(int $userId)
Definition: FrontendLoginController.php:1126
‪TYPO3\CMS\Core\Utility\ArrayUtility\intersectRecursive
‪static array intersectRecursive(array $source, array $mask=[])
Definition: ArrayUtility.php:529
‪TYPO3\CMS\Core\Authentication\LoginType\LOGOUT
‪const LOGOUT
Definition: LoginType.php:34
‪TYPO3\CMS\Felogin\Controller\FrontendLoginController\showLogout
‪string showLogout()
Definition: FrontendLoginController.php:516
‪TYPO3\CMS\Core\Authentication\LoginType\LOGIN
‪const LOGIN
Definition: LoginType.php:29
‪TYPO3\CMS\Felogin\Controller\FrontendLoginController\getPageLink
‪string getPageLink($label, $piVars, $returnUrl=false)
Definition: FrontendLoginController.php:913
‪TYPO3\CMS\Core\Database\Connection
Definition: Connection.php:31
‪TYPO3\CMS\Felogin\Controller\FrontendLoginController\getDisplayText
‪string getDisplayText($label, $stdWrapArray=[])
Definition: FrontendLoginController.php:986
‪TYPO3\CMS\Felogin\Controller\FrontendLoginController\getPreserveGetVars
‪array getPreserveGetVars()
Definition: FrontendLoginController.php:938
‪TYPO3\CMS\Frontend\Plugin\AbstractPlugin\pi_loadLL
‪pi_loadLL($languageFilePath='')
Definition: AbstractPlugin.php:956
‪TYPO3\CMS\Felogin\Controller\FrontendLoginController\$noRedirect
‪bool $noRedirect
Definition: FrontendLoginController.php:83
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:5
‪TYPO3\CMS\Felogin\Controller\FrontendLoginController\$pi_checkCHash
‪bool $pi_checkCHash
Definition: FrontendLoginController.php:55
‪TYPO3\CMS\Felogin\Controller\FrontendLoginController\$prefixId
‪string $prefixId
Definition: FrontendLoginController.php:45
‪TYPO3\CMS\Core\Utility\HttpUtility
Definition: HttpUtility.php:21
‪TYPO3\CMS\Core\Crypto\Random
Definition: Random.php:22
‪TYPO3\CMS\Core\Database\ConnectionPool
Definition: ConnectionPool.php:44
‪TYPO3\CMS\Frontend\Plugin\AbstractPlugin\pi_getRecord
‪array pi_getRecord($table, $uid, $checkPage=false)
Definition: AbstractPlugin.php:1135
‪TYPO3\CMS\Felogin\Controller
Definition: FrontendLoginController.php:2
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:45
‪TYPO3\CMS\Felogin\Controller\FrontendLoginController\changePassword
‪string changePassword()
Definition: FrontendLoginController.php:306
‪TYPO3\CMS\Core\Utility\HttpUtility\redirect
‪static redirect($url, $httpStatus=self::HTTP_STATUS_303)
Definition: HttpUtility.php:103
‪TYPO3\CMS\Core\Database\Query\Restriction\FrontendRestrictionContainer
Definition: FrontendRestrictionContainer.php:29