app = $app; $this->auth = $auth; $this->session = $session; } protected function post(array $request = []) { if (!$this->session->getLocalUserId()) { return; } if (($_POST['action'] ?? '') == 'recover') { self::checkFormSecurityTokenRedirectOnError('2fa', 'twofactor_recovery'); $recovery_code = $_POST['recovery_code'] ?? ''; if (RecoveryCode::existsForUser($this->session->getLocalUserId(), $recovery_code)) { RecoveryCode::markUsedForUser($this->session->getLocalUserId(), $recovery_code); $this->session->set('2fa', true); DI::sysmsg()->addInfo($this->t('Remaining recovery codes: %d', RecoveryCode::countValidForUser($this->session->getLocalUserId()))); $this->auth->setForUser($this->app, User::getById($this->session->getLocalUserId()), true, true); $this->baseUrl->redirect($this->session->pop('return_path', '')); } else { DI::sysmsg()->addNotice($this->t('Invalid code, please retry.')); } } } protected function content(array $request = []): string { if (!$this->session->getLocalUserId()) { $this->baseUrl->redirect(); } // Already authenticated with 2FA token if ($this->session->get('2fa')) { $this->baseUrl->redirect(); } return Renderer::replaceMacros(Renderer::getMarkupTemplate('twofactor/recovery.tpl'), [ '$form_security_token' => self::getFormSecurityToken('twofactor_recovery'), '$title' => $this->t('Two-factor recovery'), '$message' => $this->t('

You can enter one of your one-time recovery codes in case you lost access to your mobile device.

'), '$recovery_message' => $this->t('Don’t have your phone? Enter a two-factor recovery code', '2fa/recovery'), '$recovery_code' => ['recovery_code', $this->t('Please enter a recovery code'), '', '', '', 'placeholder="000000-000000"'], '$recovery_label' => $this->t('Submit recovery code and complete login'), ]); } }