From 96ce59f33071b5afb7feeacd1d8ed4049a13d73a Mon Sep 17 00:00:00 2001 From: spaced4ndy <8711996+spaced4ndy@users.noreply.github.com> Date: Wed, 15 May 2024 23:09:51 +0400 Subject: [PATCH 1/7] multiplatform: SMP proxy configuration buttons (#4188) * multiplatform: SMP proxy configuration buttons * fix * icons * icon * icon --- .../UserSettings/NetworkAndServers.swift | 6 +- .../views/usersettings/NetworkAndServers.kt | 153 +++++++++++++++++- .../commonMain/resources/MR/base/strings.xml | 21 +++ .../MR/images/ic_arrows_left_right.svg | 4 + 4 files changed, 180 insertions(+), 4 deletions(-) create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_arrows_left_right.svg diff --git a/apps/ios/Shared/Views/UserSettings/NetworkAndServers.swift b/apps/ios/Shared/Views/UserSettings/NetworkAndServers.swift index 01cb6ad2d3..6d849479e5 100644 --- a/apps/ios/Shared/Views/UserSettings/NetworkAndServers.swift +++ b/apps/ios/Shared/Views/UserSettings/NetworkAndServers.swift @@ -261,9 +261,9 @@ struct NetworkAndServers: View { private func proxyFallbackInfo(_ proxyFallback: SMPProxyFallback) -> LocalizedStringKey { switch proxyFallback { - case .allow: return "Send messages directly when your or destination server does not support 2-hop onion routing." - case .allowProtected: return "Send messages directly when IP address is protected and your or destination server does not support 2-hop onion routing." - case .prohibit: return "Do NOT send messages directly, even if your or destination server does not support 2-hop onion routing." + case .allow: return "Send messages directly when your or destination server does not support private routing." + case .allowProtected: return "Send messages directly when IP address is protected and your or destination server does not support private routing." + case .prohibit: return "Do NOT send messages directly, even if your or destination server does not support private routing." } } } diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/NetworkAndServers.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/NetworkAndServers.kt index 4d33040e29..d07fad8623 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/NetworkAndServers.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/NetworkAndServers.kt @@ -43,6 +43,8 @@ fun NetworkAndServersView() { val developerTools = chatModel.controller.appPrefs.developerTools.get() val onionHosts = remember { mutableStateOf(netCfg.onionHosts) } val sessionMode = remember { mutableStateOf(netCfg.sessionMode) } + val smpProxyMode = remember { mutableStateOf(netCfg.smpProxyMode) } + val smpProxyFallback = remember { mutableStateOf(netCfg.smpProxyFallback) } val proxyPort = remember { derivedStateOf { chatModel.controller.appPrefs.networkProxyHostPort.state.value?.split(":")?.lastOrNull()?.toIntOrNull() ?: 9050 } } NetworkAndServersLayout( @@ -51,6 +53,8 @@ fun NetworkAndServersView() { networkUseSocksProxy = networkUseSocksProxy, onionHosts = onionHosts, sessionMode = sessionMode, + smpProxyMode = smpProxyMode, + smpProxyFallback = smpProxyFallback, proxyPort = proxyPort, toggleSocksProxy = { enable -> if (enable) { @@ -137,6 +141,59 @@ fun NetworkAndServersView() { } } } + }, + updateSMPProxyMode = { + if (smpProxyMode.value == it) return@NetworkAndServersLayout + val prevValue = smpProxyMode.value + smpProxyMode.value = it + val startsWith = when (it) { + SMPProxyMode.Always -> generalGetString(MR.strings.network_smp_proxy_mode_always_description) + SMPProxyMode.Unknown -> generalGetString(MR.strings.network_smp_proxy_mode_unknown_description) + SMPProxyMode.Unprotected -> generalGetString(MR.strings.network_smp_proxy_mode_unprotected_description) + SMPProxyMode.Never -> generalGetString(MR.strings.network_smp_proxy_mode_never_description) + } + showUpdateNetworkSettingsDialog( + title = generalGetString(MR.strings.update_network_smp_proxy_mode_question), + startsWith, + onDismiss = { smpProxyMode.value = prevValue } + ) { + withBGApi { + val newCfg = chatModel.controller.getNetCfg().copy(smpProxyMode = it) + val res = chatModel.controller.apiSetNetworkConfig(newCfg) + if (res) { + chatModel.controller.setNetCfg(newCfg) + smpProxyMode.value = it + } else { + smpProxyMode.value = prevValue + } + } + } + }, + updateSMPProxyFallback = { + if (smpProxyFallback.value == it) return@NetworkAndServersLayout + val prevValue = smpProxyFallback.value + smpProxyFallback.value = it + val startsWith = when (it) { + SMPProxyFallback.Allow -> generalGetString(MR.strings.network_smp_proxy_fallback_allow_description) + SMPProxyFallback.AllowProtected -> generalGetString(MR.strings.network_smp_proxy_fallback_allow_protected_description) + SMPProxyFallback.Prohibit -> generalGetString(MR.strings.network_smp_proxy_fallback_prohibit_description) + } + showUpdateNetworkSettingsDialog( + title = generalGetString(MR.strings.update_network_smp_proxy_fallback_question), + startsWith, + onDismiss = { smpProxyFallback.value = prevValue } + ) { + withBGApi { + val newCfg = chatModel.controller.getNetCfg().copy(smpProxyFallback = it) + val res = chatModel.controller.apiSetNetworkConfig(newCfg) + if (res) { + chatModel.controller.setNetCfg(newCfg) + smpProxyFallback.value = it + } else { + smpProxyFallback.value = prevValue + } + } + } } ) } @@ -147,16 +204,22 @@ fun NetworkAndServersView() { networkUseSocksProxy: MutableState, onionHosts: MutableState, sessionMode: MutableState, + smpProxyMode: MutableState, + smpProxyFallback: MutableState, proxyPort: State, toggleSocksProxy: (Boolean) -> Unit, useOnion: (OnionHosts) -> Unit, updateSessionMode: (TransportSessionMode) -> Unit, + updateSMPProxyMode: (SMPProxyMode) -> Unit, + updateSMPProxyFallback: (SMPProxyFallback) -> Unit, ) { val m = chatModel ColumnWithScrollBar( Modifier.fillMaxWidth(), verticalArrangement = Arrangement.spacedBy(8.dp) ) { + val showModal = { it: @Composable ModalData.() -> Unit -> ModalManager.start.showModal(content = it) } + AppBarTitle(stringResource(MR.strings.network_and_servers)) if (!chatModel.desktopNoUserNoRemote) { SectionView(generalGetString(MR.strings.settings_section_title_messages)) { @@ -165,7 +228,6 @@ fun NetworkAndServersView() { SettingsActionItem(painterResource(MR.images.ic_dns), stringResource(MR.strings.xftp_servers), { ModalManager.start.showCustomModal { close -> ProtocolServersView(m, m.remoteHostId, ServerProtocol.XFTP, close) } }) if (currentRemoteHost == null) { - val showModal = { it: @Composable ModalData.() -> Unit -> ModalManager.start.showModal(content = it) } UseSocksProxySwitch(networkUseSocksProxy, proxyPort, toggleSocksProxy, showModal, chatModel.controller.appPrefs.networkProxyHostPort, false) UseOnionHosts(onionHosts, networkUseSocksProxy, showModal, useOnion) if (developerTools) { @@ -188,6 +250,18 @@ fun NetworkAndServersView() { Divider(Modifier.padding(start = DEFAULT_PADDING_HALF, top = 24.dp, end = DEFAULT_PADDING_HALF, bottom = 30.dp)) } + if (currentRemoteHost == null) { + SectionView(generalGetString(MR.strings.settings_section_title_private_message_routing)) { + SMPProxyModePicker(smpProxyMode, showModal, updateSMPProxyMode) + SMPProxyFallbackPicker(smpProxyFallback, showModal, updateSMPProxyFallback, enabled = remember { mutableStateOf(smpProxyMode.value != SMPProxyMode.Never) }) + SettingsPreferenceItem(painterResource(MR.images.ic_arrow_forward), stringResource(MR.strings.private_routing_show_message_status), chatModel.controller.appPrefs.showSentViaProxy) + } + SectionCustomFooter { + Text(stringResource(MR.strings.private_routing_explanation)) + } + Divider(Modifier.padding(start = DEFAULT_PADDING_HALF, top = 32.dp, end = DEFAULT_PADDING_HALF, bottom = 30.dp)) + } + SectionView(generalGetString(MR.strings.settings_section_title_calls)) { SettingsActionItem(painterResource(MR.images.ic_electrical_services), stringResource(MR.strings.webrtc_ice_servers), { ModalManager.start.showModal { RTCServersView(m) } }) } @@ -452,6 +526,79 @@ private fun SessionModePicker( ) } +@Composable +private fun SMPProxyModePicker( + smpProxyMode: MutableState, + showModal: (@Composable ModalData.() -> Unit) -> Unit, + updateSMPProxyMode: (SMPProxyMode) -> Unit, +) { + val density = LocalDensity.current + val values = remember { + SMPProxyMode.values().map { + when (it) { + SMPProxyMode.Always -> ValueTitleDesc(SMPProxyMode.Always, generalGetString(MR.strings.network_smp_proxy_mode_always), escapedHtmlToAnnotatedString(generalGetString(MR.strings.network_smp_proxy_mode_always_description), density)) + SMPProxyMode.Unknown -> ValueTitleDesc(SMPProxyMode.Unknown, generalGetString(MR.strings.network_smp_proxy_mode_unknown), escapedHtmlToAnnotatedString(generalGetString(MR.strings.network_smp_proxy_mode_unknown_description), density)) + SMPProxyMode.Unprotected -> ValueTitleDesc(SMPProxyMode.Unprotected, generalGetString(MR.strings.network_smp_proxy_mode_unprotected), escapedHtmlToAnnotatedString(generalGetString(MR.strings.network_smp_proxy_mode_unprotected_description), density)) + SMPProxyMode.Never -> ValueTitleDesc(SMPProxyMode.Never, generalGetString(MR.strings.network_smp_proxy_mode_never), escapedHtmlToAnnotatedString(generalGetString(MR.strings.network_smp_proxy_mode_never_description), density)) + } + } + } + + SectionItemWithValue( + generalGetString(MR.strings.network_smp_proxy_mode_private_routing), + smpProxyMode, + values, + icon = painterResource(MR.images.ic_settings_ethernet), + onSelected = { + showModal { + ColumnWithScrollBar( + Modifier.fillMaxWidth(), + ) { + AppBarTitle(stringResource(MR.strings.network_smp_proxy_mode_private_routing)) + SectionViewSelectable(null, smpProxyMode, values, updateSMPProxyMode) + } + } + } + ) +} + +@Composable +private fun SMPProxyFallbackPicker( + smpProxyFallback: MutableState, + showModal: (@Composable ModalData.() -> Unit) -> Unit, + updateSMPProxyFallback: (SMPProxyFallback) -> Unit, + enabled: State, +) { + val density = LocalDensity.current + val values = remember { + SMPProxyFallback.values().map { + when (it) { + SMPProxyFallback.Allow -> ValueTitleDesc(SMPProxyFallback.Allow, generalGetString(MR.strings.network_smp_proxy_fallback_allow), escapedHtmlToAnnotatedString(generalGetString(MR.strings.network_smp_proxy_fallback_allow_description), density)) + SMPProxyFallback.AllowProtected -> ValueTitleDesc(SMPProxyFallback.AllowProtected, generalGetString(MR.strings.network_smp_proxy_fallback_allow_protected), escapedHtmlToAnnotatedString(generalGetString(MR.strings.network_smp_proxy_fallback_allow_protected_description), density)) + SMPProxyFallback.Prohibit -> ValueTitleDesc(SMPProxyFallback.Prohibit, generalGetString(MR.strings.network_smp_proxy_fallback_prohibit), escapedHtmlToAnnotatedString(generalGetString(MR.strings.network_smp_proxy_fallback_prohibit_description), density)) + } + } + } + + SectionItemWithValue( + generalGetString(MR.strings.network_smp_proxy_fallback_allow_downgrade), + smpProxyFallback, + values, + icon = painterResource(MR.images.ic_arrows_left_right), + enabled = enabled, + onSelected = { + showModal { + ColumnWithScrollBar( + Modifier.fillMaxWidth(), + ) { + AppBarTitle(stringResource(MR.strings.network_smp_proxy_fallback_allow_downgrade)) + SectionViewSelectable(null, smpProxyFallback, values, updateSMPProxyFallback) + } + } + } + ) +} + @Composable private fun NetworkSectionFooter(revert: () -> Unit, save: () -> Unit, revertDisabled: Boolean, saveDisabled: Boolean) { Row( @@ -506,8 +653,12 @@ fun PreviewNetworkAndServersLayout() { toggleSocksProxy = {}, onionHosts = remember { mutableStateOf(OnionHosts.PREFER) }, sessionMode = remember { mutableStateOf(TransportSessionMode.User) }, + smpProxyMode = remember { mutableStateOf(SMPProxyMode.Never) }, + smpProxyFallback = remember { mutableStateOf(SMPProxyFallback.Allow) }, useOnion = {}, updateSessionMode = {}, + updateSMPProxyMode = {}, + updateSMPProxyFallback = {}, ) } } diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/base/strings.xml b/apps/multiplatform/common/src/commonMain/resources/MR/base/strings.xml index 83ca79bd3a..93e6a902f4 100644 --- a/apps/multiplatform/common/src/commonMain/resources/MR/base/strings.xml +++ b/apps/multiplatform/common/src/commonMain/resources/MR/base/strings.xml @@ -722,6 +722,26 @@ Update transport isolation mode? Use .onion hosts to No if SOCKS proxy does not support them.]]> Please note: message and file relays are connected via SOCKS proxy. Calls and sending link previews use direct connection.]]> + Private routing + Always + Unknown relays + Unprotected + Never + Always use private routing. + Use private routing with unknown servers. + Use private routing with unknown servers when IP address is not protected. + Do NOT use private routing. + Message routing mode + Allow downgrade + Yes + When IP hidden + No + Send messages directly when your or destination server does not support private routing. + Send messages directly when IP address is protected and your or destination server does not support private routing. + Do NOT send messages directly, even if your or destination server does not support private routing. + Message routing fallback + Show message status + To protect your IP address, private routing uses your SMP servers to deliver messages. Appearance Customize theme THEME COLORS @@ -1047,6 +1067,7 @@ THEMES Profile images MESSAGES AND FILES + PRIVATE MESSAGE ROUTING CALLS Network connection Incognito mode diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_arrows_left_right.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_arrows_left_right.svg new file mode 100644 index 0000000000..de3a39b826 --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_arrows_left_right.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file From ef75eceb4006aa05862af3bb8c91f992a3bdde2b Mon Sep 17 00:00:00 2001 From: spaced4ndy <8711996+spaced4ndy@users.noreply.github.com> Date: Thu, 16 May 2024 14:11:55 +0400 Subject: [PATCH 2/7] core: support message forwarding with custom ttl (#4191) --- src/Simplex/Chat.hs | 14 +++++++------- src/Simplex/Chat/Controller.hs | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/Simplex/Chat.hs b/src/Simplex/Chat.hs index f2f6fb2783..7d42cd13b8 100644 --- a/src/Simplex/Chat.hs +++ b/src/Simplex/Chat.hs @@ -870,15 +870,15 @@ processChatCommand' vr = \case throwChatError (CECommandError $ "reaction already " <> if add then "added" else "removed") when (add && length rs >= maxMsgReactions) $ throwChatError (CECommandError "too many reactions") - APIForwardChatItem (ChatRef toCType toChatId) (ChatRef fromCType fromChatId) itemId -> withUser $ \user -> case toCType of + APIForwardChatItem (ChatRef toCType toChatId) (ChatRef fromCType fromChatId) itemId itemTTL -> withUser $ \user -> case toCType of CTDirect -> do (cm, ciff) <- prepareForward user withContactLock "forwardChatItem, to contact" toChatId $ - sendContactContentMessage user toChatId False Nothing cm ciff + sendContactContentMessage user toChatId False itemTTL cm ciff CTGroup -> do (cm, ciff) <- prepareForward user withGroupLock "forwardChatItem, to group" toChatId $ - sendGroupContentMessage user toChatId False Nothing cm ciff + sendGroupContentMessage user toChatId False itemTTL cm ciff CTLocal -> do (cm, ciff) <- prepareForward user createNoteFolderContentItem user toChatId cm ciff @@ -1626,17 +1626,17 @@ processChatCommand' vr = \case contactId <- withStore $ \db -> getContactIdByName db user fromContactName forwardedItemId <- withStore $ \db -> getDirectChatItemIdByText' db user contactId forwardedMsg toChatRef <- getChatRef user toChatName - processChatCommand $ APIForwardChatItem toChatRef (ChatRef CTDirect contactId) forwardedItemId + processChatCommand $ APIForwardChatItem toChatRef (ChatRef CTDirect contactId) forwardedItemId Nothing ForwardGroupMessage toChatName fromGroupName fromMemberName_ forwardedMsg -> withUser $ \user -> do groupId <- withStore $ \db -> getGroupIdByName db user fromGroupName forwardedItemId <- withStore $ \db -> getGroupChatItemIdByText db user groupId fromMemberName_ forwardedMsg toChatRef <- getChatRef user toChatName - processChatCommand $ APIForwardChatItem toChatRef (ChatRef CTGroup groupId) forwardedItemId + processChatCommand $ APIForwardChatItem toChatRef (ChatRef CTGroup groupId) forwardedItemId Nothing ForwardLocalMessage toChatName forwardedMsg -> withUser $ \user -> do folderId <- withStore (`getUserNoteFolderId` user) forwardedItemId <- withStore $ \db -> getLocalChatItemIdByText' db user folderId forwardedMsg toChatRef <- getChatRef user toChatName - processChatCommand $ APIForwardChatItem toChatRef (ChatRef CTLocal folderId) forwardedItemId + processChatCommand $ APIForwardChatItem toChatRef (ChatRef CTLocal folderId) forwardedItemId Nothing SendMessage (ChatName cType name) msg -> withUser $ \user -> do let mc = MCText msg case cType of @@ -7141,7 +7141,7 @@ chatCommandP = "/_delete item " *> (APIDeleteChatItem <$> chatRefP <* A.space <*> A.decimal <* A.space <*> ciDeleteMode), "/_delete member item #" *> (APIDeleteMemberChatItem <$> A.decimal <* A.space <*> A.decimal <* A.space <*> A.decimal), "/_reaction " *> (APIChatItemReaction <$> chatRefP <* A.space <*> A.decimal <* A.space <*> onOffP <* A.space <*> jsonP), - "/_forward " *> (APIForwardChatItem <$> chatRefP <* A.space <*> chatRefP <* A.space <*> A.decimal), + "/_forward " *> (APIForwardChatItem <$> chatRefP <* A.space <*> chatRefP <* A.space <*> A.decimal <*> sendMessageTTLP), "/_read user " *> (APIUserRead <$> A.decimal), "/read user" $> UserRead, "/_read chat " *> (APIChatRead <$> chatRefP <*> optional (A.space *> ((,) <$> ("from=" *> A.decimal) <* A.space <*> ("to=" *> A.decimal)))), diff --git a/src/Simplex/Chat/Controller.hs b/src/Simplex/Chat/Controller.hs index 58e0e2e321..8f239088d5 100644 --- a/src/Simplex/Chat/Controller.hs +++ b/src/Simplex/Chat/Controller.hs @@ -291,7 +291,7 @@ data ChatCommand | APIDeleteChatItem ChatRef ChatItemId CIDeleteMode | APIDeleteMemberChatItem GroupId GroupMemberId ChatItemId | APIChatItemReaction {chatRef :: ChatRef, chatItemId :: ChatItemId, add :: Bool, reaction :: MsgReaction} - | APIForwardChatItem {toChatRef :: ChatRef, fromChatRef :: ChatRef, chatItemId :: ChatItemId} + | APIForwardChatItem {toChatRef :: ChatRef, fromChatRef :: ChatRef, chatItemId :: ChatItemId, ttl :: Maybe Int} | APIUserRead UserId | UserRead | APIChatRead ChatRef (Maybe (ChatItemId, ChatItemId)) From d1dde3d0c8674c33b81e709aca1e29dfc2525873 Mon Sep 17 00:00:00 2001 From: spaced4ndy <8711996+spaced4ndy@users.noreply.github.com> Date: Thu, 16 May 2024 14:12:58 +0400 Subject: [PATCH 3/7] ui: support message forwarding with custom ttl (#4192) --- apps/ios/Shared/Model/SimpleXAPI.swift | 4 ++-- .../Views/Chat/ComposeMessage/ComposeView.swift | 9 +++++---- .../Views/Chat/ComposeMessage/SendMessageView.swift | 3 +-- apps/ios/SimpleXChat/APITypes.swift | 6 ++++-- .../kotlin/chat/simplex/common/model/SimpleXAPI.kt | 11 +++++++---- .../chat/simplex/common/views/chat/ComposeView.kt | 9 +++++---- .../chat/simplex/common/views/chat/SendMsgView.kt | 2 +- 7 files changed, 25 insertions(+), 19 deletions(-) diff --git a/apps/ios/Shared/Model/SimpleXAPI.swift b/apps/ios/Shared/Model/SimpleXAPI.swift index 4a982e18bb..b270b939c4 100644 --- a/apps/ios/Shared/Model/SimpleXAPI.swift +++ b/apps/ios/Shared/Model/SimpleXAPI.swift @@ -341,8 +341,8 @@ func apiGetChatItemInfo(type: ChatType, id: Int64, itemId: Int64) async throws - throw r } -func apiForwardChatItem(toChatType: ChatType, toChatId: Int64, fromChatType: ChatType, fromChatId: Int64, itemId: Int64) async -> ChatItem? { - let cmd: ChatCommand = .apiForwardChatItem(toChatType: toChatType, toChatId: toChatId, fromChatType: fromChatType, fromChatId: fromChatId, itemId: itemId) +func apiForwardChatItem(toChatType: ChatType, toChatId: Int64, fromChatType: ChatType, fromChatId: Int64, itemId: Int64, ttl: Int?) async -> ChatItem? { + let cmd: ChatCommand = .apiForwardChatItem(toChatType: toChatType, toChatId: toChatId, fromChatType: fromChatType, fromChatId: fromChatId, itemId: itemId, ttl: ttl) return await processSendMessageCmd(toChatType: toChatType, cmd: cmd) } diff --git a/apps/ios/Shared/Views/Chat/ComposeMessage/ComposeView.swift b/apps/ios/Shared/Views/Chat/ComposeMessage/ComposeView.swift index 6cf9df782b..3f1824cd6a 100644 --- a/apps/ios/Shared/Views/Chat/ComposeMessage/ComposeView.swift +++ b/apps/ios/Shared/Views/Chat/ComposeMessage/ComposeView.swift @@ -712,9 +712,9 @@ struct ComposeView: View { if chat.chatInfo.contact?.nextSendGrpInv ?? false { await sendMemberContactInvitation() } else if case let .forwardingItem(ci, fromChatInfo) = composeState.contextItem { - sent = await forwardItem(ci, fromChatInfo) + sent = await forwardItem(ci, fromChatInfo, ttl) if !composeState.message.isEmpty { - sent = await send(checkLinkPreview(), quoted: sent?.id, live: false, ttl: nil) + sent = await send(checkLinkPreview(), quoted: sent?.id, live: false, ttl: ttl) } } else if case let .editingItem(ci) = composeState.contextItem { sent = await updateMessage(ci, live: live) @@ -890,13 +890,14 @@ struct ComposeView: View { return nil } - func forwardItem(_ forwardedItem: ChatItem, _ fromChatInfo: ChatInfo) async -> ChatItem? { + func forwardItem(_ forwardedItem: ChatItem, _ fromChatInfo: ChatInfo, _ ttl: Int?) async -> ChatItem? { if let chatItem = await apiForwardChatItem( toChatType: chat.chatInfo.chatType, toChatId: chat.chatInfo.apiId, fromChatType: fromChatInfo.chatType, fromChatId: fromChatInfo.apiId, - itemId: forwardedItem.id + itemId: forwardedItem.id, + ttl: ttl ) { await MainActor.run { chatModel.addChatItem(chat.chatInfo, chatItem) diff --git a/apps/ios/Shared/Views/Chat/ComposeMessage/SendMessageView.swift b/apps/ios/Shared/Views/Chat/ComposeMessage/SendMessageView.swift index 8b528a201c..a180efbd28 100644 --- a/apps/ios/Shared/Views/Chat/ComposeMessage/SendMessageView.swift +++ b/apps/ios/Shared/Views/Chat/ComposeMessage/SendMessageView.swift @@ -224,8 +224,7 @@ struct SendMessageView: View { @ViewBuilder private func sendButtonContextMenuItems() -> some View { if composeState.liveMessage == nil, - !composeState.editing, - !composeState.forwarding { + !composeState.editing { if case .noContextItem = composeState.contextItem, !composeState.voicePreview, let send = sendLiveMessage, diff --git a/apps/ios/SimpleXChat/APITypes.swift b/apps/ios/SimpleXChat/APITypes.swift index 6a4340ea40..980a474c17 100644 --- a/apps/ios/SimpleXChat/APITypes.swift +++ b/apps/ios/SimpleXChat/APITypes.swift @@ -48,7 +48,7 @@ public enum ChatCommand { case apiDeleteChatItem(type: ChatType, id: Int64, itemId: Int64, mode: CIDeleteMode) case apiDeleteMemberChatItem(groupId: Int64, groupMemberId: Int64, itemId: Int64) case apiChatItemReaction(type: ChatType, id: Int64, itemId: Int64, add: Bool, reaction: MsgReaction) - case apiForwardChatItem(toChatType: ChatType, toChatId: Int64, fromChatType: ChatType, fromChatId: Int64, itemId: Int64) + case apiForwardChatItem(toChatType: ChatType, toChatId: Int64, fromChatType: ChatType, fromChatId: Int64, itemId: Int64, ttl: Int?) case apiGetNtfToken case apiRegisterToken(token: DeviceToken, notificationMode: NotificationsMode) case apiVerifyToken(token: DeviceToken, nonce: String, code: String) @@ -192,7 +192,9 @@ public enum ChatCommand { case let .apiDeleteChatItem(type, id, itemId, mode): return "/_delete item \(ref(type, id)) \(itemId) \(mode.rawValue)" case let .apiDeleteMemberChatItem(groupId, groupMemberId, itemId): return "/_delete member item #\(groupId) \(groupMemberId) \(itemId)" case let .apiChatItemReaction(type, id, itemId, add, reaction): return "/_reaction \(ref(type, id)) \(itemId) \(onOff(add)) \(encodeJSON(reaction))" - case let .apiForwardChatItem(toChatType, toChatId, fromChatType, fromChatId, itemId): return "/_forward \(ref(toChatType, toChatId)) \(ref(fromChatType, fromChatId)) \(itemId)" + case let .apiForwardChatItem(toChatType, toChatId, fromChatType, fromChatId, itemId, ttl): + let ttlStr = ttl != nil ? "\(ttl!)" : "default" + return "/_forward \(ref(toChatType, toChatId)) \(ref(fromChatType, fromChatId)) \(itemId) ttl=\(ttlStr)" case .apiGetNtfToken: return "/_ntf get " case let .apiRegisterToken(token, notificationMode): return "/_ntf register \(token.cmdString) \(notificationMode.rawValue)" case let .apiVerifyToken(token, nonce, code): return "/_ntf verify \(token.cmdString) \(nonce) \(code)" diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/SimpleXAPI.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/SimpleXAPI.kt index e548ac3e6e..57b26f4bc1 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/SimpleXAPI.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/SimpleXAPI.kt @@ -782,8 +782,8 @@ object ChatController { } } - suspend fun apiForwardChatItem(rh: Long?, toChatType: ChatType, toChatId: Long, fromChatType: ChatType, fromChatId: Long, itemId: Long): ChatItem? { - val cmd = CC.ApiForwardChatItem(toChatType, toChatId, fromChatType, fromChatId, itemId) + suspend fun apiForwardChatItem(rh: Long?, toChatType: ChatType, toChatId: Long, fromChatType: ChatType, fromChatId: Long, itemId: Long, ttl: Int?): ChatItem? { + val cmd = CC.ApiForwardChatItem(toChatType, toChatId, fromChatType, fromChatId, itemId, ttl) return processSendMessageCmd(rh, cmd)?.chatItem } @@ -2428,7 +2428,7 @@ sealed class CC { class ApiDeleteChatItem(val type: ChatType, val id: Long, val itemId: Long, val mode: CIDeleteMode): CC() class ApiDeleteMemberChatItem(val groupId: Long, val groupMemberId: Long, val itemId: Long): CC() class ApiChatItemReaction(val type: ChatType, val id: Long, val itemId: Long, val add: Boolean, val reaction: MsgReaction): CC() - class ApiForwardChatItem(val toChatType: ChatType, val toChatId: Long, val fromChatType: ChatType, val fromChatId: Long, val itemId: Long): CC() + class ApiForwardChatItem(val toChatType: ChatType, val toChatId: Long, val fromChatType: ChatType, val fromChatId: Long, val itemId: Long, val ttl: Int?): CC() class ApiNewGroup(val userId: Long, val incognito: Boolean, val groupProfile: GroupProfile): CC() class ApiAddMember(val groupId: Long, val contactId: Long, val memberRole: GroupMemberRole): CC() class ApiJoinGroup(val groupId: Long): CC() @@ -2570,7 +2570,10 @@ sealed class CC { is ApiDeleteChatItem -> "/_delete item ${chatRef(type, id)} $itemId ${mode.deleteMode}" is ApiDeleteMemberChatItem -> "/_delete member item #$groupId $groupMemberId $itemId" is ApiChatItemReaction -> "/_reaction ${chatRef(type, id)} $itemId ${onOff(add)} ${json.encodeToString(reaction)}" - is ApiForwardChatItem -> "/_forward ${chatRef(toChatType, toChatId)} ${chatRef(fromChatType, fromChatId)} $itemId" + is ApiForwardChatItem -> { + val ttlStr = if (ttl != null) "$ttl" else "default" + "/_forward ${chatRef(toChatType, toChatId)} ${chatRef(fromChatType, fromChatId)} $itemId ttl=${ttlStr}" + } is ApiNewGroup -> "/_group $userId incognito=${onOff(incognito)} ${json.encodeToString(groupProfile)}" is ApiAddMember -> "/_add #$groupId $contactId ${memberRole.memberRole}" is ApiJoinGroup -> "/_join #$groupId" diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ComposeView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ComposeView.kt index 26ff8796d4..d9ea35096b 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ComposeView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ComposeView.kt @@ -408,14 +408,15 @@ fun ComposeView( composeState.value = composeState.value.copy(inProgress = true) } - suspend fun forwardItem(rhId: Long?, forwardedItem: ChatItem, fromChatInfo: ChatInfo): ChatItem? { + suspend fun forwardItem(rhId: Long?, forwardedItem: ChatItem, fromChatInfo: ChatInfo, ttl: Int?): ChatItem? { val chatItem = controller.apiForwardChatItem( rh = rhId, toChatType = chat.chatInfo.chatType, toChatId = chat.chatInfo.apiId, fromChatType = fromChatInfo.chatType, fromChatId = fromChatInfo.apiId, - itemId = forwardedItem.id + itemId = forwardedItem.id, + ttl = ttl ) if (chatItem != null) { chatModel.addChatItem(rhId, chat.chatInfo, chatItem) @@ -490,9 +491,9 @@ fun ComposeView( sendMemberContactInvitation() sent = null } else if (cs.contextItem is ComposeContextItem.ForwardingItem) { - sent = forwardItem(chat.remoteHostId, cs.contextItem.chatItem, cs.contextItem.fromChatInfo) + sent = forwardItem(chat.remoteHostId, cs.contextItem.chatItem, cs.contextItem.fromChatInfo, ttl = ttl) if (cs.message.isNotEmpty()) { - sent = send(chat, checkLinkPreview(), quoted = sent?.id, live = false, ttl = null) + sent = send(chat, checkLinkPreview(), quoted = sent?.id, live = false, ttl = ttl) } } else if (cs.contextItem is ComposeContextItem.EditingItem) { val ei = cs.contextItem.chatItem diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/SendMsgView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/SendMsgView.kt index 58705bd00a..779371a07c 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/SendMsgView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/SendMsgView.kt @@ -157,7 +157,7 @@ fun SendMsgView( fun MenuItems(): List<@Composable () -> Unit> { val menuItems = mutableListOf<@Composable () -> Unit>() - if (cs.liveMessage == null && !cs.editing && !cs.forwarding && !nextSendGrpInv || sendMsgEnabled) { + if (cs.liveMessage == null && !cs.editing && !nextSendGrpInv || sendMsgEnabled) { if ( cs.preview !is ComposePreview.VoicePreview && cs.contextItem is ComposeContextItem.NoContextItem && From 49e09ca449ed45a300bf776a8bef3b9b7431913d Mon Sep 17 00:00:00 2001 From: spaced4ndy <8711996+spaced4ndy@users.noreply.github.com> Date: Thu, 16 May 2024 17:08:13 +0400 Subject: [PATCH 4/7] core: contact disabled event (#4194) --- src/Simplex/Chat.hs | 6 ++++-- src/Simplex/Chat/Controller.hs | 1 + src/Simplex/Chat/View.hs | 1 + 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/Simplex/Chat.hs b/src/Simplex/Chat.hs index 7d42cd13b8..acdfe116ff 100644 --- a/src/Simplex/Chat.hs +++ b/src/Simplex/Chat.hs @@ -4685,8 +4685,10 @@ processAgentMessageConn vr user@User {userId} corrId agentConnId agentMessage = case err of SMP _ SMP.AUTH -> do authErrCounter' <- withStore' $ \db -> incConnectionAuthErrCounter db user conn - when (authErrCounter' >= authErrDisableCount) $ do - toView $ CRConnectionDisabled connEntity + when (authErrCounter' >= authErrDisableCount) $ case connEntity of + RcvDirectMsgConnection ctConn (Just ct) -> do + toView $ CRContactDisabled user ct {activeConn = Just ctConn {authErrCounter = authErrCounter'}} + _ -> toView $ CRConnectionDisabled connEntity _ -> pure () -- TODO v5.7 / v6.0 - together with deprecating old group protocol establishing direct connections? diff --git a/src/Simplex/Chat/Controller.hs b/src/Simplex/Chat/Controller.hs index 8f239088d5..267298f188 100644 --- a/src/Simplex/Chat/Controller.hs +++ b/src/Simplex/Chat/Controller.hs @@ -748,6 +748,7 @@ data ChatResponse | CRAgentSubs {activeSubs :: Map Text Int, pendingSubs :: Map Text Int, removedSubs :: Map Text [String]} | CRAgentSubsDetails {agentSubs :: SubscriptionsInfo} | CRAgentMsgCounts {msgCounts :: [(Text, (Int, Int))]} + | CRContactDisabled {user :: User, contact :: Contact} | CRConnectionDisabled {connectionEntity :: ConnectionEntity} | CRAgentRcvQueueDeleted {agentConnId :: AgentConnId, server :: SMPServer, agentQueueId :: AgentQueueId, agentError_ :: Maybe AgentErrorType} | CRAgentConnDeleted {agentConnId :: AgentConnId} diff --git a/src/Simplex/Chat/View.hs b/src/Simplex/Chat/View.hs index 236730e45d..4b3240fe46 100644 --- a/src/Simplex/Chat/View.hs +++ b/src/Simplex/Chat/View.hs @@ -376,6 +376,7 @@ responseToView hu@(currentRH, user_) ChatConfig {logLevel, showReactions, showRe plain . LB.unpack $ J.encode agentWorkersDetails -- this would be huge, but copypastable when has its own line ] CRAgentMsgCounts {msgCounts} -> ["received messages (total, duplicates):", plain . LB.unpack $ J.encode msgCounts] + CRContactDisabled u c -> ttyUser u ["[" <> ttyContact' c <> "] connection is disabled, to enable: " <> highlight ("/enable " <> viewContactName c) <> ", to delete: " <> highlight ("/d " <> viewContactName c)] CRConnectionDisabled entity -> viewConnectionEntityDisabled entity CRAgentRcvQueueDeleted acId srv aqId err_ -> [ ("completed deleting rcv queue, agent connection id: " <> sShow acId) From d3e522e169e54004321cf8925931fb98849a8e77 Mon Sep 17 00:00:00 2001 From: spaced4ndy <8711996+spaced4ndy@users.noreply.github.com> Date: Thu, 16 May 2024 17:08:31 +0400 Subject: [PATCH 5/7] ui: disable send field for disabled connection (based on authErrCounter) (#4193) --- apps/ios/Shared/Model/SimpleXAPI.swift | 6 ++++++ apps/ios/SimpleXChat/APITypes.swift | 3 +++ apps/ios/SimpleXChat/ChatTypes.swift | 17 ++++++++++++++--- .../chat/simplex/common/model/ChatModel.kt | 18 +++++++++++++----- .../chat/simplex/common/model/SimpleXAPI.kt | 8 ++++++++ 5 files changed, 44 insertions(+), 8 deletions(-) diff --git a/apps/ios/Shared/Model/SimpleXAPI.swift b/apps/ios/Shared/Model/SimpleXAPI.swift index b270b939c4..ef31d2f438 100644 --- a/apps/ios/Shared/Model/SimpleXAPI.swift +++ b/apps/ios/Shared/Model/SimpleXAPI.swift @@ -1873,6 +1873,12 @@ func processReceivedMsg(_ res: ChatResponse) async { m.updateGroupMemberConnectionStats(groupInfo, member, ratchetSyncProgress.connectionStats) } } + case let .contactDisabled(user, contact): + if active(user) { + await MainActor.run { + m.updateContact(contact) + } + } case let .remoteCtrlFound(remoteCtrl, ctrlAppInfo_, appVersion, compatible): await MainActor.run { if let sess = m.remoteCtrlSession, case .searching = sess.sessionState { diff --git a/apps/ios/SimpleXChat/APITypes.swift b/apps/ios/SimpleXChat/APITypes.swift index 980a474c17..97013ca2a4 100644 --- a/apps/ios/SimpleXChat/APITypes.swift +++ b/apps/ios/SimpleXChat/APITypes.swift @@ -641,6 +641,7 @@ public enum ChatResponse: Decodable, Error { case ntfMessages(user_: User?, connEntity_: ConnectionEntity?, msgTs: Date?, ntfMessages: [NtfMsgInfo]) case ntfMessage(user: UserRef, connEntity: ConnectionEntity, ntfMessage: NtfMsgInfo) case contactConnectionDeleted(user: UserRef, connection: PendingContactConnection) + case contactDisabled(user: UserRef, contact: Contact) // remote desktop responses/events case remoteCtrlList(remoteCtrls: [RemoteCtrlInfo]) case remoteCtrlFound(remoteCtrl: RemoteCtrlInfo, ctrlAppInfo_: CtrlAppInfo?, appVersion: String, compatible: Bool) @@ -798,6 +799,7 @@ public enum ChatResponse: Decodable, Error { case .ntfMessages: return "ntfMessages" case .ntfMessage: return "ntfMessage" case .contactConnectionDeleted: return "contactConnectionDeleted" + case .contactDisabled: return "contactDisabled" case .remoteCtrlList: return "remoteCtrlList" case .remoteCtrlFound: return "remoteCtrlFound" case .remoteCtrlConnecting: return "remoteCtrlConnecting" @@ -955,6 +957,7 @@ public enum ChatResponse: Decodable, Error { case let .ntfMessages(u, connEntity, msgTs, ntfMessages): return withUser(u, "connEntity: \(String(describing: connEntity))\nmsgTs: \(String(describing: msgTs))\nntfMessages: \(String(describing: ntfMessages))") case let .ntfMessage(u, connEntity, ntfMessage): return withUser(u, "connEntity: \(String(describing: connEntity))\nntfMessage: \(String(describing: ntfMessage))") case let .contactConnectionDeleted(u, connection): return withUser(u, String(describing: connection)) + case let .contactDisabled(u, contact): return withUser(u, String(describing: contact)) case let .remoteCtrlList(remoteCtrls): return String(describing: remoteCtrls) case let .remoteCtrlFound(remoteCtrl, ctrlAppInfo_, appVersion, compatible): return "remoteCtrl:\n\(String(describing: remoteCtrl))\nctrlAppInfo_:\n\(String(describing: ctrlAppInfo_))\nappVersion: \(appVersion)\ncompatible: \(compatible)" case let .remoteCtrlConnecting(remoteCtrl_, ctrlAppInfo, appVersion): return "remoteCtrl_:\n\(String(describing: remoteCtrl_))\nctrlAppInfo:\n\(String(describing: ctrlAppInfo))\nappVersion: \(appVersion)" diff --git a/apps/ios/SimpleXChat/ChatTypes.swift b/apps/ios/SimpleXChat/ChatTypes.swift index 09acd032a3..0d2a042d9d 100644 --- a/apps/ios/SimpleXChat/ChatTypes.swift +++ b/apps/ios/SimpleXChat/ChatTypes.swift @@ -1510,7 +1510,12 @@ public struct Contact: Identifiable, Decodable, NamedChat { public var ready: Bool { get { activeConn?.connStatus == .ready } } public var active: Bool { get { contactStatus == .active } } public var sendMsgEnabled: Bool { get { - (ready && active && !(activeConn?.connectionStats?.ratchetSyncSendProhibited ?? false)) + ( + ready + && active + && !(activeConn?.connectionStats?.ratchetSyncSendProhibited ?? false) + && !(activeConn?.connDisabled ?? true) + ) || nextSendGrpInv } } public var nextSendGrpInv: Bool { get { contactGroupMemberId != nil && !contactGrpInvSent } } @@ -1601,15 +1606,20 @@ public struct Connection: Decodable { public var pqEncryption: Bool public var pqSndEnabled: Bool? public var pqRcvEnabled: Bool? + public var authErrCounter: Int public var connectionStats: ConnectionStats? = nil private enum CodingKeys: String, CodingKey { - case connId, agentConnId, peerChatVRange, connStatus, connLevel, viaGroupLink, customUserProfileId, connectionCode, pqSupport, pqEncryption, pqSndEnabled, pqRcvEnabled + case connId, agentConnId, peerChatVRange, connStatus, connLevel, viaGroupLink, customUserProfileId, connectionCode, pqSupport, pqEncryption, pqSndEnabled, pqRcvEnabled, authErrCounter } public var id: ChatId { get { ":\(connId)" } } + public var connDisabled: Bool { + authErrCounter >= 10 // authErrDisableCount in core + } + public var connPQEnabled: Bool { pqSndEnabled == true && pqRcvEnabled == true } @@ -1622,7 +1632,8 @@ public struct Connection: Decodable { connLevel: 0, viaGroupLink: false, pqSupport: false, - pqEncryption: false + pqEncryption: false, + authErrCounter: 0 ) } diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/ChatModel.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/ChatModel.kt index 4c82f2e7f7..3780066092 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/ChatModel.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/ChatModel.kt @@ -1048,9 +1048,13 @@ data class Contact( override val apiId get() = contactId override val ready get() = activeConn?.connStatus == ConnStatus.Ready val active get() = contactStatus == ContactStatus.Active - override val sendMsgEnabled get() = - (ready && active && !(activeConn?.connectionStats?.ratchetSyncSendProhibited ?: false)) - || nextSendGrpInv + override val sendMsgEnabled get() = ( + ready + && active + && !(activeConn?.connectionStats?.ratchetSyncSendProhibited ?: false) + && !(activeConn?.connDisabled ?: true) + ) + || nextSendGrpInv val nextSendGrpInv get() = contactGroupMemberId != null && !contactGrpInvSent override val ntfsEnabled get() = chatSettings.enableNtfs == MsgFilter.All override val incognito get() = contactConnIncognito @@ -1150,15 +1154,19 @@ data class Connection( val pqEncryption: Boolean, val pqSndEnabled: Boolean? = null, val pqRcvEnabled: Boolean? = null, - val connectionStats: ConnectionStats? = null + val connectionStats: ConnectionStats? = null, + val authErrCounter: Int ) { val id: ChatId get() = ":$connId" + val connDisabled: Boolean + get() = authErrCounter >= 10 // authErrDisableCount in core + val connPQEnabled: Boolean get() = pqSndEnabled == true && pqRcvEnabled == true companion object { - val sampleData = Connection(connId = 1, agentConnId = "abc", connStatus = ConnStatus.Ready, connLevel = 0, viaGroupLink = false, peerChatVRange = VersionRange(1, 1), customUserProfileId = null, pqSupport = false, pqEncryption = false) + val sampleData = Connection(connId = 1, agentConnId = "abc", connStatus = ConnStatus.Ready, connLevel = 0, viaGroupLink = false, peerChatVRange = VersionRange(1, 1), customUserProfileId = null, pqSupport = false, pqEncryption = false, authErrCounter = 0) } } diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/SimpleXAPI.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/SimpleXAPI.kt index 57b26f4bc1..fa9c2580ee 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/SimpleXAPI.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/SimpleXAPI.kt @@ -2061,6 +2061,11 @@ object ChatController { chatModel.currentRemoteHost.value = r.remoteHost switchUIRemoteHost(r.remoteHost.remoteHostId) } + is CR.ContactDisabled -> { + if (active(r.user)) { + chatModel.updateContact(rhId, r.contact) + } + } is CR.RemoteHostStopped -> { val disconnectedHost = chatModel.remoteHosts.firstOrNull { it.remoteHostId == r.remoteHostId_ } chatModel.remoteHostPairing.value = null @@ -4257,6 +4262,7 @@ sealed class CR { @Serializable @SerialName("callExtraInfo") class CallExtraInfo(val user: UserRef, val contact: Contact, val extraInfo: WebRTCExtraInfo): CR() @Serializable @SerialName("callEnded") class CallEnded(val user: UserRef, val contact: Contact): CR() @Serializable @SerialName("contactConnectionDeleted") class ContactConnectionDeleted(val user: UserRef, val connection: PendingContactConnection): CR() + @Serializable @SerialName("contactDisabled") class ContactDisabled(val user: UserRef, val contact: Contact): CR() // remote events (desktop) @Serializable @SerialName("remoteHostList") class RemoteHostList(val remoteHosts: List): CR() @Serializable @SerialName("currentRemoteHost") class CurrentRemoteHost(val remoteHost_: RemoteHostInfo?): CR() @@ -4421,6 +4427,7 @@ sealed class CR { is CallExtraInfo -> "callExtraInfo" is CallEnded -> "callEnded" is ContactConnectionDeleted -> "contactConnectionDeleted" + is ContactDisabled -> "contactDisabled" is RemoteHostList -> "remoteHostList" is CurrentRemoteHost -> "currentRemoteHost" is RemoteHostStarted -> "remoteHostStarted" @@ -4581,6 +4588,7 @@ sealed class CR { is CallExtraInfo -> withUser(user, "contact: ${contact.id}\nextraInfo: ${json.encodeToString(extraInfo)}") is CallEnded -> withUser(user, "contact: ${contact.id}") is ContactConnectionDeleted -> withUser(user, json.encodeToString(connection)) + is ContactDisabled -> withUser(user, json.encodeToString(contact)) // remote events (mobile) is RemoteHostList -> json.encodeToString(remoteHosts) is CurrentRemoteHost -> if (remoteHost_ == null) "local" else json.encodeToString(remoteHost_) From b2a8797ed400999dc8fadfe6dc21535d51d48ba5 Mon Sep 17 00:00:00 2001 From: Evgeny Poberezkin Date: Thu, 16 May 2024 18:02:37 +0100 Subject: [PATCH 6/7] blog: Redefining Privacy by Making Hard Choices (#4195) * blog: Redefining Privacy by Making Hard Choices * update * update * revert * update * corrections Co-authored-by: Esra'a Al Shafei * update --------- Co-authored-by: Esra'a Al Shafei --- ...istance-signal-double-ratchet-algorithm.md | 4 +- ...ransparency-v5-7-better-user-experience.md | 2 + ...simplex-redefining-privacy-hard-choices.md | 79 +++++++++++++++++ blog/README.md | 14 +++ blog/images/20240314-comparison.jpg | Bin 142671 -> 142707 bytes blog/images/20240516-parliament.jpg | Bin 0 -> 114710 bytes blog/images/simplex-explained.svg | 82 ++++++++++++++++++ .../src/_includes/blog_previews/20240516.html | 17 ++++ website/src/call/call.js | 3 +- 9 files changed, 198 insertions(+), 3 deletions(-) create mode 100644 blog/20240516-simplex-redefining-privacy-hard-choices.md create mode 100644 blog/images/20240516-parliament.jpg create mode 100644 blog/images/simplex-explained.svg create mode 100644 website/src/_includes/blog_previews/20240516.html diff --git a/blog/20240314-simplex-chat-v5-6-quantum-resistance-signal-double-ratchet-algorithm.md b/blog/20240314-simplex-chat-v5-6-quantum-resistance-signal-double-ratchet-algorithm.md index 1e4c3adfb5..6d4c8b77a2 100644 --- a/blog/20240314-simplex-chat-v5-6-quantum-resistance-signal-double-ratchet-algorithm.md +++ b/blog/20240314-simplex-chat-v5-6-quantum-resistance-signal-double-ratchet-algorithm.md @@ -10,6 +10,8 @@ permalink: "/blog/20240314-simplex-chat-v5-6-quantum-resistance-signal-double-ra # SimpleX Chat v5.6 beta: adding quantum resistance to Signal double ratchet algorithm +**Published:** Mar 14, 2024 + This is a major upgrade for SimpleX messaging protocols, we are really proud to present the results of the hard work of our whole team on the [Pi day](https://en.wikipedia.org/wiki/Pi_Day). This post also covers various aspects of end-to-end encryption, compares different messengers, and explains why and how quantum-resistant encryption is added to SimpleX Chat: @@ -101,7 +103,7 @@ This attack is much less understood by the users, and forward secrecy does not p Out of all encryption algorithms known to us only _Signal double ratchet algorithm_ (also referred to as _Signal algorithm_ or _double ratchet algorithm_, which is not the same as Signal messaging platform and protocols) provides the ability for the encryption security to recover after break-ins attacks. This recovery happens automatically and transparently to the users, without them doing anything special or even knowing about break-in, by simply sending messages. Every time one of the communication parties replies to another party message, new random keys are generated and previously stolen keys become useless. -Double ratchet algorithm is used in Signal, Cwtch and SimpleX Chat. This is why you cannot use SimpleX Chat profile on more than one device at the same time - the encryption scheme rotates the long term keys, randomly, and keys on another device become useless, as they would become useless for the attacker who stole them. Security always has some costs to the convenience. +Double ratchet algorithm is used in Signal, Cwtch and SimpleX Chat. But Signal app by allowing to use the same profile on multiple devices compromises the break-in recovery function of Signal algorithm, as explained in [this paper](https://eprint.iacr.org/2021/626.pdf). Because of break-in recovery you cannot use SimpleX Chat profile on more than one device at the same time - the encryption scheme rotates the long term keys, randomly, and keys on another device become useless, as they would become useless for the attacker who stole them. Security always has some costs to the convenience. ### 5. Man-in-the-middle attack - mitigated by two-factor key exchange diff --git a/blog/20240426-simplex-legally-binding-transparency-v5-7-better-user-experience.md b/blog/20240426-simplex-legally-binding-transparency-v5-7-better-user-experience.md index 59d5897f41..cb3e5b2d10 100644 --- a/blog/20240426-simplex-legally-binding-transparency-v5-7-better-user-experience.md +++ b/blog/20240426-simplex-legally-binding-transparency-v5-7-better-user-experience.md @@ -10,6 +10,8 @@ permalink: "/blog/20240426-simplex-legally-binding-transparency-v5-7-better-user # SimpleX network: legally binding transparency, v5.7 released with better calls and messages +**Published:** Apr 26, 2024 + What's new in v5.7: - [quantum resistant end-to-end encryption](#quantum-resistant-end-to-end-encryption) with all contacts. - [forward and save messages](#forward-and-save-messages) without revealing the source. diff --git a/blog/20240516-simplex-redefining-privacy-hard-choices.md b/blog/20240516-simplex-redefining-privacy-hard-choices.md new file mode 100644 index 0000000000..a1545a8971 --- /dev/null +++ b/blog/20240516-simplex-redefining-privacy-hard-choices.md @@ -0,0 +1,79 @@ +--- +layout: layouts/article.html +title: "SimpleX: Redefining Privacy by Making Hard Choices" +date: 2024-05-16 +previewBody: blog_previews/20240516.html +image: images/simplex-explained.svg +imageWide: true +permalink: "/blog/20240516-simplex-redefining-privacy-hard-choices.html" +--- + +# SimpleX: Redefining Privacy by Making Hard Choices + +**Published:** May 16, 2024 + +When it comes to open source privacy tools, the status quo often dictates the limitations of existing protocols and structures. However, these norms need to be challenged to radically shift how we approach genuinely private communication. This requires doing some uncomfortable things, like making hard choices as it relates to funding, alternative decentralization models, doubling down on privacy over convenience, and more. + +There will always be questions on why the SimpleX Chat and network makes the choices it makes, and that’s good! It’s important to question us and to understand the reasoning behind each decision, whether it’s technical, structural, financial or any other. + +In this post we explain a bit more about why SimpleX operates and makes decisions the way it does. + +## No user accounts + +Within SimpleX network there are no user accounts, and more importantly, no user profile identifiers whatsoever at the protocol level, not even random numbers or cryptographic keys used to identify the users. This means there is absolutely nothing that uniquely links users to their contacts or to the network relays. While it's accurate to say, "You need an address to send something," it's crucial to understand that this "address" serves merely as a transient delivery destination, and not as a user profile identifier in any sense. + +You can read more about how SimpleX works [here](https://simplex.chat/#how-simplex-works). + +## Privacy over convenience + +One of the main considerations often ignored in security and privacy comparisons between messaging applications is multi-device access. For example, in Signal’s case, the Sesame protocol used to support multi-device access has the vulnerability that is [explained in detail here](https://eprint.iacr.org/2021/626.pdf): + +_"We present an attack on the post-compromise security of the Signal messenger that allows to stealthily register a new device via the Sesame protocol. [...] This new device can send and receive messages without raising any ‘Bad encrypted message’ errors. Our attack thus shows that the Signal messenger does not guarantee post-compromise security at all in the multi-device setting"_. + + + +Solutions are possible, and even the quoted paper proposes improvements, but they are not implemented in any existing communication solutions. Unfortunately this results in most communication systems, even those in the privacy space, having compromised security in multi-device settings due to these limitations. That's the reason we are not rushing a full multi-device support, and currently only provide [the ability to use mobile app profiles via the desktop app](./20231125-simplex-chat-v5-4-link-mobile-desktop-quantum-resistant-better-groups.md#link-mobile-and-desktop-apps-via-secure-quantum-resistant-protocol), while they are on the same network. + +Another choice that compromises privacy for convenience and usability is 3rd party push notifications. At SimpleX, we take a slow path of optimizing the network and battery consumption in the app, rather than simply hiding inefficiencies behind the quick fix solution of 3rd party push notifications that [increases vulnerability](https://www.wired.com/story/apple-google-push-notification-surveillance/), a path Signal and others chose. Like other choices, it has usability and optimization trade offs, but ultimately it’s the right thing to continue progressing towards a better solution as we explain [here](https://simplex.chat/blog/20220404-simplex-chat-instant-notifications.html). + +Whenever possible, we strive to achieve significantly higher levels of privacy and security. For example, unlike most, if not all, applications (including Signal), [we encrypt application files with per-file unique key](https://simplex.chat/blog/20230925-simplex-chat-v5-3-desktop-app-local-file-encryption-directory-service.html#encrypted-local-files-and-media-with-forward-secrecy). Consequently, once a message is deleted, there's no means to open a file that someone may have stolen in hopes of acquiring the key later. Similarly, apps like Session have done away with forward secrecy, a decision which caused them [not to be recommended](https://www.privacyguides.org/en/real-time-communication/#additional-options) for "long-term or sensitive communications". And [misinformation](https://simplifiedprivacy.com/spain-has-banned-telegram-defending-session/) around this makes it dangerous and irresponsible to recommend without such necessary disclosures for people’s awareness. + +Session’s decision was based on [the incorrect statements](https://getsession.org/blog/session-protocol-explained) about double ratchet being impossible in decentralized networks, and underplayed importance of forward secrecy, break-in recovery and deniability - the absence of these crucial qualities makes Session a much weaker choice for private messaging. For transparency, this was something that was debated with their team [here](https://twitter.com/SimpleXChat/status/1755216356159414602). We also made [a separate post](./20240314-simplex-chat-v5-6-quantum-resistance-signal-double-ratchet-algorithm.md#end-to-end-encryption-security-attacks-and-defense) about these qualities of end-to-end encryption and their presence in different messengers, to show that not all end-to-end encrypted apps offer the same level of protections. + +## Network decentralization + + + +It's important to recognize that a model of decentralization where all servers are openly known and accessible to all clients, that some users ask for, actually results in a less decentralized network, and as the network grows it often requires an introduction of a central authority to protect from bad actors with malicious intent. Therefore, we've deliberately opted for a slower path towards achieving a higher degree of decentralization where there is no central server registry or network authority. For example, p2p designs may offer higher initial decentralization but often compromise on privacy and eventual decentralization. In essence, our approach prioritizes a balance between initial decentralization, privacy, and higher degree of decentralization down the line. + +Additionally, while it's true that we haven't yet established a model to incentivize other network operators, it's certainly on the roadmap. We see the decentralization of network operators offered within the app as a top priority.  + +Where it stands today, users have the freedom to select their preferred servers within the SimpleX network by configuring the app, with thousands of self-hosted servers in operation. Moreover, numerous third-party applications rely on our code for their in-app communications, operating independently of our servers, many of which we may not even be aware of. + +Decentralization is an ongoing journey, and we strive to proceed at a measured pace to ensure its proper implementation. While the immediate results may not always appear ideal, prioritizing a careful approach ensures that in the long run, the decisions made in this area align with our ultimate objectives of a private, efficient, reliable and fully decentralized network. + +## Funding and profitability + +We explain our rationale for funding [here](../docs/FAQ.md#funding-and-business-model). Funding sources is always one of the most difficult choices to make, and it’s important to underline that VC models don’t necessarily translate to a quest for control, interference of any kind, or overall influence on product roadmap and strategy. The vast majority of investors seek profitability. Irrespective of the organization type profitability is essential for a sustainable operation, and it can and should be done while adhering to the highest possible standards for privacy. For-profit vs. nonprofit is also not an accurate metric to measure a commitment towards privacy and open standards, which is further explained [here](./20240404-why-i-joined-simplex-chat-esraa-al-shafei.md).   + +To make a profit, satisfying customers is the key. Unlike the many companies that profit from selling customer data, we put user privacy first. Doing this at scale requires investments. If the investors don’t own or control a company, their participation becomes merely about profit for them, and not about how this profit is obtained. With the investors we have, we are completely aligned on this - they are betting on the future where privacy is the norm. They do not dictate on anything related to our model. We build SimpleX chat, protocols and network the way Internet should have been built if we as developers always put the privacy and empowerment of users first. + +## Company jurisdiction + + + +With regards to jurisdictions, nowhere is perfect. For that reason we plan to establish the foundations for protocol governance in [various jurisdictions](https://simplex.chat/blog/20240323-simplex-network-privacy-non-profit-v5-6-quantum-resistant-e2e-encryption-simple-migration.html#the-journey-to-the-decentralized-non-profit-protocol-governance). + +But we’d like to clarify some misconceptions about the UK, where SimpleX Chat Ltd. is registered, and the UK legislation. + +For example, the Online Safety Act (OSA). Some people believe that it applies only to UK companies. But the OSA applicability isn’t determined by the company’s jurisdiction - it applies based on the nature and characteristics of the business and its services, as well as the number of its users in the UK. In case of SimpleX network, the OSA doesn’t apply for both of these reasons. + +The UK’s position on communication encryption, and more specifically, on end-to-end encrypted messaging, remains the subject of political debates. But with the OSA, the legislative intent was to propose technical measures to block CSAM, and it was trying to explore ways to do this via client-side scanning, which of course would undermine the encryption. However, and thanks to the hard work of privacy experts, researchers, academics and rights organizations throughout the UK and the rest of the world, the Online Safety Bill did not prohibit end-to-end encrypted apps without such scanners. It is an open question whether such technology will ever be possible, and the UK government made a public commitment that client-side scanning won't be required until it is. + +For now, strong end-to-end encryption remains permissible and protected, and we hope to also add to the privacy advocacy and debates as a UK-based company to keep it legally protected. + +Overall, we view the UK as being better jurisdiction for privacy than many alternatives - there are some trade-offs everywhere. + +## Looking ahead  + +The future of the Internet should be based on decentralized infrastructure operated by commercially viable organizations. These operators need to possess minimal user data, so that users have genuine control over their identities, and free from lock-in by the operators, to support fair competition. This requires a drastic re-imagining of the current norms and newer, more privacy-minded protocols. All in all, private messaging is surrounded by very difficult challenges but it’s worth it to keep pushing the industry forward and not settle for the status quo and current trade offs, protocol limitations and vulnerabilities. The Internet deserves better standards, and so do users. diff --git a/blog/README.md b/blog/README.md index 2f3b5aeeb2..a5f3d60b2e 100644 --- a/blog/README.md +++ b/blog/README.md @@ -1,5 +1,19 @@ # Blog +May 16, 2024 [SimpleX: Redefining Privacy by Making Hard Choices](./20240516-simplex-redefining-privacy-hard-choices.md) + +When it comes to open source privacy tools, the status quo often dictates the limitations of existing protocols and structures. However, these norms need to be challenged to radically shift how we approach genuinely private communication. This requires doing some uncomfortable things, like making hard choices as it relates to funding, alternative decentralization models, doubling down on privacy over convenience, and more. + +In this post we explain a bit more about why SimpleX operates and makes decisions the way it does: + +- No user accounts. +- Privacy over convenience. +- Network decentralization. +- Funding and profitability. +- Company jurisdiction. + +--- + Apr 26, 2024 [SimpleX network: legally binding transparency, v5.7 released with better calls and messages](./20240426-simplex-legally-binding-transparency-v5-7-better-user-experience.md) We published Transparency Reports, Security Policy, and Frequently Asked Questions, and updated Privacy Policy. diff --git a/blog/images/20240314-comparison.jpg b/blog/images/20240314-comparison.jpg index 579b2fd73c10ac7c89b24a08e30bccd7a1b1c156..5ff22be0052c3f080a382af4aef961d207b5a44c 100644 GIT binary patch delta 1631 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�i1iutr(5`55I@pxL2luDS3&mJ;!scp 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 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/website/src/_includes/blog_previews/20240516.html b/website/src/_includes/blog_previews/20240516.html new file mode 100644 index 0000000000..0d434eac36 --- /dev/null +++ b/website/src/_includes/blog_previews/20240516.html @@ -0,0 +1,17 @@ +

When it comes to open source privacy tools, the status quo often dictates the limitations of + existing protocols and + structures. However, these norms need to be challenged to radically shift how we approach genuinely + private communication. This requires doing some uncomfortable things, like making hard choices as it relates to + funding, alternative decentralization models, doubling down on privacy over convenience, and more. +

+ +

In this post we explain a bit more about why SimpleX operates and makes decisions the way it does: +

+ +
    +
  • No user accounts.
  • +
  • Privacy over convenience.
  • +
  • Network decentralization.
  • +
  • Funding and profitability.
  • +
  • Company jurisdiction.
  • +
\ No newline at end of file diff --git a/website/src/call/call.js b/website/src/call/call.js index 8104470686..b247431f4b 100644 --- a/website/src/call/call.js +++ b/website/src/call/call.js @@ -24,9 +24,8 @@ var TransformOperation; let activeCall; const processCommand = (function () { const defaultIceServers = [ - { urls: ["stuns:stun.simplex.im:443"] }, { urls: ["stun:stun.simplex.im:443"] }, - { urls: ["turns:turn.simplex.im:443"], username: "private2", credential: "Hxuq2QxUjnhj96Zq2r4HjqHRj" }, + { urls: ["turn:turn.simplex.im:443"], username: "private", credential: "yleob6AVkiNI87hpR94Z" }, ]; function getCallConfig(encodedInsertableStreams, iceServers, relay) { return { From ed3365bb6d8284060a154dfc6452a8b79ef9a43e Mon Sep 17 00:00:00 2001 From: Evgeny Poberezkin Date: Thu, 16 May 2024 18:16:00 +0100 Subject: [PATCH 7/7] website: fix links --- blog/20240416-dangers-of-metadata-in-messengers.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/blog/20240416-dangers-of-metadata-in-messengers.md b/blog/20240416-dangers-of-metadata-in-messengers.md index 2b99c755d3..b0832af4f7 100644 --- a/blog/20240416-dangers-of-metadata-in-messengers.md +++ b/blog/20240416-dangers-of-metadata-in-messengers.md @@ -45,7 +45,7 @@ But we also need to acknowledge that the world is becoming increasingly dangerou End-to-end encryption is a solid start, but it's just the beginning of our pursuit for true privacy and security. True privacy means that even when legal demands come knocking, there's no useful metadata to hand over. It's not enough to just protect the content of messages; we need consistent innovation in protecting metadata too. -Changing ingrained habits is tough, but your privacy is always worth the fight. Although giants like WhatsApp and Telegram may dominate global messaging for now, increasing concerns about data harvesting and AI-driven surveillance are fueling demand for alternatives. SimpleX Chat aims to be one of those strong alternatives, hence its radical focus on a decentralized framework with no user identifiers (in other words, nothing that uniquely identifies users on the protocol level to their contacts or to the relays) and extra optionality (self-hosting an [SMP server](../docs/server.md) or [XFTP server](../docs/xftp-server.md), access via Tor, [chat profiles](../docs/guide/chat-profiles.md) with incognito mode, etc.) +Changing ingrained habits is tough, but your privacy is always worth the fight. Although giants like WhatsApp and Telegram may dominate global messaging for now, increasing concerns about data harvesting and AI-driven surveillance are fueling demand for alternatives. SimpleX Chat aims to be one of those strong alternatives, hence its radical focus on a decentralized framework with no user identifiers (in other words, nothing that uniquely identifies users on the protocol level to their contacts or to the relays) and extra optionality (self-hosting an [SMP server](../docs/SERVER.md) or [XFTP server](../docs/XFTP-SERVER.md), access via Tor, [chat profiles](../docs/guide/chat-profiles.md) with incognito mode, etc.) As of today, most messaging alternatives, including SimpleX, will have some limitations. But with the limited resources we have, we are committed to daily progress towards creating a truly private messenger that anyone can use while maintaining the features that users have come to know and love in messaging interfaces. We want to be the prime example of a messenger that achieves genuine privacy without compromising it for convenience. We need to be able to reliably move away from small and niche use cases to endorsing and enforcing global standards for privacy and making it accessible for all users regardless of their technical expertise.