diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/sas/CancelCode.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/sas/CancelCode.kt index 149d099b66..a8ad1de421 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/sas/CancelCode.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/sas/CancelCode.kt @@ -27,7 +27,9 @@ enum class CancelCode(val value: String, val humanReadable: String) { UnexpectedMessage("m.unexpected_message", "the device received an unexpected message"), InvalidMessage("m.invalid_message", "an invalid message was received"), MismatchedKeys("m.key_mismatch", "Key mismatch"), - UserMismatchError("m.user_error", "User mismatch") + UserError("m.user_error", "User mismatch"), + UserMismatchError("m.user_mismatch", "Key mismatch"), + QrCodeInvalid("m.qr_code.invalid", "User mismatch") } fun safeValueOf(code: String?): CancelCode { diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/sas/QRVerificationTransaction.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/sas/QRVerificationTransaction.kt deleted file mode 100644 index 4464e6a0e4..0000000000 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/sas/QRVerificationTransaction.kt +++ /dev/null @@ -1,7 +0,0 @@ -package im.vector.matrix.android.api.session.crypto.sas - -interface QRVerificationTransaction : VerificationTransaction { - - fun userHasScannedRemoteQrCode(scannedData: String) - -} diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/sas/QrCodeVerificationTransaction.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/sas/QrCodeVerificationTransaction.kt new file mode 100644 index 0000000000..9e90681fc0 --- /dev/null +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/sas/QrCodeVerificationTransaction.kt @@ -0,0 +1,30 @@ +/* + * Copyright 2020 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.matrix.android.api.session.crypto.sas + +interface QrCodeVerificationTransaction : VerificationTransaction { + + /** + * To use to display a qr code, for the other user to scan it + */ + val qrCodeText: String? + + /** + * Call when you have scan the other user QR code + */ + fun userHasScannedRemoteQrCode(otherQrCodeText: String): CancelCode? +} diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/sas/VerificationService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/sas/VerificationService.kt index e1c0a1d455..aafc64d267 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/sas/VerificationService.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/sas/VerificationService.kt @@ -67,7 +67,10 @@ interface VerificationService { /** * Returns false if the request is unknown */ - fun readyPendingVerificationInDMs(otherUserId: String, roomId: String, transactionId: String): Boolean + fun readyPendingVerificationInDMs(methods: List, + otherUserId: String, + roomId: String, + transactionId: String): Boolean // fun transactionUpdated(tx: SasVerificationTransaction) diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/sas/VerificationTransaction.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/sas/VerificationTransaction.kt index 793c67ae33..16bb37e180 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/sas/VerificationTransaction.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/sas/VerificationTransaction.kt @@ -24,6 +24,8 @@ interface VerificationTransaction { val transactionId: String val otherUserId: String var otherDeviceId: String? + + // TODO Not used. Remove? val isIncoming: Boolean /** * User wants to cancel the transaction diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/rest/VerificationMethodValues.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/rest/VerificationMethodValues.kt index e3659bbde2..643ac5a495 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/rest/VerificationMethodValues.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/rest/VerificationMethodValues.kt @@ -33,11 +33,3 @@ internal fun VerificationMethod.toValue(): String { VerificationMethod.QR_CODE_SHOW -> VERIFICATION_METHOD_QR_CODE_SHOW } } - -internal val supportedVerificationMethods = - listOf( - VERIFICATION_METHOD_SAS, - VERIFICATION_METHOD_QR_CODE_SHOW, - VERIFICATION_METHOD_QR_CODE_SCAN, - VERIFICATION_METHOD_RECIPROCATE - ) diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/DefaultVerificationService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/DefaultVerificationService.kt index 1bf35b2108..b7d44aace2 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/DefaultVerificationService.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/DefaultVerificationService.kt @@ -55,11 +55,12 @@ import im.vector.matrix.android.internal.crypto.model.rest.KeyVerificationKey import im.vector.matrix.android.internal.crypto.model.rest.KeyVerificationMac import im.vector.matrix.android.internal.crypto.model.rest.KeyVerificationStart import im.vector.matrix.android.internal.crypto.model.rest.VERIFICATION_METHOD_QR_CODE_SCAN +import im.vector.matrix.android.internal.crypto.model.rest.VERIFICATION_METHOD_QR_CODE_SHOW import im.vector.matrix.android.internal.crypto.model.rest.VERIFICATION_METHOD_RECIPROCATE import im.vector.matrix.android.internal.crypto.model.rest.VERIFICATION_METHOD_SAS -import im.vector.matrix.android.internal.crypto.model.rest.supportedVerificationMethods import im.vector.matrix.android.internal.crypto.model.rest.toValue import im.vector.matrix.android.internal.crypto.store.IMXCryptoStore +import im.vector.matrix.android.internal.crypto.verification.qrcode.DefaultQrCodeVerificationTransaction import im.vector.matrix.android.internal.crypto.verification.qrcode.QrCodeData import im.vector.matrix.android.internal.crypto.verification.qrcode.generateSharedSecret import im.vector.matrix.android.internal.crypto.verification.qrcode.toUrl @@ -413,6 +414,16 @@ internal class DefaultVerificationService @Inject constructor( autoAccept).also { txConfigure(it) } addTransaction(tx) tx.acceptVerificationEvent(otherUserId, startReq) + } else if (startReq.method == VERIFICATION_METHOD_RECIPROCATE) { + // Other user has scanned my QR code + val pendingTransaction = getExistingTransaction(otherUserId, startReq.transactionID!!) + + if (pendingTransaction != null && pendingTransaction is DefaultQrCodeVerificationTransaction) { + pendingTransaction.onStartReceived(startReq) + } else { + Timber.w("## SAS onStartRequestReceived - unknown transaction ${startReq.transactionID}") + return CancelCode.UnknownTransaction + } } else { Timber.e("## SAS onStartRequestReceived - unknown method ${startReq.method}") return CancelCode.UnknownMethod @@ -606,7 +617,7 @@ internal class DefaultVerificationService @Inject constructor( return } - handleReadyReceived(event.senderId, readyReq) + handleReadyReceived(event.senderId, event.roomId!!, readyReq) } private fun onRoomDoneReceived(event: Event) { @@ -651,7 +662,7 @@ internal class DefaultVerificationService @Inject constructor( } } - private fun handleReadyReceived(senderId: String, readyReq: VerificationInfoReady) { + private fun handleReadyReceived(senderId: String, roomId: String, readyReq: VerificationInfoReady) { val existingRequest = getExistingVerificationRequest(senderId)?.find { it.transactionId == readyReq.transactionID } if (existingRequest == null) { Timber.e("## SAS Received Ready for unknown request txId:${readyReq.transactionID} fromDevice ${readyReq.fromDevice}") @@ -710,10 +721,26 @@ internal class DefaultVerificationService @Inject constructor( ).toUrl() } + if (qrCodeText != null) { + // Create the pending transaction + val tx = DefaultQrCodeVerificationTransaction( + readyReq.transactionID!!, + senderId, + readyReq.fromDevice, + crossSigningService, + cryptoStore, + myGeneratedSharedSecret!!, + qrCodeText, + deviceId ?: "", + false) + + tx.transport = verificationTransportRoomMessageFactory.createTransport(roomId, tx) + + addTransaction(tx) + } + updatePendingRequest(existingRequest.copy( - readyInfo = readyReq, - myGeneratedSecret = myGeneratedSharedSecret, - qrCodeText = qrCodeText + readyInfo = readyReq )) } @@ -916,23 +943,26 @@ internal class DefaultVerificationService @Inject constructor( } } - override fun readyPendingVerificationInDMs(otherUserId: String, roomId: String, transactionId: String): Boolean { + override fun readyPendingVerificationInDMs(methods: List, + otherUserId: String, + roomId: String, + transactionId: String): Boolean { Timber.v("## SAS readyPendingVerificationInDMs $otherUserId room:$roomId tx:$transactionId") // Let's find the related request val existingRequest = getExistingVerificationRequest(otherUserId, transactionId) if (existingRequest != null) { // we need to send a ready event, with matching methods val transport = verificationTransportRoomMessageFactory.createTransport(roomId, null) - // TODO We should not use supportedVerificationMethods here, because it depends on the client implementation - val methods = existingRequest.requestInfo?.methods?.intersect(supportedVerificationMethods)?.toList() + val computedMethods = computeReadyMethods(existingRequest.requestInfo?.methods, methods) if (methods.isNullOrEmpty()) { Timber.i("Cannot ready this request, no common methods found txId:$transactionId") // TODO buttons should not be shown in this case? return false } // TODO this is not yet related to a transaction, maybe we should use another method like for cancel? - val readyMsg = transport.createReady(transactionId, deviceId ?: "", methods) - transport.sendToOther(EventType.KEY_VERIFICATION_READY, readyMsg, + val readyMsg = transport.createReady(transactionId, deviceId ?: "", computedMethods) + transport.sendToOther(EventType.KEY_VERIFICATION_READY, + readyMsg, VerificationTxState.None, CancelCode.User, null // TODO handle error? @@ -946,6 +976,31 @@ internal class DefaultVerificationService @Inject constructor( } } + private fun computeReadyMethods(otherUserMethods: List?, methods: List): List { + if (otherUserMethods.isNullOrEmpty()) { + return emptyList() + } + + val result = mutableSetOf() + + if (VERIFICATION_METHOD_SAS in otherUserMethods && VerificationMethod.SAS in methods) { + // Other can do SAS and so do I + result + VERIFICATION_METHOD_SAS + } + if (VERIFICATION_METHOD_QR_CODE_SCAN in otherUserMethods && VerificationMethod.QR_CODE_SHOW in methods) { + // Other can Scan and I can show QR code + result + VERIFICATION_METHOD_QR_CODE_SHOW + result + VERIFICATION_METHOD_RECIPROCATE + } + if (VERIFICATION_METHOD_QR_CODE_SHOW in otherUserMethods && VerificationMethod.QR_CODE_SCAN in methods) { + // Other can show and I can scan QR code + result + VERIFICATION_METHOD_QR_CODE_SCAN + result + VERIFICATION_METHOD_RECIPROCATE + } + + return result.toList() + } + /** * This string must be unique for the pair of users performing verification for the duration that the transaction is valid */ diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/PendingVerificationRequest.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/PendingVerificationRequest.kt index 4548313ba1..cc0df09adb 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/PendingVerificationRequest.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/PendingVerificationRequest.kt @@ -38,12 +38,7 @@ data class PendingVerificationRequest( val readyInfo: VerificationInfoReady? = null, val cancelConclusion: CancelCode? = null, val isSuccessful: Boolean = false, - val handledByOtherSession: Boolean = false, - // TODO Move to OutgoingQrCodeTransaction - val myGeneratedSecret: String? = null, - // TODO Move to OutgoingQrCodeTransaction - val qrCodeText: String? = null - + val handledByOtherSession: Boolean = false ) { val isReady: Boolean = readyInfo != null val isSent: Boolean = transactionId != null diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/qrcode/DefaultQrCodeVerificationTransaction.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/qrcode/DefaultQrCodeVerificationTransaction.kt new file mode 100644 index 0000000000..a85c68ca83 --- /dev/null +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/qrcode/DefaultQrCodeVerificationTransaction.kt @@ -0,0 +1,156 @@ +/* + * Copyright 2020 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.matrix.android.internal.crypto.verification.qrcode + +import im.vector.matrix.android.api.MatrixCallback +import im.vector.matrix.android.api.session.crypto.crosssigning.CrossSigningService +import im.vector.matrix.android.api.session.crypto.sas.CancelCode +import im.vector.matrix.android.api.session.crypto.sas.QrCodeVerificationTransaction +import im.vector.matrix.android.api.session.crypto.sas.VerificationTxState +import im.vector.matrix.android.api.session.events.model.EventType +import im.vector.matrix.android.internal.crypto.model.rest.SignatureUploadResponse +import im.vector.matrix.android.internal.crypto.store.IMXCryptoStore +import im.vector.matrix.android.internal.crypto.verification.DefaultVerificationTransaction +import im.vector.matrix.android.internal.crypto.verification.VerificationInfo +import im.vector.matrix.android.internal.crypto.verification.VerificationInfoStart +import timber.log.Timber +import kotlin.properties.Delegates + +internal class DefaultQrCodeVerificationTransaction( + override val transactionId: String, + override val otherUserId: String, + override var otherDeviceId: String?, + private val crossSigningService: CrossSigningService, + private val cryptoStore: IMXCryptoStore, + private val myGeneratedSecret: String, + override val qrCodeText: String, + val deviceId: String, + override val isIncoming: Boolean +) : DefaultVerificationTransaction(transactionId, otherUserId, otherDeviceId, isIncoming), QrCodeVerificationTransaction { + + override var cancelledReason: CancelCode? = null + + override var state by Delegates.observable(VerificationTxState.None) { _, _, _ -> + listeners.forEach { + try { + it.transactionUpdated(this) + } catch (e: Throwable) { + Timber.e(e, "## Error while notifying listeners") + } + } + } + + override fun userHasScannedRemoteQrCode(otherQrCodeText: String): CancelCode? { + val qrCodeData = otherQrCodeText.toQrCodeData() ?: return CancelCode.QrCodeInvalid + + // Perform some checks + if (qrCodeData.action != QrCodeData.ACTION_VERIFY) { + return CancelCode.QrCodeInvalid + } + + if (qrCodeData.userId != otherUserId) { + return CancelCode.UserMismatchError + } + + if (qrCodeData.requestEventId != transactionId) { + return CancelCode.QrCodeInvalid + } + + // check master key + if (qrCodeData.otherUserKey != crossSigningService.getUserCrossSigningKeys(otherUserId)?.masterKey()?.unpaddedBase64PublicKey) { + return CancelCode.MismatchedKeys + } + + val otherDevices = cryptoStore.getUserDevices(otherUserId) + qrCodeData.keys.keys.forEach { key -> + Timber.w("Checking key $key") + val fingerprint = otherDevices?.get(key)?.fingerprint() + if (fingerprint != null && fingerprint != qrCodeData.keys[key]) { + return CancelCode.MismatchedKeys + } + } + + // All checks are correct + + // Trust the other user + trust() + state = VerificationTxState.Verified + + // Send the shared secret so that sender can trust me + // qrCodeData.sharedSecret will be used to send the start request + start(qrCodeData.sharedSecret) + + return null + } + + fun start(remoteSecret: String) { + if (state != VerificationTxState.None) { + Timber.e("## SAS O: start verification from invalid state") + // should I cancel?? + throw IllegalStateException("Interactive Key verification already started") + } + + val startMessage = transport.createStartForQrCode( + deviceId, + transactionId, + remoteSecret + ) + + transport.sendToOther( + EventType.KEY_VERIFICATION_START, + startMessage, + VerificationTxState.Started, + CancelCode.User, + null + ) + } + + override fun acceptVerificationEvent(senderId: String, info: VerificationInfo) { + } + + override fun cancel() { + cancel(CancelCode.User) + } + + override fun cancel(code: CancelCode) { + cancelledReason = code + state = VerificationTxState.Cancelled + transport.cancelTransaction(transactionId, otherUserId, otherDeviceId ?: "", code) + } + + override fun isToDeviceTransport() = false + + // Remote user has scanned our QR code. check that the secret matched, so we can trust him + fun onStartReceived(startReq: VerificationInfoStart) { + if (startReq.sharedSecret == myGeneratedSecret) { + // Ok, we can trust the other user + trust() + } else { + // Display a warning + cancelledReason = CancelCode.QrCodeInvalid + state = VerificationTxState.OnCancelled + } + } + + private fun trust() { + crossSigningService.trustUser(otherUserId, object : MatrixCallback { + override fun onFailure(failure: Throwable) { + Timber.e(failure, "## QR Verification: Failed to trust User $otherUserId") + } + }) + } +} diff --git a/vector/src/main/java/im/vector/riotx/features/crypto/verification/VerificationBottomSheetViewModel.kt b/vector/src/main/java/im/vector/riotx/features/crypto/verification/VerificationBottomSheetViewModel.kt index 5a680556ca..6b67e8f477 100644 --- a/vector/src/main/java/im/vector/riotx/features/crypto/verification/VerificationBottomSheetViewModel.kt +++ b/vector/src/main/java/im/vector/riotx/features/crypto/verification/VerificationBottomSheetViewModel.kt @@ -31,7 +31,7 @@ import com.squareup.inject.assisted.AssistedInject import im.vector.matrix.android.api.MatrixCallback import im.vector.matrix.android.api.session.Session import im.vector.matrix.android.api.session.crypto.sas.CancelCode -import im.vector.matrix.android.api.session.crypto.sas.QRVerificationTransaction +import im.vector.matrix.android.api.session.crypto.sas.QrCodeVerificationTransaction import im.vector.matrix.android.api.session.crypto.sas.SasVerificationTransaction import im.vector.matrix.android.api.session.crypto.sas.VerificationMethod import im.vector.matrix.android.api.session.crypto.sas.VerificationService @@ -166,7 +166,7 @@ class VerificationBottomSheetViewModel @AssistedInject constructor(@Assisted ini } is VerificationAction.RemoteQrCodeScanned -> { val existingTransaction = session.getVerificationService() - .getExistingTransaction(action.otherUserId, action.transactionId) as? QRVerificationTransaction + .getExistingTransaction(action.otherUserId, action.transactionId) as? QrCodeVerificationTransaction existingTransaction ?.userHasScannedRemoteQrCode(action.scannedData) } diff --git a/vector/src/main/java/im/vector/riotx/features/crypto/verification/choose/VerificationChooseMethodViewModel.kt b/vector/src/main/java/im/vector/riotx/features/crypto/verification/choose/VerificationChooseMethodViewModel.kt index e4b8f75a8c..852488a3ed 100644 --- a/vector/src/main/java/im/vector/riotx/features/crypto/verification/choose/VerificationChooseMethodViewModel.kt +++ b/vector/src/main/java/im/vector/riotx/features/crypto/verification/choose/VerificationChooseMethodViewModel.kt @@ -22,8 +22,9 @@ import com.airbnb.mvrx.ViewModelContext import com.squareup.inject.assisted.Assisted import com.squareup.inject.assisted.AssistedInject import im.vector.matrix.android.api.session.Session -import im.vector.matrix.android.api.session.crypto.sas.VerificationService +import im.vector.matrix.android.api.session.crypto.sas.QrCodeVerificationTransaction import im.vector.matrix.android.api.session.crypto.sas.VerificationMethod +import im.vector.matrix.android.api.session.crypto.sas.VerificationService import im.vector.matrix.android.api.session.crypto.sas.VerificationTransaction import im.vector.matrix.android.internal.crypto.verification.PendingVerificationRequest import im.vector.riotx.core.di.HasScreenInjector @@ -46,9 +47,19 @@ class VerificationChooseMethodViewModel @AssistedInject constructor( private val session: Session ) : VectorViewModel(initialState), VerificationService.VerificationListener { - override fun transactionCreated(tx: VerificationTransaction) {} + override fun transactionCreated(tx: VerificationTransaction) { + transactionUpdated(tx) + } - override fun transactionUpdated(tx: VerificationTransaction) {} + override fun transactionUpdated(tx: VerificationTransaction) = withState { state -> + if (tx.transactionId == state.transactionId && tx is QrCodeVerificationTransaction) { + setState { + copy( + qrCodeText = tx.qrCodeText + ) + } + } + } override fun verificationRequestUpdated(pr: PendingVerificationRequest) = withState { state -> val pvr = session.getVerificationService().getExistingVerificationRequest(state.otherUserId, state.transactionId) @@ -57,7 +68,6 @@ class VerificationChooseMethodViewModel @AssistedInject constructor( copy( otherCanShowQrCode = pvr?.hasMethod(VerificationMethod.QR_CODE_SHOW) ?: false, otherCanScanQrCode = pvr?.hasMethod(VerificationMethod.QR_CODE_SCAN) ?: false, - qrCodeText = pvr?.qrCodeText, SASModeAvailable = pvr?.hasMethod(VerificationMethod.SAS) ?: false ) } @@ -92,7 +102,6 @@ class VerificationChooseMethodViewModel @AssistedInject constructor( transactionId = args.verificationId ?: "", otherCanShowQrCode = pvr?.hasMethod(VerificationMethod.QR_CODE_SHOW) ?: false, otherCanScanQrCode = pvr?.hasMethod(VerificationMethod.QR_CODE_SCAN) ?: false, - qrCodeText = pvr?.qrCodeText, SASModeAvailable = pvr?.hasMethod(VerificationMethod.SAS) ?: false ) } diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailViewModel.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailViewModel.kt index 695dfa8d33..b3b31aa00e 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailViewModel.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailViewModel.kt @@ -809,7 +809,10 @@ class RoomDetailViewModel @AssistedInject constructor(@Assisted initialState: Ro private fun handleAcceptVerification(action: RoomDetailAction.AcceptVerificationRequest) { Timber.v("## SAS handleAcceptVerification ${action.otherUserId}, roomId:${room.roomId}, txId:${action.transactionId}") - if (session.getVerificationService().readyPendingVerificationInDMs(action.otherUserId, room.roomId, + if (session.getVerificationService().readyPendingVerificationInDMs( + supportedVerificationMethods, + action.otherUserId, + room.roomId, action.transactionId)) { _requestLiveData.postValue(LiveEvent(Success(action))) }