diff --git a/core/Controller/TwoFactorChallengeController.php b/core/Controller/TwoFactorChallengeController.php index 7152078c338..48fd365fd12 100644 --- a/core/Controller/TwoFactorChallengeController.php +++ b/core/Controller/TwoFactorChallengeController.php @@ -213,13 +213,14 @@ class TwoFactorChallengeController extends Controller { * @NoCSRFRequired */ #[FrontpageRoute(verb: 'GET', url: 'login/setupchallenge')] - public function setupProviders(): StandaloneTemplateResponse { + public function setupProviders(?string $redirect_url = null): StandaloneTemplateResponse { $user = $this->userSession->getUser(); $setupProviders = $this->twoFactorManager->getLoginSetupProviders($user); $data = [ 'providers' => $setupProviders, 'logout_url' => $this->getLogoutUrl(), + 'redirect_url' => $redirect_url, ]; return new StandaloneTemplateResponse($this->appName, 'twofactorsetupselection', $data, 'guest'); @@ -230,7 +231,7 @@ class TwoFactorChallengeController extends Controller { * @NoCSRFRequired */ #[FrontpageRoute(verb: 'GET', url: 'login/setupchallenge/{providerId}')] - public function setupProvider(string $providerId) { + public function setupProvider(string $providerId, ?string $redirect_url = null) { $user = $this->userSession->getUser(); $providers = $this->twoFactorManager->getLoginSetupProviders($user); @@ -251,6 +252,7 @@ class TwoFactorChallengeController extends Controller { $data = [ 'provider' => $provider, 'logout_url' => $this->getLogoutUrl(), + 'redirect_url' => $redirect_url, 'template' => $tmpl->fetchPage(), ]; $response = new StandaloneTemplateResponse($this->appName, 'twofactorsetupchallenge', $data, 'guest'); @@ -264,11 +266,12 @@ class TwoFactorChallengeController extends Controller { * @todo handle the extreme edge case of an invalid provider ID and redirect to the provider selection page */ #[FrontpageRoute(verb: 'POST', url: 'login/setupchallenge/{providerId}')] - public function confirmProviderSetup(string $providerId) { + public function confirmProviderSetup(string $providerId, ?string $redirect_url = null) { return new RedirectResponse($this->urlGenerator->linkToRoute( 'core.TwoFactorChallenge.showChallenge', [ 'challengeProviderId' => $providerId, + 'redirect_url' => $redirect_url, ] )); } diff --git a/core/Middleware/TwoFactorMiddleware.php b/core/Middleware/TwoFactorMiddleware.php index 4b5618eb23d..682df1312d6 100644 --- a/core/Middleware/TwoFactorMiddleware.php +++ b/core/Middleware/TwoFactorMiddleware.php @@ -134,8 +134,10 @@ class TwoFactorMiddleware extends Middleware { public function afterException($controller, $methodName, Exception $exception) { if ($exception instanceof TwoFactorAuthRequiredException) { - $params = []; - if (isset($this->request->server['REQUEST_URI'])) { + $params = [ + 'redirect_url' => $this->request->getParam('redirect_url'), + ]; + if (!isset($params['redirect_url']) && isset($this->request->server['REQUEST_URI'])) { $params['redirect_url'] = $this->request->server['REQUEST_URI']; } return new RedirectResponse($this->urlGenerator->linkToRoute('core.TwoFactorChallenge.selectChallenge', $params)); diff --git a/core/templates/twofactorsetupselection.php b/core/templates/twofactorsetupselection.php index 4ef19d86349..fb8db49cf17 100644 --- a/core/templates/twofactorsetupselection.php +++ b/core/templates/twofactorsetupselection.php @@ -33,6 +33,7 @@ declare(strict_types=1); href="getURLGenerator()->linkToRoute('core.TwoFactorChallenge.setupProvider', [ 'providerId' => $provider->getId(), + 'redirect_url' => $_['redirect_url'], ] )) ?>"> assertEquals($expected, $this->controller->solveChallenge('myprovider', 'token', '/url')); } - public function testSetUpProviders() { + public function testSetUpProviders(): void { $user = $this->createMock(IUser::class); $this->userSession->expects($this->once()) ->method('getUser') @@ -357,6 +357,7 @@ class TwoFactorChallengeControllerTest extends TestCase { $provider, ], 'logout_url' => 'logoutAttribute', + 'redirect_url' => null, ], 'guest' ); @@ -392,7 +393,7 @@ class TwoFactorChallengeControllerTest extends TestCase { $this->assertEquals($expected, $response); } - public function testSetUpProvider() { + public function testSetUpProvider(): void { $user = $this->createMock(IUser::class); $this->userSession->expects($this->once()) ->method('getUser') @@ -426,6 +427,7 @@ class TwoFactorChallengeControllerTest extends TestCase { 'provider' => $provider, 'logout_url' => 'logoutAttribute', 'template' => 'tmpl', + 'redirect_url' => null, ], 'guest' ); @@ -435,13 +437,14 @@ class TwoFactorChallengeControllerTest extends TestCase { $this->assertEquals($expected, $response); } - public function testConfirmProviderSetup() { + public function testConfirmProviderSetup(): void { $this->urlGenerator->expects($this->once()) ->method('linkToRoute') ->with( 'core.TwoFactorChallenge.showChallenge', [ 'challengeProviderId' => 'totp', + 'redirect_url' => null, ]) ->willReturn('2fa/select/page'); $expected = new RedirectResponse('2fa/select/page');