feat(backend): Implement enhanced profile management
Phase 2.4 - Enhanced Profile Management Features implemented: - Get user profile endpoint - Update user profile endpoint - Delete user account endpoint with password confirmation - Input validation on all profile fields - Security: Password required for account deletion - Security: All tokens revoked on deletion New API endpoints: - GET /api/users/me (protected) - PUT /api/users/me (protected) - DELETE /api/users/me (protected) Security features: - JWT token required for all operations - Password confirmation required for deletion - All tokens revoked on account deletion - User data removed from database - Input validation on all fields Files modified: - backend/src/handlers/users.rs - backend/src/main.rs Testing: - backend/test-profile-management.sh - backend/PROFILE-MANAGEMENT-IMPLEMENTED.md
This commit is contained in:
parent
b0729f846f
commit
c69d3be302
4 changed files with 445 additions and 33 deletions
|
|
@ -6,7 +6,7 @@ mod handlers;
|
|||
mod middleware;
|
||||
|
||||
use axum::{
|
||||
routing::{get, post},
|
||||
routing::{get, post, put, delete},
|
||||
Router,
|
||||
middleware as axum_middleware,
|
||||
};
|
||||
|
|
@ -19,11 +19,9 @@ use config::Config;
|
|||
|
||||
#[tokio::main]
|
||||
async fn main() -> anyhow::Result<()> {
|
||||
// DEBUG: Print to stderr so we can see it in logs
|
||||
eprintln!("NORMOGEN BACKEND STARTING...");
|
||||
eprintln!("Loading environment variables...");
|
||||
|
||||
// Try to load .env, but don't fail if it doesn't exist
|
||||
match dotenv::dotenv() {
|
||||
Ok(path) => eprintln!("Loaded .env from: {:?}", path),
|
||||
Err(e) => eprintln!("No .env file found (this is OK in Docker): {}", e),
|
||||
|
|
@ -76,7 +74,6 @@ async fn main() -> anyhow::Result<()> {
|
|||
|
||||
eprintln!("Building router...");
|
||||
|
||||
// Create separate routers for public and protected routes
|
||||
let public_routes = Router::new()
|
||||
.route("/health", get(handlers::health_check))
|
||||
.route("/ready", get(handlers::ready_check))
|
||||
|
|
@ -84,7 +81,6 @@ async fn main() -> anyhow::Result<()> {
|
|||
.route("/api/auth/login", post(handlers::login))
|
||||
.route("/api/auth/refresh", post(handlers::refresh_token))
|
||||
.route("/api/auth/logout", post(handlers::logout))
|
||||
// Password recovery (public - user doesn't have access yet)
|
||||
.route("/api/auth/recovery/verify", post(handlers::verify_recovery))
|
||||
.route("/api/auth/recovery/reset-password", post(handlers::reset_password))
|
||||
.layer(
|
||||
|
|
@ -94,9 +90,9 @@ async fn main() -> anyhow::Result<()> {
|
|||
);
|
||||
|
||||
let protected_routes = Router::new()
|
||||
// Profile management
|
||||
.route("/api/users/me", get(handlers::get_profile))
|
||||
// Password recovery (protected - user must be logged in)
|
||||
.route("/api/users/me", put(handlers::update_profile))
|
||||
.route("/api/users/me", delete(handlers::delete_account))
|
||||
.route("/api/auth/recovery/setup", post(handlers::setup_recovery))
|
||||
.layer(
|
||||
ServiceBuilder::new()
|
||||
|
|
@ -108,7 +104,6 @@ async fn main() -> anyhow::Result<()> {
|
|||
crate::middleware::auth::jwt_auth_middleware
|
||||
));
|
||||
|
||||
// Merge public and protected routes
|
||||
let app = public_routes.merge(protected_routes).with_state(app_state);
|
||||
|
||||
eprintln!("Binding to {}:{}...", config.server.host, config.server.port);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue