Merge branch 'stable' into stable-fdroid

This commit is contained in:
Evgeny Poberezkin 2024-10-18 19:21:12 +01:00
commit 854c9c9e99
No known key found for this signature in database
GPG key ID: 494BDDD9A28B577D
71 changed files with 1108 additions and 351 deletions

View file

@ -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. 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 ### 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. **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

View file

@ -233,14 +233,12 @@ You can use SimpleX with your own servers and still communicate with people usin
Recent and important updates: 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) [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) [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) [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) [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). [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). [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). [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. [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. 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.

View file

@ -13,6 +13,7 @@ struct ContentView: View {
@EnvironmentObject var chatModel: ChatModel @EnvironmentObject var chatModel: ChatModel
@ObservedObject var alertManager = AlertManager.shared @ObservedObject var alertManager = AlertManager.shared
@ObservedObject var callController = CallController.shared @ObservedObject var callController = CallController.shared
@ObservedObject var appSheetState = AppSheetState.shared
@Environment(\.colorScheme) var colorScheme @Environment(\.colorScheme) var colorScheme
@EnvironmentObject var theme: AppTheme @EnvironmentObject var theme: AppTheme
@EnvironmentObject var sceneDelegate: SceneDelegate @EnvironmentObject var sceneDelegate: SceneDelegate
@ -250,7 +251,8 @@ struct ContentView: View {
private func mainView() -> some View { private func mainView() -> some View {
ZStack(alignment: .top) { ZStack(alignment: .top) {
ChatListView(activeUserPickerSheet: $chatListUserPickerSheet).privacySensitive(protectScreen) ChatListView(activeUserPickerSheet: $chatListUserPickerSheet)
.redacted(reason: appSheetState.redactionReasons(protectScreen))
.onAppear { .onAppear {
requestNtfAuthorization() requestNtfAuthorization()
// Local Authentication notice is to be shown on next start after onboarding is complete // Local Authentication notice is to be shown on next start after onboarding is complete

View file

@ -147,6 +147,7 @@ final class ChatModel: ObservableObject {
@Published var chatDbEncrypted: Bool? @Published var chatDbEncrypted: Bool?
@Published var chatDbStatus: DBMigrationResult? @Published var chatDbStatus: DBMigrationResult?
@Published var ctrlInitInProgress: Bool = false @Published var ctrlInitInProgress: Bool = false
@Published var notificationResponse: UNNotificationResponse?
// local authentication // local authentication
@Published var contentViewAccessAuthenticated: Bool = false @Published var contentViewAccessAuthenticated: Bool = false
@Published var laRequest: LocalAuthRequest? @Published var laRequest: LocalAuthRequest?

View file

@ -29,17 +29,33 @@ class NtfManager: NSObject, UNUserNotificationCenterDelegate, ObservableObject {
private var granted = false private var granted = false
private var prevNtfTime: Dictionary<ChatId, Date> = [:] private var prevNtfTime: Dictionary<ChatId, Date> = [:]
override init() {
super.init()
UNUserNotificationCenter.current().delegate = self
}
// Handle notification when app is in background // Handle notification when app is in background
func userNotificationCenter(_ center: UNUserNotificationCenter, func userNotificationCenter(_ center: UNUserNotificationCenter,
didReceive response: UNNotificationResponse, didReceive response: UNNotificationResponse,
withCompletionHandler handler: () -> Void) { withCompletionHandler handler: () -> Void) {
logger.debug("NtfManager.userNotificationCenter: didReceive") 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 chatModel = ChatModel.shared
let action = response.actionIdentifier let content = ntfResponse.notification.request.content
logger.debug("NtfManager.userNotificationCenter: didReceive: action \(action), categoryIdentifier \(content.categoryIdentifier)") let action = ntfResponse.actionIdentifier
logger.debug("NtfManager.processNotificationResponse: didReceive: action \(action), categoryIdentifier \(content.categoryIdentifier)")
if let userId = content.userInfo["userId"] as? Int64, if let userId = content.userInfo["userId"] as? Int64,
userId != chatModel.currentUser?.userId { userId != chatModel.currentUser?.userId {
logger.debug("NtfManager.processNotificationResponse changeActiveUser")
changeActiveUser(userId, viewPwd: nil) changeActiveUser(userId, viewPwd: nil)
} }
if content.categoryIdentifier == ntfCategoryContactRequest && (action == ntfActionAcceptContact || action == ntfActionAcceptContactIncognito), if content.categoryIdentifier == ntfCategoryContactRequest && (action == ntfActionAcceptContact || action == ntfActionAcceptContactIncognito),
@ -61,7 +77,6 @@ class NtfManager: NSObject, UNUserNotificationCenterDelegate, ObservableObject {
ItemsModel.shared.loadOpenChat(chatId) ItemsModel.shared.loadOpenChat(chatId)
} }
} }
handler()
} }
private func ntfCallAction(_ content: UNNotificationContent, _ action: String) -> (ChatId, NtfCallAction)? { private func ntfCallAction(_ content: UNNotificationContent, _ action: String) -> (ChatId, NtfCallAction)? {
@ -76,7 +91,6 @@ class NtfManager: NSObject, UNUserNotificationCenterDelegate, ObservableObject {
return nil return nil
} }
// Handle notification when the app is in foreground // Handle notification when the app is in foreground
func userNotificationCenter(_ center: UNUserNotificationCenter, func userNotificationCenter(_ center: UNUserNotificationCenter,
willPresent notification: UNNotification, willPresent notification: UNNotification,
@ -210,7 +224,6 @@ class NtfManager: NSObject, UNUserNotificationCenterDelegate, ObservableObject {
} }
} }
} }
center.delegate = self
} }
func notifyContactRequest(_ user: any UserLike, _ contactRequest: UserContactRequest) { func notifyContactRequest(_ user: any UserLike, _ contactRequest: UserContactRequest) {

View file

@ -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." 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) 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))): case let .chatCmdError(_, .errorAgent(.INTERNAL(internalErr))):
if internalErr == "SEUniqueID" { if internalErr == "SEUniqueID" {
let alert = mkAlert( let alert = mkAlert(

View file

@ -82,11 +82,17 @@ struct SimpleXApp: App {
if appState != .stopped { if appState != .stopped {
startChatAndActivate { startChatAndActivate {
if appState.inactive && chatModel.chatRunning == true { if chatModel.chatRunning == true {
Task { if let ntfResponse = chatModel.notificationResponse {
await updateChats() chatModel.notificationResponse = nil
if !chatModel.showCallView && !CallController.shared.hasActiveCalls() { NtfManager.shared.processNotificationResponse(ntfResponse)
await updateCallInvitations() }
if appState.inactive {
Task {
await updateChats()
if !chatModel.showCallView && !CallController.shared.hasActiveCalls() {
await updateCallInvitations()
}
} }
} }
} }

View file

@ -11,11 +11,11 @@ import SimpleXChat
struct CIChatFeatureView: View { struct CIChatFeatureView: View {
@EnvironmentObject var m: ChatModel @EnvironmentObject var m: ChatModel
@Environment(\.revealed) var revealed: Bool
@ObservedObject var im = ItemsModel.shared @ObservedObject var im = ItemsModel.shared
@ObservedObject var chat: Chat @ObservedObject var chat: Chat
@EnvironmentObject var theme: AppTheme @EnvironmentObject var theme: AppTheme
var chatItem: ChatItem var chatItem: ChatItem
@Binding var revealed: Bool
var feature: Feature var feature: Feature
var icon: String? = nil var icon: String? = nil
var iconColor: Color var iconColor: Color
@ -106,6 +106,9 @@ struct CIChatFeatureView: View {
struct CIChatFeatureView_Previews: PreviewProvider { struct CIChatFeatureView_Previews: PreviewProvider {
static var previews: some View { static var previews: some View {
let enabled = FeatureEnabled(forUser: false, forContact: false) 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)
} }
} }

View file

@ -285,17 +285,18 @@ struct CIFileView_Previews: PreviewProvider {
file: nil file: nil
) )
Group { Group {
ChatItemView(chat: Chat.sampleData, chatItem: sentFile, revealed: Binding.constant(false)) ChatItemView(chat: Chat.sampleData, chatItem: sentFile)
ChatItemView(chat: Chat.sampleData, chatItem: ChatItem.getFileMsgContentSample(), revealed: Binding.constant(false)) ChatItemView(chat: Chat.sampleData, chatItem: ChatItem.getFileMsgContentSample())
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(fileName: "some_long_file_name_here", fileStatus: .rcvInvitation))
ChatItemView(chat: Chat.sampleData, chatItem: ChatItem.getFileMsgContentSample(fileStatus: .rcvAccepted), revealed: Binding.constant(false)) ChatItemView(chat: Chat.sampleData, chatItem: ChatItem.getFileMsgContentSample(fileStatus: .rcvAccepted))
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: .rcvTransfer(rcvProgress: 7, rcvTotal: 10)))
ChatItemView(chat: Chat.sampleData, chatItem: ChatItem.getFileMsgContentSample(fileStatus: .rcvCancelled), revealed: Binding.constant(false)) ChatItemView(chat: Chat.sampleData, chatItem: ChatItem.getFileMsgContentSample(fileStatus: .rcvCancelled))
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(fileSize: 1_000_000_000, fileStatus: .rcvInvitation))
ChatItemView(chat: Chat.sampleData, chatItem: ChatItem.getFileMsgContentSample(text: "Hello there", fileStatus: .rcvInvitation), revealed: Binding.constant(false)) 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), 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))
ChatItemView(chat: Chat.sampleData, chatItem: fileChatItemWtFile, revealed: Binding.constant(false)) ChatItemView(chat: Chat.sampleData, chatItem: fileChatItemWtFile)
} }
.environment(\.revealed, false)
.previewLayout(.fixed(width: 360, height: 360)) .previewLayout(.fixed(width: 360, height: 360))
} }
} }

View file

@ -510,10 +510,10 @@ struct CIVoiceView_Previews: PreviewProvider {
duration: 30, duration: 30,
allowMenu: Binding.constant(true) allowMenu: Binding.constant(true)
) )
ChatItemView(chat: Chat.sampleData, chatItem: sentVoiceMessage, revealed: Binding.constant(false), allowMenu: .constant(true)) ChatItemView(chat: Chat.sampleData, chatItem: sentVoiceMessage, allowMenu: .constant(true))
ChatItemView(chat: Chat.sampleData, chatItem: ChatItem.getVoiceMsgContentSample(), revealed: Binding.constant(false), 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)), revealed: Binding.constant(false), 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, revealed: Binding.constant(false), allowMenu: .constant(true)) ChatItemView(chat: Chat.sampleData, chatItem: voiceMessageWtFile, allowMenu: .constant(true))
} }
.previewLayout(.fixed(width: 360, height: 360)) .previewLayout(.fixed(width: 360, height: 360))
} }

View file

@ -92,12 +92,13 @@ struct FramedCIVoiceView_Previews: PreviewProvider {
file: CIFile.getSample(fileStatus: .sndComplete) file: CIFile.getSample(fileStatus: .sndComplete)
) )
Group { Group {
ChatItemView(chat: Chat.sampleData, chatItem: sentVoiceMessage, revealed: Binding.constant(false)) ChatItemView(chat: Chat.sampleData, chatItem: sentVoiceMessage)
ChatItemView(chat: Chat.sampleData, chatItem: ChatItem.getVoiceMsgContentSample(text: "Hello there"), revealed: Binding.constant(false)) 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)), revealed: Binding.constant(false)) 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."), 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."))
ChatItemView(chat: Chat.sampleData, chatItem: voiceMessageWithQuote, revealed: Binding.constant(false)) ChatItemView(chat: Chat.sampleData, chatItem: voiceMessageWithQuote)
} }
.environment(\.revealed, false)
.previewLayout(.fixed(width: 360, height: 360)) .previewLayout(.fixed(width: 360, height: 360))
} }
} }

File diff suppressed because one or more lines are too long

View file

@ -12,9 +12,9 @@ import SimpleXChat
struct MarkedDeletedItemView: View { struct MarkedDeletedItemView: View {
@EnvironmentObject var m: ChatModel @EnvironmentObject var m: ChatModel
@EnvironmentObject var theme: AppTheme @EnvironmentObject var theme: AppTheme
@Environment(\.revealed) var revealed: Bool
@ObservedObject var chat: Chat @ObservedObject var chat: Chat
var chatItem: ChatItem var chatItem: ChatItem
@Binding var revealed: Bool
var body: some View { var body: some View {
(Text(mergedMarkedDeletedText).italic() + Text(" ") + chatItem.timestampText) (Text(mergedMarkedDeletedText).italic() + Text(" ") + chatItem.timestampText)
@ -79,7 +79,10 @@ struct MarkedDeletedItemView: View {
struct MarkedDeletedItemView_Previews: PreviewProvider { struct MarkedDeletedItemView_Previews: PreviewProvider {
static var previews: some View { static var previews: some View {
Group { 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)) .previewLayout(.fixed(width: 360, height: 200))
} }

View file

@ -14,19 +14,28 @@ extension EnvironmentValues {
static let defaultValue: Bool = true static let defaultValue: Bool = true
} }
struct Revealed: EnvironmentKey {
static let defaultValue: Bool = true
}
var showTimestamp: Bool { var showTimestamp: Bool {
get { self[ShowTimestamp.self] } get { self[ShowTimestamp.self] }
set { self[ShowTimestamp.self] = newValue } set { self[ShowTimestamp.self] = newValue }
} }
var revealed: Bool {
get { self[Revealed.self] }
set { self[Revealed.self] = newValue }
}
} }
struct ChatItemView: View { struct ChatItemView: View {
@ObservedObject var chat: Chat @ObservedObject var chat: Chat
@EnvironmentObject var theme: AppTheme @EnvironmentObject var theme: AppTheme
@Environment(\.showTimestamp) var showTimestamp: Bool @Environment(\.showTimestamp) var showTimestamp: Bool
@Environment(\.revealed) var revealed: Bool
var chatItem: ChatItem var chatItem: ChatItem
var maxWidth: CGFloat = .infinity var maxWidth: CGFloat = .infinity
@Binding var revealed: Bool
@Binding var allowMenu: Bool @Binding var allowMenu: Bool
init( init(
@ -34,27 +43,25 @@ struct ChatItemView: View {
chatItem: ChatItem, chatItem: ChatItem,
showMember: Bool = false, showMember: Bool = false,
maxWidth: CGFloat = .infinity, maxWidth: CGFloat = .infinity,
revealed: Binding<Bool>,
allowMenu: Binding<Bool> = .constant(false) allowMenu: Binding<Bool> = .constant(false)
) { ) {
self.chat = chat self.chat = chat
self.chatItem = chatItem self.chatItem = chatItem
self.maxWidth = maxWidth self.maxWidth = maxWidth
_revealed = revealed
_allowMenu = allowMenu _allowMenu = allowMenu
} }
var body: some View { var body: some View {
let ci = chatItem let ci = chatItem
if chatItem.meta.itemDeleted != nil && (!revealed || chatItem.isDeletedContent) { 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 { } 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) { if let mc = ci.content.msgContent, mc.isText && isShortEmoji(ci.content.text) {
EmojiItemView(chat: chat, chatItem: ci) EmojiItemView(chat: chat, chatItem: ci)
} else if ci.content.text.isEmpty, case let .voice(_, duration) = ci.content.msgContent { } 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) CIVoiceView(chat: chat, chatItem: ci, recordingFile: ci.file, duration: duration, allowMenu: $allowMenu)
} else if ci.content.msgContent == nil { } 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 { } else {
framedItemView() framedItemView()
} }
@ -84,7 +91,6 @@ struct ChatItemView: View {
chat: chat, chat: chat,
chatItem: chatItem, chatItem: chatItem,
preview: preview, preview: preview,
revealed: $revealed,
maxWidth: maxWidth, maxWidth: maxWidth,
imgWidth: adjustedMaxWidth, imgWidth: adjustedMaxWidth,
videoWidth: adjustedMaxWidth, videoWidth: adjustedMaxWidth,
@ -96,9 +102,9 @@ struct ChatItemView: View {
struct ChatItemContentView<Content: View>: View { struct ChatItemContentView<Content: View>: View {
@EnvironmentObject var chatModel: ChatModel @EnvironmentObject var chatModel: ChatModel
@EnvironmentObject var theme: AppTheme @EnvironmentObject var theme: AppTheme
@Environment(\.revealed) var revealed: Bool
@ObservedObject var chat: Chat @ObservedObject var chat: Chat
var chatItem: ChatItem var chatItem: ChatItem
@Binding var revealed: Bool
var msgContentView: () -> Content var msgContentView: () -> Content
@AppStorage(DEFAULT_DEVELOPER_TOOLS) private var developerTools = false @AppStorage(DEFAULT_DEVELOPER_TOOLS) private var developerTools = false
@ -130,7 +136,7 @@ struct ChatItemContentView<Content: View>: View {
case let .rcvChatPreference(feature, allowed, param): case let .rcvChatPreference(feature, allowed, param):
CIFeaturePreferenceView(chat: chat, chatItem: chatItem, feature: feature, allowed: allowed, param: param) CIFeaturePreferenceView(chat: chat, chatItem: chatItem, feature: feature, allowed: allowed, param: param)
case let .sndChatPreference(feature, _, _): 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 .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 .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) 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 { 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? { private var mergedGroupEventText: Text? {
@ -238,16 +244,17 @@ func chatEventText(_ ci: ChatItem, _ secondaryColor: Color) -> Text {
struct ChatItemView_Previews: PreviewProvider { struct ChatItemView_Previews: PreviewProvider {
static var previews: some View { static var previews: some View {
Group{ Group{
ChatItemView(chat: Chat.sampleData, chatItem: ChatItem.getSample(1, .directSnd, .now, "hello"), revealed: Binding.constant(false)) ChatItemView(chat: Chat.sampleData, chatItem: ChatItem.getSample(1, .directSnd, .now, "hello"))
ChatItemView(chat: Chat.sampleData, chatItem: ChatItem.getSample(2, .directRcv, .now, "hello there too"), revealed: Binding.constant(false)) ChatItemView(chat: Chat.sampleData, chatItem: ChatItem.getSample(2, .directRcv, .now, "hello there too"))
ChatItemView(chat: Chat.sampleData, chatItem: ChatItem.getSample(1, .directSnd, .now, "🙂"), revealed: Binding.constant(false)) ChatItemView(chat: Chat.sampleData, chatItem: ChatItem.getSample(1, .directSnd, .now, "🙂"))
ChatItemView(chat: Chat.sampleData, chatItem: ChatItem.getSample(2, .directRcv, .now, "🙂🙂🙂🙂🙂"), revealed: Binding.constant(false)) ChatItemView(chat: Chat.sampleData, chatItem: ChatItem.getSample(2, .directRcv, .now, "🙂🙂🙂🙂🙂"))
ChatItemView(chat: Chat.sampleData, chatItem: ChatItem.getSample(2, .directRcv, .now, "🙂🙂🙂🙂🙂🙂"), revealed: Binding.constant(false)) ChatItemView(chat: Chat.sampleData, chatItem: ChatItem.getSample(2, .directRcv, .now, "🙂🙂🙂🙂🙂🙂"))
ChatItemView(chat: Chat.sampleData, chatItem: ChatItem.getDeletedContentSample(), revealed: Binding.constant(false)) 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)), revealed: Binding.constant(false)) 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), revealed: Binding.constant(true)) 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), revealed: Binding.constant(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)) .previewLayout(.fixed(width: 360, height: 70))
.environmentObject(Chat.sampleData) .environmentObject(Chat.sampleData)
} }
@ -265,8 +272,7 @@ struct ChatItemView_NonMsgContentDeleted_Previews: PreviewProvider {
content: .rcvIntegrityError(msgError: .msgSkipped(fromMsgId: 1, toMsgId: 2)), content: .rcvIntegrityError(msgError: .msgSkipped(fromMsgId: 1, toMsgId: 2)),
quotedItem: nil, quotedItem: nil,
file: nil file: nil
), )
revealed: Binding.constant(true)
) )
ChatItemView( ChatItemView(
chat: Chat.sampleData, chat: Chat.sampleData,
@ -276,8 +282,7 @@ struct ChatItemView_NonMsgContentDeleted_Previews: PreviewProvider {
content: .rcvDecryptionError(msgDecryptError: .ratchetHeader, msgCount: 2), content: .rcvDecryptionError(msgDecryptError: .ratchetHeader, msgCount: 2),
quotedItem: nil, quotedItem: nil,
file: nil file: nil
), )
revealed: Binding.constant(true)
) )
ChatItemView( ChatItemView(
chat: Chat.sampleData, chat: Chat.sampleData,
@ -287,8 +292,7 @@ struct ChatItemView_NonMsgContentDeleted_Previews: PreviewProvider {
content: .rcvGroupInvitation(groupInvitation: CIGroupInvitation.getSample(status: .pending), memberRole: .admin), content: .rcvGroupInvitation(groupInvitation: CIGroupInvitation.getSample(status: .pending), memberRole: .admin),
quotedItem: nil, quotedItem: nil,
file: nil file: nil
), )
revealed: Binding.constant(true)
) )
ChatItemView( ChatItemView(
chat: Chat.sampleData, chat: Chat.sampleData,
@ -298,8 +302,7 @@ struct ChatItemView_NonMsgContentDeleted_Previews: PreviewProvider {
content: .rcvGroupEvent(rcvGroupEvent: .memberAdded(groupMemberId: 1, profile: Profile.sampleData)), content: .rcvGroupEvent(rcvGroupEvent: .memberAdded(groupMemberId: 1, profile: Profile.sampleData)),
quotedItem: nil, quotedItem: nil,
file: nil file: nil
), )
revealed: Binding.constant(true)
) )
ChatItemView( ChatItemView(
chat: Chat.sampleData, chat: Chat.sampleData,
@ -309,10 +312,10 @@ struct ChatItemView_NonMsgContentDeleted_Previews: PreviewProvider {
content: ciFeatureContent, content: ciFeatureContent,
quotedItem: nil, quotedItem: nil,
file: nil file: nil
), )
revealed: Binding.constant(true)
) )
} }
.environment(\.revealed, true)
.previewLayout(.fixed(width: 360, height: 70)) .previewLayout(.fixed(width: 360, height: 70))
.environmentObject(Chat.sampleData) .environmentObject(Chat.sampleData)
} }

View file

@ -1183,9 +1183,9 @@ struct ChatView: View {
chat: chat, chat: chat,
chatItem: ci, chatItem: ci,
maxWidth: maxWidth, maxWidth: maxWidth,
revealed: .constant(revealed),
allowMenu: $allowMenu allowMenu: $allowMenu
) )
.environment(\.revealed, revealed)
.environment(\.showTimestamp, itemSeparation.timestamp) .environment(\.showTimestamp, itemSeparation.timestamp)
.modifier(ChatItemClipped(ci, tailVisible: itemSeparation.largeGap && (ci.meta.itemDeleted == nil || revealed))) .modifier(ChatItemClipped(ci, tailVisible: itemSeparation.largeGap && (ci.meta.itemDeleted == nil || revealed)))
.contextMenu { menu(ci, range, live: composeState.liveMessage != nil) } .contextMenu { menu(ci, range, live: composeState.liveMessage != nil) }

View file

@ -287,8 +287,8 @@ struct ComposeView: View {
// this is a workaround to fire an explicit event in certain cases // this is a workaround to fire an explicit event in certain cases
@State private var stopPlayback: Bool = false @State private var stopPlayback: Bool = false
@AppStorage(DEFAULT_PRIVACY_SAVE_LAST_DRAFT) private var saveLastDraft = true @UserDefault(DEFAULT_PRIVACY_SAVE_LAST_DRAFT) private var saveLastDraft = true
@AppStorage(DEFAULT_TOOLBAR_MATERIAL) private var toolbarMaterial = ToolbarMaterial.defaultMaterial @UserDefault(DEFAULT_TOOLBAR_MATERIAL) private var toolbarMaterial = ToolbarMaterial.defaultMaterial
var body: some View { var body: some View {
VStack(spacing: 0) { VStack(spacing: 0) {

View file

@ -40,7 +40,7 @@ struct SendMessageView: View {
@State private var showCustomTimePicker = false @State private var showCustomTimePicker = false
@State private var selectedDisappearingMessageTime: Int? = customDisappearingMessageTimeDefault.get() @State private var selectedDisappearingMessageTime: Int? = customDisappearingMessageTimeDefault.get()
@State private var progressByTimeout = false @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 { var body: some View {
ZStack { ZStack {

View file

@ -78,7 +78,7 @@ struct ReverseList<Content: View>: UIViewControllerRepresentable {
self.dataSource = UITableViewDiffableDataSource<Section, ChatItem>( self.dataSource = UITableViewDiffableDataSource<Section, ChatItem>(
tableView: tableView tableView: tableView
) { (tableView, indexPath, item) -> UITableViewCell? in ) { (tableView, indexPath, item) -> UITableViewCell? in
if indexPath.item > self.itemCount - 8, self.itemCount > 8 { if indexPath.item > self.itemCount - 8 {
self.representer.loadPage() self.representer.loadPage()
} }
let cell = tableView.dequeueReusableCell(withIdentifier: cellReuseId, for: indexPath) let cell = tableView.dequeueReusableCell(withIdentifier: cellReuseId, for: indexPath)

View file

@ -121,9 +121,11 @@ struct ChatListView: View {
UserPicker(userPickerShown: $userPickerShown, activeSheet: $activeUserPickerSheet) UserPicker(userPickerShown: $userPickerShown, activeSheet: $activeUserPickerSheet)
} }
) )
.sheet(item: $activeUserPickerSheet) { .appSheet(
UserPickerSheetView(sheet: $0) item: $activeUserPickerSheet,
} onDismiss: { chatModel.laRequest = nil },
content: { UserPickerSheetView(sheet: $0) }
)
.onChange(of: activeUserPickerSheet) { .onChange(of: activeUserPickerSheet) {
if $0 != nil { if $0 != nil {
DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) { DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {

View file

@ -11,6 +11,12 @@ import SwiftUI
class AppSheetState: ObservableObject { class AppSheetState: ObservableObject {
static let shared = AppSheetState() static let shared = AppSheetState()
@Published var scenePhaseActive: Bool = false @Published var scenePhaseActive: Bool = false
func redactionReasons(_ protectScreen: Bool) -> RedactionReasons {
!protectScreen || scenePhaseActive
? RedactionReasons()
: RedactionReasons.placeholder
}
} }
private struct PrivacySensitive: ViewModifier { private struct PrivacySensitive: ViewModifier {
@ -19,11 +25,7 @@ private struct PrivacySensitive: ViewModifier {
@ObservedObject var appSheetState: AppSheetState = AppSheetState.shared @ObservedObject var appSheetState: AppSheetState = AppSheetState.shared
func body(content: Content) -> some View { func body(content: Content) -> some View {
if !protectScreen { content.redacted(reason: appSheetState.redactionReasons(protectScreen))
content
} else {
content.privacySensitive(!appSheetState.scenePhaseActive).redacted(reason: .privacy)
}
} }
} }

View file

@ -16,6 +16,7 @@ struct UserWallpaperEditor: View {
@State var themeModeOverride: ThemeModeOverride @State var themeModeOverride: ThemeModeOverride
@State var applyToMode: DefaultThemeMode? @State var applyToMode: DefaultThemeMode?
@State var showMore: Bool = false @State var showMore: Bool = false
@State var showFileImporter: Bool = false
@Binding var globalThemeUsed: Bool @Binding var globalThemeUsed: Bool
var save: (DefaultThemeMode?, ThemeModeOverride?) async -> Void var save: (DefaultThemeMode?, ThemeModeOverride?) async -> Void
@ -125,24 +126,27 @@ struct UserWallpaperEditor: View {
CustomizeThemeColorsSection(editColor: { name in editColor(name, theme) }) 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)
let importedFromString = imported.wallpaper?.importFromString()
let importedType = importedFromString?.toAppWallpaper().type
let currentTheme = ThemeManager.currentColors(nil, nil, nil, themeOverridesDefault.get())
let type: WallpaperType? = if importedType?.sameType(currentTheme.wallpaper.type) == true { nil } else { importedType }
let colors = ThemeManager.currentThemeOverridesForExport(type, nil, nil).colors
let res = ThemeModeOverride(mode: imported.base.mode, colors: imported.colors, wallpaper: importedFromString).removeSameColors(imported.base, colorsToCompare: colors)
Task {
await MainActor.run {
themeModeOverride = res
}
await save(applyToMode, res)
}
}
} else { } else {
AdvancedSettingsButton(theme.colors.primary) { showMore = true } 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())
let type: WallpaperType? = if importedType?.sameType(currentTheme.wallpaper.type) == true { nil } else { importedType }
let colors = ThemeManager.currentThemeOverridesForExport(type, nil, nil).colors
let res = ThemeModeOverride(mode: imported.base.mode, colors: imported.colors, wallpaper: importedFromString).removeSameColors(imported.base, colorsToCompare: colors)
Task {
await MainActor.run {
themeModeOverride = res
}
await save(applyToMode, res)
}
}
)
} }
private func onTypeCopyFromSameTheme(_ type: WallpaperType?) -> Bool { private func onTypeCopyFromSameTheme(_ type: WallpaperType?) -> Bool {
@ -216,6 +220,7 @@ struct ChatWallpaperEditor: View {
@State var themeModeOverride: ThemeModeOverride @State var themeModeOverride: ThemeModeOverride
@State var applyToMode: DefaultThemeMode? @State var applyToMode: DefaultThemeMode?
@State var showMore: Bool = false @State var showMore: Bool = false
@State var showFileImporter: Bool = false
@Binding var globalThemeUsed: Bool @Binding var globalThemeUsed: Bool
var save: (DefaultThemeMode?, ThemeModeOverride?) async -> Void var save: (DefaultThemeMode?, ThemeModeOverride?) async -> Void
@ -328,24 +333,27 @@ struct ChatWallpaperEditor: View {
CustomizeThemeColorsSection(editColor: editColor) CustomizeThemeColorsSection(editColor: editColor)
ImportExportThemeSection(perChat: themeModeOverride, perUser: ChatModel.shared.currentUser?.uiThemes) { imported in ImportExportThemeSection(showFileImporter: $showFileImporter, perChat: themeModeOverride, perUser: ChatModel.shared.currentUser?.uiThemes)
let importedFromString = imported.wallpaper?.importFromString()
let importedType = importedFromString?.toAppWallpaper().type
let currentTheme = ThemeManager.currentColors(nil, nil, ChatModel.shared.currentUser?.uiThemes, themeOverridesDefault.get())
let type: WallpaperType? = if importedType?.sameType(currentTheme.wallpaper.type) == true { nil } else { importedType }
let colors = ThemeManager.currentThemeOverridesForExport(type, nil, ChatModel.shared.currentUser?.uiThemes).colors
let res = ThemeModeOverride(mode: imported.base.mode, colors: imported.colors, wallpaper: importedFromString).removeSameColors(imported.base, colorsToCompare: colors)
Task {
await MainActor.run {
themeModeOverride = res
}
await save(applyToMode, res)
}
}
} else { } else {
AdvancedSettingsButton(theme.colors.primary) { showMore = true } 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())
let type: WallpaperType? = if importedType?.sameType(currentTheme.wallpaper.type) == true { nil } else { importedType }
let colors = ThemeManager.currentThemeOverridesForExport(type, nil, ChatModel.shared.currentUser?.uiThemes).colors
let res = ThemeModeOverride(mode: imported.base.mode, colors: imported.colors, wallpaper: importedFromString).removeSameColors(imported.base, colorsToCompare: colors)
Task {
await MainActor.run {
themeModeOverride = res
}
await save(applyToMode, res)
}
}
)
} }
private func onTypeCopyFromSameTheme(_ type: WallpaperType?) -> Bool { private func onTypeCopyFromSameTheme(_ type: WallpaperType?) -> Bool {

View 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) }
}

View file

@ -105,7 +105,12 @@ struct TerminalView: View {
} }
} }
.navigationViewStyle(.stack) .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()) .modifier(ThemedBackground())
} }

View file

@ -367,13 +367,13 @@ struct ChatThemePreview: View {
let alice = ChatItem.getSample(1, CIDirection.directRcv, Date.now, NSLocalizedString("Good afternoon!", comment: "message preview")) 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)) 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 { HStack {
ChatItemView(chat: Chat.sampleData, chatItem: alice, revealed: Binding.constant(false)) ChatItemView(chat: Chat.sampleData, chatItem: alice)
.modifier(ChatItemClipped(alice, tailVisible: true)) .modifier(ChatItemClipped(alice, tailVisible: true))
Spacer() Spacer()
} }
HStack { HStack {
Spacer() Spacer()
ChatItemView(chat: Chat.sampleData, chatItem: bob, revealed: Binding.constant(false)) ChatItemView(chat: Chat.sampleData, chatItem: bob)
.modifier(ChatItemClipped(bob, tailVisible: true)) .modifier(ChatItemClipped(bob, tailVisible: true))
.frame(alignment: .trailing) .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) ThemeManager.saveAndApplyThemeOverrides(theme)
saveThemeToDatabase(nil) saveThemeToDatabase(nil)
}) }
} )
/// When changing app theme, user overrides are hidden. User overrides will be returned back after closing Appearance screen, see ThemeDestinationPicker() /// When changing app theme, user overrides are hidden. User overrides will be returned back after closing Appearance screen, see ThemeDestinationPicker()
.interactiveDismissDisabled(true) .interactiveDismissDisabled(true)
} }
@ -595,10 +598,9 @@ struct CustomizeThemeView: View {
struct ImportExportThemeSection: View { struct ImportExportThemeSection: View {
@EnvironmentObject var theme: AppTheme @EnvironmentObject var theme: AppTheme
@Binding var showFileImporter: Bool
var perChat: ThemeModeOverride? var perChat: ThemeModeOverride?
var perUser: ThemeModeOverrides? var perUser: ThemeModeOverrides?
var save: (ThemeOverrides) -> Void
@State private var showFileImporter = false
var body: some View { var body: some View {
Section { Section {
@ -626,39 +628,47 @@ struct ImportExportThemeSection: View {
} label: { } label: {
Text("Import theme").foregroundColor(theme.colors.primary) Text("Import theme").foregroundColor(theme.colors.primary)
} }
.fileImporter( }
isPresented: $showFileImporter, }
allowedContentTypes: [.data/*.plainText*/], }
allowsMultipleSelection: false
) { result in struct ThemeImporter: ViewModifier {
if case let .success(files) = result, let fileURL = files.first { @Binding var isPresented: Bool
do { var save: (ThemeOverrides) -> Void
var fileSize: Int? = nil
if fileURL.startAccessingSecurityScopedResource() { func body(content: Content) -> some View {
let resourceValues = try fileURL.resourceValues(forKeys: [.fileSizeKey]) content.fileImporter(
fileSize = resourceValues.fileSize isPresented: $isPresented,
} allowedContentTypes: [.data/*.plainText*/],
if let fileSize = fileSize, allowsMultipleSelection: false
// Same as Android/desktop ) { result in
fileSize <= 5_500_000 { if case let .success(files) = result, let fileURL = files.first {
if let string = try? String(contentsOf: fileURL, encoding: .utf8), let theme: ThemeOverrides = decodeYAML("themeId: \(UUID().uuidString)\n" + string) { do {
save(theme) var fileSize: Int? = nil
logger.error("Saved theme from file") if fileURL.startAccessingSecurityScopedResource() {
} else { let resourceValues = try fileURL.resourceValues(forKeys: [.fileSizeKey])
logger.error("Error decoding theme file") fileSize = resourceValues.fileSize
}
fileURL.stopAccessingSecurityScopedResource()
} else {
fileURL.stopAccessingSecurityScopedResource()
let prettyMaxFileSize = ByteCountFormatter.string(fromByteCount: 5_500_000, countStyle: .binary)
AlertManager.shared.showAlertMsg(
title: "Large file!",
message: "Currently maximum supported file size is \(prettyMaxFileSize)."
)
}
} catch {
logger.error("Appearance fileImporter error \(error.localizedDescription)")
} }
if let fileSize = fileSize,
// Same as Android/desktop
fileSize <= 5_500_000 {
if let string = try? String(contentsOf: fileURL, encoding: .utf8), let theme: ThemeOverrides = decodeYAML("themeId: \(UUID().uuidString)\n" + string) {
save(theme)
logger.error("Saved theme from file")
} else {
logger.error("Error decoding theme file")
}
fileURL.stopAccessingSecurityScopedResource()
} else {
fileURL.stopAccessingSecurityScopedResource()
let prettyMaxFileSize = ByteCountFormatter.string(fromByteCount: 5_500_000, countStyle: .binary)
AlertManager.shared.showAlertMsg(
title: "Large file!",
message: "Currently maximum supported file size is \(prettyMaxFileSize)."
)
}
} catch {
logger.error("Appearance fileImporter error \(error.localizedDescription)")
} }
} }
} }

View file

@ -331,7 +331,12 @@ struct SettingsView: View {
chatDatabaseRow() chatDatabaseRow()
NavigationLink { NavigationLink {
MigrateFromDevice(showProgressOnSettings: $showProgress) 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)) .modifier(ThemedBackground(grouped: true))
.navigationBarTitleDisplayMode(.large) .navigationBarTitleDisplayMode(.large)
} label: { } label: {

View file

@ -204,6 +204,7 @@
CE38A29C2C3FCD72005ED185 /* SwiftyGif in Frameworks */ = {isa = PBXBuildFile; productRef = CE38A29B2C3FCD72005ED185 /* SwiftyGif */; }; CE38A29C2C3FCD72005ED185 /* SwiftyGif in Frameworks */ = {isa = PBXBuildFile; productRef = CE38A29B2C3FCD72005ED185 /* SwiftyGif */; };
CE75480A2C622630009579B7 /* SwipeLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE7548092C622630009579B7 /* SwipeLabel.swift */; }; CE75480A2C622630009579B7 /* SwipeLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE7548092C622630009579B7 /* SwipeLabel.swift */; };
CE984D4B2C36C5D500E3AEFF /* ChatItemClipShape.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE984D4A2C36C5D500E3AEFF /* ChatItemClipShape.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 */; }; CEDB245B2C9CD71800FBC5F6 /* StickyScrollView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEDB245A2C9CD71800FBC5F6 /* StickyScrollView.swift */; };
CEDE70222C48FD9500233B1F /* SEChatState.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEDE70212C48FD9500233B1F /* SEChatState.swift */; }; CEDE70222C48FD9500233B1F /* SEChatState.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEDE70212C48FD9500233B1F /* SEChatState.swift */; };
CEE723AA2C3BD3D70009AE93 /* ShareViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEE723A92C3BD3D70009AE93 /* ShareViewController.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 */; }; D77B92DC2952372200A5A1CC /* SwiftyGif in Frameworks */ = {isa = PBXBuildFile; productRef = D77B92DB2952372200A5A1CC /* SwiftyGif */; };
D7F0E33929964E7E0068AF69 /* LZString in Frameworks */ = {isa = PBXBuildFile; productRef = D7F0E33829964E7E0068AF69 /* LZString */; }; D7F0E33929964E7E0068AF69 /* LZString in Frameworks */ = {isa = PBXBuildFile; productRef = D7F0E33829964E7E0068AF69 /* LZString */; };
E51CC1E62C62085600DB91FE /* OneHandUICard.swift in Sources */ = {isa = PBXBuildFile; fileRef = E51CC1E52C62085600DB91FE /* OneHandUICard.swift */; }; 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 */; }; E5DCF8DB2C56FAC1007928CC /* SimpleXChat.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5CE2BA682845308900EC33A6 /* SimpleXChat.framework */; };
E5DCF9712C590272007928CC /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = E5DCF96F2C590272007928CC /* Localizable.strings */; }; E5DCF9712C590272007928CC /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = E5DCF96F2C590272007928CC /* Localizable.strings */; };
E5DCF9842C5902CE007928CC /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = E5DCF9822C5902CE007928CC /* Localizable.strings */; }; E5DCF9842C5902CE007928CC /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = E5DCF9822C5902CE007928CC /* Localizable.strings */; };
E5DCF9982C5906FF007928CC /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = E5DCF9962C5906FF007928CC /* InfoPlist.strings */; }; E5DCF9982C5906FF007928CC /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = E5DCF9962C5906FF007928CC /* InfoPlist.strings */; };
E5E997C92CBA891A00D7A2FA /* libgmpxx.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E5E997C42CBA891A00D7A2FA /* libgmpxx.a */; }; E5E997C92CBA891A00D7A2FA /* libgmpxx.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E5E997C42CBA891A00D7A2FA /* libgmpxx.a */; };
E5E997CA2CBA891A00D7A2FA /* libgmp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E5E997C52CBA891A00D7A2FA /* libgmp.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 */; }; 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 */ /* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */ /* Begin PBXContainerItemProxy section */
@ -545,6 +546,7 @@
CE3097FA2C4C0C9F00180898 /* ErrorAlert.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ErrorAlert.swift; sourceTree = "<group>"; }; 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>"; }; 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>"; }; 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>"; }; 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>"; }; 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; }; 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; }; 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; }; 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>"; }; 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>"; }; 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>"; }; 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>"; }; 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>"; }; 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>"; }; 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>"; }; 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>"; }; 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 */ /* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */ /* Begin PBXFrameworksBuildPhase section */
@ -656,13 +658,13 @@
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
E5E997C92CBA891A00D7A2FA /* libgmpxx.a in Frameworks */, E5E997C92CBA891A00D7A2FA /* libgmpxx.a in Frameworks */,
E5E997CB2CBA891A00D7A2FA /* libHSsimplex-chat-6.1.0.9-3X73OucN19a19eYgUK66sv-ghc9.6.3.a in Frameworks */,
E5E997CA2CBA891A00D7A2FA /* libgmp.a in Frameworks */, E5E997CA2CBA891A00D7A2FA /* libgmp.a in Frameworks */,
5CE2BA93284534B000EC33A6 /* libiconv.tbd in Frameworks */, 5CE2BA93284534B000EC33A6 /* libiconv.tbd in Frameworks */,
E5E997CC2CBA891A00D7A2FA /* libffi.a in Frameworks */, E5E997CC2CBA891A00D7A2FA /* libffi.a in Frameworks */,
5CE2BA94284534BB00EC33A6 /* libz.tbd in Frameworks */, 5CE2BA94284534BB00EC33A6 /* libz.tbd in Frameworks */,
E56F46202CC2B2E300F1559D /* libHSsimplex-chat-6.1.1.0-KwHIA7FZqPI5ZTCAoi00n9.a in Frameworks */,
CE38A29C2C3FCD72005ED185 /* SwiftyGif 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; runOnlyForDeploymentPostprocessing = 0;
}; };
@ -742,8 +744,8 @@
E5E997C72CBA891A00D7A2FA /* libffi.a */, E5E997C72CBA891A00D7A2FA /* libffi.a */,
E5E997C52CBA891A00D7A2FA /* libgmp.a */, E5E997C52CBA891A00D7A2FA /* libgmp.a */,
E5E997C42CBA891A00D7A2FA /* libgmpxx.a */, E5E997C42CBA891A00D7A2FA /* libgmpxx.a */,
E5E997C62CBA891A00D7A2FA /* libHSsimplex-chat-6.1.0.9-3X73OucN19a19eYgUK66sv-ghc9.6.3.a */, E56F461F2CC2B2E300F1559D /* libHSsimplex-chat-6.1.1.0-KwHIA7FZqPI5ZTCAoi00n9-ghc9.6.3.a */,
E5E997C82CBA891A00D7A2FA /* libHSsimplex-chat-6.1.0.9-3X73OucN19a19eYgUK66sv.a */, E56F461E2CC2B2E300F1559D /* libHSsimplex-chat-6.1.1.0-KwHIA7FZqPI5ZTCAoi00n9.a */,
); );
path = Libraries; path = Libraries;
sourceTree = "<group>"; sourceTree = "<group>";
@ -802,6 +804,7 @@
CE176F1F2C87014C00145DBC /* InvertedForegroundStyle.swift */, CE176F1F2C87014C00145DBC /* InvertedForegroundStyle.swift */,
CEDB245A2C9CD71800FBC5F6 /* StickyScrollView.swift */, CEDB245A2C9CD71800FBC5F6 /* StickyScrollView.swift */,
CEFB2EDE2CA1BCC7004B1ECE /* SheetRepresentable.swift */, CEFB2EDE2CA1BCC7004B1ECE /* SheetRepresentable.swift */,
CEA6E91B2CBD21B0002B5DB4 /* UserDefault.swift */,
); );
path = Helpers; path = Helpers;
sourceTree = "<group>"; sourceTree = "<group>";
@ -1482,6 +1485,7 @@
5CFA59D12864782E00863A68 /* ChatArchiveView.swift in Sources */, 5CFA59D12864782E00863A68 /* ChatArchiveView.swift in Sources */,
649BCDA22805D6EF00C3A862 /* CIImageView.swift in Sources */, 649BCDA22805D6EF00C3A862 /* CIImageView.swift in Sources */,
5CADE79C292131E900072E13 /* ContactPreferencesView.swift in Sources */, 5CADE79C292131E900072E13 /* ContactPreferencesView.swift in Sources */,
CEA6E91C2CBD21B0002B5DB4 /* UserDefault.swift in Sources */,
5CB346E52868AA7F001FD2EF /* SuspendChat.swift in Sources */, 5CB346E52868AA7F001FD2EF /* SuspendChat.swift in Sources */,
5C9C2DA52894777E00CC63B1 /* GroupProfileView.swift in Sources */, 5C9C2DA52894777E00CC63B1 /* GroupProfileView.swift in Sources */,
5CEACCED27DEA495000BD591 /* MsgContentView.swift in Sources */, 5CEACCED27DEA495000BD591 /* MsgContentView.swift in Sources */,
@ -1899,7 +1903,7 @@
CLANG_TIDY_MISC_REDUNDANT_EXPRESSION = YES; CLANG_TIDY_MISC_REDUNDANT_EXPRESSION = YES;
CODE_SIGN_ENTITLEMENTS = "SimpleX (iOS).entitlements"; CODE_SIGN_ENTITLEMENTS = "SimpleX (iOS).entitlements";
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 244; CURRENT_PROJECT_VERSION = 245;
DEAD_CODE_STRIPPING = YES; DEAD_CODE_STRIPPING = YES;
DEVELOPMENT_TEAM = 5NN7GUYB6T; DEVELOPMENT_TEAM = 5NN7GUYB6T;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
@ -1924,7 +1928,7 @@
"@executable_path/Frameworks", "@executable_path/Frameworks",
); );
LLVM_LTO = YES_THIN; LLVM_LTO = YES_THIN;
MARKETING_VERSION = 6.1; MARKETING_VERSION = 6.1.1;
PRODUCT_BUNDLE_IDENTIFIER = chat.simplex.app; PRODUCT_BUNDLE_IDENTIFIER = chat.simplex.app;
PRODUCT_NAME = SimpleX; PRODUCT_NAME = SimpleX;
SDKROOT = iphoneos; SDKROOT = iphoneos;
@ -1948,7 +1952,7 @@
CLANG_TIDY_MISC_REDUNDANT_EXPRESSION = YES; CLANG_TIDY_MISC_REDUNDANT_EXPRESSION = YES;
CODE_SIGN_ENTITLEMENTS = "SimpleX (iOS).entitlements"; CODE_SIGN_ENTITLEMENTS = "SimpleX (iOS).entitlements";
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 244; CURRENT_PROJECT_VERSION = 245;
DEAD_CODE_STRIPPING = YES; DEAD_CODE_STRIPPING = YES;
DEVELOPMENT_TEAM = 5NN7GUYB6T; DEVELOPMENT_TEAM = 5NN7GUYB6T;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
@ -1973,7 +1977,7 @@
"@executable_path/Frameworks", "@executable_path/Frameworks",
); );
LLVM_LTO = YES; LLVM_LTO = YES;
MARKETING_VERSION = 6.1; MARKETING_VERSION = 6.1.1;
PRODUCT_BUNDLE_IDENTIFIER = chat.simplex.app; PRODUCT_BUNDLE_IDENTIFIER = chat.simplex.app;
PRODUCT_NAME = SimpleX; PRODUCT_NAME = SimpleX;
SDKROOT = iphoneos; SDKROOT = iphoneos;
@ -1989,11 +1993,11 @@
buildSettings = { buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 244; CURRENT_PROJECT_VERSION = 245;
DEVELOPMENT_TEAM = 5NN7GUYB6T; DEVELOPMENT_TEAM = 5NN7GUYB6T;
GENERATE_INFOPLIST_FILE = YES; GENERATE_INFOPLIST_FILE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 15.0; IPHONEOS_DEPLOYMENT_TARGET = 15.0;
MARKETING_VERSION = 6.1; MARKETING_VERSION = 6.1.1;
PRODUCT_BUNDLE_IDENTIFIER = "chat.simplex.Tests-iOS"; PRODUCT_BUNDLE_IDENTIFIER = "chat.simplex.Tests-iOS";
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = iphoneos; SDKROOT = iphoneos;
@ -2009,11 +2013,11 @@
buildSettings = { buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 244; CURRENT_PROJECT_VERSION = 245;
DEVELOPMENT_TEAM = 5NN7GUYB6T; DEVELOPMENT_TEAM = 5NN7GUYB6T;
GENERATE_INFOPLIST_FILE = YES; GENERATE_INFOPLIST_FILE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 15.0; IPHONEOS_DEPLOYMENT_TARGET = 15.0;
MARKETING_VERSION = 6.1; MARKETING_VERSION = 6.1.1;
PRODUCT_BUNDLE_IDENTIFIER = "chat.simplex.Tests-iOS"; PRODUCT_BUNDLE_IDENTIFIER = "chat.simplex.Tests-iOS";
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = iphoneos; SDKROOT = iphoneos;
@ -2034,7 +2038,7 @@
CODE_SIGN_ENTITLEMENTS = "SimpleX NSE/SimpleX NSE.entitlements"; CODE_SIGN_ENTITLEMENTS = "SimpleX NSE/SimpleX NSE.entitlements";
CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 244; CURRENT_PROJECT_VERSION = 245;
DEVELOPMENT_TEAM = 5NN7GUYB6T; DEVELOPMENT_TEAM = 5NN7GUYB6T;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
GCC_OPTIMIZATION_LEVEL = s; GCC_OPTIMIZATION_LEVEL = s;
@ -2049,7 +2053,7 @@
"@executable_path/../../Frameworks", "@executable_path/../../Frameworks",
); );
LLVM_LTO = YES; LLVM_LTO = YES;
MARKETING_VERSION = 6.1; MARKETING_VERSION = 6.1.1;
PRODUCT_BUNDLE_IDENTIFIER = "chat.simplex.app.SimpleX-NSE"; PRODUCT_BUNDLE_IDENTIFIER = "chat.simplex.app.SimpleX-NSE";
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = ""; PROVISIONING_PROFILE_SPECIFIER = "";
@ -2071,7 +2075,7 @@
CODE_SIGN_ENTITLEMENTS = "SimpleX NSE/SimpleX NSE.entitlements"; CODE_SIGN_ENTITLEMENTS = "SimpleX NSE/SimpleX NSE.entitlements";
CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 244; CURRENT_PROJECT_VERSION = 245;
DEVELOPMENT_TEAM = 5NN7GUYB6T; DEVELOPMENT_TEAM = 5NN7GUYB6T;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
ENABLE_CODE_COVERAGE = NO; ENABLE_CODE_COVERAGE = NO;
@ -2086,7 +2090,7 @@
"@executable_path/../../Frameworks", "@executable_path/../../Frameworks",
); );
LLVM_LTO = YES; LLVM_LTO = YES;
MARKETING_VERSION = 6.1; MARKETING_VERSION = 6.1.1;
PRODUCT_BUNDLE_IDENTIFIER = "chat.simplex.app.SimpleX-NSE"; PRODUCT_BUNDLE_IDENTIFIER = "chat.simplex.app.SimpleX-NSE";
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = ""; PROVISIONING_PROFILE_SPECIFIER = "";
@ -2108,7 +2112,7 @@
CLANG_TIDY_BUGPRONE_REDUNDANT_BRANCH_CONDITION = YES; CLANG_TIDY_BUGPRONE_REDUNDANT_BRANCH_CONDITION = YES;
CLANG_TIDY_MISC_REDUNDANT_EXPRESSION = YES; CLANG_TIDY_MISC_REDUNDANT_EXPRESSION = YES;
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 244; CURRENT_PROJECT_VERSION = 245;
DEFINES_MODULE = YES; DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = 5NN7GUYB6T; DEVELOPMENT_TEAM = 5NN7GUYB6T;
DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_COMPATIBILITY_VERSION = 1;
@ -2134,7 +2138,7 @@
"$(PROJECT_DIR)/Libraries/sim", "$(PROJECT_DIR)/Libraries/sim",
); );
LLVM_LTO = YES; LLVM_LTO = YES;
MARKETING_VERSION = 6.1; MARKETING_VERSION = 6.1.1;
PRODUCT_BUNDLE_IDENTIFIER = chat.simplex.SimpleXChat; PRODUCT_BUNDLE_IDENTIFIER = chat.simplex.SimpleXChat;
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
SDKROOT = iphoneos; SDKROOT = iphoneos;
@ -2159,7 +2163,7 @@
CLANG_TIDY_BUGPRONE_REDUNDANT_BRANCH_CONDITION = YES; CLANG_TIDY_BUGPRONE_REDUNDANT_BRANCH_CONDITION = YES;
CLANG_TIDY_MISC_REDUNDANT_EXPRESSION = YES; CLANG_TIDY_MISC_REDUNDANT_EXPRESSION = YES;
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 244; CURRENT_PROJECT_VERSION = 245;
DEFINES_MODULE = YES; DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = 5NN7GUYB6T; DEVELOPMENT_TEAM = 5NN7GUYB6T;
DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_COMPATIBILITY_VERSION = 1;
@ -2185,7 +2189,7 @@
"$(PROJECT_DIR)/Libraries/sim", "$(PROJECT_DIR)/Libraries/sim",
); );
LLVM_LTO = YES; LLVM_LTO = YES;
MARKETING_VERSION = 6.1; MARKETING_VERSION = 6.1.1;
PRODUCT_BUNDLE_IDENTIFIER = chat.simplex.SimpleXChat; PRODUCT_BUNDLE_IDENTIFIER = chat.simplex.SimpleXChat;
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
SDKROOT = iphoneos; SDKROOT = iphoneos;
@ -2210,7 +2214,7 @@
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
CODE_SIGN_ENTITLEMENTS = "SimpleX SE/SimpleX SE.entitlements"; CODE_SIGN_ENTITLEMENTS = "SimpleX SE/SimpleX SE.entitlements";
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 244; CURRENT_PROJECT_VERSION = 245;
DEVELOPMENT_TEAM = 5NN7GUYB6T; DEVELOPMENT_TEAM = 5NN7GUYB6T;
ENABLE_USER_SCRIPT_SANDBOXING = YES; ENABLE_USER_SCRIPT_SANDBOXING = YES;
GCC_C_LANGUAGE_STANDARD = gnu17; GCC_C_LANGUAGE_STANDARD = gnu17;
@ -2225,7 +2229,7 @@
"@executable_path/../../Frameworks", "@executable_path/../../Frameworks",
); );
LOCALIZATION_PREFERS_STRING_CATALOGS = YES; LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
MARKETING_VERSION = 6.1; MARKETING_VERSION = 6.1.1;
PRODUCT_BUNDLE_IDENTIFIER = "chat.simplex.app.SimpleX-SE"; PRODUCT_BUNDLE_IDENTIFIER = "chat.simplex.app.SimpleX-SE";
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = iphoneos; SDKROOT = iphoneos;
@ -2244,7 +2248,7 @@
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
CODE_SIGN_ENTITLEMENTS = "SimpleX SE/SimpleX SE.entitlements"; CODE_SIGN_ENTITLEMENTS = "SimpleX SE/SimpleX SE.entitlements";
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 244; CURRENT_PROJECT_VERSION = 245;
DEVELOPMENT_TEAM = 5NN7GUYB6T; DEVELOPMENT_TEAM = 5NN7GUYB6T;
ENABLE_USER_SCRIPT_SANDBOXING = YES; ENABLE_USER_SCRIPT_SANDBOXING = YES;
GCC_C_LANGUAGE_STANDARD = gnu17; GCC_C_LANGUAGE_STANDARD = gnu17;
@ -2259,7 +2263,7 @@
"@executable_path/../../Frameworks", "@executable_path/../../Frameworks",
); );
LOCALIZATION_PREFERS_STRING_CATALOGS = YES; LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
MARKETING_VERSION = 6.1; MARKETING_VERSION = 6.1.1;
PRODUCT_BUNDLE_IDENTIFIER = "chat.simplex.app.SimpleX-SE"; PRODUCT_BUNDLE_IDENTIFIER = "chat.simplex.app.SimpleX-SE";
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = iphoneos; SDKROOT = iphoneos;

View file

@ -2088,6 +2088,7 @@ public enum ProtocolErrorType: Decodable, Hashable {
case AUTH case AUTH
case CRYPTO case CRYPTO
case QUOTA case QUOTA
case STORE(storeErr: String)
case NO_MSG case NO_MSG
case LARGE_MSG case LARGE_MSG
case EXPIRED case EXPIRED

View file

@ -1226,6 +1226,15 @@ object ChatController {
) )
return null 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 -> { else -> {
if (!(networkErrorAlert(r))) { if (!(networkErrorAlert(r))) {
apiErrorAlert("apiConnect", generalGetString(MR.strings.connection_error), r) apiErrorAlert("apiConnect", generalGetString(MR.strings.connection_error), r)
@ -6045,6 +6054,7 @@ sealed class SMPErrorType {
is AUTH -> "AUTH" is AUTH -> "AUTH"
is CRYPTO -> "CRYPTO" is CRYPTO -> "CRYPTO"
is QUOTA -> "QUOTA" is QUOTA -> "QUOTA"
is STORE -> "STORE ${storeErr}"
is NO_MSG -> "NO_MSG" is NO_MSG -> "NO_MSG"
is LARGE_MSG -> "LARGE_MSG" is LARGE_MSG -> "LARGE_MSG"
is EXPIRED -> "EXPIRED" is EXPIRED -> "EXPIRED"
@ -6057,6 +6067,7 @@ sealed class SMPErrorType {
@Serializable @SerialName("AUTH") class AUTH: SMPErrorType() @Serializable @SerialName("AUTH") class AUTH: SMPErrorType()
@Serializable @SerialName("CRYPTO") class CRYPTO: SMPErrorType() @Serializable @SerialName("CRYPTO") class CRYPTO: SMPErrorType()
@Serializable @SerialName("QUOTA") class QUOTA: 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("NO_MSG") class NO_MSG: SMPErrorType()
@Serializable @SerialName("LARGE_MSG") class LARGE_MSG: SMPErrorType() @Serializable @SerialName("LARGE_MSG") class LARGE_MSG: SMPErrorType()
@Serializable @SerialName("EXPIRED") class EXPIRED: SMPErrorType() @Serializable @SerialName("EXPIRED") class EXPIRED: SMPErrorType()

View file

@ -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="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">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_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="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="sender_may_have_deleted_the_connection_request">Sender may have deleted the connection request.</string>
<string name="error_deleting_contact">Error deleting contact</string> <string name="error_deleting_contact">Error deleting contact</string>

View file

@ -26,11 +26,11 @@ android.enableJetifier=true
kotlin.mpp.androidSourceSetLayoutVersion=2 kotlin.mpp.androidSourceSetLayoutVersion=2
kotlin.jvm.target=11 kotlin.jvm.target=11
android.version_name=6.1 android.version_name=6.1.1
android.version_code=247 android.version_code=249
desktop.version_name=6.1 desktop.version_name=6.1.1
desktop.version_code=73 desktop.version_code=74
kotlin.version=1.9.23 kotlin.version=1.9.23
gradle.plugin.version=8.2.0 gradle.plugin.version=8.2.0

View file

@ -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). 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 ### Medium severity issues

View file

@ -2,10 +2,9 @@
layout: layouts/article.html layout: layouts/article.html
title: "SimpleX network: cryptographic design review by Trail of Bits, v6.1 released with better calls and user experience." title: "SimpleX network: cryptographic design review by Trail of Bits, v6.1 released with better calls and user experience."
date: 2024-10-14 date: 2024-10-14
# image: images/20240814-reachable.png image: images/20221108-trail-of-bits.jpg
# previewBody: blog_previews/20240814.html previewBody: blog_previews/20241014.html
permalink: "/blog/20241014-simplex-network-v6-1-security-review-better-calls-user-experience.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 **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 &mdash; a protocol for sending files, &mdash; and XRCP &mdash; 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 &mdash; 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 &mdash; 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 &mdash; 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 &mdash; 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 &mdash; 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) &mdash; 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 &mdash; 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 &mdash; 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

View file

@ -0,0 +1,39 @@
---
layout: layouts/article.html
title: "Wireds 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"
---
# Wireds 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 &mdash; 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 &mdash; thats the point. To paint this as problematic solely because of who may use such apps misses the broader, critical context.
SimpleXs 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 &mdash; the information that can reveal who youre 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 &mdash; 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 doesnt justify broad criticism. Additionally, the lobbying for client-side scanning, which Wireds 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.
Its 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 EUs 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 &mdash; 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.

View file

@ -1,8 +1,19 @@
# Blog # 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) 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. Announcing the investment from Jack Dorsey and Asymmetric.

Binary file not shown.

After

Width:  |  Height:  |  Size: 286 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 582 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 241 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 364 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 360 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

View file

@ -12,7 +12,7 @@ constraints: zip +disable-bzip2 +disable-zstd
source-repository-package source-repository-package
type: git type: git
location: https://github.com/simplex-chat/simplexmq.git location: https://github.com/simplex-chat/simplexmq.git
tag: c41bfe831d6d3fdf068f7419cbfed6afa46cb5b5 tag: 967afaf802d7ea98480eaf280bfc6f35d4d43f05
source-repository-package source-repository-package
type: git type: git

View file

@ -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. 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 ## Reporting security issues

View file

@ -1,13 +1,16 @@
--- ---
title: Hosting your own SMP Server 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 ### Table of Contents
- [Hosting your own SMP server](#hosting-your-own-smp-server) - [Quick start](#quick-start)
- [Detailed guide](#detailed-guide)
- [Overview](#overview) - [Overview](#overview)
- [Installation](#installation) - [Installation](#installation)
- [Configuration](#configuration) - [Configuration](#configuration)
@ -29,17 +32,218 @@ revision: 03.06.2024
- [Updating your SMP server](#updating-your-smp-server) - [Updating your SMP server](#updating-your-smp-server)
- [Configuring the app to use the server](#configuring-the-app-to-use-the-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. 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. 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. _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`: 1. First, install `smp-server`:
@ -82,8 +286,10 @@ Manual installation requires some preliminary actions:
```sh ```sh
# For Ubuntu # For Ubuntu
sudo ufw allow 5223/tcp sudo ufw allow 5223/tcp
sudo ufw allow 443/tcp
sudo ufw allow 80/tcp
# For Fedora # 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 sudo firewall-cmd --reload
``` ```
@ -102,6 +308,7 @@ Manual installation requires some preliminary actions:
LimitNOFILE=65535 LimitNOFILE=65535
KillSignal=SIGINT KillSignal=SIGINT
TimeoutStopSec=infinity TimeoutStopSec=infinity
AmbientCapabilities=CAP_NET_BIND_SERVICE
[Install] [Install]
WantedBy=multi-user.target WantedBy=multi-user.target
@ -109,7 +316,7 @@ Manual installation requires some preliminary actions:
And execute `sudo systemctl daemon-reload`. And execute `sudo systemctl daemon-reload`.
## Configuration ### Configuration
To see which options are available, execute `smp-server` without flags: 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`: After that, we need to configure `smp-server`:
### Interactively #### Interactively
Execute the following command: 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. 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: 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. 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: 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 # condition_amendments: link
# Server location and operator. # Server location and operator.
server_country: <YOUR_SERVER_LOCATION> # server_country: ISO-3166 2-letter code
operator: <YOUR_NAME> # operator: entity (organization or person name)
operator_country: <YOUR_LOCATION> # operator_country: ISO-3166 2-letter code
website: <WEBSITE_IF_AVAILABLE> # website:
# Administrative contacts. # Administrative contacts.
#admin_simplex: SimpleX address # admin_simplex: SimpleX address
admin_email: <EMAIL> # admin_email:
# admin_pgp: # admin_pgp:
# admin_pgp_fingerprint: # admin_pgp_fingerprint:
# Contacts for complaints and feedback. # Contacts for complaints and feedback.
# complaints_simplex: SimpleX address # complaints_simplex: SimpleX address
complaints_email: <COMPLAINTS_EMAIL> # complaints_email:
# complaints_pgp: # complaints_pgp:
# complaints_pgp_fingerprint: # complaints_pgp_fingerprint:
# Hosting provider. # Hosting provider.
hosting: <HOSTING_PROVIDER_NAME> # hosting: entity (organization or person name)
hosting_country: <HOSTING_PROVIDER_LOCATION> # hosting_country: ISO-3166 2-letter code
[STORE_LOG] [STORE_LOG]
# The server uses STM memory for persistence, # The server uses STM memory for persistence,
@ -278,6 +485,7 @@ enable: on
# they are preserved in the .bak file until the next restart. # they are preserved in the .bak file until the next restart.
restore_messages: on restore_messages: on
expire_messages_days: 21 expire_messages_days: 21
expire_ntfs_hours: 24
# Log daily server statistics to CSV file # Log daily server statistics to CSV file
log_stats: on log_stats: on
@ -294,11 +502,17 @@ new_queues: on
# with the users who you want to allow creating messaging queues on your server. # 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 '/') # create_password: password to create new queues (any printable ASCII characters without whitespace, '@', ':' and '/')
# control_port_admin_password:
# control_port_user_password:
[TRANSPORT] [TRANSPORT]
# host is only used to print server address on start # Host is only used to print server address on start.
host: <your server domain/ip> # You can specify multiple server ports.
port: 5223 host: <domain/ip>
port: 5223,443
log_tls_errors: off log_tls_errors: off
# Use `websockets: 443` to run websockets server in addition to plain TLS.
websockets: off websockets: off
# control_port: 5224 # control_port: 5224
@ -310,7 +524,7 @@ websockets: off
# required_host_mode: off # required_host_mode: off
# The domain suffixes of the relays you operate (space-separated) to count as separate proxy statistics. # 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. # SOCKS proxy port for forwarding messages to destination servers.
# You may need a separate instance of SOCKS proxy for incoming single-hop requests. # You may need a separate instance of SOCKS proxy for incoming single-hop requests.
@ -326,7 +540,7 @@ websockets: off
[INACTIVE_CLIENTS] [INACTIVE_CLIENTS]
# TTL and interval to check inactive clients # TTL and interval to check inactive clients
disconnect: off disconnect: off
# ttl: 43200 # ttl: 21600
# check_interval: 3600 # check_interval: 3600
[WEB] [WEB]
@ -336,18 +550,18 @@ static_path: /var/opt/simplex/www
# Run an embedded server on this port # Run an embedded server on this port
# Onion sites can use any port and register it in the hidden service config. # Onion sites can use any port and register it in the hidden service config.
# Running on a port 80 may require setting process capabilities. # 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. # 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. # Not required for running relay on onion address.
# https: 443 https: 443
# cert: /etc/opt/simplex/web.cert cert: /etc/opt/simplex/web.crt
# key: /etc/opt/simplex/web.key 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. 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/ 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: 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 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: 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! 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. 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 # smp-server hidden service host directory and port mappings
HiddenServiceDir /var/lib/tor/simplex-smp/ HiddenServiceDir /var/lib/tor/simplex-smp/
HiddenServicePort 5223 localhost:5223 HiddenServicePort 5223 localhost:5223
HiddenServicePort 443 localhost:443
``` ```
- Create directories: - 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 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. 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): 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 ```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] [WEB]
https: 443
static_path: /var/opt/simplex/www static_path: /var/opt/simplex/www
cert: /etc/opt/simplex/web.crt
key: /etc/opt/simplex/web.key
[INFORMATION] [INFORMATION]
# AGPLv3 license requires that you make any source code modifications # 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) [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 ```sh
vim /etc/caddy/Caddyfile vim /etc/caddy/Caddyfile
``` ```
```caddy ```
<YOUR_DOMAIN> { http://YOUR_DOMAIN {
root * /var/opt/simplex/www redir https://YOUR_DOMAIN{uri} permanent
file_server }
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 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. 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. 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: 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. 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: 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 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. 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: Logs will be stored as `csv` file in `/var/opt/simplex/smp-server-stats.daily.log`. Fields for the `csv` file are:
```sh ```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 | | Field number | Field name | Field Description |
| ------------- | ---------------------------- | -------------------------- | | ------------- | ---------------------------- | -------------------------- |
| 1 | `fromTime` | Date of statistics | | 1 | `fromTime` | Date of statistics |
@ -856,6 +1151,34 @@ fromTime,qCreated,qSecured,qDeleted,msgSent,msgRecv,dayMsgQueues,weekMsgQueues,m
| 45 | `msgSentAuth` | Authentication errors | | 45 | `msgSentAuth` | Authentication errors |
| 46 | `msgSentQuota` | Quota errors | | 46 | `msgSentQuota` | Quota errors |
| 47 | `msgSentLarge` | Large message 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: To import `csv` to `Grafana` one should:
@ -863,83 +1186,112 @@ To import `csv` to `Grafana` one should:
2. Allow local mode by appending following: 2. Allow local mode by appending following:
```sh ```sh
[plugin.marcusolsson-csv-datasource] [plugin.marcusolsson-csv-datasource]
allow_local_mode = true allow_local_mode = true
``` ```
... to `/etc/grafana/grafana.ini` ... to `/etc/grafana/grafana.ini`
3. Add a CSV data source: 3. Add a CSV data source:
- In the side menu, click the Configuration tab (cog icon) - In the side menu, click the Configuration tab (cog icon)
- Click Add data source in the top-right corner of the Data Sources tab - Click Add data source in the top-right corner of the Data Sources tab
- Enter "CSV" in the search box to find the CSV data source - Enter "CSV" in the search box to find the CSV data source
- Click the search result that says "CSV" - Click the search result that says "CSV"
- In URL, enter a file that points to CSV content - In URL, enter a file that points to CSV content
4. You're done! You should be able to create your own dashboard with statistics. 4. You're done! You should be able to create your own dashboard with statistics.
For further documentation, see: [CSV Data Source for Grafana - Documentation](https://grafana.github.io/grafana-csv-datasource/) 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: To update your smp-server to latest version, choose your installation method and follow the steps:
- Manual deployment - Manual deployment
1. Stop the server: 1. Stop the server:
```sh ```sh
sudo systemctl stop smp-server sudo systemctl stop smp-server
``` ```
2. Update the binary: 2. Update the binary:
```sh ```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 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: 3. Start the server:
```sh ```sh
sudo systemctl start smp-server sudo systemctl start smp-server
``` ```
- [Offical installation script](https://github.com/simplex-chat/simplexmq#using-installation-script) - [Offical installation script](https://github.com/simplex-chat/simplexmq#using-installation-script)
1. Execute the followin command: 1. Execute the followin command:
```sh ```sh
sudo simplex-servers-update sudo simplex-servers-update
``` ```
To install specific version, run:
```sh
export VER=<version_from_github_releases> &&\
sudo -E simplex-servers-update
```
2. Done! 2. Done!
- [Docker container](https://github.com/simplex-chat/simplexmq#using-docker) - [Docker container](https://github.com/simplex-chat/simplexmq#using-docker)
1. Stop and remove the container: 1. Stop and remove the container:
```sh ```sh
docker rm $(docker stop $(docker ps -a -q --filter ancestor=simplexchat/smp-server --format="\{\{.ID\}\}")) docker rm $(docker stop $(docker ps -a -q --filter ancestor=simplexchat/smp-server --format="\{\{.ID\}\}"))
``` ```
2. Pull latest image: 2. Pull latest image:
```sh ```sh
docker pull simplexchat/smp-server:latest docker pull simplexchat/smp-server:latest
``` ```
3. Start new container: 3. Start new container:
```sh ```sh
docker run -d \ docker run -d \
-p 5223:5223 \ -p 5223:5223 \
-p 443:443 \
-v $HOME/simplex/smp/config:/etc/opt/simplex:z \ -v $HOME/simplex/smp/config:/etc/opt/simplex:z \
-v $HOME/simplex/smp/logs:/var/opt/simplex:z \ -v $HOME/simplex/smp/logs:/var/opt/simplex:z \
simplexchat/smp-server:latest simplexchat/smp-server:latest
``` ```
- [Linode Marketplace](https://www.linode.com/marketplace/apps/simplex-chat/simplex-chat/) - [Linode Marketplace](https://www.linode.com/marketplace/apps/simplex-chat/simplex-chat/)
1. Pull latest images: 1. Pull latest images:
```sh ```sh
docker-compose --project-directory /etc/docker/compose/simplex pull docker-compose --project-directory /etc/docker/compose/simplex pull
``` ```
2. Restart the containers: 2. Restart the containers:
```sh ```sh
docker-compose --project-directory /etc/docker/compose/simplex up -d --remove-orphans docker-compose --project-directory /etc/docker/compose/simplex up -d --remove-orphans
``` ```
3. Remove obsolete images: 3. Remove obsolete images:
```sh ```sh
docker image prune 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. 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.

View file

@ -6,7 +6,7 @@ revision: 16.07.2024
# Transparency Reports # 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. 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) - [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) - [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) - [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). 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).

View file

@ -226,7 +226,7 @@ While introduced members establish connection inside group, inviting member forw
### Member roles ### 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 ### Messages to manage groups and add members

View file

@ -1,5 +1,5 @@
name: simplex-chat name: simplex-chat
version: 6.1.0.9 version: 6.1.1.0
#synopsis: #synopsis:
#description: #description:
homepage: https://github.com/simplex-chat/simplex-chat#readme homepage: https://github.com/simplex-chat/simplex-chat#readme

View file

@ -38,6 +38,30 @@
</description> </description>
<releases> <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"> <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> <url type="details">https://simplex.chat/blog/20240814-simplex-chat-vision-funding-v6-private-routing-new-user-experience.html</url>
<description> <description>

View file

@ -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/hs-socks.git"."a30cc7a79a08d8108316094f8f2f82a0c5e1ac51" = "0yasvnr7g91k76mjkamvzab2kvlb1g5pspjyjn2fr6v83swjhj38";
"https://github.com/simplex-chat/direct-sqlcipher.git"."f814ee68b16a9447fbb467ccc8f29bdd3546bfd9" = "1ql13f4kfwkbaq7nygkxgw84213i0zm7c1a8hwvramayxl38dq5d"; "https://github.com/simplex-chat/direct-sqlcipher.git"."f814ee68b16a9447fbb467ccc8f29bdd3546bfd9" = "1ql13f4kfwkbaq7nygkxgw84213i0zm7c1a8hwvramayxl38dq5d";
"https://github.com/simplex-chat/sqlcipher-simple.git"."a46bd361a19376c5211f1058908fc0ae6bf42446" = "1z0r78d8f0812kxbgsm735qf6xx8lvaz27k1a0b4a2m0sshpd5gl"; "https://github.com/simplex-chat/sqlcipher-simple.git"."a46bd361a19376c5211f1058908fc0ae6bf42446" = "1z0r78d8f0812kxbgsm735qf6xx8lvaz27k1a0b4a2m0sshpd5gl";

View file

@ -5,7 +5,7 @@ cabal-version: 1.12
-- see: https://github.com/sol/hpack -- see: https://github.com/sol/hpack
name: simplex-chat name: simplex-chat
version: 6.1.0.9 version: 6.1.1.0
category: Web, System, Services, Cryptography category: Web, System, Services, Cryptography
homepage: https://github.com/simplex-chat/simplex-chat#readme homepage: https://github.com/simplex-chat/simplex-chat#readme
author: simplex.chat author: simplex.chat

View file

@ -203,8 +203,9 @@ _defaultSMPServers =
_defaultNtfServers :: [NtfServer] _defaultNtfServers :: [NtfServer]
_defaultNtfServers = _defaultNtfServers =
[ "ntf://KmpZNNXiVZJx_G2T7jRUmDFxWXM3OAnunz3uLT0tqAA=@ntf3.simplex.im,pxculznuryunjdvtvh6s6szmanyadumpbmvevgdpe4wk5c65unyt4yid.onion", [ "ntf://FB-Uop7RTaZZEG0ZLD2CIaTjsPh-Fw0zFAnb7QyA8Ks=@ntf2.simplex.im,5ex3mupcazy3zlky64ab27phjhijpemsiby33qzq3pliejipbtx5xgad.onion"
"ntf://CJ5o7X6fCxj2FFYRU2KuCo70y4jSqz7td2HYhLnXWbU=@ntf4.simplex.im,wtvuhdj26jwprmomnyfu5wfuq2hjkzfcc72u44vi6gdhrwxldt6xauad.onion" -- "ntf://KmpZNNXiVZJx_G2T7jRUmDFxWXM3OAnunz3uLT0tqAA=@ntf3.simplex.im,pxculznuryunjdvtvh6s6szmanyadumpbmvevgdpe4wk5c65unyt4yid.onion",
-- "ntf://CJ5o7X6fCxj2FFYRU2KuCo70y4jSqz7td2HYhLnXWbU=@ntf4.simplex.im,wtvuhdj26jwprmomnyfu5wfuq2hjkzfcc72u44vi6gdhrwxldt6xauad.onion"
] ]
maxImageSize :: Integer maxImageSize :: Integer

View file

@ -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> قاعدة بيانات الدردشة وإعادة تثبيت التطبيق.", "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 لا يمكنها أن تتنازل عن تعمية بين الطرفين. تحقق من رمز الأمان للتخفيف من الهجوم على القناة خارج النطاق", "comparison-section-list-point-4a": "مُرحلات SimpleX لا يمكنها أن تتنازل عن تعمية بين الطرفين. تحقق من رمز الأمان للتخفيف من الهجوم على القناة خارج النطاق",
"hero-overlay-3-title": "التقييم الأمني", "hero-overlay-3-title": "التقييم الأمني",
"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-3-p-3": "اقرأ المزيد في <a href=\"/blog/20221108-simplex-chat-v4.2-security-audit-new-website.html\">الإعلان</a>.",
"jobs": "انضم للفريق", "jobs": "انضم للفريق",
"hero-overlay-3-textlink": "التقييم الأمني", "hero-overlay-3-textlink": "التقييم الأمني",
"hero-overlay-card-3-p-1": "<a href=\"https://www.trailofbits.com/about/\">Trail of Bits</a> هي شركة رائدة في مجال الاستشارات الأمنية والتكنولوجية، ومن بين عملائها شركات التكنولوجيا الكبرى والوكالات الحكومية ومشاريع blockchain الكبرى.", "hero-overlay-card-3-p-1": "<a href=\"https://www.trailofbits.com/about/\">Trail of Bits</a> هي شركة رائدة في مجال الاستشارات الأمنية والتكنولوجية، ومن بين عملائها شركات التكنولوجيا الكبرى والوكالات الحكومية ومشاريع blockchain الكبرى.",
@ -256,4 +255,4 @@
"docs-dropdown-10": "الشفافية", "docs-dropdown-10": "الشفافية",
"docs-dropdown-11": "الأسئلة الأكثر شيوعًا", "docs-dropdown-11": "الأسئلة الأكثر شيوعًا",
"docs-dropdown-12": "الأمان" "docs-dropdown-12": "الأمان"
} }

View file

@ -250,10 +250,9 @@
"stable-versions-built-by-f-droid-org": "Stabilní verze vytvořené F-Droid.org", "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", "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", "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-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>.",
"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>.",
"docs-dropdown-9": "Ke stažení", "docs-dropdown-9": "Ke stažení",
"docs-dropdown-10": "Transparentnost", "docs-dropdown-10": "Transparentnost",
"docs-dropdown-11": "FAQ (často kladené dotazy)", "docs-dropdown-11": "FAQ (často kladené dotazy)",
"docs-dropdown-12": "Bezpečnost" "docs-dropdown-12": "Bezpečnost"
} }

View file

@ -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:", "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", "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-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-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>.",
"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>.",
"jobs": "Treten Sie dem Team bei", "jobs": "Treten Sie dem Team bei",
"hero-overlay-3-textlink": "Sicherheits-Gutachten", "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.", "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.",
@ -256,4 +255,4 @@
"docs-dropdown-10": "Transparent", "docs-dropdown-10": "Transparent",
"docs-dropdown-11": "FAQ", "docs-dropdown-11": "FAQ",
"docs-dropdown-12": "Sicherheit" "docs-dropdown-12": "Sicherheit"
} }

View file

@ -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-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-1-textlink": "Why user IDs are bad for privacy?",
"hero-overlay-2-textlink": "How does SimpleX work?", "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": "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-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-1-title": "How does SimpleX work?",
"hero-overlay-2-title": "Why user IDs are bad for privacy?", "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-1-title": "E2E-encrypted messages with markdown and editing",
"feature-2-title": "E2E-encrypted<br>images, videos and files", "feature-2-title": "E2E-encrypted<br>images, videos and files",
"feature-3-title": "E2E-encrypted decentralized groups &mdash; only users know they exist", "feature-3-title": "E2E-encrypted decentralized groups &mdash; 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-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-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-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-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": "Read more in <a href=\"/blog/20221108-simplex-chat-v4.2-security-audit-new-website.html\">the announcement</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-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-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.", "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.",
@ -256,4 +256,4 @@
"jobs": "Join team", "jobs": "Join team",
"please-enable-javascript": "Please enable JavaScript to see the QR code.", "please-enable-javascript": "Please enable JavaScript to see the QR code.",
"please-use-link-in-mobile-app": "Please use the link in the mobile app" "please-use-link-in-mobile-app": "Please use the link in the mobile app"
} }

View file

@ -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", "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", "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-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-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>.",
"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>.",
"jobs": "Únete al equipo", "jobs": "Únete al equipo",
"hero-overlay-3-textlink": "Evaluación de la seguridad", "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.", "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.",
@ -256,4 +255,4 @@
"docs-dropdown-10": "Transparencia", "docs-dropdown-10": "Transparencia",
"docs-dropdown-11": "FAQ", "docs-dropdown-11": "FAQ",
"docs-dropdown-12": "Seguridad" "docs-dropdown-12": "Seguridad"
} }

View file

@ -249,8 +249,7 @@
"hero-overlay-3-title": "Turvallisuuden arviointi", "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-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-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-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>.",
"hero-overlay-card-3-p-3": "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-enable-javascript": "Ota JavaScript käyttöön nähdäksesi QR-koodin.",
"please-use-link-in-mobile-app": "Käytä mobiilisovelluksessa olevaa linkkiä" "please-use-link-in-mobile-app": "Käytä mobiilisovelluksessa olevaa linkkiä"
} }

View file

@ -246,8 +246,7 @@
"stable-versions-built-by-f-droid-org": "Versions stables créées par F-Droid.org", "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", "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-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-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>.",
"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>.",
"jobs": "Rejoignez notre équipe", "jobs": "Rejoignez notre équipe",
"hero-overlay-3-textlink": "Évaluation de sécurité", "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.", "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.",
@ -257,4 +256,4 @@
"docs-dropdown-10": "Transparence", "docs-dropdown-10": "Transparence",
"docs-dropdown-12": "Sécurité", "docs-dropdown-12": "Sécurité",
"docs-dropdown-11": "FAQ" "docs-dropdown-11": "FAQ"
} }

View file

@ -87,12 +87,11 @@
"simplex-unique-1-title": "יש לך פרטיות מלאה", "simplex-unique-1-title": "יש לך פרטיות מלאה",
"simplex-private-card-10-point-1": "SimpleX משתמש בכתובות ואישורים אנונימיים זמניים בזוגות עבור כל איש קשר של משתמש או חבר בקבוצה.", "simplex-private-card-10-point-1": "SimpleX משתמש בכתובות ואישורים אנונימיים זמניים בזוגות עבור כל איש קשר של משתמש או חבר בקבוצה.",
"privacy-matters-overlay-card-1-p-1": "הרבה חברות גדולות משתמשות במידע עם מי אתה בקשר כדי להעריך את ההכנסה שלך, למכור לך מוצרים שאתה לא באמת צריך ולקבוע את המחירים.", "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-4": "SimpleX מגן מפני התקפות אלה בכך שאין בעיצובו מזהי משתמש. ואם אתה משתמש במצב זהות נסתרת, יהיה לך שם תצוגה שונה לכל איש קשר, תוך הימנעות מכל מידע משותף ביניהם.",
"hero-overlay-card-2-p-1": "כאשר למשתמשים יש זהויות מתמשכות, גם אם זה רק מספר אקראי, כמו מזהה הפעלה, קיים סיכון שהספק או התוקף יוכלו לראות כיצד המשתמשים מחוברים וכמה הודעות הם שולחים.", "hero-overlay-card-2-p-1": "כאשר למשתמשים יש זהויות מתמשכות, גם אם זה רק מספר אקראי, כמו מזהה הפעלה, קיים סיכון שהספק או התוקף יוכלו לראות כיצד המשתמשים מחוברים וכמה הודעות הם שולחים.",
"hero-overlay-card-1-p-5": "רק מכשירי לקוח מאחסנים פרופילי משתמשים, אנשי קשר וקבוצות; ההודעות נשלחות עם הצפנה דו-שכבתית מקצה לקצה.", "hero-overlay-card-1-p-5": "רק מכשירי לקוח מאחסנים פרופילי משתמשים, אנשי קשר וקבוצות; ההודעות נשלחות עם הצפנה דו-שכבתית מקצה לקצה.",
"privacy-matters-overlay-card-1-p-2": "קמעונאים מקוונים יודעים שאנשים עם הכנסה נמוכה יותר נוטים יותר לבצע רכישות דחופות, ולכן הם עשויים לגבות מחירים גבוהים יותר או להסיר הנחות.", "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 משתמש במזהים אנונימיים זמניים זוגיים של תורי הודעות, נפרדים עבור כל אחד מהחיבורים שלך &mdash; אין מזהים לטווח ארוך.", "hero-overlay-card-1-p-2": "כדי להעביר הודעות, במקום מזהי משתמש המשמשים את כל הפלטפורמות האחרות, SimpleX משתמש במזהים אנונימיים זמניים זוגיים של תורי הודעות, נפרדים עבור כל אחד מהחיבורים שלך &mdash; אין מזהים לטווח ארוך.",
"hero-overlay-card-2-p-2": "לאחר מכן הם יוכלו לקשר מידע זה עם הרשתות החברתיות הציבוריות הקיימות, ולקבוע כמה זהויות אמיתיות.", "hero-overlay-card-2-p-2": "לאחר מכן הם יוכלו לקשר מידע זה עם הרשתות החברתיות הציבוריות הקיימות, ולקבוע כמה זהויות אמיתיות.",
"privacy-matters-overlay-card-1-p-3": "חלק מחברות פיננסיות וביטוח משתמשות בגרפים חברתיים כדי לקבוע שיעורי ריבית ופרמיות. לעתים קרובות זה גורם לאנשים עם הכנסה נמוכה יותר לשלם יותר &mdash; זה ידוע בתור <a href='https://fairbydesign.com/povertypremium/' target='_blank'>'פרמיית עוני'</a>.", "privacy-matters-overlay-card-1-p-3": "חלק מחברות פיננסיות וביטוח משתמשות בגרפים חברתיים כדי לקבוע שיעורי ריבית ופרמיות. לעתים קרובות זה גורם לאנשים עם הכנסה נמוכה יותר לשלם יותר &mdash; זה ידוע בתור <a href='https://fairbydesign.com/povertypremium/' target='_blank'>'פרמיית עוני'</a>.",
@ -256,4 +255,4 @@
"docs-dropdown-10": "שקיפות", "docs-dropdown-10": "שקיפות",
"docs-dropdown-11": "שאלות ותשובות", "docs-dropdown-11": "שאלות ותשובות",
"docs-dropdown-12": "אבטחה" "docs-dropdown-12": "אבטחה"
} }

View file

@ -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-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-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-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-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-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.", "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.", "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ó", "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 &mdash; 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-1-p-3": "Ön határozza meg, hogy melyik kiszolgáló(ka)t használja az üzenetek fogadására, a kapcsolatokhoz &mdash; 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.", "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", "chat-bot-example": "Chat bot példa",
"simplex-private-3-title": "Biztonságos, hitelesített<br>TLS adatátvitel", "simplex-private-3-title": "Biztonságos, hitelesített<br>TLS adatátvitel",
@ -256,4 +255,4 @@
"simplex-chat-via-f-droid": "SimpleX Chat az F-Droidon keresztül", "simplex-chat-via-f-droid": "SimpleX Chat az F-Droidon keresztül",
"simplex-chat-repo": "SimpleX Chat tároló", "simplex-chat-repo": "SimpleX Chat tároló",
"stable-and-beta-versions-built-by-developers": "A fejlesztők által készített stabil és béta verziók" "stable-and-beta-versions-built-by-developers": "A fejlesztők által készített stabil és béta verziók"
} }

View file

@ -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:", "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", "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-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-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>.",
"hero-overlay-card-3-p-3": "Maggiori informazioni nell'<a href=\"/blog/20221108-simplex-chat-v4.2-security-audit-new-website.html\">annuncio</a>.",
"jobs": "Unisciti al team", "jobs": "Unisciti al team",
"hero-overlay-3-textlink": "Valutazione della sicurezza", "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.", "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.",
@ -256,4 +255,4 @@
"docs-dropdown-10": "Trasparenza", "docs-dropdown-10": "Trasparenza",
"docs-dropdown-12": "Sicurezza", "docs-dropdown-12": "Sicurezza",
"docs-dropdown-11": "Domande frequenti" "docs-dropdown-11": "Domande frequenti"
} }

View file

@ -245,15 +245,14 @@
"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>し、アプリを再インストールしてください。", "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>コンテンツパディング", "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-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": "チームに参加する", "jobs": "チームに参加する",
"hero-overlay-3-textlink": "セキュリティ監査", "hero-overlay-3-textlink": "セキュリティ監査",
"hero-overlay-3-title": "セキュリティ監査", "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": "ダウンロード", "docs-dropdown-9": "ダウンロード",
"please-enable-javascript": "QRコードを表示するためにJavaScriptを有効にしてください。", "please-enable-javascript": "QRコードを表示するためにJavaScriptを有効にしてください。",
"please-use-link-in-mobile-app": "このリンクをモバイルアプリで使用してください", "please-use-link-in-mobile-app": "このリンクをモバイルアプリで使用してください",
"docs-dropdown-10": "透明性", "docs-dropdown-10": "透明性",
"docs-dropdown-11": "よくある質問", "docs-dropdown-11": "よくある質問",
"docs-dropdown-12": "セキュリティ" "docs-dropdown-12": "セキュリティ"
} }

View file

@ -245,8 +245,7 @@
"docs-dropdown-8": "SimpleX Directory Service", "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", "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-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-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>.",
"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>.",
"jobs": "Sluit je aan bij het team", "jobs": "Sluit je aan bij het team",
"hero-overlay-3-textlink": "Beveiligings beoordeling", "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.", "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.",
@ -256,4 +255,4 @@
"docs-dropdown-10": "Transparantie", "docs-dropdown-10": "Transparantie",
"docs-dropdown-11": "FAQ", "docs-dropdown-11": "FAQ",
"docs-dropdown-12": "Beveiliging" "docs-dropdown-12": "Beveiliging"
} }

View file

@ -245,8 +245,7 @@
"releases-to-this-repo-are-done-1-2-days-later": "Wydania na tym repo są kilka dni później", "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", "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-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-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>.",
"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>.",
"jobs": "Dołącz do zespołu", "jobs": "Dołącz do zespołu",
"hero-overlay-3-textlink": "Ocena bezpieczeństwa", "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.", "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.",
@ -256,4 +255,4 @@
"docs-dropdown-10": "Przezroczystość", "docs-dropdown-10": "Przezroczystość",
"docs-dropdown-12": "Bezpieczeństwo", "docs-dropdown-12": "Bezpieczeństwo",
"docs-dropdown-11": "Często zadawane pytania" "docs-dropdown-11": "Często zadawane pytania"
} }

View file

@ -246,8 +246,7 @@
"hero-overlay-3-textlink": "Avaliação Segura", "hero-overlay-3-textlink": "Avaliação Segura",
"hero-overlay-3-title": "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-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-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>.",
"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>.",
"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.", "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.", "please-enable-javascript": "Por favor habilite o JavaScript para ver o QR code.",
"jobs": "Junte-se à equipe", "jobs": "Junte-se à equipe",
@ -256,4 +255,4 @@
"docs-dropdown-11": "FAQ", "docs-dropdown-11": "FAQ",
"docs-dropdown-10": "Transparência", "docs-dropdown-10": "Transparência",
"docs-dropdown-12": "Segurança" "docs-dropdown-12": "Segurança"
} }

View file

@ -37,7 +37,8 @@
"simplex-explained-tab-1-text": "1. Как это видят пользователи", "simplex-explained-tab-1-text": "1. Как это видят пользователи",
"tap-to-close": "Нажмите, чтобы закрыть", "tap-to-close": "Нажмите, чтобы закрыть",
"simplex-unique-card-4-p-2": "Вы можете <strong>использовать SimpleX со своими собственными серверами</strong> или с серверами, предоставленными нами &mdash; и при этом подключаться к любому пользователю SimpleX.", "simplex-unique-card-4-p-2": "Вы можете <strong>использовать SimpleX со своими собственными серверами</strong> или с серверами, предоставленными нами &mdash; и при этом подключаться к любому пользователю 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 и редактированием", "feature-1-title": "Сообщения зашифрованные E2E-шифрованием<br>с поддержкой markdown и редактированием",
"comparison-point-4-text": "Единая или Централизованная сеть", "comparison-point-4-text": "Единая или Централизованная сеть",
"guide-dropdown-9": "Установление соединений", "guide-dropdown-9": "Установление соединений",
@ -77,7 +78,6 @@
"simplex-unique-2-overlay-1-title": "Лучшая защита от спама и злоупотреблений", "simplex-unique-2-overlay-1-title": "Лучшая защита от спама и злоупотреблений",
"simplex-private-6-title": "Внеполосный<br>Обмен ключами", "simplex-private-6-title": "Внеполосный<br>Обмен ключами",
"join-us-on-GitHub": "Присоединяйтесь к нам на GitHub", "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": "Сравнение с другими протоколами", "comparison-section-header": "Сравнение с другими протоколами",
"invitation-hero-header": "Вы получили одноразовую ссылку для подключения в SimpleX Chat", "invitation-hero-header": "Вы получили одноразовую ссылку для подключения в SimpleX Chat",
"no-secure": "Нет - безопасно", "no-secure": "Нет - безопасно",
@ -256,4 +256,4 @@
"docs-dropdown-10": "Прозрачность", "docs-dropdown-10": "Прозрачность",
"docs-dropdown-12": "Безопасность", "docs-dropdown-12": "Безопасность",
"docs-dropdown-11": "Часто задаваемые вопросы" "docs-dropdown-11": "Часто задаваемые вопросы"
} }

View file

@ -244,8 +244,7 @@
"stable-and-beta-versions-built-by-developers": "Стабільні та бета-версії, побудовані розробниками", "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> базу даних чату та перевстановіть додаток.", "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-3-title": "Оцінка безпеки",
"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-3-p-3": "Читайте більше в <a href=\"/blog/20221108-simplex-chat-v4.2-security-audit-new-website.html\">оголошенні</a>.",
"jobs": "Приєднатися до команди", "jobs": "Приєднатися до команди",
"hero-overlay-3-textlink": "Оцінка безпеки", "hero-overlay-3-textlink": "Оцінка безпеки",
"hero-overlay-card-3-p-1": "<a href=\"https://www.trailofbits.com/about/\">Trail of Bits</a> є провідною консалтинговою фірмою з безпеки та технологій, клієнтами якої є великі технологічні компанії, урядові агенції та великі проекти у сфері блокчейну.", "hero-overlay-card-3-p-1": "<a href=\"https://www.trailofbits.com/about/\">Trail of Bits</a> є провідною консалтинговою фірмою з безпеки та технологій, клієнтами якої є великі технологічні компанії, урядові агенції та великі проекти у сфері блокчейну.",
@ -256,4 +255,4 @@
"docs-dropdown-11": "ПОШИРЕНІ ЗАПИТАННЯ", "docs-dropdown-11": "ПОШИРЕНІ ЗАПИТАННЯ",
"docs-dropdown-10": "Прозорість", "docs-dropdown-10": "Прозорість",
"docs-dropdown-12": "Безпека" "docs-dropdown-12": "Безпека"
} }

View file

@ -245,8 +245,7 @@
"docs-dropdown-8": "SimpleX 目录服务", "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>聊天数据库并重新安装应用。", "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-3-title": "安全性评估",
"hero-overlay-card-3-p-2": "2022年11月份Trail of Bits 审核了 SimpleX 平台的密码学和网络部件。", "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>。",
"hero-overlay-card-3-p-3": "更多内容见 <a href=\"/blog/20221108-simplex-chat-v4.2-security-audit-new-website.html\">该公告</a>。",
"jobs": "加入团队", "jobs": "加入团队",
"hero-overlay-3-textlink": "安全性评估", "hero-overlay-3-textlink": "安全性评估",
"hero-overlay-card-3-p-1": "<a href=\"https://www.trailofbits.com/about/\">Trail of Bits</a> 是一家领先的安全和技术咨询企业,其客户包括大型科技公司、政府机构和重要的区块链项目。", "hero-overlay-card-3-p-1": "<a href=\"https://www.trailofbits.com/about/\">Trail of Bits</a> 是一家领先的安全和技术咨询企业,其客户包括大型科技公司、政府机构和重要的区块链项目。",
@ -256,4 +255,4 @@
"docs-dropdown-10": "透明度", "docs-dropdown-10": "透明度",
"docs-dropdown-11": "常问问题", "docs-dropdown-11": "常问问题",
"docs-dropdown-12": "安全性" "docs-dropdown-12": "安全性"
} }

View 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>

View 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>

View file

@ -6,4 +6,4 @@
</p> </p>
<p> <p>
{{ "hero-overlay-card-3-p-3" | i18n({}, lang ) | safe }} {{ "hero-overlay-card-3-p-3" | i18n({}, lang ) | safe }}
</p> </p>