From c0f7e39c1493b1e67880fa9766f1362fb72963e2 Mon Sep 17 00:00:00 2001 From: boxdot Date: Sun, 10 Jul 2022 19:55:09 +0200 Subject: [PATCH] Improve name resolution (#167) Name resolution from profile (via signal service) was broken due to fetching of unversioned profile in libsignal-service. We patched the library. The patch is not yet upstreamed and used from the main branch due to the issue [62]. [62]: https://github.com/whisperfish/presage/issues/62 --- CHANGELOG.md | 9 ++++++- Cargo.lock | 6 ++--- Cargo.toml | 2 +- src/app.rs | 70 ++++++++++++++++++++++++++++------------------------ 4 files changed, 50 insertions(+), 37 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 29114af..f030059 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,11 +4,18 @@ ### Changed -- Fixed receiving direct messages sent from another device - Replace log4rs with tracing ([#158], [#160]) +- Display date only once per day ([#164]) + +### Fixed + +- Fixed receiving direct messages sent from another device ([#162]) +- Improve name resolution ([#167]) [#158]: https://github.com/boxdot/gurk-rs/pull/158 [#160]: https://github.com/boxdot/gurk-rs/pull/160 +[#162]: https://github.com/boxdot/gurk-rs/pull/162 +[#167]: https://github.com/boxdot/gurk-rs/pull/167 ## 0.2.4 diff --git a/Cargo.lock b/Cargo.lock index 5d686df..f759f9f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1396,7 +1396,7 @@ dependencies = [ [[package]] name = "libsignal-service" version = "0.1.0" -source = "git+https://github.com/whisperfish/libsignal-service-rs?rev=efd4ea86f57520d99141bb9c1c4b38a2ac646d6a#efd4ea86f57520d99141bb9c1c4b38a2ac646d6a" +source = "git+https://github.com/boxdot/libsignal-service-rs?rev=8be91da2#8be91da26eb6393fc222f476381da3ecdda8a5df" dependencies = [ "aes", "aes-gcm", @@ -1429,7 +1429,7 @@ dependencies = [ [[package]] name = "libsignal-service-hyper" version = "0.1.0" -source = "git+https://github.com/whisperfish/libsignal-service-rs?rev=efd4ea86f57520d99141bb9c1c4b38a2ac646d6a#efd4ea86f57520d99141bb9c1c4b38a2ac646d6a" +source = "git+https://github.com/boxdot/libsignal-service-rs?rev=8be91da2#8be91da26eb6393fc222f476381da3ecdda8a5df" dependencies = [ "async-trait", "async-tungstenite", @@ -2001,7 +2001,7 @@ checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857" [[package]] name = "presage" version = "0.2.0" -source = "git+https://github.com/whisperfish/presage.git?rev=8fcfb65#8fcfb6510c3a3ae4aeb9bafb535091d5b6ef1824" +source = "git+https://github.com/boxdot/presage.git?rev=f908e8f#f908e8ff89e0532831dcee82e22b6cc0a35bf9a6" dependencies = [ "async-trait", "base64 0.12.3", diff --git a/Cargo.toml b/Cargo.toml index df593e2..0e4d906 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,7 +22,7 @@ debug = 0 lto = "thin" [dependencies] -presage = { git = "https://github.com/whisperfish/presage.git", rev = "8fcfb65" } +presage = { git = "https://github.com/boxdot/presage.git", rev = "f908e8f" } anyhow = "1.0.40" async-trait = "0.1.51" diff --git a/src/app.rs b/src/app.rs index 7c32845..5b9b444 100644 --- a/src/app.rs +++ b/src/app.rs @@ -598,6 +598,15 @@ impl App { self.storage.save_app_data(&self.data) } + // Resolves name of a user by their id + // + // The resolution is done in the following way: + // + // 1. It's us => name from config + // 2. User id is in presage's signal manager (that is, it is a known contact from our address + // book) => use it, + // 3. User id is in the gurk's user name table (custom name) => use it, + // 4. give up with "Unknown User" pub fn name_by_id(&self, id: Uuid) -> String { if self.user_id == id { // it's me @@ -1366,7 +1375,7 @@ impl App { profile_keys, } = self.signal_manager.resolve_group(master_key).await?; - self.try_ensure_users_are_known( + self.ensure_users_are_known( group_data .members .iter() @@ -1387,7 +1396,7 @@ impl App { profile_keys, } = self.signal_manager.resolve_group(master_key).await?; - self.try_ensure_users_are_known( + self.ensure_users_are_known( group_data .members .iter() @@ -1409,8 +1418,18 @@ impl App { } async fn ensure_user_is_known(&mut self, uuid: Uuid, profile_key: ProfileKey) { - if !self.try_ensure_user_is_known(uuid, profile_key).await { - let name = self + // is_known <=> + // * in names, or + // * is not a phone numbers, or + // * is not their uuid + let is_known = self + .data + .names + .get(&uuid) + .filter(|name| !util::is_phone_number(name) && Uuid::from_str(name) != Ok(uuid)) + .is_some(); + if !is_known { + if let Some(name) = self .signal_manager .contact_by_id(uuid) .ok() @@ -1419,44 +1438,31 @@ impl App { c.address .phonenumber .and_then(|p| Some(p.format().mode(Mode::E164).to_string())) - }); - self.data - .names - .insert(uuid, name.unwrap_or_else(|| uuid.to_string())); - } - } - - /// Returns `true`, if user name was resolved successfully, otherwise `false` - async fn try_ensure_user_is_known(&mut self, uuid: Uuid, profile_key: ProfileKey) -> bool { - let is_phone_number_or_unknown = self - .data - .names - .get(&uuid) - .map(util::is_phone_number) - .unwrap_or(true); - if is_phone_number_or_unknown { - let name = match profile_key.try_into() { - Ok(key) => { - self.signal_manager - .resolve_name_from_profile(uuid, key) - .await - } - Err(_) => None, - }; - if let Some(name) = name { + }) + { + // resolved from contact list self.data.names.insert(uuid, name); + } else if let Some(name) = self + .signal_manager + .resolve_name_from_profile(uuid, profile_key) + .await + { + // resolved from signal service via their profile + self.data.names.insert(uuid, name); + } else { + // failed to resolve + self.data.names.insert(uuid, uuid.to_string()); } } - self.data.names.contains_key(&uuid) } - async fn try_ensure_users_are_known( + async fn ensure_users_are_known( &mut self, users_with_keys: impl Iterator, ) { // TODO: Run in parallel for (uuid, profile_key) in users_with_keys { - self.try_ensure_user_is_known(uuid, profile_key).await; + self.ensure_user_is_known(uuid, profile_key).await; } }