Skip to content

Commit

Permalink
add check-email
Browse files Browse the repository at this point in the history
  • Loading branch information
Kirill-K-1 committed Apr 17, 2024
1 parent 49f4802 commit 9fe27d8
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 0 deletions.
27 changes: 27 additions & 0 deletions gov-portal-db/src/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -140,6 +148,7 @@ pub async fn start(config: AppConfig, users_manager: Arc<UsersManager>) -> 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))
Expand Down Expand Up @@ -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<AppState>,
Json(req): Json<CheckEmailRequest>,
) -> Result<Json<bool>, 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<AppState>,
Expand Down
24 changes: 24 additions & 0 deletions gov-portal-db/src/users_manager/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<bool, anyhow::Error> {
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.
Expand Down

0 comments on commit 9fe27d8

Please sign in to comment.