diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 65991bc..103f34a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -22,8 +22,8 @@ jobs: uses: actions/checkout@v3 with: submodules: true - - name: Install Rust (1.67 w/ clippy) - uses: dtolnay/rust-toolchain@1.67 + - name: Install Rust (1.70 w/ clippy) + uses: dtolnay/rust-toolchain@1.70 with: components: clippy - name: Install Rust (nightly w/ rustfmt) diff --git a/Cargo.lock b/Cargo.lock index 40e46bf..d4eda07 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,18 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "accessory" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "850bb534b9dc04744fbbb71d30ad6d25a7e4cf6dc33e223c81ef3a92ebab4e0b" +dependencies = [ + "macroific", + "proc-macro2", + "quote", + "syn 2.0.52", +] + [[package]] name = "addr2line" version = "0.21.0" @@ -19,12 +31,12 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" [[package]] name = "aead" -version = "0.4.3" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b613b8e1e3cf911a086f53f03bf286f52fd7a7258e4fa606f0ef220d39d8877" +checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0" dependencies = [ + "crypto-common", "generic-array", - "rand_core 0.6.4", ] [[package]] @@ -34,19 +46,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac1f845298e95f983ff1944b728ae08b8cebab80d684f0a832ed0fc74dfa27e2" dependencies = [ "cfg-if", - "cipher 0.4.4", + "cipher", "cpufeatures", ] [[package]] name = "ahash" -version = "0.7.6" +version = "0.8.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" +checksum = "8b79b82693f705137f8fb9b37871d99e4f9a7df12b917eed79c3d3954830a60b" dependencies = [ - "getrandom 0.2.10", + "cfg-if", "once_cell", "version_check", + "zerocopy", ] [[package]] @@ -58,6 +71,12 @@ dependencies = [ "memchr", ] +[[package]] +name = "allocator-api2" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" + [[package]] name = "android-tzdata" version = "0.1.1" @@ -134,6 +153,20 @@ version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d301b3b94cb4b2f23d7917810addbbaff90738e0ca2be692bd027e70d7e0330c" +[[package]] +name = "aquamarine" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21cc1548309245035eb18aa7f0967da6bc65587005170c56e6ef2788a4cf3f4e" +dependencies = [ + "include_dir", + "itertools 0.10.5", + "proc-macro-error", + "proc-macro2", + "quote", + "syn 2.0.52", +] + [[package]] name = "arboard" version = "3.3.0" @@ -168,6 +201,12 @@ dependencies = [ "serde", ] +[[package]] +name = "as_variant" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f38fa22307249f86fb7fad906fcae77f2564caeb56d7209103c551cd1cf4798f" + [[package]] name = "assign" version = "1.1.1" @@ -175,20 +214,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5f093eed78becd229346bf859eec0aa4dd7ddde0757287b2b4107a1f09c80002" [[package]] -name = "async-lock" -version = "2.8.0" +name = "async-channel" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "287272293e9d8c41773cec55e365490fe034813a2f172f502d6ddcf75b2f582b" +checksum = "f28243a43d821d11341ab73c80bed182dc015c514b951616cf79bd4af39af0c3" dependencies = [ - "event-listener", + "concurrent-queue", + "event-listener 5.2.0", + "event-listener-strategy", + "futures-core", + "pin-project-lite", ] -[[package]] -name = "async-once-cell" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72faff1fdc615a0199d7bf71e6f389af54d46a66e9beb5d76c39e48eda93ecce" - [[package]] name = "async-stream" version = "0.3.5" @@ -208,7 +245,7 @@ checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.52", ] [[package]] @@ -219,15 +256,9 @@ checksum = "bc00ceb34980c03614e35a3a4e218276a0a824e911d07651cd0d858a51e8c0f0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.52", ] -[[package]] -name = "atomic" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c59bdb34bc650a32731b31bd8f0829cc15d24a708ee31559e0bb34f2bc320cba" - [[package]] name = "autocfg" version = "1.1.0" @@ -241,10 +272,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b62ddb9cb1ec0a098ad4bbf9344d0713fa193ae1a80af55febcff2627b6a00c1" dependencies = [ "futures-core", - "getrandom 0.2.10", + "getrandom", "instant", "pin-project-lite", - "rand 0.8.5", + "rand", "tokio", ] @@ -265,15 +296,9 @@ dependencies = [ [[package]] name = "base64" -version = "0.13.1" +version = "0.21.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" - -[[package]] -name = "base64" -version = "0.21.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ba43ea6f343b788c8764558649e08df62f86c6ef251fdaeb1ffd010a9ae50a2" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" [[package]] name = "base64ct" @@ -323,6 +348,12 @@ version = "2.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +[[package]] +name = "bitmaps" +version = "3.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1d084b0137aaa901caf9f1e8b21daa6aa24d41cd806e111335541eff9683bd6" + [[package]] name = "blake3" version = "1.5.0" @@ -342,15 +373,6 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" -[[package]] -name = "block-buffer" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" -dependencies = [ - "generic-array", -] - [[package]] name = "block-buffer" version = "0.10.4" @@ -369,6 +391,15 @@ dependencies = [ "generic-array", ] +[[package]] +name = "bs58" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5353f36341f7451062466f0b755b96ac3a9547e4d7f6b70d603fc721a7d7896" +dependencies = [ + "tinyvec", +] + [[package]] name = "bumpalo" version = "3.14.0" @@ -393,6 +424,12 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" +[[package]] +name = "bytesize" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3e368af43e418a04d52505cf3dbc23dda4e3407ae2fa99fd0e4f308ce546acc" + [[package]] name = "cassowary" version = "0.3.0" @@ -405,7 +442,7 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26b52a9543ae338f279b96b0b9fed9c8093744685043739079ce85cd58f289a6" dependencies = [ - "cipher 0.4.4", + "cipher", ] [[package]] @@ -424,26 +461,37 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] -name = "chacha20" -version = "0.8.2" +name = "cfg-vis" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c80e5460aa66fe3b91d40bcbdab953a597b60053e34d684ac6903f863b680a6" +checksum = "c3a2c3bf5fc10fe2ca157564fbe08a4cb2b0a7d2ff3fe2f9683e65d5e7c7859c" +dependencies = [ + "proc-macro-crate 1.3.1", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "chacha20" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3613f74bd2eac03dad61bd53dbe620703d4371614fe0bc3b9f04dd36fe4e818" dependencies = [ "cfg-if", - "cipher 0.3.0", + "cipher", "cpufeatures", - "zeroize", ] [[package]] name = "chacha20poly1305" -version = "0.9.1" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a18446b09be63d457bbec447509e85f662f32952b035ce892290396bc0b0cff5" +checksum = "10cd79432192d1c0f4e1a0fef9527696cc039165d729fb41b3f4f4f354c2dc35" dependencies = [ "aead", "chacha20", - "cipher 0.3.0", + "cipher", "poly1305", "zeroize", ] @@ -462,15 +510,6 @@ dependencies = [ "windows-targets", ] -[[package]] -name = "cipher" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ee52072ec15386f770805afd189a01c8841be8696bed250fa2f13c4c0d6dfb7" -dependencies = [ - "generic-array", -] - [[package]] name = "cipher" version = "0.4.4" @@ -479,6 +518,7 @@ checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" dependencies = [ "crypto-common", "inout", + "zeroize", ] [[package]] @@ -514,7 +554,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.52", ] [[package]] @@ -567,10 +607,25 @@ dependencies = [ ] [[package]] -name = "const-oid" -version = "0.7.1" +name = "concurrent-queue" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4c78c047431fee22c1a7bb92e00ad095a02a983affe4d8a72e2a2c62c1b94f3" +checksum = "d16048cd947b08fa32c24458a22f5dc5e835264f689f4f5653210c69fd107363" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "const-oid" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" + +[[package]] +name = "const_panic" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6051f239ecec86fde3410901ab7860d458d160371533842974fc61f96d15879b" [[package]] name = "constant_time_eq" @@ -739,6 +794,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" dependencies = [ "generic-array", + "rand_core", "typenum", ] @@ -757,78 +813,112 @@ version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835" dependencies = [ - "cipher 0.4.4", + "cipher", ] [[package]] name = "curve25519-dalek" -version = "3.2.1" +version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90f9d052967f590a76e62eb387bd0bbb1b000182c3cefe5364db6b7211651bc0" +checksum = "0a677b8922c94e01bdbb12126b0bc852f00447528dee1782229af9c720c3f348" dependencies = [ - "byteorder", - "digest 0.9.0", - "rand_core 0.5.1", + "cfg-if", + "cpufeatures", + "curve25519-dalek-derive", + "digest", + "fiat-crypto", + "platforms", + "rustc_version", "serde", "subtle", "zeroize", ] [[package]] -name = "darling" -version = "0.14.4" +name = "curve25519-dalek-derive" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b750cb3417fd1b327431a470f388520309479ab0bf5e323505daf0290cd3850" +checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ - "darling_core", - "darling_macro", -] - -[[package]] -name = "darling_core" -version = "0.14.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "109c1ca6e6b7f82cc233a97004ea8ed7ca123a9af07a8230878fcfda9b158bf0" -dependencies = [ - "fnv", - "ident_case", "proc-macro2", "quote", - "strsim", - "syn 1.0.109", + "syn 2.0.52", ] [[package]] -name = "darling_macro" -version = "0.14.4" +name = "deadpool" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4aab4dbc9f7611d8b55048a3a16d2d010c2c8334e46304b40ac1cc14bf3b48e" +checksum = "fb84100978c1c7b37f09ed3ce3e5f843af02c2a2c431bae5b19230dad2c1b490" dependencies = [ - "darling_core", + "async-trait", + "deadpool-runtime", + "num_cpus", + "tokio", +] + +[[package]] +name = "deadpool-runtime" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63dfa964fe2a66f3fde91fc70b267fe193d822c7e603e2a675a49a7f46ad3f49" +dependencies = [ + "tokio", +] + +[[package]] +name = "deadpool-sqlite" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8010e36e12f3be22543a5e478b4af20aeead9a700dd69581a5e050a070fc22c" +dependencies = [ + "deadpool", + "deadpool-sync", + "rusqlite", +] + +[[package]] +name = "deadpool-sync" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8db70494c13cae4ce67b4b4dafdaf828cf0df7237ab5b9e2fcabee4965d0a0a" +dependencies = [ + "deadpool-runtime", +] + +[[package]] +name = "delegate-display" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98a85201f233142ac819bbf6226e36d0b5e129a47bd325084674261c82d4cd66" +dependencies = [ + "macroific", + "proc-macro2", "quote", - "syn 1.0.109", -] - -[[package]] -name = "dashmap" -version = "5.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" -dependencies = [ - "cfg-if", - "hashbrown 0.14.1", - "lock_api", - "once_cell", - "parking_lot_core 0.9.8", + "syn 2.0.52", ] [[package]] name = "der" -version = "0.5.1" +version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6919815d73839e7ad218de758883aae3a257ba6759ce7a9992501efbb53d705c" +checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c" dependencies = [ "const-oid", + "der_derive", + "flagset", + "zeroize", +] + +[[package]] +name = "der_derive" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fe87ce4529967e0ba1dcf8450bab64d97dfd5010a6256187ffe2e43e6f0e049" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.52", ] [[package]] @@ -837,37 +927,6 @@ version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f2696e8a945f658fd14dc3b87242e6b80cd0f36ff04ea560fa39082368847946" -[[package]] -name = "derive_builder" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d07adf7be193b71cc36b193d0f5fe60b918a3a9db4dad0449f57bcfd519704a3" -dependencies = [ - "derive_builder_macro", -] - -[[package]] -name = "derive_builder_core" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f91d4cfa921f1c05904dc3c57b4a32c38aed3340cce209f3a6fd1478babafc4" -dependencies = [ - "darling", - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "derive_builder_macro" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f0314b72bed045f3a68671b3c86328386762c93f82d98c65c3cb5e5f573dd68" -dependencies = [ - "derive_builder_core", - "syn 1.0.109", -] - [[package]] name = "derive_more" version = "0.99.17" @@ -899,22 +958,13 @@ version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8" -[[package]] -name = "digest" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" -dependencies = [ - "generic-array", -] - [[package]] name = "digest" version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ - "block-buffer 0.10.4", + "block-buffer", "crypto-common", "subtle", ] @@ -939,12 +989,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "discard" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "212d0f5754cb6769937f4501cc0e67f4f4483c8d2c3e1e922ee9edbe4ab4c7c0" - [[package]] name = "displaydoc" version = "0.2.4" @@ -953,7 +997,7 @@ checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.52", ] [[package]] @@ -964,26 +1008,27 @@ checksum = "23d2f3407d9a573d666de4b5bdf10569d73ca9478087346697dcbae6244bfbcd" [[package]] name = "ed25519" -version = "1.5.3" +version = "2.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91cff35c70bba8a626e3185d8cd48cc11b5437e1a5bcd15b9b5fa3c64b6dfee7" +checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53" dependencies = [ + "pkcs8", "serde", "signature", ] [[package]] name = "ed25519-dalek" -version = "1.0.1" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c762bae6dcaf24c4c84667b8579785430908723d5c889f469d76a41d59cc7a9d" +checksum = "4a3daa8e81a3963a60642bcc1f90a670680bd4a77535faa384e9d1c79d620871" dependencies = [ "curve25519-dalek", "ed25519", - "rand 0.7.3", + "rand_core", "serde", - "serde_bytes", - "sha2 0.9.9", + "sha2", + "subtle", "zeroize", ] @@ -1072,9 +1117,35 @@ dependencies = [ [[package]] name = "event-listener" -version = "2.5.3" +version = "4.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" +checksum = "67b215c49b2b248c855fb73579eb1f4f26c38ffdc12973e20e07b91d78d5646e" +dependencies = [ + "concurrent-queue", + "parking", + "pin-project-lite", +] + +[[package]] +name = "event-listener" +version = "5.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b5fb89194fa3cad959b833185b3063ba881dbfc7030680b314250779fb4cc91" +dependencies = [ + "concurrent-queue", + "parking", + "pin-project-lite", +] + +[[package]] +name = "event-listener-strategy" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "feedafcaa9b749175d5ac357452a9d41ea2911da598fde46ce1fe02c37751291" +dependencies = [ + "event-listener 5.2.0", + "pin-project-lite", +] [[package]] name = "exr" @@ -1092,6 +1163,42 @@ dependencies = [ "zune-inflate", ] +[[package]] +name = "eyeball" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42482893d982111055ce4b24234d6250396d3785767c6b04cedd84612a0b80fb" +dependencies = [ + "futures-core", + "readlock", + "tracing", +] + +[[package]] +name = "eyeball-im" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "021fab29d9670be5867b16d56a95c29a12c3c1bb654e7d589010a028716d625d" +dependencies = [ + "futures-core", + "imbl", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "fallible-iterator" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2acce4a10f12dc2fb14a218589d4f1f62ef011b2d0cc4b3cb1bba8e94da14649" + +[[package]] +name = "fallible-streaming-iterator" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a" + [[package]] name = "fancy-regex" version = "0.11.0" @@ -1102,6 +1209,18 @@ dependencies = [ "regex", ] +[[package]] +name = "fancy_constructor" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f71f317e4af73b2f8f608fac190c52eac4b1879d2145df1db2fe48881ca69435" +dependencies = [ + "macroific", + "proc-macro2", + "quote", + "syn 2.0.52", +] + [[package]] name = "fastrand" version = "2.0.1" @@ -1117,6 +1236,18 @@ dependencies = [ "simd-adler32", ] +[[package]] +name = "fiat-crypto" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1676f435fc1dadde4d03e43f5d62b259e1ce5f40bd4ffb21db2b42ebe59c1382" + +[[package]] +name = "flagset" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d52a7e408202050813e6f1d9addadcaafef3dca7530c7ddfb005d4081cce6779" + [[package]] name = "flate2" version = "1.0.27" @@ -1176,12 +1307,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "fs_extra" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" - [[package]] name = "futf" version = "0.1.5" @@ -1248,21 +1373,7 @@ checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", -] - -[[package]] -name = "futures-signals" -version = "0.3.33" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b175f2f6600dd81d92d20cf10872b03ea9df6b2513ca7f672341260dacb1ab2" -dependencies = [ - "discard", - "futures-channel", - "futures-core", - "futures-util", - "gensym", - "pin-project", + "syn 2.0.52", ] [[package]] @@ -1314,18 +1425,6 @@ dependencies = [ "version_check", ] -[[package]] -name = "gensym" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "913dce4c5f06c2ea40fc178c06f777ac89fc6b1383e90c254fafb1abe4ba3c82" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.38", - "uuid 1.4.1", -] - [[package]] name = "gethostname" version = "0.3.0" @@ -1357,27 +1456,14 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.1.16" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" +checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5" dependencies = [ "cfg-if", "js-sys", "libc", - "wasi 0.9.0+wasi-snapshot-preview1", - "wasm-bindgen", -] - -[[package]] -name = "getrandom" -version = "0.2.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" -dependencies = [ - "cfg-if", - "js-sys", - "libc", - "wasi 0.11.0+wasi-snapshot-preview1", + "wasi", "wasm-bindgen", ] @@ -1397,6 +1483,31 @@ version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" +[[package]] +name = "gloo-timers" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbb143cf96099802033e0d4f4963b19fd2e0b728bcf076cd9cf7f6634f092994" +dependencies = [ + "futures-channel", + "futures-core", + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "gloo-utils" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b5555354113b18c547c1d3a98fbf7fb32a9ff4f6fa112ce823a21641a0ba3aa" +dependencies = [ + "js-sys", + "serde", + "serde_json", + "wasm-bindgen", + "web-sys", +] + [[package]] name = "h2" version = "0.3.21" @@ -1430,39 +1541,24 @@ name = "hashbrown" version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" -dependencies = [ - "ahash", -] [[package]] name = "hashbrown" version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7dfda62a12f55daeae5015f81b0baea145391cb4520f86c248fc615d72640d12" - -[[package]] -name = "headers" -version = "0.3.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3e372db8e5c0d213e0cd0b9be18be2aca3d44cf2fe30a9d46a65581cd454584" dependencies = [ - "base64 0.13.1", - "bitflags 1.3.2", - "bytes", - "headers-core", - "http", - "httpdate", - "mime", - "sha1", + "ahash", + "allocator-api2", ] [[package]] -name = "headers-core" -version = "0.2.0" +name = "hashlink" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7f66481bfee273957b1f20485a4ff3362987f85b2c236580d81b4eb7a326429" +checksum = "e8094feaf31ff591f651a2664fb9cfd92bba7a60ce3197265e9482ebe753c8f7" dependencies = [ - "http", + "hashbrown 0.14.1", ] [[package]] @@ -1479,9 +1575,9 @@ checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" [[package]] name = "hkdf" -version = "0.12.3" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "791a029f6b9fc27657f6f188ec6e5e43f6911f6f878e0dc5501396e09809d437" +checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" dependencies = [ "hmac", ] @@ -1492,7 +1588,7 @@ version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" dependencies = [ - "digest 0.10.7", + "digest", ] [[package]] @@ -1618,12 +1714,15 @@ dependencies = [ "modalkit-ratatui", "open", "pretty_assertions", + "rand", "ratatui", "ratatui-image", "regex", "rpassword", "serde", "serde_json", + "sled", + "temp-dir", "thiserror", "tokio", "tracing", @@ -1664,12 +1763,6 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1dc4d30216c3fc247730a4c6c74db2bd217a5454361ce24d70e504bda0cd345e" -[[package]] -name = "ident_case" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" - [[package]] name = "idna" version = "0.4.0" @@ -1700,14 +1793,59 @@ dependencies = [ ] [[package]] -name = "indexed_db_futures" -version = "0.2.3" +name = "imbl" +version = "2.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d26ac735f676c52305becf53264b91cea9866a8de61ccbf464405b377b9cbca9" +checksum = "978d142c8028edf52095703af2fad11d6f611af1246685725d6b850634647085" dependencies = [ + "bitmaps", + "imbl-sized-chunks", + "rand_core", + "rand_xoshiro", + "serde", + "version_check", +] + +[[package]] +name = "imbl-sized-chunks" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "144006fb58ed787dcae3f54575ff4349755b00ccc99f4b4873860b654be1ed63" +dependencies = [ + "bitmaps", +] + +[[package]] +name = "include_dir" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18762faeff7122e89e0857b02f7ce6fcc0d101d5e9ad2ad7846cc01d61b7f19e" +dependencies = [ + "include_dir_macros", +] + +[[package]] +name = "include_dir_macros" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b139284b5cf57ecfa712bcc66950bb635b31aff41c188e8a4cfc758eca374a3f" +dependencies = [ + "proc-macro2", + "quote", +] + +[[package]] +name = "indexed_db_futures" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6cc2083760572ee02385ab8b7c02c20925d2dd1f97a1a25a8737a238608f1152" +dependencies = [ + "accessory", "cfg-if", + "delegate-display", + "fancy_constructor", "js-sys", - "uuid 0.8.2", + "uuid", "wasm-bindgen", "wasm-bindgen-futures", "web-sys", @@ -1721,7 +1859,6 @@ checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" dependencies = [ "autocfg", "hashbrown 0.12.3", - "serde", ] [[package]] @@ -1732,6 +1869,7 @@ checksum = "8adf3ddd720272c6ea8bf59463c04e0f93d0bbf7c5439b691bca2987e0270897" dependencies = [ "equivalent", "hashbrown 0.14.1", + "serde", ] [[package]] @@ -1817,6 +1955,15 @@ dependencies = [ "either", ] +[[package]] +name = "itertools" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +dependencies = [ + "either", +] + [[package]] name = "itoa" version = "1.0.9" @@ -1869,6 +2016,26 @@ dependencies = [ "unicode-width", ] +[[package]] +name = "konst" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d712a8c49d4274f8d8a5cf61368cb5f3c143d149882b1a2918129e53395fdb0" +dependencies = [ + "const_panic", + "konst_kernel", + "typewit", +] + +[[package]] +name = "konst_kernel" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dac6ea8c376b6e208a81cf39b8e82bebf49652454d98a4829e907dac16ef1790" +dependencies = [ + "typewit", +] + [[package]] name = "lazy_static" version = "0.1.16" @@ -1889,9 +2056,20 @@ checksum = "03087c2bad5e1034e8cace5926dec053fb3790248370865f5117a7d0213354c8" [[package]] name = "libc" -version = "0.2.148" +version = "0.2.153" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cdc71e17332e86d2e1d38c1f99edcb6288ee11b815fb1a4b049eaa2114d369b" +checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" + +[[package]] +name = "libsqlite3-sys" +version = "0.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf4e226dcd58b4be396f7bd3c20da8fdee2911400705297ba7d2d7cc2c30f716" +dependencies = [ + "cc", + "pkg-config", + "vcpkg", +] [[package]] name = "line-wrap" @@ -1936,21 +2114,59 @@ version = "0.4.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" -[[package]] -name = "lru" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6e8aaa3f231bb4bd57b84b2d5dc3ae7f350265df8aa96492e0bc394a1571909" -dependencies = [ - "hashbrown 0.12.3", -] - [[package]] name = "mac" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4" +[[package]] +name = "macroific" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f05c00ac596022625d01047c421a0d97d7f09a18e429187b341c201cb631b9dd" +dependencies = [ + "macroific_attr_parse", + "macroific_core", + "macroific_macro", +] + +[[package]] +name = "macroific_attr_parse" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd94d5da95b30ae6e10621ad02340909346ad91661f3f8c0f2b62345e46a2f67" +dependencies = [ + "cfg-if", + "proc-macro2", + "quote", + "syn 2.0.52", +] + +[[package]] +name = "macroific_core" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13198c120864097a565ccb3ff947672d969932b7975ebd4085732c9f09435e55" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.52", +] + +[[package]] +name = "macroific_macro" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0c9853143cbed7f1e41dc39fee95f9b361bec65c8dc2a01bf609be01b61f5ae" +dependencies = [ + "macroific_attr_parse", + "macroific_core", + "proc-macro2", + "quote", + "syn 2.0.52", +] + [[package]] name = "malloc_buf" version = "0.0.6" @@ -2003,128 +2219,174 @@ dependencies = [ ] [[package]] -name = "matrix-sdk" -version = "0.6.2" +name = "matrix-pickle" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbeafb4809f33f377165f2fbcf10e0613053ad206762194c3050a727fd3abcb2" +checksum = "d7fd26463ce5d86b8d9bb9c4142d453198ba22fb91bd46d3c9f144ae699d821d" +dependencies = [ + "matrix-pickle-derive", + "thiserror", +] + +[[package]] +name = "matrix-pickle-derive" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93779aa78d39c2fe34746287b10a866192cf8af1b81767fff76bd64099acc0f5" +dependencies = [ + "proc-macro-crate 2.0.2", + "proc-macro-error", + "proc-macro2", + "quote", + "syn 2.0.52", +] + +[[package]] +name = "matrix-sdk" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "336687e5fc8b33661a31681e988a67e9a3090c7fb1a8323a7f71eeaabad642ec" dependencies = [ "anymap2", - "async-once-cell", + "aquamarine", + "as_variant", + "async-channel", "async-stream", "async-trait", "backoff", "bytes", - "dashmap", - "derive_builder", - "event-listener", + "bytesize", + "cfg-vis", + "event-listener 4.0.3", + "eyeball", + "eyeball-im", "futures-core", - "futures-signals", "futures-util", + "gloo-timers", "http", + "hyper", + "imbl", + "indexmap 2.0.2", "matrix-sdk-base", "matrix-sdk-common", "matrix-sdk-indexeddb", - "matrix-sdk-sled", + "matrix-sdk-sqlite", "mime", - "rand 0.8.5", + "mime2ext", + "rand", "reqwest", "ruma", "serde", + "serde_html_form", "serde_json", + "tempfile", "thiserror", "tokio", "tokio-stream", + "tokio-util", + "tower", "tracing", "url", - "warp", - "wasm-timer", + "urlencoding", "zeroize", ] [[package]] name = "matrix-sdk-base" -version = "0.6.1" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b944f6d1fc8779ba790dd0b942ceff45c626c1f5da847f01122d355ad06511bd" +checksum = "00891954d0826a94f1d130f46cbca64176003a234c1be5d9d282970d31cf0c87" dependencies = [ - "async-stream", + "as_variant", "async-trait", - "dashmap", - "futures-channel", - "futures-core", - "futures-signals", + "bitflags 2.4.2", + "eyeball", + "eyeball-im", "futures-util", - "lru", "matrix-sdk-common", "matrix-sdk-crypto", + "matrix-sdk-store-encryption", "once_cell", "ruma", "serde", "serde_json", "thiserror", + "tokio", "tracing", - "zeroize", ] [[package]] name = "matrix-sdk-common" -version = "0.6.0" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b85a6a743cc9dcf9385e61a26db78276078beddd27f3762d9d82baa2030695f1" +checksum = "bb365a626ab6f6c6a2422cfe2565522f19accb06706c6d04bca8f0f71df29c9f" dependencies = [ - "async-lock", + "async-trait", "futures-core", "futures-util", + "gloo-timers", "instant", "ruma", "serde", + "serde_json", + "thiserror", "tokio", + "tracing", + "tracing-subscriber", + "wasm-bindgen", "wasm-bindgen-futures", - "wasm-timer", + "web-sys", ] [[package]] name = "matrix-sdk-crypto" -version = "0.6.0" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68fa699e8dd54578a4b92e3fcd18a50da8e415a0c042da1706b0330fc2d8f949" +checksum = "72aaeca3deb1387a63cd8c689270bd499b9eac3a594c2aaec72d7441ff00cd09" dependencies = [ "aes", + "as_variant", "async-trait", - "atomic", - "base64 0.13.1", + "bs58", "byteorder", + "cbc", + "cfg-if", "ctr", - "dashmap", - "event-listener", + "eyeball", + "futures-core", "futures-util", + "hkdf", "hmac", + "itertools 0.12.1", "matrix-sdk-common", "pbkdf2", - "rand 0.8.5", + "rand", + "rmp-serde", "ruma", "serde", "serde_json", - "sha2 0.10.8", + "sha2", + "subtle", "thiserror", "tokio", + "tokio-stream", "tracing", + "ulid", "vodozemac", "zeroize", ] [[package]] name = "matrix-sdk-indexeddb" -version = "0.2.0" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7847d36bba832bc787214323bc042b71dca7fdf2aee9f0e3eb573b64f2f7eb7f" +checksum = "ad388005c5d4ed2ff38f405d52aa7fa606f4e1ab51baf5f2504721124ed4a58b" dependencies = [ "anyhow", "async-trait", - "base64 0.13.1", - "dashmap", - "derive_builder", - "getrandom 0.2.10", + "base64", + "getrandom", + "gloo-utils", "indexed_db_futures", "js-sys", "matrix-sdk-base", @@ -2132,54 +2394,55 @@ dependencies = [ "matrix-sdk-store-encryption", "ruma", "serde", + "serde-wasm-bindgen", "serde_json", "thiserror", + "tokio", "tracing", "wasm-bindgen", "web-sys", ] [[package]] -name = "matrix-sdk-sled" -version = "0.2.0" +name = "matrix-sdk-sqlite" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ded5a703ad8a82b8edfde808228711315c8761a5fbf7ac2b98ab4951dadd066" +checksum = "20bd36bc5fa7ecd93516b242ba27466196d52b4a8743d85dd883a67bd6db11dc" dependencies = [ - "async-stream", "async-trait", - "dashmap", - "derive_builder", - "fs_extra", - "futures-core", - "futures-util", + "deadpool-sqlite", + "itertools 0.12.1", "matrix-sdk-base", - "matrix-sdk-common", "matrix-sdk-crypto", "matrix-sdk-store-encryption", + "rmp-serde", "ruma", + "rusqlite", "serde", "serde_json", - "sled", "thiserror", "tokio", "tracing", + "vodozemac", ] [[package]] name = "matrix-sdk-store-encryption" -version = "0.2.0" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ddee75c3cca58f3a323283dc4e849d19d52988903f907ed0fb53dcad5d6fd25" +checksum = "6a7e3162e9f982a4c57ab46df01a4775f697dec8899738bf62d7e97b63faa61c" dependencies = [ "blake3", "chacha20poly1305", "displaydoc", + "getrandom", "hmac", "pbkdf2", - "rand 0.8.5", + "rand", + "rmp-serde", "serde", "serde_json", - "sha2 0.10.8", + "sha2", "thiserror", "zeroize", ] @@ -2214,6 +2477,12 @@ version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" +[[package]] +name = "mime2ext" +version = "0.1.52" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1a85a5069ebd40e64b1985773cc81addbe9d90d7ecf60e7b5475a57ad584c70" + [[package]] name = "mime_guess" version = "2.0.4" @@ -2248,7 +2517,7 @@ checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2" dependencies = [ "libc", "log", - "wasi 0.11.0+wasi-snapshot-preview1", + "wasi", "windows-sys 0.48.0", ] @@ -2471,6 +2740,12 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" +[[package]] +name = "parking" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb813b8af86854136c6922af0598d719255ecb2179515e6e7730d468f05c9cae" + [[package]] name = "parking_lot" version = "0.11.2" @@ -2519,17 +2794,6 @@ dependencies = [ "windows-targets", ] -[[package]] -name = "password-hash" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7676374caaee8a325c9e7a2ae557f216c5563a171d6997b0ef8a65af35147700" -dependencies = [ - "base64ct", - "rand_core 0.6.4", - "subtle", -] - [[package]] name = "paste" version = "1.0.14" @@ -2544,14 +2808,12 @@ checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd" [[package]] name = "pbkdf2" -version = "0.11.0" +version = "0.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83a0692ec44e4cf1ef28ca317f14f8f07da2d95ec3fa01f86e4467b725e60917" +checksum = "f8ed6a7761f76e3b9f92dfb0a60a6a6477c61024b775147ff0973a02653abaf2" dependencies = [ - "digest 0.10.7", + "digest", "hmac", - "password-hash", - "sha2 0.10.8", ] [[package]] @@ -2595,7 +2857,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5d5285893bb5eb82e6aaf5d59ee909a06a16737a8970984dd7746ba9283498d6" dependencies = [ "phf_shared 0.10.0", - "rand 0.8.5", + "rand", ] [[package]] @@ -2616,26 +2878,6 @@ dependencies = [ "siphasher", ] -[[package]] -name = "pin-project" -version = "1.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fda4ed1c6c173e3fc7a83629421152e01d7b1f9b7f65fb301e490e8cfc656422" -dependencies = [ - "pin-project-internal", -] - -[[package]] -name = "pin-project-internal" -version = "1.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.38", -] - [[package]] name = "pin-project-lite" version = "0.2.13" @@ -2650,9 +2892,20 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "pkcs7" -version = "0.3.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f7364e6d0e236473de91e042395d71e0e64715f99a60620b014a4a4c7d1619b" +checksum = "d79178be066405e0602bf3035946edef6b11b3f9dde46dfe5f8bfd7dea4b77e7" +dependencies = [ + "der", + "spki", + "x509-cert", +] + +[[package]] +name = "pkcs8" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" dependencies = [ "der", "spki", @@ -2664,13 +2917,19 @@ version = "0.3.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" +[[package]] +name = "platforms" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "626dec3cac7cc0e1577a2ec3fc496277ec2baa084bebad95bb6fdbfae235f84c" + [[package]] name = "plist" version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bdc0001cfea3db57a2e24bc0d818e9e20e554b5f97fabb9bc231dc240269ae06" dependencies = [ - "base64 0.21.4", + "base64", "indexmap 1.9.3", "line-wrap", "quick-xml", @@ -2693,9 +2952,9 @@ dependencies = [ [[package]] name = "poly1305" -version = "0.7.2" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "048aeb476be11a4b6ca432ca569e375810de9294ae78f4774e78ea98a9246ede" +checksum = "8159bd90725d2df49889a078b54f4f79e87f1f8a8444194cdca81d38f5393abf" dependencies = [ "cpufeatures", "opaque-debug", @@ -2731,23 +2990,57 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" dependencies = [ "once_cell", - "toml_edit", + "toml_edit 0.19.15", +] + +[[package]] +name = "proc-macro-crate" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b00f26d3400549137f92511a46ac1cd8ce37cb5598a96d382381458b992a5d24" +dependencies = [ + "toml_datetime", + "toml_edit 0.20.2", +] + +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn 1.0.109", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", ] [[package]] name = "proc-macro2" -version = "1.0.67" +version = "1.0.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d433d9f1a3e8c1263d9456598b16fec66f4acc9a74dacffd35c7bb09b3a1328" +checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" dependencies = [ "unicode-ident", ] [[package]] name = "prost" -version = "0.11.9" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b82eaa1d779e9a4bc1c3217db8ffbeabaae1dca241bf70183242128d48681cd" +checksum = "146c289cda302b98a28d40c8b3b90498d6e526dd24ac2ecea73e4e491685b94a" dependencies = [ "bytes", "prost-derive", @@ -2755,15 +3048,15 @@ dependencies = [ [[package]] name = "prost-derive" -version = "0.11.9" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5d2d8d10f3c6ded6da8b05b5fb3b8a5082514344d56c9f871412d29b4e075b4" +checksum = "efb6c9a1dd1def8e2124d17e83a20af56f1570d6c2d2bd9e266ccb768df3840e" dependencies = [ "anyhow", - "itertools 0.10.5", + "itertools 0.11.0", "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.52", ] [[package]] @@ -2798,9 +3091,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.33" +version = "1.0.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" dependencies = [ "proc-macro2", ] @@ -2815,19 +3108,6 @@ dependencies = [ "nibble_vec", ] -[[package]] -name = "rand" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" -dependencies = [ - "getrandom 0.1.16", - "libc", - "rand_chacha 0.2.2", - "rand_core 0.5.1", - "rand_hc", -] - [[package]] name = "rand" version = "0.8.5" @@ -2835,18 +3115,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ "libc", - "rand_chacha 0.3.1", - "rand_core 0.6.4", -] - -[[package]] -name = "rand_chacha" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" -dependencies = [ - "ppv-lite86", - "rand_core 0.5.1", + "rand_chacha", + "rand_core", ] [[package]] @@ -2856,16 +3126,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" dependencies = [ "ppv-lite86", - "rand_core 0.6.4", -] - -[[package]] -name = "rand_core" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" -dependencies = [ - "getrandom 0.1.16", + "rand_core", ] [[package]] @@ -2874,16 +3135,16 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom 0.2.10", + "getrandom", ] [[package]] -name = "rand_hc" -version = "0.2.0" +name = "rand_xoshiro" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" +checksum = "6f97cdb2a36ed4183de61b2f824cc45c9f1037f28afe0a322e9fff4c108b5aaa" dependencies = [ - "rand_core 0.5.1", + "rand_core", ] [[package]] @@ -2909,12 +3170,12 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d864e8e24222cc289906cc53fede6f8751ce2935d636842a04dc65dfb9958e62" dependencies = [ - "base64 0.21.4", + "base64", "crossterm 0.25.0", "dyn-clone", "icy_sixel", "image", - "rand 0.8.5", + "rand", "ratatui", "rustix 0.38.17", "serde", @@ -2940,6 +3201,12 @@ dependencies = [ "crossbeam-utils", ] +[[package]] +name = "readlock" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7b323e7196daa571c8584de958be19e92941c41f845776fe06babfe8fa280a2" + [[package]] name = "redox_syscall" version = "0.2.16" @@ -2964,7 +3231,7 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" dependencies = [ - "getrandom 0.2.10", + "getrandom", "redox_syscall 0.2.16", "thiserror", ] @@ -3004,7 +3271,7 @@ version = "0.11.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "046cd98826c46c2ac8ddecae268eb5c2e58628688a5fc7a2643704a73faba95b" dependencies = [ - "base64 0.21.4", + "base64", "bytes", "encoding_rs", "futures-core", @@ -3029,10 +3296,12 @@ dependencies = [ "system-configuration", "tokio", "tokio-rustls", + "tokio-util", "tower-service", "url", "wasm-bindgen", "wasm-bindgen-futures", + "wasm-streams", "web-sys", "webpki-roots", "winreg", @@ -3053,6 +3322,28 @@ dependencies = [ "winapi", ] +[[package]] +name = "rmp" +version = "0.8.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f9860a6cc38ed1da53456442089b4dfa35e7cedaa326df63017af88385e6b20" +dependencies = [ + "byteorder", + "num-traits", + "paste", +] + +[[package]] +name = "rmp-serde" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bffea85eea980d8a74453e5d02a8d93028f3c34725de143085a844ebe953258a" +dependencies = [ + "byteorder", + "rmp", + "serde", +] + [[package]] name = "ropey" version = "1.6.0" @@ -3086,54 +3377,82 @@ dependencies = [ [[package]] name = "ruma" -version = "0.7.4" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8dc348e3a4a18abc4e97fffa5e2e623f6edd50ba3a1dd5f47eb249fea713b69f" +checksum = "2779c38df072964c63476259d9300efb07d0d1a7178c6469893636ce0c547a36" dependencies = [ "assign", "js_int", "js_option", "ruma-client-api", "ruma-common", + "ruma-events", "ruma-federation-api", ] [[package]] name = "ruma-client-api" -version = "0.15.3" +version = "0.17.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1e72bc731b4dc8b569aa83915f13e419144b67110d858c65bb74aa05e2dc4b7" +checksum = "641837258fa214a70823477514954ef0f5d3bc6ae8e1d5d85081856a33103386" dependencies = [ "assign", "bytes", "http", "js_int", + "js_option", "maplit", - "percent-encoding", "ruma-common", + "ruma-events", "serde", + "serde_html_form", "serde_json", ] [[package]] name = "ruma-common" -version = "0.10.5" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "716889595f4edc3cfeb94d9f122e413f73e37d7d80ea1c14196e1004241a3889" +checksum = "3bca4c33c50e47b4cdceeac71bdef0c04153b0e29aa992d9030ec14a62323e85" dependencies = [ - "base64 0.13.1", + "as_variant", + "base64", "bytes", "form_urlencoded", - "getrandom 0.2.10", + "getrandom", "http", - "indexmap 1.9.3", - "itoa", + "indexmap 2.0.2", "js-sys", "js_int", + "konst", + "percent-encoding", + "rand", + "regex", + "ruma-identifiers-validation", + "ruma-macros", + "serde", + "serde_html_form", + "serde_json", + "thiserror", + "tracing", + "url", + "uuid", + "wildmatch", +] + +[[package]] +name = "ruma-events" +version = "0.27.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d20a52770e5a9fb30b7a1c14ba8b3dcf76dadc01674e58e40094f78e6bd5e3f1" +dependencies = [ + "as_variant", + "indexmap 2.0.2", + "js_int", "js_option", "percent-encoding", - "rand 0.8.5", "regex", + "ruma-common", "ruma-identifiers-validation", "ruma-macros", "serde", @@ -3141,27 +3460,27 @@ dependencies = [ "thiserror", "tracing", "url", - "uuid 1.4.1", "wildmatch", ] [[package]] name = "ruma-federation-api" -version = "0.6.0" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f905d12f6144c7a754bd0339fa6893698c03d03a908abb20cc6eeb4ec7f9466" +checksum = "e1901c1f27bc327652d58af2a130c73acef3198abeccd24cee97f7267fdf3fe7" dependencies = [ "js_int", "ruma-common", + "ruma-events", "serde", "serde_json", ] [[package]] name = "ruma-identifiers-validation" -version = "0.9.1" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebefdab34311af44d07cd2cd91c36cfe6a8c770647c6b00f6ab47f1186b2bb72" +checksum = "bf8ad1259274f2f57c20901bd1cc5e4a8f23169d1c1d887b6338b02f058e9b41" dependencies = [ "js_int", "thiserror", @@ -3169,20 +3488,34 @@ dependencies = [ [[package]] name = "ruma-macros" -version = "0.10.5" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f82e91eb61cd86d9287303133ee55b54618eccb75a522cc22a42c15f5bda340" +checksum = "0280534a4b3e34416f883285fac4f9c408cd0b737890ae66f3e7a7056d14be80" dependencies = [ "once_cell", - "proc-macro-crate", + "proc-macro-crate 2.0.2", "proc-macro2", "quote", "ruma-identifiers-validation", "serde", - "syn 1.0.109", + "syn 2.0.52", "toml", ] +[[package]] +name = "rusqlite" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a78046161564f5e7cd9008aff3b2990b3850dc8e0349119b98e8f251e099f24d" +dependencies = [ + "bitflags 2.4.2", + "fallible-iterator", + "fallible-streaming-iterator", + "hashlink", + "libsqlite3-sys", + "smallvec", +] + [[package]] name = "rustc-demangle" version = "0.1.23" @@ -3243,7 +3576,7 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2d3987094b1d07b653b7dfdc3f70ce9a1da9c51ac18c1b06b662e4f9a0e9f4b2" dependencies = [ - "base64 0.21.4", + "base64", ] [[package]] @@ -3283,12 +3616,6 @@ dependencies = [ "winapi-util", ] -[[package]] -name = "scoped-tls" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" - [[package]] name = "scopeguard" version = "1.2.0" @@ -3313,44 +3640,77 @@ checksum = "ad977052201c6de01a8ef2aa3378c4bd23217a056337d1d6da40468d267a4fb0" [[package]] name = "serde" -version = "1.0.188" +version = "1.0.197" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e" +checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" dependencies = [ "serde_derive", ] [[package]] -name = "serde_bytes" -version = "0.11.12" +name = "serde-wasm-bindgen" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab33ec92f677585af6d88c65593ae2375adde54efdbf16d597f2cbc7a6d368ff" +checksum = "8302e169f0eddcc139c70f139d19d6467353af16f9fce27e8c30158036a1e16b" +dependencies = [ + "js-sys", + "serde", + "wasm-bindgen", +] + +[[package]] +name = "serde_bytes" +version = "0.11.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b8497c313fd43ab992087548117643f6fcd935cbf36f176ffda0aacf9591734" dependencies = [ "serde", ] [[package]] name = "serde_derive" -version = "1.0.188" +version = "1.0.197" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" +checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.52", +] + +[[package]] +name = "serde_html_form" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20e1066e1cfa6692a722cf40386a2caec36da5ddc4a2c16df592f0f609677e8c" +dependencies = [ + "form_urlencoded", + "indexmap 2.0.2", + "itoa", + "ryu", + "serde", ] [[package]] name = "serde_json" -version = "1.0.107" +version = "1.0.114" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b420ce6e3d8bd882e9b243c6eed35dbc9a6110c9769e74b584e0d68d1f20c65" +checksum = "c5f09b1bd632ef549eaa9f60a1f8de742bdbc698e6cee2095fc84dde5f549ae0" dependencies = [ "itoa", "ryu", "serde", ] +[[package]] +name = "serde_spanned" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb3622f419d1296904700073ea6cc23ad690adbd66f13ea683df73298736f0c1" +dependencies = [ + "serde", +] + [[package]] name = "serde_urlencoded" version = "0.7.1" @@ -3363,30 +3723,6 @@ dependencies = [ "serde", ] -[[package]] -name = "sha1" -version = "0.10.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f04293dc80c3993519f2d7f6f511707ee7094fe0c6d3406feb330cdb3540eba3" -dependencies = [ - "cfg-if", - "cpufeatures", - "digest 0.10.7", -] - -[[package]] -name = "sha2" -version = "0.9.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" -dependencies = [ - "block-buffer 0.9.0", - "cfg-if", - "cpufeatures", - "digest 0.9.0", - "opaque-debug", -] - [[package]] name = "sha2" version = "0.10.8" @@ -3395,7 +3731,7 @@ checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" dependencies = [ "cfg-if", "cpufeatures", - "digest 0.10.7", + "digest", ] [[package]] @@ -3445,9 +3781,12 @@ dependencies = [ [[package]] name = "signature" -version = "1.6.4" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" +dependencies = [ + "rand_core", +] [[package]] name = "simd-adler32" @@ -3544,10 +3883,11 @@ dependencies = [ [[package]] name = "spki" -version = "0.5.4" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44d01ac02a6ccf3e07db148d2be087da624fea0221a16152ed01f0496a6b0a27" +checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" dependencies = [ + "base64ct", "der", ] @@ -3614,7 +3954,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.38", + "syn 2.0.52", ] [[package]] @@ -3636,9 +3976,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.38" +version = "2.0.52" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +checksum = "b699d15b36d1f02c3e7c69f8ffef53de37aefae075d8488d4ba1a7788d574a07" dependencies = [ "proc-macro2", "quote", @@ -3688,6 +4028,12 @@ dependencies = [ "libc", ] +[[package]] +name = "temp-dir" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd16aa9ffe15fe021c6ee3766772132c6e98dfa395a167e16864f61a9cfb71d6" + [[package]] name = "tempfile" version = "3.8.0" @@ -3735,22 +4081,22 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.49" +version = "1.0.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1177e8c6d7ede7afde3585fd2513e611227efd6481bd78d2e82ba1ce16557ed4" +checksum = "1e45bcbe8ed29775f228095caf2cd67af7a4ccf756ebff23a306bf3e8b47b24b" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.49" +version = "1.0.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10712f02019e9288794769fba95cd6847df9874d49d871d062172f9dd41bc4cc" +checksum = "a953cb265bef375dae3de6663da4d3804eee9682ea80d8e2542529b73c531c81" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.52", ] [[package]] @@ -3844,7 +4190,7 @@ checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.52", ] [[package]] @@ -3866,6 +4212,7 @@ dependencies = [ "futures-core", "pin-project-lite", "tokio", + "tokio-util", ] [[package]] @@ -3884,11 +4231,14 @@ dependencies = [ [[package]] name = "toml" -version = "0.5.11" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" +checksum = "185d8ab0dfbb35cf1399a6344d8484209c088f75f8f68230da55d48d95d43e3d" dependencies = [ "serde", + "serde_spanned", + "toml_datetime", + "toml_edit 0.20.2", ] [[package]] @@ -3896,6 +4246,9 @@ name = "toml_datetime" version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b" +dependencies = [ + "serde", +] [[package]] name = "toml_edit" @@ -3908,6 +4261,39 @@ dependencies = [ "winnow", ] +[[package]] +name = "toml_edit" +version = "0.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "396e4d48bbb2b7554c944bde63101b5ae446cff6ec4a24227428f15eb72ef338" +dependencies = [ + "indexmap 2.0.2", + "serde", + "serde_spanned", + "toml_datetime", + "winnow", +] + +[[package]] +name = "tower" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" +dependencies = [ + "futures-util", + "pin-project-lite", + "tokio", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower-layer" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" + [[package]] name = "tower-service" version = "0.3.2" @@ -3916,11 +4302,10 @@ checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" [[package]] name = "tracing" -version = "0.1.37" +version = "0.1.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" dependencies = [ - "cfg-if", "log", "pin-project-lite", "tracing-attributes", @@ -3940,20 +4325,20 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.26" +version = "0.1.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab" +checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.52", ] [[package]] name = "tracing-core" -version = "0.1.31" +version = "0.1.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0955b8137a1df6f1a2e9a37d8a6656291ff0297c1a97c24e0d8425fe2312f79a" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" dependencies = [ "once_cell", "valuable", @@ -4002,6 +4387,32 @@ version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" +[[package]] +name = "typewit" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6fb9ae6a3cafaf0a5d14c2302ca525f9ae8e07a0f0e6949de88d882c37a6e24" +dependencies = [ + "typewit_proc_macros", +] + +[[package]] +name = "typewit_proc_macros" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e36a83ea2b3c704935a01b4642946aadd445cea40b10935e3f8bd8052b8193d6" + +[[package]] +name = "ulid" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34778c17965aa2a08913b57e1f34db9b4a63f5de31768b55bf20d2795f921259" +dependencies = [ + "getrandom", + "rand", + "web-time", +] + [[package]] name = "unicase" version = "2.7.0" @@ -4058,11 +4469,11 @@ checksum = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e" [[package]] name = "universal-hash" -version = "0.4.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8326b2c654932e3e4f9196e69d08fdf7cfd718e1dc6f66b347e6024a0c961402" +checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea" dependencies = [ - "generic-array", + "crypto-common", "subtle", ] @@ -4084,6 +4495,12 @@ dependencies = [ "serde", ] +[[package]] +name = "urlencoding" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da" + [[package]] name = "utf-8" version = "0.7.6" @@ -4098,20 +4515,11 @@ checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" [[package]] name = "uuid" -version = "0.8.2" +version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" +checksum = "5e395fcf16a7a3d8127ec99782007af141946b4795001f876d54fb0d55978560" dependencies = [ - "getrandom 0.2.10", -] - -[[package]] -name = "uuid" -version = "1.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79daa5ed5740825c40b389c5e50312b9c86df53fccd33f281df655642b43869d" -dependencies = [ - "getrandom 0.2.10", + "getrandom", "wasm-bindgen", ] @@ -4121,6 +4529,12 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + [[package]] name = "vergen" version = "8.2.5" @@ -4140,23 +4554,27 @@ checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" [[package]] name = "vodozemac" -version = "0.3.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6f20153a1c82ac5f1243b62e80f067ae608facc415c6ef82f88426a61c79886" +checksum = "2790dffeecc522299d72d9a855c43adb0c23ba1dc1112d79a651fdf3beb2a356" dependencies = [ "aes", "arrayvec", - "base64 0.13.1", + "base64", "cbc", + "curve25519-dalek", "ed25519-dalek", + "getrandom", "hkdf", "hmac", + "matrix-pickle", "pkcs7", "prost", - "rand 0.7.3", + "rand", "serde", + "serde_bytes", "serde_json", - "sha2 0.10.8", + "sha2", "subtle", "thiserror", "x25519-dalek", @@ -4182,41 +4600,6 @@ dependencies = [ "try-lock", ] -[[package]] -name = "warp" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba431ef570df1287f7f8b07e376491ad54f84d26ac473489427231e1718e1f69" -dependencies = [ - "bytes", - "futures-channel", - "futures-util", - "headers", - "http", - "hyper", - "log", - "mime", - "mime_guess", - "percent-encoding", - "pin-project", - "rustls-pemfile", - "scoped-tls", - "serde", - "serde_json", - "serde_urlencoded", - "tokio", - "tokio-stream", - "tokio-util", - "tower-service", - "tracing", -] - -[[package]] -name = "wasi" -version = "0.9.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" - [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" @@ -4230,8 +4613,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" dependencies = [ "cfg-if", - "serde", - "serde_json", "wasm-bindgen-macro", ] @@ -4246,7 +4627,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.52", "wasm-bindgen-shared", ] @@ -4280,7 +4661,7 @@ checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.52", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -4292,15 +4673,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" [[package]] -name = "wasm-timer" -version = "0.2.5" +name = "wasm-streams" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be0ecb0db480561e9a7642b5d3e4187c128914e58aa84330b9493e3eb68c5e7f" +checksum = "b4609d447824375f43e1ffbc051b50ad8f4b3ae8219680c94452ea05eb240ac7" dependencies = [ - "futures", + "futures-util", "js-sys", - "parking_lot 0.11.2", - "pin-utils", "wasm-bindgen", "wasm-bindgen-futures", "web-sys", @@ -4316,6 +4695,16 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "web-time" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ee269d72cc29bf77a2c4bc689cc750fb39f5cbd493d2205bbb3f5c7779cf7b0" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + [[package]] name = "webpki-roots" version = "0.25.2" @@ -4561,16 +4950,27 @@ dependencies = [ [[package]] name = "x25519-dalek" -version = "1.2.0" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2392b6b94a576b4e2bf3c5b2757d63f10ada8020a2e4d08ac849ebcf6ea8e077" +checksum = "c7e468321c81fb07fa7f4c636c3972b9100f0346e5b6a9f2bd0603a52f7ed277" dependencies = [ "curve25519-dalek", - "rand_core 0.5.1", + "rand_core", "serde", "zeroize", ] +[[package]] +name = "x509-cert" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1301e935010a701ae5f8655edc0ad17c44bad3ac5ce8c39185f75453b720ae94" +dependencies = [ + "const-oid", + "der", + "spki", +] + [[package]] name = "xdg" version = "2.5.2" @@ -4604,10 +5004,30 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec" [[package]] -name = "zeroize" -version = "1.3.0" +name = "zerocopy" +version = "0.7.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4756f7db3f7b5574938c3eb1c117038b8e07f95ee6718c0efad4ac21508f1efd" +checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.52", +] + +[[package]] +name = "zeroize" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" dependencies = [ "zeroize_derive", ] @@ -4620,7 +5040,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.52", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 905c355..84a596d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,7 +11,7 @@ license = "Apache-2.0" exclude = [".github", "CONTRIBUTING.md"] keywords = ["matrix", "chat", "tui", "vim"] categories = ["command-line-utilities"] -rust-version = "1.67" +rust-version = "1.70" build = "build.rs" [build-dependencies] @@ -40,12 +40,15 @@ markup5ever_rcdom = "0.2.0" mime = "^0.3.16" mime_guess = "^2.0.4" open = "3.2.0" +rand = "0.8.5" ratatui = "0.23" ratatui-image = { version = "0.4.3", features = ["serde"] } regex = "^1.5" rpassword = "^7.2" serde = "^1.0" serde_json = "^1.0" +sled = "0.34.7" +temp-dir = "0.1.12" thiserror = "^1.0.37" tracing = "~0.1.36" tracing-appender = "~0.2.2" @@ -66,9 +69,9 @@ git = "https://github.com/ulyssa/modalkit" rev = "cb8c8aeb9a499b9b16615ce144f9014d78036e01" [dependencies.matrix-sdk] -version = "^0.6.2" +version = "0.7.1" default-features = false -features = ["e2e-encryption", "sled", "rustls-tls", "sso-login"] +features = ["e2e-encryption", "rustls-tls", "bundled-sqlite", "sso-login"] [dependencies.tokio] version = "1.24.1" diff --git a/README.md b/README.md index 2d45619..a5ac745 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ website, [iamb.chat]. ## Installation -Install Rust (1.67.0 or above) and Cargo, and then run: +Install Rust (1.70.0 or above) and Cargo, and then run: ``` cargo install --locked iamb diff --git a/src/base.rs b/src/base.rs index 091ef09..d4ca0f6 100644 --- a/src/base.rs +++ b/src/base.rs @@ -32,17 +32,18 @@ use url::Url; use matrix_sdk::{ encryption::verification::SasVerification, - room::{Joined, Room as MatrixRoom}, + room::Room as MatrixRoom, ruma::{ events::{ reaction::ReactionEvent, + relation::Replacement, room::encrypted::RoomEncryptedEvent, room::message::{ OriginalRoomMessageEvent, Relation, - Replacement, RoomMessageEvent, RoomMessageEventContent, + RoomMessageEventContentWithoutRelation, }, tag::{TagName, Tags}, MessageLikeEvent, @@ -55,6 +56,7 @@ use matrix_sdk::{ RoomId, UserId, }, + RoomState as MatrixRoomState, }; use modalkit::{ @@ -581,6 +583,10 @@ pub enum IambError { #[error("Cryptographic storage error: {0}")] CryptoStore(#[from] matrix_sdk::encryption::CryptoStoreError), + /// A failure related to the cryptographic store. + #[error("Cannot export keys from sled: {0}")] + UpgradeSled(#[from] crate::sled_export::SledMigrationError), + /// An HTTP error. #[error("HTTP client error: {0}")] Http(#[from] matrix_sdk::HttpError), @@ -809,9 +815,9 @@ impl RoomInfo { } /// Insert an edit. - pub fn insert_edit(&mut self, msg: Replacement) { + pub fn insert_edit(&mut self, msg: Replacement) { let event_id = msg.event_id; - let new_content = msg.new_content; + let new_msgtype = msg.new_content; let key = if let Some(EventLocation::Message(k)) = self.keys.get(&event_id) { k @@ -827,10 +833,10 @@ impl RoomInfo { match &mut msg.event { MessageEvent::Original(orig) => { - orig.content.msgtype = new_content.msgtype; + orig.content.apply_replacement(new_msgtype); }, MessageEvent::Local(_, content) => { - content.msgtype = new_content.msgtype; + content.apply_replacement(new_msgtype); }, MessageEvent::Redacted(_) | MessageEvent::EncryptedOriginal(_) | @@ -1182,8 +1188,16 @@ impl ChatStore { } /// Get a joined room. - pub fn get_joined_room(&self, room_id: &RoomId) -> Option { - self.worker.client.get_joined_room(room_id) + pub fn get_joined_room(&self, room_id: &RoomId) -> Option { + let Some(room) = self.worker.client.get_room(room_id) else { + return None; + }; + + if room.state() == MatrixRoomState::Joined { + Some(room) + } else { + None + } } /// Get the title for a room. diff --git a/src/config.rs b/src/config.rs index 5fb28b3..d3d3fe2 100644 --- a/src/config.rs +++ b/src/config.rs @@ -5,20 +5,29 @@ use std::collections::HashMap; use std::fmt; use std::fs::File; use std::hash::{Hash, Hasher}; -use std::io::BufReader; +use std::io::{BufReader, BufWriter}; use std::path::{Path, PathBuf}; use std::process; use clap::Parser; -use matrix_sdk::ruma::{OwnedRoomAliasId, OwnedRoomId, OwnedUserId, UserId}; +use matrix_sdk::matrix_auth::MatrixSession; +use matrix_sdk::ruma::{OwnedDeviceId, OwnedRoomAliasId, OwnedRoomId, OwnedUserId, UserId}; use ratatui::style::{Color, Modifier as StyleModifier, Style}; use ratatui::text::Span; use ratatui_image::picker::ProtocolType; -use serde::{de::Error as SerdeError, de::Visitor, Deserialize, Deserializer}; +use serde::{de::Error as SerdeError, de::Visitor, Deserialize, Deserializer, Serialize}; use tracing::Level; use url::Url; -use super::base::{IambId, RoomInfo, SortColumn, SortFieldRoom, SortFieldUser, SortOrder}; +use super::base::{ + IambError, + IambId, + RoomInfo, + SortColumn, + SortFieldRoom, + SortFieldUser, + SortOrder, +}; macro_rules! usage { ( $($args: tt)* ) => { @@ -215,6 +224,40 @@ impl<'de> Deserialize<'de> for UserColor { } } +#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)] +pub struct Session { + access_token: String, + refresh_token: Option, + user_id: OwnedUserId, + device_id: OwnedDeviceId, +} + +impl From for MatrixSession { + fn from(session: Session) -> Self { + MatrixSession { + tokens: matrix_sdk::matrix_auth::MatrixSessionTokens { + access_token: session.access_token, + refresh_token: session.refresh_token, + }, + meta: matrix_sdk::SessionMeta { + user_id: session.user_id, + device_id: session.device_id, + }, + } + } +} + +impl From for Session { + fn from(session: MatrixSession) -> Self { + Session { + access_token: session.tokens.access_token, + refresh_token: session.tokens.refresh_token, + user_id: session.meta.user_id, + device_id: session.meta.device_id, + } + } +} + #[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq)] pub struct UserDisplayTunables { pub color: Option, @@ -421,14 +464,35 @@ impl Tunables { #[derive(Clone)] pub struct DirectoryValues { pub cache: PathBuf, + pub data: PathBuf, pub logs: PathBuf, pub downloads: Option, pub image_previews: PathBuf, } +impl DirectoryValues { + fn create_dir_all(&self) -> std::io::Result<()> { + use std::fs::create_dir_all; + + let Self { cache, data, logs, downloads, image_previews } = self; + + create_dir_all(cache)?; + create_dir_all(data)?; + create_dir_all(logs)?; + create_dir_all(image_previews)?; + + if let Some(downloads) = downloads { + create_dir_all(downloads)?; + } + + Ok(()) + } +} + #[derive(Clone, Default, Deserialize)] pub struct Directories { pub cache: Option, + pub data: Option, pub logs: Option, pub downloads: Option, pub image_previews: Option, @@ -438,6 +502,7 @@ impl Directories { fn merge(self, other: Self) -> Self { Directories { cache: self.cache.or(other.cache), + data: self.data.or(other.data), logs: self.logs.or(other.logs), downloads: self.downloads.or(other.downloads), image_previews: self.image_previews.or(other.image_previews), @@ -454,6 +519,15 @@ impl Directories { }) .expect("no dirs.cache value configured!"); + let data = self + .data + .or_else(|| { + let mut dir = dirs::data_dir()?; + dir.push("iamb"); + dir.into() + }) + .expect("no dirs.data value configured!"); + let logs = self.logs.unwrap_or_else(|| { let mut dir = cache.clone(); dir.push("logs"); @@ -468,7 +542,7 @@ impl Directories { dir }); - DirectoryValues { cache, logs, downloads, image_previews } + DirectoryValues { cache, data, logs, downloads, image_previews } } } @@ -540,9 +614,11 @@ impl IambConfig { #[derive(Clone)] pub struct ApplicationSettings { - pub matrix_dir: PathBuf, pub layout_json: PathBuf, pub session_json: PathBuf, + pub session_json_old: PathBuf, + pub sled_dir: PathBuf, + pub sqlite_dir: PathBuf, pub profile_name: String, pub profile: ProfileConfig, pub tunables: TunableValues, @@ -602,17 +678,30 @@ impl ApplicationSettings { let dirs = profile.dirs.take().unwrap_or_default().merge(dirs); let dirs = dirs.values(); + // Create directories + dirs.create_dir_all()?; + // Set up paths that live inside the profile's data directory. let mut profile_dir = config_dir.clone(); profile_dir.push("profiles"); profile_dir.push(profile_name.as_str()); - let mut matrix_dir = profile_dir.clone(); - matrix_dir.push("matrix"); + let mut profile_data_dir = dirs.data.clone(); + profile_data_dir.push("profiles"); + profile_data_dir.push(profile_name.as_str()); - let mut session_json = profile_dir; + let mut sled_dir = profile_dir.clone(); + sled_dir.push("matrix"); + + let mut sqlite_dir = profile_data_dir.clone(); + sqlite_dir.push("sqlite"); + + let mut session_json = profile_data_dir.clone(); session_json.push("session.json"); + let mut session_json_old = profile_dir; + session_json_old.push("session.json"); + // Set up paths that live inside the profile's cache directory. let mut cache_dir = dirs.cache.clone(); cache_dir.push("profiles"); @@ -622,9 +711,11 @@ impl ApplicationSettings { layout_json.push("layout.json"); let settings = ApplicationSettings { - matrix_dir, + sled_dir, layout_json, session_json, + session_json_old, + sqlite_dir, profile_name, profile, tunables, @@ -635,6 +726,21 @@ impl ApplicationSettings { Ok(settings) } + pub fn read_session(&self, path: impl AsRef) -> Result { + let file = File::open(path)?; + let reader = BufReader::new(file); + let session = serde_json::from_reader(reader).map_err(IambError::from)?; + Ok(session) + } + + pub fn write_session(&self, session: MatrixSession) -> Result<(), IambError> { + let file = File::create(self.session_json.as_path())?; + let writer = BufWriter::new(file); + let session = Session::from(session); + serde_json::to_writer(writer, &session).map_err(IambError::from)?; + Ok(()) + } + pub fn get_user_char_span<'a>(&self, user_id: &'a UserId) -> Span<'a> { let (color, c) = self .tunables diff --git a/src/main.rs b/src/main.rs index a32cd67..0e11203 100644 --- a/src/main.rs +++ b/src/main.rs @@ -19,7 +19,7 @@ use std::collections::VecDeque; use std::convert::TryFrom; use std::fmt::Display; use std::fs::{create_dir_all, File}; -use std::io::{stdout, BufReader, BufWriter, Stdout}; +use std::io::{stdout, BufWriter, Stdout}; use std::ops::DerefMut; use std::process; use std::sync::atomic::{AtomicUsize, Ordering}; @@ -27,7 +27,10 @@ use std::sync::Arc; use std::time::Duration; use clap::Parser; +use matrix_sdk::crypto::encrypt_room_key_export; use matrix_sdk::ruma::OwnedUserId; +use rand::{distributions::Alphanumeric, Rng}; +use temp_dir::TempDir; use tokio::sync::Mutex as AsyncMutex; use tracing_subscriber::FmtSubscriber; @@ -62,6 +65,7 @@ mod config; mod keybindings; mod message; mod preview; +mod sled_export; mod util; mod windows; mod worker; @@ -558,7 +562,7 @@ impl Application { match action { HomeserverAction::CreateRoom(alias, vis, flags) => { let client = &store.application.worker.client; - let room_id = create_room(client, alias.as_deref(), vis, flags).await?; + let room_id = create_room(client, alias, vis, flags).await?; let room = IambId::Room(room_id); let target = OpenTarget::Application(room); let action = WindowAction::Switch(target); @@ -659,36 +663,57 @@ impl Application { } } -async fn login(worker: Requester, settings: &ApplicationSettings) -> IambResult<()> { - println!("Logging in for {}...", settings.profile.user_id); +fn gen_passphrase() -> String { + rand::thread_rng() + .sample_iter(&Alphanumeric) + .take(20) + .map(char::from) + .collect() +} +fn read_response(question: &str) -> String { + println!("{question}"); + let mut input = String::new(); + let _ = std::io::stdin().read_line(&mut input); + input +} + +fn read_yesno(question: &str) -> Option { + read_response(question).chars().next().map(|c| c.to_ascii_lowercase()) +} + +async fn login(worker: &Requester, settings: &ApplicationSettings) -> IambResult<()> { if settings.session_json.is_file() { - let file = File::open(settings.session_json.as_path())?; - let reader = BufReader::new(file); - let session = serde_json::from_reader(reader).map_err(IambError::from)?; + let session = settings.read_session(&settings.session_json)?; + worker.login(LoginStyle::SessionRestore(session.into()))?; - worker.login(LoginStyle::SessionRestore(session))?; + return Ok(()); + } + + if settings.session_json_old.is_file() && !settings.sled_dir.is_dir() { + let session = settings.read_session(&settings.session_json_old)?; + worker.login(LoginStyle::SessionRestore(session.into()))?; return Ok(()); } loop { - println!("Please select login type: [p]assword / [s]ingle sign on"); - - let mut input = String::new(); - std::io::stdin().read_line(&mut input).unwrap(); - - let login_style = match input.chars().next().map(|c| c.to_ascii_lowercase()) { - None | Some('p') => { - let password = rpassword::prompt_password("Password: ")?; - LoginStyle::Password(password) - }, - Some('s') => LoginStyle::SingleSignOn, - Some(_) => { - println!("Failed to login. Please enter 'p' or 's'"); - continue; - }, - }; + let login_style = + match read_response("Please select login type: [p]assword / [s]ingle sign on") + .chars() + .next() + .map(|c| c.to_ascii_lowercase()) + { + None | Some('p') => { + let password = rpassword::prompt_password("Password: ")?; + LoginStyle::Password(password) + }, + Some('s') => LoginStyle::SingleSignOn, + Some(_) => { + println!("Failed to login. Please enter 'p' or 's'"); + continue; + }, + }; match worker.login(login_style) { Ok(info) => { @@ -713,17 +738,142 @@ fn print_exit(v: T) -> N { process::exit(2); } +// We can't access the OlmMachine directly, so write the keys to a temporary +// file first, and then import them later. +async fn check_import_keys( + settings: &ApplicationSettings, +) -> IambResult> { + let do_import = settings.sled_dir.is_dir() && !settings.sqlite_dir.is_dir(); + + if !do_import { + return Ok(None); + } + + let question = format!( + "Found old sled store in {}. Would you like to export room keys from it? [y]es/[n]o", + settings.sled_dir.display() + ); + + loop { + match read_yesno(&question) { + Some('y') => { + break; + }, + Some('n') => { + return Ok(None); + }, + Some(_) | None => { + continue; + }, + } + } + + let keys = sled_export::export_room_keys(&settings.sled_dir).await?; + let passphrase = gen_passphrase(); + + println!("* Encrypting {} room keys with the passphrase {passphrase:?}...", keys.len()); + + let encrypted = match encrypt_room_key_export(&keys, &passphrase, 500000) { + Ok(encrypted) => encrypted, + Err(e) => { + format!("* Failed to encrypt room keys during export: {e}"); + process::exit(2); + }, + }; + + let tmpdir = TempDir::new()?; + let exported = tmpdir.child("keys"); + + println!("* Writing encrypted room keys to {}...", exported.display()); + tokio::fs::write(&exported, &encrypted).await?; + + Ok(Some((tmpdir, passphrase))) +} + +async fn login_upgrade( + keydir: TempDir, + passphrase: String, + worker: &Requester, + settings: &ApplicationSettings, + store: &AsyncProgramStore, +) -> IambResult<()> { + println!( + "Please log in for {} to import the room keys into a new session", + settings.profile.user_id + ); + + login(worker, settings).await?; + + println!("* Importing room keys..."); + + let exported = keydir.child("keys"); + let imported = worker.client.encryption().import_room_keys(exported, &passphrase).await; + + match imported { + Ok(res) => { + println!( + "* Successfully imported {} out of {} keys", + res.imported_count, res.total_count + ); + let _ = keydir.cleanup(); + }, + Err(e) => { + println!( + "Failed to import room keys from {}/keys: {e}\n\n\ + They have been encrypted with the passphrase {passphrase:?}.\ + Please save them and try importing them manually instead\n", + keydir.path().display() + ); + + loop { + match read_yesno("Would you like to continue logging in? [y]es/[n]o") { + Some('y') => break, + Some('n') => print_exit("* Exiting..."), + Some(_) | None => continue, + } + } + }, + } + + println!("* Syncing..."); + worker::do_first_sync(&worker.client, store).await; + + Ok(()) +} + +async fn login_normal( + worker: &Requester, + settings: &ApplicationSettings, + store: &AsyncProgramStore, +) -> IambResult<()> { + println!("* Logging in for {}...", settings.profile.user_id); + login(worker, settings).await?; + worker::do_first_sync(&worker.client, store).await; + Ok(()) +} + async fn run(settings: ApplicationSettings) -> IambResult<()> { + // Get old keys the first time we run w/ the upgraded SDK. + let import_keys = check_import_keys(&settings).await?; + + // Set up client state. + create_dir_all(settings.sqlite_dir.as_path())?; + let client = worker::create_client(&settings).await; + // Set up the async worker thread and global store. - let worker = ClientWorker::spawn(settings.clone()).await; - let client = worker.client.clone(); + let worker = ClientWorker::spawn(client.clone(), settings.clone()).await; let store = ChatStore::new(worker.clone(), settings.clone()); let store = Store::new(store); let store = Arc::new(AsyncMutex::new(store)); worker.init(store.clone()); - login(worker, &settings).await.unwrap_or_else(print_exit); - worker::do_first_sync(client, &store).await; + if let Some((keydir, pass)) = import_keys { + login_upgrade(keydir, pass, &worker, &settings, &store) + .await + .unwrap_or_else(print_exit); + } else { + login_normal(&worker, &settings, &store).await.unwrap_or_else(print_exit); + } fn restore_tty() { let _ = crossterm::terminal::disable_raw_mode(); @@ -767,10 +917,6 @@ fn main() -> IambResult<()> { let log_prefix = format!("iamb-log-{}", settings.profile_name); let log_dir = settings.dirs.logs.as_path(); - create_dir_all(settings.matrix_dir.as_path())?; - create_dir_all(settings.dirs.image_previews.as_path())?; - create_dir_all(log_dir)?; - let appender = tracing_appender::rolling::daily(log_dir, log_prefix); let (appender, guard) = tracing_appender::non_blocking(appender); diff --git a/src/message/mod.rs b/src/message/mod.rs index 814ec29..0717ef7 100644 --- a/src/message/mod.rs +++ b/src/message/mod.rs @@ -9,6 +9,7 @@ use std::hash::{Hash, Hasher}; use chrono::{DateTime, Local as LocalTz, NaiveDateTime, TimeZone}; use comrak::{markdown_to_html, ComrakOptions}; +use serde_json::json; use unicode_width::UnicodeWidthStr; use matrix_sdk::ruma::{ @@ -33,7 +34,7 @@ use matrix_sdk::ruma::{ redaction::SyncRoomRedactionEvent, }, AnyMessageLikeEvent, - Redact, + RedactContent, RedactedUnsigned, }, EventId, @@ -345,6 +346,28 @@ impl PartialOrd for MessageCursor { } } +fn redaction_reason(ev: &SyncRoomRedactionEvent) -> Option<&str> { + let SyncRoomRedactionEvent::Original(ev) = ev else { + return None; + }; + + return ev.content.reason.as_deref(); +} + +fn redaction_unsigned(ev: SyncRoomRedactionEvent) -> RedactedUnsigned { + let reason = redaction_reason(&ev); + let redacted_because = json!({ + "content": { + "reason": reason + }, + "event_id": ev.event_id(), + "sender": ev.sender(), + "origin_server_ts": ev.origin_server_ts(), + "unsigned": {}, + }); + RedactedUnsigned::new(serde_json::from_value(redacted_because).unwrap()) +} + #[derive(Clone)] pub enum MessageEvent { EncryptedOriginal(Box), @@ -419,7 +442,14 @@ impl MessageEvent { MessageEvent::Redacted(_) => return, MessageEvent::Local(_, _) => return, MessageEvent::Original(ev) => { - let redacted = ev.clone().redact(redaction, version); + let redacted = RedactedRoomMessageEvent { + content: ev.content.clone().redact(version), + event_id: ev.event_id.clone(), + sender: ev.sender.clone(), + origin_server_ts: ev.origin_server_ts, + room_id: ev.room_id.clone(), + unsigned: redaction_unsigned(redaction), + }; *self = MessageEvent::Redacted(Box::new(redacted)); }, } @@ -455,11 +485,7 @@ fn body_cow_content(content: &RoomMessageEventContent) -> Cow<'_, str> { } fn body_cow_reason(unsigned: &RedactedUnsigned) -> Cow<'_, str> { - let reason = unsigned - .redacted_because - .as_ref() - .and_then(|e| e.as_original()) - .and_then(|r| r.content.reason.as_ref()); + let reason = unsigned.redacted_because.content.reason.as_ref(); if let Some(r) = reason { Cow::Owned(format!("[Redacted: {r:?}]")) diff --git a/src/sled_export.rs b/src/sled_export.rs new file mode 100644 index 0000000..bf549b2 --- /dev/null +++ b/src/sled_export.rs @@ -0,0 +1,58 @@ +//! # sled -> sqlite migration code +//! +//! Before the 0.0.9 release, iamb used matrix-sdk@0.6.2, which used [sled] +//! for storing information, including room keys. In matrix-sdk@0.7.0, +//! the SDK switched to using SQLite. This module takes care of opening +//! sled, exporting the inbound group sessions used for decryption, +//! and importing them into SQLite. +//! +//! This code will eventually be removed once people have been given enough +//! time to upgrade off of pre-0.0.9 versions. +//! +//! [sled]: https://docs.rs/sled/0.34.7/sled/index.html +use sled::{Config, IVec}; +use std::path::Path; + +use crate::base::IambError; +use matrix_sdk::crypto::olm::{ExportedRoomKey, InboundGroupSession, PickledInboundGroupSession}; + +#[derive(Debug, thiserror::Error)] +pub enum SledMigrationError { + #[error("sled failure: {0}")] + Sled(#[from] sled::Error), + + #[error("deserialization failure: {0}")] + Deserialize(#[from] serde_json::Error), +} + +fn group_session_from_slice( + (_, bytes): (IVec, IVec), +) -> Result { + serde_json::from_slice(&bytes).map_err(SledMigrationError::from) +} + +async fn export_room_keys_priv( + sled_dir: &Path, +) -> Result, SledMigrationError> { + let path = sled_dir.join("matrix-sdk-state"); + let store = Config::new().temporary(false).path(&path).open()?; + let inbound_groups = store.open_tree("inbound_group_sessions")?; + + let mut exported = vec![]; + let sessions = inbound_groups + .iter() + .map(|p| p.map_err(SledMigrationError::from).and_then(group_session_from_slice)) + .collect::, _>>()? + .into_iter() + .filter_map(|p| InboundGroupSession::from_pickle(p).ok()); + + for session in sessions { + exported.push(session.export().await); + } + + Ok(exported) +} + +pub async fn export_room_keys(sled_dir: &Path) -> Result, IambError> { + export_room_keys_priv(sled_dir).await.map_err(IambError::from) +} diff --git a/src/tests.rs b/src/tests.rs index 975d167..f2ffb83 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -169,6 +169,7 @@ pub fn mock_room() -> RoomInfo { pub fn mock_dirs() -> DirectoryValues { DirectoryValues { cache: PathBuf::new(), + data: PathBuf::new(), logs: PathBuf::new(), downloads: None, image_previews: PathBuf::new(), @@ -202,9 +203,11 @@ pub fn mock_tunables() -> TunableValues { pub fn mock_settings() -> ApplicationSettings { ApplicationSettings { - matrix_dir: PathBuf::new(), layout_json: PathBuf::new(), session_json: PathBuf::new(), + session_json_old: PathBuf::new(), + sled_dir: PathBuf::new(), + sqlite_dir: PathBuf::new(), profile_name: "test".into(), profile: ProfileConfig { diff --git a/src/windows/room/chat.rs b/src/windows/room/chat.rs index ea15c51..dc171ab 100644 --- a/src/windows/room/chat.rs +++ b/src/windows/room/chat.rs @@ -14,14 +14,16 @@ use url::Url; use matrix_sdk::{ attachment::AttachmentConfig, media::{MediaFormat, MediaRequest}, - room::{Joined, Room as MatrixRoom}, + room::Room as MatrixRoom, ruma::{ - events::reaction::{ReactionEventContent, Relation as Reaction}, + events::reaction::ReactionEventContent, + events::relation::{Annotation, Replacement}, events::room::message::{ + AddMentions, + ForwardThread, MessageType, OriginalRoomMessageEvent, Relation, - Replacement, RoomMessageEventContent, TextMessageEventContent, }, @@ -29,6 +31,7 @@ use matrix_sdk::{ OwnedRoomId, RoomId, }, + RoomState, }; use ratatui::{ @@ -126,8 +129,16 @@ impl ChatState { } } - fn get_joined(&self, worker: &Requester) -> Result { - worker.client.get_joined_room(self.id()).ok_or(IambError::NotJoined) + fn get_joined(&self, worker: &Requester) -> Result { + let Some(room) = worker.client.get_room(self.id()) else { + return Err(IambError::NotJoined); + }; + + if room.state() == RoomState::Joined { + Ok(room) + } else { + Err(IambError::NotJoined) + } } fn get_reply_to<'a>(&self, info: &'a RoomInfo) -> Option<&'a OriginalRoomMessageEvent> { @@ -356,9 +367,9 @@ impl ChatState { }, }; - let reaction = Reaction::new(event_id, emoji); + let reaction = Annotation::new(event_id, emoji); let msg = ReactionEventContent::new(reaction); - let _ = room.send(msg, None).await.map_err(IambError::from)?; + let _ = room.send(msg).await.map_err(IambError::from)?; Ok(None) }, @@ -449,12 +460,7 @@ impl ChatState { _: ProgramContext, store: &mut ProgramStore, ) -> IambResult { - let room = store - .application - .worker - .client - .get_joined_room(self.id()) - .ok_or(IambError::NotJoined)?; + let room = self.get_joined(&store.application.worker)?; let info = store.application.rooms.get_or_default(self.id().to_owned()); let mut show_echo = true; @@ -475,18 +481,18 @@ impl ChatState { if let Some((_, event_id)) = &self.editing { msg.relates_to = Some(Relation::Replacement(Replacement::new( event_id.clone(), - Box::new(msg.clone()), + msg.msgtype.clone().into(), ))); show_echo = false; } else if let Some(m) = self.get_reply_to(info) { // XXX: Switch to RoomMessageEventContent::reply() once it's stable? - msg = msg.make_reply_to(m); + msg = msg.make_reply_to(m, ForwardThread::Yes, AddMentions::No); } // XXX: second parameter can be a locally unique transaction id. // Useful for doing retries. - let resp = room.send(msg.clone(), None).await.map_err(IambError::from)?; + let resp = room.send(msg.clone()).await.map_err(IambError::from)?; let event_id = resp.event_id; // Reset message bar state now that it's been sent. @@ -506,7 +512,7 @@ impl ChatState { let config = AttachmentConfig::new(); let resp = room - .send_attachment(name.as_ref(), &mime, bytes.as_ref(), config) + .send_attachment(name.as_ref(), &mime, bytes, config) .await .map_err(IambError::from)?; @@ -536,7 +542,7 @@ impl ChatState { let config = AttachmentConfig::new(); let resp = room - .send_attachment(name.as_ref(), &mime, bytes.as_ref(), config) + .send_attachment(name.as_ref(), &mime, bytes, config) .await .map_err(IambError::from)?; diff --git a/src/windows/room/mod.rs b/src/windows/room/mod.rs index 83493ac..d304fd6 100644 --- a/src/windows/room/mod.rs +++ b/src/windows/room/mod.rs @@ -1,6 +1,6 @@ //! # Windows for Matrix rooms and spaces use matrix_sdk::{ - room::{Invited, Room as MatrixRoom}, + room::Room as MatrixRoom, ruma::{ events::{ room::{name::RoomNameEventContent, topic::RoomTopicEventContent}, @@ -9,6 +9,7 @@ use matrix_sdk::{ RoomId, }, DisplayName, + RoomState as MatrixRoomState, }; use ratatui::{ @@ -114,7 +115,7 @@ impl RoomState { fn draw_invite( &self, - invited: Invited, + invited: MatrixRoom, area: Rect, buf: &mut Buffer, store: &mut ProgramStore, @@ -177,12 +178,12 @@ impl RoomState { ) -> IambResult, ProgramContext)>> { match act { RoomAction::InviteAccept => { - if let Some(room) = store.application.worker.client.get_invited_room(self.id()) { + if let Some(room) = store.application.worker.client.get_room(self.id()) { let details = room.invite_details().await.map_err(IambError::from)?; let details = details.invitee.event().original_content(); let is_direct = details.and_then(|ev| ev.is_direct).unwrap_or_default(); - room.accept_invitation().await.map_err(IambError::from)?; + room.join().await.map_err(IambError::from)?; if is_direct { room.set_is_direct(true).await.map_err(IambError::from)?; @@ -194,8 +195,8 @@ impl RoomState { } }, RoomAction::InviteReject => { - if let Some(room) = store.application.worker.client.get_invited_room(self.id()) { - room.reject_invitation().await.map_err(IambError::from)?; + if let Some(room) = store.application.worker.client.get_room(self.id()) { + room.leave().await.map_err(IambError::from)?; Ok(vec![]) } else { @@ -203,7 +204,7 @@ impl RoomState { } }, RoomAction::InviteSend(user) => { - if let Some(room) = store.application.worker.client.get_joined_room(self.id()) { + if let Some(room) = store.application.worker.client.get_room(self.id()) { room.invite_user_by_id(user.as_ref()).await.map_err(IambError::from)?; Ok(vec![]) @@ -212,7 +213,7 @@ impl RoomState { } }, RoomAction::Leave(skip_confirm) => { - if let Some(room) = store.application.worker.client.get_joined_room(self.id()) { + if let Some(room) = store.application.worker.client.get_room(self.id()) { if skip_confirm { room.leave().await.map_err(IambError::from)?; @@ -247,7 +248,7 @@ impl RoomState { match field { RoomField::Name => { - let ev = RoomNameEventContent::new(value.into()); + let ev = RoomNameEventContent::new(value); let _ = room.send_state_event(ev).await.map_err(IambError::from)?; }, RoomField::Tag(tag) => { @@ -272,7 +273,7 @@ impl RoomState { match field { RoomField::Name => { - let ev = RoomNameEventContent::new(None); + let ev = RoomNameEventContent::new("".into()); let _ = room.send_state_event(ev).await.map_err(IambError::from)?; }, RoomField::Tag(tag) => { @@ -381,12 +382,12 @@ impl TerminalCursor for RoomState { impl WindowOps for RoomState { fn draw(&mut self, area: Rect, buf: &mut Buffer, focused: bool, store: &mut ProgramStore) { - if let MatrixRoom::Invited(_) = self.room() { + if self.room().state() == MatrixRoomState::Invited { self.refresh_room(store); } - if let MatrixRoom::Invited(invited) = self.room() { - self.draw_invite(invited.clone(), area, buf, store); + if self.room().state() == MatrixRoomState::Invited { + self.draw_invite(self.room().clone(), area, buf, store); } match self { diff --git a/src/worker.rs b/src/worker.rs index 2d2b1dc..66a9c29 100644 --- a/src/worker.rs +++ b/src/worker.rs @@ -5,8 +5,7 @@ use std::collections::HashMap; use std::convert::TryFrom; use std::fmt::{Debug, Formatter}; -use std::fs::File; -use std::io::BufWriter; +use std::ops::Deref; use std::str::FromStr; use std::sync::mpsc::{sync_channel, Receiver, SyncSender}; use std::sync::Arc; @@ -17,13 +16,15 @@ use gethostname::gethostname; use tokio::sync::mpsc::{unbounded_channel, UnboundedReceiver, UnboundedSender}; use tokio::task::JoinHandle; use tracing::{error, warn}; +use url::Url; use matrix_sdk::{ config::{RequestConfig, SyncSettings}, encryption::verification::{SasVerification, Verification}, event_handler::Ctx, + matrix_auth::MatrixSession, reqwest, - room::{Invited, Messages, MessagesOptions, Room as MatrixRoom, RoomMember}, + room::{Messages, MessagesOptions, Room as MatrixRoom, RoomMember}, ruma::{ api::client::{ filter::{FilterDefinition, LazyLoadOptions, RoomEventFilter, RoomFilter}, @@ -42,7 +43,8 @@ use matrix_sdk::{ }, presence::PresenceEvent, reaction::ReactionEventContent, - receipt::{ReceiptEventContent, ReceiptType}, + receipt::ReceiptType, + receipt::{ReceiptEventContent, ReceiptThread}, room::{ encryption::RoomEncryptionEventContent, member::OriginalSyncRoomMemberEvent, @@ -73,8 +75,9 @@ use matrix_sdk::{ RoomVersionId, }, Client, + ClientBuildError, DisplayName, - Session, + RoomMemberships, }; use modalkit::errors::UIError; @@ -106,9 +109,13 @@ fn initial_devname() -> String { format!("{} on {}", IAMB_DEVICE_NAME, gethostname().to_string_lossy()) } +async fn is_direct(room: &MatrixRoom) -> bool { + room.deref().is_direct().await.unwrap_or_default() +} + pub async fn create_room( client: &Client, - room_alias_name: Option<&str>, + room_alias_name: Option, rt: CreateRoomType, flags: CreateRoomFlags, ) -> IambResult { @@ -154,8 +161,8 @@ pub async fn create_room( let request = assign!(CreateRoomRequest::new(), { room_alias_name, creation_content, - initial_state: initial_state.as_slice(), - invite: invite.as_slice(), + initial_state, + invite, is_direct, visibility, preset, @@ -164,27 +171,31 @@ pub async fn create_room( let resp = client.create_room(request).await.map_err(IambError::from)?; if is_direct { - if let Some(room) = client.get_room(&resp.room_id) { + if let Some(room) = client.get_room(resp.room_id()) { room.set_is_direct(true).await.map_err(IambError::from)?; } else { error!( - room_id = resp.room_id.as_str(), + room_id = resp.room_id().as_str(), "Couldn't set is_direct for new direct message room" ); } } - return Ok(resp.room_id); + return Ok(resp.room_id().to_owned()); } async fn update_event_receipts(info: &mut RoomInfo, room: &MatrixRoom, event_id: &EventId) { - let receipts = match room.event_read_receipts(event_id).await { + let receipts = match room + .load_event_receipts(ReceiptType::Read, ReceiptThread::Main, event_id) + .await + { Ok(receipts) => receipts, Err(e) => { tracing::warn!(?event_id, "failed to get event receipts: {e}"); return; }, }; + for (user_id, _) in receipts { info.set_receipt(user_id, event_id.to_owned()); } @@ -339,7 +350,10 @@ async fn load_older(client: &Client, store: &AsyncProgramStore) -> usize { async fn members_load(client: &Client, room_id: &RoomId) -> IambResult> { if let Some(room) = client.get_room(room_id) { - Ok(room.members_no_sync().await.map_err(IambError::from)?) + Ok(room + .members_no_sync(RoomMemberships::all()) + .await + .map_err(IambError::from)?) } else { Err(IambError::UnknownRoom(room_id.to_owned()).into()) } @@ -388,12 +402,12 @@ async fn refresh_rooms(client: &Client, store: &AsyncProgramStore) { names.push((room.room_id().to_owned(), name)); - if room.is_direct() { - dms.push(Arc::new((room.into(), tags))); + if is_direct(&room).await { + dms.push(Arc::new((room, tags))); } else if room.is_space() { - spaces.push(Arc::new((room.into(), tags))); + spaces.push(Arc::new((room, tags))); } else { - rooms.push(Arc::new((room.into(), tags))); + rooms.push(Arc::new((room, tags))); } } @@ -403,12 +417,12 @@ async fn refresh_rooms(client: &Client, store: &AsyncProgramStore) { names.push((room.room_id().to_owned(), name)); - if room.is_direct() { - dms.push(Arc::new((room.into(), tags))); + if is_direct(&room).await { + dms.push(Arc::new((room, tags))); } else if room.is_space() { - spaces.push(Arc::new((room.into(), tags))); + spaces.push(Arc::new((room, tags))); } else { - rooms.push(Arc::new((room.into(), tags))); + rooms.push(Arc::new((room, tags))); } } @@ -458,10 +472,20 @@ async fn send_receipts_forever(client: &Client, store: &AsyncProgramStore) { drop(locked); for (room_id, new_receipt) in updates { - let Some(room) = client.get_joined_room(&room_id) else { + use matrix_sdk::ruma::api::client::receipt::create_receipt::v3::ReceiptType; + + let Some(room) = client.get_room(&room_id) else { continue; }; - match room.read_receipt(&new_receipt).await { + + match room + .send_single_receipt( + ReceiptType::Read, + ReceiptThread::Unthreaded, + new_receipt.clone(), + ) + .await + { Ok(()) => { sent.insert(room_id, new_receipt); }, @@ -471,7 +495,7 @@ async fn send_receipts_forever(client: &Client, store: &AsyncProgramStore) { } } -pub async fn do_first_sync(client: Client, store: &AsyncProgramStore) { +pub async fn do_first_sync(client: &Client, store: &AsyncProgramStore) { // Perform an initial, lazily-loaded sync. let mut room = RoomEventFilter::default(); room.lazy_load_options = LazyLoadOptions::Enabled { include_redundant_members: false }; @@ -490,7 +514,7 @@ pub async fn do_first_sync(client: Client, store: &AsyncProgramStore) { } // Populate sync_info with our initial set of rooms/dms/spaces. - refresh_rooms(&client, store).await; + refresh_rooms(client, store).await; // Insert Need::Messages to fetch accurate recent timestamps in the background. let mut locked = store.lock().await; @@ -509,7 +533,7 @@ pub async fn do_first_sync(client: Client, store: &AsyncProgramStore) { #[derive(Debug)] pub enum LoginStyle { - SessionRestore(Session), + SessionRestore(MatrixSession), Password(String), SingleSignOn, } @@ -543,7 +567,7 @@ pub enum WorkerTask { Init(AsyncProgramStore, ClientReply<()>), Login(LoginStyle, ClientReply>), Logout(String, ClientReply>), - GetInviter(Invited, ClientReply>>), + GetInviter(MatrixRoom, ClientReply>>), GetRoom(OwnedRoomId, ClientReply>), JoinRoom(String, ClientReply>), Members(OwnedRoomId, ClientReply>>), @@ -618,6 +642,56 @@ impl Debug for WorkerTask { } } +async fn create_client_inner( + homeserver: &Option, + settings: &ApplicationSettings, +) -> Result { + let req_timeout = Duration::from_secs(settings.tunables.request_timeout); + + // Set up the HTTP client. + let http = reqwest::Client::builder() + .user_agent(IAMB_USER_AGENT) + .timeout(req_timeout) + .pool_idle_timeout(Duration::from_secs(60)) + .pool_max_idle_per_host(10) + .tcp_keepalive(Duration::from_secs(10)) + .build() + .unwrap(); + + let req_config = RequestConfig::new().timeout(req_timeout).retry_timeout(req_timeout); + + // Set up the Matrix client for the selected profile. + let builder = Client::builder() + .http_client(http) + .sqlite_store(settings.sqlite_dir.as_path(), None) + .request_config(req_config); + + let builder = if let Some(url) = homeserver { + // Use the explicitly specified homeserver. + builder.homeserver_url(url.as_str()) + } else { + // Try to discover the homeserver from the user ID. + let account = &settings.profile; + builder.server_name(account.user_id.server_name()) + }; + + builder.build().await +} + +pub async fn create_client(settings: &ApplicationSettings) -> Client { + let account = &settings.profile; + let res = match create_client_inner(&account.url, settings).await { + Err(ClientBuildError::AutoDiscovery(_)) => { + let url = format!("https://{}/", account.user_id.server_name().as_str()); + let url = Url::parse(&url).unwrap(); + create_client_inner(&Some(url), settings).await + }, + res => res, + }; + + res.expect("Failed to instantiate client") +} + #[derive(Clone)] pub struct Requester { pub client: Client, @@ -649,7 +723,7 @@ impl Requester { return response.recv(); } - pub fn get_inviter(&self, invite: Invited) -> IambResult> { + pub fn get_inviter(&self, invite: MatrixRoom) -> IambResult> { let (reply, response) = oneshot(); self.tx.send(WorkerTask::GetInviter(invite, reply)).unwrap(); @@ -719,40 +793,8 @@ pub struct ClientWorker { } impl ClientWorker { - pub async fn spawn(settings: ApplicationSettings) -> Requester { + pub async fn spawn(client: Client, settings: ApplicationSettings) -> Requester { let (tx, rx) = unbounded_channel(); - let account = &settings.profile; - - let req_timeout = Duration::from_secs(settings.tunables.request_timeout); - - // Set up the HTTP client. - let http = reqwest::Client::builder() - .user_agent(IAMB_USER_AGENT) - .timeout(req_timeout) - .pool_idle_timeout(Duration::from_secs(60)) - .pool_max_idle_per_host(10) - .tcp_keepalive(Duration::from_secs(10)) - .build() - .unwrap(); - - let req_config = RequestConfig::new().timeout(req_timeout).retry_timeout(req_timeout); - - // Set up the Matrix client for the selected profile. - let builder = Client::builder() - .http_client(Arc::new(http)) - .sled_store(settings.matrix_dir.as_path(), None) - .expect("Failed to setup up sled store for Matrix SDK") - .request_config(req_config); - - let builder = if let Some(url) = account.url.as_ref() { - // Use the explicitly specified homeserver. - builder.homeserver_url(url.as_str()) - } else { - // Try to discover the homeserver from the user ID. - builder.server_name(account.user_id.server_name()) - }; - - let client = builder.build().await.expect("Failed to instantiate Matrix client"); let mut worker = ClientWorker { initialized: false, @@ -872,13 +914,11 @@ impl ClientWorker { store: Ctx| { async move { if let SyncStateEvent::Original(ev) = ev { - if let Some(room_name) = ev.content.name { - let room_id = room.room_id().to_owned(); - let room_name = Some(room_name.to_string()); - let mut locked = store.lock().await; - let info = locked.application.rooms.get_or_default(room_id.clone()); - info.name = room_name; - } + let room_id = room.room_id().to_owned(); + let room_name = Some(ev.content.name); + let mut locked = store.lock().await; + let info = locked.application.rooms.get_or_default(room_id.clone()); + info.name = room_name; } } }, @@ -980,7 +1020,11 @@ impl ClientWorker { let mut locked = store.lock().await; let info = locked.application.get_room_info(room_id.to_owned()); - match info.keys.get(&ev.redacts) { + let Some(redacts) = &ev.redacts else { + return; + }; + + match info.keys.get(redacts) { None => return, Some(EventLocation::Message(key)) => { if let Some(msg) = info.messages.get_mut(key) { @@ -990,10 +1034,10 @@ impl ClientWorker { }, Some(EventLocation::Reaction(event_id)) => { if let Some(reactions) = info.reactions.get_mut(event_id) { - reactions.remove(&ev.redacts); + reactions.remove(redacts); } - info.keys.remove(&ev.redacts); + info.keys.remove(redacts); }, } } @@ -1165,22 +1209,22 @@ impl ClientWorker { match style { LoginStyle::SessionRestore(session) => { - client.restore_login(session).await.map_err(IambError::from)?; + client.restore_session(session).await.map_err(IambError::from)?; }, LoginStyle::Password(password) => { let resp = client + .matrix_auth() .login_username(&self.settings.profile.user_id, &password) .initial_device_display_name(initial_devname().as_str()) .send() .await .map_err(IambError::from)?; - let file = File::create(self.settings.session_json.as_path())?; - let writer = BufWriter::new(file); - let session = Session::from(resp); - serde_json::to_writer(writer, &session).map_err(IambError::from)?; + let session = MatrixSession::from(&resp); + self.settings.write_session(session)?; }, LoginStyle::SingleSignOn => { let resp = client + .matrix_auth() .login_sso(|url| { let opened = format!( "The following URL should have been opened in your browser:\n {url}" @@ -1197,10 +1241,8 @@ impl ClientWorker { .await .map_err(IambError::from)?; - let file = File::create(self.settings.session_json.as_path())?; - let writer = BufWriter::new(file); - let session = Session::from(resp); - serde_json::to_writer(writer, &session).map_err(IambError::from)?; + let session = MatrixSession::from(&resp); + self.settings.write_session(session)?; }, } @@ -1213,7 +1255,7 @@ impl ClientWorker { }) .into(); - Ok(Some(InfoMessage::from("Successfully logged in!"))) + Ok(Some(InfoMessage::from("* Successfully logged in!"))) } async fn logout(&mut self, user_id: String) -> IambResult { @@ -1228,7 +1270,7 @@ impl ClientWorker { } // Send the logout request. - if let Err(e) = self.client.logout().await { + if let Err(e) = self.client.matrix_auth().logout().await { let msg = format!("Failed to logout: {e}"); let err = UIError::Failure(msg); @@ -1243,7 +1285,7 @@ impl ClientWorker { async fn direct_message(&mut self, user: OwnedUserId) -> IambResult { for room in self.client.rooms() { - if !room.is_direct() { + if !is_direct(&room).await { continue; } @@ -1267,7 +1309,7 @@ impl ClientWorker { }) } - async fn get_inviter(&mut self, invited: Invited) -> IambResult> { + async fn get_inviter(&mut self, invited: MatrixRoom) -> IambResult> { let details = invited.invite_details().await.map_err(IambError::from)?; Ok(details.inviter) @@ -1287,7 +1329,7 @@ impl ClientWorker { async fn join_room(&mut self, name: String) -> IambResult { if let Ok(alias_id) = OwnedRoomOrAliasId::from_str(name.as_str()) { match self.client.join_room_by_id_or_alias(&alias_id, &[]).await { - Ok(resp) => Ok(resp.room_id), + Ok(resp) => Ok(resp.room_id().to_owned()), Err(e) => { let msg = e.to_string(); let err = UIError::Failure(msg); @@ -1307,14 +1349,14 @@ impl ClientWorker { async fn members(&mut self, room_id: OwnedRoomId) -> IambResult> { if let Some(room) = self.client.get_room(room_id.as_ref()) { - Ok(room.active_members().await.map_err(IambError::from)?) + Ok(room.members(RoomMemberships::ACTIVE).await.map_err(IambError::from)?) } else { Err(IambError::UnknownRoom(room_id).into()) } } async fn space_members(&mut self, space: OwnedRoomId) -> IambResult> { - let mut req = SpaceHierarchyRequest::new(&space); + let mut req = SpaceHierarchyRequest::new(space); req.limit = Some(1000u32.into()); req.max_depth = Some(1u32.into()); @@ -1326,7 +1368,7 @@ impl ClientWorker { } async fn typing_notice(&mut self, room_id: OwnedRoomId) { - if let Some(room) = self.client.get_joined_room(room_id.as_ref()) { + if let Some(room) = self.client.get_room(room_id.as_ref()) { let _ = room.typing_notice(true).await; } }