diff --git a/src/web/api/v1/contexts/user/handlers.rs b/src/web/api/v1/contexts/user/handlers.rs index 9fccff14..da72c053 100644 --- a/src/web/api/v1/contexts/user/handlers.rs +++ b/src/web/api/v1/contexts/user/handlers.rs @@ -2,8 +2,9 @@ //! context. use std::sync::Arc; -use axum::extract::{self, Host, State}; +use axum::extract::{self, Host, Path, State}; use axum::Json; +use serde::Deserialize; use super::forms::RegistrationForm; use super::responses::{self, NewUser}; @@ -38,6 +39,18 @@ pub async fn registration_handler( } } +#[derive(Deserialize)] +pub struct TokenParam(String); + +/// It handles the verification of the email verification token. +#[allow(clippy::unused_async)] +pub async fn email_verification_handler(State(app_data): State>, Path(token): Path) -> String { + match app_data.registration_service.verify_email(&token.0).await { + Ok(_) => String::from("Email verified, you can close this page."), + Err(error) => error.to_string(), + } +} + /// It returns the base API URL without the port. For example: `http://localhost`. fn api_base_url(host: &str) -> String { // HTTPS is not supported yet. diff --git a/src/web/api/v1/contexts/user/routes.rs b/src/web/api/v1/contexts/user/routes.rs index a517f1d2..bc4723bc 100644 --- a/src/web/api/v1/contexts/user/routes.rs +++ b/src/web/api/v1/contexts/user/routes.rs @@ -3,13 +3,15 @@ //! Refer to the [API endpoint documentation](crate::web::api::v1::contexts::user). use std::sync::Arc; -use axum::routing::post; +use axum::routing::{get, post}; use axum::Router; -use super::handlers::registration_handler; +use super::handlers::{email_verification_handler, registration_handler}; use crate::common::AppData; /// Routes for the [`user`](crate::web::api::v1::contexts::user) API context. pub fn router(app_data: Arc) -> Router { - Router::new().route("/register", post(registration_handler).with_state(app_data)) + Router::new() + .route("/register", post(registration_handler).with_state(app_data.clone())) + .route("/email/verify/:token", get(email_verification_handler).with_state(app_data)) } diff --git a/src/web/api/v1/routes.rs b/src/web/api/v1/routes.rs index 1787e3bb..79185bf6 100644 --- a/src/web/api/v1/routes.rs +++ b/src/web/api/v1/routes.rs @@ -3,6 +3,7 @@ use std::sync::Arc; use axum::Router; +//use tower_http::cors::CorsLayer; use super::contexts::{about, user}; use crate::common::AppData; @@ -14,5 +15,11 @@ pub fn router(app_data: Arc) -> Router { let api_routes = Router::new().nest("/user", user_routes).nest("/about", about_routes); + // For development purposes only. + // It allows calling the API on a different port. For example + // API: http://localhost:3000/v1 + // Webapp: http://localhost:8080 + //Router::new().nest("/v1", api_routes).layer(CorsLayer::permissive()) + Router::new().nest("/v1", api_routes) } diff --git a/tests/e2e/contexts/user/contract.rs b/tests/e2e/contexts/user/contract.rs index c436d2c3..9fa767be 100644 --- a/tests/e2e/contexts/user/contract.rs +++ b/tests/e2e/contexts/user/contract.rs @@ -209,6 +209,7 @@ mod with_axum_implementation { env.start(api::Implementation::Axum).await; if env::var(ENV_VAR_E2E_EXCLUDE_AXUM_IMPL).is_ok() { + println!("Skipped"); return; }