feat: Phase 1 - Complete authentication system with JWT
Backend Implementation (FastAPI + MongoDB): - JWT authentication with access/refresh tokens - User registration and login endpoints - Password hashing with bcrypt (fixed 72-byte limit) - Protected endpoints with JWT middleware - Token refresh mechanism - Role-Based Access Control (RBAC) structure - Pydantic v2 models and async MongoDB with Motor - API endpoints: /api/auth/register, /api/auth/login, /api/auth/me, /api/auth/refresh Frontend Implementation (React + TypeScript + Material-UI): - Login and Register pages with validation - AuthContext for global authentication state - API client with Axios interceptors for token refresh - Protected routes with automatic redirect - User profile display in navigation - Logout functionality Technical Achievements: - Resolved bcrypt 72-byte limit (replaced passlib with native bcrypt) - Fixed Pydantic v2 compatibility (PyObjectId, ConfigDict) - Implemented automatic token refresh on 401 errors - Created comprehensive test suite for all auth endpoints Docker & Kubernetes: - Backend image: yakenator/site11-console-backend:latest - Frontend image: yakenator/site11-console-frontend:latest - Deployed to site11-pipeline namespace - Nginx reverse proxy configuration Documentation: - CONSOLE_ARCHITECTURE.md - Complete system architecture - PHASE1_COMPLETION.md - Detailed completion report - PROGRESS.md - Updated with Phase 1 status All authentication endpoints tested and verified working. 🤖 Generated with Claude Code Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
0
services/console/backend/app/schemas/__init__.py
Normal file
0
services/console/backend/app/schemas/__init__.py
Normal file
89
services/console/backend/app/schemas/auth.py
Normal file
89
services/console/backend/app/schemas/auth.py
Normal file
@ -0,0 +1,89 @@
|
||||
from pydantic import BaseModel, EmailStr, Field, ConfigDict
|
||||
from typing import Optional
|
||||
|
||||
|
||||
class UserRegister(BaseModel):
|
||||
"""User registration schema"""
|
||||
email: EmailStr = Field(..., description="User email")
|
||||
username: str = Field(..., min_length=3, max_length=50, description="Username")
|
||||
password: str = Field(..., min_length=6, description="Password")
|
||||
full_name: Optional[str] = Field(None, description="Full name")
|
||||
|
||||
model_config = ConfigDict(
|
||||
json_schema_extra={
|
||||
"example": {
|
||||
"email": "user@example.com",
|
||||
"username": "johndoe",
|
||||
"password": "securepassword123",
|
||||
"full_name": "John Doe"
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
class UserLogin(BaseModel):
|
||||
"""User login schema"""
|
||||
username: str = Field(..., description="Username or email")
|
||||
password: str = Field(..., description="Password")
|
||||
|
||||
model_config = ConfigDict(
|
||||
json_schema_extra={
|
||||
"example": {
|
||||
"username": "johndoe",
|
||||
"password": "securepassword123"
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
class Token(BaseModel):
|
||||
"""Token response schema"""
|
||||
access_token: str = Field(..., description="JWT access token")
|
||||
refresh_token: Optional[str] = Field(None, description="JWT refresh token")
|
||||
token_type: str = Field(default="bearer", description="Token type")
|
||||
|
||||
model_config = ConfigDict(
|
||||
json_schema_extra={
|
||||
"example": {
|
||||
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
|
||||
"refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
|
||||
"token_type": "bearer"
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
class TokenRefresh(BaseModel):
|
||||
"""Token refresh schema"""
|
||||
refresh_token: str = Field(..., description="Refresh token")
|
||||
|
||||
|
||||
class UserResponse(BaseModel):
|
||||
"""User response schema (without password)"""
|
||||
id: str = Field(..., alias="_id", description="User ID")
|
||||
email: EmailStr
|
||||
username: str
|
||||
full_name: Optional[str] = None
|
||||
role: str
|
||||
permissions: list = []
|
||||
status: str
|
||||
is_active: bool
|
||||
created_at: str
|
||||
last_login_at: Optional[str] = None
|
||||
|
||||
model_config = ConfigDict(
|
||||
populate_by_name=True,
|
||||
json_schema_extra={
|
||||
"example": {
|
||||
"_id": "507f1f77bcf86cd799439011",
|
||||
"email": "user@example.com",
|
||||
"username": "johndoe",
|
||||
"full_name": "John Doe",
|
||||
"role": "viewer",
|
||||
"permissions": [],
|
||||
"status": "active",
|
||||
"is_active": True,
|
||||
"created_at": "2024-01-01T00:00:00Z"
|
||||
}
|
||||
}
|
||||
)
|
||||
Reference in New Issue
Block a user