initializeResultArray(); $currentBackendUser = $this->getBackendUser(); $tableName = $this->data['tableName']; // This renderType only works for user tables: be_users, fe_users if (!in_array($tableName, self::ALLOWED_TABLES, true)) { return $resultArray; } // Initialize a user based on the current table name $targetUser = ($tableName === 'be_users' || $tableName === 'be_users_settings') ? GeneralUtility::makeInstance(BackendUserAuthentication::class) : GeneralUtility::makeInstance(FrontendUserAuthentication::class); $userId = (int)($this->data['databaseRow'][$targetUser->userid_column] ?? 0); $targetUser->enablecolumns = ['deleted' => true]; $targetUser->setBeUserByUid($userId); $isDeactivationAllowed = true; // Providers from system maintainers can only be deactivated by system maintainers. // However, this check is only necessary if the target is a backend user. if (($targetUser instanceof BackendUserAuthentication) && $targetUser->isSystemMaintainer(true) && !$currentBackendUser->isSystemMaintainer() ) { $isDeactivationAllowed = false; } // Fetch providers from the mfa field $mfaProviders = json_decode($this->data['parameterArray']['itemFormElValue'] ?? '', true) ?? []; $hasFormValue = $mfaProviders !== []; // Initialize variables $html = $childHtml = $activeProviders = $lockedProviders = $mfaSetupInfo = []; $lang = $this->getLanguageService(); $enabledLabel = htmlspecialchars($lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.mfa.enabled')); $disabledLabel = htmlspecialchars($lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.mfa.disabled')); $status = '' . $disabledLabel . ''; // Unset invalid providers foreach ($mfaProviders as $identifier => $providerSettings) { if (!$this->mfaProviderRegistry->hasProvider($identifier)) { unset($mfaProviders[$identifier]); } } if ($mfaProviders !== []) { // Check if remaining providers are active and/or locked for the user foreach ($mfaProviders as $identifier => $providerSettings) { $provider = $this->mfaProviderRegistry->getProvider($identifier); $propertyManager = MfaProviderPropertyManager::create($provider, $targetUser); if (!$provider->isActive($propertyManager)) { continue; } $activeProviders[$identifier] = $provider; if ($provider->isLocked($propertyManager)) { $lockedProviders[] = $identifier; } } if ($activeProviders !== []) { // Change status label to MFA being enabled $status = '' . $enabledLabel . ''; $childHtml = $this->buildProviderListHtml($activeProviders, $lockedProviders, $isDeactivationAllowed); } } elseif (!$hasFormValue) { // Fallback: read MFA state directly from the user when no form value was provided $activeProviders = $this->mfaProviderRegistry->getActiveProviders($targetUser); $lockedProviders = array_keys($this->mfaProviderRegistry->getLockedProviders($targetUser)); if ($activeProviders !== []) { $status = '' . $enabledLabel . ''; $childHtml = $this->buildProviderListHtml($activeProviders, $lockedProviders, false); } $mfaSetupInfo[] = '
' . nl2br(htmlspecialchars($lang->sL('LLL:EXT:backend/Resources/Private/Language/user_profile.xlf:mfa_providers.description'))) . '
'; if (!$this->mfaProviderRegistry->hasProviders()) { $mfaSetupInfo[] = '' . htmlspecialchars($lang->sL('LLL:EXT:backend/Resources/Private/Language/user_profile.xlf:mfa_providers.not_available')) . ''; } else { $mfaSetupInfo[] = '
'; $mfaSetupInfo[] = ''; $mfaSetupInfo[] = htmlspecialchars($lang->sL('LLL:EXT:backend/Resources/Private/Language/user_profile.xlf:mfa_providers.' . ($activeProviders !== [] ? 'manage_link_title' : 'setup_link_title'))); $mfaSetupInfo[] = ''; $mfaSetupInfo[] = '
'; } } $fieldId = 't3js-form-field-mfa-id' . StringUtility::getUniqueId('-'); $html[] = '
'; $html[] = implode(PHP_EOL, $mfaSetupInfo); $html[] = '
'; $html[] = '
'; $html[] = '
'; $html[] = implode(PHP_EOL, $childHtml); if ($isDeactivationAllowed) { $html[] = '
'; $html[] = ''; $html[] = '
'; } $html[] = '
'; $html[] = '
'; $html[] = '
'; $html[] = '
'; // JavaScript is not needed in case deactivation is not allowed or no active providers exist if ($isDeactivationAllowed && $activeProviders !== []) { $resultArray['javaScriptModules'][] = JavaScriptModuleInstruction::create( '@typo3/backend/form-engine/element/mfa-info-element.js' )->instance('#' . $fieldId, ['userId' => $userId, 'tableName' => $tableName]); } $resultArray['html'] = $this->wrapWithFieldsetAndLegend($status . implode(PHP_EOL, $html)); return $resultArray; } /** * Build the HTML list of active MFA providers with their status badges * and optional deactivation buttons. * * @param MfaProviderManifestInterface[] $activeProviders * @param string[] $lockedProviders * @return string[] */ private function buildProviderListHtml( array $activeProviders, array $lockedProviders, bool $isDeactivationAllowed, ): array { $childHtml = []; $lang = $this->getLanguageService(); $childHtml[] = ''; return $childHtml; } }