diff --git a/changelog.d/9141.misc b/changelog.d/9141.misc new file mode 100644 index 00000000000..a9bafaa6465 --- /dev/null +++ b/changelog.d/9141.misc @@ -0,0 +1 @@ +Show "Verify this device" banner on un-verified devices. diff --git a/library/ui-strings/src/main/res/values-de/strings.xml b/library/ui-strings/src/main/res/values-de/strings.xml index 8eb8f730935..d2c35e39d6b 100644 --- a/library/ui-strings/src/main/res/values-de/strings.xml +++ b/library/ui-strings/src/main/res/values-de/strings.xml @@ -1290,6 +1290,8 @@ %d aktive Sitzungen Verifiziere dieses Gerät + Ab Oktober 2026 können unverifizierte Geräte keine Nachrichten mehr senden und empfangen. + Jetzt verifizieren Nutze eine vorhandene Sitzung um diese Sitzung zu verifizieren und ihr Zugriff auf verschlüsselte Nachrichten zu gewähren. Verifizieren Verifiziert diff --git a/library/ui-strings/src/main/res/values-fr/strings.xml b/library/ui-strings/src/main/res/values-fr/strings.xml index 6d3608a66e1..3bd58f0efdf 100644 --- a/library/ui-strings/src/main/res/values-fr/strings.xml +++ b/library/ui-strings/src/main/res/values-fr/strings.xml @@ -1265,6 +1265,8 @@ %d sessions actives Vérifier cet appareil + À partir d’octobre 2026, les appareils non vérifiés ne pourront plus envoyer ni recevoir de messages + Vérifier maintenant Utilisez une session existante pour vérifier celle-ci, ce qui lui permettra d’avoir accès aux messages chiffrés. Vérifier Vérifié diff --git a/library/ui-strings/src/main/res/values-hr/strings.xml b/library/ui-strings/src/main/res/values-hr/strings.xml index 4ac76dab8c3..9491f2c23d7 100644 --- a/library/ui-strings/src/main/res/values-hr/strings.xml +++ b/library/ui-strings/src/main/res/values-hr/strings.xml @@ -844,4 +844,8 @@ Ti si kreirao sobu %1$s je kreirao sobu Tvoja pozivnica + Verificirajte ovaj uređaj + Od listopada 2026. neverificirani uređaji više neće moći slati i primati poruke. + Saznajte više + Verificiraj sada diff --git a/library/ui-strings/src/main/res/values-nl/strings.xml b/library/ui-strings/src/main/res/values-nl/strings.xml index 581074b3979..47f45182244 100644 --- a/library/ui-strings/src/main/res/values-nl/strings.xml +++ b/library/ui-strings/src/main/res/values-nl/strings.xml @@ -1991,6 +1991,8 @@ Kan geen sessies ophalen Gebruik een bestaande sessie om deze te verifiëren en deze toegang te verlenen tot versleutelde berichten. Verifieer dit apparaat + Vanaf oktober 2026 kunnen niet-geverifieerde apparaten geen berichten meer verzenden en ontvangen. + Nu verifiëren %d actieve sessie %d actieve sessies diff --git a/library/ui-strings/src/main/res/values-pl/strings.xml b/library/ui-strings/src/main/res/values-pl/strings.xml index 34a3fb83648..ad29d2b39a3 100644 --- a/library/ui-strings/src/main/res/values-pl/strings.xml +++ b/library/ui-strings/src/main/res/values-pl/strings.xml @@ -1126,6 +1126,8 @@ %d aktywnych sesji Weryfikuj to urządzenie + Od października 2026 r. niezweryfikowane urządzenia nie będą mogły wysyłać ani odbierać wiadomości. + Zweryfikuj teraz Otwórz obecną sesję i użyj jej do zweryfikowania obecnej, przyznając jej dostęp do zaszyfrowanych wiadomości. Zweryfkuj Zweryfikowano diff --git a/library/ui-strings/src/main/res/values/strings.xml b/library/ui-strings/src/main/res/values/strings.xml index 6bcca18d660..02c87d3e9a3 100644 --- a/library/ui-strings/src/main/res/values/strings.xml +++ b/library/ui-strings/src/main/res/values/strings.xml @@ -2717,7 +2717,7 @@ Review to ensure your account is safe Verify the new login accessing your account: %1$s - As of April 2026 unverified devices will not be able to send and receive messages. + As of October 2026 unverified devices will not be able to send and receive messages. Verify now Manually Verify by Text diff --git a/vector/src/main/java/im/vector/app/features/home/HomeDetailViewModel.kt b/vector/src/main/java/im/vector/app/features/home/HomeDetailViewModel.kt index 5cc55f2e781..f714f2f00ab 100644 --- a/vector/src/main/java/im/vector/app/features/home/HomeDetailViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/HomeDetailViewModel.kt @@ -61,7 +61,8 @@ class HomeDetailViewModel @AssistedInject constructor( private val directRoomHelper: DirectRoomHelper, private val spaceStateHandler: SpaceStateHandler, private val autoAcceptInvites: AutoAcceptInvites, - private val vectorOverrides: VectorOverrides + private val vectorOverrides: VectorOverrides, + private val showVerifyDeviceBannerChecker: ShowVerifyDeviceBannerChecker, ) : VectorViewModel(initialState), CallProtocolsChecker.Listener { @@ -103,18 +104,20 @@ class HomeDetailViewModel @AssistedInject constructor( } private fun observeCrossSigningState() { - session - .flow() - .liveCrossSigningInfo(session.myUserId) - .onEach { info -> - val isVerified = info.getOrNull()?.isTrusted() ?: false - setState { - copy( - isSessionVerified = isVerified, - ) + if (showVerifyDeviceBannerChecker.canShowVerifyDeviceBanner(session.myUserId)) { + session + .flow() + .liveCrossSigningInfo(session.myUserId) + .onEach { info -> + val isVerified = info.getOrNull()?.isTrusted() ?: false + setState { + copy( + showVerifyDeviceBanner = !isVerified, + ) + } } - } - .launchIn(viewModelScope) + .launchIn(viewModelScope) + } } private fun observeDataStore() { diff --git a/vector/src/main/java/im/vector/app/features/home/HomeDetailViewState.kt b/vector/src/main/java/im/vector/app/features/home/HomeDetailViewState.kt index 812cbd807e1..d880a18bf4f 100644 --- a/vector/src/main/java/im/vector/app/features/home/HomeDetailViewState.kt +++ b/vector/src/main/java/im/vector/app/features/home/HomeDetailViewState.kt @@ -34,13 +34,10 @@ data class HomeDetailViewState( val pushCounter: Int = 0, val pstnSupportFlag: Boolean = false, val forceDialPadTab: Boolean = false, - // Set to true by default to avoid glitch - val isSessionVerified: Boolean = true, + // Set to false by default to avoid glitch + val showVerifyDeviceBanner: Boolean = false, ) : MavericksState { val showDialPadTab = forceDialPadTab || pstnSupportFlag - - // Temporarily disabled until we have a way to reset from the verification screen. - val showVerifyDeviceBanner = false // !isSessionVerified } sealed class HomeTab(@StringRes val titleRes: Int) { diff --git a/vector/src/main/java/im/vector/app/features/home/ShowVerifyDeviceBannerChecker.kt b/vector/src/main/java/im/vector/app/features/home/ShowVerifyDeviceBannerChecker.kt new file mode 100644 index 00000000000..d29399bfbb0 --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/home/ShowVerifyDeviceBannerChecker.kt @@ -0,0 +1,31 @@ +/* + * Copyright 2026 New Vector Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial + * Please see LICENSE files in the repository root for full details. + */ + +package im.vector.app.features.home + +import org.matrix.android.sdk.api.MatrixPatterns.getServerName +import java.security.MessageDigest +import javax.inject.Inject + +class ShowVerifyDeviceBannerChecker @Inject constructor() { + companion object { + private val EXCLUDED_HASHED_DOMAINS = setOf( + "9e6d1ca3e739dd3f879b8046af783402a34d247f879dfa1b531edbd56a56c1a6", + ) + } + + @OptIn(ExperimentalStdlibApi::class) + fun canShowVerifyDeviceBanner(userId: String): Boolean { + val sha256 = MessageDigest.getInstance("SHA-256") + val hashedDomain = userId.getServerName() + .split(".") + .takeLast(2) + .joinToString(".") + .let { sha256.digest(it.toByteArray()).toHexString() } + return hashedDomain !in EXCLUDED_HASHED_DOMAINS + } +} diff --git a/vector/src/test/java/im/vector/app/features/home/ShowVerifyDeviceBannerCheckerTest.kt b/vector/src/test/java/im/vector/app/features/home/ShowVerifyDeviceBannerCheckerTest.kt new file mode 100644 index 00000000000..e5c7bf1ec5e --- /dev/null +++ b/vector/src/test/java/im/vector/app/features/home/ShowVerifyDeviceBannerCheckerTest.kt @@ -0,0 +1,30 @@ +/* + * Copyright 2026 New Vector Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial + * Please see LICENSE files in the repository root for full details. + */ + +package im.vector.app.features.home + +import org.junit.Assert.assertTrue +import org.junit.Test +import org.junit.runner.RunWith +import org.robolectric.RobolectricTestRunner + +@RunWith(RobolectricTestRunner::class) +class ShowVerifyDeviceBannerCheckerTest { + private val checker = ShowVerifyDeviceBannerChecker() + + @Test + fun `should show banner for non excluded domain`() { + val userId = "@user:example.com" + assertTrue(checker.canShowVerifyDeviceBanner(userId)) + } + + @Test + fun `should show banner for matrix_org users`() { + val userId = "@user:matrix.org" + assertTrue(checker.canShowVerifyDeviceBanner(userId)) + } +}