2023-05-17 09:49:39 +08:00
|
|
|
use std::sync::Arc;
|
|
|
|
|
|
|
|
use strum_macros::Display;
|
|
|
|
|
2023-04-04 08:41:16 +08:00
|
|
|
use flowy_derive::{Flowy_Event, ProtoBuf_Enum};
|
|
|
|
use flowy_error::FlowyResult;
|
2022-01-11 13:34:45 +08:00
|
|
|
use lib_dispatch::prelude::*;
|
2023-05-21 18:53:59 +08:00
|
|
|
use lib_infra::box_any::BoxAny;
|
2023-05-31 17:42:14 +08:00
|
|
|
use lib_infra::future::{to_fut, Fut, FutureResult};
|
2023-05-17 09:49:39 +08:00
|
|
|
|
2023-05-21 18:53:59 +08:00
|
|
|
use crate::entities::{SignInResponse, SignUpResponse, UpdateUserProfileParams, UserProfile};
|
2023-05-17 09:49:39 +08:00
|
|
|
use crate::event_handler::*;
|
2023-05-21 18:53:59 +08:00
|
|
|
use crate::services::AuthType;
|
2023-05-17 09:49:39 +08:00
|
|
|
use crate::{errors::FlowyError, services::UserSession};
|
2021-07-09 14:02:42 +08:00
|
|
|
|
2022-12-01 08:35:50 +08:00
|
|
|
pub fn init(user_session: Arc<UserSession>) -> AFPlugin {
|
2023-02-13 09:29:49 +08:00
|
|
|
AFPlugin::new()
|
|
|
|
.name("Flowy-User")
|
|
|
|
.state(user_session)
|
|
|
|
.event(UserEvent::SignIn, sign_in)
|
|
|
|
.event(UserEvent::SignUp, sign_up)
|
|
|
|
.event(UserEvent::InitUser, init_user_handler)
|
|
|
|
.event(UserEvent::GetUserProfile, get_user_profile_handler)
|
|
|
|
.event(UserEvent::SignOut, sign_out)
|
|
|
|
.event(UserEvent::UpdateUserProfile, update_user_profile_handler)
|
|
|
|
.event(UserEvent::CheckUser, check_user_handler)
|
|
|
|
.event(UserEvent::SetAppearanceSetting, set_appearance_setting)
|
|
|
|
.event(UserEvent::GetAppearanceSetting, get_appearance_setting)
|
|
|
|
.event(UserEvent::GetUserSetting, get_user_setting)
|
2023-05-21 18:53:59 +08:00
|
|
|
.event(UserEvent::ThirdPartyAuth, third_party_auth_handler)
|
2021-06-29 16:52:29 +08:00
|
|
|
}
|
2022-01-10 23:45:59 +08:00
|
|
|
|
2023-05-31 17:42:14 +08:00
|
|
|
pub(crate) struct DefaultUserStatusCallback;
|
|
|
|
impl UserStatusCallback for DefaultUserStatusCallback {
|
|
|
|
fn auth_type_did_changed(&self, _auth_type: AuthType) {}
|
|
|
|
|
|
|
|
fn did_sign_in(&self, _user_id: i64, _workspace_id: &str) -> Fut<FlowyResult<()>> {
|
|
|
|
to_fut(async { Ok(()) })
|
|
|
|
}
|
|
|
|
|
2023-07-05 20:57:09 +08:00
|
|
|
fn did_sign_up(&self, _is_new: bool, _user_profile: &UserProfile) -> Fut<FlowyResult<()>> {
|
2023-05-31 17:42:14 +08:00
|
|
|
to_fut(async { Ok(()) })
|
|
|
|
}
|
|
|
|
|
|
|
|
fn did_expired(&self, _token: &str, _user_id: i64) -> Fut<FlowyResult<()>> {
|
|
|
|
to_fut(async { Ok(()) })
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-01-31 19:30:48 +08:00
|
|
|
pub trait UserStatusCallback: Send + Sync + 'static {
|
2023-05-31 17:42:14 +08:00
|
|
|
fn auth_type_did_changed(&self, auth_type: AuthType);
|
2023-05-21 18:53:59 +08:00
|
|
|
fn did_sign_in(&self, user_id: i64, workspace_id: &str) -> Fut<FlowyResult<()>>;
|
2023-07-05 20:57:09 +08:00
|
|
|
fn did_sign_up(&self, is_new: bool, user_profile: &UserProfile) -> Fut<FlowyResult<()>>;
|
2023-04-04 08:41:16 +08:00
|
|
|
fn did_expired(&self, token: &str, user_id: i64) -> Fut<FlowyResult<()>>;
|
2023-01-31 19:30:48 +08:00
|
|
|
}
|
|
|
|
|
2023-05-21 18:53:59 +08:00
|
|
|
/// The user cloud service provider.
|
|
|
|
/// The provider can be supabase, firebase, aws, or any other cloud service.
|
|
|
|
pub trait UserCloudServiceProvider: Send + Sync + 'static {
|
2023-05-23 23:55:21 +08:00
|
|
|
fn set_auth_type(&self, auth_type: AuthType);
|
2023-05-31 17:42:14 +08:00
|
|
|
fn get_auth_service(&self) -> Result<Arc<dyn UserAuthService>, FlowyError>;
|
2023-05-21 18:53:59 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
impl<T> UserCloudServiceProvider for Arc<T>
|
|
|
|
where
|
|
|
|
T: UserCloudServiceProvider,
|
|
|
|
{
|
2023-05-23 23:55:21 +08:00
|
|
|
fn set_auth_type(&self, auth_type: AuthType) {
|
|
|
|
(**self).set_auth_type(auth_type)
|
|
|
|
}
|
|
|
|
|
2023-05-31 17:42:14 +08:00
|
|
|
fn get_auth_service(&self) -> Result<Arc<dyn UserAuthService>, FlowyError> {
|
|
|
|
(**self).get_auth_service()
|
2023-05-21 18:53:59 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-07-05 20:57:09 +08:00
|
|
|
#[derive(Clone, Debug)]
|
|
|
|
pub struct UserCredentials {
|
|
|
|
/// Currently, the token is only used when the [AuthType] is SelfHosted
|
|
|
|
pub token: Option<String>,
|
|
|
|
|
|
|
|
/// The user id
|
|
|
|
pub uid: Option<i64>,
|
|
|
|
|
|
|
|
/// The user id
|
|
|
|
pub uuid: Option<String>,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl UserCredentials {
|
|
|
|
pub fn from_uid(uid: i64) -> Self {
|
|
|
|
Self {
|
|
|
|
token: None,
|
|
|
|
uid: Some(uid),
|
|
|
|
uuid: None,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn from_uuid(uuid: String) -> Self {
|
|
|
|
Self {
|
|
|
|
token: None,
|
|
|
|
uid: None,
|
|
|
|
uuid: Some(uuid),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn new(token: Option<String>, uid: Option<i64>, uuid: Option<String>) -> Self {
|
|
|
|
Self { token, uid, uuid }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-05-21 18:53:59 +08:00
|
|
|
/// Provide the generic interface for the user cloud service
|
|
|
|
/// The user cloud service is responsible for the user authentication and user profile management
|
|
|
|
pub trait UserAuthService: Send + Sync {
|
|
|
|
/// Sign up a new account.
|
|
|
|
/// The type of the params is defined the this trait's implementation.
|
|
|
|
/// Use the `unbox_or_error` of the [BoxAny] to get the params.
|
|
|
|
fn sign_up(&self, params: BoxAny) -> FutureResult<SignUpResponse, FlowyError>;
|
|
|
|
|
|
|
|
/// Sign in an account
|
|
|
|
/// The type of the params is defined the this trait's implementation.
|
|
|
|
fn sign_in(&self, params: BoxAny) -> FutureResult<SignInResponse, FlowyError>;
|
|
|
|
|
|
|
|
/// Sign out an account
|
|
|
|
fn sign_out(&self, token: Option<String>) -> FutureResult<(), FlowyError>;
|
|
|
|
|
|
|
|
/// Using the user's token to update the user information
|
2023-02-13 09:29:49 +08:00
|
|
|
fn update_user(
|
|
|
|
&self,
|
2023-07-05 20:57:09 +08:00
|
|
|
credential: UserCredentials,
|
2023-02-13 09:29:49 +08:00
|
|
|
params: UpdateUserProfileParams,
|
|
|
|
) -> FutureResult<(), FlowyError>;
|
2023-05-21 18:53:59 +08:00
|
|
|
|
2023-07-05 20:57:09 +08:00
|
|
|
/// Get the user information using the user's token or uid
|
|
|
|
/// return None if the user is not found
|
2023-05-21 18:53:59 +08:00
|
|
|
fn get_user_profile(
|
|
|
|
&self,
|
2023-07-05 20:57:09 +08:00
|
|
|
credential: UserCredentials,
|
2023-05-21 18:53:59 +08:00
|
|
|
) -> FutureResult<Option<UserProfile>, FlowyError>;
|
2023-07-05 20:57:09 +08:00
|
|
|
|
|
|
|
fn check_user(&self, credential: UserCredentials) -> FutureResult<(), FlowyError>;
|
2022-01-10 23:45:59 +08:00
|
|
|
}
|
2022-01-28 10:56:55 +08:00
|
|
|
|
|
|
|
#[derive(Clone, Copy, PartialEq, Eq, Debug, Display, Hash, ProtoBuf_Enum, Flowy_Event)]
|
|
|
|
#[event_err = "FlowyError"]
|
|
|
|
pub enum UserEvent {
|
2023-05-21 18:53:59 +08:00
|
|
|
/// Only use when the [AuthType] is Local or SelfHosted
|
2023-02-13 09:29:49 +08:00
|
|
|
/// Logging into an account using a register email and password
|
|
|
|
#[event(input = "SignInPayloadPB", output = "UserProfilePB")]
|
|
|
|
SignIn = 0,
|
2022-01-28 10:56:55 +08:00
|
|
|
|
2023-05-21 18:53:59 +08:00
|
|
|
/// Only use when the [AuthType] is Local or SelfHosted
|
2023-02-13 09:29:49 +08:00
|
|
|
/// Creating a new account
|
|
|
|
#[event(input = "SignUpPayloadPB", output = "UserProfilePB")]
|
|
|
|
SignUp = 1,
|
2022-01-28 10:56:55 +08:00
|
|
|
|
2023-02-13 09:29:49 +08:00
|
|
|
/// Logging out fo an account
|
2023-05-21 18:53:59 +08:00
|
|
|
#[event(input = "SignOutPB")]
|
2023-02-13 09:29:49 +08:00
|
|
|
SignOut = 2,
|
2022-01-28 10:56:55 +08:00
|
|
|
|
2023-02-13 09:29:49 +08:00
|
|
|
/// Update the user information
|
|
|
|
#[event(input = "UpdateUserProfilePayloadPB")]
|
|
|
|
UpdateUserProfile = 3,
|
2022-01-28 10:56:55 +08:00
|
|
|
|
2023-02-13 09:29:49 +08:00
|
|
|
/// Get the user information
|
|
|
|
#[event(output = "UserProfilePB")]
|
|
|
|
GetUserProfile = 4,
|
2022-01-28 10:56:55 +08:00
|
|
|
|
2023-02-13 09:29:49 +08:00
|
|
|
/// Check the user current session is valid or not
|
|
|
|
#[event(output = "UserProfilePB")]
|
|
|
|
CheckUser = 5,
|
2023-02-13 08:21:25 +08:00
|
|
|
|
2023-02-13 09:29:49 +08:00
|
|
|
/// Initialize resources for the current user after launching the application
|
|
|
|
#[event()]
|
|
|
|
InitUser = 6,
|
2022-01-28 10:56:55 +08:00
|
|
|
|
2023-02-13 09:29:49 +08:00
|
|
|
/// Change the visual elements of the interface, such as theme, font and more
|
|
|
|
#[event(input = "AppearanceSettingsPB")]
|
|
|
|
SetAppearanceSetting = 7,
|
2022-01-28 10:56:55 +08:00
|
|
|
|
2023-02-13 09:29:49 +08:00
|
|
|
/// Get the appearance setting
|
|
|
|
#[event(output = "AppearanceSettingsPB")]
|
|
|
|
GetAppearanceSetting = 8,
|
2022-11-11 17:24:10 +08:00
|
|
|
|
2023-02-13 09:29:49 +08:00
|
|
|
/// Get the settings of the user, such as the user storage folder
|
|
|
|
#[event(output = "UserSettingPB")]
|
|
|
|
GetUserSetting = 9,
|
2023-05-21 18:53:59 +08:00
|
|
|
|
|
|
|
#[event(input = "ThirdPartyAuthPB", output = "UserProfilePB")]
|
|
|
|
ThirdPartyAuth = 10,
|
2022-01-28 10:56:55 +08:00
|
|
|
}
|