diff --git a/flutter/lib/common/hbbs/hbbs.dart b/flutter/lib/common/hbbs/hbbs.dart index d6baabdc0..2d559ec74 100644 --- a/flutter/lib/common/hbbs/hbbs.dart +++ b/flutter/lib/common/hbbs/hbbs.dart @@ -14,6 +14,8 @@ class HttpType { static const kAuthResTypeEmailCheck = "email_check"; } +// to-do: The UserPayload does not contain all the fields of the user. +// Is all the fields of the user needed? class UserPayload { String id = ''; String name = ''; @@ -29,6 +31,16 @@ class UserPayload { note = json['note'] ?? '', status = json['status'], isAdmin = json['is_admin'] == true; + + Map toJson() { + final Map map = { + 'name': name, + }; + if (status != null) { + map['status'] = status!; + } + return map; + } } class PeerPayload { diff --git a/flutter/lib/common/widgets/login.dart b/flutter/lib/common/widgets/login.dart index 99422cb9d..10960dc33 100644 --- a/flutter/lib/common/widgets/login.dart +++ b/flutter/lib/common/widgets/login.dart @@ -424,6 +424,8 @@ Future loginDialog() async { if (resp.access_token != null) { await bind.mainSetLocalOption( key: 'access_token', value: resp.access_token!); + await bind.mainSetLocalOption( + key: 'user_info', value: jsonEncode(resp.user ?? {})); close(true); return; } @@ -482,12 +484,8 @@ Future loginDialog() async { curOP: curOP, cbLogin: (Map authBody) { try { - final loginResp = - gFFI.userModel.getLoginResponseFromAuthBody(authBody); - if (loginResp.access_token != null) { - bind.mainSetLocalOption( - key: 'access_token', value: loginResp.access_token!); - } + // access_token is already stored in the rust side. + gFFI.userModel.getLoginResponseFromAuthBody(authBody); } catch (e) { debugPrint('Failed too parse oidc login body: "$authBody"'); } diff --git a/flutter/lib/models/user_model.dart b/flutter/lib/models/user_model.dart index 9f3f1571a..a6d2117c0 100644 --- a/flutter/lib/models/user_model.dart +++ b/flutter/lib/models/user_model.dart @@ -75,6 +75,7 @@ class UserModel { Future reset() async { await bind.mainSetLocalOption(key: 'access_token', value: ''); + await bind.mainSetLocalOption(key: 'user_info', value: ''); await gFFI.abModel.reset(); await gFFI.groupModel.reset(); userName.value = ''; diff --git a/src/hbbs_http/account.rs b/src/hbbs_http/account.rs index 95868e194..08b15ba90 100644 --- a/src/hbbs_http/account.rs +++ b/src/hbbs_http/account.rs @@ -4,6 +4,7 @@ use hbb_common::{ log, ResultType, }; use reqwest::blocking::Client; +use serde::ser::SerializeStruct; use serde_derive::{Deserialize, Serialize}; use serde_repr::{Deserialize_repr, Serialize_repr}; use std::{ @@ -90,7 +91,7 @@ pub enum UserRole { Member = 0, } -#[derive(Debug, Clone, Serialize, Deserialize)] +#[derive(Debug, Clone, Deserialize)] pub struct UserPayload { pub name: String, pub email: Option, @@ -99,6 +100,9 @@ pub struct UserPayload { pub info: UserInfo, pub role: UserRole, pub is_admin: bool, + // helper field for serialize + #[serde(default)] + pub ser_store_local: bool, } #[derive(Debug, Clone, Serialize, Deserialize)] @@ -127,6 +131,30 @@ pub struct AuthResult { pub auth_body: Option, } +impl serde::Serialize for UserPayload { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + if self.ser_store_local { + let mut state = serializer.serialize_struct("UserPayload", 1)?; + state.serialize_field("name", &self.name)?; + state.serialize_field("status", &self.status)?; + state.end() + } else { + let mut state = serializer.serialize_struct("UserPayload", 7)?; + state.serialize_field("name", &self.name)?; + state.serialize_field("email", &self.email)?; + state.serialize_field("note", &self.note)?; + state.serialize_field("status", &self.status)?; + state.serialize_field("info", &self.info)?; + state.serialize_field("role", &self.role)?; + state.serialize_field("is_admin", &self.is_admin)?; + state.end() + } + } +} + impl OidcSession { fn new() -> Self { Self { @@ -226,16 +254,18 @@ impl OidcSession { let query_timeout = OIDC_SESSION.read().unwrap().query_timeout; while OIDC_SESSION.read().unwrap().keep_querying && begin.elapsed() < query_timeout { match Self::query(&code_url.code, &id, &uuid) { - Ok(HbbHttpResponse::<_>::Data(auth_body)) => { + Ok(HbbHttpResponse::<_>::Data(mut auth_body)) => { if remember_me { LocalConfig::set_option( "access_token".to_owned(), auth_body.access_token.clone(), ); + auth_body.user.ser_store_local = true; LocalConfig::set_option( "user_info".to_owned(), serde_json::to_string(&auth_body.user).unwrap_or_default(), ); + auth_body.user.ser_store_local = false; } OIDC_SESSION .write() diff --git a/src/ui_interface.rs b/src/ui_interface.rs index e298e1167..834a2a581 100644 --- a/src/ui_interface.rs +++ b/src/ui_interface.rs @@ -822,7 +822,11 @@ pub fn account_auth_cancel() { #[cfg(feature = "flutter")] pub fn account_auth_result() -> String { - serde_json::to_string(&account::OidcSession::get_result()).unwrap_or_default() + let mut auth_result = account::OidcSession::get_result(); + if let Some(auth) = auth_result.auth_body.as_mut() { + auth.user.ser_store_local = false; + } + serde_json::to_string(&auth_result).unwrap_or_default() } #[cfg(feature = "flutter")]