appflowy 3 лет назад
Родитель
Сommit
3fb74f51fe

+ 14 - 0
app_flowy/packages/flowy_sdk/lib/protobuf/flowy-user/auth.pb.dart

@@ -375,6 +375,7 @@ class SignUpResponse extends $pb.GeneratedMessage {
     ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'uid')
     ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'name')
     ..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'email')
+    ..aOS(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'token')
     ..hasRequiredFields = false
   ;
 
@@ -383,6 +384,7 @@ class SignUpResponse extends $pb.GeneratedMessage {
     $core.String? uid,
     $core.String? name,
     $core.String? email,
+    $core.String? token,
   }) {
     final _result = create();
     if (uid != null) {
@@ -394,6 +396,9 @@ class SignUpResponse extends $pb.GeneratedMessage {
     if (email != null) {
       _result.email = email;
     }
+    if (token != null) {
+      _result.token = token;
+    }
     return _result;
   }
   factory SignUpResponse.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
@@ -443,6 +448,15 @@ class SignUpResponse extends $pb.GeneratedMessage {
   $core.bool hasEmail() => $_has(2);
   @$pb.TagNumber(3)
   void clearEmail() => clearField(3);
+
+  @$pb.TagNumber(4)
+  $core.String get token => $_getSZ(3);
+  @$pb.TagNumber(4)
+  set token($core.String v) { $_setString(3, v); }
+  @$pb.TagNumber(4)
+  $core.bool hasToken() => $_has(3);
+  @$pb.TagNumber(4)
+  void clearToken() => clearField(4);
 }
 
 class SignOutParams extends $pb.GeneratedMessage {

+ 2 - 1
app_flowy/packages/flowy_sdk/lib/protobuf/flowy-user/auth.pbjson.dart

@@ -74,11 +74,12 @@ const SignUpResponse$json = const {
     const {'1': 'uid', '3': 1, '4': 1, '5': 9, '10': 'uid'},
     const {'1': 'name', '3': 2, '4': 1, '5': 9, '10': 'name'},
     const {'1': 'email', '3': 3, '4': 1, '5': 9, '10': 'email'},
+    const {'1': 'token', '3': 4, '4': 1, '5': 9, '10': 'token'},
   ],
 };
 
 /// Descriptor for `SignUpResponse`. Decode as a `google.protobuf.DescriptorProto`.
-final $typed_data.Uint8List signUpResponseDescriptor = $convert.base64Decode('Cg5TaWduVXBSZXNwb25zZRIQCgN1aWQYASABKAlSA3VpZBISCgRuYW1lGAIgASgJUgRuYW1lEhQKBWVtYWlsGAMgASgJUgVlbWFpbA==');
+final $typed_data.Uint8List signUpResponseDescriptor = $convert.base64Decode('Cg5TaWduVXBSZXNwb25zZRIQCgN1aWQYASABKAlSA3VpZBISCgRuYW1lGAIgASgJUgRuYW1lEhQKBWVtYWlsGAMgASgJUgVlbWFpbBIUCgV0b2tlbhgEIAEoCVIFdG9rZW4=');
 @$core.Deprecated('Use signOutParamsDescriptor instead')
 const SignOutParams$json = const {
   '1': 'SignOutParams',

+ 2 - 2
backend/src/entities/token.rs

@@ -45,8 +45,8 @@ impl Claim {
 #[derive(From, Into, Clone)]
 pub struct Token(String);
 impl Token {
-    pub fn create_token(data: &UserTable) -> Result<Self, ServerError> {
-        let claims = Claim::with_email(&data.email);
+    pub fn create_token(data: &str) -> Result<Self, ServerError> {
+        let claims = Claim::with_email(&data);
         encode(
             &Header::new(DEFAULT_ALGORITHM),
             &claims,

+ 6 - 2
backend/src/user_service/auth.rs

@@ -44,14 +44,15 @@ pub async fn sign_in(pool: &PgPool, params: SignInParams) -> Result<SignInRespon
 
     match verify_password(&password.0, &user.password) {
         Ok(true) => {
-            let token = Token::create_token(&user)?;
+            let token = Token::create_token(&user.email)?;
+            let _ = AUTHORIZED_USERS.store_auth(user.email.clone().into(), true)?;
+
             let mut response_data = SignInResponse::default();
             response_data.set_uid(user.id.to_string());
             response_data.set_name(user.name);
             response_data.set_email(user.email);
             response_data.set_token(token.clone().into());
 
-            let _ = AUTHORIZED_USERS.store_auth(LoggedUser::from_token(token.into())?, true)?;
             Ok(response_data)
         },
         _ => Err(ServerError::password_not_match()),
@@ -89,6 +90,7 @@ pub async fn register_user(
     .await
     .context("Failed to insert user")?;
 
+    let _ = AUTHORIZED_USERS.store_auth(email.as_ref().to_string().into(), true)?;
     let _ = create_default_workspace(&mut transaction, response_data.get_uid()).await?;
 
     transaction
@@ -164,6 +166,7 @@ async fn insert_new_user(
     email: &str,
     password: &str,
 ) -> Result<SignUpResponse, ServerError> {
+    let token = Token::create_token(email)?;
     let uuid = uuid::Uuid::new_v4();
     let password = hash_password(password)?;
     let _ = sqlx::query!(
@@ -185,6 +188,7 @@ async fn insert_new_user(
     response.set_uid(uuid.to_string());
     response.set_name(name.to_string());
     response.set_email(email.to_string());
+    response.set_token(token.into());
 
     Ok(response)
 }

+ 4 - 0
backend/src/user_service/logged_user.rs

@@ -23,6 +23,10 @@ impl std::convert::From<Claim> for LoggedUser {
     }
 }
 
+impl std::convert::From<String> for LoggedUser {
+    fn from(email: String) -> Self { Self { email } }
+}
+
 impl LoggedUser {
     pub fn from_token(token: String) -> Result<Self, ServerError> {
         let user: LoggedUser = Token::decode_token(&token.into())?.into();

+ 24 - 3
backend/tests/api/auth.rs

@@ -1,5 +1,11 @@
 use crate::helper::{spawn_app, TestApp};
-use flowy_user::entities::{SignInParams, SignOutParams, SignUpParams, SignUpResponse};
+use flowy_user::entities::{
+    QueryUserDetailParams,
+    SignInParams,
+    SignOutParams,
+    SignUpParams,
+    SignUpResponse,
+};
 
 #[actix_rt::test]
 async fn user_register() {
@@ -55,11 +61,26 @@ async fn user_sign_out() {
         })
         .await;
 
+    let token = sign_in_resp.token.clone();
     let sign_out_params = SignOutParams {
-        token: sign_in_resp.token,
+        token: token.clone(),
     };
-
     app.sign_out(sign_out_params).await;
+
+    let query_user_params = QueryUserDetailParams { token };
+    app.get_user_detail(query_user_params).await;
+}
+
+#[actix_rt::test]
+async fn user_get_detail() {
+    let app = spawn_app().await;
+    let email = "[email protected]";
+    let password = "HelloWork123!";
+    let sign_up_resp = register_user(&app, email, password).await;
+    let query_user_params = QueryUserDetailParams {
+        token: sign_up_resp.token,
+    };
+    log::info!("{:?}", app.get_user_detail(query_user_params).await);
 }
 
 async fn register_user(app: &TestApp, email: &str, password: &str) -> SignUpResponse {

+ 6 - 0
backend/tests/api/helper.rs

@@ -32,6 +32,12 @@ impl TestApp {
         let _ = user_sign_out(params, &url).await.unwrap();
     }
 
+    pub async fn get_user_detail(&self, params: QueryUserDetailParams) -> UserDetail {
+        let url = format!("{}/api/auth", self.address);
+        let user_detail = get_user_detail(params, &url).await.unwrap();
+        user_detail
+    }
+
     pub async fn create_workspace(&self, params: CreateWorkspaceParams) -> Workspace {
         let url = format!("{}/api/workspace", self.address);
         let workspace = create_workspace_request(params, &url).await.unwrap();

+ 3 - 0
rust-lib/flowy-user/src/entities/auth.rs

@@ -100,6 +100,9 @@ pub struct SignUpResponse {
 
     #[pb(index = 3)]
     pub email: String,
+
+    #[pb(index = 4)]
+    pub token: String,
 }
 
 #[derive(Default, ProtoBuf)]

+ 107 - 62
rust-lib/flowy-user/src/protobuf/model/auth.rs

@@ -1202,6 +1202,7 @@ pub struct SignUpResponse {
     pub uid: ::std::string::String,
     pub name: ::std::string::String,
     pub email: ::std::string::String,
+    pub token: ::std::string::String,
     // special fields
     pub unknown_fields: ::protobuf::UnknownFields,
     pub cached_size: ::protobuf::CachedSize,
@@ -1295,6 +1296,32 @@ impl SignUpResponse {
     pub fn take_email(&mut self) -> ::std::string::String {
         ::std::mem::replace(&mut self.email, ::std::string::String::new())
     }
+
+    // string token = 4;
+
+
+    pub fn get_token(&self) -> &str {
+        &self.token
+    }
+    pub fn clear_token(&mut self) {
+        self.token.clear();
+    }
+
+    // Param is passed by value, moved
+    pub fn set_token(&mut self, v: ::std::string::String) {
+        self.token = v;
+    }
+
+    // Mutable pointer to the field.
+    // If field is not initialized, it is initialized with default value first.
+    pub fn mut_token(&mut self) -> &mut ::std::string::String {
+        &mut self.token
+    }
+
+    // Take field
+    pub fn take_token(&mut self) -> ::std::string::String {
+        ::std::mem::replace(&mut self.token, ::std::string::String::new())
+    }
 }
 
 impl ::protobuf::Message for SignUpResponse {
@@ -1315,6 +1342,9 @@ impl ::protobuf::Message for SignUpResponse {
                 3 => {
                     ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.email)?;
                 },
+                4 => {
+                    ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.token)?;
+                },
                 _ => {
                     ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?;
                 },
@@ -1336,6 +1366,9 @@ impl ::protobuf::Message for SignUpResponse {
         if !self.email.is_empty() {
             my_size += ::protobuf::rt::string_size(3, &self.email);
         }
+        if !self.token.is_empty() {
+            my_size += ::protobuf::rt::string_size(4, &self.token);
+        }
         my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields());
         self.cached_size.set(my_size);
         my_size
@@ -1351,6 +1384,9 @@ impl ::protobuf::Message for SignUpResponse {
         if !self.email.is_empty() {
             os.write_string(3, &self.email)?;
         }
+        if !self.token.is_empty() {
+            os.write_string(4, &self.token)?;
+        }
         os.write_unknown_fields(self.get_unknown_fields())?;
         ::std::result::Result::Ok(())
     }
@@ -1404,6 +1440,11 @@ impl ::protobuf::Message for SignUpResponse {
                 |m: &SignUpResponse| { &m.email },
                 |m: &mut SignUpResponse| { &mut m.email },
             ));
+            fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
+                "token",
+                |m: &SignUpResponse| { &m.token },
+                |m: &mut SignUpResponse| { &mut m.token },
+            ));
             ::protobuf::reflect::MessageDescriptor::new_pb_name::<SignUpResponse>(
                 "SignUpResponse",
                 fields,
@@ -1423,6 +1464,7 @@ impl ::protobuf::Clear for SignUpResponse {
         self.uid.clear();
         self.name.clear();
         self.email.clear();
+        self.token.clear();
         self.unknown_fields.clear();
     }
 }
@@ -1610,69 +1652,72 @@ static file_descriptor_proto_data: &'static [u8] = b"\
     \x01(\tR\x04name\x12\x1a\n\x08password\x18\x03\x20\x01(\tR\x08password\"\
     T\n\x0cSignUpParams\x12\x14\n\x05email\x18\x01\x20\x01(\tR\x05email\x12\
     \x12\n\x04name\x18\x02\x20\x01(\tR\x04name\x12\x1a\n\x08password\x18\x03\
-    \x20\x01(\tR\x08password\"L\n\x0eSignUpResponse\x12\x10\n\x03uid\x18\x01\
+    \x20\x01(\tR\x08password\"b\n\x0eSignUpResponse\x12\x10\n\x03uid\x18\x01\
     \x20\x01(\tR\x03uid\x12\x12\n\x04name\x18\x02\x20\x01(\tR\x04name\x12\
-    \x14\n\x05email\x18\x03\x20\x01(\tR\x05email\"%\n\rSignOutParams\x12\x14\
-    \n\x05token\x18\x01\x20\x01(\tR\x05tokenJ\x98\t\n\x06\x12\x04\0\0!\x01\n\
-    \x08\n\x01\x0c\x12\x03\0\0\x12\n\n\n\x02\x04\0\x12\x04\x02\0\x05\x01\n\n\
-    \n\x03\x04\0\x01\x12\x03\x02\x08\x15\n\x0b\n\x04\x04\0\x02\0\x12\x03\x03\
-    \x04\x15\n\x0c\n\x05\x04\0\x02\0\x05\x12\x03\x03\x04\n\n\x0c\n\x05\x04\0\
-    \x02\0\x01\x12\x03\x03\x0b\x10\n\x0c\n\x05\x04\0\x02\0\x03\x12\x03\x03\
-    \x13\x14\n\x0b\n\x04\x04\0\x02\x01\x12\x03\x04\x04\x18\n\x0c\n\x05\x04\0\
-    \x02\x01\x05\x12\x03\x04\x04\n\n\x0c\n\x05\x04\0\x02\x01\x01\x12\x03\x04\
-    \x0b\x13\n\x0c\n\x05\x04\0\x02\x01\x03\x12\x03\x04\x16\x17\n\n\n\x02\x04\
-    \x01\x12\x04\x06\0\t\x01\n\n\n\x03\x04\x01\x01\x12\x03\x06\x08\x14\n\x0b\
-    \n\x04\x04\x01\x02\0\x12\x03\x07\x04\x15\n\x0c\n\x05\x04\x01\x02\0\x05\
-    \x12\x03\x07\x04\n\n\x0c\n\x05\x04\x01\x02\0\x01\x12\x03\x07\x0b\x10\n\
-    \x0c\n\x05\x04\x01\x02\0\x03\x12\x03\x07\x13\x14\n\x0b\n\x04\x04\x01\x02\
-    \x01\x12\x03\x08\x04\x18\n\x0c\n\x05\x04\x01\x02\x01\x05\x12\x03\x08\x04\
-    \n\n\x0c\n\x05\x04\x01\x02\x01\x01\x12\x03\x08\x0b\x13\n\x0c\n\x05\x04\
-    \x01\x02\x01\x03\x12\x03\x08\x16\x17\n\n\n\x02\x04\x02\x12\x04\n\0\x0f\
-    \x01\n\n\n\x03\x04\x02\x01\x12\x03\n\x08\x16\n\x0b\n\x04\x04\x02\x02\0\
-    \x12\x03\x0b\x04\x13\n\x0c\n\x05\x04\x02\x02\0\x05\x12\x03\x0b\x04\n\n\
-    \x0c\n\x05\x04\x02\x02\0\x01\x12\x03\x0b\x0b\x0e\n\x0c\n\x05\x04\x02\x02\
-    \0\x03\x12\x03\x0b\x11\x12\n\x0b\n\x04\x04\x02\x02\x01\x12\x03\x0c\x04\
-    \x14\n\x0c\n\x05\x04\x02\x02\x01\x05\x12\x03\x0c\x04\n\n\x0c\n\x05\x04\
-    \x02\x02\x01\x01\x12\x03\x0c\x0b\x0f\n\x0c\n\x05\x04\x02\x02\x01\x03\x12\
-    \x03\x0c\x12\x13\n\x0b\n\x04\x04\x02\x02\x02\x12\x03\r\x04\x15\n\x0c\n\
-    \x05\x04\x02\x02\x02\x05\x12\x03\r\x04\n\n\x0c\n\x05\x04\x02\x02\x02\x01\
-    \x12\x03\r\x0b\x10\n\x0c\n\x05\x04\x02\x02\x02\x03\x12\x03\r\x13\x14\n\
-    \x0b\n\x04\x04\x02\x02\x03\x12\x03\x0e\x04\x15\n\x0c\n\x05\x04\x02\x02\
-    \x03\x05\x12\x03\x0e\x04\n\n\x0c\n\x05\x04\x02\x02\x03\x01\x12\x03\x0e\
-    \x0b\x10\n\x0c\n\x05\x04\x02\x02\x03\x03\x12\x03\x0e\x13\x14\n\n\n\x02\
-    \x04\x03\x12\x04\x10\0\x14\x01\n\n\n\x03\x04\x03\x01\x12\x03\x10\x08\x15\
-    \n\x0b\n\x04\x04\x03\x02\0\x12\x03\x11\x04\x15\n\x0c\n\x05\x04\x03\x02\0\
-    \x05\x12\x03\x11\x04\n\n\x0c\n\x05\x04\x03\x02\0\x01\x12\x03\x11\x0b\x10\
-    \n\x0c\n\x05\x04\x03\x02\0\x03\x12\x03\x11\x13\x14\n\x0b\n\x04\x04\x03\
-    \x02\x01\x12\x03\x12\x04\x14\n\x0c\n\x05\x04\x03\x02\x01\x05\x12\x03\x12\
-    \x04\n\n\x0c\n\x05\x04\x03\x02\x01\x01\x12\x03\x12\x0b\x0f\n\x0c\n\x05\
-    \x04\x03\x02\x01\x03\x12\x03\x12\x12\x13\n\x0b\n\x04\x04\x03\x02\x02\x12\
-    \x03\x13\x04\x18\n\x0c\n\x05\x04\x03\x02\x02\x05\x12\x03\x13\x04\n\n\x0c\
-    \n\x05\x04\x03\x02\x02\x01\x12\x03\x13\x0b\x13\n\x0c\n\x05\x04\x03\x02\
-    \x02\x03\x12\x03\x13\x16\x17\n\n\n\x02\x04\x04\x12\x04\x15\0\x19\x01\n\n\
-    \n\x03\x04\x04\x01\x12\x03\x15\x08\x14\n\x0b\n\x04\x04\x04\x02\0\x12\x03\
-    \x16\x04\x15\n\x0c\n\x05\x04\x04\x02\0\x05\x12\x03\x16\x04\n\n\x0c\n\x05\
-    \x04\x04\x02\0\x01\x12\x03\x16\x0b\x10\n\x0c\n\x05\x04\x04\x02\0\x03\x12\
-    \x03\x16\x13\x14\n\x0b\n\x04\x04\x04\x02\x01\x12\x03\x17\x04\x14\n\x0c\n\
-    \x05\x04\x04\x02\x01\x05\x12\x03\x17\x04\n\n\x0c\n\x05\x04\x04\x02\x01\
-    \x01\x12\x03\x17\x0b\x0f\n\x0c\n\x05\x04\x04\x02\x01\x03\x12\x03\x17\x12\
-    \x13\n\x0b\n\x04\x04\x04\x02\x02\x12\x03\x18\x04\x18\n\x0c\n\x05\x04\x04\
-    \x02\x02\x05\x12\x03\x18\x04\n\n\x0c\n\x05\x04\x04\x02\x02\x01\x12\x03\
-    \x18\x0b\x13\n\x0c\n\x05\x04\x04\x02\x02\x03\x12\x03\x18\x16\x17\n\n\n\
-    \x02\x04\x05\x12\x04\x1a\0\x1e\x01\n\n\n\x03\x04\x05\x01\x12\x03\x1a\x08\
-    \x16\n\x0b\n\x04\x04\x05\x02\0\x12\x03\x1b\x04\x13\n\x0c\n\x05\x04\x05\
-    \x02\0\x05\x12\x03\x1b\x04\n\n\x0c\n\x05\x04\x05\x02\0\x01\x12\x03\x1b\
-    \x0b\x0e\n\x0c\n\x05\x04\x05\x02\0\x03\x12\x03\x1b\x11\x12\n\x0b\n\x04\
-    \x04\x05\x02\x01\x12\x03\x1c\x04\x14\n\x0c\n\x05\x04\x05\x02\x01\x05\x12\
-    \x03\x1c\x04\n\n\x0c\n\x05\x04\x05\x02\x01\x01\x12\x03\x1c\x0b\x0f\n\x0c\
-    \n\x05\x04\x05\x02\x01\x03\x12\x03\x1c\x12\x13\n\x0b\n\x04\x04\x05\x02\
-    \x02\x12\x03\x1d\x04\x15\n\x0c\n\x05\x04\x05\x02\x02\x05\x12\x03\x1d\x04\
-    \n\n\x0c\n\x05\x04\x05\x02\x02\x01\x12\x03\x1d\x0b\x10\n\x0c\n\x05\x04\
-    \x05\x02\x02\x03\x12\x03\x1d\x13\x14\n\n\n\x02\x04\x06\x12\x04\x1f\0!\
-    \x01\n\n\n\x03\x04\x06\x01\x12\x03\x1f\x08\x15\n\x0b\n\x04\x04\x06\x02\0\
-    \x12\x03\x20\x04\x15\n\x0c\n\x05\x04\x06\x02\0\x05\x12\x03\x20\x04\n\n\
-    \x0c\n\x05\x04\x06\x02\0\x01\x12\x03\x20\x0b\x10\n\x0c\n\x05\x04\x06\x02\
-    \0\x03\x12\x03\x20\x13\x14b\x06proto3\
+    \x14\n\x05email\x18\x03\x20\x01(\tR\x05email\x12\x14\n\x05token\x18\x04\
+    \x20\x01(\tR\x05token\"%\n\rSignOutParams\x12\x14\n\x05token\x18\x01\x20\
+    \x01(\tR\x05tokenJ\xcf\t\n\x06\x12\x04\0\0\"\x01\n\x08\n\x01\x0c\x12\x03\
+    \0\0\x12\n\n\n\x02\x04\0\x12\x04\x02\0\x05\x01\n\n\n\x03\x04\0\x01\x12\
+    \x03\x02\x08\x15\n\x0b\n\x04\x04\0\x02\0\x12\x03\x03\x04\x15\n\x0c\n\x05\
+    \x04\0\x02\0\x05\x12\x03\x03\x04\n\n\x0c\n\x05\x04\0\x02\0\x01\x12\x03\
+    \x03\x0b\x10\n\x0c\n\x05\x04\0\x02\0\x03\x12\x03\x03\x13\x14\n\x0b\n\x04\
+    \x04\0\x02\x01\x12\x03\x04\x04\x18\n\x0c\n\x05\x04\0\x02\x01\x05\x12\x03\
+    \x04\x04\n\n\x0c\n\x05\x04\0\x02\x01\x01\x12\x03\x04\x0b\x13\n\x0c\n\x05\
+    \x04\0\x02\x01\x03\x12\x03\x04\x16\x17\n\n\n\x02\x04\x01\x12\x04\x06\0\t\
+    \x01\n\n\n\x03\x04\x01\x01\x12\x03\x06\x08\x14\n\x0b\n\x04\x04\x01\x02\0\
+    \x12\x03\x07\x04\x15\n\x0c\n\x05\x04\x01\x02\0\x05\x12\x03\x07\x04\n\n\
+    \x0c\n\x05\x04\x01\x02\0\x01\x12\x03\x07\x0b\x10\n\x0c\n\x05\x04\x01\x02\
+    \0\x03\x12\x03\x07\x13\x14\n\x0b\n\x04\x04\x01\x02\x01\x12\x03\x08\x04\
+    \x18\n\x0c\n\x05\x04\x01\x02\x01\x05\x12\x03\x08\x04\n\n\x0c\n\x05\x04\
+    \x01\x02\x01\x01\x12\x03\x08\x0b\x13\n\x0c\n\x05\x04\x01\x02\x01\x03\x12\
+    \x03\x08\x16\x17\n\n\n\x02\x04\x02\x12\x04\n\0\x0f\x01\n\n\n\x03\x04\x02\
+    \x01\x12\x03\n\x08\x16\n\x0b\n\x04\x04\x02\x02\0\x12\x03\x0b\x04\x13\n\
+    \x0c\n\x05\x04\x02\x02\0\x05\x12\x03\x0b\x04\n\n\x0c\n\x05\x04\x02\x02\0\
+    \x01\x12\x03\x0b\x0b\x0e\n\x0c\n\x05\x04\x02\x02\0\x03\x12\x03\x0b\x11\
+    \x12\n\x0b\n\x04\x04\x02\x02\x01\x12\x03\x0c\x04\x14\n\x0c\n\x05\x04\x02\
+    \x02\x01\x05\x12\x03\x0c\x04\n\n\x0c\n\x05\x04\x02\x02\x01\x01\x12\x03\
+    \x0c\x0b\x0f\n\x0c\n\x05\x04\x02\x02\x01\x03\x12\x03\x0c\x12\x13\n\x0b\n\
+    \x04\x04\x02\x02\x02\x12\x03\r\x04\x15\n\x0c\n\x05\x04\x02\x02\x02\x05\
+    \x12\x03\r\x04\n\n\x0c\n\x05\x04\x02\x02\x02\x01\x12\x03\r\x0b\x10\n\x0c\
+    \n\x05\x04\x02\x02\x02\x03\x12\x03\r\x13\x14\n\x0b\n\x04\x04\x02\x02\x03\
+    \x12\x03\x0e\x04\x15\n\x0c\n\x05\x04\x02\x02\x03\x05\x12\x03\x0e\x04\n\n\
+    \x0c\n\x05\x04\x02\x02\x03\x01\x12\x03\x0e\x0b\x10\n\x0c\n\x05\x04\x02\
+    \x02\x03\x03\x12\x03\x0e\x13\x14\n\n\n\x02\x04\x03\x12\x04\x10\0\x14\x01\
+    \n\n\n\x03\x04\x03\x01\x12\x03\x10\x08\x15\n\x0b\n\x04\x04\x03\x02\0\x12\
+    \x03\x11\x04\x15\n\x0c\n\x05\x04\x03\x02\0\x05\x12\x03\x11\x04\n\n\x0c\n\
+    \x05\x04\x03\x02\0\x01\x12\x03\x11\x0b\x10\n\x0c\n\x05\x04\x03\x02\0\x03\
+    \x12\x03\x11\x13\x14\n\x0b\n\x04\x04\x03\x02\x01\x12\x03\x12\x04\x14\n\
+    \x0c\n\x05\x04\x03\x02\x01\x05\x12\x03\x12\x04\n\n\x0c\n\x05\x04\x03\x02\
+    \x01\x01\x12\x03\x12\x0b\x0f\n\x0c\n\x05\x04\x03\x02\x01\x03\x12\x03\x12\
+    \x12\x13\n\x0b\n\x04\x04\x03\x02\x02\x12\x03\x13\x04\x18\n\x0c\n\x05\x04\
+    \x03\x02\x02\x05\x12\x03\x13\x04\n\n\x0c\n\x05\x04\x03\x02\x02\x01\x12\
+    \x03\x13\x0b\x13\n\x0c\n\x05\x04\x03\x02\x02\x03\x12\x03\x13\x16\x17\n\n\
+    \n\x02\x04\x04\x12\x04\x15\0\x19\x01\n\n\n\x03\x04\x04\x01\x12\x03\x15\
+    \x08\x14\n\x0b\n\x04\x04\x04\x02\0\x12\x03\x16\x04\x15\n\x0c\n\x05\x04\
+    \x04\x02\0\x05\x12\x03\x16\x04\n\n\x0c\n\x05\x04\x04\x02\0\x01\x12\x03\
+    \x16\x0b\x10\n\x0c\n\x05\x04\x04\x02\0\x03\x12\x03\x16\x13\x14\n\x0b\n\
+    \x04\x04\x04\x02\x01\x12\x03\x17\x04\x14\n\x0c\n\x05\x04\x04\x02\x01\x05\
+    \x12\x03\x17\x04\n\n\x0c\n\x05\x04\x04\x02\x01\x01\x12\x03\x17\x0b\x0f\n\
+    \x0c\n\x05\x04\x04\x02\x01\x03\x12\x03\x17\x12\x13\n\x0b\n\x04\x04\x04\
+    \x02\x02\x12\x03\x18\x04\x18\n\x0c\n\x05\x04\x04\x02\x02\x05\x12\x03\x18\
+    \x04\n\n\x0c\n\x05\x04\x04\x02\x02\x01\x12\x03\x18\x0b\x13\n\x0c\n\x05\
+    \x04\x04\x02\x02\x03\x12\x03\x18\x16\x17\n\n\n\x02\x04\x05\x12\x04\x1a\0\
+    \x1f\x01\n\n\n\x03\x04\x05\x01\x12\x03\x1a\x08\x16\n\x0b\n\x04\x04\x05\
+    \x02\0\x12\x03\x1b\x04\x13\n\x0c\n\x05\x04\x05\x02\0\x05\x12\x03\x1b\x04\
+    \n\n\x0c\n\x05\x04\x05\x02\0\x01\x12\x03\x1b\x0b\x0e\n\x0c\n\x05\x04\x05\
+    \x02\0\x03\x12\x03\x1b\x11\x12\n\x0b\n\x04\x04\x05\x02\x01\x12\x03\x1c\
+    \x04\x14\n\x0c\n\x05\x04\x05\x02\x01\x05\x12\x03\x1c\x04\n\n\x0c\n\x05\
+    \x04\x05\x02\x01\x01\x12\x03\x1c\x0b\x0f\n\x0c\n\x05\x04\x05\x02\x01\x03\
+    \x12\x03\x1c\x12\x13\n\x0b\n\x04\x04\x05\x02\x02\x12\x03\x1d\x04\x15\n\
+    \x0c\n\x05\x04\x05\x02\x02\x05\x12\x03\x1d\x04\n\n\x0c\n\x05\x04\x05\x02\
+    \x02\x01\x12\x03\x1d\x0b\x10\n\x0c\n\x05\x04\x05\x02\x02\x03\x12\x03\x1d\
+    \x13\x14\n\x0b\n\x04\x04\x05\x02\x03\x12\x03\x1e\x04\x15\n\x0c\n\x05\x04\
+    \x05\x02\x03\x05\x12\x03\x1e\x04\n\n\x0c\n\x05\x04\x05\x02\x03\x01\x12\
+    \x03\x1e\x0b\x10\n\x0c\n\x05\x04\x05\x02\x03\x03\x12\x03\x1e\x13\x14\n\n\
+    \n\x02\x04\x06\x12\x04\x20\0\"\x01\n\n\n\x03\x04\x06\x01\x12\x03\x20\x08\
+    \x15\n\x0b\n\x04\x04\x06\x02\0\x12\x03!\x04\x15\n\x0c\n\x05\x04\x06\x02\
+    \0\x05\x12\x03!\x04\n\n\x0c\n\x05\x04\x06\x02\0\x01\x12\x03!\x0b\x10\n\
+    \x0c\n\x05\x04\x06\x02\0\x03\x12\x03!\x13\x14b\x06proto3\
 ";
 
 static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT;

+ 1 - 0
rust-lib/flowy-user/src/protobuf/proto/auth.proto

@@ -28,6 +28,7 @@ message SignUpResponse {
     string uid = 1;
     string name = 2;
     string email = 3;
+    string token = 4;
 }
 message SignOutParams {
     string token = 1;

+ 14 - 1
rust-lib/flowy-user/src/services/user/user_server/server_api.rs

@@ -3,7 +3,7 @@ use crate::{
     errors::{ErrorBuilder, ErrorCode, UserError},
 };
 
-use crate::entities::SignOutParams;
+use crate::entities::{QueryUserDetailParams, SignOutParams};
 use flowy_net::{config::*, future::ResultFuture, request::HttpRequestBuilder};
 
 pub trait UserServerAPI {
@@ -63,3 +63,16 @@ pub async fn user_sign_out(params: SignOutParams, url: &str) -> Result<(), UserE
         .await?;
     Ok(())
 }
+
+pub async fn get_user_detail(
+    params: QueryUserDetailParams,
+    url: &str,
+) -> Result<UserDetail, UserError> {
+    let user_detail = HttpRequestBuilder::get(&url.to_owned())
+        .protobuf(params)?
+        .send()
+        .await?
+        .response()
+        .await?;
+    Ok(user_detail)
+}

+ 1 - 0
rust-lib/flowy-user/src/services/user/user_server/server_api_mock.rs

@@ -23,6 +23,7 @@ impl UserServerAPI for UserServerMock {
                 uid,
                 name: params.name,
                 email: params.email,
+                token: "fake token".to_owned(),
             })
         })
     }