From 36921af9b42c019b2e802e6d6f9ab66707fcbeef Mon Sep 17 00:00:00 2001 From: Sun Date: Thu, 23 Dec 2021 20:58:20 +0800 Subject: [PATCH] fix sync friend info --- lib/global.dart | 2 +- lib/l10n/localizations_en.dart | 2 +- lib/l10n/localizations_zh.dart | 2 +- src/account.rs | 9 +-- src/apps/chat/layer.rs | 110 ++++++++++++--------------------- src/apps/chat/models/friend.rs | 2 +- src/apps/chat/rpc.rs | 27 +++----- src/apps/wallet/rpc.rs | 1 + src/group.rs | 12 +++- 9 files changed, 70 insertions(+), 97 deletions(-) diff --git a/lib/global.dart b/lib/global.dart index 3ce693f..c26a935 100644 --- a/lib/global.dart +++ b/lib/global.dart @@ -1,5 +1,5 @@ class Global { - static String version = 'v0.2.0'; + static String version = 'v0.5.0'; static String gid = '0000000000000000000000000000000000000000000000000000000000000000'; static String httpRpc = '127.0.0.1:8000'; static String wsRpc = '127.0.0.1:8080'; diff --git a/lib/l10n/localizations_en.dart b/lib/l10n/localizations_en.dart index 1158160..abacfe8 100644 --- a/lib/l10n/localizations_en.dart +++ b/lib/l10n/localizations_en.dart @@ -301,7 +301,7 @@ class AppLocalizationsEn extends AppLocalizations { @override String get deviceQrcodeIntro => 'Tips: Scan to Login and sync, use it with care, and do not tell others'; @override - String get about2 => 'An open source encrypted peer-to-peer session system would allow data to be sent securely from one terminal to another without going through third-party services.'; + String get about2 => 'An open source encrypted peer-to-peer system for data security. Your place, your rules.'; @override String get donate => 'Donate'; @override diff --git a/lib/l10n/localizations_zh.dart b/lib/l10n/localizations_zh.dart index a793054..7e37331 100644 --- a/lib/l10n/localizations_zh.dart +++ b/lib/l10n/localizations_zh.dart @@ -301,7 +301,7 @@ class AppLocalizationsZh extends AppLocalizations { @override String get deviceQrcodeIntro => '扫码登陆与同步账户,小心使用,请勿告知他人'; @override - String get about2 => '一款开源的加密对等通信系统,允许信息安全地从发送端经由网络直接到达接收端而不用经过第三方服务。'; + String get about2 => '属于自己的安全数据环境,你的地盘,你做主。'; @override String get donate => '捐助'; @override diff --git a/src/account.rs b/src/account.rs index 1849933..786aaa8 100644 --- a/src/account.rs +++ b/src/account.rs @@ -275,11 +275,11 @@ impl Account { pub fn update_info(&self, db: &DStorage) -> Result { let sql = format!( - "UPDATE accounts SET name='{}', avatar='{}', wallet='{}', height={} WHERE id = {}", + "UPDATE accounts SET name='{}', avatar='{}', wallet='{}', pub_height={} WHERE id = {}", self.name, base64::encode(&self.avatar), self.wallet, - self.pub_height + 1, + self.pub_height, self.id, ); db.update(&sql) @@ -314,12 +314,13 @@ pub(crate) struct User { } impl User { - pub fn simple( + pub fn new( id: GroupId, addr: PeerId, name: String, avatar: Vec, wallet: String, + height: i64, ) -> Self { Self { id, @@ -327,7 +328,7 @@ impl User { name, avatar, wallet, - height: 0, + height, } } diff --git a/src/apps/chat/layer.rs b/src/apps/chat/layer.rs index a5166bc..8223383 100644 --- a/src/apps/chat/layer.rs +++ b/src/apps/chat/layer.rs @@ -17,6 +17,7 @@ use crate::layer::{Layer, Online}; use crate::migrate::consensus::{FRIEND_TABLE_PATH, MESSAGE_TABLE_PATH, REQUEST_TABLE_PATH}; use crate::rpc::{ notice_menu, session_connect, session_create, session_last, session_lost, session_suspend, + session_update_name, }; use crate::session::{connect_session, Session, SessionType}; use crate::storage::{account_db, chat_db, session_db, write_avatar_sync}; @@ -38,10 +39,12 @@ pub(crate) enum LayerEvent { Suspend(GroupId), /// actived. extend BaseLayerEvent. Actived(GroupId), - /// make friendship request. user is simple. - Request(User, String), - /// agree friendship request. user is simple. - Agree(User, Proof), + /// make friendship request. + /// params is name, remark, proof. + Request(String, String, Proof), + /// agree friendship request. + /// params is gid. + Agree(Proof), /// reject friendship request. Reject, /// receiver gid, sender gid, message. @@ -199,7 +202,6 @@ impl LayerEvent { bytes: Vec, ) -> Result { let event: LayerEvent = bincode::deserialize(&bytes)?; - let mut results = HandleResult::new(); match event { @@ -219,77 +221,44 @@ impl LayerEvent { let _ = layer.running_mut(&mgid)?.active(&fgid, false); results.rpcs.push(session_connect(mgid, &sid, &addr)); } - LayerEvent::Request(remote, remark) => { + LayerEvent::Request(name, remark, proof) => { + // 1. check verify. + proof.verify(&fgid, &addr, &layer.addr)?; + if load_friend(&layer.base, &mgid, &fgid).is_err() { // check if exist request. let db = chat_db(&layer.base, &mgid)?; - if let Ok(req) = Request::get_id(&db, &remote.id) { + if let Ok(req) = Request::get_id(&db, &fgid) { Request::delete(&db, &req.id)?; // delete the old request. results.rpcs.push(rpc::request_delete(mgid, req.id)); } - let mut request = Request::new( - remote.id, - addr, - remote.name.clone(), - remark.clone(), - false, - true, - ); + let mut request = Request::new(fgid, addr, name, remark, false, true); // save to db. request.insert(&db)?; drop(db); - // save the avatar. - write_avatar_sync(&layer.base, &mgid, &request.gid, remote.avatar.clone())?; - - layer.group.write().await.broadcast( - &mgid, - InnerEvent::SessionRequestCreate(false, remote, remark), - REQUEST_TABLE_PATH, - request.id, - &mut results, - )?; results.rpcs.push(rpc::request_create(mgid, &request)); results.rpcs.push(notice_menu(mgid, &SessionType::Chat)); return Ok(results); } else { - let group_lock = layer.group.read().await; - let me = group_lock.clone_user(&mgid)?; - let proof = group_lock.prove_addr(&mgid, &addr)?; - drop(group_lock); - let msg = agree_message(proof, me, addr)?; + let proof = layer.group.read().await.prove_addr(&mgid, &addr)?; + let msg = agree_message(proof, addr)?; results.layers.push((mgid, fgid, msg)); } } - LayerEvent::Agree(remote, proof) => { + LayerEvent::Agree(proof) => { // 0. check verify. proof.verify(&fgid, &addr, &layer.addr)?; // 1. check friendship. if load_friend(&layer.base, &mgid, &fgid).is_err() { - // agree request for friend. + // 2. agree request for friend. let db = chat_db(&layer.base, &mgid)?; - if let Ok(mut request) = Request::get_id(&db, &remote.id) { - layer.group.write().await.broadcast( - &mgid, - InnerEvent::SessionRequestHandle( - request.gid, - true, - remote.avatar.clone(), - ), - REQUEST_TABLE_PATH, - request.id, - &mut results, - )?; - request.is_over = true; - request.is_ok = true; - request.update(&db)?; - let request_id = request.id; - let friend = - Friend::from_remote(&db, remote.id, remote.name, addr, remote.wallet)?; - write_avatar_sync(&layer.base, &mgid, &remote.id, remote.avatar)?; - results - .rpcs - .push(rpc::request_agree(mgid, request_id, &friend)); + if let Ok(mut r) = Request::get_id(&db, &fgid) { + r.is_over = true; + r.is_ok = true; + r.update(&db)?; + let friend = Friend::from_remote(&db, fgid, r.name, addr, "".to_owned())?; + results.rpcs.push(rpc::request_agree(mgid, r.id, &friend)); // ADD NEW SESSION. let s_db = session_db(&layer.base, &mgid)?; @@ -361,17 +330,20 @@ impl LayerEvent { } } LayerEvent::InfoRes(remote) => { - let (_sid, fid) = layer.get_running_remote_id(&mgid, &fgid)?; + let (sid, fid) = layer.get_running_remote_id(&mgid, &fgid)?; let avatar = remote.avatar.clone(); let db = chat_db(&layer.base, &mgid)?; let mut f = Friend::get(&db, &fid)?; + let name = remote.name.clone(); f.name = remote.name; - f.addr = remote.addr; f.wallet = remote.wallet; f.height = remote.height; f.remote_update(&db)?; drop(db); write_avatar_sync(&layer.base, &mgid, &remote.id, remote.avatar)?; + results.rpcs.push(rpc::friend_info(mgid, &f)); + let _ = Session::update_name(&session_db(&layer.base, &mgid)?, &sid, &name); + results.rpcs.push(session_update_name(mgid, &sid, &name)); layer.group.write().await.broadcast( &mgid, @@ -380,7 +352,6 @@ impl LayerEvent { f.id, &mut results, )?; - results.rpcs.push(rpc::friend_info(mgid, &f)); } LayerEvent::Close => { let (_sid, fid) = layer.get_running_remote_id(&mgid, &fgid)?; @@ -440,24 +411,25 @@ fn update_friend(base: &PathBuf, mgid: &GroupId, fgid: &GroupId, addr: &PeerId) Ok(friend) } -pub(super) fn req_message(layer: &mut Layer, me: User, request: Request) -> SendType { +pub(super) fn req_message( + layer: &mut Layer, + gid: GroupId, + name: String, + proof: Proof, + request: Request, +) -> SendType { // update delivery. let uid = layer.delivery.len() as u64 + 1; - layer.delivery.insert(uid, (me.id, request.id)); - let req = LayerEvent::Request(me, request.remark); + layer.delivery.insert(uid, (gid, request.id)); + let req = LayerEvent::Request(name, request.remark, proof); let data = bincode::serialize(&req).unwrap_or(vec![]); SendType::Event(uid, request.addr, data) } -pub(super) fn reject_message( - layer: &mut Layer, - tid: i64, - addr: PeerId, - me_id: GroupId, -) -> SendType { +pub(super) fn reject_message(layer: &mut Layer, tid: i64, addr: PeerId, gid: GroupId) -> SendType { let data = bincode::serialize(&LayerEvent::Reject).unwrap_or(vec![]); let uid = layer.delivery.len() as u64 + 1; - layer.delivery.insert(uid, (me_id, tid)); + layer.delivery.insert(uid, (gid, tid)); SendType::Event(uid, addr, data) } @@ -479,8 +451,8 @@ pub(crate) fn chat_conn(proof: Proof, addr: Peer) -> SendType { SendType::Connect(0, addr, data) } -pub(super) fn agree_message(proof: Proof, me: User, addr: PeerId) -> Result { - let data = bincode::serialize(&LayerEvent::Agree(me, proof)).unwrap_or(vec![]); +pub(super) fn agree_message(proof: Proof, addr: PeerId) -> Result { + let data = bincode::serialize(&LayerEvent::Agree(proof)).unwrap_or(vec![]); Ok(SendType::Event(0, addr, data)) } diff --git a/src/apps/chat/models/friend.rs b/src/apps/chat/models/friend.rs index a87c227..c909c92 100644 --- a/src/apps/chat/models/friend.rs +++ b/src/apps/chat/models/friend.rs @@ -208,7 +208,7 @@ impl Friend { pub fn remote_update(&self, db: &DStorage) -> Result { let sql = format!( - "UPDATE friends SET addr='{}', name='{}', wallet='{}', height={}, is_closed = false, is_deleted = false WHERE id = {}", + "UPDATE friends SET addr='{}', name='{}', wallet='{}', height={}, is_closed = false WHERE id = {}", self.addr.to_hex(), self.name, self.wallet, diff --git a/src/apps/chat/rpc.rs b/src/apps/chat/rpc.rs index 3fc3199..f65ee9c 100644 --- a/src/apps/chat/rpc.rs +++ b/src/apps/chat/rpc.rs @@ -9,13 +9,12 @@ use tdn::types::{ use chat_types::MessageType; -use crate::account::User; use crate::event::InnerEvent; use crate::migrate::consensus::{FRIEND_TABLE_PATH, MESSAGE_TABLE_PATH, REQUEST_TABLE_PATH}; use crate::rpc::{session_create, sleep_waiting_close_stable, RpcState}; use crate::storage::{chat_db, delete_avatar, session_db}; -use super::layer::{update_session, LayerEvent}; +use super::layer::{agree_message, reject_message, req_message, update_session, LayerEvent}; use super::{Friend, Message, Request}; #[inline] @@ -267,7 +266,10 @@ pub(crate) fn new_rpc_handler(handler: &mut RpcHandler) { false, ); - let me = state.group.read().await.clone_user(&gid)?; + let group_lock = state.group.read().await; + let name = group_lock.username(&gid)?; + let proof = group_lock.prove_addr(&gid, &remote_addr)?; + drop(group_lock); let mut layer_lock = state.layer.write().await; let db = chat_db(layer_lock.base(), &gid)?; @@ -286,22 +288,10 @@ pub(crate) fn new_rpc_handler(handler: &mut RpcHandler) { let mut results = HandleResult::rpc(json!(request.to_rpc())); - state.group.write().await.broadcast( - &gid, - InnerEvent::SessionRequestCreate( - true, - User::simple(remote_gid, remote_addr, remote_name, vec![], "".to_owned()), - remark, - ), - REQUEST_TABLE_PATH, - request.id, - &mut results, - )?; - results.layers.push(( gid, remote_gid, - super::layer::req_message(&mut layer_lock, me, request), + req_message(&mut layer_lock, gid, name, proof, request), )); drop(layer_lock); @@ -316,7 +306,6 @@ pub(crate) fn new_rpc_handler(handler: &mut RpcHandler) { let id = params[0].as_i64().ok_or(RpcError::ParseError)?; let mut group_lock = state.group.write().await; - let me = group_lock.clone_user(&gid)?; let db = chat_db(group_lock.base(), &gid)?; let mut request = Request::get(&db, &id)?; let mut results = HandleResult::new(); @@ -343,7 +332,7 @@ pub(crate) fn new_rpc_handler(handler: &mut RpcHandler) { results.rpcs.push(session_create(gid, &session)); let proof = group_lock.prove_addr(&gid, &friend.addr)?; - let msg = super::layer::agree_message(proof, me, friend.addr)?; + let msg = agree_message(proof, friend.addr)?; results.layers.push((gid, friend.gid, msg)); Ok(results) @@ -362,7 +351,7 @@ pub(crate) fn new_rpc_handler(handler: &mut RpcHandler) { req.is_over = true; req.update(&db)?; drop(db); - let msg = super::layer::reject_message(&mut layer_lock, id, req.addr, gid); + let msg = reject_message(&mut layer_lock, id, req.addr, gid); drop(layer_lock); let mut results = HandleResult::layer(gid, req.gid, msg); diff --git a/src/apps/wallet/rpc.rs b/src/apps/wallet/rpc.rs index 662a776..ca5aece 100644 --- a/src/apps/wallet/rpc.rs +++ b/src/apps/wallet/rpc.rs @@ -596,6 +596,7 @@ pub(crate) fn new_rpc_handler(handler: &mut RpcHandler) { let mut group_lock = state.group.write().await; let account = group_lock.account_mut(&gid)?; account.wallet = address.chain.update_main(&address.address, &account.wallet); + account.pub_height = account.pub_height + 1; account.update_info(&a_db)?; drop(group_lock); Ok(HandleResult::new()) diff --git a/src/group.rs b/src/group.rs index f89fd5f..681b6df 100644 --- a/src/group.rs +++ b/src/group.rs @@ -428,18 +428,27 @@ impl Group { pub fn clone_user(&self, gid: &GroupId) -> Result { if let Some(u) = self.accounts.get(gid) { - Ok(User::simple( + Ok(User::new( u.gid, self.addr, u.name.clone(), u.avatar.clone(), u.wallet.clone(), + u.pub_height, )) } else { Err(anyhow!("user missing.")) } } + pub fn username(&self, gid: &GroupId) -> Result { + if let Some(u) = self.accounts.get(gid) { + Ok(u.name.clone()) + } else { + Err(anyhow!("user missing.")) + } + } + pub fn list_users(&self) -> &HashMap { &self.accounts } @@ -502,6 +511,7 @@ impl Group { if avatar.len() > 0 { account.avatar = avatar; } + account.pub_height = account.pub_height + 1; account.update_info(&account_db)?; account_db.close() }