This commit is contained in:
Valere 2019-12-30 18:42:32 +01:00
parent 6bf3a703df
commit 3eed9b5083
16 changed files with 19 additions and 59 deletions

View File

@ -25,10 +25,8 @@ import im.vector.matrix.android.api.session.room.model.message.*
import im.vector.matrix.android.internal.crypto.algorithms.olm.OlmDecryptionResult import im.vector.matrix.android.internal.crypto.algorithms.olm.OlmDecryptionResult
import im.vector.matrix.android.internal.crypto.verification.DefaultSasVerificationService import im.vector.matrix.android.internal.crypto.verification.DefaultSasVerificationService
import im.vector.matrix.android.internal.di.DeviceId import im.vector.matrix.android.internal.di.DeviceId
import im.vector.matrix.android.internal.di.SessionDatabase
import im.vector.matrix.android.internal.di.UserId import im.vector.matrix.android.internal.di.UserId
import im.vector.matrix.android.internal.task.Task import im.vector.matrix.android.internal.task.Task
import io.realm.RealmConfiguration
import timber.log.Timber import timber.log.Timber
import java.util.* import java.util.*
import javax.inject.Inject import javax.inject.Inject
@ -51,8 +49,7 @@ internal class DefaultRoomVerificationUpdateTask @Inject constructor(
private val transactionsHandledByOtherDevice = ArrayList<String>() private val transactionsHandledByOtherDevice = ArrayList<String>()
} }
override suspend fun execute(params: RoomVerificationUpdateTask.Params): Unit { override suspend fun execute(params: RoomVerificationUpdateTask.Params) {
// TODO ignore initial sync or back pagination? // TODO ignore initial sync or back pagination?
val now = System.currentTimeMillis() val now = System.currentTimeMillis()
@ -160,5 +157,4 @@ internal class DefaultRoomVerificationUpdateTask @Inject constructor(
} }
} }
} }
} }

View File

@ -196,13 +196,13 @@ internal class DefaultSasVerificationService @Inject constructor(
val senderId = event.senderId ?: return val senderId = event.senderId ?: return
if (requestInfo.toUserId != credentials.userId) { if (requestInfo.toUserId != credentials.userId) {
//I should ignore this, it's not for me // I should ignore this, it's not for me
Timber.w("## SAS Verification ignoring request from ${event.senderId}, not sent to me") Timber.w("## SAS Verification ignoring request from ${event.senderId}, not sent to me")
return return
} }
if(checkKeysAreDownloaded(senderId, requestInfo.fromDevice) == null) { if (checkKeysAreDownloaded(senderId, requestInfo.fromDevice) == null) {
//I should ignore this, it's not for me // I should ignore this, it's not for me
Timber.e("## SAS Verification device ${requestInfo.fromDevice} is not knwon") Timber.e("## SAS Verification device ${requestInfo.fromDevice} is not knwon")
// TODO cancel? // TODO cancel?
return return
@ -216,7 +216,7 @@ internal class DefaultSasVerificationService @Inject constructor(
val pendingVerificationRequest = PendingVerificationRequest( val pendingVerificationRequest = PendingVerificationRequest(
isIncoming = true, isIncoming = true,
otherUserId = senderId,//requestInfo.toUserId, otherUserId = senderId, // requestInfo.toUserId,
transactionId = event.eventId, transactionId = event.eventId,
requestInfo = requestInfo requestInfo = requestInfo
) )
@ -512,13 +512,12 @@ internal class DefaultSasVerificationService @Inject constructor(
// TODO should we cancel? // TODO should we cancel?
return return
} }
if(checkKeysAreDownloaded(event.senderId, readyReq.fromDevice ?: "") == null) { if (checkKeysAreDownloaded(event.senderId, readyReq.fromDevice ?: "") == null) {
Timber.e("## SAS Verification device ${readyReq.fromDevice} is not knwown") Timber.e("## SAS Verification device ${readyReq.fromDevice} is not knwown")
// TODO cancel? // TODO cancel?
return return
} }
handleReadyReceived(event.senderId, readyReq) handleReadyReceived(event.senderId, readyReq)
} }
@ -616,8 +615,7 @@ internal class DefaultSasVerificationService @Inject constructor(
override fun requestKeyVerificationInDMs(userId: String, roomId: String, callback: MatrixCallback<String>?) override fun requestKeyVerificationInDMs(userId: String, roomId: String, callback: MatrixCallback<String>?)
: PendingVerificationRequest { : PendingVerificationRequest {
Timber.i("## SAS Requesting verification to user: $userId in room $roomId")
Timber.i("## SAS Requesting verification to user: $userId in room ${roomId}")
val requestsForUser = pendingRequests[userId] val requestsForUser = pendingRequests[userId]
?: ArrayList<PendingVerificationRequest>().also { ?: ArrayList<PendingVerificationRequest>().also {
pendingRequests[userId] = it pendingRequests[userId] = it

View File

@ -68,6 +68,5 @@ internal class VerificationMessageLiveObserver @Inject constructor(
roomVerificationUpdateTask.configureWith( roomVerificationUpdateTask.configureWith(
RoomVerificationUpdateTask.Params(events, sasVerificationService, cryptoService) RoomVerificationUpdateTask.Params(events, sasVerificationService, cryptoService)
).executeBy(taskExecutor) ).executeBy(taskExecutor)
} }
} }

View File

@ -273,7 +273,6 @@ interface FragmentModule {
@FragmentKey(SoftLogoutFragment::class) @FragmentKey(SoftLogoutFragment::class)
fun bindSoftLogoutFragment(fragment: SoftLogoutFragment): Fragment fun bindSoftLogoutFragment(fragment: SoftLogoutFragment): Fragment
@Binds @Binds
@IntoMap @IntoMap
@FragmentKey(VerificationRequestFragment::class) @FragmentKey(VerificationRequestFragment::class)
@ -284,13 +283,11 @@ interface FragmentModule {
@FragmentKey(VerificationChooseMethodFragment::class) @FragmentKey(VerificationChooseMethodFragment::class)
fun bindVerificationMethodChooserFragment(fragment: VerificationChooseMethodFragment): Fragment fun bindVerificationMethodChooserFragment(fragment: VerificationChooseMethodFragment): Fragment
@Binds @Binds
@IntoMap @IntoMap
@FragmentKey(SASVerificationCodeFragment::class) @FragmentKey(SASVerificationCodeFragment::class)
fun bindVerificationSasCodeFragment(fragment: SASVerificationCodeFragment): Fragment fun bindVerificationSasCodeFragment(fragment: SASVerificationCodeFragment): Fragment
@Binds @Binds
@IntoMap @IntoMap
@FragmentKey(VerificationConclusionFragment::class) @FragmentKey(VerificationConclusionFragment::class)

View File

@ -37,7 +37,6 @@ class SASVerificationCodeFragment @Inject constructor(
@BindView(R.id.sas_emoji_grid) @BindView(R.id.sas_emoji_grid)
lateinit var emojiGrid: ViewGroup lateinit var emojiGrid: ViewGroup
@BindView(R.id.sas_decimal_code) @BindView(R.id.sas_decimal_code)
lateinit var decimalTextView: TextView lateinit var decimalTextView: TextView
@ -56,7 +55,6 @@ class SASVerificationCodeFragment @Inject constructor(
@BindView(R.id.emoji6) @BindView(R.id.emoji6)
lateinit var emoji6View: ViewGroup lateinit var emoji6View: ViewGroup
private val viewModel by fragmentViewModel(SASVerificationCodeViewModel::class) private val viewModel by fragmentViewModel(SASVerificationCodeViewModel::class)
private val sharedViewModel by parentFragmentViewModel(VerificationBottomSheetViewModel::class) private val sharedViewModel by parentFragmentViewModel(VerificationBottomSheetViewModel::class)
@ -65,7 +63,7 @@ class SASVerificationCodeFragment @Inject constructor(
if (state.supportsEmoji) { if (state.supportsEmoji) {
decimalTextView.isVisible = false decimalTextView.isVisible = false
when(val emojiDescription = state.emojiDescription) { when (val emojiDescription = state.emojiDescription) {
is Success -> { is Success -> {
sasLoadingProgress.isVisible = false sasLoadingProgress.isVisible = false
emojiGrid.isVisible = true emojiGrid.isVisible = true
@ -104,20 +102,19 @@ class SASVerificationCodeFragment @Inject constructor(
} }
if (state.isWaitingFromOther) { if (state.isWaitingFromOther) {
//hide buttons // hide buttons
ButtonsVisibilityGroup.isInvisible = true ButtonsVisibilityGroup.isInvisible = true
sasCodeWaitingPartnerText.isVisible = true sasCodeWaitingPartnerText.isVisible = true
} else { } else {
ButtonsVisibilityGroup.isVisible = true ButtonsVisibilityGroup.isVisible = true
sasCodeWaitingPartnerText.isVisible = false sasCodeWaitingPartnerText.isVisible = false
} }
} }
is Fail -> { is Fail -> {
sasLoadingProgress.isVisible = false sasLoadingProgress.isVisible = false
emojiGrid.isInvisible = true emojiGrid.isInvisible = true
ButtonsVisibilityGroup.isInvisible = true ButtonsVisibilityGroup.isInvisible = true
//TODO? // TODO?
} }
else -> { else -> {
sasLoadingProgress.isVisible = true sasLoadingProgress.isVisible = true
@ -126,15 +123,15 @@ class SASVerificationCodeFragment @Inject constructor(
} }
} }
} else { } else {
//Decimal // Decimal
emojiGrid.isInvisible = true emojiGrid.isInvisible = true
decimalTextView.isVisible = true decimalTextView.isVisible = true
val decimalCode = state.decimalDescription.invoke() val decimalCode = state.decimalDescription.invoke()
decimalTextView.text = decimalCode decimalTextView.text = decimalCode
//TODO // TODO
if (state.isWaitingFromOther) { if (state.isWaitingFromOther) {
//hide buttons // hide buttons
ButtonsVisibilityGroup.isInvisible = true ButtonsVisibilityGroup.isInvisible = true
sasCodeWaitingPartnerText.isVisible = true sasCodeWaitingPartnerText.isVisible = true
} else { } else {
@ -144,10 +141,9 @@ class SASVerificationCodeFragment @Inject constructor(
} }
} }
@OnClick(R.id.sas_request_continue_button) @OnClick(R.id.sas_request_continue_button)
fun onMatchButtonTapped() = withState(viewModel) { state -> fun onMatchButtonTapped() = withState(viewModel) { state ->
//UX echo // UX echo
ButtonsVisibilityGroup.isInvisible = true ButtonsVisibilityGroup.isInvisible = true
sasCodeWaitingPartnerText.isVisible = true sasCodeWaitingPartnerText.isVisible = true
sharedViewModel.handle(VerificationAction.SASMatchAction(state.otherUserId, state.transactionId)) sharedViewModel.handle(VerificationAction.SASMatchAction(state.otherUserId, state.transactionId))
@ -155,10 +151,9 @@ class SASVerificationCodeFragment @Inject constructor(
@OnClick(R.id.sas_request_cancel_button) @OnClick(R.id.sas_request_cancel_button)
fun onDoNotMatchButtonTapped() = withState(viewModel) { state -> fun onDoNotMatchButtonTapped() = withState(viewModel) { state ->
//UX echo // UX echo
ButtonsVisibilityGroup.isInvisible = true ButtonsVisibilityGroup.isInvisible = true
sasCodeWaitingPartnerText.isVisible = true sasCodeWaitingPartnerText.isVisible = true
sharedViewModel.handle(VerificationAction.SASDoNotMatchAction(state.otherUserId, state.transactionId)) sharedViewModel.handle(VerificationAction.SASDoNotMatchAction(state.otherUserId, state.transactionId))
} }
} }

View File

@ -41,8 +41,7 @@ data class SASVerificationCodeViewState(
class SASVerificationCodeViewModel @AssistedInject constructor( class SASVerificationCodeViewModel @AssistedInject constructor(
@Assisted initialState: SASVerificationCodeViewState, @Assisted initialState: SASVerificationCodeViewState,
private val session: Session private val session: Session
) : VectorViewModel<SASVerificationCodeViewState, EmptyAction>(initialState) ) : VectorViewModel<SASVerificationCodeViewState, EmptyAction>(initialState), SasVerificationService.SasVerificationListener {
, SasVerificationService.SasVerificationListener {
init { init {
withState { state -> withState { state ->
@ -165,6 +164,5 @@ class SASVerificationCodeViewModel @AssistedInject constructor(
} }
override fun handle(action: EmptyAction) { override fun handle(action: EmptyAction) {
} }
} }

View File

@ -24,7 +24,6 @@ import im.vector.matrix.android.api.session.crypto.sas.SasVerificationService
import im.vector.matrix.android.api.session.crypto.sas.SasVerificationTransaction import im.vector.matrix.android.api.session.crypto.sas.SasVerificationTransaction
import im.vector.matrix.android.api.session.crypto.sas.SasVerificationTxState import im.vector.matrix.android.api.session.crypto.sas.SasVerificationTxState
import im.vector.matrix.android.api.session.user.model.User import im.vector.matrix.android.api.session.user.model.User
import im.vector.matrix.android.internal.crypto.verification.PendingVerificationRequest
import im.vector.riotx.core.utils.LiveEvent import im.vector.riotx.core.utils.LiveEvent
import javax.inject.Inject import javax.inject.Inject

View File

@ -56,7 +56,6 @@ class VerificationBottomSheet : VectorBaseBottomSheetDialogFragment() {
val roomId: String? = null val roomId: String? = null
) : Parcelable ) : Parcelable
@Inject @Inject
lateinit var verificationRequestViewModelFactory: VerificationRequestViewModel.Factory lateinit var verificationRequestViewModelFactory: VerificationRequestViewModel.Factory
@Inject @Inject
@ -99,7 +98,6 @@ class VerificationBottomSheet : VectorBaseBottomSheetDialogFragment() {
} }
override fun invalidate() = withState(viewModel) { override fun invalidate() = withState(viewModel) {
it.otherUserMxItem?.let { matrixItem -> it.otherUserMxItem?.let { matrixItem ->
val displayName = matrixItem.displayName ?: "" val displayName = matrixItem.displayName ?: ""
otherUserNameText.text = getString(R.string.verification_request_alert_title, displayName) otherUserNameText.text = getString(R.string.verification_request_alert_title, displayName)
@ -111,7 +109,6 @@ class VerificationBottomSheet : VectorBaseBottomSheetDialogFragment() {
// Did the request result in a SAS transaction? // Did the request result in a SAS transaction?
if (it.sasTransactionState != null) { if (it.sasTransactionState != null) {
when (it.sasTransactionState) { when (it.sasTransactionState) {
SasVerificationTxState.None, SasVerificationTxState.None,
SasVerificationTxState.SendingStart, SasVerificationTxState.SendingStart,
@ -148,7 +145,6 @@ class VerificationBottomSheet : VectorBaseBottomSheetDialogFragment() {
return@withState return@withState
} }
// Transaction has not yet started // Transaction has not yet started
if (it.pendingRequest == null || !it.pendingRequest.isReady) { if (it.pendingRequest == null || !it.pendingRequest.isReady) {
showFragment(VerificationRequestFragment::class, Bundle().apply { showFragment(VerificationRequestFragment::class, Bundle().apply {
@ -159,7 +155,6 @@ class VerificationBottomSheet : VectorBaseBottomSheetDialogFragment() {
putParcelable(MvRx.KEY_ARG, VerificationArgs(it.otherUserMxItem?.id putParcelable(MvRx.KEY_ARG, VerificationArgs(it.otherUserMxItem?.id
?: "", it.pendingRequest.transactionId)) ?: "", it.pendingRequest.transactionId))
}) })
} }
super.invalidate() super.invalidate()
@ -173,7 +168,6 @@ class VerificationBottomSheet : VectorBaseBottomSheetDialogFragment() {
} }
// Commit now, to ensure changes occurs before next rendering frame (or bottomsheet want animate) // Commit now, to ensure changes occurs before next rendering frame (or bottomsheet want animate)
childFragmentManager.commitTransactionNow { childFragmentManager.commitTransactionNow {
replace(R.id.bottomSheetFragmentContainer, replace(R.id.bottomSheetFragmentContainer,
fragmentClass.java, fragmentClass.java,
bundle, bundle,
@ -184,7 +178,6 @@ class VerificationBottomSheet : VectorBaseBottomSheetDialogFragment() {
} }
} }
fun View.getParentCoordinatorLayout(): CoordinatorLayout? { fun View.getParentCoordinatorLayout(): CoordinatorLayout? {
var current = this as? View var current = this as? View
while (current != null) { while (current != null) {

View File

@ -34,7 +34,6 @@ import im.vector.riotx.core.platform.VectorViewModel
import im.vector.riotx.core.platform.VectorViewModelAction import im.vector.riotx.core.platform.VectorViewModelAction
import im.vector.riotx.core.utils.LiveEvent import im.vector.riotx.core.utils.LiveEvent
data class VerificationBottomSheetViewState( data class VerificationBottomSheetViewState(
val otherUserMxItem: MatrixItem? = null, val otherUserMxItem: MatrixItem? = null,
val roomId: String? = null, val roomId: String? = null,
@ -43,7 +42,6 @@ data class VerificationBottomSheetViewState(
val cancelCode: CancelCode? = null val cancelCode: CancelCode? = null
) : MvRxState ) : MvRxState
sealed class VerificationAction : VectorViewModelAction { sealed class VerificationAction : VectorViewModelAction {
data class RequestVerificationByDM(val userID: String, val roomId: String?) : VerificationAction() data class RequestVerificationByDM(val userID: String, val roomId: String?) : VerificationAction()
data class StartSASVerification(val userID: String, val pendingRequestTransactionId: String) : VerificationAction() data class StartSASVerification(val userID: String, val pendingRequestTransactionId: String) : VerificationAction()
@ -57,7 +55,6 @@ class VerificationBottomSheetViewModel @AssistedInject constructor(@Assisted ini
: VectorViewModel<VerificationBottomSheetViewState, VerificationAction>(initialState), : VectorViewModel<VerificationBottomSheetViewState, VerificationAction>(initialState),
SasVerificationService.SasVerificationListener { SasVerificationService.SasVerificationListener {
// Can be used for several actions, for a one shot result // Can be used for several actions, for a one shot result
private val _requestLiveData = MutableLiveData<LiveEvent<Async<VerificationAction>>>() private val _requestLiveData = MutableLiveData<LiveEvent<Async<VerificationAction>>>()
val requestLiveData: LiveData<LiveEvent<Async<VerificationAction>>> val requestLiveData: LiveData<LiveEvent<Async<VerificationAction>>>
@ -146,7 +143,6 @@ class VerificationBottomSheetViewModel @AssistedInject constructor(@Assisted ini
} }
} }
override fun transactionCreated(tx: SasVerificationTransaction) { override fun transactionCreated(tx: SasVerificationTransaction) {
transactionUpdated(tx) transactionUpdated(tx)
} }

View File

@ -43,7 +43,6 @@ class VerificationChooseMethodFragment @Inject constructor(
if (state.QRModeAvailable) { if (state.QRModeAvailable) {
val cSpan = object : ClickableSpan() { val cSpan = object : ClickableSpan() {
override fun onClick(widget: View) { override fun onClick(widget: View) {
} }
} }
val openLink = getString(R.string.verify_open_camera_link) val openLink = getString(R.string.verify_open_camera_link)
@ -65,5 +64,4 @@ class VerificationChooseMethodFragment @Inject constructor(
sharedViewModel.handle(VerificationAction.StartSASVerification(it.otherUserMxItem?.id ?: "", it.pendingRequest?.transactionId sharedViewModel.handle(VerificationAction.StartSASVerification(it.otherUserMxItem?.id ?: "", it.pendingRequest?.transactionId
?: "")) ?: ""))
} }
} }

View File

@ -33,13 +33,11 @@ data class VerificationChooseMethodViewState(
val SASMOdeAvailable: Boolean = false val SASMOdeAvailable: Boolean = false
) : MvRxState ) : MvRxState
class VerificationChooseMethodViewModel @AssistedInject constructor( class VerificationChooseMethodViewModel @AssistedInject constructor(
@Assisted initialState: VerificationChooseMethodViewState, @Assisted initialState: VerificationChooseMethodViewState,
private val session: Session private val session: Session
) : VectorViewModel<VerificationChooseMethodViewState, EmptyAction>(initialState) { ) : VectorViewModel<VerificationChooseMethodViewState, EmptyAction>(initialState) {
init { init {
withState { state -> withState { state ->
val pvr = session.getSasVerificationService().getExistingVerificationRequest(state.otherUserId)?.first { val pvr = session.getSasVerificationService().getExistingVerificationRequest(state.otherUserId)?.first {
@ -70,8 +68,5 @@ class VerificationChooseMethodViewModel @AssistedInject constructor(
} }
} }
override fun handle(action: EmptyAction) {} override fun handle(action: EmptyAction) {}
} }

View File

@ -50,7 +50,6 @@ class VerificationConclusionFragment @Inject constructor() : VectorBaseFragment(
verifyConclusionDescription.setTextOrHide(getString(R.string.sas_verified_successful_description)) verifyConclusionDescription.setTextOrHide(getString(R.string.sas_verified_successful_description))
verifyConclusionBottomDescription.text = getString(R.string.verification_green_shield) verifyConclusionBottomDescription.text = getString(R.string.verification_green_shield)
verifyConclusionImageView.setImageDrawable(ContextCompat.getDrawable(requireContext(), R.drawable.ic_shield_trusted)) verifyConclusionImageView.setImageDrawable(ContextCompat.getDrawable(requireContext(), R.drawable.ic_shield_trusted))
} }
ConclusionState.WARNING -> { ConclusionState.WARNING -> {
verificationConclusionTitle.text = getString(R.string.verification_conclusion_not_secure) verificationConclusionTitle.text = getString(R.string.verification_conclusion_not_secure)

View File

@ -55,7 +55,7 @@ class VerificationRequestFragment @Inject constructor(
when (state.started) { when (state.started) {
is Loading -> { is Loading -> {
//Hide the start button, show waiting // Hide the start button, show waiting
verificationStartButton.isInvisible = true verificationStartButton.isInvisible = true
verificationWaitingText.isVisible = true verificationWaitingText.isVisible = true
val otherUser = state.matrixItem.displayName ?: state.matrixItem.id val otherUser = state.matrixItem.displayName ?: state.matrixItem.id
@ -79,5 +79,4 @@ class VerificationRequestFragment @Inject constructor(
verificationStartButton.isEnabled = false verificationStartButton.isEnabled = false
sharedViewModel.handle(VerificationAction.RequestVerificationByDM(state.matrixItem.id, state.roomId)) sharedViewModel.handle(VerificationAction.RequestVerificationByDM(state.matrixItem.id, state.roomId))
} }
} }

View File

@ -27,14 +27,12 @@ import im.vector.matrix.android.internal.crypto.verification.PendingVerification
import im.vector.riotx.core.di.HasScreenInjector import im.vector.riotx.core.di.HasScreenInjector
import im.vector.riotx.core.platform.VectorViewModel import im.vector.riotx.core.platform.VectorViewModel
data class VerificationRequestViewState( data class VerificationRequestViewState(
val roomId: String? = null, val roomId: String? = null,
val matrixItem: MatrixItem, val matrixItem: MatrixItem,
val started: Async<Boolean> = Success(false) val started: Async<Boolean> = Success(false)
) : MvRxState ) : MvRxState
class VerificationRequestViewModel @AssistedInject constructor( class VerificationRequestViewModel @AssistedInject constructor(
@Assisted initialState: VerificationRequestViewState, @Assisted initialState: VerificationRequestViewState,
private val session: Session private val session: Session

View File

@ -1130,7 +1130,7 @@ class RoomDetailFragment @Inject constructor(
} }
override fun onAvatarClicked(informationData: MessageInformationData) { override fun onAvatarClicked(informationData: MessageInformationData) {
//vectorBaseActivity.notImplemented("Click on user avatar") // vectorBaseActivity.notImplemented("Click on user avatar")
roomDetailViewModel.handle(RoomDetailAction.RequestVerification(informationData.senderId)) roomDetailViewModel.handle(RoomDetailAction.RequestVerification(informationData.senderId))
} }

View File

@ -796,7 +796,7 @@ class RoomDetailViewModel @AssistedInject constructor(@Assisted initialState: Ro
} }
private fun handleAcceptVerification(action: RoomDetailAction.AcceptVerificationRequest) { private fun handleAcceptVerification(action: RoomDetailAction.AcceptVerificationRequest) {
session.getSasVerificationService().readyPendingVerificationInDMs(action.otherUserId,room.roomId, session.getSasVerificationService().readyPendingVerificationInDMs(action.otherUserId, room.roomId,
action.transactionId) action.transactionId)
_requestLiveData.postValue(LiveEvent(Success(action))) _requestLiveData.postValue(LiveEvent(Success(action)))
// session.getSasVerificationService().beginKeyVerificationInDMs( // session.getSasVerificationService().beginKeyVerificationInDMs(