Self verification + toDevice Request
This commit is contained in:
parent
03c5e61b2e
commit
50d5ad3625
@ -54,7 +54,9 @@ class VerificationBottomSheet : VectorBaseBottomSheetDialogFragment() {
|
||||
data class VerificationArgs(
|
||||
val otherUserId: String,
|
||||
val verificationId: String? = null,
|
||||
val roomId: String? = null
|
||||
val roomId: String? = null,
|
||||
// Special mode where UX should show loading wheel until other user sends a request/tx
|
||||
val waitForIncomingRequest : Boolean = false
|
||||
) : Parcelable
|
||||
|
||||
@Inject
|
||||
@ -97,14 +99,25 @@ class VerificationBottomSheet : VectorBaseBottomSheetDialogFragment() {
|
||||
|
||||
override fun invalidate() = withState(viewModel) {
|
||||
it.otherUserMxItem?.let { matrixItem ->
|
||||
avatarRenderer.render(matrixItem, otherUserAvatarImageView)
|
||||
|
||||
if (it.sasTransactionState == VerificationTxState.Verified || it.qrTransactionState == VerificationTxState.Verified) {
|
||||
otherUserNameText.text = getString(R.string.verification_verified_user, matrixItem.getBestName())
|
||||
otherUserShield.isVisible = true
|
||||
} else {
|
||||
otherUserNameText.text = getString(R.string.verification_verify_user, matrixItem.getBestName())
|
||||
if (it.waitForOtherUserMode) {
|
||||
if (it.sasTransactionState == VerificationTxState.Verified || it.qrTransactionState == VerificationTxState.Verified) {
|
||||
otherUserAvatarImageView.setImageResource(R.drawable.ic_shield_trusted)
|
||||
} else {
|
||||
otherUserAvatarImageView.setImageResource(R.drawable.ic_shield_warning)
|
||||
}
|
||||
otherUserNameText.text = getString(R.string.complete_security)
|
||||
otherUserShield.isVisible = false
|
||||
} else {
|
||||
avatarRenderer.render(matrixItem, otherUserAvatarImageView)
|
||||
|
||||
if (it.sasTransactionState == VerificationTxState.Verified || it.qrTransactionState == VerificationTxState.Verified) {
|
||||
otherUserNameText.text = getString(R.string.verification_verified_user, matrixItem.getBestName())
|
||||
otherUserShield.isVisible = true
|
||||
} else {
|
||||
otherUserNameText.text = getString(R.string.verification_verify_user, matrixItem.getBestName())
|
||||
otherUserShield.isVisible = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -136,12 +149,12 @@ class VerificationBottomSheet : VectorBaseBottomSheetDialogFragment() {
|
||||
}
|
||||
is VerificationTxState.Verified -> {
|
||||
showFragment(VerificationConclusionFragment::class, Bundle().apply {
|
||||
putParcelable(MvRx.KEY_ARG, VerificationConclusionFragment.Args(true, null))
|
||||
putParcelable(MvRx.KEY_ARG, VerificationConclusionFragment.Args(true, null, it.isMe))
|
||||
})
|
||||
}
|
||||
is VerificationTxState.Cancelled -> {
|
||||
showFragment(VerificationConclusionFragment::class, Bundle().apply {
|
||||
putParcelable(MvRx.KEY_ARG, VerificationConclusionFragment.Args(false, it.sasTransactionState.cancelCode.value))
|
||||
putParcelable(MvRx.KEY_ARG, VerificationConclusionFragment.Args(false, it.sasTransactionState.cancelCode.value, it.isMe))
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -156,13 +169,13 @@ class VerificationBottomSheet : VectorBaseBottomSheetDialogFragment() {
|
||||
}
|
||||
is VerificationTxState.Verified -> {
|
||||
showFragment(VerificationConclusionFragment::class, Bundle().apply {
|
||||
putParcelable(MvRx.KEY_ARG, VerificationConclusionFragment.Args(true, null))
|
||||
putParcelable(MvRx.KEY_ARG, VerificationConclusionFragment.Args(true, null, it.isMe))
|
||||
})
|
||||
return@withState
|
||||
}
|
||||
is VerificationTxState.Cancelled -> {
|
||||
showFragment(VerificationConclusionFragment::class, Bundle().apply {
|
||||
putParcelable(MvRx.KEY_ARG, VerificationConclusionFragment.Args(false, it.qrTransactionState.cancelCode.value))
|
||||
putParcelable(MvRx.KEY_ARG, VerificationConclusionFragment.Args(false, it.qrTransactionState.cancelCode.value, it.isMe))
|
||||
})
|
||||
return@withState
|
||||
}
|
||||
@ -178,7 +191,7 @@ class VerificationBottomSheet : VectorBaseBottomSheetDialogFragment() {
|
||||
}
|
||||
|
||||
// If it's an outgoing
|
||||
if (it.pendingRequest.invoke() == null || it.pendingRequest.invoke()?.isIncoming == false) {
|
||||
if (it.pendingRequest.invoke() == null || it.pendingRequest.invoke()?.isIncoming == false || it.waitForOtherUserMode) {
|
||||
Timber.v("## SAS show bottom sheet for outgoing request")
|
||||
if (it.pendingRequest.invoke()?.isReady == true) {
|
||||
Timber.v("## SAS show bottom sheet for outgoing and ready request")
|
||||
@ -225,17 +238,20 @@ class VerificationBottomSheet : VectorBaseBottomSheetDialogFragment() {
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun withArgs(roomId: String?, otherUserId: String, transactionId: String? = null): VerificationBottomSheet {
|
||||
fun withArgs(roomId: String?, otherUserId: String, transactionId: String? = null, waitForIncomingRequest: Boolean = false): VerificationBottomSheet {
|
||||
return VerificationBottomSheet().apply {
|
||||
arguments = Bundle().apply {
|
||||
putParcelable(MvRx.KEY_ARG, VerificationArgs(
|
||||
otherUserId = otherUserId,
|
||||
roomId = roomId,
|
||||
verificationId = transactionId
|
||||
verificationId = transactionId,
|
||||
waitForIncomingRequest = waitForIncomingRequest
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val WAITING_SELF_VERIF_TAG : String = "WAITING_SELF_VERIF_TAG"
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -30,6 +30,7 @@ import com.squareup.inject.assisted.Assisted
|
||||
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.IncomingSasVerificationTransaction
|
||||
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
|
||||
@ -55,7 +56,9 @@ data class VerificationBottomSheetViewState(
|
||||
val pendingLocalId: String? = null,
|
||||
val sasTransactionState: VerificationTxState? = null,
|
||||
val qrTransactionState: VerificationTxState? = null,
|
||||
val transactionId: String? = null
|
||||
val transactionId: String? = null,
|
||||
val waitForOtherUserMode: Boolean = false,
|
||||
val isMe: Boolean = false
|
||||
) : MvRxState
|
||||
|
||||
class VerificationBottomSheetViewModel @AssistedInject constructor(@Assisted initialState: VerificationBottomSheetViewState,
|
||||
@ -102,13 +105,18 @@ class VerificationBottomSheetViewModel @AssistedInject constructor(@Assisted ini
|
||||
session.getVerificationService().getExistingTransaction(args.otherUserId, it) as? QrCodeVerificationTransaction
|
||||
}
|
||||
|
||||
val isWaitingForOtherMode = args.waitForIncomingRequest
|
||||
// TODO see if active tx for this user and take it
|
||||
|
||||
return fragment.verificationViewModelFactory.create(VerificationBottomSheetViewState(
|
||||
otherUserMxItem = userItem?.toMatrixItem(),
|
||||
sasTransactionState = sasTx?.state,
|
||||
qrTransactionState = qrTx?.state,
|
||||
transactionId = args.verificationId,
|
||||
pendingRequest = if (pr != null) Success(pr) else Uninitialized,
|
||||
roomId = args.roomId)
|
||||
waitForOtherUserMode = isWaitingForOtherMode,
|
||||
roomId = args.roomId,
|
||||
isMe = args.otherUserId == session.myUserId)
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -230,6 +238,27 @@ class VerificationBottomSheetViewModel @AssistedInject constructor(@Assisted ini
|
||||
}
|
||||
|
||||
override fun transactionUpdated(tx: VerificationTransaction) = withState { state ->
|
||||
if (state.waitForOtherUserMode && state.transactionId == null) {
|
||||
// is this an incoming with that user
|
||||
if (tx.isIncoming && tx.otherUserId == state.otherUserMxItem?.id) {
|
||||
|
||||
// Also auto accept incoming if needed!
|
||||
if (tx is IncomingSasVerificationTransaction) {
|
||||
if (tx.uxState == IncomingSasVerificationTransaction.UxState.SHOW_ACCEPT) {
|
||||
tx.performAccept()
|
||||
}
|
||||
}
|
||||
// Use this one!
|
||||
setState {
|
||||
copy(
|
||||
transactionId = tx.transactionId,
|
||||
sasTransactionState = tx.state.takeIf { tx is SasVerificationTransaction },
|
||||
qrTransactionState = tx.state.takeIf { tx is QrCodeVerificationTransaction }
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
when (tx) {
|
||||
is SasVerificationTransaction -> {
|
||||
if (tx.transactionId == (state.pendingRequest.invoke()?.transactionId ?: state.transactionId)) {
|
||||
@ -260,6 +289,20 @@ class VerificationBottomSheetViewModel @AssistedInject constructor(@Assisted ini
|
||||
|
||||
override fun verificationRequestUpdated(pr: PendingVerificationRequest) = withState { state ->
|
||||
|
||||
if (state.waitForOtherUserMode && state.pendingRequest.invoke() == null && state.transactionId == null) {
|
||||
// is this an incoming with that user
|
||||
if (pr.isIncoming && pr.otherUserId == state.otherUserMxItem?.id) {
|
||||
// Use this one!
|
||||
setState {
|
||||
copy(
|
||||
transactionId = pr.transactionId,
|
||||
pendingRequest = Success(pr)
|
||||
)
|
||||
}
|
||||
return@withState
|
||||
}
|
||||
}
|
||||
|
||||
if (pr.localID == state.pendingLocalId
|
||||
|| pr.localID == state.pendingRequest.invoke()?.localID
|
||||
|| state.pendingRequest.invoke()?.transactionId == pr.transactionId) {
|
||||
|
@ -49,7 +49,10 @@ class VerificationConclusionController @Inject constructor(
|
||||
ConclusionState.SUCCESS -> {
|
||||
bottomSheetVerificationNoticeItem {
|
||||
id("notice")
|
||||
notice(stringProvider.getString(R.string.verification_conclusion_ok_notice))
|
||||
notice(stringProvider.getString(
|
||||
if (state.isSelfVerification) R.string.verification_conclusion_ok_self_notice
|
||||
else R.string.verification_conclusion_ok_notice))
|
||||
|
||||
}
|
||||
|
||||
bottomSheetVerificationBigImageItem {
|
||||
|
@ -38,7 +38,8 @@ class VerificationConclusionFragment @Inject constructor(
|
||||
@Parcelize
|
||||
data class Args(
|
||||
val isSuccessFull: Boolean,
|
||||
val cancelReason: String?
|
||||
val cancelReason: String?,
|
||||
val isMe: Boolean
|
||||
) : Parcelable
|
||||
|
||||
private val sharedViewModel by parentFragmentViewModel(VerificationBottomSheetViewModel::class)
|
||||
|
@ -25,7 +25,8 @@ import im.vector.riotx.core.platform.EmptyViewEvents
|
||||
import im.vector.riotx.core.platform.VectorViewModel
|
||||
|
||||
data class VerificationConclusionViewState(
|
||||
val conclusionState: ConclusionState = ConclusionState.CANCELLED
|
||||
val conclusionState: ConclusionState = ConclusionState.CANCELLED,
|
||||
val isSelfVerification: Boolean = false
|
||||
) : MvRxState
|
||||
|
||||
enum class ConclusionState {
|
||||
@ -48,13 +49,13 @@ class VerificationConclusionViewModel(initialState: VerificationConclusionViewSt
|
||||
CancelCode.MismatchedSas,
|
||||
CancelCode.MismatchedCommitment,
|
||||
CancelCode.MismatchedKeys -> {
|
||||
VerificationConclusionViewState(ConclusionState.WARNING)
|
||||
VerificationConclusionViewState(ConclusionState.WARNING, args.isMe)
|
||||
}
|
||||
else -> {
|
||||
VerificationConclusionViewState(
|
||||
if (args.isSuccessFull) ConclusionState.SUCCESS
|
||||
else ConclusionState.CANCELLED
|
||||
)
|
||||
, args.isMe)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -50,46 +50,66 @@ class VerificationRequestController @Inject constructor(
|
||||
val state = viewState ?: return
|
||||
val matrixItem = viewState?.otherUserMxItem ?: return
|
||||
|
||||
val styledText = matrixItem.let {
|
||||
stringProvider.getString(R.string.verification_request_notice, it.id)
|
||||
.toSpannable()
|
||||
.colorizeMatchingText(it.id, colorProvider.getColorFromAttribute(R.attr.vctr_notice_text_color))
|
||||
}
|
||||
|
||||
bottomSheetVerificationNoticeItem {
|
||||
id("notice")
|
||||
notice(styledText)
|
||||
}
|
||||
|
||||
dividerItem {
|
||||
id("sep")
|
||||
}
|
||||
|
||||
when (val pr = state.pendingRequest) {
|
||||
is Uninitialized -> {
|
||||
bottomSheetVerificationActionItem {
|
||||
id("start")
|
||||
title(stringProvider.getString(R.string.start_verification))
|
||||
titleColor(colorProvider.getColor(R.color.riotx_accent))
|
||||
subTitle(stringProvider.getString(R.string.verification_request_start_notice))
|
||||
iconRes(R.drawable.ic_arrow_right)
|
||||
iconColor(colorProvider.getColorFromAttribute(R.attr.riotx_text_primary))
|
||||
listener { listener?.onClickOnVerificationStart() }
|
||||
}
|
||||
if (state.waitForOtherUserMode) {
|
||||
bottomSheetVerificationNoticeItem {
|
||||
id("notice")
|
||||
notice(stringProvider.getString(R.string.verification_open_other_to_verify))
|
||||
}
|
||||
is Loading -> {
|
||||
bottomSheetVerificationWaitingItem {
|
||||
id("waiting")
|
||||
title(stringProvider.getString(R.string.verification_request_waiting_for, matrixItem.getBestName()))
|
||||
}
|
||||
|
||||
dividerItem {
|
||||
id("sep")
|
||||
}
|
||||
is Success -> {
|
||||
if (!pr.invoke().isReady) {
|
||||
|
||||
|
||||
bottomSheetVerificationWaitingItem {
|
||||
id("waiting")
|
||||
title(stringProvider.getString(R.string.verification_request_waiting_for, matrixItem.getBestName()))
|
||||
}
|
||||
} else {
|
||||
|
||||
val styledText = matrixItem.let {
|
||||
stringProvider.getString(R.string.verification_request_notice, it.id)
|
||||
.toSpannable()
|
||||
.colorizeMatchingText(it.id, colorProvider.getColorFromAttribute(R.attr.vctr_notice_text_color))
|
||||
}
|
||||
|
||||
bottomSheetVerificationNoticeItem {
|
||||
id("notice")
|
||||
notice(styledText)
|
||||
}
|
||||
|
||||
dividerItem {
|
||||
id("sep")
|
||||
}
|
||||
|
||||
when (val pr = state.pendingRequest) {
|
||||
is Uninitialized -> {
|
||||
bottomSheetVerificationActionItem {
|
||||
id("start")
|
||||
title(stringProvider.getString(R.string.start_verification))
|
||||
titleColor(colorProvider.getColor(R.color.riotx_accent))
|
||||
subTitle(stringProvider.getString(R.string.verification_request_start_notice))
|
||||
iconRes(R.drawable.ic_arrow_right)
|
||||
iconColor(colorProvider.getColorFromAttribute(R.attr.riotx_text_primary))
|
||||
listener { listener?.onClickOnVerificationStart() }
|
||||
}
|
||||
}
|
||||
is Loading -> {
|
||||
bottomSheetVerificationWaitingItem {
|
||||
id("waiting")
|
||||
title(stringProvider.getString(R.string.verification_request_waiting_for, matrixItem.getBestName()))
|
||||
}
|
||||
}
|
||||
is Success -> {
|
||||
if (!pr.invoke().isReady) {
|
||||
bottomSheetVerificationWaitingItem {
|
||||
id("waiting")
|
||||
title(stringProvider.getString(R.string.verification_request_waiting_for, matrixItem.getBestName()))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -22,10 +22,15 @@ import android.os.Bundle
|
||||
import android.view.MenuItem
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.appcompat.widget.Toolbar
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.view.GravityCompat
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.drawerlayout.widget.DrawerLayout
|
||||
import androidx.lifecycle.Observer
|
||||
import im.vector.matrix.android.api.MatrixCallback
|
||||
import im.vector.matrix.android.api.session.Session
|
||||
import im.vector.matrix.android.internal.crypto.model.CryptoDeviceInfo
|
||||
import im.vector.matrix.android.internal.crypto.model.MXUsersDevicesMap
|
||||
import im.vector.riotx.R
|
||||
import im.vector.riotx.core.di.ActiveSessionHolder
|
||||
import im.vector.riotx.core.di.ScreenComponent
|
||||
@ -36,6 +41,7 @@ import im.vector.riotx.core.platform.VectorBaseActivity
|
||||
import im.vector.riotx.core.pushers.PushersManager
|
||||
import im.vector.riotx.features.disclaimer.showDisclaimerDialog
|
||||
import im.vector.riotx.features.notifications.NotificationDrawerManager
|
||||
import im.vector.riotx.features.popup.PopupAlertManager
|
||||
import im.vector.riotx.features.rageshake.VectorUncaughtExceptionHandler
|
||||
import im.vector.riotx.features.workers.signout.SignOutViewModel
|
||||
import im.vector.riotx.push.fcm.FcmHelper
|
||||
@ -96,7 +102,9 @@ class HomeActivity : VectorBaseActivity(), ToolbarConfigurable {
|
||||
activeSessionHolder.getSafeActiveSession()?.getInitialSyncProgressStatus()?.observe(this, Observer { status ->
|
||||
if (status == null) {
|
||||
waiting_view.isVisible = false
|
||||
promptCompleteSecurityIfNeeded()
|
||||
} else {
|
||||
sharedActionViewModel.hasDisplayedCompleteSecurityPrompt = false
|
||||
Timber.v("${getString(status.statusText)} ${status.percentProgress}")
|
||||
waiting_view.setOnClickListener {
|
||||
// block interactions
|
||||
@ -116,6 +124,66 @@ class HomeActivity : VectorBaseActivity(), ToolbarConfigurable {
|
||||
})
|
||||
}
|
||||
|
||||
private fun promptCompleteSecurityIfNeeded() {
|
||||
val session = activeSessionHolder.getSafeActiveSession() ?: return
|
||||
if (!session.hasAlreadySynced()) return
|
||||
if (sharedActionViewModel.hasDisplayedCompleteSecurityPrompt) return
|
||||
|
||||
// ensure keys are downloaded
|
||||
session.downloadKeys(listOf(session.myUserId), true, object : MatrixCallback<MXUsersDevicesMap<CryptoDeviceInfo>> {
|
||||
override fun onSuccess(data: MXUsersDevicesMap<CryptoDeviceInfo>) {
|
||||
runOnUiThread {
|
||||
alertCompleteSecurity(session)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
private fun alertCompleteSecurity(session: Session) {
|
||||
val myCrossSigningKeys = session.getCrossSigningService()
|
||||
.getMyCrossSigningKeys()
|
||||
val crossSigningEnabledOnAccount = myCrossSigningKeys != null
|
||||
|
||||
if (crossSigningEnabledOnAccount && myCrossSigningKeys?.isTrusted() == false) {
|
||||
// We need to ask
|
||||
sharedActionViewModel.hasDisplayedCompleteSecurityPrompt = true
|
||||
PopupAlertManager.postVectorAlert(
|
||||
PopupAlertManager.VectorAlert(
|
||||
uid = "completeSecurity",
|
||||
title = getString(R.string.crosssigning_verify_this_session),
|
||||
description = getString(R.string.crosssigning_other_user_not_trust),
|
||||
iconId = R.drawable.ic_shield_warning
|
||||
).apply {
|
||||
colorInt = ContextCompat.getColor(this@HomeActivity, R.color.riotx_positive_accent)
|
||||
contentAction = Runnable {
|
||||
Runnable {
|
||||
(weakCurrentActivity?.get() as? VectorBaseActivity)?.let {
|
||||
it.navigator.waitSessionVerification(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
dismissedAction = Runnable {
|
||||
// tx.cancel()
|
||||
}
|
||||
addButton(
|
||||
getString(R.string.later),
|
||||
Runnable {
|
||||
|
||||
}
|
||||
)
|
||||
addButton(
|
||||
getString(R.string.verification_profile_verify),
|
||||
Runnable {
|
||||
(weakCurrentActivity?.get() as? VectorBaseActivity)?.let {
|
||||
it.navigator.waitSessionVerification(it)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onNewIntent(intent: Intent?) {
|
||||
super.onNewIntent(intent)
|
||||
if (intent?.hasExtra(EXTRA_CLEAR_EXISTING_NOTIFICATION) == true) {
|
||||
|
@ -19,4 +19,6 @@ package im.vector.riotx.features.home
|
||||
import im.vector.riotx.core.platform.VectorSharedActionViewModel
|
||||
import javax.inject.Inject
|
||||
|
||||
class HomeSharedActionViewModel @Inject constructor() : VectorSharedActionViewModel<HomeActivitySharedAction>()
|
||||
class HomeSharedActionViewModel @Inject constructor() : VectorSharedActionViewModel<HomeActivitySharedAction>() {
|
||||
var hasDisplayedCompleteSecurityPrompt : Boolean = false
|
||||
}
|
||||
|
@ -153,7 +153,7 @@ class MessageItemFactory @Inject constructor(
|
||||
VerificationRequestItem.Attributes(
|
||||
otherUserId = otherUserId,
|
||||
otherUserName = otherUserName.toString(),
|
||||
fromDevide = messageContent.fromDevice,
|
||||
fromDevide = messageContent.fromDevice ?: "",
|
||||
referenceId = informationData.eventId,
|
||||
informationData = informationData,
|
||||
avatarRenderer = attributes.avatarRenderer,
|
||||
|
@ -21,6 +21,7 @@ import android.content.Context
|
||||
import android.content.Intent
|
||||
import androidx.core.app.TaskStackBuilder
|
||||
import im.vector.matrix.android.api.session.crypto.sas.IncomingSasVerificationTransaction
|
||||
import im.vector.matrix.android.api.session.crypto.sas.VerificationMethod
|
||||
import im.vector.matrix.android.api.session.room.model.roomdirectory.PublicRoom
|
||||
import im.vector.riotx.R
|
||||
import im.vector.riotx.core.di.ActiveSessionHolder
|
||||
@ -75,6 +76,34 @@ class DefaultNavigator @Inject constructor(
|
||||
).show(context.supportFragmentManager, "REQPOP")
|
||||
}
|
||||
}
|
||||
|
||||
override fun requestSessionVerification(context: Context) {
|
||||
val session = sessionHolder.getSafeActiveSession() ?: return
|
||||
val pr = session.getVerificationService().requestKeyVerification(
|
||||
listOf(VerificationMethod.SAS, VerificationMethod.QR_CODE_SCAN, VerificationMethod.QR_CODE_SHOW),
|
||||
session.myUserId,
|
||||
session.getUserDevices(session.myUserId).map { it.deviceId })
|
||||
if (context is VectorBaseActivity) {
|
||||
VerificationBottomSheet.withArgs(
|
||||
roomId = null,
|
||||
otherUserId = session.myUserId,
|
||||
transactionId = pr.transactionId
|
||||
).show(context.supportFragmentManager, "REQPOP")
|
||||
}
|
||||
}
|
||||
|
||||
override fun waitSessionVerification(context: Context) {
|
||||
val session = sessionHolder.getSafeActiveSession() ?: return
|
||||
if (context is VectorBaseActivity) {
|
||||
VerificationBottomSheet.withArgs(
|
||||
roomId = null,
|
||||
otherUserId = session.myUserId,
|
||||
waitForIncomingRequest = true
|
||||
|
||||
).show(context.supportFragmentManager, VerificationBottomSheet.WAITING_SELF_VERIF_TAG)
|
||||
}
|
||||
}
|
||||
|
||||
override fun openNotJoinedRoom(context: Context, roomIdOrAlias: String?, eventId: String?, buildTask: Boolean) {
|
||||
if (context is VectorBaseActivity) {
|
||||
context.notImplemented("Open not joined room")
|
||||
|
@ -27,6 +27,8 @@ interface Navigator {
|
||||
fun openRoom(context: Context, roomId: String, eventId: String? = null, buildTask: Boolean = false)
|
||||
|
||||
fun performDeviceVerification(context: Context, otherUserId: String, sasTransationId: String)
|
||||
fun requestSessionVerification(context: Context)
|
||||
fun waitSessionVerification(context: Context)
|
||||
|
||||
fun openRoomForSharing(activity: Activity, roomId: String, sharedData: SharedData)
|
||||
|
||||
|
@ -100,18 +100,19 @@
|
||||
<string name="room_settings_enable_encryption_dialog_content">Once enabled, encryption for a room cannot be disabled. Messages sent in an encrypted room cannot be seen by the server, only by the participants of the room. Enabling encryption may prevent many bots and bridges from working correctly.</string>
|
||||
<string name="room_settings_enable_encryption_dialog_submit">Enable encryption</string>
|
||||
|
||||
<string name="verification_request_notice">For extra security, verify %s by checking a one-time code.</string>
|
||||
<string name="verification_request_start_notice">For maximum security, do this in person.</string>
|
||||
<string name="verification_request_notice">To be secure, verify %s by checking a one-time code.</string>
|
||||
<string name="verification_request_start_notice">To be secure, do this in person or use another way to communicate.</string>
|
||||
|
||||
<string name="verification_emoji_notice">Compare the unique emoji, ensuring they appear in the same order.</string>
|
||||
<string name="verification_code_notice">Compare the code with the one displayed on the other user\'s screen.</string>
|
||||
<string name="verification_conclusion_ok_notice">Messages with this user are end-to-end encrypted and can\'t be read by third parties.</string>
|
||||
<string name="verification_conclusion_ok_self_notice">Your new session is now verified. It has access to your encrypted messages, and other users will see it as trusted.</string>
|
||||
|
||||
|
||||
<string name="encryption_information_cross_signing_state">Cross-Signing</string>
|
||||
<string name="encryption_information_dg_xsigning_complete">Cross-Signing is enabled\nPrivate Keys on device.</string>
|
||||
<string name="encryption_information_dg_xsigning_trusted">Cross-Signing is enabled\nKeys are trusted\n.Private keys are not known</string>
|
||||
<string name="encryption_information_dg_xsigning_not_trusted">Cross-Signing is enabled\nKeys are not trusted</string>
|
||||
<string name="encryption_information_dg_xsigning_trusted">Cross-Signing is enabled\nKeys are trusted.\nPrivate keys are not known</string>
|
||||
<string name="encryption_information_dg_xsigning_not_trusted">Cross-Signing is enabled.\nKeys are not trusted</string>
|
||||
<string name="encryption_information_dg_xsigning_disabled">Cross-Signing is not enabled</string>
|
||||
|
||||
|
||||
@ -128,6 +129,12 @@
|
||||
<item quantity="other">%d active sessions</item>
|
||||
</plurals>
|
||||
|
||||
<string name="crosssigning_verify_this_session">Verify this session</string>
|
||||
<string name="crosssigning_other_user_not_trust">Other users may not trust it</string>
|
||||
<string name="complete_security">Complete Security</string>
|
||||
|
||||
<string name="verification_open_other_to_verify">Open an existing session & use it to verify this one, granting it access to encrypted messages. If you can’t access one, use your recovery key or passphrase.</string>
|
||||
|
||||
|
||||
<string name="verification_profile_verify">Verify</string>
|
||||
<string name="verification_profile_verified">Verified</string>
|
||||
|
Loading…
x
Reference in New Issue
Block a user