use iam_service::application::services::{AuthService, TenantService, UserService}; use iam_service::models::{CreateUserRequest, LoginRequest}; use sqlx::PgPool; use uuid::Uuid; #[tokio::test] async fn password_reset_self_and_admin_flow() -> Result<(), Box> { let database_url = match std::env::var("DATABASE_URL") { Ok(v) if !v.trim().is_empty() => v, _ => return Ok(()), }; let pool = PgPool::connect(&database_url).await?; let has_users: Option = sqlx::query_scalar("SELECT to_regclass('public.users')::text") .fetch_one(&pool) .await?; let has_refresh_tokens: Option = sqlx::query_scalar("SELECT to_regclass('public.refresh_tokens')::text") .fetch_one(&pool) .await?; if has_users.is_none() || has_refresh_tokens.is_none() { return Ok(()); } let tenant_service = TenantService::new(pool.clone()); let user_service = UserService::new(pool.clone()); let auth_service = AuthService::new(pool.clone(), "unused".to_string()); let tenant = tenant_service .create_tenant(iam_service::models::CreateTenantRequest { name: format!("pwreset-{}", Uuid::new_v4()), config: None, }) .await?; let admin = auth_service .register( tenant.id, CreateUserRequest { email: format!("admin-{}@example.com", Uuid::new_v4()), password: "AdminOldPassword123".to_string(), }, ) .await?; let user = auth_service .register( tenant.id, CreateUserRequest { email: format!("user-{}@example.com", Uuid::new_v4()), password: "UserOldPassword123".to_string(), }, ) .await?; let login1 = auth_service .login( tenant.id, LoginRequest { email: user.email.clone(), password: "UserOldPassword123".to_string(), }, ) .await?; let active_tokens: i64 = sqlx::query_scalar( "SELECT COUNT(1) FROM refresh_tokens WHERE user_id = $1 AND is_revoked = FALSE", ) .bind(user.id) .fetch_one(&pool) .await?; assert!(active_tokens >= 1); user_service .reset_my_password( tenant.id, user.id, "UserOldPassword123".to_string(), "UserNewPassword456".to_string(), ) .await?; let revoked_tokens: i64 = sqlx::query_scalar( "SELECT COUNT(1) FROM refresh_tokens WHERE user_id = $1 AND is_revoked = TRUE", ) .bind(user.id) .fetch_one(&pool) .await?; assert!(revoked_tokens >= 1); let old_login = auth_service .login( tenant.id, LoginRequest { email: user.email.clone(), password: "UserOldPassword123".to_string(), }, ) .await; assert!(old_login.is_err()); let _new_login = auth_service .login( tenant.id, LoginRequest { email: user.email.clone(), password: "UserNewPassword456".to_string(), }, ) .await?; let temp = user_service .reset_user_password_as_admin(tenant.id, admin.id, user.id, Some(24)) .await?; assert!(temp.len() >= 16 && temp.len() <= 64); let old2 = auth_service .login( tenant.id, LoginRequest { email: user.email.clone(), password: "UserNewPassword456".to_string(), }, ) .await; assert!(old2.is_err()); let _temp_login = auth_service .login( tenant.id, LoginRequest { email: user.email.clone(), password: temp.clone(), }, ) .await?; let _ = login1; Ok(()) }