diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ad4dbf15..23e19225 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -69,3 +69,28 @@ jobs: with: name: signal-cli-native path: build/native/nativeCompile/signal-cli + + build-client: + strategy: + matrix: + os: + - ubuntu + - macos + - windows + runs-on: ${{ matrix.os }}-latest + defaults: + run: + working-directory: ./client + steps: + - uses: actions/checkout@v4 + - name: Install rust + run: rustup default stable + - name: Build client + run: cargo build --release --verbose + - name: Archive production artifacts + uses: actions/upload-artifact@v4 + with: + name: signal-cli-client-${{ matrix.os }} + path: | + client/target/release/signal-cli-client + client/target/release/signal-cli-client.exe diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index b1f4027d..b7ce03f1 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -182,7 +182,7 @@ jobs: tar xf ./"${ARCHIVE_DIR}"/*.tar.gz rm -r signal-cli-archive-* signal-cli-native mkdir -p build/install/ - mv ./signal-cli-*/ build/install/signal-cli + mv ./signal-cli-"${GITHUB_REF_NAME#v}"/ build/install/signal-cli - name: Build Image id: build_image diff --git a/CHANGELOG.md b/CHANGELOG.md index 62abfe70..74d0bdc0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,25 @@ # Changelog +## [Unreleased] + +## [0.13.18] - 2025-07-16 + +Requires libsignal-client version 0.76.3. + +### Added + +- Added `--view-once` parameter to send command to send view once images + +### Fixed + +- Handle rate limit exception correctly when querying usernames + +### Improved + +- Shut down when dbus daemon connection goes away unexpectedly +- In daemon mode, exit immediately if account check fails at startup +- Improve behavior when sending to devices that have no available prekeys + ## [0.13.17] - 2025-06-28 Requires libsignal-client version 0.76.0. diff --git a/README.md b/README.md index e6d6e5ff..c7228c09 100644 --- a/README.md +++ b/README.md @@ -83,6 +83,12 @@ of all country codes.) signal-cli -a ACCOUNT send -m "This is a message" RECIPIENT ``` +* Send a message to a username, usernames need to be prefixed with `u:` + + ```sh + signal-cli -a ACCOUNT send -m "This is a message" u:USERNAME.000 + ``` + * Pipe the message content from another process. uname -a | signal-cli -a ACCOUNT send --message-from-stdin RECIPIENT diff --git a/build.gradle.kts b/build.gradle.kts index 11715e36..ea69d97e 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -8,7 +8,7 @@ plugins { allprojects { group = "org.asamk" - version = "0.13.17" + version = "0.13.19-SNAPSHOT" } java { diff --git a/buildSrc/src/main/kotlin/CheckLibVersionsPlugin.kt b/buildSrc/src/main/kotlin/CheckLibVersionsPlugin.kt index eb74acb2..ae8ae4de 100644 --- a/buildSrc/src/main/kotlin/CheckLibVersionsPlugin.kt +++ b/buildSrc/src/main/kotlin/CheckLibVersionsPlugin.kt @@ -1,12 +1,10 @@ @file:Suppress("DEPRECATION") -import groovy.util.XmlSlurper -import groovy.util.slurpersupport.GPathResult -import org.codehaus.groovy.runtime.ResourceGroovyMethods import org.gradle.api.Plugin import org.gradle.api.Project import org.gradle.api.Task import org.gradle.api.artifacts.Dependency +import javax.xml.parsers.DocumentBuilderFactory class CheckLibVersionsPlugin : Plugin { override fun apply(project: Project) { @@ -28,10 +26,10 @@ class CheckLibVersionsPlugin : Plugin { val name = dependency.name val metaDataUrl = "https://repo1.maven.org/maven2/$path/$name/maven-metadata.xml" try { - val url = ResourceGroovyMethods.toURL(metaDataUrl) - val metaDataText = ResourceGroovyMethods.getText(url) - val metadata = XmlSlurper().parseText(metaDataText) - val newest = (metadata.getProperty("versioning") as GPathResult).getProperty("latest") + val dbf = DocumentBuilderFactory.newInstance() + val db = dbf.newDocumentBuilder() + val doc = db.parse(metaDataUrl); + val newest = doc.getElementsByTagName("latest").item(0).textContent if (version != newest.toString()) { println("UPGRADE {\"group\": \"$group\", \"name\": \"$name\", \"current\": \"$version\", \"latest\": \"$newest\"}") } diff --git a/client/Cargo.lock b/client/Cargo.lock index d0cd01f4..01f28e0c 100644 --- a/client/Cargo.lock +++ b/client/Cargo.lock @@ -13,15 +13,15 @@ dependencies = [ [[package]] name = "adler2" -version = "2.0.0" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" +checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" [[package]] name = "anstream" -version = "0.6.18" +version = "0.6.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b" +checksum = "301af1932e46185686725e0fad2f8f2aa7da69dd70bf6ecc44d6b703844a3933" dependencies = [ "anstyle", "anstyle-parse", @@ -34,44 +34,44 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.10" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" +checksum = "862ed96ca487e809f1c8e5a8447f6ee2cf102f846893800b20cebdf541fc6bbd" [[package]] name = "anstyle-parse" -version = "0.2.6" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9" +checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.1.2" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" +checksum = "6c8bdeb6047d8983be085bab0ba1472e6dc604e7041dbf6fcd5e71523014fae9" dependencies = [ "windows-sys 0.59.0", ] [[package]] name = "anstyle-wincon" -version = "3.0.7" +version = "3.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca3534e77181a9cc07539ad51f2141fe32f6c3ffd4df76db8ad92346b003ae4e" +checksum = "403f75924867bb1033c59fbf0797484329750cfbe3c4325cd33127941fabc882" dependencies = [ "anstyle", - "once_cell", + "once_cell_polyfill", "windows-sys 0.59.0", ] [[package]] name = "anyhow" -version = "1.0.97" +version = "1.0.98" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcfed56ad506cb2c684a14971b8861fdc3baaaae314b9e5f9bb532cbe3ba7a4f" +checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487" [[package]] name = "async-trait" @@ -90,17 +90,11 @@ version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" -[[package]] -name = "autocfg" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" - [[package]] name = "backtrace" -version = "0.3.74" +version = "0.3.75" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" +checksum = "6806a6321ec58106fea15becdad98371e28d92ccbc7c8f1b3b6dd724fe8f1002" dependencies = [ "addr2line", "cfg-if", @@ -119,9 +113,9 @@ checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" [[package]] name = "bitflags" -version = "2.9.0" +version = "2.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd" +checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967" [[package]] name = "bytes" @@ -131,9 +125,9 @@ checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" [[package]] name = "cc" -version = "1.2.18" +version = "1.2.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "525046617d8376e3db1deffb079e91cef90a89fc3ca5c185bbf8c9ecdd15cd5c" +checksum = "5c1599538de2394445747c8cf7935946e3cc27e9625f889d979bfb2aaf569362" dependencies = [ "shlex", ] @@ -146,15 +140,15 @@ checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" [[package]] name = "cfg-if" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268" [[package]] name = "clap" -version = "4.5.35" +version = "4.5.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8aa86934b44c19c50f87cc2790e19f54f7a67aedb64101c2e1a2e5ecfb73944" +checksum = "be92d32e80243a54711e5d7ce823c35c41c9d929dc4ab58e1276f625841aadf9" dependencies = [ "clap_builder", "clap_derive", @@ -162,9 +156,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.35" +version = "4.5.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2414dbb2dd0695280da6ea9261e327479e9d37b0630f6b53ba2a11c60c679fd9" +checksum = "707eab41e9622f9139419d573eca0900137718000c517d47da73045f54331c3d" dependencies = [ "anstream", "anstyle", @@ -175,9 +169,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.32" +version = "4.5.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09176aae279615badda0765c0c0b3f6ed53f4709118af73cf4655d85d1530cd7" +checksum = "ef4f52386a59ca4c860f7393bcf8abd8dfd91ecccc0f774635ff68e92eeef491" dependencies = [ "heck", "proc-macro2", @@ -187,15 +181,15 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.7.4" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" +checksum = "b94f61472cee1439c0b966b47e3aca9ae07e45d070759512cd390ea2bebc6675" [[package]] name = "colorchoice" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" +checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" [[package]] name = "combine" @@ -209,9 +203,9 @@ dependencies = [ [[package]] name = "core-foundation" -version = "0.10.0" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b55271e5c8c478ad3f38ad24ef34923091e0548492a266d19b3c0b4d82574c63" +checksum = "b2a6cd9ae233e7f62ba4e9353e81a88df7fc8a5987b8d445b4d90c879bd156f6" dependencies = [ "core-foundation-sys", "libc", @@ -242,12 +236,12 @@ checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" [[package]] name = "errno" -version = "0.3.11" +version = "0.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "976dd42dc7e85965fe702eb8164f21f450704bdde31faefd6471dba214cb594e" +checksum = "778e2ac28f6c47af28e4907f13ffd1e1ddbd400980a9abd7c8df189bf578a5ad" dependencies = [ "libc", - "windows-sys 0.59.0", + "windows-sys 0.60.2", ] [[package]] @@ -326,9 +320,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.15" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" dependencies = [ "cfg-if", "libc", @@ -343,9 +337,9 @@ checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" [[package]] name = "h2" -version = "0.4.8" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5017294ff4bb30944501348f6f8e42e6ad28f42c8bbef7a74029aff064a4e3c2" +checksum = "17da50a276f1e01e0ba6c029e47b7100754904ee8a278f886546e98575380785" dependencies = [ "atomic-waker", "bytes", @@ -362,9 +356,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.15.2" +version = "0.15.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" +checksum = "5971ac85611da7067dbfcabef3c70ebb5606018acd9e2a3903a0da507521e0d5" [[package]] name = "heck" @@ -434,11 +428,10 @@ dependencies = [ [[package]] name = "hyper-rustls" -version = "0.27.5" +version = "0.27.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d191583f3da1305256f22463b9bb0471acad48a4e534a5218b9963e9c1f59b2" +checksum = "e3c93eb611681b207e1fe55d5a71ecf91572ec8a6705cdb6857f7d8d5242cf58" dependencies = [ - "futures-util", "http", "hyper", "hyper-util", @@ -452,12 +445,13 @@ dependencies = [ [[package]] name = "hyper-util" -version = "0.1.11" +version = "0.1.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "497bbc33a26fdd4af9ed9c70d63f61cf56a938375fbb32df34db9b1cd6d643f2" +checksum = "7f66d5bd4c6f02bf0542fad85d626775bab9258cf795a4256dcaf3161114d1df" dependencies = [ "bytes", "futures-channel", + "futures-core", "futures-util", "http", "http-body", @@ -472,21 +466,22 @@ dependencies = [ [[package]] name = "icu_collections" -version = "1.5.0" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526" +checksum = "200072f5d0e3614556f94a9930d5dc3e0662a652823904c3a75dc3b0af7fee47" dependencies = [ "displaydoc", + "potential_utf", "yoke", "zerofrom", "zerovec", ] [[package]] -name = "icu_locid" -version = "1.5.0" +name = "icu_locale_core" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637" +checksum = "0cde2700ccaed3872079a65fb1a78f6c0a36c91570f28755dda67bc8f7d9f00a" dependencies = [ "displaydoc", "litemap", @@ -495,31 +490,11 @@ dependencies = [ "zerovec", ] -[[package]] -name = "icu_locid_transform" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e" -dependencies = [ - "displaydoc", - "icu_locid", - "icu_locid_transform_data", - "icu_provider", - "tinystr", - "zerovec", -] - -[[package]] -name = "icu_locid_transform_data" -version = "1.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7515e6d781098bf9f7205ab3fc7e9709d34554ae0b21ddbcb5febfa4bc7df11d" - [[package]] name = "icu_normalizer" -version = "1.5.0" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f" +checksum = "436880e8e18df4d7bbc06d58432329d6458cc84531f7ac5f024e93deadb37979" dependencies = [ "displaydoc", "icu_collections", @@ -527,67 +502,54 @@ dependencies = [ "icu_properties", "icu_provider", "smallvec", - "utf16_iter", - "utf8_iter", - "write16", "zerovec", ] [[package]] name = "icu_normalizer_data" -version = "1.5.1" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5e8338228bdc8ab83303f16b797e177953730f601a96c25d10cb3ab0daa0cb7" +checksum = "00210d6893afc98edb752b664b8890f0ef174c8adbb8d0be9710fa66fbbf72d3" [[package]] name = "icu_properties" -version = "1.5.1" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5" +checksum = "016c619c1eeb94efb86809b015c58f479963de65bdb6253345c1a1276f22e32b" dependencies = [ "displaydoc", "icu_collections", - "icu_locid_transform", + "icu_locale_core", "icu_properties_data", "icu_provider", - "tinystr", + "potential_utf", + "zerotrie", "zerovec", ] [[package]] name = "icu_properties_data" -version = "1.5.1" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85fb8799753b75aee8d2a21d7c14d9f38921b54b3dbda10f5a3c7a7b82dba5e2" +checksum = "298459143998310acd25ffe6810ed544932242d3f07083eee1084d83a71bd632" [[package]] name = "icu_provider" -version = "1.5.0" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9" +checksum = "03c80da27b5f4187909049ee2d72f276f0d9f99a42c306bd0131ecfe04d8e5af" dependencies = [ "displaydoc", - "icu_locid", - "icu_provider_macros", + "icu_locale_core", "stable_deref_trait", "tinystr", "writeable", "yoke", "zerofrom", + "zerotrie", "zerovec", ] -[[package]] -name = "icu_provider_macros" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "idna" version = "1.0.3" @@ -601,9 +563,9 @@ dependencies = [ [[package]] name = "idna_adapter" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71" +checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" dependencies = [ "icu_normalizer", "icu_properties", @@ -611,14 +573,25 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.9.0" +version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cea70ddb795996207ad57735b50c5982d8844f38ba9ee5f1aedcfb708a2aa11e" +checksum = "fe4cd85333e22411419a0bcae1297d25e58c9443848b11dc6a86fefe8c78a661" dependencies = [ "equivalent", "hashbrown", ] +[[package]] +name = "io-uring" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b86e202f00093dcba4275d4636b93ef9dd75d025ae560d2521b45ea28ab49013" +dependencies = [ + "bitflags", + "cfg-if", + "libc", +] + [[package]] name = "is_terminal_polyfill" version = "1.70.1" @@ -655,9 +628,9 @@ checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" [[package]] name = "jsonrpsee" -version = "0.24.9" +version = "0.25.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37b26c20e2178756451cfeb0661fb74c47dd5988cb7e3939de7e9241fd604d42" +checksum = "1fba77a59c4c644fd48732367624d1bcf6f409f9c9a286fbc71d2f1fc0b2ea16" dependencies = [ "jsonrpsee-core", "jsonrpsee-http-client", @@ -668,9 +641,9 @@ dependencies = [ [[package]] name = "jsonrpsee-core" -version = "0.24.9" +version = "0.25.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "456196007ca3a14db478346f58c7238028d55ee15c1df15115596e411ff27925" +checksum = "693c93cbb7db25f4108ed121304b671a36002c2db67dff2ee4391a688c738547" dependencies = [ "async-trait", "bytes", @@ -684,19 +657,19 @@ dependencies = [ "rustc-hash", "serde", "serde_json", - "thiserror 1.0.69", + "thiserror 2.0.12", "tokio", "tokio-stream", + "tower", "tracing", ] [[package]] name = "jsonrpsee-http-client" -version = "0.24.9" +version = "0.25.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c872b6c9961a4ccc543e321bb5b89f6b2d2c7fe8b61906918273a3333c95400c" +checksum = "6962d2bd295f75e97dd328891e58fce166894b974c1f7ce2e7597f02eeceb791" dependencies = [ - "async-trait", "base64", "http-body", "hyper", @@ -708,18 +681,17 @@ dependencies = [ "rustls-platform-verifier", "serde", "serde_json", - "thiserror 1.0.69", + "thiserror 2.0.12", "tokio", "tower", - "tracing", "url", ] [[package]] name = "jsonrpsee-proc-macros" -version = "0.24.9" +version = "0.25.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e65763c942dfc9358146571911b0cd1c361c2d63e2d2305622d40d36376ca80" +checksum = "2fa4f5daed39f982a1bb9d15449a28347490ad42b212f8eaa2a2a344a0dce9e9" dependencies = [ "heck", "proc-macro-crate", @@ -730,33 +702,33 @@ dependencies = [ [[package]] name = "jsonrpsee-types" -version = "0.24.9" +version = "0.25.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08a8e70baf945b6b5752fc8eb38c918a48f1234daf11355e07106d963f860089" +checksum = "66df7256371c45621b3b7d2fb23aea923d577616b9c0e9c0b950a6ea5c2be0ca" dependencies = [ "http", "serde", "serde_json", - "thiserror 1.0.69", + "thiserror 2.0.12", ] [[package]] name = "libc" -version = "0.2.171" +version = "0.2.174" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c19937216e9d3aa9956d9bb8dfc0b0c8beb6058fc4f7a4dc4d850edf86a237d6" +checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776" [[package]] name = "linux-raw-sys" -version = "0.9.3" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe7db12097d22ec582439daf8618b8fdd1a7bef6270e9af3b1ebcd30893cf413" +checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12" [[package]] name = "litemap" -version = "0.7.5" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23fb14cb19457329c82206317a5663005a4d404783dc74f4252769b0d5f42856" +checksum = "241eaef5fd12c88705a01fc1066c48c4b36e0dd4377dcdc7ec3942cea7a69956" [[package]] name = "log" @@ -766,28 +738,28 @@ checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" [[package]] name = "memchr" -version = "2.7.4" +version = "2.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" +checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0" [[package]] name = "miniz_oxide" -version = "0.8.7" +version = "0.8.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff70ce3e48ae43fa075863cef62e8b43b71a4f2382229920e0df362592919430" +checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" dependencies = [ "adler2", ] [[package]] name = "mio" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd" +checksum = "78bed444cc8a2160f01cbcf811ef18cac863ad68ae8ca62092e8db51d51c761c" dependencies = [ "libc", "wasi", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -805,6 +777,12 @@ version = "1.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" +[[package]] +name = "once_cell_polyfill" +version = "1.70.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4895175b425cb1f87721b59f0f286c2092bd4af812243672510e1ac53e2e0ad" + [[package]] name = "openssl-probe" version = "0.1.6" @@ -849,6 +827,15 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +[[package]] +name = "potential_utf" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5a7c30837279ca13e7c867e9e40053bc68740f988cb07f7ca6df43cc734b585" +dependencies = [ + "zerovec", +] + [[package]] name = "proc-macro-crate" version = "3.3.0" @@ -860,9 +847,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.94" +version = "1.0.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a31971752e70b8b2686d7e46ec17fb38dad4051d94024c88df49b667caea9c84" +checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" dependencies = [ "unicode-ident", ] @@ -892,9 +879,9 @@ dependencies = [ [[package]] name = "rustc-demangle" -version = "0.1.24" +version = "0.1.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" +checksum = "989e6739f80c4ad5b13e0fd7fe89531180375b18520cc8c82080e4dc4035b84f" [[package]] name = "rustc-hash" @@ -904,9 +891,9 @@ checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" [[package]] name = "rustix" -version = "1.0.5" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d97817398dd4bb2e6da002002db259209759911da105da92bec29ccb12cf58bf" +checksum = "c71e83d6afe7ff64890ec6b71d6a69bb8a610ab78ce364b3352876bb4c801266" dependencies = [ "bitflags", "errno", @@ -917,9 +904,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.25" +version = "0.23.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "822ee9188ac4ec04a2f0531e55d035fb2de73f18b41a63c70c2712503b6fb13c" +checksum = "2491382039b29b9b11ff08b76ff6c97cf287671dbb74f0be44bda389fffe9bd1" dependencies = [ "log", "once_cell", @@ -944,15 +931,18 @@ dependencies = [ [[package]] name = "rustls-pki-types" -version = "1.11.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "917ce264624a4b4db1c364dcc35bfca9ded014d0a958cd47ad3e960e988ea51c" +checksum = "229a4a4c221013e7e1f1a043678c5cc39fe5171437c88fb47151a21e6f5b5c79" +dependencies = [ + "zeroize", +] [[package]] name = "rustls-platform-verifier" -version = "0.5.1" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a5467026f437b4cb2a533865eaa73eb840019a0916f4b9ec563c6e617e086c9" +checksum = "19787cda76408ec5404443dc8b31795c87cd8fec49762dc75fa727740d34acc1" dependencies = [ "core-foundation", "core-foundation-sys", @@ -965,7 +955,7 @@ dependencies = [ "rustls-webpki", "security-framework", "security-framework-sys", - "webpki-root-certs", + "webpki-root-certs 0.26.11", "windows-sys 0.59.0", ] @@ -977,9 +967,9 @@ checksum = "f87165f0995f63a9fbeea62b64d10b4d9d8e78ec6d7d51fb2125fda7bb36788f" [[package]] name = "rustls-webpki" -version = "0.103.1" +version = "0.103.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fef8b8769aaccf73098557a87cd1816b4f9c7c16811c9c77142aa695c16f2c03" +checksum = "0a17884ae0c1b773f1ccd2bd4a8c72f16da897310a98b0e84bf349ad5ead92fc" dependencies = [ "ring", "rustls-pki-types", @@ -1080,7 +1070,6 @@ dependencies = [ "clap", "futures-util", "jsonrpsee", - "log", "serde", "serde_json", "thiserror 2.0.12", @@ -1090,24 +1079,21 @@ dependencies = [ [[package]] name = "slab" -version = "0.4.9" +version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" -dependencies = [ - "autocfg", -] +checksum = "04dc19736151f35336d325007ac991178d504a119863a2fcb3758cdb5e52c50d" [[package]] name = "smallvec" -version = "1.15.0" +version = "1.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8917285742e9f3e1683f0a9c4e6b57960b7314d0b08d30d1ecd426713ee2eee9" +checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" [[package]] name = "socket2" -version = "0.5.9" +version = "0.5.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f5fd57c80058a56cf5c777ab8a126398ece8e442983605d280a44ce79d0edef" +checksum = "e22376abed350d73dd1cd119b57ffccad95b4e585a7cda43e286245ce23c0678" dependencies = [ "libc", "windows-sys 0.52.0", @@ -1133,9 +1119,9 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "syn" -version = "2.0.100" +version = "2.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0" +checksum = "17b6f705963418cdb9927482fa304bc562ece2fdd4f616084c50b7023b435a40" dependencies = [ "proc-macro2", "quote", @@ -1143,10 +1129,16 @@ dependencies = [ ] [[package]] -name = "synstructure" -version = "0.13.1" +name = "sync_wrapper" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" +checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" + +[[package]] +name = "synstructure" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" dependencies = [ "proc-macro2", "quote", @@ -1205,9 +1197,9 @@ dependencies = [ [[package]] name = "tinystr" -version = "0.7.6" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f" +checksum = "5d4f6d1145dcb577acf783d4e601bc1d76a13337bb54e6233add580b07344c8b" dependencies = [ "displaydoc", "zerovec", @@ -1215,15 +1207,17 @@ dependencies = [ [[package]] name = "tokio" -version = "1.44.2" +version = "1.46.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6b88822cbe49de4185e3a4cbf8321dd487cf5fe0c5c65695fef6346371e9c48" +checksum = "0cc3a2344dafbe23a245241fe8b09735b521110d30fcefbbd5feb1797ca35d17" dependencies = [ "backtrace", "bytes", + "io-uring", "libc", "mio", "pin-project-lite", + "slab", "socket2", "tokio-macros", "windows-sys 0.52.0", @@ -1263,9 +1257,9 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.14" +version = "0.7.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b9590b93e6fcc1739458317cccd391ad3955e2bde8913edf6f95f9e65a8f034" +checksum = "66a539a9ad6d5d281510d5bd368c973d636c02dbf8a67300bfb6b950696ad7df" dependencies = [ "bytes", "futures-core", @@ -1276,15 +1270,15 @@ dependencies = [ [[package]] name = "toml_datetime" -version = "0.6.8" +version = "0.6.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" +checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c" [[package]] name = "toml_edit" -version = "0.22.24" +version = "0.22.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17b4795ff5edd201c7cd6dca065ae59972ce77d1b80fa0a84d94950ece7d1474" +checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" dependencies = [ "indexmap", "toml_datetime", @@ -1293,17 +1287,16 @@ dependencies = [ [[package]] name = "tower" -version = "0.4.13" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" +checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9" dependencies = [ "futures-core", "futures-util", - "pin-project", "pin-project-lite", + "sync_wrapper", "tower-layer", "tower-service", - "tracing", ] [[package]] @@ -1324,7 +1317,6 @@ version = "0.1.41" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" dependencies = [ - "log", "pin-project-lite", "tracing-attributes", "tracing-core", @@ -1332,9 +1324,9 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.28" +version = "0.1.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d" +checksum = "81383ab64e72a7a8b8e13130c49e3dab29def6d0c7d76a03087b3cf71c5c6903" dependencies = [ "proc-macro2", "quote", @@ -1343,9 +1335,9 @@ dependencies = [ [[package]] name = "tracing-core" -version = "0.1.33" +version = "0.1.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" +checksum = "b9d12581f227e93f094d3af2ae690a574abb8a2b9b7a96e7cfe9647b2b617678" dependencies = [ "once_cell", ] @@ -1379,12 +1371,6 @@ dependencies = [ "percent-encoding", ] -[[package]] -name = "utf16_iter" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246" - [[package]] name = "utf8_iter" version = "1.0.4" @@ -1418,15 +1404,24 @@ dependencies = [ [[package]] name = "wasi" -version = "0.11.0+wasi-snapshot-preview1" +version = "0.11.1+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" [[package]] name = "webpki-root-certs" -version = "0.26.8" +version = "0.26.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09aed61f5e8d2c18344b3faa33a4c837855fe56642757754775548fee21386c4" +checksum = "75c7f0ef91146ebfb530314f5f1d24528d7f0767efbfd31dce919275413e393e" +dependencies = [ + "webpki-root-certs 1.0.1", +] + +[[package]] +name = "webpki-root-certs" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86138b15b2b7d561bc4469e77027b8dd005a43dc502e9031d1f5afc8ce1f280e" dependencies = [ "rustls-pki-types", ] @@ -1467,6 +1462,15 @@ dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "windows-sys" +version = "0.60.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" +dependencies = [ + "windows-targets 0.53.2", +] + [[package]] name = "windows-targets" version = "0.42.2" @@ -1491,13 +1495,29 @@ dependencies = [ "windows_aarch64_gnullvm 0.52.6", "windows_aarch64_msvc 0.52.6", "windows_i686_gnu 0.52.6", - "windows_i686_gnullvm", + "windows_i686_gnullvm 0.52.6", "windows_i686_msvc 0.52.6", "windows_x86_64_gnu 0.52.6", "windows_x86_64_gnullvm 0.52.6", "windows_x86_64_msvc 0.52.6", ] +[[package]] +name = "windows-targets" +version = "0.53.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c66f69fcc9ce11da9966ddb31a40968cad001c5bedeb5c2b82ede4253ab48aef" +dependencies = [ + "windows_aarch64_gnullvm 0.53.0", + "windows_aarch64_msvc 0.53.0", + "windows_i686_gnu 0.53.0", + "windows_i686_gnullvm 0.53.0", + "windows_i686_msvc 0.53.0", + "windows_x86_64_gnu 0.53.0", + "windows_x86_64_gnullvm 0.53.0", + "windows_x86_64_msvc 0.53.0", +] + [[package]] name = "windows_aarch64_gnullvm" version = "0.42.2" @@ -1510,6 +1530,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764" + [[package]] name = "windows_aarch64_msvc" version = "0.42.2" @@ -1522,6 +1548,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" +[[package]] +name = "windows_aarch64_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c" + [[package]] name = "windows_i686_gnu" version = "0.42.2" @@ -1534,12 +1566,24 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" +[[package]] +name = "windows_i686_gnu" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3" + [[package]] name = "windows_i686_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" +[[package]] +name = "windows_i686_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11" + [[package]] name = "windows_i686_msvc" version = "0.42.2" @@ -1552,6 +1596,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" +[[package]] +name = "windows_i686_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d" + [[package]] name = "windows_x86_64_gnu" version = "0.42.2" @@ -1564,6 +1614,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" +[[package]] +name = "windows_x86_64_gnu" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba" + [[package]] name = "windows_x86_64_gnullvm" version = "0.42.2" @@ -1576,6 +1632,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57" + [[package]] name = "windows_x86_64_msvc" version = "0.42.2" @@ -1589,31 +1651,31 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] -name = "winnow" -version = "0.7.6" +name = "windows_x86_64_msvc" +version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63d3fcd9bba44b03821e7d699eeee959f3126dcc4aa8e4ae18ec617c2a5cea10" +checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" + +[[package]] +name = "winnow" +version = "0.7.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3edebf492c8125044983378ecb5766203ad3b4c2f7a922bd7dd207f6d443e95" dependencies = [ "memchr", ] -[[package]] -name = "write16" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936" - [[package]] name = "writeable" -version = "0.5.5" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" +checksum = "ea2f10b9bb0928dfb1b42b65e1f9e36f7f54dbdf08457afefb38afcdec4fa2bb" [[package]] name = "yoke" -version = "0.7.5" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "120e6aef9aa629e3d4f52dc8cc43a015c7724194c97dfaf45180d2daf2b77f40" +checksum = "5f41bb01b8226ef4bfd589436a297c53d118f65921786300e427be8d487695cc" dependencies = [ "serde", "stable_deref_trait", @@ -1623,9 +1685,9 @@ dependencies = [ [[package]] name = "yoke-derive" -version = "0.7.5" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154" +checksum = "38da3c9736e16c5d3c8c597a9aaa5d1fa565d0532ae05e27c24aa62fb32c0ab6" dependencies = [ "proc-macro2", "quote", @@ -1661,10 +1723,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" [[package]] -name = "zerovec" -version = "0.10.4" +name = "zerotrie" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa2b893d79df23bfb12d5461018d408ea19dfafe76c2c7ef6d4eba614f8ff079" +checksum = "36f0bbd478583f79edad978b407914f61b2972f5af6fa089686016be8f9af595" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", +] + +[[package]] +name = "zerovec" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a05eb080e015ba39cc9e23bbe5e7fb04d5fb040350f99f34e338d5fdd294428" dependencies = [ "yoke", "zerofrom", @@ -1673,9 +1746,9 @@ dependencies = [ [[package]] name = "zerovec-derive" -version = "0.10.3" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" +checksum = "5b96237efa0c878c64bd89c436f661be4e46b2f3eff1ebb976f7ef2321d2f58f" dependencies = [ "proc-macro2", "quote", diff --git a/client/Cargo.toml b/client/Cargo.toml index c435149f..aff9ede4 100644 --- a/client/Cargo.toml +++ b/client/Cargo.toml @@ -1,18 +1,17 @@ [package] name = "signal-cli-client" version = "0.0.1" -edition = "2021" +edition = "2024" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] anyhow = "1" clap = { version = "4", features = ["cargo", "derive", "wrap_help"] } -log = "0.4" serde = "1" serde_json = "1" tokio = { version = "1", features = ["rt", "macros", "net", "rt-multi-thread"] } -jsonrpsee = { version = "0.24", features = [ +jsonrpsee = { version = "0.25", features = [ "macros", "async-client", "http-client", diff --git a/client/src/cli.rs b/client/src/cli.rs index 4ff9d458..7fa5d1c5 100644 --- a/client/src/cli.rs +++ b/client/src/cli.rs @@ -15,6 +15,7 @@ pub struct Cli { pub json_rpc_tcp: Option>, /// UNIX socket address and port of signal-cli daemon + #[cfg(unix)] #[arg(long, conflicts_with = "json_rpc_tcp")] pub json_rpc_socket: Option>, @@ -84,6 +85,8 @@ pub enum CliCommands { }, GetUserStatus { recipient: Vec, + #[arg(long)] + username: Vec, }, JoinGroup { #[arg(long)] @@ -176,6 +179,9 @@ pub enum CliCommands { #[arg(short = 'a', long)] attachment: Vec, + #[arg(long)] + view_once: bool, + #[arg(long)] mention: Vec, diff --git a/client/src/jsonrpc.rs b/client/src/jsonrpc.rs index b085cde5..66ef9d9d 100644 --- a/client/src/jsonrpc.rs +++ b/client/src/jsonrpc.rs @@ -70,6 +70,7 @@ pub trait Rpc { &self, account: Option, recipients: Vec, + usernames: Vec, ) -> Result; #[method(name = "joinGroup", param_kind = map)] @@ -182,6 +183,7 @@ pub trait Rpc { endSession: bool, message: String, attachments: Vec, + viewOnce: bool, mentions: Vec, textStyle: Vec, quoteTimestamp: Option, @@ -190,10 +192,10 @@ pub trait Rpc { quoteMention: Vec, quoteTextStyle: Vec, quoteAttachment: Vec, - preview_url: Option, - preview_title: Option, - preview_description: Option, - preview_image: Option, + previewUrl: Option, + previewTitle: Option, + previewDescription: Option, + previewImage: Option, sticker: Option, storyTimestamp: Option, storyAuthor: Option, @@ -409,6 +411,7 @@ pub async fn connect_tcp( Ok(ClientBuilder::default().build_with_tokio(sender, receiver)) } +#[cfg(unix)] pub async fn connect_unix( socket_path: impl AsRef, ) -> Result { @@ -417,6 +420,6 @@ pub async fn connect_unix( Ok(ClientBuilder::default().build_with_tokio(sender, receiver)) } -pub async fn connect_http(uri: &str) -> Result { +pub async fn connect_http(uri: &str) -> Result, Error> { HttpClientBuilder::default().build(uri) } diff --git a/client/src/main.rs b/client/src/main.rs index 35c1ab22..ac12331d 100644 --- a/client/src/main.rs +++ b/client/src/main.rs @@ -60,8 +60,13 @@ async fn handle_command( .delete_local_account_data(cli.account, ignore_registered) .await } - CliCommands::GetUserStatus { recipient } => { - client.get_user_status(cli.account, recipient).await + CliCommands::GetUserStatus { + recipient, + username, + } => { + client + .get_user_status(cli.account, recipient, username) + .await } CliCommands::JoinGroup { uri } => client.join_group(cli.account, uri).await, CliCommands::Link { name } => { @@ -70,7 +75,7 @@ async fn handle_command( .await .map_err(|e| RpcError::Custom(format!("JSON-RPC command startLink failed: {e:?}")))? .device_link_uri; - println!("{}", url); + println!("{url}"); client.finish_link(url, name).await } CliCommands::ListAccounts => client.list_accounts().await, @@ -139,6 +144,7 @@ async fn handle_command( end_session, message, attachment, + view_once, mention, text_style, quote_timestamp, @@ -165,6 +171,7 @@ async fn handle_command( end_session, message.unwrap_or_default(), attachment, + view_once, mention, text_style, quote_timestamp, @@ -477,23 +484,30 @@ async fn connect(cli: Cli) -> Result { handle_command(cli, client).await } else { - let socket_path = cli - .json_rpc_socket - .clone() - .unwrap_or(None) - .or_else(|| { - std::env::var_os("XDG_RUNTIME_DIR").map(|runtime_dir| { - PathBuf::from(runtime_dir) - .join(DEFAULT_SOCKET_SUFFIX) - .into() + #[cfg(windows)] + { + Err(RpcError::Custom("Invalid socket".into())) + } + #[cfg(unix)] + { + let socket_path = cli + .json_rpc_socket + .clone() + .unwrap_or(None) + .or_else(|| { + std::env::var_os("XDG_RUNTIME_DIR").map(|runtime_dir| { + PathBuf::from(runtime_dir) + .join(DEFAULT_SOCKET_SUFFIX) + .into() + }) }) - }) - .unwrap_or_else(|| ("/run".to_owned() + DEFAULT_SOCKET_SUFFIX).into()); - let client = jsonrpc::connect_unix(socket_path) - .await - .map_err(|e| RpcError::Custom(format!("Failed to connect to socket: {e}")))?; + .unwrap_or_else(|| ("/run".to_owned() + DEFAULT_SOCKET_SUFFIX).into()); + let client = jsonrpc::connect_unix(socket_path) + .await + .map_err(|e| RpcError::Custom(format!("Failed to connect to socket: {e}")))?; - handle_command(cli, client).await + handle_command(cli, client).await + } } } diff --git a/client/src/transports/mod.rs b/client/src/transports/mod.rs index 04f4390f..ed1963a0 100644 --- a/client/src/transports/mod.rs +++ b/client/src/transports/mod.rs @@ -1,10 +1,8 @@ use futures_util::{stream::StreamExt, Sink, SinkExt, Stream}; -use jsonrpsee::core::{ - async_trait, - client::{ReceivedMessage, TransportReceiverT, TransportSenderT}, -}; +use jsonrpsee::core::client::{ReceivedMessage, TransportReceiverT, TransportSenderT}; use thiserror::Error; +#[cfg(unix)] pub mod ipc; mod stream_codec; pub mod tcp; @@ -21,7 +19,6 @@ struct Sender> { inner: T, } -#[async_trait] impl + Unpin + 'static> TransportSenderT for Sender { @@ -31,7 +28,7 @@ impl + Unpin + 'static> T self.inner .send(body) .await - .map_err(|e| Errors::Other(format!("{:?}", e)))?; + .map_err(|e| Errors::Other(format!("{e:?}")))?; Ok(()) } @@ -39,7 +36,7 @@ impl + Unpin + 'static> T self.inner .close() .await - .map_err(|e| Errors::Other(format!("{:?}", e)))?; + .map_err(|e| Errors::Other(format!("{e:?}")))?; Ok(()) } } @@ -48,7 +45,6 @@ struct Receiver { inner: T, } -#[async_trait] impl> + Unpin + 'static> TransportReceiverT for Receiver { @@ -58,7 +54,7 @@ impl> + Unpin + 'static> match self.inner.next().await { None => Err(Errors::Closed), Some(Ok(msg)) => Ok(ReceivedMessage::Text(msg)), - Some(Err(e)) => Err(Errors::Other(format!("{:?}", e))), + Some(Err(e)) => Err(Errors::Other(format!("{e:?}"))), } } } diff --git a/client/src/transports/stream_codec.rs b/client/src/transports/stream_codec.rs index 6f77306f..e46233cb 100644 --- a/client/src/transports/stream_codec.rs +++ b/client/src/transports/stream_codec.rs @@ -41,7 +41,7 @@ impl Decoder for StreamCodec { match str::from_utf8(line.as_ref()) { Ok(s) => Ok(Some(s.to_string())), - Err(_) => Err(io::Error::new(io::ErrorKind::Other, "invalid UTF-8")), + Err(_) => Err(io::Error::other("invalid UTF-8")), } } else { Ok(None) diff --git a/data/org.asamk.SignalCli.metainfo.xml b/data/org.asamk.SignalCli.metainfo.xml index 95646534..c6c07411 100644 --- a/data/org.asamk.SignalCli.metainfo.xml +++ b/data/org.asamk.SignalCli.metainfo.xml @@ -45,6 +45,9 @@ intense + + https://github.com/AsamK/signal-cli/releases/tag/v0.13.18 + https://github.com/AsamK/signal-cli/releases/tag/v0.13.17 diff --git a/graalvm-config-dir/jni-config.json b/graalvm-config-dir/jni-config.json index 23a2160c..523a6c03 100644 --- a/graalvm-config-dir/jni-config.json +++ b/graalvm-config-dir/jni-config.json @@ -58,7 +58,7 @@ }, { "name":"java.lang.Throwable", - "methods":[{"name":"getMessage","parameterTypes":[] }, {"name":"toString","parameterTypes":[] }] + "methods":[{"name":"getMessage","parameterTypes":[] }, {"name":"setStackTrace","parameterTypes":["java.lang.StackTraceElement[]"] }, {"name":"toString","parameterTypes":[] }] }, { "name":"java.lang.UnsatisfiedLinkError", @@ -126,6 +126,10 @@ "name":"org.signal.libsignal.net.NetworkException", "methods":[{"name":"","parameterTypes":["java.lang.String"] }] }, +{ + "name":"org.signal.libsignal.net.RetryLaterException", + "methods":[{"name":"","parameterTypes":["long"] }] +}, { "name":"org.signal.libsignal.protocol.DuplicateMessageException", "methods":[{"name":"","parameterTypes":["java.lang.String"] }] diff --git a/graalvm-config-dir/reflect-config.json b/graalvm-config-dir/reflect-config.json index c5459804..0bfd1cdf 100644 --- a/graalvm-config-dir/reflect-config.json +++ b/graalvm-config-dir/reflect-config.json @@ -3070,6 +3070,7 @@ { "name":"org.whispersystems.signalservice.internal.storage.protos.GroupV2Record", "allDeclaredFields":true, + "fields":[{"name":"archived"}, {"name":"avatarColor"}, {"name":"blocked"}, {"name":"dontNotifyForMentionsIfMuted"}, {"name":"hideStory"}, {"name":"markedUnread"}, {"name":"masterKey"}, {"name":"mutedUntilTimestamp"}, {"name":"storySendMode"}, {"name":"whitelisted"}], "methods":[{"name":"adapter","parameterTypes":[] }, {"name":"unknownFields","parameterTypes":[] }] }, { diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 680ca54a..fec44a43 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -10,8 +10,8 @@ slf4j-api = { module = "org.slf4j:slf4j-api", version.ref = "slf4j" } slf4j-jul = { module = "org.slf4j:jul-to-slf4j", version.ref = "slf4j" } logback = "ch.qos.logback:logback-classic:1.5.18" -signalservice = "com.github.turasa:signal-service-java:2.15.3_unofficial_126" -sqlite = "org.xerial:sqlite-jdbc:3.50.1.0" +signalservice = "com.github.turasa:signal-service-java:2.15.3_unofficial_127" +sqlite = "org.xerial:sqlite-jdbc:3.50.2.0" hikari = "com.zaxxer:HikariCP:6.3.0" junit-jupiter = "org.junit.jupiter:junit-jupiter:5.13.2" junit-launcher = "org.junit.platform:junit-platform-launcher:1.13.2" diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 1b33c55b..8bdaf60c 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 002b867c..2a84e188 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.0.0-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/gradlew b/gradlew index 23d15a93..ef07e016 100755 --- a/gradlew +++ b/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/src/main/java/org/asamk/signal/manager/Manager.java b/lib/src/main/java/org/asamk/signal/manager/Manager.java index 238084e7..ccb661e1 100644 --- a/lib/src/main/java/org/asamk/signal/manager/Manager.java +++ b/lib/src/main/java/org/asamk/signal/manager/Manager.java @@ -96,7 +96,7 @@ public interface Manager extends Closeable { */ Map getUserStatus(Set numbers) throws IOException, RateLimitException; - Map getUsernameStatus(Set usernames); + Map getUsernameStatus(Set usernames) throws IOException; void updateAccountAttributes( String deviceName, diff --git a/lib/src/main/java/org/asamk/signal/manager/SignalAccountFiles.java b/lib/src/main/java/org/asamk/signal/manager/SignalAccountFiles.java index 4072a9df..cd0b5a21 100644 --- a/lib/src/main/java/org/asamk/signal/manager/SignalAccountFiles.java +++ b/lib/src/main/java/org/asamk/signal/manager/SignalAccountFiles.java @@ -2,6 +2,7 @@ package org.asamk.signal.manager; import org.asamk.signal.manager.api.AccountCheckException; import org.asamk.signal.manager.api.NotRegisteredException; +import org.asamk.signal.manager.api.Pair; import org.asamk.signal.manager.api.ServiceEnvironment; import org.asamk.signal.manager.config.ServiceConfig; import org.asamk.signal.manager.config.ServiceEnvironmentConfig; @@ -63,19 +64,28 @@ public class SignalAccountFiles { return accountsStore.getAllNumbers(); } - public MultiAccountManager initMultiAccountManager() throws IOException { - final var managers = accountsStore.getAllAccounts().parallelStream().map(a -> { + public MultiAccountManager initMultiAccountManager() throws IOException, AccountCheckException { + final var managerPairs = accountsStore.getAllAccounts().parallelStream().map(a -> { try { - return initManager(a.number(), a.path()); - } catch (NotRegisteredException | IOException | AccountCheckException e) { + return new Pair(initManager(a.number(), a.path()), null); + } catch (NotRegisteredException e) { logger.warn("Ignoring {}: {} ({})", a.number(), e.getMessage(), e.getClass().getSimpleName()); return null; - } catch (Throwable e) { + } catch (AccountCheckException | IOException e) { logger.error("Failed to load {}: {} ({})", a.number(), e.getMessage(), e.getClass().getSimpleName()); - throw e; + return new Pair(null, e); } }).filter(Objects::nonNull).toList(); + for (final var pair : managerPairs) { + if (pair.second() instanceof IOException e) { + throw e; + } else if (pair.second() instanceof AccountCheckException e) { + throw e; + } + } + + final var managers = managerPairs.stream().map(Pair::first).toList(); return new MultiAccountManagerImpl(managers, this); } diff --git a/lib/src/main/java/org/asamk/signal/manager/api/Message.java b/lib/src/main/java/org/asamk/signal/manager/api/Message.java index 48277e6d..9b372451 100644 --- a/lib/src/main/java/org/asamk/signal/manager/api/Message.java +++ b/lib/src/main/java/org/asamk/signal/manager/api/Message.java @@ -6,6 +6,7 @@ import java.util.Optional; public record Message( String messageText, List attachments, + boolean viewOnce, List mentions, Optional quote, Optional sticker, diff --git a/lib/src/main/java/org/asamk/signal/manager/config/LiveConfig.java b/lib/src/main/java/org/asamk/signal/manager/config/LiveConfig.java index 890d7081..c76da017 100644 --- a/lib/src/main/java/org/asamk/signal/manager/config/LiveConfig.java +++ b/lib/src/main/java/org/asamk/signal/manager/config/LiveConfig.java @@ -28,8 +28,9 @@ class LiveConfig { private static final byte[] UNIDENTIFIED_SENDER_TRUST_ROOT = Base64.getDecoder() .decode("BXu6QIKVz5MA8gstzfOgRQGqyLqOwNKHL6INkv3IHWMF"); private static final String CDSI_MRENCLAVE = "0f6fd79cdfdaa5b2e6337f534d3baf999318b0c462a7ac1f41297a3e4b424a57"; - private static final String SVR2_MRENCLAVE_LEGACY = "9314436a9a144992bb3680770ea5fd7934a7ffd29257844a33763a238903d570"; - private static final String SVR2_MRENCLAVE = "093be9ea32405e85ae28dbb48eb668aebeb7dbe29517b9b86ad4bec4dfe0e6a6"; + private static final String SVR2_MRENCLAVE_LEGACY_LEGACY = "9314436a9a144992bb3680770ea5fd7934a7ffd29257844a33763a238903d570"; + private static final String SVR2_MRENCLAVE_LEGACY = "093be9ea32405e85ae28dbb48eb668aebeb7dbe29517b9b86ad4bec4dfe0e6a6"; + private static final String SVR2_MRENCLAVE = "29cd63c87bea751e3bfd0fbd401279192e2e5c99948b4ee9437eafc4968355fb"; private static final String URL = "https://chat.signal.org"; private static final String CDN_URL = "https://cdn.signal.org"; @@ -91,7 +92,7 @@ class LiveConfig { createDefaultServiceConfiguration(interceptors), getUnidentifiedSenderTrustRoot(), CDSI_MRENCLAVE, - List.of(SVR2_MRENCLAVE, SVR2_MRENCLAVE_LEGACY)); + List.of(SVR2_MRENCLAVE, SVR2_MRENCLAVE_LEGACY, SVR2_MRENCLAVE_LEGACY_LEGACY)); } private LiveConfig() { diff --git a/lib/src/main/java/org/asamk/signal/manager/config/StagingConfig.java b/lib/src/main/java/org/asamk/signal/manager/config/StagingConfig.java index 6d8f08c7..e25fe21b 100644 --- a/lib/src/main/java/org/asamk/signal/manager/config/StagingConfig.java +++ b/lib/src/main/java/org/asamk/signal/manager/config/StagingConfig.java @@ -28,8 +28,9 @@ class StagingConfig { private static final byte[] UNIDENTIFIED_SENDER_TRUST_ROOT = Base64.getDecoder() .decode("BbqY1DzohE4NUZoVF+L18oUPrK3kILllLEJh2UnPSsEx"); private static final String CDSI_MRENCLAVE = "0f6fd79cdfdaa5b2e6337f534d3baf999318b0c462a7ac1f41297a3e4b424a57"; - private static final String SVR2_MRENCLAVE_LEGACY = "38e01eff4fe357dc0b0e8ef7a44b4abc5489fbccba3a78780f3872c277f62bf3"; - private static final String SVR2_MRENCLAVE = "2e8cefe6e3f389d8426adb24e9b7fb7adf10902c96f06f7bbcee36277711ed91"; + private static final String SVR2_MRENCLAVE_LEGACY_LEGACY = "38e01eff4fe357dc0b0e8ef7a44b4abc5489fbccba3a78780f3872c277f62bf3"; + private static final String SVR2_MRENCLAVE_LEGACY = "2e8cefe6e3f389d8426adb24e9b7fb7adf10902c96f06f7bbcee36277711ed91"; + private static final String SVR2_MRENCLAVE = "a75542d82da9f6914a1e31f8a7407053b99cc99a0e7291d8fbd394253e19b036"; private static final String URL = "https://chat.staging.signal.org"; private static final String CDN_URL = "https://cdn-staging.signal.org"; @@ -91,7 +92,7 @@ class StagingConfig { createDefaultServiceConfiguration(interceptors), getUnidentifiedSenderTrustRoot(), CDSI_MRENCLAVE, - List.of(SVR2_MRENCLAVE, SVR2_MRENCLAVE_LEGACY)); + List.of(SVR2_MRENCLAVE, SVR2_MRENCLAVE_LEGACY, SVR2_MRENCLAVE_LEGACY_LEGACY)); } private StagingConfig() { diff --git a/lib/src/main/java/org/asamk/signal/manager/helper/IncomingMessageHandler.java b/lib/src/main/java/org/asamk/signal/manager/helper/IncomingMessageHandler.java index 3bb7479a..dd9cb38f 100644 --- a/lib/src/main/java/org/asamk/signal/manager/helper/IncomingMessageHandler.java +++ b/lib/src/main/java/org/asamk/signal/manager/helper/IncomingMessageHandler.java @@ -41,6 +41,7 @@ import org.signal.libsignal.metadata.ProtocolNoSessionException; import org.signal.libsignal.metadata.ProtocolUntrustedIdentityException; import org.signal.libsignal.metadata.SelfSendException; import org.signal.libsignal.protocol.InvalidMessageException; +import org.signal.libsignal.protocol.UsePqRatchet; import org.signal.libsignal.protocol.groups.GroupSessionBuilder; import org.signal.libsignal.protocol.message.DecryptionErrorMessage; import org.signal.libsignal.zkgroup.InvalidInputException; @@ -105,7 +106,7 @@ public final class IncomingMessageHandler { try { final var cipherResult = dependencies.getCipher(destination == null || destination.equals(account.getAci()) ? ServiceIdType.ACI : ServiceIdType.PNI) - .decrypt(envelope.getProto(), envelope.getServerDeliveredTimestamp()); + .decrypt(envelope.getProto(), envelope.getServerDeliveredTimestamp(), UsePqRatchet.NO); content = validate(envelope.getProto(), cipherResult, envelope.getServerDeliveredTimestamp()); if (content == null) { return new Pair<>(List.of(), null); @@ -143,7 +144,7 @@ public final class IncomingMessageHandler { try { final var cipherResult = dependencies.getCipher(destination == null || destination.equals(account.getAci()) ? ServiceIdType.ACI : ServiceIdType.PNI) - .decrypt(envelope.getProto(), envelope.getServerDeliveredTimestamp()); + .decrypt(envelope.getProto(), envelope.getServerDeliveredTimestamp(), UsePqRatchet.NO); content = validate(envelope.getProto(), cipherResult, envelope.getServerDeliveredTimestamp()); if (content == null) { return new Pair<>(List.of(), null); diff --git a/lib/src/main/java/org/asamk/signal/manager/helper/RecipientHelper.java b/lib/src/main/java/org/asamk/signal/manager/helper/RecipientHelper.java index ecb85254..a73bb741 100644 --- a/lib/src/main/java/org/asamk/signal/manager/helper/RecipientHelper.java +++ b/lib/src/main/java/org/asamk/signal/manager/helper/RecipientHelper.java @@ -17,6 +17,7 @@ import org.whispersystems.signalservice.api.push.ServiceId.PNI; import org.whispersystems.signalservice.api.push.SignalServiceAddress; import org.whispersystems.signalservice.api.push.exceptions.CdsiInvalidArgumentException; import org.whispersystems.signalservice.api.push.exceptions.CdsiInvalidTokenException; +import org.whispersystems.signalservice.api.push.exceptions.NonSuccessfulResponseCodeException; import java.io.IOException; import java.util.Collection; @@ -68,7 +69,7 @@ public class RecipientHelper { .toSignalServiceAddress(); } - public Set resolveRecipients(Collection recipients) throws UnregisteredRecipientException { + public Set resolveRecipients(Collection recipients) throws UnregisteredRecipientException, IOException { final var recipientIds = new HashSet(recipients.size()); for (var number : recipients) { final var recipientId = resolveRecipient(number); @@ -91,7 +92,11 @@ public class RecipientHelper { } }); } else if (recipient instanceof RecipientIdentifier.Username(String username)) { - return resolveRecipientByUsernameOrLink(username, false); + try { + return resolveRecipientByUsernameOrLink(username, false); + } catch (Exception e) { + return null; + } } throw new AssertionError("Unexpected RecipientIdentifier: " + recipient); } @@ -99,7 +104,7 @@ public class RecipientHelper { public RecipientId resolveRecipientByUsernameOrLink( String username, boolean forceRefresh - ) throws UnregisteredRecipientException { + ) throws UnregisteredRecipientException, IOException { final Username finalUsername; try { finalUsername = getUsernameFromUsernameOrLink(username); @@ -110,11 +115,15 @@ public class RecipientHelper { try { final var aci = handleResponseException(dependencies.getUsernameApi().getAciByUsername(finalUsername)); return account.getRecipientStore().resolveRecipientTrusted(aci, finalUsername.getUsername()); - } catch (IOException e) { - throw new UnregisteredRecipientException(new org.asamk.signal.manager.api.RecipientAddress(null, - null, - null, - username)); + } catch (NonSuccessfulResponseCodeException e) { + if (e.code == 404) { + throw new UnregisteredRecipientException(new org.asamk.signal.manager.api.RecipientAddress(null, + null, + null, + username)); + } + logger.debug("Failed to get uuid for username: {}", username, e); + throw e; } } return account.getRecipientStore().resolveRecipientByUsername(finalUsername.getUsername(), () -> { diff --git a/lib/src/main/java/org/asamk/signal/manager/internal/ManagerImpl.java b/lib/src/main/java/org/asamk/signal/manager/internal/ManagerImpl.java index ffb74de2..726d0aaf 100644 --- a/lib/src/main/java/org/asamk/signal/manager/internal/ManagerImpl.java +++ b/lib/src/main/java/org/asamk/signal/manager/internal/ManagerImpl.java @@ -285,7 +285,7 @@ public class ManagerImpl implements Manager { } @Override - public Map getUsernameStatus(Set usernames) { + public Map getUsernameStatus(Set usernames) throws IOException { final var registeredUsers = new HashMap(); for (final var username : usernames) { try { @@ -810,6 +810,7 @@ public class ManagerImpl implements Manager { } else if (!additionalAttachments.isEmpty()) { messageBuilder.withAttachments(additionalAttachments); } + messageBuilder.withViewOnce(message.viewOnce()); if (!message.mentions().isEmpty()) { messageBuilder.withMentions(resolveMentions(message.mentions())); } diff --git a/lib/src/main/java/org/asamk/signal/manager/internal/SignalDependencies.java b/lib/src/main/java/org/asamk/signal/manager/internal/SignalDependencies.java index f954588f..0bc895cb 100644 --- a/lib/src/main/java/org/asamk/signal/manager/internal/SignalDependencies.java +++ b/lib/src/main/java/org/asamk/signal/manager/internal/SignalDependencies.java @@ -5,6 +5,7 @@ import org.asamk.signal.manager.config.ServiceEnvironmentConfig; import org.asamk.signal.manager.util.Utils; import org.signal.libsignal.metadata.certificate.CertificateValidator; import org.signal.libsignal.net.Network; +import org.signal.libsignal.protocol.UsePqRatchet; import org.signal.libsignal.zkgroup.profiles.ClientZkProfileOperations; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -326,7 +327,8 @@ public class SignalDependencies { Optional.empty(), executor, ServiceConfig.MAX_ENVELOPE_SIZE, - () -> true)); + () -> true, + UsePqRatchet.NO)); } public List getSecureValueRecovery() { diff --git a/lib/src/main/java/org/asamk/signal/manager/syncStorage/ContactRecordProcessor.java b/lib/src/main/java/org/asamk/signal/manager/syncStorage/ContactRecordProcessor.java index 3858bd06..e1fee99b 100644 --- a/lib/src/main/java/org/asamk/signal/manager/syncStorage/ContactRecordProcessor.java +++ b/lib/src/main/java/org/asamk/signal/manager/syncStorage/ContactRecordProcessor.java @@ -37,7 +37,7 @@ public class ContactRecordProcessor extends DefaultStorageRecordProcessor;filename=;base64,` +*--view-once*:: +Send the message as a view once message. +A conformant client will only allow the receiver to view the message once. +View Once is only supported for messages that include an image attachment. + *--sticker* STICKER:: Send a sticker of a locally known sticker pack (syntax: stickerPackId:stickerId). Shouldn't be used together with `-m` as the official clients don't support this. diff --git a/src/main/java/org/asamk/signal/App.java b/src/main/java/org/asamk/signal/App.java index e494d201..6352aa13 100644 --- a/src/main/java/org/asamk/signal/App.java +++ b/src/main/java/org/asamk/signal/App.java @@ -291,6 +291,8 @@ public class App { commandHandler.handleMultiLocalCommand(command, multiAccountManager); } catch (IOException e) { throw new IOErrorException("Failed to load local accounts file", e); + } catch (AccountCheckException e) { + throw new UnexpectedErrorException("Failed to load account file", e); } } diff --git a/src/main/java/org/asamk/signal/Shutdown.java b/src/main/java/org/asamk/signal/Shutdown.java index a59497c9..c51c12e4 100644 --- a/src/main/java/org/asamk/signal/Shutdown.java +++ b/src/main/java/org/asamk/signal/Shutdown.java @@ -1,5 +1,6 @@ package org.asamk.signal; +import org.asamk.signal.commands.exceptions.CommandException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -11,7 +12,7 @@ import sun.misc.Signal; public class Shutdown { private static final Logger logger = LoggerFactory.getLogger(Shutdown.class); - private static final CompletableFuture shutdown = new CompletableFuture<>(); + private static final CompletableFuture shutdown = new CompletableFuture<>(); private static final CompletableFuture shutdownComplete = new CompletableFuture<>(); private static boolean initialized = false; @@ -43,9 +44,17 @@ public class Shutdown { shutdown.complete(null); } - public static void waitForShutdown() throws InterruptedException { + public static void triggerShutdown(CommandException exception) { + logger.debug("Triggering shutdown with exception.", exception); + shutdown.complete(exception); + } + + public static void waitForShutdown() throws InterruptedException, CommandException { try { - shutdown.get(); + final var result = shutdown.get(); + if (result instanceof CommandException e) { + throw e; + } } catch (ExecutionException e) { throw new RuntimeException(e); } diff --git a/src/main/java/org/asamk/signal/commands/DaemonCommand.java b/src/main/java/org/asamk/signal/commands/DaemonCommand.java index 197e1286..6790c65d 100644 --- a/src/main/java/org/asamk/signal/commands/DaemonCommand.java +++ b/src/main/java/org/asamk/signal/commands/DaemonCommand.java @@ -97,7 +97,7 @@ public class DaemonCommand implements MultiLocalCommand, LocalCommand { final OutputWriter outputWriter ) throws CommandException { Shutdown.installHandler(); - logger.info("Starting daemon in single-account mode for " + m.getSelfNumber()); + logger.info("Starting daemon in single-account mode for {}", m.getSelfNumber()); final var noReceiveStdOut = Boolean.TRUE.equals(ns.getBoolean("no-receive-stdout")); final var receiveMode = ns.get("receive-mode"); final var receiveConfig = getReceiveConfig(ns); diff --git a/src/main/java/org/asamk/signal/commands/GetUserStatusCommand.java b/src/main/java/org/asamk/signal/commands/GetUserStatusCommand.java index e3d36d85..eab4155c 100644 --- a/src/main/java/org/asamk/signal/commands/GetUserStatusCommand.java +++ b/src/main/java/org/asamk/signal/commands/GetUserStatusCommand.java @@ -64,9 +64,16 @@ public class GetUserStatusCommand implements JsonRpcLocalCommand { } final var usernames = ns.getList("username"); - final var registeredUsernames = usernames == null - ? Map.of() - : m.getUsernameStatus(new HashSet<>(usernames)); + final Map registeredUsernames; + try { + registeredUsernames = usernames == null ? Map.of() : m.getUsernameStatus(new HashSet<>(usernames)); + } catch (IOException e) { + throw new IOErrorException("Unable to check if users are registered: " + + e.getMessage() + + " (" + + e.getClass().getSimpleName() + + ")", e); + } // Output switch (outputWriter) { diff --git a/src/main/java/org/asamk/signal/commands/SendCommand.java b/src/main/java/org/asamk/signal/commands/SendCommand.java index 39be74ee..98051b23 100644 --- a/src/main/java/org/asamk/signal/commands/SendCommand.java +++ b/src/main/java/org/asamk/signal/commands/SendCommand.java @@ -66,6 +66,9 @@ public class SendCommand implements JsonRpcLocalCommand { .help("Add an attachment. " + "Can be either a file path or a data URI. Data URI encoded attachments must follow the RFC 2397. Additionally a file name can be added, e.g. " + "data:;filename=;base64,."); + subparser.addArgument("--view-once") + .action(Arguments.storeTrue()) + .help("Send the message as a view once message"); subparser.addArgument("-e", "--end-session", "--endsession") .help("Clear session state and send end session message.") .action(Arguments.storeTrue()); @@ -164,6 +167,7 @@ public class SendCommand implements JsonRpcLocalCommand { if (attachments == null) { attachments = List.of(); } + final var viewOnce = Boolean.TRUE.equals(ns.getBoolean("view-once")); final var selfNumber = m.getSelfNumber(); @@ -239,6 +243,7 @@ public class SendCommand implements JsonRpcLocalCommand { try { final var message = new Message(messageText, attachments, + viewOnce, mentions, Optional.ofNullable(quote), Optional.ofNullable(sticker), @@ -250,8 +255,14 @@ public class SendCommand implements JsonRpcLocalCommand { : m.sendMessage(message, recipientIdentifiers, notifySelf); outputResult(outputWriter, results); } catch (AttachmentInvalidException | IOException e) { - throw new UnexpectedErrorException("Failed to send message: " + e.getMessage() + " (" + e.getClass() - .getSimpleName() + ")", e); + if (e instanceof IOException io && io.getMessage().contains("No prekeys available")) { + throw new UnexpectedErrorException("Failed to send message: " + e.getMessage() + " (" + e.getClass() + .getSimpleName() + "), maybe one of the devices of the recipient wasn't online for a while.", + e); + } else { + throw new UnexpectedErrorException("Failed to send message: " + e.getMessage() + " (" + e.getClass() + .getSimpleName() + ")", e); + } } catch (GroupNotFoundException | NotAGroupMemberException | GroupSendingNotAllowedException e) { throw new UserErrorException(e.getMessage()); } catch (UnregisteredRecipientException e) { diff --git a/src/main/java/org/asamk/signal/dbus/DbusHandler.java b/src/main/java/org/asamk/signal/dbus/DbusHandler.java index b6799de7..2ed6d11f 100644 --- a/src/main/java/org/asamk/signal/dbus/DbusHandler.java +++ b/src/main/java/org/asamk/signal/dbus/DbusHandler.java @@ -1,17 +1,21 @@ package org.asamk.signal.dbus; import org.asamk.signal.DbusConfig; +import org.asamk.signal.Shutdown; import org.asamk.signal.commands.exceptions.CommandException; +import org.asamk.signal.commands.exceptions.IOErrorException; import org.asamk.signal.commands.exceptions.UnexpectedErrorException; import org.asamk.signal.commands.exceptions.UserErrorException; import org.asamk.signal.manager.Manager; import org.asamk.signal.manager.MultiAccountManager; +import org.freedesktop.dbus.connections.IDisconnectCallback; import org.freedesktop.dbus.connections.impl.DBusConnection; import org.freedesktop.dbus.connections.impl.DBusConnectionBuilder; import org.freedesktop.dbus.exceptions.DBusException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.io.IOException; import java.util.ArrayList; import java.util.List; @@ -94,7 +98,9 @@ public class DbusHandler implements AutoCloseable { final var busType = isDbusSystem ? DBusConnection.DBusBusType.SYSTEM : DBusConnection.DBusBusType.SESSION; logger.debug("Starting DBus server on {} bus: {}", busType, busname); try { - dBusConnection = DBusConnectionBuilder.forType(busType).build(); + dBusConnection = DBusConnectionBuilder.forType(busType) + .withDisconnectCallback(new DisconnectCallback()) + .build(); dbusRunner.run(dBusConnection); } catch (DBusException e) { throw new UnexpectedErrorException("Dbus command failed: " + e.getMessage(), e); @@ -141,4 +147,13 @@ public class DbusHandler implements AutoCloseable { void run(DBusConnection connection) throws DBusException; } + + private static final class DisconnectCallback implements IDisconnectCallback { + + @Override + public void disconnectOnError(IOException ex) { + logger.debug("DBus daemon disconnected unexpectedly, shutting down"); + Shutdown.triggerShutdown(new IOErrorException("Unexpected dbus daemon disconnect", ex)); + } + } } diff --git a/src/main/java/org/asamk/signal/dbus/DbusSignalImpl.java b/src/main/java/org/asamk/signal/dbus/DbusSignalImpl.java index ac77df99..725df8b1 100644 --- a/src/main/java/org/asamk/signal/dbus/DbusSignalImpl.java +++ b/src/main/java/org/asamk/signal/dbus/DbusSignalImpl.java @@ -236,6 +236,7 @@ public class DbusSignalImpl implements Signal, AutoCloseable { try { final var message = new Message(messageText, attachments, + false, List.of(), Optional.empty(), Optional.empty(), @@ -399,6 +400,7 @@ public class DbusSignalImpl implements Signal, AutoCloseable { try { final var message = new Message(messageText, attachments, + false, List.of(), Optional.empty(), Optional.empty(), @@ -444,6 +446,7 @@ public class DbusSignalImpl implements Signal, AutoCloseable { try { final var message = new Message(messageText, attachments, + false, List.of(), Optional.empty(), Optional.empty(),