2024-10-07 16:48:50 -04:00
|
|
|
use std::str::FromStr;
|
2024-10-05 10:45:41 -04:00
|
|
|
|
2024-08-06 11:08:15 -04:00
|
|
|
use axum::{
|
2024-10-03 15:27:30 -04:00
|
|
|
debug_handler,
|
2024-08-06 11:08:15 -04:00
|
|
|
extract::{Path, Query, State},
|
|
|
|
response::{IntoResponse, Response},
|
2024-10-03 15:27:30 -04:00
|
|
|
Json,
|
2024-08-06 11:08:15 -04:00
|
|
|
};
|
|
|
|
use http::StatusCode;
|
2024-10-03 15:27:30 -04:00
|
|
|
use pasetors::{claims::ClaimsValidationRules, keys::SymmetricKey, version4::V4};
|
2024-10-05 13:20:53 -04:00
|
|
|
use tracing::{debug, error};
|
2024-10-05 10:45:41 -04:00
|
|
|
use uuid::Uuid;
|
2024-08-06 11:08:15 -04:00
|
|
|
|
|
|
|
use crate::{
|
2024-10-07 16:48:50 -04:00
|
|
|
db::{verify_user, DbPool},
|
|
|
|
models::{ApiResponse, AppError},
|
|
|
|
requests::{
|
|
|
|
auth::generate_login_auth_and_session_tokens,
|
|
|
|
user::verify::UserVerifyGetResponseTokenAndExpiration, AppState,
|
2024-10-06 14:08:26 -04:00
|
|
|
},
|
2024-10-07 16:48:50 -04:00
|
|
|
services::{auth_token::verify_token, user_session, CachePool},
|
2024-08-06 11:08:15 -04:00
|
|
|
};
|
|
|
|
|
2024-10-03 15:27:30 -04:00
|
|
|
use super::{UserVerifyGetParams, UserVerifyGetResponse};
|
2024-08-06 11:08:15 -04:00
|
|
|
|
2024-10-03 15:27:30 -04:00
|
|
|
#[debug_handler]
|
|
|
|
pub async fn user_verification_get_handler(
|
|
|
|
State(state): State<AppState>,
|
|
|
|
Path(user_id): Path<i32>,
|
|
|
|
Query(query): Query<UserVerifyGetParams>,
|
2024-10-03 15:55:38 -04:00
|
|
|
) -> Result<Response, AppError> {
|
2024-10-05 10:45:41 -04:00
|
|
|
let db_pool = state.db_pool();
|
|
|
|
let cache_pool = state.cache_pool();
|
2024-10-03 15:27:30 -04:00
|
|
|
let env = state.env();
|
|
|
|
|
|
|
|
let UserVerifyGetParams { verification_token } = query;
|
|
|
|
let token_key = env.token_key();
|
2024-10-05 10:45:41 -04:00
|
|
|
verify_new_user_request(db_pool, cache_pool, user_id, verification_token, token_key).await
|
2024-08-06 11:08:15 -04:00
|
|
|
}
|
|
|
|
|
2024-10-03 15:27:30 -04:00
|
|
|
async fn verify_new_user_request(
|
2024-10-05 10:45:41 -04:00
|
|
|
db_pool: &DbPool,
|
|
|
|
cache_pool: &CachePool,
|
2024-10-03 15:27:30 -04:00
|
|
|
user_id: i32,
|
|
|
|
verification_token: String,
|
|
|
|
token_key: &SymmetricKey<V4>,
|
2024-10-03 15:55:38 -04:00
|
|
|
) -> Result<Response, AppError> {
|
2024-10-03 15:27:30 -04:00
|
|
|
debug!(user_id);
|
2024-08-06 11:08:15 -04:00
|
|
|
|
|
|
|
let validation_rules = {
|
|
|
|
let mut rules = ClaimsValidationRules::new();
|
|
|
|
rules.validate_audience_with(format!("/user/{user_id}/verify").as_str());
|
|
|
|
rules
|
|
|
|
};
|
|
|
|
|
2024-10-05 10:45:41 -04:00
|
|
|
let verified_token = verify_token(
|
|
|
|
token_key,
|
|
|
|
verification_token.as_str(),
|
|
|
|
Some(validation_rules.clone()),
|
|
|
|
)
|
|
|
|
.inspect_err(|err| error!(?err))?;
|
|
|
|
|
2024-10-06 14:08:26 -04:00
|
|
|
let verification_token_id = verified_token
|
2024-10-05 10:45:41 -04:00
|
|
|
.payload_claims()
|
|
|
|
.map(|claims| claims.get_claim("jti"))
|
|
|
|
.flatten()
|
|
|
|
.map(|jti| Uuid::from_str(jti.as_str().unwrap()).unwrap())
|
|
|
|
.unwrap();
|
|
|
|
|
2024-10-06 14:08:26 -04:00
|
|
|
user_session::exists(cache_pool, verification_token_id)
|
2024-10-05 13:20:53 -04:00
|
|
|
.await
|
|
|
|
.and_then(|exists| {
|
|
|
|
if exists {
|
2024-10-06 14:08:26 -04:00
|
|
|
Ok(user_session::get_user_session(
|
|
|
|
cache_pool,
|
|
|
|
verification_token_id,
|
|
|
|
))
|
2024-10-05 13:20:53 -04:00
|
|
|
} else {
|
|
|
|
Err(AppError::no_session_found())
|
|
|
|
}
|
2024-10-06 14:08:26 -04:00
|
|
|
})?
|
|
|
|
.await?;
|
|
|
|
|
2024-10-07 16:48:50 -04:00
|
|
|
verify_user(db_pool, user_id)
|
|
|
|
.await
|
|
|
|
.inspect_err(|err| error!(?err))?;
|
2024-10-06 14:08:26 -04:00
|
|
|
|
2024-10-07 16:48:50 -04:00
|
|
|
let ((session_token, session_token_expiration), (auth_token, auth_token_expiration)) =
|
|
|
|
generate_login_auth_and_session_tokens(cache_pool, token_key, user_id).await?;
|
2024-10-06 14:08:26 -04:00
|
|
|
|
2024-10-07 16:48:50 -04:00
|
|
|
let response = UserVerifyGetResponse {
|
2024-10-06 14:08:26 -04:00
|
|
|
user_id,
|
|
|
|
session: UserVerifyGetResponseTokenAndExpiration {
|
|
|
|
token: session_token,
|
|
|
|
expires_at: session_token_expiration,
|
|
|
|
},
|
|
|
|
auth: UserVerifyGetResponseTokenAndExpiration {
|
|
|
|
token: auth_token,
|
|
|
|
expires_at: auth_token_expiration,
|
|
|
|
},
|
2024-10-07 16:48:50 -04:00
|
|
|
};
|
2024-08-06 11:08:15 -04:00
|
|
|
|
|
|
|
Ok((
|
|
|
|
StatusCode::OK,
|
|
|
|
Json(ApiResponse::<UserVerifyGetResponse>::new(response)),
|
|
|
|
)
|
|
|
|
.into_response())
|
|
|
|
}
|