From b1a6dec9b5f22faca52996a11042c01c5b520b12 Mon Sep 17 00:00:00 2001 From: Evgeny Poberezkin <2769109+epoberezkin@users.noreply.github.com> Date: Sat, 26 Aug 2023 16:32:03 +0100 Subject: [PATCH 1/3] desktop (mac): signing and notarization (#2981) * mac: signing and notarization * updated example * updated action * update build script * move mac CI script to file --------- Co-authored-by: Avently <7953703+avently@users.noreply.github.com> --- .github/workflows/build.yml | 4 +--- apps/multiplatform/build.gradle.kts | 14 ++++++++++++-- apps/multiplatform/desktop/build.gradle.kts | 17 +++++++++++++++++ apps/multiplatform/local.properties.example | 10 ++++++++++ scripts/desktop/build-desktop-mac-ci.sh | 16 ++++++++++++++++ 5 files changed, 56 insertions(+), 5 deletions(-) create mode 100644 apps/multiplatform/local.properties.example create mode 100755 scripts/desktop/build-desktop-mac-ci.sh diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 1ac690d22..09412eee5 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -167,9 +167,7 @@ jobs: if: startsWith(github.ref, 'refs/tags/v') && matrix.os == 'macos-latest' shell: bash run: | - scripts/desktop/build-lib-mac.sh - cd apps/multiplatform - ./gradlew packageDmg + scripts/desktop/build-desktop-mac-ci.sh echo "::set-output name=package_path::$(echo $PWD/release/main/dmg/SimpleX-*.dmg)" - name: Linux upload desktop package to release diff --git a/apps/multiplatform/build.gradle.kts b/apps/multiplatform/build.gradle.kts index bd5da47a1..5e0ae5eb4 100644 --- a/apps/multiplatform/build.gradle.kts +++ b/apps/multiplatform/build.gradle.kts @@ -1,6 +1,5 @@ -import org.gradle.initialization.Environment.Properties import java.io.File -import java.io.FileInputStream +import java.util.* buildscript { val prop = java.util.Properties().apply { @@ -26,6 +25,17 @@ buildscript { extra.set("compression.level", (prop["compression.level"] as String?)?.toIntOrNull() ?: 0) // NOTE: If you need a different version of something, provide it in `local.properties` // like so: compose.version=123, or gradle.plugin.version=1.2.3, etc + + + /** Mac signing and notarization */ + // You can specify `compose.desktop.mac.*` keys and values from the right side of the command in `$HOME/.gradle/gradle.properties`. + // This will be project-independent setup without requiring to have `local.properties` file + extra.set("desktop.mac.signing.identity", prop["desktop.mac.signing.identity"] ?: extra["compose.desktop.mac.signing.identity"]) + extra.set("desktop.mac.signing.keychain", prop["desktop.mac.signing.keychain"] ?: extra["compose.desktop.mac.signing.keychain"]) + extra.set("desktop.mac.notarization.apple_id", prop["desktop.mac.notarization.apple_id"] ?: extra["compose.desktop.mac.notarization.appleID"]) + extra.set("desktop.mac.notarization.password", prop["desktop.mac.notarization.password"] ?: extra["compose.desktop.mac.notarization.password"]) + extra.set("desktop.mac.notarization.team_id", prop["desktop.mac.notarization.team_id"] ?: extra["compose.desktop.mac.notarization.ascProvider"]) + repositories { google() mavenCentral() diff --git a/apps/multiplatform/desktop/build.gradle.kts b/apps/multiplatform/desktop/build.gradle.kts index 1d463a9de..dc4aa89fb 100644 --- a/apps/multiplatform/desktop/build.gradle.kts +++ b/apps/multiplatform/desktop/build.gradle.kts @@ -65,6 +65,23 @@ compose { iconFile.set(project.file("src/jvmMain/resources/distribute/simplex.icns")) appCategory = "public.app-category.social-networking" bundleID = "chat.simplex.app" + val identity = rootProject.extra["desktop.mac.signing.identity"] as String? + val keychain = rootProject.extra["desktop.mac.signing.keychain"] as String? + val appleId = rootProject.extra["desktop.mac.notarization.apple_id"] as String? + val password = rootProject.extra["desktop.mac.notarization.password"] as String? + val teamId = rootProject.extra["desktop.mac.notarization.team_id"] as String? + if (identity != null && keychain != null && appleId != null && password != null) { + signing { + sign.set(true) + this.identity.set(identity) + this.keychain.set(keychain) + } + notarization { + this.appleID.set(appleId) + this.password.set(password) + this.ascProvider.set(teamId) + } + } } val os = System.getProperty("os.name", "generic").toLowerCaseAsciiOnly() if (os.contains("mac") || os.contains("win")) { diff --git a/apps/multiplatform/local.properties.example b/apps/multiplatform/local.properties.example new file mode 100644 index 000000000..8fa9a4796 --- /dev/null +++ b/apps/multiplatform/local.properties.example @@ -0,0 +1,10 @@ +compression.level=0 +enable_debuggable=true +application_id.suffix=.debug +app.name=SimpleX Debug + +#desktop.mac.signing.identity=SimpleX Chat Ltd +#desktop.mac.signing.keychain=/path/to/simplex.keychain +#desktop.mac.notarization.apple_id=example@example.com +#desktop.mac.notarization.password=12345678 +#desktop.mac.notarization.team_id=XXXXXXXXXX diff --git a/scripts/desktop/build-desktop-mac-ci.sh b/scripts/desktop/build-desktop-mac-ci.sh new file mode 100755 index 000000000..d11dfccb5 --- /dev/null +++ b/scripts/desktop/build-desktop-mac-ci.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +set -e + +trap "rm apps/multiplatform/local.properties; rm /tmp/simplex.keychain" EXIT +echo "desktop.mac.signing.identity=Developer ID Application: SimpleX Chat Ltd (5NN7GUYB6T)" >> apps/multiplatform/local.properties +echo "desktop.mac.signing.keychain=/tmp/simplex.keychain" >> apps/multiplatform/local.properties +echo "desktop.mac.notarization.apple_id=$APPLE_SIMPLEX_NOTARIZATION_APPLE_ID" >> apps/multiplatform/local.properties +echo "desktop.mac.notarization.password=$APPLE_SIMPLEX_NOTARIZATION_PASSWORD" >> apps/multiplatform/local.properties +echo "desktop.mac.notarization.team_id=5NN7GUYB6T" >> apps/multiplatform/local.properties +echo "$APPLE_SIMPLEX_SIGNING_KEYCHAIN" | base64 --decode - > /tmp/simplex.keychain + +scripts/desktop/build-lib-mac.sh +cd apps/multiplatform +./gradlew packageDmg +./gradlew notarizeDmg From 79e1bdaf61d0b01bfca72ad7f74aecf25e09124c Mon Sep 17 00:00:00 2001 From: Evgeny Poberezkin <2769109+epoberezkin@users.noreply.github.com> Date: Sat, 26 Aug 2023 16:51:05 +0100 Subject: [PATCH 2/3] rfc: improving iOS notifications --- docs/rfcs/2023-08-26-ios-notifications.md | 26 +++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 docs/rfcs/2023-08-26-ios-notifications.md diff --git a/docs/rfcs/2023-08-26-ios-notifications.md b/docs/rfcs/2023-08-26-ios-notifications.md new file mode 100644 index 000000000..74ee58932 --- /dev/null +++ b/docs/rfcs/2023-08-26-ios-notifications.md @@ -0,0 +1,26 @@ +# Problem + +iOS notifications are not stable, and crash in the background for many users. The reason for that is concurrent database access from the main app and from NSE processes. While there are measures preventing NSE execution while the main app is running, there is nothing preventing continued NSE execution after the app returns to the foreground. + +While iOS creates a new instance of the notification service class for each incoming mutable notification, it re-uses the same process. + +In addition to that, while NSE avoids subscribing to the existing connections to avoid disrupting the subscriptions from the main app, it can create new connections, specifically for legacy file transfers (not important) and for member connections (very important), so the NSE may continue receiving the messages from these new connections, creating database contention, and at the same time the main app won't subscribe to these connections until it is restarted. + +# Possible solutions + +We could consider using WAL mode to increase SQLite concurrency, but it means that WAL files have to be included in the database archive, which is currently not done. It is unclear if it can only be one or multiple files. + +We should also consider some mechanism of suspending NSE when the app returns to the foreground, e.g. via: +- checking the shared preference in message reception loop, although it may be too late to prevent the database contention. +- checking the shared preference frequently and suspending the core, but it can be expensive. +- using Mach messages to communicate to NSE that app is resumed so it can suspend itself. + +The problem with connection subscriptions can be addressed in this way: + +1. Any connections created in NSE will use additional parameter in all APIs to avoid creating subscriptions. +2. The information about these connections will be stored in the database as "requiring subscription". +3. The main app will subscribe to them when it is resumed. + +This is similar to how XFTP files are marked as "to be received" when the message is received by NSE. + +If this is agreed, then this require changing the whole stack, including SMP protocol, as currently the subscription is done automatically when the connection is created. From ebb4c860b7b00e339ac34f80e74cfd929f9fd8cb Mon Sep 17 00:00:00 2001 From: Evgeny Poberezkin <2769109+epoberezkin@users.noreply.github.com> Date: Sat, 26 Aug 2023 18:36:34 +0100 Subject: [PATCH 3/3] 5.3.0.6: update simplexmq (create database path) --- cabal.project | 2 +- package.yaml | 2 +- scripts/nix/sha256map.nix | 2 +- simplex-chat.cabal | 2 +- stack.yaml | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/cabal.project b/cabal.project index f30b96ea7..1be6c7365 100644 --- a/cabal.project +++ b/cabal.project @@ -9,7 +9,7 @@ constraints: zip +disable-bzip2 +disable-zstd source-repository-package type: git location: https://github.com/simplex-chat/simplexmq.git - tag: 066d91b0f594e1c9a9c584900cc133e9cec01e55 + tag: 4c0b8a31d20870a23e120e243359901d8240f922 source-repository-package type: git diff --git a/package.yaml b/package.yaml index 6d3975aa4..68e7acda7 100644 --- a/package.yaml +++ b/package.yaml @@ -1,5 +1,5 @@ name: simplex-chat -version: 5.3.0.5 +version: 5.3.0.6 #synopsis: #description: homepage: https://github.com/simplex-chat/simplex-chat#readme diff --git a/scripts/nix/sha256map.nix b/scripts/nix/sha256map.nix index 58fdf3d53..f3ad3061a 100644 --- a/scripts/nix/sha256map.nix +++ b/scripts/nix/sha256map.nix @@ -1,5 +1,5 @@ { - "https://github.com/simplex-chat/simplexmq.git"."066d91b0f594e1c9a9c584900cc133e9cec01e55" = "0qy8k0fjqaw16xh2abi8852vxhkm0490vl0ljnlz2bkqgv3iz4qs"; + "https://github.com/simplex-chat/simplexmq.git"."4c0b8a31d20870a23e120e243359901d8240f922" = "0lrgfm8di0x4rmidqp7k2fw29yaal6467nmb85lwk95yz602906z"; "https://github.com/simplex-chat/hs-socks.git"."a30cc7a79a08d8108316094f8f2f82a0c5e1ac51" = "0yasvnr7g91k76mjkamvzab2kvlb1g5pspjyjn2fr6v83swjhj38"; "https://github.com/kazu-yamamoto/http2.git"."b5a1b7200cf5bc7044af34ba325284271f6dff25" = "0dqb50j57an64nf4qcf5vcz4xkd1vzvghvf8bk529c1k30r9nfzb"; "https://github.com/simplex-chat/direct-sqlcipher.git"."34309410eb2069b029b8fc1872deb1e0db123294" = "0kwkmhyfsn2lixdlgl15smgr1h5gjk7fky6abzh8rng2h5ymnffd"; diff --git a/simplex-chat.cabal b/simplex-chat.cabal index e53f047a2..f26e3432c 100644 --- a/simplex-chat.cabal +++ b/simplex-chat.cabal @@ -5,7 +5,7 @@ cabal-version: 1.12 -- see: https://github.com/sol/hpack name: simplex-chat -version: 5.3.0.5 +version: 5.3.0.6 category: Web, System, Services, Cryptography homepage: https://github.com/simplex-chat/simplex-chat#readme author: simplex.chat diff --git a/stack.yaml b/stack.yaml index bfe6f1d2a..d86d8fe57 100644 --- a/stack.yaml +++ b/stack.yaml @@ -49,7 +49,7 @@ extra-deps: # - simplexmq-1.0.0@sha256:34b2004728ae396e3ae449cd090ba7410781e2b3cefc59259915f4ca5daa9ea8,8561 # - ../simplexmq - github: simplex-chat/simplexmq - commit: 066d91b0f594e1c9a9c584900cc133e9cec01e55 + commit: 4c0b8a31d20870a23e120e243359901d8240f922 - github: kazu-yamamoto/http2 commit: b5a1b7200cf5bc7044af34ba325284271f6dff25 # - ../direct-sqlcipher