mirror of
https://github.com/simplex-chat/simplex-chat.git
synced 2026-08-28 18:18:15 +00:00
core, ui: security code verification in channels (verify member key) (#7255)
This commit is contained in:
+3
-2
@@ -2535,7 +2535,8 @@ data class GroupMember (
|
||||
var activeConn: Connection? = null,
|
||||
val supportChat: GroupSupportChat? = null,
|
||||
val memberChatVRange: VersionRange,
|
||||
val relayLink: String? = null
|
||||
val relayLink: String? = null,
|
||||
val memberVerifiedCode: SecurityCode? = null
|
||||
): NamedChat {
|
||||
val id: String get() = "#$groupId @$groupMemberId"
|
||||
val ready get() = activeConn?.connStatus == ConnStatus.Ready
|
||||
@@ -2555,7 +2556,7 @@ data class GroupMember (
|
||||
override val shortDescr: String? get() = memberProfile.shortDescr
|
||||
override val image: String? get() = memberProfile.image
|
||||
val contactLink: String? = memberProfile.contactLink
|
||||
val verified get() = activeConn?.connectionCode != null
|
||||
val verified get() = memberVerifiedCode != null || activeConn?.connectionCode != null
|
||||
// the badge shown for a member's name; a badge that expired over a month ago (ExpiredOld) is not shown
|
||||
val nameBadge: LocalBadge? get() {
|
||||
val badge = memberProfile.localBadge
|
||||
|
||||
+5
-1
@@ -12,6 +12,7 @@ import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalClipboardManager
|
||||
import dev.icerock.moko.resources.compose.painterResource
|
||||
import dev.icerock.moko.resources.StringResource
|
||||
import dev.icerock.moko.resources.compose.stringResource
|
||||
import androidx.compose.ui.text.font.FontFamily
|
||||
import androidx.compose.ui.unit.dp
|
||||
@@ -29,12 +30,14 @@ fun VerifyCodeView(
|
||||
connectionVerified: Boolean,
|
||||
verify: suspend (String?) -> Pair<Boolean, String>?,
|
||||
close: () -> Unit,
|
||||
verifyDescription: StringResource = MR.strings.to_verify_compare,
|
||||
) {
|
||||
if (connectionCode != null) {
|
||||
VerifyCodeLayout(
|
||||
displayName,
|
||||
connectionCode,
|
||||
connectionVerified,
|
||||
verifyDescription,
|
||||
verifyCode = { newCode ->
|
||||
val res = verify(newCode)
|
||||
if (res != null) {
|
||||
@@ -54,6 +57,7 @@ private fun VerifyCodeLayout(
|
||||
displayName: String,
|
||||
connectionCode: String,
|
||||
connectionVerified: Boolean,
|
||||
verifyDescription: StringResource,
|
||||
verifyCode: suspend (String?) -> Boolean,
|
||||
) {
|
||||
ColumnWithScrollBar(Modifier.padding(horizontal = DEFAULT_PADDING)) {
|
||||
@@ -90,7 +94,7 @@ private fun VerifyCodeLayout(
|
||||
}
|
||||
|
||||
Text(
|
||||
generalGetString(MR.strings.to_verify_compare),
|
||||
generalGetString(verifyDescription),
|
||||
Modifier.padding(bottom = DEFAULT_PADDING)
|
||||
)
|
||||
|
||||
|
||||
+1
-1
@@ -126,7 +126,7 @@ fun ModalData.GroupChatInfoView(
|
||||
withBGApi {
|
||||
val r = chatModel.controller.apiGroupMemberInfo(rhId, groupInfo.groupId, member.groupMemberId)
|
||||
val stats = r?.second
|
||||
val (_, code) = if (member.memberActive) {
|
||||
val (_, code) = if ((member.memberActive || (groupInfo.useRelays && member.memberCurrent)) && member.memberRole != GroupMemberRole.Relay) {
|
||||
val memCode = chatModel.controller.apiGetGroupMemberCode(rhId, groupInfo.apiId, member.groupMemberId)
|
||||
member to memCode?.second
|
||||
} else {
|
||||
|
||||
+13
-13
@@ -214,11 +214,12 @@ fun GroupMemberInfoView(
|
||||
verify = { code ->
|
||||
chatModel.controller.apiVerifyGroupMember(rhId, mem.groupId, mem.groupMemberId, code)?.let { r ->
|
||||
val (verified, existingCode) = r
|
||||
val copy = mem.copy(
|
||||
activeConn = mem.activeConn?.copy(
|
||||
connectionCode = if (verified) SecurityCode(existingCode, Clock.System.now()) else null
|
||||
)
|
||||
)
|
||||
val code = if (verified) SecurityCode(existingCode, Clock.System.now()) else null
|
||||
val copy = if (groupInfo.useRelays) {
|
||||
mem.copy(memberVerifiedCode = code)
|
||||
} else {
|
||||
mem.copy(activeConn = mem.activeConn?.copy(connectionCode = code))
|
||||
}
|
||||
withContext(Dispatchers.Main) {
|
||||
chatModel.chatsContext.upsertGroupMember(rhId, groupInfo, copy)
|
||||
}
|
||||
@@ -229,6 +230,7 @@ fun GroupMemberInfoView(
|
||||
}
|
||||
},
|
||||
close,
|
||||
verifyDescription = if (groupInfo.useRelays) MR.strings.to_verify_channel_member_key else MR.strings.to_verify_compare,
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -541,16 +543,19 @@ fun GroupMemberInfoLayout(
|
||||
member.memberRole != GroupMemberRole.Relay &&
|
||||
((groupInfo.fullGroupPreferences.support.on && member.memberRole < GroupMemberRole.Moderator)
|
||||
|| member.supportChat != null)
|
||||
val canVerifyCode = connectionCode != null && member.memberRole != GroupMemberRole.Relay
|
||||
val canSyncConn = cStats != null && cStats.ratchetSyncAllowed
|
||||
|
||||
if (member.memberActive) {
|
||||
if ((member.memberActive || (groupInfo.useRelays && member.memberCurrent))
|
||||
&& (showMemberSupportChat || canVerifyCode || canSyncConn)) {
|
||||
SectionView {
|
||||
if (showMemberSupportChat) {
|
||||
SupportChatButton()
|
||||
}
|
||||
if (connectionCode != null && !(groupInfo.useRelays && member.memberRole == GroupMemberRole.Relay)) {
|
||||
if (canVerifyCode) {
|
||||
VerifyCodeButton(member.verified, verifyClicked)
|
||||
}
|
||||
if (cStats != null && cStats.ratchetSyncAllowed) {
|
||||
if (canSyncConn) {
|
||||
SynchronizeConnectionButton(syncMemberConnection)
|
||||
}
|
||||
// } else if (developerTools) {
|
||||
@@ -558,11 +563,6 @@ fun GroupMemberInfoLayout(
|
||||
// }
|
||||
}
|
||||
SectionDividerSpaced()
|
||||
} else if (groupInfo.useRelays && member.memberCurrent && showMemberSupportChat) {
|
||||
SectionView {
|
||||
SupportChatButton()
|
||||
}
|
||||
SectionDividerSpaced()
|
||||
}
|
||||
|
||||
if (member.contactLink != null) {
|
||||
|
||||
+1
-1
@@ -79,7 +79,7 @@ fun MemberSupportChatAppBar(
|
||||
withBGApi {
|
||||
val r = chatModel.controller.apiGroupMemberInfo(rhId, groupInfo.groupId, scopeMember_.groupMemberId)
|
||||
val stats = r?.second
|
||||
val code = if (scopeMember_.memberActive) {
|
||||
val code = if ((scopeMember_.memberActive || (groupInfo.useRelays && scopeMember_.memberCurrent)) && scopeMember_.memberRole != GroupMemberRole.Relay) {
|
||||
val memCode = chatModel.controller.apiGetGroupMemberCode(rhId, groupInfo.apiId, scopeMember_.groupMemberId)
|
||||
memCode?.second
|
||||
} else {
|
||||
|
||||
@@ -1013,6 +1013,7 @@
|
||||
<string name="mark_code_verified">Mark verified</string>
|
||||
<string name="clear_verification">Clear verification</string>
|
||||
<string name="to_verify_compare">To verify end-to-end encryption with your contact compare (or scan) the code on your devices.</string>
|
||||
<string name="to_verify_channel_member_key">To verify keys with this subscriber, compare (or scan) the code on your devices.</string>
|
||||
<string name="is_verified">%s is verified</string>
|
||||
<string name="is_not_verified">%s is not verified</string>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user