diff --git a/TCHAP_CHANGES.md b/TCHAP_CHANGES.md index 80b5a43ccc..668b410f75 100644 --- a/TCHAP_CHANGES.md +++ b/TCHAP_CHANGES.md @@ -1,3 +1,11 @@ +Changes in Tchap 2.10.3 (2024-02-23) +==================================== + +Bugfixes 🐛 +---------- + - Restore rust crypto migration. ([#1013](https://github.com/tchapgouv/tchap-android/issues/1013)) + + Changes in Tchap 2.10.2 (2024-02-20) ==================================== diff --git a/library/ui-strings/src/main/res/values-fr/strings_tchap.xml b/library/ui-strings/src/main/res/values-fr/strings_tchap.xml index 08d4bc0c15..be48bdd199 100644 --- a/library/ui-strings/src/main/res/values-fr/strings_tchap.xml +++ b/library/ui-strings/src/main/res/values-fr/strings_tchap.xml @@ -110,7 +110,6 @@ Inscrire mon compte sur liste rouge Les autres utilisateurs ne pourront pas découvrir mon compte lors de leurs recherches Pour désactiver cette option, vous devez accepter que votre adresse e\u2011mail soit visible des autres utilisateurs lors de leurs recherches. - 🎄 Joyeuses Fêtes 🎄 La vérification de votre nouvelle session a échoué. diff --git a/library/ui-strings/src/main/res/values/strings_tchap.xml b/library/ui-strings/src/main/res/values/strings_tchap.xml index 635dd9b4ef..1df688e27c 100644 --- a/library/ui-strings/src/main/res/values/strings_tchap.xml +++ b/library/ui-strings/src/main/res/values/strings_tchap.xml @@ -110,7 +110,6 @@ Subscribe to the red list. "Other users won't be able to find my account in their search results." To disable this option, you must accept that your email address is visible to the other users. - 🎄 Happy Holidays 🎄 Failed to verify your new session. diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/network/RequestSender.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/network/RequestSender.kt index 88432c8fe6..5b9e2463ae 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/network/RequestSender.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/network/RequestSender.kt @@ -22,17 +22,23 @@ import dagger.Lazy import kotlinx.coroutines.CoroutineName import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.SupervisorJob +import kotlinx.coroutines.launch import org.matrix.android.sdk.api.auth.UserInteractiveAuthInterceptor +import org.matrix.android.sdk.api.extensions.tryOrNull import org.matrix.android.sdk.api.failure.Failure import org.matrix.android.sdk.api.failure.MatrixError import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysBackupLastVersionResult import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysVersion import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysVersionResult +import org.matrix.android.sdk.api.session.crypto.model.GossipingToDeviceObject import org.matrix.android.sdk.api.session.crypto.model.MXUsersDevicesMap import org.matrix.android.sdk.api.session.events.model.Content import org.matrix.android.sdk.api.session.events.model.Event +import org.matrix.android.sdk.api.session.events.model.EventType import org.matrix.android.sdk.api.session.uia.UiaResult import org.matrix.android.sdk.internal.auth.registration.handleUIA +import org.matrix.android.sdk.internal.crypto.OlmMachine +import org.matrix.android.sdk.internal.crypto.PerSessionBackupQueryRateLimiter import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.BackupKeysResult import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.CreateKeysBackupVersionBody import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.KeysBackupData @@ -53,6 +59,7 @@ import org.matrix.android.sdk.internal.crypto.model.rest.KeysUploadBody import org.matrix.android.sdk.internal.crypto.model.rest.KeysUploadResponse import org.matrix.android.sdk.internal.crypto.model.rest.RestKeyInfo import org.matrix.android.sdk.internal.crypto.model.rest.SignatureUploadResponse +import org.matrix.android.sdk.internal.crypto.store.IMXCommonCryptoStore import org.matrix.android.sdk.internal.crypto.tasks.ClaimOneTimeKeysForUsersDeviceTask import org.matrix.android.sdk.internal.crypto.tasks.DefaultSendVerificationMessageTask import org.matrix.android.sdk.internal.crypto.tasks.DownloadKeysForUsersTask @@ -95,7 +102,10 @@ internal class RequestSender @Inject constructor( private val getRoomSessionDataTask: GetRoomSessionDataTask, private val moshi: Moshi, cryptoCoroutineScope: CoroutineScope, + private val rateLimiter: PerSessionBackupQueryRateLimiter, + private val cryptoStore: IMXCommonCryptoStore, private val localEchoRepository: LocalEchoRepository, + private val olmMachine: Lazy ) { private val scope = CoroutineScope( @@ -236,9 +246,44 @@ internal class RequestSender @Inject constructor( .newBuilder() .add(CheckNumberType.JSON_ADAPTER_FACTORY) .build() - .adapter>>(Map::class.java) + .adapter>>(Map::class.java) val jsonBody = adapter.fromJson(body)!! + if (eventType == EventType.ROOM_KEY_REQUEST) { + scope.launch { + Timber.v("Intercepting key request, try backup") + /** + * It's a bit hacky, check how this can be better integrated with rust? + */ + try { + jsonBody.forEach { (_, deviceToContent) -> + deviceToContent.forEach { (_, content) -> + val hashMap = content as? Map<*, *> + val action = hashMap?.get("action")?.toString() + if (GossipingToDeviceObject.ACTION_SHARE_REQUEST == action) { + val requestBody = hashMap["body"] as? Map<*, *> + val roomId = requestBody?.get("room_id") as? String + val sessionId = requestBody?.get("session_id") as? String + val senderKey = requestBody?.get("sender_key") as? String + if (roomId != null && sessionId != null) { + // try to perform a lazy migration from legacy store + val legacy = tryOrNull("Failed to access legacy crypto store") { + cryptoStore.getInboundGroupSession(sessionId, senderKey.orEmpty()) + } + if (legacy == null || olmMachine.get().importRoomKey(legacy).isFailure) { + rateLimiter.tryFromBackupIfPossible(sessionId, roomId) + } + } + } + } + } + Timber.v("Intercepting key request, try backup") + } catch (failure: Throwable) { + Timber.v(failure, "Failed to use backup") + } + } + } + val userMap = MXUsersDevicesMap() userMap.join(jsonBody) diff --git a/towncrier.toml b/towncrier.toml index c549d28673..0854973730 100644 --- a/towncrier.toml +++ b/towncrier.toml @@ -1,5 +1,5 @@ [tool.towncrier] - version = "2.10.2" + version = "2.10.3" directory = "changelog.d" filename = "TCHAP_CHANGES.md" name = "Changes in Tchap" diff --git a/vector-app/build.gradle b/vector-app/build.gradle index 4ee522d2b5..3fceac3209 100644 --- a/vector-app/build.gradle +++ b/vector-app/build.gradle @@ -37,7 +37,7 @@ ext.versionMinor = 10 // Note: even values are reserved for regular release, odd values for hotfix release. // When creating a hotfix, you should decrease the value, since the current value // is the value for the next regular release. -ext.versionPatch = 2 +ext.versionPatch = 3 static def getGitTimestamp() { def cmd = 'git show -s --format=%ct' diff --git a/vector/src/main/java/im/vector/app/features/settings/VectorPreferences.kt b/vector/src/main/java/im/vector/app/features/settings/VectorPreferences.kt index d727ab283d..87512fad4d 100755 --- a/vector/src/main/java/im/vector/app/features/settings/VectorPreferences.kt +++ b/vector/src/main/java/im/vector/app/features/settings/VectorPreferences.kt @@ -227,7 +227,6 @@ class VectorPreferences @Inject constructor( private const val DID_ASK_TO_ENABLE_SESSION_PUSH = "DID_ASK_TO_ENABLE_SESSION_PUSH" const val TCHAP_SETTINGS_HIDE_FROM_USERS_DIRECTORY_PREFERENCE_KEY = "TCHAP_SETTINGS_HIDE_FROM_USERS_DIRECTORY_PREFERENCE_KEY" - const val TCHAP_SETTINGS_CHRISTMAS_PREFERENCE_KEY = "TCHAP_SETTINGS_CHRISTMAS_PREFERENCE_KEY" // Location Sharing const val SETTINGS_PREF_ENABLE_LOCATION_SHARING = "SETTINGS_PREF_ENABLE_LOCATION_SHARING" diff --git a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsActivity.kt b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsActivity.kt index 0435ee20bc..33557fabef 100755 --- a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsActivity.kt +++ b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsActivity.kt @@ -29,10 +29,7 @@ import im.vector.app.R import im.vector.app.core.extensions.replaceFragment import im.vector.app.core.platform.VectorBaseActivity import im.vector.app.databinding.ActivityVectorSettingsBinding -import im.vector.app.features.analytics.plan.ViewRoom import im.vector.app.features.discovery.DiscoverySettingsFragment -import im.vector.app.features.matrixto.MatrixToBottomSheet -import im.vector.app.features.navigation.Navigator import im.vector.app.features.navigation.SettingsActivityPayload import im.vector.app.features.settings.devices.VectorSettingsDevicesFragment import im.vector.app.features.settings.notifications.VectorSettingsNotificationFragment @@ -51,33 +48,9 @@ private const val KEY_ACTIVITY_PAYLOAD = "settings-activity-payload" @AndroidEntryPoint class VectorSettingsActivity : VectorBaseActivity(), PreferenceFragmentCompat.OnPreferenceStartFragmentCallback, - MatrixToBottomSheet.InteractionListener, FragmentManager.OnBackStackChangedListener, VectorSettingsFragmentInteractionListener { - // Tchap: Manage Christmas entry - private val fragmentLifecycleCallbacks = object : FragmentManager.FragmentLifecycleCallbacks() { - override fun onFragmentResumed(fm: FragmentManager, f: Fragment) { - if (f is MatrixToBottomSheet) { - f.interactionListener = this@VectorSettingsActivity - } - super.onFragmentResumed(fm, f) - } - - override fun onFragmentPaused(fm: FragmentManager, f: Fragment) { - if (f is MatrixToBottomSheet) { - f.interactionListener = null - } - super.onFragmentPaused(fm, f) - } - } - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - - supportFragmentManager.registerFragmentLifecycleCallbacks(fragmentLifecycleCallbacks, false) - } - override fun getBinding() = ActivityVectorSettingsBinding.inflate(layoutInflater) override fun getCoordinatorLayout() = views.coordinatorLayout @@ -133,7 +106,6 @@ class VectorSettingsActivity : VectorBaseActivity } override fun onDestroy() { - supportFragmentManager.unregisterFragmentLifecycleCallbacks(fragmentLifecycleCallbacks) supportFragmentManager.removeOnBackStackChangedListener(this) super.onDestroy() } @@ -189,14 +161,6 @@ class VectorSettingsActivity : VectorBaseActivity } } - // Tchap: Manage Christmas entry - override fun mxToBottomSheetNavigateToRoom(roomId: String, trigger: ViewRoom.Trigger?) { - navigator.openRoom(this, roomId, trigger = trigger) - } - override fun mxToBottomSheetSwitchToSpace(spaceId: String) { - navigator.switchToSpace(this, spaceId, Navigator.PostSwitchSpaceAction.None) - } - fun navigateTo(fragmentClass: Class, arguments: Bundle? = null) { supportFragmentManager.beginTransaction() .setCustomAnimations(R.anim.right_in, R.anim.fade_out, R.anim.fade_in, R.anim.right_out) diff --git a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsRootFragment.kt b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsRootFragment.kt index a51fd32672..ff376aefa8 100644 --- a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsRootFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsRootFragment.kt @@ -16,21 +16,14 @@ package im.vector.app.features.settings -import android.content.Context import android.os.Bundle import androidx.preference.Preference import dagger.hilt.android.AndroidEntryPoint import im.vector.app.R -import im.vector.app.core.extensions.singletonEntryPoint import im.vector.app.core.preference.VectorPreference import im.vector.app.core.utils.FirstThrottler import im.vector.app.core.utils.openUrlInChromeCustomTab import im.vector.app.features.analytics.plan.MobileScreen -import im.vector.app.features.matrixto.OriginOfMatrixTo -import im.vector.app.features.navigation.Navigator -import org.matrix.android.sdk.api.session.getRoomSummary -import org.matrix.android.sdk.api.session.room.model.Membership -import java.util.Calendar @AndroidEntryPoint class VectorSettingsRootFragment : @@ -41,14 +34,6 @@ class VectorSettingsRootFragment : private val firstThrottler = FirstThrottler(1000) - private lateinit var navigator: Navigator - - override fun onAttach(context: Context) { - val singletonEntryPoint = context.singletonEntryPoint() - navigator = singletonEntryPoint.navigator() - super.onAttach(context) - } - override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) analyticsScreenName = MobileScreen.ScreenName.Settings @@ -65,30 +50,6 @@ class VectorSettingsRootFragment : } false } - - // Tchap: Manage Christmas entry - if (Calendar.getInstance().before(Calendar.getInstance().apply { set(2024, 1, 10) })) { - findPreference(VectorPreferences.TCHAP_SETTINGS_CHRISTMAS_PREFERENCE_KEY)!!.let { - it.isVisible = true - it.onPreferenceClickListener = Preference.OnPreferenceClickListener { - if (firstThrottler.canHandle() is FirstThrottler.CanHandlerResult.Yes) { - val roomAlias = "#JoyeusesFtesdelapartdelquipeTchapGl2gFYK2OD:agent.dinum.tchap.gouv.fr" - val eventId = "\$xW9f1eJGxQ1xstdPCVReUKQO_sFU4242SfaMIfNh3NU" - - session.getRoomSummary(roomAlias).let { roomSummary -> - if (roomSummary?.membership == Membership.JOIN) { - navigator.openRoom(requireContext(), roomSummary.roomId) - } else { - session.permalinkService().createPermalink(roomAlias, eventId).let { link -> - navigator.openMatrixToBottomSheet(requireActivity(), link, OriginOfMatrixTo.LINK) - } - } - } - } - false - } - } - } } private fun tintIcons() { diff --git a/vector/src/main/res/xml/vector_settings_root.xml b/vector/src/main/res/xml/vector_settings_root.xml index 44064f2e60..13a3022233 100644 --- a/vector/src/main/res/xml/vector_settings_root.xml +++ b/vector/src/main/res/xml/vector_settings_root.xml @@ -62,10 +62,4 @@ app:fragment="im.vector.app.features.settings.legals.LegalsFragment" app:isPreferenceVisible="@bool/settings_root_legals_visible" /> - -