From 9fe27d8465142ddba9a8a87d9f7e903614bfec6d Mon Sep 17 00:00:00 2001 From: ZelionD Date: Wed, 17 Apr 2024 08:26:46 +0300 Subject: [PATCH] add check-email --- gov-portal-db/src/server.rs | 27 ++++++++++++++++++++++++++ gov-portal-db/src/users_manager/mod.rs | 24 +++++++++++++++++++++++ 2 files changed, 51 insertions(+) diff --git a/gov-portal-db/src/server.rs b/gov-portal-db/src/server.rs index 50aa519..d9113aa 100644 --- a/gov-portal-db/src/server.rs +++ b/gov-portal-db/src/server.rs @@ -91,6 +91,14 @@ pub struct UpdateUserRequest { pub session: SessionToken, } +/// JSON-serialized request passed as POST-data to `/check-email` endpoint +#[derive(Debug, Deserialize)] +pub struct CheckEmailRequest { + email: serde_email::Email, + #[serde(flatten)] + pub session: SessionToken, +} + /// JSON-serialized request passed as POST-data to `/verify-email` endpoint to send email verification link to user's email #[derive(Debug, Deserialize)] pub struct VerifyEmailRequest { @@ -140,6 +148,7 @@ pub async fn start(config: AppConfig, users_manager: Arc) -> Resul .route("/token", post(token_route)) .route("/user", post(user_route)) .route("/update-user", post(update_user_route)) + .route("/check-email", post(check_email_route)) .route("/verify-email", post(verify_email_route)) .route("/quiz", post(quiz_route)) .route("/verify-quiz", post(verify_quiz_route)) @@ -302,6 +311,24 @@ async fn update_user_route( res.map(Json) } +/// Route handler to check if an email is already in database +async fn check_email_route( + State(state): State, + Json(req): Json, +) -> Result, String> { + tracing::debug!("[/check-email] Request {req:?}"); + + let res = match state.session_manager.verify_token(&req.session) { + Ok(_) => state.users_manager.is_email_being_used(&req.email).await, + Err(e) => Err(e), + } + .map_err(|e| format!("Check email request failure. Error: {e}")); + + tracing::debug!("[/check-email] Response {res:?}"); + + res.map(Json) +} + /// Route handler to generate email verification JWT token and send it to user's email address async fn verify_email_route( State(state): State, diff --git a/gov-portal-db/src/users_manager/mod.rs b/gov-portal-db/src/users_manager/mod.rs index 0252fe0..ed4bf1a 100644 --- a/gov-portal-db/src/users_manager/mod.rs +++ b/gov-portal-db/src/users_manager/mod.rs @@ -419,6 +419,30 @@ impl UsersManager { )), } } + + /// Checks if email already being used by some user + pub async fn is_email_being_used( + &self, + email: &serde_email::Email, + ) -> Result { + let filter = doc! { + "email": bson::to_bson(&email)?, + }; + + let find_options = FindOptions::builder() + .max_time(self.mongo_client.req_timeout) + .build(); + + Ok(tokio::time::timeout(self.mongo_client.req_timeout, async { + self.mongo_client + .find(filter, find_options) + .await? + .try_next() + .await + }) + .await?? + .is_some()) + } } /// Returns true if an input error kind [`MongoErrorKind`] is representing duplication error or false otherwise.