addArgument( 'backendurl', InputArgument::REQUIRED, 'The URL of the TYPO3 Backend, e.g. https://www.example.com/typo3/' )->addArgument( 'email', InputArgument::REQUIRED, 'The email address of a valid backend user' ); } /** * Executes the command for sending out an email to reset the password. */ protected function execute(InputInterface $input, OutputInterface $output): int { $io = new SymfonyStyle($input, $output); $email = $input->getArgument('email'); $email = is_string($email) ? $email : ''; if (!GeneralUtility::validEmail($email)) { $io->error('The given email "' . $email . '" is not a valid email address.'); return Command::FAILURE; } $backendUrl = $input->getArgument('backendurl'); $backendUrl = is_string($backendUrl) ? $backendUrl : ''; if (!GeneralUtility::isValidUrl($backendUrl)) { $io->error('The given backend URL "' . $backendUrl . '" is not a valid URL.'); return Command::FAILURE; } $request = $this->createFakeWebRequest($backendUrl); $GLOBALS['TYPO3_REQUEST'] = $request; $this->passwordReset->initiateReset($request, $this->context, $email); $io->success('Password reset for email address "' . $email . '" initiated.'); return Command::SUCCESS; } /** * This is needed to create a link to the backend properly. */ protected function createFakeWebRequest(string $backendUrl): ServerRequestInterface { $uri = new Uri($backendUrl); $request = new ServerRequest( $uri, 'GET', 'php://input', [], [ 'HTTP_HOST' => $uri->getHost(), 'SERVER_NAME' => $uri->getHost(), 'HTTPS' => $uri->getScheme() === 'https', 'SCRIPT_FILENAME' => __FILE__, 'SCRIPT_NAME' => rtrim($uri->getPath(), '/') . '/', ] ); $backedUpEnvironment = $this->simulateEnvironmentForBackendEntryPoint(); $normalizedParams = NormalizedParams::createFromRequest($request); // Restore the environment Environment::initialize( Environment::getContext(), Environment::isCli(), Environment::isComposerMode(), Environment::getProjectPath(), Environment::getPublicPath(), Environment::getVarPath(), Environment::getConfigPath(), $backedUpEnvironment['currentScript'], Environment::isWindows() ? 'WINDOWS' : 'UNIX' ); return $request ->withAttribute('normalizedParams', $normalizedParams) ->withAttribute('applicationType', SystemEnvironmentBuilder::REQUESTTYPE_BE); } /** * This is a workaround to use "PublicPath . /typo3/index.php" instead of "publicPath . /typo3/sysext/core/bin/typo3" * so the web root is detected properly in normalizedParams. */ protected function simulateEnvironmentForBackendEntryPoint(): array { $currentEnvironment = Environment::toArray(); Environment::initialize( Environment::getContext(), Environment::isCli(), Environment::isComposerMode(), Environment::getProjectPath(), Environment::getPublicPath(), Environment::getVarPath(), Environment::getConfigPath(), // This is ugly, as this change fakes the directory dirname(Environment::getCurrentScript(), 4) . DIRECTORY_SEPARATOR . 'index.php', Environment::isWindows() ? 'WINDOWS' : 'UNIX' ); return $currentEnvironment; } }