diff --git a/flutter/lib/common/hbbs/hbbs.dart b/flutter/lib/common/hbbs/hbbs.dart index d6baabdc0..d1e44abc8 100644 --- a/flutter/lib/common/hbbs/hbbs.dart +++ b/flutter/lib/common/hbbs/hbbs.dart @@ -14,21 +14,39 @@ class HttpType { static const kAuthResTypeEmailCheck = "email_check"; } +enum UserStatus { kDisabled, kNormal, kUnverified } + +// 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 = ''; String email = ''; String note = ''; - int? status; + UserStatus status; bool isAdmin = false; UserPayload.fromJson(Map json) - : id = json['id'] ?? '', - name = json['name'] ?? '', + : name = json['name'] ?? '', email = json['email'] ?? '', note = json['note'] ?? '', - status = json['status'], + status = json['status'] == 0 + ? UserStatus.kDisabled + : json['status'] == -1 + ? UserStatus.kUnverified + : UserStatus.kNormal, isAdmin = json['is_admin'] == true; + + Map toJson() { + final Map map = { + 'name': name, + 'status': status == UserStatus.kDisabled + ? 0 + : status == UserStatus.kUnverified + ? -1 + : 1, + }; + 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..116c0ad02 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::{ @@ -59,8 +60,6 @@ pub struct UserInfo { #[serde(default)] pub settings: UserSettings, #[serde(default)] - pub login_ip_whitelist: Vec, - #[serde(default)] pub login_device_whitelist: Vec, #[serde(default)] pub other: HashMap, @@ -82,23 +81,18 @@ pub enum UserStatus { Unverified = -1, } -#[derive(Debug, Clone, Copy, PartialEq, Serialize_repr, Deserialize_repr)] -#[repr(i64)] -pub enum UserRole { - Owner = 10, - Admin = 1, - Member = 0, -} - -#[derive(Debug, Clone, Serialize, Deserialize)] +#[derive(Debug, Clone, Deserialize)] pub struct UserPayload { pub name: String, pub email: Option, pub note: Option, pub status: UserStatus, pub info: UserInfo, - pub role: UserRole, pub is_admin: bool, + pub third_auth_type: Option, + // helper field for serialize + #[serde(default)] + pub ser_store_local: bool, } #[derive(Debug, Clone, Serialize, Deserialize)] @@ -127,6 +121,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("is_admin", &self.is_admin)?; + state.serialize_field("third_auth_type", &self.third_auth_type)?; + state.end() + } + } +} + impl OidcSession { fn new() -> Self { Self { @@ -226,16 +244,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/index.tis b/src/ui/index.tis index adfa5a035..1227ccddb 100644 --- a/src/ui/index.tis +++ b/src/ui/index.tis @@ -1174,6 +1174,14 @@ function check_if_overlay() { checkConnectStatus(); +function set_local_user_info(user) { + var user_info = {name: user.name}; + if (user.status) { + user_info.status = user.status; + } + handler.set_local_option("user_info", JSON.stringify(user_info)); +} + function login() { var name0 = getUserName(); var pass0 = ''; @@ -1209,7 +1217,7 @@ function login() { return; } handler.set_local_option("access_token", data.access_token); - handler.set_local_option("user_info", JSON.stringify(data.user)); + set_local_user_info(data.user); show_progress(-1); myIdMenu.update(); getAb(); @@ -1248,7 +1256,7 @@ function on_email_check(last_msg) { return; } handler.set_local_option("access_token", data.access_token); - handler.set_local_option("user_info", JSON.stringify(data.user)); + set_local_user_info(data.user); show_progress(-1); myIdMenu.update(); getAb(); @@ -1298,7 +1306,7 @@ function refreshCurrentUser() { handleAbError(data.error); return; } - handler.set_local_option("user_info", JSON.stringify(data)); + set_local_user_info(data); myIdMenu.update(); getAb(); }, function(err, status) { 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")]