Implement complete full-stack authentication system
- Restructure project with separate frontend/backend architecture - Create dedicated backend with Axum, SQLite, JWT authentication - Implement real API endpoints for register/login/verify - Update frontend to use HTTP requests instead of mock auth - Add bcrypt password hashing and secure token generation - Separate Cargo.toml files for frontend and backend builds - Fix Trunk compilation by isolating WASM-incompatible dependencies - Create demo user in database for easy testing - Both servers running: frontend (8081), backend (3000) 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
85
backend/src/lib.rs
Normal file
85
backend/src/lib.rs
Normal file
@@ -0,0 +1,85 @@
|
||||
use axum::{
|
||||
extract::State,
|
||||
http::StatusCode,
|
||||
response::Json,
|
||||
routing::{get, post},
|
||||
Router,
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use sqlx::{sqlite::SqlitePool, Row};
|
||||
use tower_http::cors::{CorsLayer, Any};
|
||||
use uuid::Uuid;
|
||||
use std::sync::Arc;
|
||||
|
||||
mod auth;
|
||||
mod models;
|
||||
mod handlers;
|
||||
|
||||
use auth::AuthService;
|
||||
use models::{LoginRequest, RegisterRequest, AuthResponse, ApiError};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct AppState {
|
||||
pub auth_service: AuthService,
|
||||
}
|
||||
|
||||
pub async fn run_server() -> Result<(), Box<dyn std::error::Error>> {
|
||||
// Initialize logging
|
||||
println!("🚀 Starting Calendar Backend Server");
|
||||
|
||||
// Set up database
|
||||
let database_url = std::env::var("DATABASE_URL")
|
||||
.unwrap_or_else(|_| "sqlite:calendar.db?mode=rwc".to_string());
|
||||
|
||||
let db_pool = SqlitePool::connect(&database_url).await?;
|
||||
|
||||
// Run migrations - create database file if it doesn't exist
|
||||
// The migrate!() macro looks for migrations in the current directory
|
||||
// so we don't need to run explicit migrations here since we handle it in init_db()
|
||||
|
||||
// Create auth service
|
||||
let jwt_secret = std::env::var("JWT_SECRET")
|
||||
.unwrap_or_else(|_| "your-super-secret-jwt-key-change-in-production".to_string());
|
||||
|
||||
let auth_service = AuthService::new(db_pool, jwt_secret);
|
||||
|
||||
// Initialize database schema
|
||||
auth_service.init_db().await?;
|
||||
|
||||
let app_state = AppState { auth_service };
|
||||
|
||||
// Build our application with routes
|
||||
let app = Router::new()
|
||||
.route("/", get(root))
|
||||
.route("/api/health", get(health_check))
|
||||
.route("/api/auth/register", post(handlers::register))
|
||||
.route("/api/auth/login", post(handlers::login))
|
||||
.route("/api/auth/verify", get(handlers::verify_token))
|
||||
.layer(
|
||||
CorsLayer::new()
|
||||
.allow_origin(Any)
|
||||
.allow_methods(Any)
|
||||
.allow_headers(Any),
|
||||
)
|
||||
.with_state(Arc::new(app_state));
|
||||
|
||||
// Start server
|
||||
let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await?;
|
||||
println!("📡 Server listening on http://0.0.0.0:3000");
|
||||
|
||||
axum::serve(listener, app).await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn root() -> &'static str {
|
||||
"Calendar Backend API v0.1.0"
|
||||
}
|
||||
|
||||
async fn health_check() -> Json<serde_json::Value> {
|
||||
Json(serde_json::json!({
|
||||
"status": "healthy",
|
||||
"service": "calendar-backend",
|
||||
"version": "0.1.0"
|
||||
}))
|
||||
}
|
||||
Reference in New Issue
Block a user