mirror of
https://github.com/simplex-chat/simplex-chat.git
synced 2025-06-29 04:39:53 +00:00
Merge branch 'stable' into stable-fdroid
This commit is contained in:
commit
854c9c9e99
71 changed files with 1108 additions and 351 deletions
|
@ -25,7 +25,9 @@ While SimpleX Chat Ltd is not a communication service provider, and provide publ
|
|||
|
||||
We see users and data sovereignty, and device and provider portability as critically important properties for any communication system.
|
||||
|
||||
SimpleX Chat security assessment was done in October 2022 by [Trail of Bits](https://www.trailofbits.com/about), and most fixes were released in v4.2 – see [the announcement](/blog/20221108-simplex-chat-v4.2-security-audit-new-website.md).
|
||||
The implementation security assessment of SimpleX cryptography and networking was done in October 2022 by [Trail of Bits](https://www.trailofbits.com/about), and most fixes were released in v4.2 – see [the announcement](/blog/20221108-simplex-chat-v4.2-security-audit-new-website.md).
|
||||
|
||||
The cryptographic review of SimpleX protocols design was done in July 2024 by Trail of Bits – see [the announcement](/blog/20241014-simplex-network-v6-1-security-review-better-calls-user-experience.md).
|
||||
|
||||
### Your information
|
||||
|
||||
|
@ -172,4 +174,4 @@ You accept the Conditions of Use of Software and Infrastructure ("Conditions") b
|
|||
|
||||
**Ending these conditions**. You may end these Conditions with SimpleX Chat Ltd at any time by deleting our Applications from your devices and discontinuing use of our Infrastructure. The provisions related to Licenses, Disclaimers, Limitation of Liability, Resolving dispute, Availability, Changes to the conditions, Enforcing the conditions, and Ending these conditions will survive termination of your relationship with SimpleX Chat Ltd.
|
||||
|
||||
Updated April 24, 2024
|
||||
Updated October 14, 2024
|
||||
|
|
14
README.md
14
README.md
|
@ -233,14 +233,12 @@ You can use SimpleX with your own servers and still communicate with people usin
|
|||
|
||||
Recent and important updates:
|
||||
|
||||
[Oct 14, 2024. SimpleX network: security review of protocols design by Trail of Bits, v6.1 released with better calls and user experience.](./blog/20241014-simplex-network-v6-1-security-review-better-calls-user-experience.md)
|
||||
|
||||
[Aug 14, 2024. SimpleX network: the investment from Jack Dorsey and Asymmetric, v6.0 released with the new user experience and private message routing](./blog/20240814-simplex-chat-vision-funding-v6-private-routing-new-user-experience.md)
|
||||
|
||||
[Jun 4, 2024. SimpleX network: private message routing, v5.8 released with IP address protection and chat themes](./blog/20240604-simplex-chat-v5.8-private-message-routing-chat-themes.md)
|
||||
|
||||
[Apr 26, 2024. SimpleX network: legally binding transparency, v5.7 released with better calls and messages.](./blog/20240426-simplex-legally-binding-transparency-v5-7-better-user-experience.md)
|
||||
|
||||
[Mar 23, 2024. SimpleX network: real privacy and stable profits, non-profits for protocols, v5.6 released with quantum resistant e2e encryption and simple profile migration.](./blog/20240323-simplex-network-privacy-non-profit-v5-6-quantum-resistant-e2e-encryption-simple-migration.md)
|
||||
|
||||
[Mar 14, 2024. SimpleX Chat v5.6 beta: adding quantum resistance to Signal double ratchet algorithm.](./blog/20240314-simplex-chat-v5-6-quantum-resistance-signal-double-ratchet-algorithm.md)
|
||||
|
||||
[Jan 24, 2024. SimpleX Chat: free infrastructure from Linode, v5.5 released with private notes, group history and a simpler UX to connect.](./blog/20240124-simplex-chat-infrastructure-costs-v5-5-simplex-ux-private-notes-group-history.md)
|
||||
|
@ -249,10 +247,6 @@ Recent and important updates:
|
|||
|
||||
[Sep 25, 2023. SimpleX Chat v5.3 released: desktop app, local file encryption, improved groups and directory service](./blog/20230925-simplex-chat-v5-3-desktop-app-local-file-encryption-directory-service.md).
|
||||
|
||||
[Jul 22, 2023. SimpleX Chat: v5.2 released with message delivery receipts](./blog/20230722-simplex-chat-v5-2-message-delivery-receipts.md).
|
||||
|
||||
[May 23, 2023. SimpleX Chat: v5.1 released with message reactions and self-destruct passcode](./blog/20230523-simplex-chat-v5-1-message-reactions-self-destruct-passcode.md).
|
||||
|
||||
[Apr 22, 2023. SimpleX Chat: vision and funding, v5.0 released with videos and files up to 1gb](./blog/20230422-simplex-chat-vision-funding-v5-videos-files-passcode.md).
|
||||
|
||||
[Mar 1, 2023. SimpleX File Transfer Protocol – send large files efficiently, privately and securely, soon to be integrated into SimpleX Chat apps.](./blog/20230301-simplex-file-transfer-protocol.md).
|
||||
|
@ -409,7 +403,9 @@ Please also join [#simplex-devs](https://simplex.chat/contact#/?v=1-2&smp=smp%3A
|
|||
|
||||
[SimpleX protocols and security model](https://github.com/simplex-chat/simplexmq/blob/master/protocol/overview-tjr.md) was reviewed, and had many breaking changes and improvements in v1.0.0.
|
||||
|
||||
The security audit was performed in October 2022 by [Trail of Bits](https://www.trailofbits.com/about), and most fixes were released in v4.2.0 – see [the announcement](./blog/20221108-simplex-chat-v4.2-security-audit-new-website.md).
|
||||
The implementation security assessment of SimpleX cryptography and networking was done in October 2022 by [Trail of Bits](https://www.trailofbits.com/about) – see [the announcement](./blog/20221108-simplex-chat-v4.2-security-audit-new-website.md).
|
||||
|
||||
The cryptographic review of SimpleX protocols was done in July 2024 by Trail of Bits – see [the announcement](./blog/20241014-simplex-network-v6-1-security-review-better-calls-user-experience.md).
|
||||
|
||||
SimpleX Chat is still a relatively early stage platform (the mobile apps were released in March 2022), so you may discover some bugs and missing features. We would really appreciate if you let us know anything that needs to be fixed or improved.
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@ struct ContentView: View {
|
|||
@EnvironmentObject var chatModel: ChatModel
|
||||
@ObservedObject var alertManager = AlertManager.shared
|
||||
@ObservedObject var callController = CallController.shared
|
||||
@ObservedObject var appSheetState = AppSheetState.shared
|
||||
@Environment(\.colorScheme) var colorScheme
|
||||
@EnvironmentObject var theme: AppTheme
|
||||
@EnvironmentObject var sceneDelegate: SceneDelegate
|
||||
|
@ -250,7 +251,8 @@ struct ContentView: View {
|
|||
|
||||
private func mainView() -> some View {
|
||||
ZStack(alignment: .top) {
|
||||
ChatListView(activeUserPickerSheet: $chatListUserPickerSheet).privacySensitive(protectScreen)
|
||||
ChatListView(activeUserPickerSheet: $chatListUserPickerSheet)
|
||||
.redacted(reason: appSheetState.redactionReasons(protectScreen))
|
||||
.onAppear {
|
||||
requestNtfAuthorization()
|
||||
// Local Authentication notice is to be shown on next start after onboarding is complete
|
||||
|
|
|
@ -147,6 +147,7 @@ final class ChatModel: ObservableObject {
|
|||
@Published var chatDbEncrypted: Bool?
|
||||
@Published var chatDbStatus: DBMigrationResult?
|
||||
@Published var ctrlInitInProgress: Bool = false
|
||||
@Published var notificationResponse: UNNotificationResponse?
|
||||
// local authentication
|
||||
@Published var contentViewAccessAuthenticated: Bool = false
|
||||
@Published var laRequest: LocalAuthRequest?
|
||||
|
|
|
@ -29,17 +29,33 @@ class NtfManager: NSObject, UNUserNotificationCenterDelegate, ObservableObject {
|
|||
private var granted = false
|
||||
private var prevNtfTime: Dictionary<ChatId, Date> = [:]
|
||||
|
||||
override init() {
|
||||
super.init()
|
||||
UNUserNotificationCenter.current().delegate = self
|
||||
}
|
||||
|
||||
// Handle notification when app is in background
|
||||
func userNotificationCenter(_ center: UNUserNotificationCenter,
|
||||
didReceive response: UNNotificationResponse,
|
||||
withCompletionHandler handler: () -> Void) {
|
||||
logger.debug("NtfManager.userNotificationCenter: didReceive")
|
||||
let content = response.notification.request.content
|
||||
if appStateGroupDefault.get() == .active {
|
||||
processNotificationResponse(response)
|
||||
} else {
|
||||
logger.debug("NtfManager.userNotificationCenter: remember response in model")
|
||||
ChatModel.shared.notificationResponse = response
|
||||
}
|
||||
handler()
|
||||
}
|
||||
|
||||
func processNotificationResponse(_ ntfResponse: UNNotificationResponse) {
|
||||
let chatModel = ChatModel.shared
|
||||
let action = response.actionIdentifier
|
||||
logger.debug("NtfManager.userNotificationCenter: didReceive: action \(action), categoryIdentifier \(content.categoryIdentifier)")
|
||||
let content = ntfResponse.notification.request.content
|
||||
let action = ntfResponse.actionIdentifier
|
||||
logger.debug("NtfManager.processNotificationResponse: didReceive: action \(action), categoryIdentifier \(content.categoryIdentifier)")
|
||||
if let userId = content.userInfo["userId"] as? Int64,
|
||||
userId != chatModel.currentUser?.userId {
|
||||
logger.debug("NtfManager.processNotificationResponse changeActiveUser")
|
||||
changeActiveUser(userId, viewPwd: nil)
|
||||
}
|
||||
if content.categoryIdentifier == ntfCategoryContactRequest && (action == ntfActionAcceptContact || action == ntfActionAcceptContactIncognito),
|
||||
|
@ -61,7 +77,6 @@ class NtfManager: NSObject, UNUserNotificationCenterDelegate, ObservableObject {
|
|||
ItemsModel.shared.loadOpenChat(chatId)
|
||||
}
|
||||
}
|
||||
handler()
|
||||
}
|
||||
|
||||
private func ntfCallAction(_ content: UNNotificationContent, _ action: String) -> (ChatId, NtfCallAction)? {
|
||||
|
@ -76,7 +91,6 @@ class NtfManager: NSObject, UNUserNotificationCenterDelegate, ObservableObject {
|
|||
return nil
|
||||
}
|
||||
|
||||
|
||||
// Handle notification when the app is in foreground
|
||||
func userNotificationCenter(_ center: UNUserNotificationCenter,
|
||||
willPresent notification: UNNotification,
|
||||
|
@ -210,7 +224,6 @@ class NtfManager: NSObject, UNUserNotificationCenterDelegate, ObservableObject {
|
|||
}
|
||||
}
|
||||
}
|
||||
center.delegate = self
|
||||
}
|
||||
|
||||
func notifyContactRequest(_ user: any UserLike, _ contactRequest: UserContactRequest) {
|
||||
|
|
|
@ -743,6 +743,12 @@ func apiConnect_(incognito: Bool, connReq: String) async -> ((ConnReqType, Pendi
|
|||
message: "Unless your contact deleted the connection or this link was already used, it might be a bug - please report it.\nTo connect, please ask your contact to create another connection link and check that you have a stable network connection."
|
||||
)
|
||||
return (nil, alert)
|
||||
case .chatCmdError(_, .errorAgent(.SMP(_, .QUOTA))):
|
||||
let alert = mkAlert(
|
||||
title: "Undelivered messages",
|
||||
message: "The connection reached the limit of undelivered messages, your contact may be offline."
|
||||
)
|
||||
return (nil, alert)
|
||||
case let .chatCmdError(_, .errorAgent(.INTERNAL(internalErr))):
|
||||
if internalErr == "SEUniqueID" {
|
||||
let alert = mkAlert(
|
||||
|
|
|
@ -82,7 +82,12 @@ struct SimpleXApp: App {
|
|||
|
||||
if appState != .stopped {
|
||||
startChatAndActivate {
|
||||
if appState.inactive && chatModel.chatRunning == true {
|
||||
if chatModel.chatRunning == true {
|
||||
if let ntfResponse = chatModel.notificationResponse {
|
||||
chatModel.notificationResponse = nil
|
||||
NtfManager.shared.processNotificationResponse(ntfResponse)
|
||||
}
|
||||
if appState.inactive {
|
||||
Task {
|
||||
await updateChats()
|
||||
if !chatModel.showCallView && !CallController.shared.hasActiveCalls() {
|
||||
|
@ -92,6 +97,7 @@ struct SimpleXApp: App {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
default:
|
||||
break
|
||||
}
|
||||
|
|
|
@ -11,11 +11,11 @@ import SimpleXChat
|
|||
|
||||
struct CIChatFeatureView: View {
|
||||
@EnvironmentObject var m: ChatModel
|
||||
@Environment(\.revealed) var revealed: Bool
|
||||
@ObservedObject var im = ItemsModel.shared
|
||||
@ObservedObject var chat: Chat
|
||||
@EnvironmentObject var theme: AppTheme
|
||||
var chatItem: ChatItem
|
||||
@Binding var revealed: Bool
|
||||
var feature: Feature
|
||||
var icon: String? = nil
|
||||
var iconColor: Color
|
||||
|
@ -106,6 +106,9 @@ struct CIChatFeatureView: View {
|
|||
struct CIChatFeatureView_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
let enabled = FeatureEnabled(forUser: false, forContact: false)
|
||||
CIChatFeatureView(chat: Chat.sampleData, chatItem: ChatItem.getChatFeatureSample(.fullDelete, enabled), revealed: Binding.constant(true), feature: ChatFeature.fullDelete, iconColor: enabled.iconColor(.secondary))
|
||||
CIChatFeatureView(
|
||||
chat: Chat.sampleData,
|
||||
chatItem: ChatItem.getChatFeatureSample(.fullDelete, enabled), feature: ChatFeature.fullDelete, iconColor: enabled.iconColor(.secondary)
|
||||
).environment(\.revealed, true)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -285,17 +285,18 @@ struct CIFileView_Previews: PreviewProvider {
|
|||
file: nil
|
||||
)
|
||||
Group {
|
||||
ChatItemView(chat: Chat.sampleData, chatItem: sentFile, revealed: Binding.constant(false))
|
||||
ChatItemView(chat: Chat.sampleData, chatItem: ChatItem.getFileMsgContentSample(), revealed: Binding.constant(false))
|
||||
ChatItemView(chat: Chat.sampleData, chatItem: ChatItem.getFileMsgContentSample(fileName: "some_long_file_name_here", fileStatus: .rcvInvitation), revealed: Binding.constant(false))
|
||||
ChatItemView(chat: Chat.sampleData, chatItem: ChatItem.getFileMsgContentSample(fileStatus: .rcvAccepted), revealed: Binding.constant(false))
|
||||
ChatItemView(chat: Chat.sampleData, chatItem: ChatItem.getFileMsgContentSample(fileStatus: .rcvTransfer(rcvProgress: 7, rcvTotal: 10)), revealed: Binding.constant(false))
|
||||
ChatItemView(chat: Chat.sampleData, chatItem: ChatItem.getFileMsgContentSample(fileStatus: .rcvCancelled), revealed: Binding.constant(false))
|
||||
ChatItemView(chat: Chat.sampleData, chatItem: ChatItem.getFileMsgContentSample(fileSize: 1_000_000_000, fileStatus: .rcvInvitation), revealed: Binding.constant(false))
|
||||
ChatItemView(chat: Chat.sampleData, chatItem: ChatItem.getFileMsgContentSample(text: "Hello there", fileStatus: .rcvInvitation), revealed: Binding.constant(false))
|
||||
ChatItemView(chat: Chat.sampleData, chatItem: ChatItem.getFileMsgContentSample(text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", fileStatus: .rcvInvitation), revealed: Binding.constant(false))
|
||||
ChatItemView(chat: Chat.sampleData, chatItem: fileChatItemWtFile, revealed: Binding.constant(false))
|
||||
ChatItemView(chat: Chat.sampleData, chatItem: sentFile)
|
||||
ChatItemView(chat: Chat.sampleData, chatItem: ChatItem.getFileMsgContentSample())
|
||||
ChatItemView(chat: Chat.sampleData, chatItem: ChatItem.getFileMsgContentSample(fileName: "some_long_file_name_here", fileStatus: .rcvInvitation))
|
||||
ChatItemView(chat: Chat.sampleData, chatItem: ChatItem.getFileMsgContentSample(fileStatus: .rcvAccepted))
|
||||
ChatItemView(chat: Chat.sampleData, chatItem: ChatItem.getFileMsgContentSample(fileStatus: .rcvTransfer(rcvProgress: 7, rcvTotal: 10)))
|
||||
ChatItemView(chat: Chat.sampleData, chatItem: ChatItem.getFileMsgContentSample(fileStatus: .rcvCancelled))
|
||||
ChatItemView(chat: Chat.sampleData, chatItem: ChatItem.getFileMsgContentSample(fileSize: 1_000_000_000, fileStatus: .rcvInvitation))
|
||||
ChatItemView(chat: Chat.sampleData, chatItem: ChatItem.getFileMsgContentSample(text: "Hello there", fileStatus: .rcvInvitation))
|
||||
ChatItemView(chat: Chat.sampleData, chatItem: ChatItem.getFileMsgContentSample(text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", fileStatus: .rcvInvitation))
|
||||
ChatItemView(chat: Chat.sampleData, chatItem: fileChatItemWtFile)
|
||||
}
|
||||
.environment(\.revealed, false)
|
||||
.previewLayout(.fixed(width: 360, height: 360))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -510,10 +510,10 @@ struct CIVoiceView_Previews: PreviewProvider {
|
|||
duration: 30,
|
||||
allowMenu: Binding.constant(true)
|
||||
)
|
||||
ChatItemView(chat: Chat.sampleData, chatItem: sentVoiceMessage, revealed: Binding.constant(false), allowMenu: .constant(true))
|
||||
ChatItemView(chat: Chat.sampleData, chatItem: ChatItem.getVoiceMsgContentSample(), revealed: Binding.constant(false), allowMenu: .constant(true))
|
||||
ChatItemView(chat: Chat.sampleData, chatItem: ChatItem.getVoiceMsgContentSample(fileStatus: .rcvTransfer(rcvProgress: 7, rcvTotal: 10)), revealed: Binding.constant(false), allowMenu: .constant(true))
|
||||
ChatItemView(chat: Chat.sampleData, chatItem: voiceMessageWtFile, revealed: Binding.constant(false), allowMenu: .constant(true))
|
||||
ChatItemView(chat: Chat.sampleData, chatItem: sentVoiceMessage, allowMenu: .constant(true))
|
||||
ChatItemView(chat: Chat.sampleData, chatItem: ChatItem.getVoiceMsgContentSample(), allowMenu: .constant(true))
|
||||
ChatItemView(chat: Chat.sampleData, chatItem: ChatItem.getVoiceMsgContentSample(fileStatus: .rcvTransfer(rcvProgress: 7, rcvTotal: 10)), allowMenu: .constant(true))
|
||||
ChatItemView(chat: Chat.sampleData, chatItem: voiceMessageWtFile, allowMenu: .constant(true))
|
||||
}
|
||||
.previewLayout(.fixed(width: 360, height: 360))
|
||||
}
|
||||
|
|
|
@ -92,12 +92,13 @@ struct FramedCIVoiceView_Previews: PreviewProvider {
|
|||
file: CIFile.getSample(fileStatus: .sndComplete)
|
||||
)
|
||||
Group {
|
||||
ChatItemView(chat: Chat.sampleData, chatItem: sentVoiceMessage, revealed: Binding.constant(false))
|
||||
ChatItemView(chat: Chat.sampleData, chatItem: ChatItem.getVoiceMsgContentSample(text: "Hello there"), revealed: Binding.constant(false))
|
||||
ChatItemView(chat: Chat.sampleData, chatItem: ChatItem.getVoiceMsgContentSample(text: "Hello there", fileStatus: .rcvTransfer(rcvProgress: 7, rcvTotal: 10)), revealed: Binding.constant(false))
|
||||
ChatItemView(chat: Chat.sampleData, chatItem: ChatItem.getVoiceMsgContentSample(text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."), revealed: Binding.constant(false))
|
||||
ChatItemView(chat: Chat.sampleData, chatItem: voiceMessageWithQuote, revealed: Binding.constant(false))
|
||||
ChatItemView(chat: Chat.sampleData, chatItem: sentVoiceMessage)
|
||||
ChatItemView(chat: Chat.sampleData, chatItem: ChatItem.getVoiceMsgContentSample(text: "Hello there"))
|
||||
ChatItemView(chat: Chat.sampleData, chatItem: ChatItem.getVoiceMsgContentSample(text: "Hello there", fileStatus: .rcvTransfer(rcvProgress: 7, rcvTotal: 10)))
|
||||
ChatItemView(chat: Chat.sampleData, chatItem: ChatItem.getVoiceMsgContentSample(text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."))
|
||||
ChatItemView(chat: Chat.sampleData, chatItem: voiceMessageWithQuote)
|
||||
}
|
||||
.environment(\.revealed, false)
|
||||
.previewLayout(.fixed(width: 360, height: 360))
|
||||
}
|
||||
}
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -12,9 +12,9 @@ import SimpleXChat
|
|||
struct MarkedDeletedItemView: View {
|
||||
@EnvironmentObject var m: ChatModel
|
||||
@EnvironmentObject var theme: AppTheme
|
||||
@Environment(\.revealed) var revealed: Bool
|
||||
@ObservedObject var chat: Chat
|
||||
var chatItem: ChatItem
|
||||
@Binding var revealed: Bool
|
||||
|
||||
var body: some View {
|
||||
(Text(mergedMarkedDeletedText).italic() + Text(" ") + chatItem.timestampText)
|
||||
|
@ -79,7 +79,10 @@ struct MarkedDeletedItemView: View {
|
|||
struct MarkedDeletedItemView_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
Group {
|
||||
MarkedDeletedItemView(chat: Chat.sampleData, chatItem: ChatItem.getSample(1, .directSnd, .now, "hello", .sndSent(sndProgress: .complete), itemDeleted: .deleted(deletedTs: .now)), revealed: Binding.constant(true))
|
||||
MarkedDeletedItemView(
|
||||
chat: Chat.sampleData,
|
||||
chatItem: ChatItem.getSample(1, .directSnd, .now, "hello", .sndSent(sndProgress: .complete), itemDeleted: .deleted(deletedTs: .now))
|
||||
).environment(\.revealed, true)
|
||||
}
|
||||
.previewLayout(.fixed(width: 360, height: 200))
|
||||
}
|
||||
|
|
|
@ -14,19 +14,28 @@ extension EnvironmentValues {
|
|||
static let defaultValue: Bool = true
|
||||
}
|
||||
|
||||
struct Revealed: EnvironmentKey {
|
||||
static let defaultValue: Bool = true
|
||||
}
|
||||
|
||||
var showTimestamp: Bool {
|
||||
get { self[ShowTimestamp.self] }
|
||||
set { self[ShowTimestamp.self] = newValue }
|
||||
}
|
||||
|
||||
var revealed: Bool {
|
||||
get { self[Revealed.self] }
|
||||
set { self[Revealed.self] = newValue }
|
||||
}
|
||||
}
|
||||
|
||||
struct ChatItemView: View {
|
||||
@ObservedObject var chat: Chat
|
||||
@EnvironmentObject var theme: AppTheme
|
||||
@Environment(\.showTimestamp) var showTimestamp: Bool
|
||||
@Environment(\.revealed) var revealed: Bool
|
||||
var chatItem: ChatItem
|
||||
var maxWidth: CGFloat = .infinity
|
||||
@Binding var revealed: Bool
|
||||
@Binding var allowMenu: Bool
|
||||
|
||||
init(
|
||||
|
@ -34,27 +43,25 @@ struct ChatItemView: View {
|
|||
chatItem: ChatItem,
|
||||
showMember: Bool = false,
|
||||
maxWidth: CGFloat = .infinity,
|
||||
revealed: Binding<Bool>,
|
||||
allowMenu: Binding<Bool> = .constant(false)
|
||||
) {
|
||||
self.chat = chat
|
||||
self.chatItem = chatItem
|
||||
self.maxWidth = maxWidth
|
||||
_revealed = revealed
|
||||
_allowMenu = allowMenu
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
let ci = chatItem
|
||||
if chatItem.meta.itemDeleted != nil && (!revealed || chatItem.isDeletedContent) {
|
||||
MarkedDeletedItemView(chat: chat, chatItem: chatItem, revealed: $revealed)
|
||||
MarkedDeletedItemView(chat: chat, chatItem: chatItem)
|
||||
} else if ci.quotedItem == nil && ci.meta.itemForwarded == nil && ci.meta.itemDeleted == nil && !ci.meta.isLive {
|
||||
if let mc = ci.content.msgContent, mc.isText && isShortEmoji(ci.content.text) {
|
||||
EmojiItemView(chat: chat, chatItem: ci)
|
||||
} else if ci.content.text.isEmpty, case let .voice(_, duration) = ci.content.msgContent {
|
||||
CIVoiceView(chat: chat, chatItem: ci, recordingFile: ci.file, duration: duration, allowMenu: $allowMenu)
|
||||
} else if ci.content.msgContent == nil {
|
||||
ChatItemContentView(chat: chat, chatItem: chatItem, revealed: $revealed, msgContentView: { Text(ci.text) }) // msgContent is unreachable branch in this case
|
||||
ChatItemContentView(chat: chat, chatItem: chatItem, msgContentView: { Text(ci.text) }) // msgContent is unreachable branch in this case
|
||||
} else {
|
||||
framedItemView()
|
||||
}
|
||||
|
@ -84,7 +91,6 @@ struct ChatItemView: View {
|
|||
chat: chat,
|
||||
chatItem: chatItem,
|
||||
preview: preview,
|
||||
revealed: $revealed,
|
||||
maxWidth: maxWidth,
|
||||
imgWidth: adjustedMaxWidth,
|
||||
videoWidth: adjustedMaxWidth,
|
||||
|
@ -96,9 +102,9 @@ struct ChatItemView: View {
|
|||
struct ChatItemContentView<Content: View>: View {
|
||||
@EnvironmentObject var chatModel: ChatModel
|
||||
@EnvironmentObject var theme: AppTheme
|
||||
@Environment(\.revealed) var revealed: Bool
|
||||
@ObservedObject var chat: Chat
|
||||
var chatItem: ChatItem
|
||||
@Binding var revealed: Bool
|
||||
var msgContentView: () -> Content
|
||||
@AppStorage(DEFAULT_DEVELOPER_TOOLS) private var developerTools = false
|
||||
|
||||
|
@ -130,7 +136,7 @@ struct ChatItemContentView<Content: View>: View {
|
|||
case let .rcvChatPreference(feature, allowed, param):
|
||||
CIFeaturePreferenceView(chat: chat, chatItem: chatItem, feature: feature, allowed: allowed, param: param)
|
||||
case let .sndChatPreference(feature, _, _):
|
||||
CIChatFeatureView(chat: chat, chatItem: chatItem, revealed: $revealed, feature: feature, icon: feature.icon, iconColor: theme.colors.secondary)
|
||||
CIChatFeatureView(chat: chat, chatItem: chatItem, feature: feature, icon: feature.icon, iconColor: theme.colors.secondary)
|
||||
case let .rcvGroupFeature(feature, preference, _, role): chatFeatureView(feature, preference.enabled(role, for: chat.chatInfo.groupInfo?.membership).iconColor(theme.colors.secondary))
|
||||
case let .sndGroupFeature(feature, preference, _, role): chatFeatureView(feature, preference.enabled(role, for: chat.chatInfo.groupInfo?.membership).iconColor(theme.colors.secondary))
|
||||
case let .rcvChatFeatureRejected(feature): chatFeatureView(feature, .red)
|
||||
|
@ -177,7 +183,7 @@ struct ChatItemContentView<Content: View>: View {
|
|||
}
|
||||
|
||||
private func chatFeatureView(_ feature: Feature, _ iconColor: Color) -> some View {
|
||||
CIChatFeatureView(chat: chat, chatItem: chatItem, revealed: $revealed, feature: feature, iconColor: iconColor)
|
||||
CIChatFeatureView(chat: chat, chatItem: chatItem, feature: feature, iconColor: iconColor)
|
||||
}
|
||||
|
||||
private var mergedGroupEventText: Text? {
|
||||
|
@ -238,16 +244,17 @@ func chatEventText(_ ci: ChatItem, _ secondaryColor: Color) -> Text {
|
|||
struct ChatItemView_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
Group{
|
||||
ChatItemView(chat: Chat.sampleData, chatItem: ChatItem.getSample(1, .directSnd, .now, "hello"), revealed: Binding.constant(false))
|
||||
ChatItemView(chat: Chat.sampleData, chatItem: ChatItem.getSample(2, .directRcv, .now, "hello there too"), revealed: Binding.constant(false))
|
||||
ChatItemView(chat: Chat.sampleData, chatItem: ChatItem.getSample(1, .directSnd, .now, "🙂"), revealed: Binding.constant(false))
|
||||
ChatItemView(chat: Chat.sampleData, chatItem: ChatItem.getSample(2, .directRcv, .now, "🙂🙂🙂🙂🙂"), revealed: Binding.constant(false))
|
||||
ChatItemView(chat: Chat.sampleData, chatItem: ChatItem.getSample(2, .directRcv, .now, "🙂🙂🙂🙂🙂🙂"), revealed: Binding.constant(false))
|
||||
ChatItemView(chat: Chat.sampleData, chatItem: ChatItem.getDeletedContentSample(), revealed: Binding.constant(false))
|
||||
ChatItemView(chat: Chat.sampleData, chatItem: ChatItem.getSample(1, .directSnd, .now, "hello", .sndSent(sndProgress: .complete), itemDeleted: .deleted(deletedTs: .now)), revealed: Binding.constant(false))
|
||||
ChatItemView(chat: Chat.sampleData, chatItem: ChatItem.getSample(1, .directSnd, .now, "🙂", .sndSent(sndProgress: .complete), itemLive: true), revealed: Binding.constant(true))
|
||||
ChatItemView(chat: Chat.sampleData, chatItem: ChatItem.getSample(1, .directSnd, .now, "hello", .sndSent(sndProgress: .complete), itemLive: true), revealed: Binding.constant(true))
|
||||
ChatItemView(chat: Chat.sampleData, chatItem: ChatItem.getSample(1, .directSnd, .now, "hello"))
|
||||
ChatItemView(chat: Chat.sampleData, chatItem: ChatItem.getSample(2, .directRcv, .now, "hello there too"))
|
||||
ChatItemView(chat: Chat.sampleData, chatItem: ChatItem.getSample(1, .directSnd, .now, "🙂"))
|
||||
ChatItemView(chat: Chat.sampleData, chatItem: ChatItem.getSample(2, .directRcv, .now, "🙂🙂🙂🙂🙂"))
|
||||
ChatItemView(chat: Chat.sampleData, chatItem: ChatItem.getSample(2, .directRcv, .now, "🙂🙂🙂🙂🙂🙂"))
|
||||
ChatItemView(chat: Chat.sampleData, chatItem: ChatItem.getDeletedContentSample())
|
||||
ChatItemView(chat: Chat.sampleData, chatItem: ChatItem.getSample(1, .directSnd, .now, "hello", .sndSent(sndProgress: .complete), itemDeleted: .deleted(deletedTs: .now)))
|
||||
ChatItemView(chat: Chat.sampleData, chatItem: ChatItem.getSample(1, .directSnd, .now, "🙂", .sndSent(sndProgress: .complete), itemLive: true)).environment(\.revealed, true)
|
||||
ChatItemView(chat: Chat.sampleData, chatItem: ChatItem.getSample(1, .directSnd, .now, "hello", .sndSent(sndProgress: .complete), itemLive: true)).environment(\.revealed, true)
|
||||
}
|
||||
.environment(\.revealed, false)
|
||||
.previewLayout(.fixed(width: 360, height: 70))
|
||||
.environmentObject(Chat.sampleData)
|
||||
}
|
||||
|
@ -265,8 +272,7 @@ struct ChatItemView_NonMsgContentDeleted_Previews: PreviewProvider {
|
|||
content: .rcvIntegrityError(msgError: .msgSkipped(fromMsgId: 1, toMsgId: 2)),
|
||||
quotedItem: nil,
|
||||
file: nil
|
||||
),
|
||||
revealed: Binding.constant(true)
|
||||
)
|
||||
)
|
||||
ChatItemView(
|
||||
chat: Chat.sampleData,
|
||||
|
@ -276,8 +282,7 @@ struct ChatItemView_NonMsgContentDeleted_Previews: PreviewProvider {
|
|||
content: .rcvDecryptionError(msgDecryptError: .ratchetHeader, msgCount: 2),
|
||||
quotedItem: nil,
|
||||
file: nil
|
||||
),
|
||||
revealed: Binding.constant(true)
|
||||
)
|
||||
)
|
||||
ChatItemView(
|
||||
chat: Chat.sampleData,
|
||||
|
@ -287,8 +292,7 @@ struct ChatItemView_NonMsgContentDeleted_Previews: PreviewProvider {
|
|||
content: .rcvGroupInvitation(groupInvitation: CIGroupInvitation.getSample(status: .pending), memberRole: .admin),
|
||||
quotedItem: nil,
|
||||
file: nil
|
||||
),
|
||||
revealed: Binding.constant(true)
|
||||
)
|
||||
)
|
||||
ChatItemView(
|
||||
chat: Chat.sampleData,
|
||||
|
@ -298,8 +302,7 @@ struct ChatItemView_NonMsgContentDeleted_Previews: PreviewProvider {
|
|||
content: .rcvGroupEvent(rcvGroupEvent: .memberAdded(groupMemberId: 1, profile: Profile.sampleData)),
|
||||
quotedItem: nil,
|
||||
file: nil
|
||||
),
|
||||
revealed: Binding.constant(true)
|
||||
)
|
||||
)
|
||||
ChatItemView(
|
||||
chat: Chat.sampleData,
|
||||
|
@ -309,10 +312,10 @@ struct ChatItemView_NonMsgContentDeleted_Previews: PreviewProvider {
|
|||
content: ciFeatureContent,
|
||||
quotedItem: nil,
|
||||
file: nil
|
||||
),
|
||||
revealed: Binding.constant(true)
|
||||
)
|
||||
)
|
||||
}
|
||||
.environment(\.revealed, true)
|
||||
.previewLayout(.fixed(width: 360, height: 70))
|
||||
.environmentObject(Chat.sampleData)
|
||||
}
|
||||
|
|
|
@ -1183,9 +1183,9 @@ struct ChatView: View {
|
|||
chat: chat,
|
||||
chatItem: ci,
|
||||
maxWidth: maxWidth,
|
||||
revealed: .constant(revealed),
|
||||
allowMenu: $allowMenu
|
||||
)
|
||||
.environment(\.revealed, revealed)
|
||||
.environment(\.showTimestamp, itemSeparation.timestamp)
|
||||
.modifier(ChatItemClipped(ci, tailVisible: itemSeparation.largeGap && (ci.meta.itemDeleted == nil || revealed)))
|
||||
.contextMenu { menu(ci, range, live: composeState.liveMessage != nil) }
|
||||
|
|
|
@ -287,8 +287,8 @@ struct ComposeView: View {
|
|||
// this is a workaround to fire an explicit event in certain cases
|
||||
@State private var stopPlayback: Bool = false
|
||||
|
||||
@AppStorage(DEFAULT_PRIVACY_SAVE_LAST_DRAFT) private var saveLastDraft = true
|
||||
@AppStorage(DEFAULT_TOOLBAR_MATERIAL) private var toolbarMaterial = ToolbarMaterial.defaultMaterial
|
||||
@UserDefault(DEFAULT_PRIVACY_SAVE_LAST_DRAFT) private var saveLastDraft = true
|
||||
@UserDefault(DEFAULT_TOOLBAR_MATERIAL) private var toolbarMaterial = ToolbarMaterial.defaultMaterial
|
||||
|
||||
var body: some View {
|
||||
VStack(spacing: 0) {
|
||||
|
|
|
@ -40,7 +40,7 @@ struct SendMessageView: View {
|
|||
@State private var showCustomTimePicker = false
|
||||
@State private var selectedDisappearingMessageTime: Int? = customDisappearingMessageTimeDefault.get()
|
||||
@State private var progressByTimeout = false
|
||||
@AppStorage(DEFAULT_LIVE_MESSAGE_ALERT_SHOWN) private var liveMessageAlertShown = false
|
||||
@UserDefault(DEFAULT_LIVE_MESSAGE_ALERT_SHOWN) private var liveMessageAlertShown = false
|
||||
|
||||
var body: some View {
|
||||
ZStack {
|
||||
|
|
|
@ -78,7 +78,7 @@ struct ReverseList<Content: View>: UIViewControllerRepresentable {
|
|||
self.dataSource = UITableViewDiffableDataSource<Section, ChatItem>(
|
||||
tableView: tableView
|
||||
) { (tableView, indexPath, item) -> UITableViewCell? in
|
||||
if indexPath.item > self.itemCount - 8, self.itemCount > 8 {
|
||||
if indexPath.item > self.itemCount - 8 {
|
||||
self.representer.loadPage()
|
||||
}
|
||||
let cell = tableView.dequeueReusableCell(withIdentifier: cellReuseId, for: indexPath)
|
||||
|
|
|
@ -121,9 +121,11 @@ struct ChatListView: View {
|
|||
UserPicker(userPickerShown: $userPickerShown, activeSheet: $activeUserPickerSheet)
|
||||
}
|
||||
)
|
||||
.sheet(item: $activeUserPickerSheet) {
|
||||
UserPickerSheetView(sheet: $0)
|
||||
}
|
||||
.appSheet(
|
||||
item: $activeUserPickerSheet,
|
||||
onDismiss: { chatModel.laRequest = nil },
|
||||
content: { UserPickerSheetView(sheet: $0) }
|
||||
)
|
||||
.onChange(of: activeUserPickerSheet) {
|
||||
if $0 != nil {
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {
|
||||
|
|
|
@ -11,6 +11,12 @@ import SwiftUI
|
|||
class AppSheetState: ObservableObject {
|
||||
static let shared = AppSheetState()
|
||||
@Published var scenePhaseActive: Bool = false
|
||||
|
||||
func redactionReasons(_ protectScreen: Bool) -> RedactionReasons {
|
||||
!protectScreen || scenePhaseActive
|
||||
? RedactionReasons()
|
||||
: RedactionReasons.placeholder
|
||||
}
|
||||
}
|
||||
|
||||
private struct PrivacySensitive: ViewModifier {
|
||||
|
@ -19,11 +25,7 @@ private struct PrivacySensitive: ViewModifier {
|
|||
@ObservedObject var appSheetState: AppSheetState = AppSheetState.shared
|
||||
|
||||
func body(content: Content) -> some View {
|
||||
if !protectScreen {
|
||||
content
|
||||
} else {
|
||||
content.privacySensitive(!appSheetState.scenePhaseActive).redacted(reason: .privacy)
|
||||
}
|
||||
content.redacted(reason: appSheetState.redactionReasons(protectScreen))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@ struct UserWallpaperEditor: View {
|
|||
@State var themeModeOverride: ThemeModeOverride
|
||||
@State var applyToMode: DefaultThemeMode?
|
||||
@State var showMore: Bool = false
|
||||
@State var showFileImporter: Bool = false
|
||||
@Binding var globalThemeUsed: Bool
|
||||
var save: (DefaultThemeMode?, ThemeModeOverride?) async -> Void
|
||||
|
||||
|
@ -125,7 +126,13 @@ struct UserWallpaperEditor: View {
|
|||
|
||||
CustomizeThemeColorsSection(editColor: { name in editColor(name, theme) })
|
||||
|
||||
ImportExportThemeSection(perChat: nil, perUser: ChatModel.shared.currentUser?.uiThemes) { imported in
|
||||
ImportExportThemeSection(showFileImporter: $showFileImporter, perChat: nil, perUser: ChatModel.shared.currentUser?.uiThemes)
|
||||
} else {
|
||||
AdvancedSettingsButton(theme.colors.primary) { showMore = true }
|
||||
}
|
||||
}
|
||||
.modifier(
|
||||
ThemeImporter(isPresented: $showFileImporter) { imported in
|
||||
let importedFromString = imported.wallpaper?.importFromString()
|
||||
let importedType = importedFromString?.toAppWallpaper().type
|
||||
let currentTheme = ThemeManager.currentColors(nil, nil, nil, themeOverridesDefault.get())
|
||||
|
@ -139,10 +146,7 @@ struct UserWallpaperEditor: View {
|
|||
await save(applyToMode, res)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
AdvancedSettingsButton(theme.colors.primary) { showMore = true }
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
private func onTypeCopyFromSameTheme(_ type: WallpaperType?) -> Bool {
|
||||
|
@ -216,6 +220,7 @@ struct ChatWallpaperEditor: View {
|
|||
@State var themeModeOverride: ThemeModeOverride
|
||||
@State var applyToMode: DefaultThemeMode?
|
||||
@State var showMore: Bool = false
|
||||
@State var showFileImporter: Bool = false
|
||||
@Binding var globalThemeUsed: Bool
|
||||
var save: (DefaultThemeMode?, ThemeModeOverride?) async -> Void
|
||||
|
||||
|
@ -328,7 +333,13 @@ struct ChatWallpaperEditor: View {
|
|||
|
||||
CustomizeThemeColorsSection(editColor: editColor)
|
||||
|
||||
ImportExportThemeSection(perChat: themeModeOverride, perUser: ChatModel.shared.currentUser?.uiThemes) { imported in
|
||||
ImportExportThemeSection(showFileImporter: $showFileImporter, perChat: themeModeOverride, perUser: ChatModel.shared.currentUser?.uiThemes)
|
||||
} else {
|
||||
AdvancedSettingsButton(theme.colors.primary) { showMore = true }
|
||||
}
|
||||
}
|
||||
.modifier(
|
||||
ThemeImporter(isPresented: $showFileImporter) { imported in
|
||||
let importedFromString = imported.wallpaper?.importFromString()
|
||||
let importedType = importedFromString?.toAppWallpaper().type
|
||||
let currentTheme = ThemeManager.currentColors(nil, nil, ChatModel.shared.currentUser?.uiThemes, themeOverridesDefault.get())
|
||||
|
@ -342,10 +353,7 @@ struct ChatWallpaperEditor: View {
|
|||
await save(applyToMode, res)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
AdvancedSettingsButton(theme.colors.primary) { showMore = true }
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
private func onTypeCopyFromSameTheme(_ type: WallpaperType?) -> Bool {
|
||||
|
|
62
apps/ios/Shared/Views/Helpers/UserDefault.swift
Normal file
62
apps/ios/Shared/Views/Helpers/UserDefault.swift
Normal file
|
@ -0,0 +1,62 @@
|
|||
//
|
||||
// UserDefault.swift
|
||||
// SimpleX (iOS)
|
||||
//
|
||||
// Created by user on 14/10/2024.
|
||||
// Copyright © 2024 SimpleX Chat. All rights reserved.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
import Combine
|
||||
|
||||
@propertyWrapper
|
||||
public struct UserDefault<Value: Equatable>: DynamicProperty {
|
||||
@StateObject private var observer = UserDefaultObserver()
|
||||
let initialValue: Value
|
||||
let key: String
|
||||
let store: UserDefaults
|
||||
|
||||
public init(
|
||||
wrappedValue: Value,
|
||||
_ key: String,
|
||||
store: UserDefaults = .standard
|
||||
) {
|
||||
self.initialValue = wrappedValue
|
||||
self.key = key
|
||||
self.store = store
|
||||
}
|
||||
|
||||
public var wrappedValue: Value {
|
||||
get {
|
||||
// Observer can only be accessed after the property wrapper is installed in view (runtime exception)
|
||||
observer.subscribe(to: key)
|
||||
return store.object(forKey: key) as? Value ?? initialValue
|
||||
}
|
||||
nonmutating set {
|
||||
store.set(newValue, forKey: key)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class UserDefaultObserver: ObservableObject {
|
||||
private var subscribed = false
|
||||
|
||||
func subscribe(to key: String) {
|
||||
if !subscribed {
|
||||
NotificationCenter.default.addObserver(
|
||||
self,
|
||||
selector: #selector(userDefaultsDidChange),
|
||||
name: UserDefaults.didChangeNotification,
|
||||
object: nil
|
||||
)
|
||||
subscribed = true
|
||||
}
|
||||
}
|
||||
|
||||
@objc
|
||||
private func userDefaultsDidChange(_ notification: Notification) {
|
||||
Task { @MainActor in objectWillChange.send() }
|
||||
}
|
||||
|
||||
deinit { NotificationCenter.default.removeObserver(self) }
|
||||
}
|
|
@ -105,7 +105,12 @@ struct TerminalView: View {
|
|||
}
|
||||
}
|
||||
.navigationViewStyle(.stack)
|
||||
.navigationTitle("Chat console")
|
||||
.toolbar {
|
||||
// Redaction broken for `.navigationTitle` - using a toolbar item instead.
|
||||
ToolbarItem(placement: .principal) {
|
||||
Text("Chat console").font(.headline)
|
||||
}
|
||||
}
|
||||
.modifier(ThemedBackground())
|
||||
}
|
||||
|
||||
|
|
|
@ -367,13 +367,13 @@ struct ChatThemePreview: View {
|
|||
let alice = ChatItem.getSample(1, CIDirection.directRcv, Date.now, NSLocalizedString("Good afternoon!", comment: "message preview"))
|
||||
let bob = ChatItem.getSample(2, CIDirection.directSnd, Date.now, NSLocalizedString("Good morning!", comment: "message preview"), quotedItem: CIQuote.getSample(alice.id, alice.meta.itemTs, alice.content.text, chatDir: alice.chatDir))
|
||||
HStack {
|
||||
ChatItemView(chat: Chat.sampleData, chatItem: alice, revealed: Binding.constant(false))
|
||||
ChatItemView(chat: Chat.sampleData, chatItem: alice)
|
||||
.modifier(ChatItemClipped(alice, tailVisible: true))
|
||||
Spacer()
|
||||
}
|
||||
HStack {
|
||||
Spacer()
|
||||
ChatItemView(chat: Chat.sampleData, chatItem: bob, revealed: Binding.constant(false))
|
||||
ChatItemView(chat: Chat.sampleData, chatItem: bob)
|
||||
.modifier(ChatItemClipped(bob, tailVisible: true))
|
||||
.frame(alignment: .trailing)
|
||||
}
|
||||
|
@ -583,11 +583,14 @@ struct CustomizeThemeView: View {
|
|||
}
|
||||
}
|
||||
|
||||
ImportExportThemeSection(perChat: nil, perUser: nil, save: { theme in
|
||||
ImportExportThemeSection(showFileImporter: $showFileImporter, perChat: nil, perUser: nil)
|
||||
}
|
||||
.modifier(
|
||||
ThemeImporter(isPresented: $showFileImporter) { theme in
|
||||
ThemeManager.saveAndApplyThemeOverrides(theme)
|
||||
saveThemeToDatabase(nil)
|
||||
})
|
||||
}
|
||||
)
|
||||
/// When changing app theme, user overrides are hidden. User overrides will be returned back after closing Appearance screen, see ThemeDestinationPicker()
|
||||
.interactiveDismissDisabled(true)
|
||||
}
|
||||
|
@ -595,10 +598,9 @@ struct CustomizeThemeView: View {
|
|||
|
||||
struct ImportExportThemeSection: View {
|
||||
@EnvironmentObject var theme: AppTheme
|
||||
@Binding var showFileImporter: Bool
|
||||
var perChat: ThemeModeOverride?
|
||||
var perUser: ThemeModeOverrides?
|
||||
var save: (ThemeOverrides) -> Void
|
||||
@State private var showFileImporter = false
|
||||
|
||||
var body: some View {
|
||||
Section {
|
||||
|
@ -626,8 +628,17 @@ struct ImportExportThemeSection: View {
|
|||
} label: {
|
||||
Text("Import theme").foregroundColor(theme.colors.primary)
|
||||
}
|
||||
.fileImporter(
|
||||
isPresented: $showFileImporter,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct ThemeImporter: ViewModifier {
|
||||
@Binding var isPresented: Bool
|
||||
var save: (ThemeOverrides) -> Void
|
||||
|
||||
func body(content: Content) -> some View {
|
||||
content.fileImporter(
|
||||
isPresented: $isPresented,
|
||||
allowedContentTypes: [.data/*.plainText*/],
|
||||
allowsMultipleSelection: false
|
||||
) { result in
|
||||
|
@ -662,7 +673,6 @@ struct ImportExportThemeSection: View {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct UserWallpaperEditorSheet: View {
|
||||
|
|
|
@ -331,7 +331,12 @@ struct SettingsView: View {
|
|||
chatDatabaseRow()
|
||||
NavigationLink {
|
||||
MigrateFromDevice(showProgressOnSettings: $showProgress)
|
||||
.navigationTitle("Migrate device")
|
||||
.toolbar {
|
||||
// Redaction broken for `.navigationTitle` - using a toolbar item instead.
|
||||
ToolbarItem(placement: .principal) {
|
||||
Text("Migrate device").font(.headline)
|
||||
}
|
||||
}
|
||||
.modifier(ThemedBackground(grouped: true))
|
||||
.navigationBarTitleDisplayMode(.large)
|
||||
} label: {
|
||||
|
|
|
@ -204,6 +204,7 @@
|
|||
CE38A29C2C3FCD72005ED185 /* SwiftyGif in Frameworks */ = {isa = PBXBuildFile; productRef = CE38A29B2C3FCD72005ED185 /* SwiftyGif */; };
|
||||
CE75480A2C622630009579B7 /* SwipeLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE7548092C622630009579B7 /* SwipeLabel.swift */; };
|
||||
CE984D4B2C36C5D500E3AEFF /* ChatItemClipShape.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE984D4A2C36C5D500E3AEFF /* ChatItemClipShape.swift */; };
|
||||
CEA6E91C2CBD21B0002B5DB4 /* UserDefault.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEA6E91B2CBD21B0002B5DB4 /* UserDefault.swift */; };
|
||||
CEDB245B2C9CD71800FBC5F6 /* StickyScrollView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEDB245A2C9CD71800FBC5F6 /* StickyScrollView.swift */; };
|
||||
CEDE70222C48FD9500233B1F /* SEChatState.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEDE70212C48FD9500233B1F /* SEChatState.swift */; };
|
||||
CEE723AA2C3BD3D70009AE93 /* ShareViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEE723A92C3BD3D70009AE93 /* ShareViewController.swift */; };
|
||||
|
@ -219,15 +220,15 @@
|
|||
D77B92DC2952372200A5A1CC /* SwiftyGif in Frameworks */ = {isa = PBXBuildFile; productRef = D77B92DB2952372200A5A1CC /* SwiftyGif */; };
|
||||
D7F0E33929964E7E0068AF69 /* LZString in Frameworks */ = {isa = PBXBuildFile; productRef = D7F0E33829964E7E0068AF69 /* LZString */; };
|
||||
E51CC1E62C62085600DB91FE /* OneHandUICard.swift in Sources */ = {isa = PBXBuildFile; fileRef = E51CC1E52C62085600DB91FE /* OneHandUICard.swift */; };
|
||||
E56F46202CC2B2E300F1559D /* libHSsimplex-chat-6.1.1.0-KwHIA7FZqPI5ZTCAoi00n9.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E56F461E2CC2B2E300F1559D /* libHSsimplex-chat-6.1.1.0-KwHIA7FZqPI5ZTCAoi00n9.a */; };
|
||||
E56F46212CC2B2E300F1559D /* libHSsimplex-chat-6.1.1.0-KwHIA7FZqPI5ZTCAoi00n9-ghc9.6.3.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E56F461F2CC2B2E300F1559D /* libHSsimplex-chat-6.1.1.0-KwHIA7FZqPI5ZTCAoi00n9-ghc9.6.3.a */; };
|
||||
E5DCF8DB2C56FAC1007928CC /* SimpleXChat.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5CE2BA682845308900EC33A6 /* SimpleXChat.framework */; };
|
||||
E5DCF9712C590272007928CC /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = E5DCF96F2C590272007928CC /* Localizable.strings */; };
|
||||
E5DCF9842C5902CE007928CC /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = E5DCF9822C5902CE007928CC /* Localizable.strings */; };
|
||||
E5DCF9982C5906FF007928CC /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = E5DCF9962C5906FF007928CC /* InfoPlist.strings */; };
|
||||
E5E997C92CBA891A00D7A2FA /* libgmpxx.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E5E997C42CBA891A00D7A2FA /* libgmpxx.a */; };
|
||||
E5E997CA2CBA891A00D7A2FA /* libgmp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E5E997C52CBA891A00D7A2FA /* libgmp.a */; };
|
||||
E5E997CB2CBA891A00D7A2FA /* libHSsimplex-chat-6.1.0.9-3X73OucN19a19eYgUK66sv-ghc9.6.3.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E5E997C62CBA891A00D7A2FA /* libHSsimplex-chat-6.1.0.9-3X73OucN19a19eYgUK66sv-ghc9.6.3.a */; };
|
||||
E5E997CC2CBA891A00D7A2FA /* libffi.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E5E997C72CBA891A00D7A2FA /* libffi.a */; };
|
||||
E5E997CD2CBA891A00D7A2FA /* libHSsimplex-chat-6.1.0.9-3X73OucN19a19eYgUK66sv.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E5E997C82CBA891A00D7A2FA /* libHSsimplex-chat-6.1.0.9-3X73OucN19a19eYgUK66sv.a */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
|
@ -545,6 +546,7 @@
|
|||
CE3097FA2C4C0C9F00180898 /* ErrorAlert.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ErrorAlert.swift; sourceTree = "<group>"; };
|
||||
CE7548092C622630009579B7 /* SwipeLabel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SwipeLabel.swift; sourceTree = "<group>"; };
|
||||
CE984D4A2C36C5D500E3AEFF /* ChatItemClipShape.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatItemClipShape.swift; sourceTree = "<group>"; };
|
||||
CEA6E91B2CBD21B0002B5DB4 /* UserDefault.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserDefault.swift; sourceTree = "<group>"; };
|
||||
CEDB245A2C9CD71800FBC5F6 /* StickyScrollView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StickyScrollView.swift; sourceTree = "<group>"; };
|
||||
CEDE70212C48FD9500233B1F /* SEChatState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SEChatState.swift; sourceTree = "<group>"; };
|
||||
CEE723A72C3BD3D70009AE93 /* SimpleX SE.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = "SimpleX SE.appex"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
|
@ -560,6 +562,8 @@
|
|||
D741547929AF90B00022400A /* PushKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = PushKit.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS16.1.sdk/System/Library/Frameworks/PushKit.framework; sourceTree = DEVELOPER_DIR; };
|
||||
D7AA2C3429A936B400737B40 /* MediaEncryption.playground */ = {isa = PBXFileReference; lastKnownFileType = file.playground; name = MediaEncryption.playground; path = Shared/MediaEncryption.playground; sourceTree = SOURCE_ROOT; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
|
||||
E51CC1E52C62085600DB91FE /* OneHandUICard.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OneHandUICard.swift; sourceTree = "<group>"; };
|
||||
E56F461E2CC2B2E300F1559D /* libHSsimplex-chat-6.1.1.0-KwHIA7FZqPI5ZTCAoi00n9.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-6.1.1.0-KwHIA7FZqPI5ZTCAoi00n9.a"; sourceTree = "<group>"; };
|
||||
E56F461F2CC2B2E300F1559D /* libHSsimplex-chat-6.1.1.0-KwHIA7FZqPI5ZTCAoi00n9-ghc9.6.3.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-6.1.1.0-KwHIA7FZqPI5ZTCAoi00n9-ghc9.6.3.a"; sourceTree = "<group>"; };
|
||||
E5DCF9702C590272007928CC /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||
E5DCF9722C590274007928CC /* bg */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = bg; path = bg.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||
E5DCF9732C590275007928CC /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/Localizable.strings"; sourceTree = "<group>"; };
|
||||
|
@ -614,9 +618,7 @@
|
|||
E5DCF9A82C590732007928CC /* uk */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = uk; path = uk.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
||||
E5E997C42CBA891A00D7A2FA /* libgmpxx.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgmpxx.a; sourceTree = "<group>"; };
|
||||
E5E997C52CBA891A00D7A2FA /* libgmp.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgmp.a; sourceTree = "<group>"; };
|
||||
E5E997C62CBA891A00D7A2FA /* libHSsimplex-chat-6.1.0.9-3X73OucN19a19eYgUK66sv-ghc9.6.3.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-6.1.0.9-3X73OucN19a19eYgUK66sv-ghc9.6.3.a"; sourceTree = "<group>"; };
|
||||
E5E997C72CBA891A00D7A2FA /* libffi.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libffi.a; sourceTree = "<group>"; };
|
||||
E5E997C82CBA891A00D7A2FA /* libHSsimplex-chat-6.1.0.9-3X73OucN19a19eYgUK66sv.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-6.1.0.9-3X73OucN19a19eYgUK66sv.a"; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
|
@ -656,13 +658,13 @@
|
|||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
E5E997C92CBA891A00D7A2FA /* libgmpxx.a in Frameworks */,
|
||||
E5E997CB2CBA891A00D7A2FA /* libHSsimplex-chat-6.1.0.9-3X73OucN19a19eYgUK66sv-ghc9.6.3.a in Frameworks */,
|
||||
E5E997CA2CBA891A00D7A2FA /* libgmp.a in Frameworks */,
|
||||
5CE2BA93284534B000EC33A6 /* libiconv.tbd in Frameworks */,
|
||||
E5E997CC2CBA891A00D7A2FA /* libffi.a in Frameworks */,
|
||||
5CE2BA94284534BB00EC33A6 /* libz.tbd in Frameworks */,
|
||||
E56F46202CC2B2E300F1559D /* libHSsimplex-chat-6.1.1.0-KwHIA7FZqPI5ZTCAoi00n9.a in Frameworks */,
|
||||
CE38A29C2C3FCD72005ED185 /* SwiftyGif in Frameworks */,
|
||||
E5E997CD2CBA891A00D7A2FA /* libHSsimplex-chat-6.1.0.9-3X73OucN19a19eYgUK66sv.a in Frameworks */,
|
||||
E56F46212CC2B2E300F1559D /* libHSsimplex-chat-6.1.1.0-KwHIA7FZqPI5ZTCAoi00n9-ghc9.6.3.a in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
@ -742,8 +744,8 @@
|
|||
E5E997C72CBA891A00D7A2FA /* libffi.a */,
|
||||
E5E997C52CBA891A00D7A2FA /* libgmp.a */,
|
||||
E5E997C42CBA891A00D7A2FA /* libgmpxx.a */,
|
||||
E5E997C62CBA891A00D7A2FA /* libHSsimplex-chat-6.1.0.9-3X73OucN19a19eYgUK66sv-ghc9.6.3.a */,
|
||||
E5E997C82CBA891A00D7A2FA /* libHSsimplex-chat-6.1.0.9-3X73OucN19a19eYgUK66sv.a */,
|
||||
E56F461F2CC2B2E300F1559D /* libHSsimplex-chat-6.1.1.0-KwHIA7FZqPI5ZTCAoi00n9-ghc9.6.3.a */,
|
||||
E56F461E2CC2B2E300F1559D /* libHSsimplex-chat-6.1.1.0-KwHIA7FZqPI5ZTCAoi00n9.a */,
|
||||
);
|
||||
path = Libraries;
|
||||
sourceTree = "<group>";
|
||||
|
@ -802,6 +804,7 @@
|
|||
CE176F1F2C87014C00145DBC /* InvertedForegroundStyle.swift */,
|
||||
CEDB245A2C9CD71800FBC5F6 /* StickyScrollView.swift */,
|
||||
CEFB2EDE2CA1BCC7004B1ECE /* SheetRepresentable.swift */,
|
||||
CEA6E91B2CBD21B0002B5DB4 /* UserDefault.swift */,
|
||||
);
|
||||
path = Helpers;
|
||||
sourceTree = "<group>";
|
||||
|
@ -1482,6 +1485,7 @@
|
|||
5CFA59D12864782E00863A68 /* ChatArchiveView.swift in Sources */,
|
||||
649BCDA22805D6EF00C3A862 /* CIImageView.swift in Sources */,
|
||||
5CADE79C292131E900072E13 /* ContactPreferencesView.swift in Sources */,
|
||||
CEA6E91C2CBD21B0002B5DB4 /* UserDefault.swift in Sources */,
|
||||
5CB346E52868AA7F001FD2EF /* SuspendChat.swift in Sources */,
|
||||
5C9C2DA52894777E00CC63B1 /* GroupProfileView.swift in Sources */,
|
||||
5CEACCED27DEA495000BD591 /* MsgContentView.swift in Sources */,
|
||||
|
@ -1899,7 +1903,7 @@
|
|||
CLANG_TIDY_MISC_REDUNDANT_EXPRESSION = YES;
|
||||
CODE_SIGN_ENTITLEMENTS = "SimpleX (iOS).entitlements";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 244;
|
||||
CURRENT_PROJECT_VERSION = 245;
|
||||
DEAD_CODE_STRIPPING = YES;
|
||||
DEVELOPMENT_TEAM = 5NN7GUYB6T;
|
||||
ENABLE_BITCODE = NO;
|
||||
|
@ -1924,7 +1928,7 @@
|
|||
"@executable_path/Frameworks",
|
||||
);
|
||||
LLVM_LTO = YES_THIN;
|
||||
MARKETING_VERSION = 6.1;
|
||||
MARKETING_VERSION = 6.1.1;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = chat.simplex.app;
|
||||
PRODUCT_NAME = SimpleX;
|
||||
SDKROOT = iphoneos;
|
||||
|
@ -1948,7 +1952,7 @@
|
|||
CLANG_TIDY_MISC_REDUNDANT_EXPRESSION = YES;
|
||||
CODE_SIGN_ENTITLEMENTS = "SimpleX (iOS).entitlements";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 244;
|
||||
CURRENT_PROJECT_VERSION = 245;
|
||||
DEAD_CODE_STRIPPING = YES;
|
||||
DEVELOPMENT_TEAM = 5NN7GUYB6T;
|
||||
ENABLE_BITCODE = NO;
|
||||
|
@ -1973,7 +1977,7 @@
|
|||
"@executable_path/Frameworks",
|
||||
);
|
||||
LLVM_LTO = YES;
|
||||
MARKETING_VERSION = 6.1;
|
||||
MARKETING_VERSION = 6.1.1;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = chat.simplex.app;
|
||||
PRODUCT_NAME = SimpleX;
|
||||
SDKROOT = iphoneos;
|
||||
|
@ -1989,11 +1993,11 @@
|
|||
buildSettings = {
|
||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 244;
|
||||
CURRENT_PROJECT_VERSION = 245;
|
||||
DEVELOPMENT_TEAM = 5NN7GUYB6T;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
|
||||
MARKETING_VERSION = 6.1;
|
||||
MARKETING_VERSION = 6.1.1;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "chat.simplex.Tests-iOS";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SDKROOT = iphoneos;
|
||||
|
@ -2009,11 +2013,11 @@
|
|||
buildSettings = {
|
||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 244;
|
||||
CURRENT_PROJECT_VERSION = 245;
|
||||
DEVELOPMENT_TEAM = 5NN7GUYB6T;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
|
||||
MARKETING_VERSION = 6.1;
|
||||
MARKETING_VERSION = 6.1.1;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "chat.simplex.Tests-iOS";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SDKROOT = iphoneos;
|
||||
|
@ -2034,7 +2038,7 @@
|
|||
CODE_SIGN_ENTITLEMENTS = "SimpleX NSE/SimpleX NSE.entitlements";
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 244;
|
||||
CURRENT_PROJECT_VERSION = 245;
|
||||
DEVELOPMENT_TEAM = 5NN7GUYB6T;
|
||||
ENABLE_BITCODE = NO;
|
||||
GCC_OPTIMIZATION_LEVEL = s;
|
||||
|
@ -2049,7 +2053,7 @@
|
|||
"@executable_path/../../Frameworks",
|
||||
);
|
||||
LLVM_LTO = YES;
|
||||
MARKETING_VERSION = 6.1;
|
||||
MARKETING_VERSION = 6.1.1;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "chat.simplex.app.SimpleX-NSE";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
|
@ -2071,7 +2075,7 @@
|
|||
CODE_SIGN_ENTITLEMENTS = "SimpleX NSE/SimpleX NSE.entitlements";
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 244;
|
||||
CURRENT_PROJECT_VERSION = 245;
|
||||
DEVELOPMENT_TEAM = 5NN7GUYB6T;
|
||||
ENABLE_BITCODE = NO;
|
||||
ENABLE_CODE_COVERAGE = NO;
|
||||
|
@ -2086,7 +2090,7 @@
|
|||
"@executable_path/../../Frameworks",
|
||||
);
|
||||
LLVM_LTO = YES;
|
||||
MARKETING_VERSION = 6.1;
|
||||
MARKETING_VERSION = 6.1.1;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "chat.simplex.app.SimpleX-NSE";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
|
@ -2108,7 +2112,7 @@
|
|||
CLANG_TIDY_BUGPRONE_REDUNDANT_BRANCH_CONDITION = YES;
|
||||
CLANG_TIDY_MISC_REDUNDANT_EXPRESSION = YES;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 244;
|
||||
CURRENT_PROJECT_VERSION = 245;
|
||||
DEFINES_MODULE = YES;
|
||||
DEVELOPMENT_TEAM = 5NN7GUYB6T;
|
||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||
|
@ -2134,7 +2138,7 @@
|
|||
"$(PROJECT_DIR)/Libraries/sim",
|
||||
);
|
||||
LLVM_LTO = YES;
|
||||
MARKETING_VERSION = 6.1;
|
||||
MARKETING_VERSION = 6.1.1;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = chat.simplex.SimpleXChat;
|
||||
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
|
||||
SDKROOT = iphoneos;
|
||||
|
@ -2159,7 +2163,7 @@
|
|||
CLANG_TIDY_BUGPRONE_REDUNDANT_BRANCH_CONDITION = YES;
|
||||
CLANG_TIDY_MISC_REDUNDANT_EXPRESSION = YES;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 244;
|
||||
CURRENT_PROJECT_VERSION = 245;
|
||||
DEFINES_MODULE = YES;
|
||||
DEVELOPMENT_TEAM = 5NN7GUYB6T;
|
||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||
|
@ -2185,7 +2189,7 @@
|
|||
"$(PROJECT_DIR)/Libraries/sim",
|
||||
);
|
||||
LLVM_LTO = YES;
|
||||
MARKETING_VERSION = 6.1;
|
||||
MARKETING_VERSION = 6.1.1;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = chat.simplex.SimpleXChat;
|
||||
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
|
||||
SDKROOT = iphoneos;
|
||||
|
@ -2210,7 +2214,7 @@
|
|||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
|
||||
CODE_SIGN_ENTITLEMENTS = "SimpleX SE/SimpleX SE.entitlements";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 244;
|
||||
CURRENT_PROJECT_VERSION = 245;
|
||||
DEVELOPMENT_TEAM = 5NN7GUYB6T;
|
||||
ENABLE_USER_SCRIPT_SANDBOXING = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu17;
|
||||
|
@ -2225,7 +2229,7 @@
|
|||
"@executable_path/../../Frameworks",
|
||||
);
|
||||
LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
|
||||
MARKETING_VERSION = 6.1;
|
||||
MARKETING_VERSION = 6.1.1;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "chat.simplex.app.SimpleX-SE";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SDKROOT = iphoneos;
|
||||
|
@ -2244,7 +2248,7 @@
|
|||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
|
||||
CODE_SIGN_ENTITLEMENTS = "SimpleX SE/SimpleX SE.entitlements";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 244;
|
||||
CURRENT_PROJECT_VERSION = 245;
|
||||
DEVELOPMENT_TEAM = 5NN7GUYB6T;
|
||||
ENABLE_USER_SCRIPT_SANDBOXING = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu17;
|
||||
|
@ -2259,7 +2263,7 @@
|
|||
"@executable_path/../../Frameworks",
|
||||
);
|
||||
LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
|
||||
MARKETING_VERSION = 6.1;
|
||||
MARKETING_VERSION = 6.1.1;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "chat.simplex.app.SimpleX-SE";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SDKROOT = iphoneos;
|
||||
|
|
|
@ -2088,6 +2088,7 @@ public enum ProtocolErrorType: Decodable, Hashable {
|
|||
case AUTH
|
||||
case CRYPTO
|
||||
case QUOTA
|
||||
case STORE(storeErr: String)
|
||||
case NO_MSG
|
||||
case LARGE_MSG
|
||||
case EXPIRED
|
||||
|
|
|
@ -1226,6 +1226,15 @@ object ChatController {
|
|||
)
|
||||
return null
|
||||
}
|
||||
r is CR.ChatCmdError && r.chatError is ChatError.ChatErrorAgent
|
||||
&& r.chatError.agentError is AgentErrorType.SMP
|
||||
&& r.chatError.agentError.smpErr is SMPErrorType.QUOTA -> {
|
||||
AlertManager.shared.showAlertMsg(
|
||||
generalGetString(MR.strings.connection_error_quota),
|
||||
generalGetString(MR.strings.connection_error_quota_desc)
|
||||
)
|
||||
return null
|
||||
}
|
||||
else -> {
|
||||
if (!(networkErrorAlert(r))) {
|
||||
apiErrorAlert("apiConnect", generalGetString(MR.strings.connection_error), r)
|
||||
|
@ -6045,6 +6054,7 @@ sealed class SMPErrorType {
|
|||
is AUTH -> "AUTH"
|
||||
is CRYPTO -> "CRYPTO"
|
||||
is QUOTA -> "QUOTA"
|
||||
is STORE -> "STORE ${storeErr}"
|
||||
is NO_MSG -> "NO_MSG"
|
||||
is LARGE_MSG -> "LARGE_MSG"
|
||||
is EXPIRED -> "EXPIRED"
|
||||
|
@ -6057,6 +6067,7 @@ sealed class SMPErrorType {
|
|||
@Serializable @SerialName("AUTH") class AUTH: SMPErrorType()
|
||||
@Serializable @SerialName("CRYPTO") class CRYPTO: SMPErrorType()
|
||||
@Serializable @SerialName("QUOTA") class QUOTA: SMPErrorType()
|
||||
@Serializable @SerialName("STORE") class STORE(val storeErr: String): SMPErrorType()
|
||||
@Serializable @SerialName("NO_MSG") class NO_MSG: SMPErrorType()
|
||||
@Serializable @SerialName("LARGE_MSG") class LARGE_MSG: SMPErrorType()
|
||||
@Serializable @SerialName("EXPIRED") class EXPIRED: SMPErrorType()
|
||||
|
|
|
@ -144,6 +144,8 @@
|
|||
<string name="please_check_correct_link_and_maybe_ask_for_a_new_one">Please check that you used the correct link or ask your contact to send you another one.</string>
|
||||
<string name="connection_error_auth">Connection error (AUTH)</string>
|
||||
<string name="connection_error_auth_desc">Unless your contact deleted the connection or this link was already used, it might be a bug - please report it.\nTo connect, please ask your contact to create another connection link and check that you have a stable network connection.</string>
|
||||
<string name="connection_error_quota">Undelivered messages</string>
|
||||
<string name="connection_error_quota_desc">The connection reached the limit of undelivered messages, your contact may be offline.</string>
|
||||
<string name="error_accepting_contact_request">Error accepting contact request</string>
|
||||
<string name="sender_may_have_deleted_the_connection_request">Sender may have deleted the connection request.</string>
|
||||
<string name="error_deleting_contact">Error deleting contact</string>
|
||||
|
|
|
@ -26,11 +26,11 @@ android.enableJetifier=true
|
|||
kotlin.mpp.androidSourceSetLayoutVersion=2
|
||||
kotlin.jvm.target=11
|
||||
|
||||
android.version_name=6.1
|
||||
android.version_code=247
|
||||
android.version_name=6.1.1
|
||||
android.version_code=249
|
||||
|
||||
desktop.version_name=6.1
|
||||
desktop.version_code=73
|
||||
desktop.version_name=6.1.1
|
||||
desktop.version_code=74
|
||||
|
||||
kotlin.version=1.9.23
|
||||
gradle.plugin.version=8.2.0
|
||||
|
|
|
@ -27,7 +27,7 @@ In the course of the audit, Trail of Bits assessed the maturity of the [simplexm
|
|||
|
||||
Explained below is our understanding of the issues, as well as fixes implemented by the SimpleX Chat team after project completion. The full security review is available via [Trail of Bits publications](https://github.com/trailofbits/publications/blob/master/reviews/SimpleXChat.pdf).
|
||||
|
||||
We are hugely thankful to Trail of Bits and their engineers for the work they did, helping us identify these issues and supporting the ongoing efforts to make Simple Chat more secure.
|
||||
We are hugely thankful to Trail of Bits and their engineers for the work they did, helping us identify these issues and supporting the ongoing efforts to make SimpleX Chat more secure.
|
||||
|
||||
### Medium severity issues
|
||||
|
||||
|
|
|
@ -2,10 +2,9 @@
|
|||
layout: layouts/article.html
|
||||
title: "SimpleX network: cryptographic design review by Trail of Bits, v6.1 released with better calls and user experience."
|
||||
date: 2024-10-14
|
||||
# image: images/20240814-reachable.png
|
||||
# previewBody: blog_previews/20240814.html
|
||||
image: images/20221108-trail-of-bits.jpg
|
||||
previewBody: blog_previews/20241014.html
|
||||
permalink: "/blog/20241014-simplex-network-v6-1-security-review-better-calls-user-experience.html"
|
||||
draft: true
|
||||
|
||||
---
|
||||
|
||||
|
@ -13,6 +12,181 @@ draft: true
|
|||
|
||||
**Published:** Oct 14, 2024
|
||||
|
||||
This is the placeholder for the security review and release announcement.
|
||||
[New security audit](#simplex-cryptographic-design-review-by-trail-of-bits):
|
||||
- [review findings](#review-findings-our-comments-and-improvements), our comments and improvements.
|
||||
- [next](#next-security-audit-in-2025): security audit in early 2025.
|
||||
|
||||
Come back on Monday afternoon!
|
||||
[What's new in v6.1](#whats-new-in-v61):
|
||||
- [better calls](#better-calls).
|
||||
- [better iOS notifications](#better-ios-notifications).
|
||||
- [better user experience](#better-user-experience).
|
||||
|
||||
## SimpleX cryptographic design review by Trail of Bits
|
||||
|
||||
<img src="./images/20221108-trail-of-bits.jpg" width=240 class="float-to-right">
|
||||
|
||||
It's been almost two years since Trail of Bits did the first security assessment of SimpleX Chat.
|
||||
|
||||
Since then SimpleX Chat grew a lot, both in the number of users and in its functionality. We added XFTP — a protocol for sending files, — and XRCP — the protocol for using a mobile app profile from a desktop app. Messaging protocols also evolved a lot, adding private message routing and quantum resistant encryption.
|
||||
|
||||
Trail of Bits reviewed the design of protocols used in SimpleX network and applications in July 2024. Even though there are no critical issues, we made some security improvements based on this report.
|
||||
|
||||
[Trail of Bits](https://www.trailofbits.com/about) is a US based security and technology consultancy whose clients include big tech companies, governmental agencies and major blockchain projects. Its engineers reviewed the cryptographic design of the protocols used in SimpleX network and applications over a week:
|
||||
- SimpleX Messaging Protocol (SMP), including a formal verification of currently used message queue negotiation protocol,
|
||||
- the SMP agent protocol,
|
||||
- the push notification system,
|
||||
- the file transfer protocol (XFTP),
|
||||
- the remote control protocol (XRCP),
|
||||
- and the chat protocol.
|
||||
|
||||
There are 3 medium and 1 low severity findings, all of which require a high difficulty attack to exploit — the attacker would need to have a privileged access to the system, may need to know complex technical details, or must discover other weaknesses to exploit them. Additionally, there are 3 informational findings.
|
||||
|
||||
3 of these issues are improved in v6.1, and the remaining issues are accepted. Below we are commenting on these findings in detail, and also on the released improvements.
|
||||
|
||||
The full cryptographic design review is available [here](https://github.com/simplex-chat/simplex-chat/blob/stable/docs/SimpleX_Design_Review_2024_Summary_Report_12_08_2024.pdf).
|
||||
|
||||
We are very thankful to Trail of Bits and their engineers for their work identifying these issues and helping us make SimpleX Chat more secure.
|
||||
|
||||
### Review findings, our comments and improvements
|
||||
|
||||
#### Protocols specifications (informational)
|
||||
|
||||
The review finding #1 is that the protocols specification is informal. We addressed [reported](https://github.com/simplex-chat/simplexmq/commit/7b6c86c6c1093cdae5ad2ee566655828076bc25c) [inconsistencies](https://github.com/simplex-chat/simplex-chat/commit/1cb3c25478db0f2a42c943f7469f5f9f75752a27), and we accept that we need to improve specification beyond verbose descriptions and ABNF syntax specification, and add algebraic notations and sequence diagrams. Having said that, the current specification correctly describes the implemented protocol, without any contradictions.
|
||||
|
||||
#### User-correlating attacks via introduced latency or via GET command of messaging protocol (medium and low severity)
|
||||
|
||||
These two findings #7 and #2 of the report relate to the attacks confirming that two known users communicate via observing their internet traffic.
|
||||
|
||||
The first attack is possible for a party that can introduce the latency in the network traffic. This attacker has to control some network node that passes the traffic of the sender — for example, it could be the sender's ISP, VPN provider, Tor entry node operator, the operator of the forwarding SMP server or a server hosting provider, etc. Such attacker can correlate delays in sender's traffic and the suspected recipient's traffic to confirm that they communicate.
|
||||
|
||||
The second attack relates to GET command used by iOS clients receiving notifications — depending on whether the server has the message, there will be a different number of packets sent, allowing the observer to determine if there was the message. While this comment is correct, in practice iOS clients only send GET commands when they receive notification, which also happens only when there is a message on the server, so in absolute majority of cases the number of packets will be the same.
|
||||
|
||||
These are not new findings — this type of attacks is covered in [threat model](https://github.com/simplex-chat/simplexmq/blob/stable/protocol/overview-tjr.md#a-passive-adversary-able-to-monitor-a-set-of-senders-and-recipients): _a passive adversary able to monitor a set of senders and recipients **can** perform traffic correlation attacks against senders and recipients and correlate senders and recipients within the monitored set, frustrated by the number of users on the servers_.
|
||||
|
||||
As threat model states, this attack is more likely to be successful with the less busy servers, and also for the users with few connections.
|
||||
|
||||
The recommendation of the review is to add optional randomized latency to message delivery that would reduce the opportunities for traffic correlation attacks — we consider adding it in the future.
|
||||
|
||||
#### A compromised transport protocol allows more efficient correlation attacks (medium severity)
|
||||
|
||||
The finding #3 is about the incorrect statement in threat model for SMP and XFTP protocols: _a passive adversary, able to monitor a set of senders and recipients, **cannot**, even in case of a compromised transport protocol perform traffic correlation attacks with any increase in efficiency over a non-compromised transport protocol_.
|
||||
|
||||
For protocols prior to v6.1 it is only partially correct, as responses to the commands that create a messaging queue or a file chunk include the identifiers both for senders and for the recipients, so if any observers were to compromise transport protocol (TLS) and record these identifiers, then they were able to correlate message senders with the recipients (and file recipients with the file senders).
|
||||
|
||||
The solution to make this correlation impossible even in case of compromised TLS is to encrypt these identifiers, as proposed in the review, or, better, encrypt the whole transmission inside TLS.
|
||||
|
||||
However unlikely is TLS being compromised, we added additional [transport encryption layer in SMP protocol](https://github.com/simplex-chat/simplexmq/pull/1317/files), where it can be more important, and we are going to add the same layer of encryption in XFTP protocol later, where we [amended the threat model](https://github.com/simplex-chat/simplexmq/commit/7b6c86c6c1093cdae5ad2ee566655828076bc25c).
|
||||
|
||||
#### XRCP protocol recommendations (informational)
|
||||
|
||||
XRCP protocol is used for connecting desktop and mobile. There are two findings in the review:
|
||||
|
||||
- SHA256 was used as a KDF in XRCP (#4).
|
||||
- there was no forward secrecy or break-in recovery between sessions (#5).
|
||||
|
||||
SHA256 is now [replaced with SHA3-256](https://github.com/simplex-chat/simplexmq/pull/1302/files), as was [recommended](https://www.ietf.org/archive/id/draft-josefsson-ntruprime-hybrid-01.html) by the internet draft about hybrid key agreement that XRCP uses.
|
||||
|
||||
Even though XRCP sessions are short lived, and usually the connection happens over local network, we added forward secrecy to XRCP sessions [here](https://github.com/simplex-chat/simplexmq/pull/1328/files) and [here](https://github.com/simplex-chat/simplex-chat/pull/4926/files) — each request from desktop app to mobile app is now encrypted with a new key derived from chain ratchets. This improves security of this connection.
|
||||
|
||||
We believe that it is unnecessary to have in-session break-in recovery in XRCP protocol, as there is break-in recovery between the sessions.
|
||||
|
||||
#### Device compromise can be hidden in some scenarios (medium)
|
||||
|
||||
The finding #6 in the report is about an attacker who was not only able to break into the device and get a copy of the database, which would be mitigated by break-in recovery in [double ratchet protocol](../docs/GLOSSARY.md#double-ratchet-algorithm), but also was able to modify the state of the app database and to substitute the addresses and cryptographic keys of the messaging queues used with some contact with other message queues that the attacker controls.
|
||||
|
||||
Even though this is a very hard attack, if successful, it would allow the attacker intercepting all messages with this contact.
|
||||
|
||||
Effectively, it is a [man-in-the-middle attack](../docs/GLOSSARY.md#man-in-the-middle-attack), where an intermediary is inserted via the app database modification. Such attack can be mitigated by periodic verification of security codes. Although, the attacker who was able to modify the state of the device, could have also modified the app itself, making it show the same security code as the compromised contact has, thus avoiding detection.
|
||||
|
||||
We accept that such an attack is possible, and we don't believe there is any viable defense against the attacker who can modify the device state. We may consider adding the measures to validate the database integrity, but they may be ineffective in case the app and/or operating system are compromised.
|
||||
|
||||
### Next: security audit in 2025
|
||||
|
||||
We are planning the implementation security assessment with Trail of Bits in the beginning of 2025. It will be a twice bigger assessment than we did in 2022 — it will cover both the core of the app and the handling of cryptographic secrets in the mobile applications.
|
||||
|
||||
## What's new in v6.1
|
||||
|
||||
This release has many user experience and stability improvements.
|
||||
|
||||
### Better calls
|
||||
|
||||
<img src="./images/20241014-calls.png" width="288" class="float-to-right">
|
||||
|
||||
This release improves reliability and usability of the calls. Now you can enable the camera and share the screen from the desktop app even if the call started as a voice call. We've also fixed several issues that prevented calls from connecting.
|
||||
|
||||
This is a substantial change, and some issues may have been introduced - please report them.
|
||||
|
||||
We will be further improving the calls interface in the app in the next versions.
|
||||
|
||||
### Better iOS notifications
|
||||
|
||||
iOS notifications were added [more than 2 years ago](./20220711-simplex-chat-v3-released-ios-notifications-audio-video-calls-database-export-import-protocol-improvements.md), based on this [system design](./20220404-simplex-chat-instant-notifications.md). Until recently we made almost no improvements to them. As the number of iOS users is growing, their reliability is insufficient. In addition to that, once we started the work on improving them, we have found several important issues, one of which was introduced recently, when we improved the speed of creating new connections.
|
||||
|
||||
This release fixes many important issues with iOS notifications delivery in iOS app, improves app performance and reduces traffic required to manage notifications.
|
||||
|
||||
We also fixed several notification server issues, made change that almost completely prevents losing notifications when notification servers are restarted, and added real-time monitoring to diagnose any issues with iOS notifications delivery.
|
||||
|
||||
This work is not over – iOS notifications in a decentralized network are complex and require more work. We will be further improving both client apps and servers to make their delivery stable.
|
||||
|
||||
|
||||
### Better user experience
|
||||
|
||||
#### New conversation layout and customizable messages
|
||||
|
||||
<img src="./images/20241014-messages.png" width="288" class="float-to-right">
|
||||
|
||||
Messages are now grouped when they are sent sequentially, with less than 60 seconds between them. We also made message shapes configurable, and separated the messages in different days. When you scroll conversation quickly, there will be a floating date indication, allowing to find messages faster.
|
||||
|
||||
#### Improved switching between user profiles
|
||||
|
||||
<img src="./images/20241014-profiles2.png" width="288" class="float-to-right"> <img src="./images/20241014-profiles1.png" width="288" class="float-to-right">
|
||||
|
||||
Another improvement relates to switching between chat profiles. Previously, when you added multiple chat profiles to the app, there were two problems:
|
||||
- you had to tap twice to get to some important functions in the app,
|
||||
- anybody who could see your screen, could also see all your chat profiles.
|
||||
|
||||
We changed this design by making important functions available after tapping profile image once, and by only showing the previously used profile image to switch to it quickly, while switching to other profiles now requires scrolling to them or opening *Your chat profiles* screen.
|
||||
|
||||
You also can switch chat profile when creating a one-time invitation link.
|
||||
|
||||
#### Faster deletion, moderation and forwarding of messages
|
||||
|
||||
<img src="./images/20241014-forward.png" width="288" class="float-to-right">
|
||||
|
||||
You now can forward multiple messages at once - up to 20. If you are forwarding messages with files or media, and they were not received, the app will offer you to download them, and it will also allow forwarding messages without files. These messages will be "packed" into the smallest number of sent messages as possible. If there are no images and messages are not too large, it will be just one sent message containing all forwarded messages.
|
||||
|
||||
The previous version allowed deleting and moderating multiple messages. As most users now upgraded the app, we increased the maximum number of messages that can be deleted or moderated to 200 messages - in most cases all these deletions will be packed into one sent message.
|
||||
|
||||
## SimpleX network
|
||||
|
||||
Some links to answer the most common questions:
|
||||
|
||||
[How can SimpleX deliver messages without user identifiers](./20220511-simplex-chat-v2-images-files.md#the-first-messaging-platform-without-user-identifiers).
|
||||
|
||||
[What are the risks to have identifiers assigned to the users](./20220711-simplex-chat-v3-released-ios-notifications-audio-video-calls-database-export-import-protocol-improvements.md#why-having-users-identifiers-is-bad-for-the-users).
|
||||
|
||||
[Technical details and limitations](https://github.com/simplex-chat/simplex-chat#privacy-technical-details-and-limitations).
|
||||
|
||||
[Frequently asked questions](../docs/FAQ.md).
|
||||
|
||||
Please also see our [website](https://simplex.chat).
|
||||
|
||||
## Please support us with your donations
|
||||
|
||||
Huge *thank you* to everybody who donated to SimpleX Chat!
|
||||
|
||||
Prioritizing users privacy and security, and also raising the investment, would have been impossible without your support and donations.
|
||||
|
||||
Also, funding the work to transition the protocols to non-profit governance model would not have been possible without the donations we received from the users.
|
||||
|
||||
Our pledge to our users is that SimpleX protocols are and will remain open, and in public domain, so anybody can build the future implementations of the clients and the servers. We are building SimpleX platform based on the same principles as email and web, but much more private and secure.
|
||||
|
||||
Your donations help us raise more funds — any amount, even the price of the cup of coffee, makes a big difference for us.
|
||||
|
||||
See [this section](https://github.com/simplex-chat/simplex-chat/tree/master#help-us-with-donations) for the ways to donate.
|
||||
|
||||
Thank you,
|
||||
|
||||
Evgeny
|
||||
|
||||
SimpleX Chat founder
|
||||
|
|
39
blog/20241016-wired-attack-on-privacy.md
Normal file
39
blog/20241016-wired-attack-on-privacy.md
Normal file
|
@ -0,0 +1,39 @@
|
|||
---
|
||||
layout: layouts/article.html
|
||||
title: "Wired’s Attack on Privacy"
|
||||
date: 2024-10-16
|
||||
previewBody: blog_previews/20241016.html
|
||||
image: images/20241016-wired-privacy.jpg
|
||||
imageWide: true
|
||||
permalink: "/blog/20241016-wired-attack-on-privacy.html"
|
||||
---
|
||||
|
||||
# Wired’s Attack on Privacy
|
||||
|
||||
<img src="./images/20241016-wired-privacy.jpg" width="330" class="float-to-right">
|
||||
|
||||
The [Wired article](https://www.wired.com/story/neo-nazis-flee-telegram-encrypted-app-simplex/) by David Gilbert focusing on neo-Nazis moving to SimpleX Chat following the Telegram's changes in privacy policy is biased and misleading. By cherry-picking information from [the report](https://www.isdglobal.org/digital_dispatches/neo-nazi-accelerationists-seek-new-digital-refuge-amid-looming-telegram-crackdown/) by the Institute for Strategic Dialogue (ISD), Wired fails to mention that SimpleX network design prioritizes privacy in order to protect human rights defenders, journalists, and everyday users who value their privacy — many people feel safer using SimpleX than non-private apps, being protected from strangers contacting them.
|
||||
|
||||
Yes, privacy-focused SimpleX network offers encryption and anonymity — that’s the point. To paint this as problematic solely because of who may use such apps misses the broader, critical context.
|
||||
|
||||
SimpleX’s true strength lies in protection of [users' metadata](./20240416-dangers-of-metadata-in-messengers.md), which can reveal sensitive information about who is communicating, when, and how often. SimpleX protocols are designed to minimize metadata collection. For countless people, especially vulnerable groups, these features can be life-saving. Wired article ignores these essential protections, and overlooks the positive aspects of having such a unique design, as noted in the publication which [they link to](https://www.maargentino.com/is-telegrams-privacy-shift-driving-extremists-toward-simplex/):
|
||||
|
||||
> *“SimpleX also has a significant advantage when it comes to protecting metadata — the information that can reveal who you’re talking to, when, and how often. SimpleX is designed with privacy at its core, minimizing the amount of metadata collected and ensuring that any temporary data necessary for functionality is not retained or linked to identifiable users.”*
|
||||
|
||||
Both publications referenced by Wired also explore how SimpleX design actually hinders extremist groups from spreading propaganda or building large networks. SimpleX design restricts message visibility and file retention, making it far from ideal for those looking to coordinate large networks. Yet these important qualities are ignored by Wired in favor of fear-mongering about encryption — an argument we've seen before when apps like Signal [faced similar treatment](https://foreignpolicy.com/2021/03/13/telegram-signal-apps-right-wing-extremism-islamic-state-terrorism-violence-europol-encrypted/). Ironically, Wired just a month earlier encouraged its readers to [adopt encrypted messaging apps](https://www.wired.com/story/gadget-lab-podcast-657/), making its current stance even more contradictory.
|
||||
|
||||
The vilification of apps that offer critically important privacy, anonymity, and encryption must stop. That a small share of users may abuse these tools doesn’t justify broad criticism. Additionally, the lobbying for client-side scanning, which Wired’s article seems to indirectly endorse, is not only dangerous but goes against fundamental principles of free speech and personal security. We strongly oppose the use of private communications for any kind of monitoring, including AI training, which would undermine the very trust encryption is designed to build.
|
||||
|
||||
It’s alarming to see Wired not only criticize SimpleX for its strong privacy protections but also subtly blame the European Court of Human Rights for [upholding basic human rights](https://www.theregister.com/2024/02/15/echr_backdoor_encryption/) by rejecting laws that would force encrypted apps to scan and hand over private messages before encryption. Wired writes:
|
||||
|
||||
> *…European Court of Human Rights decision in February of this year ruled that forcing encrypted messaging apps to provide a backdoor to law enforcement was illegal. This decision undermined the EU’s controversial proposal that would potentially force encrypted messaging apps to scan all user content for identifiers of child sexual abuse material.*
|
||||
|
||||
This commentary is both inappropriate and misguided — it plays into the hands of anti-privacy lobbyists attempting to criminalize access to private communications. Framing privacy and anonymity as tools for criminals ignores the reality that these protections are essential for millions of legitimate users, from activists to journalists, to ordinary citizens. Client-side scanning can't have any meaningful effect on reducing CSAM distribution, instead resulting in increase of crime and abuse when criminals get access to this data.
|
||||
|
||||
We need to correct this narrative. The real danger lies not in protecting communication, but in failing to do so. Privacy apps like SimpleX are crucial, not just for those resisting mass surveillance, but for everyone who values the right to communicate without fear of their conversations being monitored or misused. This is a right we must defend and incorporate into law, [as we wrote before](./20240704-future-of-privacy-enforcing-privacy-standards.md).
|
||||
|
||||
Wired could have stood on the right side of this battle and helped normalize the demand for privacy, genuinely protecting people from criminals and from the exploitation of the increasingly AI-enabled mass surveillance. Instead they chose the path of spreading fear and uncertainty of encrypted messaging and tools that enable privacy and anonymity.
|
||||
|
||||
Spreading misinformation about privacy and security undermines trust in the tools that protect us, making it easier to justify more invasive surveillance measures that chip away at our civil liberties.
|
||||
|
||||
Wired did not respond to our request for comment.
|
|
@ -1,8 +1,19 @@
|
|||
# Blog
|
||||
|
||||
Oct 14, 2024 [SimpleX network: security review of protocols design by Trail of Bits, v6.1 released with better calls and user experience.](./20241014-simplex-network-v6-1-security-review-better-calls-user-experience.md)
|
||||
|
||||
New security audit: Trail of Bits reviewed the cryptographic design of protocols used in SimpleX network and apps.
|
||||
|
||||
What's new in v6.1:
|
||||
- Better calls: switch audio and video during the call.
|
||||
- Better iOS notifications: improved delivery, reduced traffic usage.
|
||||
- Better user experience: switch chat profiles, customizable message shapes, forward up to 20 messages.
|
||||
|
||||
---
|
||||
|
||||
Aug 14, 2024 [SimpleX network: the investment from Jack Dorsey and Asymmetric, v6.0 released with the new user experience and private message routing](./20240814-simplex-chat-vision-funding-v6-private-routing-new-user-experience.md)
|
||||
|
||||
[SimpleX Chat: vision and funding 2.0](#simplex-chat-vision-and-funding-20): past, present, future.
|
||||
SimpleX Chat: vision and funding 2.0: past, present, future.
|
||||
|
||||
Announcing the investment from Jack Dorsey and Asymmetric.
|
||||
|
||||
|
|
BIN
blog/images/20241014-calls.png
Normal file
BIN
blog/images/20241014-calls.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 286 KiB |
BIN
blog/images/20241014-forward.png
Normal file
BIN
blog/images/20241014-forward.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 582 KiB |
BIN
blog/images/20241014-messages.png
Normal file
BIN
blog/images/20241014-messages.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 241 KiB |
BIN
blog/images/20241014-profiles1.png
Normal file
BIN
blog/images/20241014-profiles1.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 364 KiB |
BIN
blog/images/20241014-profiles2.png
Normal file
BIN
blog/images/20241014-profiles2.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 360 KiB |
BIN
blog/images/20241016-wired-privacy.jpg
Normal file
BIN
blog/images/20241016-wired-privacy.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 42 KiB |
|
@ -12,7 +12,7 @@ constraints: zip +disable-bzip2 +disable-zstd
|
|||
source-repository-package
|
||||
type: git
|
||||
location: https://github.com/simplex-chat/simplexmq.git
|
||||
tag: c41bfe831d6d3fdf068f7419cbfed6afa46cb5b5
|
||||
tag: 967afaf802d7ea98480eaf280bfc6f35d4d43f05
|
||||
|
||||
source-repository-package
|
||||
type: git
|
||||
|
|
|
@ -8,9 +8,11 @@ revision: 23.04.2024
|
|||
|
||||
While great care is taken to ensure the highest level of security and privacy in SimpleX network servers and clients, all software can have flaws, and we believe it is a critical part of an organization's social responsibility to minimize the impact of these flaws through continual vulnerability discovery efforts, defense in depth design, and prompt remediation and notification.
|
||||
|
||||
The security assessment of SimpleX cryptography and networking was done by Trail of Bits in [November 2022](../blog/20221108-simplex-chat-v4.2-security-audit-new-website.md).
|
||||
The implementation security assessment of SimpleX cryptography and networking was done by Trail of Bits in [November 2022](../blog/20221108-simplex-chat-v4.2-security-audit-new-website.md).
|
||||
|
||||
We are planning design review of SimpleX protocols in July 2024 and implementation review in December 2024/January 2025.
|
||||
The cryptographic review of SimpleX protocols design was done by Trail of Bits in [July 2024](../blog/20241014-simplex-network-v6-1-security-review-better-calls-user-experience.md).
|
||||
|
||||
We are planning implementation security assessment in early 2025.
|
||||
|
||||
## Reporting security issues
|
||||
|
||||
|
|
456
docs/SERVER.md
456
docs/SERVER.md
|
@ -1,13 +1,16 @@
|
|||
---
|
||||
title: Hosting your own SMP Server
|
||||
revision: 03.06.2024
|
||||
revision: 12.10.2024
|
||||
---
|
||||
|
||||
| Updated 28.05.2024 | Languages: EN, [FR](/docs/lang/fr/SERVER.md), [CZ](/docs/lang/cs/SERVER.md), [PL](/docs/lang/pl/SERVER.md) |
|
||||
# Hosting your own SMP Server
|
||||
|
||||
| Updated 12.10.2024 | Languages: EN, [FR](/docs/lang/fr/SERVER.md), [CZ](/docs/lang/cs/SERVER.md), [PL](/docs/lang/pl/SERVER.md) |
|
||||
|
||||
### Table of Contents
|
||||
|
||||
- [Hosting your own SMP server](#hosting-your-own-smp-server)
|
||||
- [Quick start](#quick-start)
|
||||
- [Detailed guide](#detailed-guide)
|
||||
- [Overview](#overview)
|
||||
- [Installation](#installation)
|
||||
- [Configuration](#configuration)
|
||||
|
@ -29,17 +32,218 @@ revision: 03.06.2024
|
|||
- [Updating your SMP server](#updating-your-smp-server)
|
||||
- [Configuring the app to use the server](#configuring-the-app-to-use-the-server)
|
||||
|
||||
# Hosting your own SMP Server
|
||||
## Quick start
|
||||
|
||||
## Overview
|
||||
To create SMP server, you'll need:
|
||||
|
||||
- VPS or any other server.
|
||||
- Your server domain, with A and AAAA records specifying server IPv4 and IPv6 addresses (`smp1.example.com`)
|
||||
- A basic Linux knowledge.
|
||||
|
||||
*Please note*: while you can run an SMP server without a domain name, in the near future client applications will start using server domain name in the invitation links (instead of `simplex.chat` domain they use now). In case a server does not have domain name and server pages (see below), the clients will be generaing the links with `simplex:` scheme that cannot be opened in the browsers.
|
||||
|
||||
1. Install server with [Installation script](https://github.com/simplex-chat/simplexmq#using-installation-script).
|
||||
|
||||
2. Adjust firewall:
|
||||
|
||||
```sh
|
||||
ufw allow 80/tcp &&\
|
||||
ufw allow 443/tcp &&\
|
||||
ufw allow 5223/tcp
|
||||
```
|
||||
|
||||
3. Init server:
|
||||
|
||||
Replace `smp1.example.com` with your actual server domain.
|
||||
|
||||
```sh
|
||||
su smp -c 'smp-server init --yes \
|
||||
--store-log \
|
||||
--no-password \
|
||||
--control-port \
|
||||
--socks-proxy \
|
||||
--source-code \
|
||||
--fqdn=smp1.example.com
|
||||
```
|
||||
|
||||
4. Install tor:
|
||||
|
||||
```sh
|
||||
CODENAME="$(lsb_release -c | awk '{print $2}')"
|
||||
|
||||
echo "deb [signed-by=/usr/share/keyrings/tor-archive-keyring.gpg] https://deb.torproject.org/torproject.org ${CODENAME} main
|
||||
deb-src [signed-by=/usr/share/keyrings/tor-archive-keyring.gpg] https://deb.torproject.org/torproject.org ${CODENAME} main" > /etc/apt/sources.list.d/tor.list &&\
|
||||
curl --proto '=https' --tlsv1.2 -sSf https://deb.torproject.org/torproject.org/A3C4F0F979CAA22CDBA8F512EE8CBC9E886DDD89.asc | gpg --dearmor | tee /usr/share/keyrings/tor-archive-keyring.gpg >/dev/null &&\
|
||||
apt update && apt install -y tor deb.torproject.org-keyring
|
||||
```
|
||||
|
||||
5. Configure tor:
|
||||
|
||||
```sh
|
||||
tor-instance-create tor2 &&\
|
||||
mkdir /var/lib/tor/simplex-smp/ &&\
|
||||
chown debian-tor:debian-tor /var/lib/tor/simplex-smp/ &&\
|
||||
chmod 700 /var/lib/tor/simplex-smp/
|
||||
```
|
||||
|
||||
```sh
|
||||
vim /etc/tor/torrc
|
||||
```
|
||||
|
||||
Paste the following:
|
||||
|
||||
```sh
|
||||
# Enable log (otherwise, tor doesn't seem to deploy onion address)
|
||||
Log notice file /var/log/tor/notices.log
|
||||
# Enable single hop routing (2 options below are dependencies of the third) - It will reduce the latency at the cost of lower anonimity of the server - as SMP-server onion address is used in the clients together with public address, this is ok. If you deploy SMP-server with onion-only address, keep standard configuration.
|
||||
SOCKSPort 0
|
||||
HiddenServiceNonAnonymousMode 1
|
||||
HiddenServiceSingleHopMode 1
|
||||
# smp-server hidden service host directory and port mappings
|
||||
HiddenServiceDir /var/lib/tor/simplex-smp/
|
||||
HiddenServicePort 5223 localhost:5223
|
||||
HiddenServicePort 443 localhost:443
|
||||
```
|
||||
|
||||
```sh
|
||||
vim /etc/tor/instances/tor2/torrc
|
||||
```
|
||||
|
||||
Paste the following:
|
||||
|
||||
```sh
|
||||
# Log tor to systemd daemon
|
||||
Log notice syslog
|
||||
# Listen to local 9050 port for socks proxy
|
||||
SocksPort 9050
|
||||
```
|
||||
|
||||
6. Start tor:
|
||||
|
||||
```sh
|
||||
systemctl enable tor &&\
|
||||
systemctl start tor &&\
|
||||
systemctl restart tor &&\
|
||||
systemctl enable --now tor@tor2
|
||||
```
|
||||
|
||||
7. Install Caddy:
|
||||
|
||||
```sh
|
||||
sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https curl &&\
|
||||
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg &&\
|
||||
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list &&\
|
||||
sudo apt update && sudo apt install caddy
|
||||
```
|
||||
|
||||
8. Configure Caddy:
|
||||
|
||||
```sh
|
||||
vim /etc/caddy/Caddyfile
|
||||
```
|
||||
|
||||
Replace `smp1.example.com` with your actual server domain. Paste the following:
|
||||
|
||||
```
|
||||
http://smp1.example.com {
|
||||
redir https://smp1.example.com{uri} permanent
|
||||
}
|
||||
|
||||
smp1.example.com:8443 {
|
||||
tls {
|
||||
key_type rsa4096
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```sh
|
||||
vim /usr/local/bin/simplex-servers-certs
|
||||
```
|
||||
|
||||
Replace `smp1.example.com` with your actual server domain. Paste the following:
|
||||
|
||||
```sh
|
||||
#!/usr/bin/env sh
|
||||
set -eu
|
||||
|
||||
user='smp'
|
||||
group="$user"
|
||||
|
||||
domain='smp1.example.com'
|
||||
folder_in="/var/lib/caddy/.local/share/caddy/certificates/acme-v02.api.letsencrypt.org-directory/${domain}"
|
||||
folder_out='/etc/opt/simplex'
|
||||
key_name='web.key'
|
||||
cert_name='web.crt'
|
||||
|
||||
# Copy certifiacte from Caddy directory to smp-server directory
|
||||
cp "${folder_in}/${domain}.crt" "${folder_out}/${cert_name}"
|
||||
# Assign correct permissions
|
||||
chown "$user":"$group" "${folder_out}/${cert_name}"
|
||||
|
||||
# Copy certifiacte key from Caddy directory to smp-server directory
|
||||
cp "${folder_in}/${domain}.key" "${folder_out}/${key_name}"
|
||||
# Assign correct permissions
|
||||
chown "$user":"$group" "${folder_out}/${key_name}"
|
||||
```
|
||||
|
||||
```sh
|
||||
chmod +x /usr/local/bin/simplex-servers-certs
|
||||
```
|
||||
|
||||
```sh
|
||||
sudo crontab -e
|
||||
```
|
||||
|
||||
Paste the following:
|
||||
|
||||
```sh
|
||||
# Every week on 00:20 sunday
|
||||
20 0 * * 0 /usr/local/bin/simplex-servers-certs
|
||||
```
|
||||
|
||||
9. Enable and start Caddy service:
|
||||
|
||||
Wait until "good to go" has been printed.
|
||||
|
||||
```sh
|
||||
systemctl enable --now caddy &&\
|
||||
sleep 10 &&\
|
||||
/usr/local/bin/simplex-servers-certs &&\
|
||||
echo 'good to go'
|
||||
```
|
||||
|
||||
10. Enable and start smp-server:
|
||||
|
||||
```sh
|
||||
systemctl enable --now smp-server.service
|
||||
```
|
||||
|
||||
11. Print your address:
|
||||
|
||||
```sh
|
||||
smp="$(journalctl --output cat -q _SYSTEMD_INVOCATION_ID="$(systemctl show -p InvocationID --value smp-server)" | grep -m1 'Server address:' | awk '{print $NF}' | sed 's/:443.*//')"
|
||||
tor="$(cat /var/lib/tor/simplex-smp/hostname)"
|
||||
|
||||
echo "$smp,$tor"
|
||||
```
|
||||
|
||||
## Detailed guide
|
||||
|
||||
### Overview
|
||||
|
||||
SMP server is the relay server used to pass messages in SimpleX network. SimpleX Chat apps have preset servers (for mobile apps these are smp11, smp12 and smp14.simplex.im), but you can easily change app configuration to use other servers.
|
||||
|
||||
SimpleX clients only determine which server is used to receive the messages, separately for each contact (or group connection with a group member), and these servers are only temporary, as the delivery address can change.
|
||||
|
||||
To create SMP server, you'll need:
|
||||
|
||||
1. VPS or any other server.
|
||||
2. Your own domain, pointed at the server (`smp.example.com`)
|
||||
3. A basic Linux knowledge.
|
||||
|
||||
_Please note_: when you change the servers in the app configuration, it only affects which servers will be used for the new contacts, the existing contacts will not automatically move to the new servers, but you can move them manually using ["Change receiving address"](../blog/20221108-simplex-chat-v4.2-security-audit-new-website.md#change-your-delivery-address-beta) button in contact/member information pages – it will be automated in the future.
|
||||
|
||||
## Installation
|
||||
### Installation
|
||||
|
||||
1. First, install `smp-server`:
|
||||
|
||||
|
@ -82,8 +286,10 @@ Manual installation requires some preliminary actions:
|
|||
```sh
|
||||
# For Ubuntu
|
||||
sudo ufw allow 5223/tcp
|
||||
sudo ufw allow 443/tcp
|
||||
sudo ufw allow 80/tcp
|
||||
# For Fedora
|
||||
sudo firewall-cmd --permanent --add-port=5223/tcp && \
|
||||
sudo firewall-cmd --permanent --add-port=5223/tcp --add-port=443/tcp --add-port=80/tcp && \
|
||||
sudo firewall-cmd --reload
|
||||
```
|
||||
|
||||
|
@ -102,6 +308,7 @@ Manual installation requires some preliminary actions:
|
|||
LimitNOFILE=65535
|
||||
KillSignal=SIGINT
|
||||
TimeoutStopSec=infinity
|
||||
AmbientCapabilities=CAP_NET_BIND_SERVICE
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
|
@ -109,7 +316,7 @@ Manual installation requires some preliminary actions:
|
|||
|
||||
And execute `sudo systemctl daemon-reload`.
|
||||
|
||||
## Configuration
|
||||
### Configuration
|
||||
|
||||
To see which options are available, execute `smp-server` without flags:
|
||||
|
||||
|
@ -129,7 +336,7 @@ You can get further help by executing `sudo su smp -c "smp-server <command> -h"`
|
|||
|
||||
After that, we need to configure `smp-server`:
|
||||
|
||||
### Interactively
|
||||
#### Interactively
|
||||
|
||||
Execute the following command:
|
||||
|
||||
|
@ -159,7 +366,7 @@ These statistics include daily counts of created, secured and deleted queues, se
|
|||
|
||||
Enter your domain or ip address that your smp-server is running on - it will be included in server certificates and also printed as part of server address.
|
||||
|
||||
### Via command line options
|
||||
#### Via command line options
|
||||
|
||||
Execute the following command:
|
||||
|
||||
|
@ -223,7 +430,7 @@ Server address: smp://d5fcsc7hhtPpexYUbI2XPxDbyU2d3WsVmROimcL90ss=:V8ONoJ6ICwnrZ
|
|||
|
||||
The server address above should be used in your client configuration, and if you added server password it should only be shared with the other people who you want to allow using your server to receive the messages (all your contacts will be able to send messages - it does not require a password). If you passed IP address or hostnames during the initialisation, they will be printed as part of server address, otherwise replace `<hostnames>` with the actual server hostnames.
|
||||
|
||||
## Further configuration
|
||||
### Further configuration
|
||||
|
||||
All generated configuration, along with a description for each parameter, is available inside configuration file in `/etc/opt/simplex/smp-server.ini` for further customization. Depending on the smp-server version, the configuration file looks something like this:
|
||||
|
||||
|
@ -245,26 +452,26 @@ source_code: https://github.com/simplex-chat/simplexmq
|
|||
# condition_amendments: link
|
||||
|
||||
# Server location and operator.
|
||||
server_country: <YOUR_SERVER_LOCATION>
|
||||
operator: <YOUR_NAME>
|
||||
operator_country: <YOUR_LOCATION>
|
||||
website: <WEBSITE_IF_AVAILABLE>
|
||||
# server_country: ISO-3166 2-letter code
|
||||
# operator: entity (organization or person name)
|
||||
# operator_country: ISO-3166 2-letter code
|
||||
# website:
|
||||
|
||||
# Administrative contacts.
|
||||
#admin_simplex: SimpleX address
|
||||
admin_email: <EMAIL>
|
||||
# admin_simplex: SimpleX address
|
||||
# admin_email:
|
||||
# admin_pgp:
|
||||
# admin_pgp_fingerprint:
|
||||
|
||||
# Contacts for complaints and feedback.
|
||||
# complaints_simplex: SimpleX address
|
||||
complaints_email: <COMPLAINTS_EMAIL>
|
||||
# complaints_email:
|
||||
# complaints_pgp:
|
||||
# complaints_pgp_fingerprint:
|
||||
|
||||
# Hosting provider.
|
||||
hosting: <HOSTING_PROVIDER_NAME>
|
||||
hosting_country: <HOSTING_PROVIDER_LOCATION>
|
||||
# hosting: entity (organization or person name)
|
||||
# hosting_country: ISO-3166 2-letter code
|
||||
|
||||
[STORE_LOG]
|
||||
# The server uses STM memory for persistence,
|
||||
|
@ -278,6 +485,7 @@ enable: on
|
|||
# they are preserved in the .bak file until the next restart.
|
||||
restore_messages: on
|
||||
expire_messages_days: 21
|
||||
expire_ntfs_hours: 24
|
||||
|
||||
# Log daily server statistics to CSV file
|
||||
log_stats: on
|
||||
|
@ -294,11 +502,17 @@ new_queues: on
|
|||
# with the users who you want to allow creating messaging queues on your server.
|
||||
# create_password: password to create new queues (any printable ASCII characters without whitespace, '@', ':' and '/')
|
||||
|
||||
# control_port_admin_password:
|
||||
# control_port_user_password:
|
||||
|
||||
[TRANSPORT]
|
||||
# host is only used to print server address on start
|
||||
host: <your server domain/ip>
|
||||
port: 5223
|
||||
# Host is only used to print server address on start.
|
||||
# You can specify multiple server ports.
|
||||
host: <domain/ip>
|
||||
port: 5223,443
|
||||
log_tls_errors: off
|
||||
|
||||
# Use `websockets: 443` to run websockets server in addition to plain TLS.
|
||||
websockets: off
|
||||
# control_port: 5224
|
||||
|
||||
|
@ -310,7 +524,7 @@ websockets: off
|
|||
# required_host_mode: off
|
||||
|
||||
# The domain suffixes of the relays you operate (space-separated) to count as separate proxy statistics.
|
||||
# own_server_domains: <your domain suffixes>
|
||||
# own_server_domains:
|
||||
|
||||
# SOCKS proxy port for forwarding messages to destination servers.
|
||||
# You may need a separate instance of SOCKS proxy for incoming single-hop requests.
|
||||
|
@ -326,7 +540,7 @@ websockets: off
|
|||
[INACTIVE_CLIENTS]
|
||||
# TTL and interval to check inactive clients
|
||||
disconnect: off
|
||||
# ttl: 43200
|
||||
# ttl: 21600
|
||||
# check_interval: 3600
|
||||
|
||||
[WEB]
|
||||
|
@ -336,18 +550,18 @@ static_path: /var/opt/simplex/www
|
|||
# Run an embedded server on this port
|
||||
# Onion sites can use any port and register it in the hidden service config.
|
||||
# Running on a port 80 may require setting process capabilities.
|
||||
# http: 8000
|
||||
#http: 8000
|
||||
|
||||
# You can run an embedded TLS web server too if you provide port and cert and key files.
|
||||
# Not required for running relay on onion address.
|
||||
# https: 443
|
||||
# cert: /etc/opt/simplex/web.cert
|
||||
# key: /etc/opt/simplex/web.key
|
||||
https: 443
|
||||
cert: /etc/opt/simplex/web.crt
|
||||
key: /etc/opt/simplex/web.key
|
||||
```
|
||||
|
||||
## Server security
|
||||
### Server security
|
||||
|
||||
### Initialization
|
||||
#### Initialization
|
||||
|
||||
Although it's convenient to initialize smp-server configuration directly on the server, operators **ARE ADVISED** to initialize smp-server fully offline to protect your SMP server CA private key.
|
||||
|
||||
|
@ -367,7 +581,7 @@ Follow the steps to quickly initialize the server offline:
|
|||
rsync -hzasP $HOME/simplex/smp/config/ <server_user>@<server_address>:/etc/opt/simplex/
|
||||
```
|
||||
|
||||
### Private keys
|
||||
#### Private keys
|
||||
|
||||
Connection to the smp server occurs via a TLS connection. During the TLS handshake, the client verifies smp-server CA and server certificates by comparing its fingerprint with the one included in server address. If server TLS credential is compromised, this key can be used to sign a new one, keeping the same server identity and established connections. In order to protect your smp-server from bad actors, operators **ARE ADVISED** to move CA private key to a safe place. That could be:
|
||||
|
||||
|
@ -392,7 +606,7 @@ Follow the steps to secure your CA keys:
|
|||
rm /etc/opt/simplex/ca.key
|
||||
```
|
||||
|
||||
### Online certificate rotation
|
||||
#### Online certificate rotation
|
||||
|
||||
Operators of smp servers **ARE ADVISED** to rotate online certificate regularly (e.g., every 3 months). In order to do this, follow the steps:
|
||||
|
||||
|
@ -468,9 +682,9 @@ Operators of smp servers **ARE ADVISED** to rotate online certificate regularly
|
|||
|
||||
10. Done!
|
||||
|
||||
## Tor: installation and configuration
|
||||
### Tor: installation and configuration
|
||||
|
||||
### Installation for onion address
|
||||
#### Installation for onion address
|
||||
|
||||
SMP-server can also be deployed to be available via [Tor](https://www.torproject.org) network. Run the following commands as `root` user.
|
||||
|
||||
|
@ -526,6 +740,7 @@ SMP-server can also be deployed to be available via [Tor](https://www.torproject
|
|||
# smp-server hidden service host directory and port mappings
|
||||
HiddenServiceDir /var/lib/tor/simplex-smp/
|
||||
HiddenServicePort 5223 localhost:5223
|
||||
HiddenServicePort 443 localhost:443
|
||||
```
|
||||
|
||||
- Create directories:
|
||||
|
@ -550,7 +765,7 @@ SMP-server can also be deployed to be available via [Tor](https://www.torproject
|
|||
cat /var/lib/tor/simplex-smp/hostname
|
||||
```
|
||||
|
||||
### SOCKS port for SMP PROXY
|
||||
#### SOCKS port for SMP PROXY
|
||||
|
||||
SMP-server versions starting from `v5.8.0-beta.0` can be configured to PROXY smp servers available exclusively through [Tor](https://www.torproject.org) network to be accessible to the clients that do not use Tor. Run the following commands as `root` user.
|
||||
|
||||
|
@ -597,9 +812,11 @@ SMP-server versions starting from `v5.8.0-beta.0` can be configured to PROXY smp
|
|||
...
|
||||
```
|
||||
|
||||
## Server information page
|
||||
### Server information page
|
||||
|
||||
SMP-server versions starting from `v5.8.0` can be configured to serve Web page with server information that can include admin info, server info, provider info, etc. Run the following commands as `root` user.
|
||||
SMP server **SHOULD** be configured to serve Web page with server information that can include admin info, server info, provider info, etc. It will also serve connection links, generated using the mobile/desktop apps. Run the following commands as `root` user.
|
||||
|
||||
_Please note:_ this configuration is supported since `v6.1.0-beta.2`.
|
||||
|
||||
1. Add the following to your smp-server configuration (please modify fields in [INFORMATION] section to include relevant information):
|
||||
|
||||
|
@ -608,8 +825,19 @@ SMP-server versions starting from `v5.8.0` can be configured to serve Web page w
|
|||
```
|
||||
|
||||
```ini
|
||||
[TRANSPORT]
|
||||
# host is only used to print server address on start
|
||||
host: <domain/ip>
|
||||
port: 443,5223
|
||||
websockets: off
|
||||
log_tls_errors: off
|
||||
control_port: 5224
|
||||
|
||||
[WEB]
|
||||
https: 443
|
||||
static_path: /var/opt/simplex/www
|
||||
cert: /etc/opt/simplex/web.crt
|
||||
key: /etc/opt/simplex/web.key
|
||||
|
||||
[INFORMATION]
|
||||
# AGPLv3 license requires that you make any source code modifications
|
||||
|
@ -678,16 +906,23 @@ SMP-server versions starting from `v5.8.0` can be configured to serve Web page w
|
|||
|
||||
[Full Caddy instllation instructions](https://caddyserver.com/docs/install)
|
||||
|
||||
3. Replace Caddy configuration with the following (don't forget to replace `<YOUR_DOMAIN>`):
|
||||
3. Replace Caddy configuration with the following:
|
||||
|
||||
Please replace `YOUR_DOMAIN` with your actual domain (smp.example.com).
|
||||
|
||||
```sh
|
||||
vim /etc/caddy/Caddyfile
|
||||
```
|
||||
|
||||
```caddy
|
||||
<YOUR_DOMAIN> {
|
||||
root * /var/opt/simplex/www
|
||||
file_server
|
||||
```
|
||||
http://YOUR_DOMAIN {
|
||||
redir https://YOUR_DOMAIN{uri} permanent
|
||||
}
|
||||
|
||||
YOUR_DOMAIN:8443 {
|
||||
tls {
|
||||
key_type rsa4096
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -697,17 +932,75 @@ SMP-server versions starting from `v5.8.0` can be configured to serve Web page w
|
|||
systemctl enable --now caddy
|
||||
```
|
||||
|
||||
5. Upgrade your smp-server to latest version - [Updating your smp server](#updating-your-smp-server)
|
||||
5. Create script to copy certificates to your smp directory:
|
||||
|
||||
6. Access the webpage you've deployed from your browser. You should see the smp-server information that you've provided in your ini file.
|
||||
Please replace `YOUR_DOMAIN` with your actual domain (smp.example.com).
|
||||
|
||||
## Documentation
|
||||
```sh
|
||||
vim /usr/local/bin/simplex-servers-certs
|
||||
```
|
||||
|
||||
```sh
|
||||
#!/usr/bin/env sh
|
||||
set -eu
|
||||
|
||||
user='smp'
|
||||
group="$user"
|
||||
|
||||
domain='HOST'
|
||||
folder_in="/var/lib/caddy/.local/share/caddy/certificates/acme-v02.api.letsencrypt.org-directory/${domain}"
|
||||
folder_out='/etc/opt/simplex'
|
||||
key_name='web.key'
|
||||
cert_name='web.crt'
|
||||
|
||||
# Copy certifiacte from Caddy directory to smp-server directory
|
||||
cp "${folder_in}/${domain}.crt" "${folder_out}/${cert_name}"
|
||||
# Assign correct permissions
|
||||
chown "$user":"$group" "${folder_out}/${cert_name}"
|
||||
|
||||
# Copy certifiacte key from Caddy directory to smp-server directory
|
||||
cp "${folder_in}/${domain}.key" "${folder_out}/${key_name}"
|
||||
# Assign correct permissions
|
||||
chown "$user":"$group" "${folder_out}/${key_name}"
|
||||
```
|
||||
|
||||
6. Make the script executable and execute it:
|
||||
|
||||
```sh
|
||||
chmod +x /usr/local/bin/simplex-servers-certs && /usr/local/bin/simplex-servers-certs
|
||||
```
|
||||
|
||||
7. Check if certificates were copied:
|
||||
|
||||
```sh
|
||||
ls -haltr /etc/opt/simplex/web*
|
||||
```
|
||||
|
||||
8. Create cronjob to copy certificates to smp directory in timely manner:
|
||||
|
||||
```sh
|
||||
sudo crontab -e
|
||||
```
|
||||
|
||||
```sh
|
||||
# Every week on 00:20 sunday
|
||||
20 0 * * 0 /usr/local/bin/simplex-servers-certs
|
||||
```
|
||||
|
||||
9. Then:
|
||||
|
||||
- If you're running at least `v6.1.0-beta.2`, [restart the server](#systemd-commands).
|
||||
- If you're running below `v6.1.0-beta.2`, [upgrade the server](#updating-your-smp-server).
|
||||
|
||||
10. Access the webpage you've deployed from your browser (`https://smp.example.org`). You should see the smp-server information that you've provided in your ini file.
|
||||
|
||||
### Documentation
|
||||
|
||||
All necessary files for `smp-server` are located in `/etc/opt/simplex/` folder.
|
||||
|
||||
Stored messages, connections, statistics and server log are located in `/var/opt/simplex/` folder.
|
||||
|
||||
### SMP server address
|
||||
#### SMP server address
|
||||
|
||||
SMP server address has the following format:
|
||||
|
||||
|
@ -727,7 +1020,7 @@ smp://<fingerprint>[:<password>]@<public_hostname>[,<onion_hostname>]
|
|||
|
||||
Your configured hostname(s) of `smp-server`. You can check your configured hosts in `/etc/opt/simplex/smp-server.ini`, under `[TRANSPORT]` section in `host:` field.
|
||||
|
||||
### Systemd commands
|
||||
#### Systemd commands
|
||||
|
||||
To start `smp-server` on host boot, run:
|
||||
|
||||
|
@ -786,16 +1079,18 @@ Nov 23 19:23:21 5588ab759e80 smp-server[30878]: not expiring inactive clients
|
|||
Nov 23 19:23:21 5588ab759e80 smp-server[30878]: creating new queues requires password
|
||||
```
|
||||
|
||||
### Monitoring
|
||||
#### Monitoring
|
||||
|
||||
You can enable `smp-server` statistics for `Grafana` dashboard by setting value `on` in `/etc/opt/simplex/smp-server.ini`, under `[STORE_LOG]` section in `log_stats:` field.
|
||||
|
||||
Logs will be stored as `csv` file in `/var/opt/simplex/smp-server-stats.daily.log`. Fields for the `csv` file are:
|
||||
|
||||
```sh
|
||||
fromTime,qCreated,qSecured,qDeleted,msgSent,msgRecv,dayMsgQueues,weekMsgQueues,monthMsgQueues,msgSentNtf,msgRecvNtf,dayCountNtf,weekCountNtf,monthCountNtf,qCount,msgCount,msgExpired,qDeletedNew,qDeletedSecured,pRelays_pRequests,pRelays_pSuccesses,pRelays_pErrorsConnect,pRelays_pErrorsCompat,pRelays_pErrorsOther,pRelaysOwn_pRequests,pRelaysOwn_pSuccesses,pRelaysOwn_pErrorsConnect,pRelaysOwn_pErrorsCompat,pRelaysOwn_pErrorsOther,pMsgFwds_pRequests,pMsgFwds_pSuccesses,pMsgFwds_pErrorsConnect,pMsgFwds_pErrorsCompat,pMsgFwds_pErrorsOther,pMsgFwdsOwn_pRequests,pMsgFwdsOwn_pSuccesses,pMsgFwdsOwn_pErrorsConnect,pMsgFwdsOwn_pErrorsCompat,pMsgFwdsOwn_pErrorsOther,pMsgFwdsRecv,qSub,qSubAuth,qSubDuplicate,qSubProhibited,msgSentAuth,msgSentQuota,msgSentLarge
|
||||
fromTime,qCreated,qSecured,qDeleted,msgSent,msgRecv,dayMsgQueues,weekMsgQueues,monthMsgQueues,msgSentNtf,msgRecvNtf,dayCountNtf,weekCountNtf,monthCountNtf,qCount,msgCount,msgExpired,qDeletedNew,qDeletedSecured,pRelays_pRequests,pRelays_pSuccesses,pRelays_pErrorsConnect,pRelays_pErrorsCompat,pRelays_pErrorsOther,pRelaysOwn_pRequests,pRelaysOwn_pSuccesses,pRelaysOwn_pErrorsConnect,pRelaysOwn_pErrorsCompat,pRelaysOwn_pErrorsOther,pMsgFwds_pRequests,pMsgFwds_pSuccesses,pMsgFwds_pErrorsConnect,pMsgFwds_pErrorsCompat,pMsgFwds_pErrorsOther,pMsgFwdsOwn_pRequests,pMsgFwdsOwn_pSuccesses,pMsgFwdsOwn_pErrorsConnect,pMsgFwdsOwn_pErrorsCompat,pMsgFwdsOwn_pErrorsOther,pMsgFwdsRecv,qSub,qSubAuth,qSubDuplicate,qSubProhibited,msgSentAuth,msgSentQuota,msgSentLarge,msgNtfs,msgNtfNoSub,msgNtfLost,qSubNoMsg,msgRecvGet,msgGet,msgGetNoMsg,msgGetAuth,msgGetDuplicate,msgGetProhibited,psSubDaily,psSubWeekly,psSubMonthly,qCount2,ntfCreated,ntfDeleted,ntfSub,ntfSubAuth,ntfSubDuplicate,ntfCount,qDeletedAllB,qSubAllB,qSubEnd,qSubEndB,ntfDeletedB,ntfSubB,msgNtfsB,msgNtfExpired
|
||||
```
|
||||
|
||||
#### Fields description
|
||||
|
||||
| Field number | Field name | Field Description |
|
||||
| ------------- | ---------------------------- | -------------------------- |
|
||||
| 1 | `fromTime` | Date of statistics |
|
||||
|
@ -856,6 +1151,34 @@ fromTime,qCreated,qSecured,qDeleted,msgSent,msgRecv,dayMsgQueues,weekMsgQueues,m
|
|||
| 45 | `msgSentAuth` | Authentication errors |
|
||||
| 46 | `msgSentQuota` | Quota errors |
|
||||
| 47 | `msgSentLarge` | Large message errors |
|
||||
| 48 | `msgNtfs` | XXXXXXXXXXXXXXXXXXXX |
|
||||
| 49 | `msgNtfNoSub` | XXXXXXXXXXXXXXXXXXXX |
|
||||
| 50 | `msgNtfLost` | XXXXXXXXXXXXXXXXXXXX |
|
||||
| 51 | `qSubNoMsg` | Removed, always 0 |
|
||||
| 52 | `msgRecvGet` | XXXXXXXXXXXXXXXXX |
|
||||
| 53 | `msgGet` | XXXXXXXXXXXXXXXXX |
|
||||
| 54 | `msgGetNoMsg` | XXXXXXXXXXXXXXXXX |
|
||||
| 55 | `msgGetAuth` | XXXXXXXXXXXXXXXXX |
|
||||
| 56 | `msgGetDuplicate` | XXXXXXXXXXXXXXXXX |
|
||||
| 57 | `msgGetProhibited` | XXXXXXXXXXXXXXXXX |
|
||||
| 58 | `psSub_dayCount` | Removed, always 0 |
|
||||
| 59 | `psSub_weekCount` | Removed, always 0 |
|
||||
| 60 | `psSub_monthCount` | Removed, always 0 |
|
||||
| 61 | `qCount` | XXXXXXXXXXXXXXXXX |
|
||||
| 62 | `ntfCreated` | XXXXXXXXXXXXXXXXX |
|
||||
| 63 | `ntfDeleted` | XXXXXXXXXXXXXXXXX |
|
||||
| 64 | `ntfSub` | XXXXXXXXXXXXXXXXX |
|
||||
| 65 | `ntfSubAuth` | XXXXXXXXXXXXXXXXX |
|
||||
| 66 | `ntfSubDuplicate` | XXXXXXXXXXXXXXXXX |
|
||||
| 67 | `ntfCount` | XXXXXXXXXXXXXXXXX |
|
||||
| 68 | `qDeletedAllB` | XXXXXXXXXXXXXXXXX |
|
||||
| 69 | `qSubAllB` | XXXXXXXXXXXXXXXXX |
|
||||
| 70 | `qSubEnd` | XXXXXXXXXXXXXXXXX |
|
||||
| 71 | `qSubEndB` | XXXXXXXXXXXXXXXXX |
|
||||
| 72 | `ntfDeletedB` | XXXXXXXXXXXXXXXXX |
|
||||
| 73 | `ntfSubB` | XXXXXXXXXXXXXXXXX |
|
||||
| 74 | `msgNtfsB` | XXXXXXXXXXXXXXXXX |
|
||||
| 75 | `msgNtfExpired` | XXXXXXXXXXXXXXXXX |
|
||||
|
||||
To import `csv` to `Grafana` one should:
|
||||
|
||||
|
@ -882,64 +1205,93 @@ To import `csv` to `Grafana` one should:
|
|||
|
||||
For further documentation, see: [CSV Data Source for Grafana - Documentation](https://grafana.github.io/grafana-csv-datasource/)
|
||||
|
||||
## Updating your SMP server
|
||||
### Updating your SMP server
|
||||
|
||||
To update your smp-server to latest version, choose your installation method and follow the steps:
|
||||
|
||||
- Manual deployment
|
||||
|
||||
1. Stop the server:
|
||||
|
||||
```sh
|
||||
sudo systemctl stop smp-server
|
||||
```
|
||||
|
||||
2. Update the binary:
|
||||
|
||||
```sh
|
||||
curl -L https://github.com/simplex-chat/simplexmq/releases/latest/download/smp-server-ubuntu-20_04-x86-64 -o /usr/local/bin/smp-server && chmod +x /usr/local/bin/smp-server
|
||||
```
|
||||
|
||||
3. Start the server:
|
||||
|
||||
```sh
|
||||
sudo systemctl start smp-server
|
||||
```
|
||||
|
||||
- [Offical installation script](https://github.com/simplex-chat/simplexmq#using-installation-script)
|
||||
|
||||
1. Execute the followin command:
|
||||
|
||||
```sh
|
||||
sudo simplex-servers-update
|
||||
```
|
||||
|
||||
To install specific version, run:
|
||||
|
||||
```sh
|
||||
export VER=<version_from_github_releases> &&\
|
||||
sudo -E simplex-servers-update
|
||||
```
|
||||
|
||||
2. Done!
|
||||
|
||||
- [Docker container](https://github.com/simplex-chat/simplexmq#using-docker)
|
||||
|
||||
1. Stop and remove the container:
|
||||
|
||||
```sh
|
||||
docker rm $(docker stop $(docker ps -a -q --filter ancestor=simplexchat/smp-server --format="\{\{.ID\}\}"))
|
||||
```
|
||||
|
||||
2. Pull latest image:
|
||||
|
||||
```sh
|
||||
docker pull simplexchat/smp-server:latest
|
||||
```
|
||||
|
||||
3. Start new container:
|
||||
|
||||
```sh
|
||||
docker run -d \
|
||||
-p 5223:5223 \
|
||||
-p 443:443 \
|
||||
-v $HOME/simplex/smp/config:/etc/opt/simplex:z \
|
||||
-v $HOME/simplex/smp/logs:/var/opt/simplex:z \
|
||||
simplexchat/smp-server:latest
|
||||
```
|
||||
|
||||
- [Linode Marketplace](https://www.linode.com/marketplace/apps/simplex-chat/simplex-chat/)
|
||||
|
||||
1. Pull latest images:
|
||||
|
||||
```sh
|
||||
docker-compose --project-directory /etc/docker/compose/simplex pull
|
||||
```
|
||||
|
||||
2. Restart the containers:
|
||||
|
||||
```sh
|
||||
docker-compose --project-directory /etc/docker/compose/simplex up -d --remove-orphans
|
||||
```
|
||||
|
||||
3. Remove obsolete images:
|
||||
|
||||
```sh
|
||||
docker image prune
|
||||
```
|
||||
|
||||
## Configuring the app to use the server
|
||||
### Configuring the app to use the server
|
||||
|
||||
To configure the app to use your messaging server copy it's full address, including password, and add it to the app. You have an option to use your server together with preset servers or without them - you can remove or disable them.
|
||||
|
||||
|
|
BIN
docs/SimpleX_Design_Review_2024_Summary_Report_12_08_2024.pdf
Normal file
BIN
docs/SimpleX_Design_Review_2024_Summary_Report_12_08_2024.pdf
Normal file
Binary file not shown.
|
@ -6,7 +6,7 @@ revision: 16.07.2024
|
|||
|
||||
# Transparency Reports
|
||||
|
||||
**Updated**: Jul 16, 2024
|
||||
**Updated**: Oct 14, 2024
|
||||
|
||||
SimpleX Chat Ltd. is a company registered in the UK – it develops communication software enabling users to operate and communicate via SimpleX network, without user profile identifiers of any kind, and without having their data hosted by any network infrastructure operators.
|
||||
|
||||
|
@ -23,6 +23,9 @@ Our objective is to consistently ensure that no user data and absolute minimum o
|
|||
- [Trust in servers](https://github.com/simplex-chat/simplexmq/blob/stable/protocol/overview-tjr.md#trust-in-servers)
|
||||
- [Encryption Primitives Used](https://github.com/simplex-chat/simplexmq/blob/stable/protocol/overview-tjr.md#encryption-primitives-used)
|
||||
- [Threat model](https://github.com/simplex-chat/simplexmq/blob/stable/protocol/overview-tjr.md#threat-model)
|
||||
- Security assessments:
|
||||
- Trail of Bits, SimpleX cryptography and networking, [October 2022](../blog/20221108-simplex-chat-v4.2-security-audit-new-website.md).
|
||||
- Trail of Bits, the cryptographic review of SimpleX protocols design, [July 2024](../blog/20241014-simplex-network-v6-1-security-review-better-calls-user-experience.md).
|
||||
|
||||
Have a more specific question? Reach out to us via [SimpleX Chat](https://simplex.chat/contact#/?v=1&smp=smp%3A%2F%2FPQUV2eL0t7OStZOoAsPEV2QYWt4-xilbakvGUGOItUo%3D%40smp6.simplex.im%2FK1rslx-m5bpXVIdMZg9NLUZ_8JBm8xTt%23%2F%3Fv%3D1%26dh%3DMCowBQYDK2VuAyEALDeVe-sG8mRY22LsXlPgiwTNs9dbiLrNuA7f3ZMAJ2w%253D%26srv%3Dbylepyau3ty4czmn77q4fglvperknl4bi2eb2fdy2bh4jxtf32kf73yd.onion) or via email [chat@simplex.chat](mailto:chat@simplex.chat).
|
||||
|
||||
|
|
|
@ -226,7 +226,7 @@ While introduced members establish connection inside group, inviting member forw
|
|||
|
||||
### Member roles
|
||||
|
||||
Currently members can have one of three roles - `owner`, `admin`, `member` and `observer`. The user that created the group is self-assigned owner role, the new members are assigned role by the member who adds them - only `owner` and `admin` members can add new members; only `owner` members can add members with `owner` role. `Observer` members only receive messages and aren't allowed to send messages.
|
||||
Currently members can have one of four roles - `owner`, `admin`, `member` and `observer`. The user that created the group is self-assigned owner role, the new members are assigned role by the member who adds them - only `owner` and `admin` members can add new members; only `owner` members can add members with `owner` role. `Observer` members only receive messages and aren't allowed to send messages.
|
||||
|
||||
### Messages to manage groups and add members
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
name: simplex-chat
|
||||
version: 6.1.0.9
|
||||
version: 6.1.1.0
|
||||
#synopsis:
|
||||
#description:
|
||||
homepage: https://github.com/simplex-chat/simplex-chat#readme
|
||||
|
|
|
@ -38,6 +38,30 @@
|
|||
</description>
|
||||
|
||||
<releases>
|
||||
<release version="6.1.0" date="2024-10-14">
|
||||
<url type="details">https://simplex.chat/blog/20241014-simplex-network-v6-1-security-review-better-calls-user-experience.html</url>
|
||||
<description>
|
||||
<p>New in v6.1:</p>
|
||||
<p>Better security:</p>
|
||||
<ul>
|
||||
<li>SimpleX protocols reviewed by Trail of Bits.</li>
|
||||
<li>security improvements (don't worry, there is nothing critical there).</li>
|
||||
</ul>
|
||||
<p>Better calls:</p>
|
||||
<ul>
|
||||
<li>you can switch audio and video during the call.</li>
|
||||
<li>share the screen from desktop app.</li>
|
||||
</ul>
|
||||
<p>Better user experience:</p>
|
||||
<ul>
|
||||
<li>switch chat profile for 1-time invitations.</li>
|
||||
<li>customizable message shape.</li>
|
||||
<li>better message dates.</li>
|
||||
<li>forward up to 20 messages at once.</li>
|
||||
<li>delete or moderate up to 200 messages.</li>
|
||||
</ul>
|
||||
</description>
|
||||
</release>
|
||||
<release version="6.0.4" date="2024-08-31">
|
||||
<url type="details">https://simplex.chat/blog/20240814-simplex-chat-vision-funding-v6-private-routing-new-user-experience.html</url>
|
||||
<description>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"https://github.com/simplex-chat/simplexmq.git"."c41bfe831d6d3fdf068f7419cbfed6afa46cb5b5" = "1awqy4srdgcwmjf7q3s9w75w6wp38qk65fza2k3q1a1s2lj6h8w1";
|
||||
"https://github.com/simplex-chat/simplexmq.git"."967afaf802d7ea98480eaf280bfc6f35d4d43f05" = "0k8m07hxfgn8h8pqrfchqd8490fvv1jf8slw8qjp0vxdpxa84n3i";
|
||||
"https://github.com/simplex-chat/hs-socks.git"."a30cc7a79a08d8108316094f8f2f82a0c5e1ac51" = "0yasvnr7g91k76mjkamvzab2kvlb1g5pspjyjn2fr6v83swjhj38";
|
||||
"https://github.com/simplex-chat/direct-sqlcipher.git"."f814ee68b16a9447fbb467ccc8f29bdd3546bfd9" = "1ql13f4kfwkbaq7nygkxgw84213i0zm7c1a8hwvramayxl38dq5d";
|
||||
"https://github.com/simplex-chat/sqlcipher-simple.git"."a46bd361a19376c5211f1058908fc0ae6bf42446" = "1z0r78d8f0812kxbgsm735qf6xx8lvaz27k1a0b4a2m0sshpd5gl";
|
||||
|
|
|
@ -5,7 +5,7 @@ cabal-version: 1.12
|
|||
-- see: https://github.com/sol/hpack
|
||||
|
||||
name: simplex-chat
|
||||
version: 6.1.0.9
|
||||
version: 6.1.1.0
|
||||
category: Web, System, Services, Cryptography
|
||||
homepage: https://github.com/simplex-chat/simplex-chat#readme
|
||||
author: simplex.chat
|
||||
|
|
|
@ -203,8 +203,9 @@ _defaultSMPServers =
|
|||
|
||||
_defaultNtfServers :: [NtfServer]
|
||||
_defaultNtfServers =
|
||||
[ "ntf://KmpZNNXiVZJx_G2T7jRUmDFxWXM3OAnunz3uLT0tqAA=@ntf3.simplex.im,pxculznuryunjdvtvh6s6szmanyadumpbmvevgdpe4wk5c65unyt4yid.onion",
|
||||
"ntf://CJ5o7X6fCxj2FFYRU2KuCo70y4jSqz7td2HYhLnXWbU=@ntf4.simplex.im,wtvuhdj26jwprmomnyfu5wfuq2hjkzfcc72u44vi6gdhrwxldt6xauad.onion"
|
||||
[ "ntf://FB-Uop7RTaZZEG0ZLD2CIaTjsPh-Fw0zFAnb7QyA8Ks=@ntf2.simplex.im,5ex3mupcazy3zlky64ab27phjhijpemsiby33qzq3pliejipbtx5xgad.onion"
|
||||
-- "ntf://KmpZNNXiVZJx_G2T7jRUmDFxWXM3OAnunz3uLT0tqAA=@ntf3.simplex.im,pxculznuryunjdvtvh6s6szmanyadumpbmvevgdpe4wk5c65unyt4yid.onion",
|
||||
-- "ntf://CJ5o7X6fCxj2FFYRU2KuCo70y4jSqz7td2HYhLnXWbU=@ntf4.simplex.im,wtvuhdj26jwprmomnyfu5wfuq2hjkzfcc72u44vi6gdhrwxldt6xauad.onion"
|
||||
]
|
||||
|
||||
maxImageSize :: Integer
|
||||
|
|
|
@ -245,8 +245,7 @@
|
|||
"f-droid-page-f-droid-org-repo-section-text": "مستودعات SimpleX Chat و F-Droid.org مبنية على مفاتيح مختلفة. للتبديل، يُرجى <a href='/docs/guide/chat-profiles.html#move-your-chat-profiles-to-another-device'>تصدير</a> قاعدة بيانات الدردشة وإعادة تثبيت التطبيق.",
|
||||
"comparison-section-list-point-4a": "مُرحلات SimpleX لا يمكنها أن تتنازل عن تعمية بين الطرفين. تحقق من رمز الأمان للتخفيف من الهجوم على القناة خارج النطاق",
|
||||
"hero-overlay-3-title": "التقييم الأمني",
|
||||
"hero-overlay-card-3-p-2": "قامت Trail of Bits بمراجعة مكونات التشفير والشبكات الخاصة بمنصة SimpleX في نوفمبر 2022.",
|
||||
"hero-overlay-card-3-p-3": "اقرأ المزيد في <a href=\"/blog/20221108-simplex-chat-v4.2-security-audit-new-website.html\">الإعلان</a>.",
|
||||
"hero-overlay-card-3-p-2": "قامت Trail of Bits بمراجعة مكونات التشفير والشبكات الخاصة بمنصة SimpleX في نوفمبر 2022. <a href=\"/blog/20221108-simplex-chat-v4.2-security-audit-new-website.html\">اقرأ المزيد في الإعلان</a>.",
|
||||
"jobs": "انضم للفريق",
|
||||
"hero-overlay-3-textlink": "التقييم الأمني",
|
||||
"hero-overlay-card-3-p-1": "<a href=\"https://www.trailofbits.com/about/\">Trail of Bits</a> هي شركة رائدة في مجال الاستشارات الأمنية والتكنولوجية، ومن بين عملائها شركات التكنولوجيا الكبرى والوكالات الحكومية ومشاريع blockchain الكبرى.",
|
||||
|
|
|
@ -250,8 +250,7 @@
|
|||
"stable-versions-built-by-f-droid-org": "Stabilní verze vytvořené F-Droid.org",
|
||||
"releases-to-this-repo-are-done-1-2-days-later": "Vydání v tomto repozitáři se provádí o několik dní později",
|
||||
"jobs": "Připojit k týmu",
|
||||
"hero-overlay-card-3-p-2": "Trail of Bits přezkoumala kryptografii a síťové komponenty SimpleX platformy v listopadu 2022.",
|
||||
"hero-overlay-card-3-p-3": "Přečtěte si více v <a href=\"/blog/20221108-simplex-chat-v4.2-security-audit-new-website.html\">ohlášení</a>.",
|
||||
"hero-overlay-card-3-p-2": "Trail of Bits přezkoumala kryptografii a síťové komponenty SimpleX platformy v listopadu 2022. Přečtěte si více v <a href=\"/blog/20221108-simplex-chat-v4.2-security-audit-new-website.html\">ohlášení</a>.",
|
||||
"docs-dropdown-9": "Ke stažení",
|
||||
"docs-dropdown-10": "Transparentnost",
|
||||
"docs-dropdown-11": "FAQ (často kladené dotazy)",
|
||||
|
|
|
@ -245,8 +245,7 @@
|
|||
"f-droid-page-simplex-chat-repo-section-text": "Um es Ihrem F-Droid-Client hinzuzufügen, <span class='hide-on-mobile'>scannen Sie den QR-Code oder</span> nutzen Sie diese URL:",
|
||||
"comparison-section-list-point-4a": "SimpleX-Relais können die E2E-Verschlüsselung nicht kompromittieren. Überprüfen Sie den Sicherheitscode, um einen möglichen Angriff auf den Out-of-Band-Kanal zu entschärfen",
|
||||
"hero-overlay-3-title": "Sicherheits-Gutachten",
|
||||
"hero-overlay-card-3-p-2": "Trail of Bits untersuchte im November 2022 die kryptografischen und Netzwerk-Komponenten der SimpleX-Plattform.",
|
||||
"hero-overlay-card-3-p-3": "Lesen Sie mehr dazu in der <a href=\"/blog/20221108-simplex-chat-v4.2-security-audit-new-website.html\">Ankündigung</a>.",
|
||||
"hero-overlay-card-3-p-2": "Trail of Bits untersuchte im November 2022 die kryptografischen und Netzwerk-Komponenten der SimpleX-Plattform. Lesen Sie mehr dazu in der <a href=\"/blog/20221108-simplex-chat-v4.2-security-audit-new-website.html\">Ankündigung</a>.",
|
||||
"jobs": "Treten Sie dem Team bei",
|
||||
"hero-overlay-3-textlink": "Sicherheits-Gutachten",
|
||||
"hero-overlay-card-3-p-1": "<a href=\"https://www.trailofbits.com/about/\">Trail of Bits</a> ist eine führende Security- und Technologie-Unternehmensberatung, deren Kunden aus den Bereichen Big-Tech, Regierungsbehörden und großen Blockchain-Projekten stammen.",
|
||||
|
|
|
@ -30,12 +30,12 @@
|
|||
"hero-p-1": "Other apps have user IDs: Signal, Matrix, Session, Briar, Jami, Cwtch, etc.<br> SimpleX does not, <strong>not even random numbers</strong>.<br> This radically improves your privacy.",
|
||||
"hero-overlay-1-textlink": "Why user IDs are bad for privacy?",
|
||||
"hero-overlay-2-textlink": "How does SimpleX work?",
|
||||
"hero-overlay-3-textlink": "Security assessment",
|
||||
"hero-overlay-3-textlink": "Security assessments",
|
||||
"hero-2-header": "Make a private connection",
|
||||
"hero-2-header-desc": "The video shows how you connect to your friend via their 1-time QR-code, in person or via a video link. You can also connect by sharing an invitation link.",
|
||||
"hero-overlay-1-title": "How does SimpleX work?",
|
||||
"hero-overlay-2-title": "Why user IDs are bad for privacy?",
|
||||
"hero-overlay-3-title": "Security assessment",
|
||||
"hero-overlay-3-title": "Security assessments",
|
||||
"feature-1-title": "E2E-encrypted messages with markdown and editing",
|
||||
"feature-2-title": "E2E-encrypted<br>images, videos and files",
|
||||
"feature-3-title": "E2E-encrypted decentralized groups — only users know they exist",
|
||||
|
@ -102,8 +102,8 @@
|
|||
"hero-overlay-card-2-p-3": "Even with the most private apps that use Tor v3 services, if you talk to two different contacts via the same profile they can prove that they are connected to the same person.",
|
||||
"hero-overlay-card-2-p-4": "SimpleX protects against these attacks by not having any user IDs in its design. And, if you use Incognito mode, you will have a different display name for each contact, avoiding any shared data between them.",
|
||||
"hero-overlay-card-3-p-1": "<a href=\"https://www.trailofbits.com/about/\">Trail of Bits</a> is a leading security and technology consultancy whose clients include big tech, governmental agencies and major blockchain projects.",
|
||||
"hero-overlay-card-3-p-2": "Trail of Bits reviewed SimpleX platform cryptography and networking components in November 2022.",
|
||||
"hero-overlay-card-3-p-3": "Read more in <a href=\"/blog/20221108-simplex-chat-v4.2-security-audit-new-website.html\">the announcement</a>.",
|
||||
"hero-overlay-card-3-p-2": "Trail of Bits reviewed SimpleX network cryptography and networking components in November 2022. <a href=\"/blog/20221108-simplex-chat-v4.2-security-audit-new-website.html\">Read more</a>.",
|
||||
"hero-overlay-card-3-p-3": "Trail of Bits reviewed cryptographic design of SimpleX network protocols in July 2024. <a href=\"/blog/20241014-simplex-network-v6-1-security-review-better-calls-user-experience.html\">Read more</a>.",
|
||||
"simplex-network-overlay-card-1-p-1": "<a href='https://en.wikipedia.org/wiki/Peer-to-peer'>P2P</a> messaging protocols and apps have various problems that make them less reliable than SimpleX, more complex to analyse, and vulnerable to several types of attack.",
|
||||
"simplex-network-overlay-card-1-li-1": "P2P networks rely on some variant of <a href='https://en.wikipedia.org/wiki/Distributed_hash_table'>DHT</a> to route messages. DHT designs have to balance delivery guarantee and latency. SimpleX has both better delivery guarantee and lower latency than P2P, because the message can be redundantly passed via several servers in parallel, using the servers chosen by the recipient. In P2P networks the message is passed through <em>O(log N)</em> nodes sequentially, using nodes chosen by the algorithm.",
|
||||
"simplex-network-overlay-card-1-li-2": "SimpleX design, unlike most P2P networks, has no global user identifiers of any kind, even temporary, and only uses temporary pairwise identifiers, providing better anonymity and metadata protection.",
|
||||
|
|
|
@ -245,8 +245,7 @@
|
|||
"releases-to-this-repo-are-done-1-2-days-later": "Las versiones aparecen varios días más tarde en este repositorio",
|
||||
"comparison-section-list-point-4a": "Los servidores de retransmisión no pueden comprometer la encriptación e2e. Para evitar posibles ataques, verifique el código de seguridad mediante un canal alternativo",
|
||||
"hero-overlay-3-title": "Evaluación de la seguridad",
|
||||
"hero-overlay-card-3-p-2": "Trail of Bits revisó la criptografía y los componentes de red de la plataforma SimpleX en noviembre de 2022.",
|
||||
"hero-overlay-card-3-p-3": "Más información en <a href=\"/blog/20221108-simplex-chat-v4.2-security-audit-new-website.html\">la noticia</a>.",
|
||||
"hero-overlay-card-3-p-2": "Trail of Bits revisó la criptografía y los componentes de red de la plataforma SimpleX en noviembre de 2022. <a href=\"/blog/20221108-simplex-chat-v4.2-security-audit-new-website.html\">Más información</a>.",
|
||||
"jobs": "Únete al equipo",
|
||||
"hero-overlay-3-textlink": "Evaluación de la seguridad",
|
||||
"hero-overlay-card-3-p-1": "<a href=\"https://www.trailofbits.com/about/\">Trail of Bits</a> es una consultora de seguridad y tecnología líder cuyos clientes incluyen grandes tecnológicas, agencias gubernamentales e importantes proyectos de blockchain.",
|
||||
|
|
|
@ -249,8 +249,7 @@
|
|||
"hero-overlay-3-title": "Turvallisuuden arviointi",
|
||||
"hero-overlay-card-3-p-1": "<a href=\"https://www.trailofbits.com/about/\">Trail of Bits</a> on johtava turvallisuus- ja teknologiakonsultointiyritys, jonka asiakkaita ovat muun muassa suuret teknologiayritykset, valtion virastot ja suuret lohkoketjuprojektit.",
|
||||
"hero-overlay-3-textlink": "Turvallisuusarviointi",
|
||||
"hero-overlay-card-3-p-2": "Trail of Bits tarkasteli SimpleX-alustan salaus- ja verkkokomponentteja marraskuussa 2022.",
|
||||
"hero-overlay-card-3-p-3": "Lue lisää <a href=\"/blog/20221108-simplex-chat-v4.2-security-audit-new-website.html\">ilmoituksesta</a>.",
|
||||
"hero-overlay-card-3-p-2": "Trail of Bits tarkasteli SimpleX-alustan salaus- ja verkkokomponentteja marraskuussa 2022. Lue lisää <a href=\"/blog/20221108-simplex-chat-v4.2-security-audit-new-website.html\">ilmoituksesta</a>.",
|
||||
"please-enable-javascript": "Ota JavaScript käyttöön nähdäksesi QR-koodin.",
|
||||
"please-use-link-in-mobile-app": "Käytä mobiilisovelluksessa olevaa linkkiä"
|
||||
}
|
|
@ -246,8 +246,7 @@
|
|||
"stable-versions-built-by-f-droid-org": "Versions stables créées par F-Droid.org",
|
||||
"comparison-section-list-point-4a": "Les relais SimpleX ne peuvent pas compromettre le chiffrement e2e. Vérifier le code de sécurité pour limiter les attaques sur le canal hors bande",
|
||||
"hero-overlay-3-title": "Évaluation de sécurité",
|
||||
"hero-overlay-card-3-p-2": "Trail of Bits a examiné les composants cryptographiques et réseau de la plateforme SimpleX en novembre 2022.",
|
||||
"hero-overlay-card-3-p-3": "En savoir plus <a href=\"/blog/20221108-simplex-chat-v4.2-security-audit-new-website.html\">sur l'annonce</a>.",
|
||||
"hero-overlay-card-3-p-2": "Trail of Bits a examiné les composants cryptographiques et réseau de la plateforme SimpleX en novembre 2022. <a href=\"/blog/20221108-simplex-chat-v4.2-security-audit-new-website.html\">En savoir plus</a>.",
|
||||
"jobs": "Rejoignez notre équipe",
|
||||
"hero-overlay-3-textlink": "Évaluation de sécurité",
|
||||
"hero-overlay-card-3-p-1": "<a href=\"https://www.trailofbits.com/about/\">Trail of Bits</a> est un cabinet leader dans le secteur de la sécurité et des technologies qui compte parmi ses clients des grandes entreprises de la tech, des agences gouvernementales et d'importants projets de blockchain.",
|
||||
|
|
|
@ -87,12 +87,11 @@
|
|||
"simplex-unique-1-title": "יש לך פרטיות מלאה",
|
||||
"simplex-private-card-10-point-1": "SimpleX משתמש בכתובות ואישורים אנונימיים זמניים בזוגות עבור כל איש קשר של משתמש או חבר בקבוצה.",
|
||||
"privacy-matters-overlay-card-1-p-1": "הרבה חברות גדולות משתמשות במידע עם מי אתה בקשר כדי להעריך את ההכנסה שלך, למכור לך מוצרים שאתה לא באמת צריך ולקבוע את המחירים.",
|
||||
"hero-overlay-card-3-p-2": "Trail of Bits סקרה את רכיבי ההצפנה והרשת של פלטפורמת SimpleX בנובמבר 2022.",
|
||||
"hero-overlay-card-3-p-2": "Trail of Bits סקרה את רכיבי ההצפנה והרשת של פלטפורמת SimpleX בנובמבר 2022. <a href=\"/blog/20221108-simplex-chat-v4.2-security-audit-new-website.html\">קרא עוד ב הודעה</a>.",
|
||||
"hero-overlay-card-2-p-4": "SimpleX מגן מפני התקפות אלה בכך שאין בעיצובו מזהי משתמש. ואם אתה משתמש במצב זהות נסתרת, יהיה לך שם תצוגה שונה לכל איש קשר, תוך הימנעות מכל מידע משותף ביניהם.",
|
||||
"hero-overlay-card-2-p-1": "כאשר למשתמשים יש זהויות מתמשכות, גם אם זה רק מספר אקראי, כמו מזהה הפעלה, קיים סיכון שהספק או התוקף יוכלו לראות כיצד המשתמשים מחוברים וכמה הודעות הם שולחים.",
|
||||
"hero-overlay-card-1-p-5": "רק מכשירי לקוח מאחסנים פרופילי משתמשים, אנשי קשר וקבוצות; ההודעות נשלחות עם הצפנה דו-שכבתית מקצה לקצה.",
|
||||
"privacy-matters-overlay-card-1-p-2": "קמעונאים מקוונים יודעים שאנשים עם הכנסה נמוכה יותר נוטים יותר לבצע רכישות דחופות, ולכן הם עשויים לגבות מחירים גבוהים יותר או להסיר הנחות.",
|
||||
"hero-overlay-card-3-p-3": "קרא עוד ב<a href=\"/blog/20221108-simplex-chat-v4.2-security-audit-new-website.html\">הודעה</a>.",
|
||||
"hero-overlay-card-1-p-2": "כדי להעביר הודעות, במקום מזהי משתמש המשמשים את כל הפלטפורמות האחרות, SimpleX משתמש במזהים אנונימיים זמניים זוגיים של תורי הודעות, נפרדים עבור כל אחד מהחיבורים שלך — אין מזהים לטווח ארוך.",
|
||||
"hero-overlay-card-2-p-2": "לאחר מכן הם יוכלו לקשר מידע זה עם הרשתות החברתיות הציבוריות הקיימות, ולקבוע כמה זהויות אמיתיות.",
|
||||
"privacy-matters-overlay-card-1-p-3": "חלק מחברות פיננסיות וביטוח משתמשות בגרפים חברתיים כדי לקבוע שיעורי ריבית ופרמיות. לעתים קרובות זה גורם לאנשים עם הכנסה נמוכה יותר לשלם יותר — זה ידוע בתור <a href='https://fairbydesign.com/povertypremium/' target='_blank'>'פרמיית עוני'</a>.",
|
||||
|
|
|
@ -95,7 +95,7 @@
|
|||
"hero-overlay-card-2-p-3": "Még a Tor v3 szolgáltatásokat használó, legprivátabb alkalmazások esetében is, ha két különböző kapcsolattartóval beszél ugyanazon a profilon keresztül, bizonyítani tudják, hogy ugyanahhoz a személyhez kapcsolódnak.",
|
||||
"hero-overlay-card-2-p-4": "A SimpleX úgy védekezik ezen támadások ellen, hogy nem tartalmaz felhasználói azonosítókat. Ha pedig használja az inkognitó módot, akkor minden egyes létrejött kapcsolatban más-más felhasználó név jelenik meg, így elkerülhető a közöttük lévő összefüggések bizonyítása.",
|
||||
"hero-overlay-card-3-p-1": "<a href=\"https://www.trailofbits.com/about/\">Trail of Bits</a> egy vezető biztonsági és technológiai tanácsadó cég, amelynek ügyfelei közé tartoznak a nagy technológiai cégek, kormányzati ügynökségek és jelentős blokklánc projektek.",
|
||||
"hero-overlay-card-3-p-2": "A Trail of Bits 2022 novemberében áttekintette a SimpleX-platform kriptográfiai és hálózati komponenseit.",
|
||||
"hero-overlay-card-3-p-2": "A Trail of Bits 2022 novemberében áttekintette a SimpleX-platform kriptográfiai és hálózati komponenseit. <a href=\"/blog/20221108-simplex-chat-v4.2-security-audit-new-website.html\">További információk</a>.",
|
||||
"simplex-network-overlay-card-1-li-1": "A P2P-hálózatok az üzenetek továbbítására a <a href='https://en.wikipedia.org/wiki/Distributed_hash_table'>DHT</a> valamelyik változatát használják. A DHT kialakításakor egyensúlyt kell teremteni a kézbesítési garancia és a késleltetés között. A SimpleX jobb kézbesítési garanciával és alacsonyabb késleltetéssel rendelkezik, mint a P2P, mivel az üzenet redundánsan, a címzett által kiválasztott kiszolgálók segítségével több kiszolgálón keresztül párhuzamosan továbbítható. A P2P-hálózatokban az üzenet <em>O(log N)</em> csomóponton halad át szekvenciálisan, az algoritmus által kiválasztott csomópontok segítségével.",
|
||||
"simplex-network-overlay-card-1-li-2": "A SimpleX kialakítása a legtöbb P2P-hálózattól eltérően nem rendelkezik semmiféle globális felhasználói azonosítóval, még ideiglenesen sem, és csak ideiglenes páros azonosítókat használ, ami jobb névtelenséget és metaadatvédelmet biztosít.",
|
||||
"simplex-network-overlay-card-1-li-3": "A P2P nem oldja meg a <a href='https://en.wikipedia.org/wiki/Man-in-the-middle_attack'>MITM-támadás</a> problémát, és a legtöbb létező implementáció nem használ sávon kívüli üzeneteket a kezdeti kulcscseréhez. A SimpleX a kezdeti kulcscseréhez sávon kívüli üzeneteket, vagy bizonyos esetekben már meglévő biztonságos és megbízható kapcsolatokat használ.",
|
||||
|
@ -229,7 +229,6 @@
|
|||
"simplex-private-card-5-point-2": "A kiszolgálók és a hálózatot megfigyelők számára a különböző méretű üzenetek egyformának tűnnek.",
|
||||
"privacy-matters-1-title": "Hirdetés és árdiszkrimináció",
|
||||
"hero-overlay-card-1-p-3": "Ön határozza meg, hogy melyik kiszolgáló(ka)t használja az üzenetek fogadására, a kapcsolatokhoz — azokat a kiszolgálókat, amelyeket az üzenetek küldésére használ. Minden beszélgetés két különböző kiszolgálót használ.",
|
||||
"hero-overlay-card-3-p-3": "További információk <a href=\"/blog/20221108-simplex-chat-v4.2-security-audit-new-website.html\">a közleményben</a>.",
|
||||
"simplex-network-overlay-card-1-p-1": "A <a href='https://en.wikipedia.org/wiki/Peer-to-peer'>P2P</a> üzenetküldő protokollok és alkalmazások számos problémával küzdenek, amelyek miatt kevésbé megbízhatóak, mint a SimpleX, bonyolultabb az elemzésük és többféle támadással szemben sebezhetőek.",
|
||||
"chat-bot-example": "Chat bot példa",
|
||||
"simplex-private-3-title": "Biztonságos, hitelesített<br>TLS adatátvitel",
|
||||
|
|
|
@ -245,8 +245,7 @@
|
|||
"f-droid-page-simplex-chat-repo-section-text": "Per aggiungerlo al tuo client F-Droid <span class='hide-on-mobile'>scansiona il codice QR o</span> usa questo URL:",
|
||||
"comparison-section-list-point-4a": "I relay di SimpleX non possono compromettere la crittografia e2e. Verifica il codice di sicurezza per mitigare gli attacchi sul canale fuori banda",
|
||||
"hero-overlay-3-title": "Valutazione della sicurezza",
|
||||
"hero-overlay-card-3-p-2": "Trail of Bits ha revisionato i componenti di crittografia e di rete della piattaforma SimpleX nel novembre 2022.",
|
||||
"hero-overlay-card-3-p-3": "Maggiori informazioni nell'<a href=\"/blog/20221108-simplex-chat-v4.2-security-audit-new-website.html\">annuncio</a>.",
|
||||
"hero-overlay-card-3-p-2": "Trail of Bits ha revisionato i componenti di crittografia e di rete della piattaforma SimpleX nel novembre 2022. <a href=\"/blog/20221108-simplex-chat-v4.2-security-audit-new-website.html\">Maggiori informazioni</a>.",
|
||||
"jobs": "Unisciti al team",
|
||||
"hero-overlay-3-textlink": "Valutazione della sicurezza",
|
||||
"hero-overlay-card-3-p-1": "<a href=\"https://www.trailofbits.com/about/\">Trail of Bits</a> è leader nella consulenza di sicurezza e tecnologia, i cui clienti includono grandi aziende, agenzie governative e importanti progetti di blockchain.",
|
||||
|
|
|
@ -245,11 +245,10 @@
|
|||
"f-droid-page-f-droid-org-repo-section-text": "SimpleX Chat と F-Droid.org リポジトリは、異なるキーを使用してビルドに署名します。 切り替えるには、チャット データベースを<a href='/docs/guide/chat-profiles.html#move-your-chat-profiles-to-another-device'>エクスポート</a>し、アプリを再インストールしてください。",
|
||||
"simplex-private-5-title": "何レイヤーもの<br>コンテンツパディング",
|
||||
"hero-overlay-card-3-p-1": "<a href=\"https://www.trailofbits.com/about/\">Trail of Bits</a>は、大手ハイテク企業、政府機関、主要なブロックチェーン・プロジェクトなどを顧客に持つ、セキュリティとテクノロジーの大手コンサルタント会社です。",
|
||||
"hero-overlay-card-3-p-3": "詳しくは <a href=\"/blog/20221108-simplex-chat-v4.2-security-audit-new-website.html\">お知らせ</a>をご覧ください。",
|
||||
"jobs": "チームに参加する",
|
||||
"hero-overlay-3-textlink": "セキュリティ監査",
|
||||
"hero-overlay-3-title": "セキュリティ監査",
|
||||
"hero-overlay-card-3-p-2": "Trail of Bitsは2022年11月にSimpleXプラットフォームの暗号とネットワークのコンポーネントを検証しました。",
|
||||
"hero-overlay-card-3-p-2": "Trail of Bitsは2022年11月にSimpleXプラットフォームの暗号とネットワークのコンポーネントを検証しました。<a href=\"/blog/20221108-simplex-chat-v4.2-security-audit-new-website.html\">詳しくは お知らせをご覧ください。</a>",
|
||||
"docs-dropdown-9": "ダウンロード",
|
||||
"please-enable-javascript": "QRコードを表示するためにJavaScriptを有効にしてください。",
|
||||
"please-use-link-in-mobile-app": "このリンクをモバイルアプリで使用してください",
|
||||
|
|
|
@ -245,8 +245,7 @@
|
|||
"docs-dropdown-8": "SimpleX Directory Service",
|
||||
"comparison-section-list-point-4a": "SimpleX relais kunnen de e2e-versleuteling niet in gevaar brengen. Controleer de beveiligingscode om aanvallen op out-of-band kanalen te beperken",
|
||||
"hero-overlay-3-title": "Beveiligings beoordeling",
|
||||
"hero-overlay-card-3-p-2": "Trail of Bits heeft in november 2022 de cryptografie en netwerkcomponenten van het SimpleX-platform beoordeeld.",
|
||||
"hero-overlay-card-3-p-3": "Lees meer in <a href=\"/blog/20221108-simplex-chat-v4.2-security-audit-new-website.html\">de aankondiging</a>.",
|
||||
"hero-overlay-card-3-p-2": "Trail of Bits heeft in november 2022 de cryptografie en netwerkcomponenten van het SimpleX-platform beoordeeld. Lees meer in <a href=\"/blog/20221108-simplex-chat-v4.2-security-audit-new-website.html\">de aankondiging</a>.",
|
||||
"jobs": "Sluit je aan bij het team",
|
||||
"hero-overlay-3-textlink": "Beveiligings beoordeling",
|
||||
"hero-overlay-card-3-p-1": "<a href=\"https://www.trailofbits.com/about/\">Trail of Bits</a> is een toonaangevend beveiligings- en technologieadviesbureau met klanten onder meer grote technologiebedrijven, overheidsinstanties en grote blockchain-projecten.",
|
||||
|
|
|
@ -245,8 +245,7 @@
|
|||
"releases-to-this-repo-are-done-1-2-days-later": "Wydania na tym repo są kilka dni później",
|
||||
"comparison-section-list-point-4a": "Przekaźniki SimpleX nie mogą skompromitować szyfrowania e2e. Zweryfikuj kody bezpieczeństwa aby złagodzić atak na kanał pozapasmowy",
|
||||
"hero-overlay-3-title": "Ocena bezpieczeństwa",
|
||||
"hero-overlay-card-3-p-2": "Trail of Bits przejrzał komponenty kryptograficzne i sieciowe platformy SimpleX w listopadzie 2022.",
|
||||
"hero-overlay-card-3-p-3": "Przeczytaj więcej w <a href=\"/blog/20221108-simplex-chat-v4.2-security-audit-new-website.html\">ogłoszeniach</a>.",
|
||||
"hero-overlay-card-3-p-2": "Trail of Bits przejrzał komponenty kryptograficzne i sieciowe platformy SimpleX w listopadzie 2022. Przeczytaj więcej w <a href=\"/blog/20221108-simplex-chat-v4.2-security-audit-new-website.html\">ogłoszeniach</a>.",
|
||||
"jobs": "Dołącz do zespołu",
|
||||
"hero-overlay-3-textlink": "Ocena bezpieczeństwa",
|
||||
"hero-overlay-card-3-p-1": "<a href=\"https://www.trailofbits.com/about/\">Trail of Bits</a> jest wiodącą firmą konsultingową w zakresie bezpieczeństwa i technologii, której klientami są duże firmy technologiczne, agencje rządowe i główne projekty blockchain.",
|
||||
|
|
|
@ -246,8 +246,7 @@
|
|||
"hero-overlay-3-textlink": "Avaliação Segura",
|
||||
"hero-overlay-3-title": "Avaliação Segura",
|
||||
"hero-overlay-card-3-p-1": "<a href=\"https://www.trailofbits.com/about/\">Trail of Bits</a> é uma consultoria líder em segurança e tecnologia cujos clientes incluem grandes empresas de tecnologia, agências governamentais e grandes projetos de blockchain.",
|
||||
"hero-overlay-card-3-p-2": "Trail of Bits analisou a criptografia da plataforma SimpleX e os componentes de rede em novembro de 2022.",
|
||||
"hero-overlay-card-3-p-3": "Leia mais em <a href=\"/blog/20221108-simplex-chat-v4.2-security-audit-new-website.html\">o anúncio</a>.",
|
||||
"hero-overlay-card-3-p-2": "Trail of Bits analisou a criptografia da plataforma SimpleX e os componentes de rede em novembro de 2022. Leia mais em <a href=\"/blog/20221108-simplex-chat-v4.2-security-audit-new-website.html\">o anúncio</a>.",
|
||||
"f-droid-page-f-droid-org-repo-section-text": "Os repositórios SimpleX Chat e F-Droid.org assinam compilações com chaves diferentes. Para mudar, <a href='/docs/guide/chat-profiles.html#move-your-chat-profiles-to-another-device'>exporte</a> o banco de dados de bate-papo e reinstale o aplicativo.",
|
||||
"please-enable-javascript": "Por favor habilite o JavaScript para ver o QR code.",
|
||||
"jobs": "Junte-se à equipe",
|
||||
|
|
|
@ -37,7 +37,8 @@
|
|||
"simplex-explained-tab-1-text": "1. Как это видят пользователи",
|
||||
"tap-to-close": "Нажмите, чтобы закрыть",
|
||||
"simplex-unique-card-4-p-2": "Вы можете <strong>использовать SimpleX со своими собственными серверами</strong> или с серверами, предоставленными нами — и при этом подключаться к любому пользователю SimpleX.",
|
||||
"hero-overlay-card-3-p-2": "В ноябре 2022 года Trail of Bits провела обзор криптографии и сетевых компонентов SimpleX.",
|
||||
"hero-overlay-card-3-p-2": "В ноябре 2022 года Trail of Bits провела обзор криптографии и сетевых компонентов SimpleX. <a href=\"/blog/20221108-simplex-chat-v4.2-security-audit-new-website.html\">Дополнительная информация</a>.",
|
||||
"hero-overlay-card-3-p-3": "В июле 2024 года Trail of Bits провела обзор криптографического дизайна протоколов SimpleX. <a href=\"/blog/20241014-simplex-network-v6-1-security-review-better-calls-user-experience.html\">Дополнительная информация</a>.",
|
||||
"feature-1-title": "Сообщения зашифрованные E2E-шифрованием<br>с поддержкой markdown и редактированием",
|
||||
"comparison-point-4-text": "Единая или Централизованная сеть",
|
||||
"guide-dropdown-9": "Установление соединений",
|
||||
|
@ -77,7 +78,6 @@
|
|||
"simplex-unique-2-overlay-1-title": "Лучшая защита от спама и злоупотреблений",
|
||||
"simplex-private-6-title": "Внеполосный<br>Обмен ключами",
|
||||
"join-us-on-GitHub": "Присоединяйтесь к нам на GitHub",
|
||||
"hero-overlay-card-3-p-3": "Подробнее читайте в <a href=\"/blog/20221108-simplex-chat-v4.2-security-audit-new-website.html\">анонсе</a>.",
|
||||
"comparison-section-header": "Сравнение с другими протоколами",
|
||||
"invitation-hero-header": "Вы получили одноразовую ссылку для подключения в SimpleX Chat",
|
||||
"no-secure": "Нет - безопасно",
|
||||
|
|
|
@ -244,8 +244,7 @@
|
|||
"stable-and-beta-versions-built-by-developers": "Стабільні та бета-версії, побудовані розробниками",
|
||||
"f-droid-page-f-droid-org-repo-section-text": "SimpleX Chat та репозитарії F-Droid.org підписують збірки різними ключами. Щоб переключитися, будь ласка, <a href='/docs/guide/chat-profiles.html#move-your-chat-profiles-to-another-device'>експортуйте</a> базу даних чату та перевстановіть додаток.",
|
||||
"hero-overlay-3-title": "Оцінка безпеки",
|
||||
"hero-overlay-card-3-p-2": "Trail of Bits переглянувало криптографію та компоненти мережі платформи SimpleX у листопаді 2022 року.",
|
||||
"hero-overlay-card-3-p-3": "Читайте більше в <a href=\"/blog/20221108-simplex-chat-v4.2-security-audit-new-website.html\">оголошенні</a>.",
|
||||
"hero-overlay-card-3-p-2": "Trail of Bits переглянувало криптографію та компоненти мережі платформи SimpleX у листопаді 2022 року. Читайте більше в <a href=\"/blog/20221108-simplex-chat-v4.2-security-audit-new-website.html\">оголошенні</a>.",
|
||||
"jobs": "Приєднатися до команди",
|
||||
"hero-overlay-3-textlink": "Оцінка безпеки",
|
||||
"hero-overlay-card-3-p-1": "<a href=\"https://www.trailofbits.com/about/\">Trail of Bits</a> є провідною консалтинговою фірмою з безпеки та технологій, клієнтами якої є великі технологічні компанії, урядові агенції та великі проекти у сфері блокчейну.",
|
||||
|
|
|
@ -245,8 +245,7 @@
|
|||
"docs-dropdown-8": "SimpleX 目录服务",
|
||||
"f-droid-page-f-droid-org-repo-section-text": "SimpleX Chat 和 F-Droid.org 存储库使用不同的密钥对构建进行签名。 如需切换,请<a href='/docs/guide/chat-profiles.html#move-your-chat-profiles-to-another-device'>导出</a>聊天数据库并重新安装应用。",
|
||||
"hero-overlay-3-title": "安全性评估",
|
||||
"hero-overlay-card-3-p-2": "2022年11月份,Trail of Bits 审核了 SimpleX 平台的密码学和网络部件。",
|
||||
"hero-overlay-card-3-p-3": "更多内容见 <a href=\"/blog/20221108-simplex-chat-v4.2-security-audit-new-website.html\">该公告</a>。",
|
||||
"hero-overlay-card-3-p-2": "2022年11月份,Trail of Bits 审核了 SimpleX 平台的密码学和网络部件。<a href=\"/blog/20221108-simplex-chat-v4.2-security-audit-new-website.html\">更多内容见 该公告</a>。",
|
||||
"jobs": "加入团队",
|
||||
"hero-overlay-3-textlink": "安全性评估",
|
||||
"hero-overlay-card-3-p-1": "<a href=\"https://www.trailofbits.com/about/\">Trail of Bits</a> 是一家领先的安全和技术咨询企业,其客户包括大型科技公司、政府机构和重要的区块链项目。",
|
||||
|
|
12
website/src/_includes/blog_previews/20241014.html
Normal file
12
website/src/_includes/blog_previews/20241014.html
Normal file
|
@ -0,0 +1,12 @@
|
|||
<p><strong>New security audit!</strong></p>
|
||||
|
||||
<p class="mb-[12px]">Trail of Bits reviewed the cryptographic design of protocols used in SimpleX network and apps.
|
||||
</p>
|
||||
|
||||
<p><strong>v6.1 is released:</strong></p>
|
||||
|
||||
<ul>
|
||||
<li>Better calls: switch audio and video during the call.</li>
|
||||
<li>Better iOS notifications: improved delivery, reduced traffic usage.</li>
|
||||
<li>Better user experience: switch chat profiles, customizable message shapes, forward up to 20 messages.</li>
|
||||
</ul>
|
4
website/src/_includes/blog_previews/20241016.html
Normal file
4
website/src/_includes/blog_previews/20241016.html
Normal file
|
@ -0,0 +1,4 @@
|
|||
<p>The Wired article by David Gilbert focusing on neo-Nazis moving to SimpleX Chat following the Telegram's changes in
|
||||
privacy policy is biased and misleading. By cherry-picking information from the report by the Institute for
|
||||
Strategic Dialogue (ISD), Wired fails to mention that SimpleX network design prioritizes privacy in order to protect
|
||||
human rights defenders, journalists, and everyday users who value their privacy.</p>
|
Loading…
Add table
Add a link
Reference in a new issue