Completed
Push — master ( f980d9...1492ed )
by
unknown
26:56 queued 15s
created
core/templates/twofactorselectchallenge.php 1 patch
Braces   +13 added lines, -5 removed lines patch added patch discarded remove patch
@@ -32,11 +32,15 @@  discard block
 block discarded – undo
32 32
 					<?php p($l->t('Set up two-factor authentication')) ?>
33 33
 				</a>
34 34
 			<?php } ?>
35
-		<?php else: ?>
35
+		<?php else {
36
+    : ?>
36 37
 			<strong><?php p($l->t('Two-factor authentication is enforced but has not been configured on your account. Use one of your backup codes to log in or contact your admin for assistance.')) ?></strong>
37
-		<?php endif; ?>
38
+		<?php endif;
39
+}
40
+?>
38 41
 	</p>
39
-	<?php else: ?>
42
+	<?php else {
43
+    : ?>
40 44
 	<ul>
41 45
 	<?php foreach ($_['providers'] as $provider): ?>
42 46
 		<li>
@@ -50,6 +54,7 @@  discard block
 block discarded – undo
50 54
 				<?php
51 55
 				if ($provider instanceof \OCP\Authentication\TwoFactorAuth\IProvidesIcons) {
52 56
 					$icon = $provider->getLightIcon();
57
+}
53 58
 				} else {
54 59
 					$icon = image_path('core', 'actions/password-white.svg');
55 60
 				}
@@ -66,7 +71,8 @@  discard block
 block discarded – undo
66 71
 	<?php endif ?>
67 72
 	<?php if (!is_null($_['backupProvider'])): ?>
68 73
 	<p>
69
-		<a class="<?php if ($noProviders): ?>button primary two-factor-primary<?php else: ?>two-factor-secondary<?php endif ?>" href="<?php p(\OCP\Server::get(\OCP\IURLGenerator::class)->linkToRoute('core.TwoFactorChallenge.showChallenge',
74
+		<a class="<?php if ($noProviders): ?>button primary two-factor-primary<?php else {
75
+    : ?>two-factor-secondary<?php endif ?>" href="<?php p(\OCP\Server::get(\OCP\IURLGenerator::class)->linkToRoute('core.TwoFactorChallenge.showChallenge',
70 76
 			[
71 77
 				'challengeProviderId' => $_['backupProvider']->getId(),
72 78
 				'redirect_url' => $_['redirect_url'],
@@ -75,7 +81,9 @@  discard block
 block discarded – undo
75 81
 			<?php p($l->t('Use backup code')) ?>
76 82
 		</a>
77 83
 	</p>
78
-	<?php endif; ?>
84
+	<?php endif;
85
+}
86
+?>
79 87
 	<p><a id="cancel-login" class="two-factor-secondary" href="<?php print_unescaped($_['logout_url']); ?>">
80 88
 		<?php p($l->t('Cancel login')) ?>
81 89
 	</a></p>
Please login to merge, or discard this patch.
core/Controller/CSRFTokenController.php 1 patch
Indentation   +30 added lines, -30 removed lines patch added patch discarded remove patch
@@ -19,37 +19,37 @@
 block discarded – undo
19 19
 use OCP\IRequest;
20 20
 
21 21
 class CSRFTokenController extends Controller {
22
-	public function __construct(
23
-		string $appName,
24
-		IRequest $request,
25
-		private CsrfTokenManager $tokenManager,
26
-	) {
27
-		parent::__construct($appName, $request);
28
-	}
22
+    public function __construct(
23
+        string $appName,
24
+        IRequest $request,
25
+        private CsrfTokenManager $tokenManager,
26
+    ) {
27
+        parent::__construct($appName, $request);
28
+    }
29 29
 
30
-	/**
31
-	 * Returns a new CSRF token.
32
-	 *
33
-	 * @return JSONResponse<Http::STATUS_OK, array{token: string}, array{}>|JSONResponse<Http::STATUS_FORBIDDEN, list<empty>, array{}>
34
-	 *
35
-	 * 200: CSRF token returned
36
-	 * 403: Strict cookie check failed
37
-	 *
38
-	 * @NoTwoFactorRequired
39
-	 */
40
-	#[PublicPage]
41
-	#[NoCSRFRequired]
42
-	#[FrontpageRoute(verb: 'GET', url: '/csrftoken')]
43
-	#[OpenAPI(scope: OpenAPI::SCOPE_DEFAULT)]
44
-	public function index(): JSONResponse {
45
-		if (!$this->request->passesStrictCookieCheck()) {
46
-			return new JSONResponse([], Http::STATUS_FORBIDDEN);
47
-		}
30
+    /**
31
+     * Returns a new CSRF token.
32
+     *
33
+     * @return JSONResponse<Http::STATUS_OK, array{token: string}, array{}>|JSONResponse<Http::STATUS_FORBIDDEN, list<empty>, array{}>
34
+     *
35
+     * 200: CSRF token returned
36
+     * 403: Strict cookie check failed
37
+     *
38
+     * @NoTwoFactorRequired
39
+     */
40
+    #[PublicPage]
41
+    #[NoCSRFRequired]
42
+    #[FrontpageRoute(verb: 'GET', url: '/csrftoken')]
43
+    #[OpenAPI(scope: OpenAPI::SCOPE_DEFAULT)]
44
+    public function index(): JSONResponse {
45
+        if (!$this->request->passesStrictCookieCheck()) {
46
+            return new JSONResponse([], Http::STATUS_FORBIDDEN);
47
+        }
48 48
 
49
-		$requestToken = $this->tokenManager->getToken();
49
+        $requestToken = $this->tokenManager->getToken();
50 50
 
51
-		return new JSONResponse([
52
-			'token' => $requestToken->getEncryptedValue(),
53
-		]);
54
-	}
51
+        return new JSONResponse([
52
+            'token' => $requestToken->getEncryptedValue(),
53
+        ]);
54
+    }
55 55
 }
Please login to merge, or discard this patch.
core/Controller/TwoFactorChallengeController.php 1 patch
Indentation   +204 added lines, -204 removed lines patch added patch discarded remove patch
@@ -30,232 +30,232 @@
 block discarded – undo
30 30
 
31 31
 #[OpenAPI(scope: OpenAPI::SCOPE_IGNORE)]
32 32
 class TwoFactorChallengeController extends Controller {
33
-	public function __construct(
34
-		string $appName,
35
-		IRequest $request,
36
-		private Manager $twoFactorManager,
37
-		private IUserSession $userSession,
38
-		private ISession $session,
39
-		private IURLGenerator $urlGenerator,
40
-		private LoggerInterface $logger,
41
-	) {
42
-		parent::__construct($appName, $request);
43
-	}
33
+    public function __construct(
34
+        string $appName,
35
+        IRequest $request,
36
+        private Manager $twoFactorManager,
37
+        private IUserSession $userSession,
38
+        private ISession $session,
39
+        private IURLGenerator $urlGenerator,
40
+        private LoggerInterface $logger,
41
+    ) {
42
+        parent::__construct($appName, $request);
43
+    }
44 44
 
45
-	/**
46
-	 * @return string
47
-	 */
48
-	protected function getLogoutUrl() {
49
-		return OC_User::getLogoutUrl($this->urlGenerator);
50
-	}
45
+    /**
46
+     * @return string
47
+     */
48
+    protected function getLogoutUrl() {
49
+        return OC_User::getLogoutUrl($this->urlGenerator);
50
+    }
51 51
 
52
-	/**
53
-	 * @param IProvider[] $providers
54
-	 */
55
-	private function splitProvidersAndBackupCodes(array $providers): array {
56
-		$regular = [];
57
-		$backup = null;
58
-		foreach ($providers as $provider) {
59
-			if ($provider->getId() === 'backup_codes') {
60
-				$backup = $provider;
61
-			} else {
62
-				$regular[] = $provider;
63
-			}
64
-		}
52
+    /**
53
+     * @param IProvider[] $providers
54
+     */
55
+    private function splitProvidersAndBackupCodes(array $providers): array {
56
+        $regular = [];
57
+        $backup = null;
58
+        foreach ($providers as $provider) {
59
+            if ($provider->getId() === 'backup_codes') {
60
+                $backup = $provider;
61
+            } else {
62
+                $regular[] = $provider;
63
+            }
64
+        }
65 65
 
66
-		return [$regular, $backup];
67
-	}
66
+        return [$regular, $backup];
67
+    }
68 68
 
69
-	/**
70
-	 * @TwoFactorSetUpDoneRequired
71
-	 *
72
-	 * @param string $redirect_url
73
-	 * @return StandaloneTemplateResponse
74
-	 */
75
-	#[NoAdminRequired]
76
-	#[NoCSRFRequired]
77
-	#[FrontpageRoute(verb: 'GET', url: '/login/selectchallenge')]
78
-	public function selectChallenge($redirect_url) {
79
-		$user = $this->userSession->getUser();
80
-		$providerSet = $this->twoFactorManager->getProviderSet($user);
81
-		$allProviders = $providerSet->getProviders();
82
-		[$providers, $backupProvider] = $this->splitProvidersAndBackupCodes($allProviders);
83
-		$setupProviders = $this->twoFactorManager->getLoginSetupProviders($user);
69
+    /**
70
+     * @TwoFactorSetUpDoneRequired
71
+     *
72
+     * @param string $redirect_url
73
+     * @return StandaloneTemplateResponse
74
+     */
75
+    #[NoAdminRequired]
76
+    #[NoCSRFRequired]
77
+    #[FrontpageRoute(verb: 'GET', url: '/login/selectchallenge')]
78
+    public function selectChallenge($redirect_url) {
79
+        $user = $this->userSession->getUser();
80
+        $providerSet = $this->twoFactorManager->getProviderSet($user);
81
+        $allProviders = $providerSet->getProviders();
82
+        [$providers, $backupProvider] = $this->splitProvidersAndBackupCodes($allProviders);
83
+        $setupProviders = $this->twoFactorManager->getLoginSetupProviders($user);
84 84
 
85
-		$data = [
86
-			'providers' => $providers,
87
-			'backupProvider' => $backupProvider,
88
-			'providerMissing' => $providerSet->isProviderMissing(),
89
-			'redirect_url' => $redirect_url,
90
-			'logout_url' => $this->getLogoutUrl(),
91
-			'hasSetupProviders' => !empty($setupProviders),
92
-		];
93
-		Util::addScript('core', 'twofactor-request-token');
94
-		return new StandaloneTemplateResponse($this->appName, 'twofactorselectchallenge', $data, 'guest');
95
-	}
85
+        $data = [
86
+            'providers' => $providers,
87
+            'backupProvider' => $backupProvider,
88
+            'providerMissing' => $providerSet->isProviderMissing(),
89
+            'redirect_url' => $redirect_url,
90
+            'logout_url' => $this->getLogoutUrl(),
91
+            'hasSetupProviders' => !empty($setupProviders),
92
+        ];
93
+        Util::addScript('core', 'twofactor-request-token');
94
+        return new StandaloneTemplateResponse($this->appName, 'twofactorselectchallenge', $data, 'guest');
95
+    }
96 96
 
97
-	/**
98
-	 * @TwoFactorSetUpDoneRequired
99
-	 *
100
-	 * @param string $challengeProviderId
101
-	 * @param string $redirect_url
102
-	 * @return StandaloneTemplateResponse|RedirectResponse
103
-	 */
104
-	#[NoAdminRequired]
105
-	#[NoCSRFRequired]
106
-	#[UseSession]
107
-	#[FrontpageRoute(verb: 'GET', url: '/login/challenge/{challengeProviderId}')]
108
-	public function showChallenge($challengeProviderId, $redirect_url) {
109
-		$user = $this->userSession->getUser();
110
-		$providerSet = $this->twoFactorManager->getProviderSet($user);
111
-		$provider = $providerSet->getProvider($challengeProviderId);
97
+    /**
98
+     * @TwoFactorSetUpDoneRequired
99
+     *
100
+     * @param string $challengeProviderId
101
+     * @param string $redirect_url
102
+     * @return StandaloneTemplateResponse|RedirectResponse
103
+     */
104
+    #[NoAdminRequired]
105
+    #[NoCSRFRequired]
106
+    #[UseSession]
107
+    #[FrontpageRoute(verb: 'GET', url: '/login/challenge/{challengeProviderId}')]
108
+    public function showChallenge($challengeProviderId, $redirect_url) {
109
+        $user = $this->userSession->getUser();
110
+        $providerSet = $this->twoFactorManager->getProviderSet($user);
111
+        $provider = $providerSet->getProvider($challengeProviderId);
112 112
 
113
-		if (is_null($provider)) {
114
-			return new RedirectResponse($this->urlGenerator->linkToRoute('core.TwoFactorChallenge.selectChallenge'));
115
-		}
113
+        if (is_null($provider)) {
114
+            return new RedirectResponse($this->urlGenerator->linkToRoute('core.TwoFactorChallenge.selectChallenge'));
115
+        }
116 116
 
117
-		$backupProvider = $providerSet->getProvider('backup_codes');
118
-		if (!is_null($backupProvider) && $backupProvider->getId() === $provider->getId()) {
119
-			// Don't show the backup provider link if we're already showing that provider's challenge
120
-			$backupProvider = null;
121
-		}
117
+        $backupProvider = $providerSet->getProvider('backup_codes');
118
+        if (!is_null($backupProvider) && $backupProvider->getId() === $provider->getId()) {
119
+            // Don't show the backup provider link if we're already showing that provider's challenge
120
+            $backupProvider = null;
121
+        }
122 122
 
123
-		$errorMessage = '';
124
-		$error = false;
125
-		if ($this->session->exists('two_factor_auth_error')) {
126
-			$this->session->remove('two_factor_auth_error');
127
-			$error = true;
128
-			$errorMessage = $this->session->get('two_factor_auth_error_message');
129
-			$this->session->remove('two_factor_auth_error_message');
130
-		}
131
-		$tmpl = $provider->getTemplate($user);
132
-		$tmpl->assign('redirect_url', $redirect_url);
133
-		$data = [
134
-			'error' => $error,
135
-			'error_message' => $errorMessage,
136
-			'provider' => $provider,
137
-			'backupProvider' => $backupProvider,
138
-			'logout_url' => $this->getLogoutUrl(),
139
-			'redirect_url' => $redirect_url,
140
-			'template' => $tmpl->fetchPage(),
141
-		];
142
-		$response = new StandaloneTemplateResponse($this->appName, 'twofactorshowchallenge', $data, 'guest');
143
-		if ($provider instanceof IProvidesCustomCSP) {
144
-			$response->setContentSecurityPolicy($provider->getCSP());
145
-		}
146
-		Util::addScript('core', 'twofactor-request-token');
147
-		return $response;
148
-	}
123
+        $errorMessage = '';
124
+        $error = false;
125
+        if ($this->session->exists('two_factor_auth_error')) {
126
+            $this->session->remove('two_factor_auth_error');
127
+            $error = true;
128
+            $errorMessage = $this->session->get('two_factor_auth_error_message');
129
+            $this->session->remove('two_factor_auth_error_message');
130
+        }
131
+        $tmpl = $provider->getTemplate($user);
132
+        $tmpl->assign('redirect_url', $redirect_url);
133
+        $data = [
134
+            'error' => $error,
135
+            'error_message' => $errorMessage,
136
+            'provider' => $provider,
137
+            'backupProvider' => $backupProvider,
138
+            'logout_url' => $this->getLogoutUrl(),
139
+            'redirect_url' => $redirect_url,
140
+            'template' => $tmpl->fetchPage(),
141
+        ];
142
+        $response = new StandaloneTemplateResponse($this->appName, 'twofactorshowchallenge', $data, 'guest');
143
+        if ($provider instanceof IProvidesCustomCSP) {
144
+            $response->setContentSecurityPolicy($provider->getCSP());
145
+        }
146
+        Util::addScript('core', 'twofactor-request-token');
147
+        return $response;
148
+    }
149 149
 
150
-	/**
151
-	 * @TwoFactorSetUpDoneRequired
152
-	 *
153
-	 * @UserRateThrottle(limit=5, period=100)
154
-	 *
155
-	 * @param string $challengeProviderId
156
-	 * @param string $challenge
157
-	 * @param string $redirect_url
158
-	 * @return RedirectResponse
159
-	 */
160
-	#[NoAdminRequired]
161
-	#[NoCSRFRequired]
162
-	#[UseSession]
163
-	#[FrontpageRoute(verb: 'POST', url: '/login/challenge/{challengeProviderId}')]
164
-	public function solveChallenge($challengeProviderId, $challenge, $redirect_url = null) {
165
-		$user = $this->userSession->getUser();
166
-		$provider = $this->twoFactorManager->getProvider($user, $challengeProviderId);
167
-		if (is_null($provider)) {
168
-			return new RedirectResponse($this->urlGenerator->linkToRoute('core.TwoFactorChallenge.selectChallenge'));
169
-		}
150
+    /**
151
+     * @TwoFactorSetUpDoneRequired
152
+     *
153
+     * @UserRateThrottle(limit=5, period=100)
154
+     *
155
+     * @param string $challengeProviderId
156
+     * @param string $challenge
157
+     * @param string $redirect_url
158
+     * @return RedirectResponse
159
+     */
160
+    #[NoAdminRequired]
161
+    #[NoCSRFRequired]
162
+    #[UseSession]
163
+    #[FrontpageRoute(verb: 'POST', url: '/login/challenge/{challengeProviderId}')]
164
+    public function solveChallenge($challengeProviderId, $challenge, $redirect_url = null) {
165
+        $user = $this->userSession->getUser();
166
+        $provider = $this->twoFactorManager->getProvider($user, $challengeProviderId);
167
+        if (is_null($provider)) {
168
+            return new RedirectResponse($this->urlGenerator->linkToRoute('core.TwoFactorChallenge.selectChallenge'));
169
+        }
170 170
 
171
-		try {
172
-			if ($this->twoFactorManager->verifyChallenge($challengeProviderId, $user, $challenge)) {
173
-				if (!is_null($redirect_url)) {
174
-					return new RedirectResponse($this->urlGenerator->getAbsoluteURL(urldecode($redirect_url)));
175
-				}
176
-				return new RedirectResponse($this->urlGenerator->linkToDefaultPageUrl());
177
-			}
178
-		} catch (TwoFactorException $e) {
179
-			/*
171
+        try {
172
+            if ($this->twoFactorManager->verifyChallenge($challengeProviderId, $user, $challenge)) {
173
+                if (!is_null($redirect_url)) {
174
+                    return new RedirectResponse($this->urlGenerator->getAbsoluteURL(urldecode($redirect_url)));
175
+                }
176
+                return new RedirectResponse($this->urlGenerator->linkToDefaultPageUrl());
177
+            }
178
+        } catch (TwoFactorException $e) {
179
+            /*
180 180
 			 * The 2FA App threw an TwoFactorException. Now we display more
181 181
 			 * information to the user. The exception text is stored in the
182 182
 			 * session to be used in showChallenge()
183 183
 			 */
184
-			$this->session->set('two_factor_auth_error_message', $e->getMessage());
185
-		}
184
+            $this->session->set('two_factor_auth_error_message', $e->getMessage());
185
+        }
186 186
 
187
-		$ip = $this->request->getRemoteAddress();
188
-		$uid = $user->getUID();
189
-		$this->logger->warning("Two-factor challenge failed: $uid (Remote IP: $ip)");
190
-		$this->session->set('two_factor_auth_error', true);
191
-		return new RedirectResponse($this->urlGenerator->linkToRoute('core.TwoFactorChallenge.showChallenge', [
192
-			'challengeProviderId' => $provider->getId(),
193
-			'redirect_url' => $redirect_url,
194
-		]));
195
-	}
187
+        $ip = $this->request->getRemoteAddress();
188
+        $uid = $user->getUID();
189
+        $this->logger->warning("Two-factor challenge failed: $uid (Remote IP: $ip)");
190
+        $this->session->set('two_factor_auth_error', true);
191
+        return new RedirectResponse($this->urlGenerator->linkToRoute('core.TwoFactorChallenge.showChallenge', [
192
+            'challengeProviderId' => $provider->getId(),
193
+            'redirect_url' => $redirect_url,
194
+        ]));
195
+    }
196 196
 
197
-	#[NoAdminRequired]
198
-	#[NoCSRFRequired]
199
-	#[FrontpageRoute(verb: 'GET', url: 'login/setupchallenge')]
200
-	public function setupProviders(?string $redirect_url = null): StandaloneTemplateResponse {
201
-		$user = $this->userSession->getUser();
202
-		$setupProviders = $this->twoFactorManager->getLoginSetupProviders($user);
197
+    #[NoAdminRequired]
198
+    #[NoCSRFRequired]
199
+    #[FrontpageRoute(verb: 'GET', url: 'login/setupchallenge')]
200
+    public function setupProviders(?string $redirect_url = null): StandaloneTemplateResponse {
201
+        $user = $this->userSession->getUser();
202
+        $setupProviders = $this->twoFactorManager->getLoginSetupProviders($user);
203 203
 
204
-		$data = [
205
-			'providers' => $setupProviders,
206
-			'logout_url' => $this->getLogoutUrl(),
207
-			'redirect_url' => $redirect_url,
208
-		];
204
+        $data = [
205
+            'providers' => $setupProviders,
206
+            'logout_url' => $this->getLogoutUrl(),
207
+            'redirect_url' => $redirect_url,
208
+        ];
209 209
 
210
-		Util::addScript('core', 'twofactor-request-token');
211
-		return new StandaloneTemplateResponse($this->appName, 'twofactorsetupselection', $data, 'guest');
212
-	}
210
+        Util::addScript('core', 'twofactor-request-token');
211
+        return new StandaloneTemplateResponse($this->appName, 'twofactorsetupselection', $data, 'guest');
212
+    }
213 213
 
214
-	#[NoAdminRequired]
215
-	#[NoCSRFRequired]
216
-	#[FrontpageRoute(verb: 'GET', url: 'login/setupchallenge/{providerId}')]
217
-	public function setupProvider(string $providerId, ?string $redirect_url = null) {
218
-		$user = $this->userSession->getUser();
219
-		$providers = $this->twoFactorManager->getLoginSetupProviders($user);
214
+    #[NoAdminRequired]
215
+    #[NoCSRFRequired]
216
+    #[FrontpageRoute(verb: 'GET', url: 'login/setupchallenge/{providerId}')]
217
+    public function setupProvider(string $providerId, ?string $redirect_url = null) {
218
+        $user = $this->userSession->getUser();
219
+        $providers = $this->twoFactorManager->getLoginSetupProviders($user);
220 220
 
221
-		$provider = null;
222
-		foreach ($providers as $p) {
223
-			if ($p->getId() === $providerId) {
224
-				$provider = $p;
225
-				break;
226
-			}
227
-		}
221
+        $provider = null;
222
+        foreach ($providers as $p) {
223
+            if ($p->getId() === $providerId) {
224
+                $provider = $p;
225
+                break;
226
+            }
227
+        }
228 228
 
229
-		if ($provider === null) {
230
-			return new RedirectResponse($this->urlGenerator->linkToRoute('core.TwoFactorChallenge.selectChallenge'));
231
-		}
229
+        if ($provider === null) {
230
+            return new RedirectResponse($this->urlGenerator->linkToRoute('core.TwoFactorChallenge.selectChallenge'));
231
+        }
232 232
 
233
-		/** @var IActivatableAtLogin $provider */
234
-		$tmpl = $provider->getLoginSetup($user)->getBody();
235
-		$data = [
236
-			'provider' => $provider,
237
-			'logout_url' => $this->getLogoutUrl(),
238
-			'redirect_url' => $redirect_url,
239
-			'template' => $tmpl->fetchPage(),
240
-		];
241
-		$response = new StandaloneTemplateResponse($this->appName, 'twofactorsetupchallenge', $data, 'guest');
242
-		Util::addScript('core', 'twofactor-request-token');
243
-		return $response;
244
-	}
233
+        /** @var IActivatableAtLogin $provider */
234
+        $tmpl = $provider->getLoginSetup($user)->getBody();
235
+        $data = [
236
+            'provider' => $provider,
237
+            'logout_url' => $this->getLogoutUrl(),
238
+            'redirect_url' => $redirect_url,
239
+            'template' => $tmpl->fetchPage(),
240
+        ];
241
+        $response = new StandaloneTemplateResponse($this->appName, 'twofactorsetupchallenge', $data, 'guest');
242
+        Util::addScript('core', 'twofactor-request-token');
243
+        return $response;
244
+    }
245 245
 
246
-	/**
247
-	 * @todo handle the extreme edge case of an invalid provider ID and redirect to the provider selection page
248
-	 */
249
-	#[NoAdminRequired]
250
-	#[NoCSRFRequired]
251
-	#[FrontpageRoute(verb: 'POST', url: 'login/setupchallenge/{providerId}')]
252
-	public function confirmProviderSetup(string $providerId, ?string $redirect_url = null) {
253
-		return new RedirectResponse($this->urlGenerator->linkToRoute(
254
-			'core.TwoFactorChallenge.showChallenge',
255
-			[
256
-				'challengeProviderId' => $providerId,
257
-				'redirect_url' => $redirect_url,
258
-			]
259
-		));
260
-	}
246
+    /**
247
+     * @todo handle the extreme edge case of an invalid provider ID and redirect to the provider selection page
248
+     */
249
+    #[NoAdminRequired]
250
+    #[NoCSRFRequired]
251
+    #[FrontpageRoute(verb: 'POST', url: 'login/setupchallenge/{providerId}')]
252
+    public function confirmProviderSetup(string $providerId, ?string $redirect_url = null) {
253
+        return new RedirectResponse($this->urlGenerator->linkToRoute(
254
+            'core.TwoFactorChallenge.showChallenge',
255
+            [
256
+                'challengeProviderId' => $providerId,
257
+                'redirect_url' => $redirect_url,
258
+            ]
259
+        ));
260
+    }
261 261
 }
Please login to merge, or discard this patch.