From fd04e6445ba178f5e72f1abd8962596380aea012 Mon Sep 17 00:00:00 2001 From: "Z. Charles Dziura" Date: Thu, 6 Mar 2025 16:31:10 -0500 Subject: [PATCH] Remove user_id from user creation and verification responses --- .../20231221181946_create-tables.up.sql | 3 + api/src/requests/user/create/handler.rs | 23 +++----- .../requests/user/create/models/response.rs | 2 - api/src/requests/user/mod.rs | 4 +- api/src/requests/user/verify/handler.rs | 55 +++++++++++-------- .../requests/user/verify/models/response.rs | 1 - api/src/services/auth_token.rs | 2 +- 7 files changed, 46 insertions(+), 44 deletions(-) diff --git a/api/migrations/20231221181946_create-tables.up.sql b/api/migrations/20231221181946_create-tables.up.sql index f3c7c04..9d6e0d6 100644 --- a/api/migrations/20231221181946_create-tables.up.sql +++ b/api/migrations/20231221181946_create-tables.up.sql @@ -79,6 +79,9 @@ CREATE TABLE IF NOT EXISTS updated_at TIMESTAMP WITH TIME ZONE NULL ); +CREATE INDEX IF NOT EXISTS user_account_permission_user_id_idx ON public.user_account_permission(user_id); +CREATE INDEX IF NOT EXISTS user_account_permission_account_id_idx ON public.user_account_permission(account_id); + CREATE TABLE IF NOT EXISTS public.budget ( id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, diff --git a/api/src/requests/user/create/handler.rs b/api/src/requests/user/create/handler.rs index ad9cdab..5f0fa39 100644 --- a/api/src/requests/user/create/handler.rs +++ b/api/src/requests/user/create/handler.rs @@ -1,19 +1,18 @@ use std::{sync::mpsc::Sender, time::SystemTime}; use crate::{ - db::{insert_new_user, DbPool, NewUserEntity, UserEntity}, + db::{DbPool, NewUserEntity, UserEntity, insert_new_user}, models::{ApiResponse, AppError, Session}, requests::AppState, services::{ - self, auth_token::generate_new_user_token, hash_password, CachePool, - UserConfirmationMessage, + self, CachePool, UserConfirmationMessage, auth_token::generate_new_user_token, + hash_password, }, }; use axum::{ - debug_handler, + Json, debug_handler, extract::State, response::{IntoResponse, Response}, - Json, }; use http::StatusCode; use pasetors::{keys::SymmetricKey, version4::V4}; @@ -38,6 +37,9 @@ pub async fn user_registration_post_handler( mail_sender, ) .await + .map(|(status_code, response)| { + (status_code, ApiResponse::new(response).into_json_response()).into_response() + }) } async fn register_new_user_request( @@ -47,7 +49,7 @@ async fn register_new_user_request( signing_key: &SymmetricKey, send_verification_email: bool, email_sender: &Sender, -) -> Result { +) -> Result<(StatusCode, UserRegistrationResponse), AppError> { debug!(?body, send_verification_email); let UserRegistrationRequest { @@ -111,22 +113,15 @@ async fn register_new_user_request( }); UserRegistrationResponse { - user_id, expires_at: None, session_token: None, } } else { UserRegistrationResponse { - user_id, expires_at: Some(expires_at), session_token: Some(verification_token), } }; - let response = ( - StatusCode::CREATED, - ApiResponse::new(response_body).into_json_response(), - ); - - Ok(response.into_response()) + Ok((StatusCode::CREATED, response_body)) } diff --git a/api/src/requests/user/create/models/response.rs b/api/src/requests/user/create/models/response.rs index 4849e22..8b462cc 100644 --- a/api/src/requests/user/create/models/response.rs +++ b/api/src/requests/user/create/models/response.rs @@ -8,8 +8,6 @@ use serde_with::{serde_as, skip_serializing_none}; #[derive(Debug, Serialize)] #[serde(rename_all = "camelCase")] pub struct UserRegistrationResponse { - pub user_id: i32, - #[serde(serialize_with = "humantime_serde::serialize")] pub expires_at: Option, diff --git a/api/src/requests/user/mod.rs b/api/src/requests/user/mod.rs index 4d33436..af53185 100644 --- a/api/src/requests/user/mod.rs +++ b/api/src/requests/user/mod.rs @@ -2,8 +2,8 @@ mod create; mod verify; use axum::{ - routing::{get, post}, Router, + routing::{get, post}, }; use create::user_registration_post_handler; @@ -17,7 +17,7 @@ pub fn requests(state: AppState) -> Router { "/user", Router::new() .route("/", post(user_registration_post_handler)) - .route("/{user_id}/verify", get(user_verification_get_handler)), + .route("/verify", get(user_verification_get_handler)), ) .with_state(state.clone()) } diff --git a/api/src/requests/user/verify/handler.rs b/api/src/requests/user/verify/handler.rs index c42847f..16d1f53 100644 --- a/api/src/requests/user/verify/handler.rs +++ b/api/src/requests/user/verify/handler.rs @@ -2,23 +2,22 @@ use std::str::FromStr; use axum::{ debug_handler, - extract::{Path, Query, State}, + extract::{Query, State}, response::{IntoResponse, Response}, - Json, }; use http::StatusCode; use pasetors::{claims::ClaimsValidationRules, keys::SymmetricKey, version4::V4}; -use tracing::{debug, error}; +use tracing::error; use uuid::Uuid; use crate::{ - db::{verify_user, DbPool}, + db::{DbPool, verify_user}, models::{ApiResponse, AppError}, requests::{ - auth::generate_login_auth_and_session_tokens, - user::verify::UserVerifyGetResponseTokenAndExpiration, AppState, + AppState, auth::generate_login_auth_and_session_tokens, + user::verify::UserVerifyGetResponseTokenAndExpiration, }, - services::{auth_token::verify_token, user_session, CachePool}, + services::{CachePool, auth_token::verify_token, user_session}, }; use super::{UserVerifyGetParams, UserVerifyGetResponse}; @@ -26,7 +25,6 @@ use super::{UserVerifyGetParams, UserVerifyGetResponse}; #[debug_handler] pub async fn user_verification_get_handler( State(state): State, - Path(user_id): Path, Query(query): Query, ) -> Result { let db_pool = state.db_pool(); @@ -34,21 +32,22 @@ pub async fn user_verification_get_handler( let token_key = state.config().secrets().token_key(); let UserVerifyGetParams { verification_token } = query; - verify_new_user_request(db_pool, cache_pool, user_id, verification_token, token_key).await + verify_new_user_request(db_pool, cache_pool, verification_token, token_key) + .await + .map(|(status_code, response)| { + (status_code, ApiResponse::new(response).into_json_response()).into_response() + }) } async fn verify_new_user_request( db_pool: &DbPool, cache_pool: &CachePool, - user_id: i32, verification_token: String, token_key: &SymmetricKey, -) -> Result { - debug!(user_id); - +) -> Result<(StatusCode, UserVerifyGetResponse), AppError> { let validation_rules = { let mut rules = ClaimsValidationRules::new(); - rules.validate_audience_with(format!("/user/{user_id}/verify").as_str()); + rules.validate_audience_with(format!("/user/verify").as_str()); rules }; @@ -59,11 +58,24 @@ async fn verify_new_user_request( ) .inspect_err(|err| error!(?err))?; - let verification_token_id = verified_token + let (user_id, verification_token_id) = verified_token .payload_claims() - .map(|claims| claims.get_claim("jti")) - .flatten() - .map(|jti| Uuid::from_str(jti.as_str().unwrap()).unwrap()) + .map(|claims| { + ( + claims + .get_claim("sub") + .map(|sub| sub.as_str()) + .flatten() + .map(|sub| sub.parse::().unwrap()) + .unwrap(), + claims + .get_claim("jti") + .map(|jti| jti.as_str()) + .flatten() + .unwrap(), + ) + }) + .map(|(user_id, jti)| (user_id, Uuid::from_str(jti).unwrap())) .unwrap(); user_session::exists(cache_pool, verification_token_id) @@ -88,7 +100,6 @@ async fn verify_new_user_request( generate_login_auth_and_session_tokens(cache_pool, token_key, user_id).await?; let response = UserVerifyGetResponse { - user_id, session: UserVerifyGetResponseTokenAndExpiration { token: session_token, expires_at: session_token_expiration, @@ -99,9 +110,5 @@ async fn verify_new_user_request( }, }; - Ok(( - StatusCode::OK, - Json(ApiResponse::::new(response)), - ) - .into_response()) + Ok((StatusCode::OK, response)) } diff --git a/api/src/requests/user/verify/models/response.rs b/api/src/requests/user/verify/models/response.rs index 68f9ba3..c246062 100644 --- a/api/src/requests/user/verify/models/response.rs +++ b/api/src/requests/user/verify/models/response.rs @@ -5,7 +5,6 @@ use serde::Serialize; #[derive(Debug, Serialize)] #[serde(rename_all = "camelCase")] pub struct UserVerifyGetResponse { - pub user_id: i32, pub session: UserVerifyGetResponseTokenAndExpiration, pub auth: UserVerifyGetResponseTokenAndExpiration, } diff --git a/api/src/services/auth_token.rs b/api/src/services/auth_token.rs index 4bb5e69..3797cde 100644 --- a/api/src/services/auth_token.rs +++ b/api/src/services/auth_token.rs @@ -96,7 +96,7 @@ pub fn generate_new_user_token(key: &SymmetricKey, user_id: i32) -> (String, key, user_id, FIFTEEN_MINUTES, - Some(format!("/user/{user_id}/verify").as_str()), + Some(format!("/user/verify").as_str()), ) }