=> 0, 'try_count' => null, 'options' => ['key' => $config['code']], ] ); break; case 'yubikey': $this->getLanguage()->load('plg_multifactorauth_yubikey', JPATH_ADMINISTRATOR); Factory::getApplication()->bootComponent('com_users')->getMVCFactory()->createTable('Mfa', 'Administrator')->save( [ 'user_id' => $user->id, 'title' => \sprintf("%s %s", Text::_('PLG_MULTIFACTORAUTH_YUBIKEY_METHOD_TITLE'), $config['yubikey']), 'method' => 'yubikey', 'default' => 0, 'created_on' => Date::getInstance()->toSql(), 'last_used' => null, 'tries' => 0, 'try_count' => null, 'options' => ['id' => $config['yubikey']], ] ); break; default: $hasConverted = false; break; } } // Convert the emergency codes if ($hasConverted && !empty(@json_decode($otep, true))) { // Delete any other record with the same user_id and Method. $method = 'emergencycodes'; $userId = $user->id; $query = $db->createQuery() ->delete($db->quoteName('#__user_mfa')) ->where($db->quoteName('user_id') . ' = :user_id') ->where($db->quoteName('method') . ' = :method') ->bind(':user_id', $userId, ParameterType::INTEGER) ->bind(':method', $method); $db->setQuery($query)->execute(); // Migrate data Factory::getApplication()->bootComponent('com_users')->getMVCFactory()->createTable('Mfa', 'Administrator')->save( [ 'user_id' => $user->id, 'title' => Text::_('COM_USERS_USER_BACKUPCODES'), 'method' => 'backupcodes', 'default' => 0, 'created_on' => Date::getInstance()->toSql(), 'last_used' => null, 'tries' => 0, 'try_count' => null, 'options' => @json_decode($otep, true), ] ); } // Remove the legacy MFA $update = (object) [ 'id' => $user->id, 'otpKey' => '', 'otep' => '', ]; $db->updateObject('#__users', $update, ['id']); } /** * Tries to decrypt the legacy MFA configuration. * * @param string $secret Site's secret key * @param string $stringToDecrypt Base64-encoded and encrypted, JSON-encoded information * * @return string Decrypted, but JSON-encoded, information * * @link https://github.com/joomla/joomla-cms/pull/12497 * @since 4.2.0 */ private function decryptLegacyTFAString(string $secret, string $stringToDecrypt): string { // Is this already decrypted? try { $decrypted = @json_decode($stringToDecrypt, true); } catch (\Exception) { $decrypted = null; } if (!empty($decrypted)) { return $stringToDecrypt; } // No, we need to decrypt the string $aes = new Aes($secret, 256); $decrypted = $aes->decryptString($stringToDecrypt); if (!\is_string($decrypted) || empty($decrypted)) { $aes->setPassword($secret, true); $decrypted = $aes->decryptString($stringToDecrypt); } if (!\is_string($decrypted) || empty($decrypted)) { return ''; } // Remove the null padding added during encryption return rtrim($decrypted, "\0"); } }
The server returned a "500 - Whoops, looks like something went wrong."