feat: Initial commit - Task Reporter incident response system
Complete implementation of the production line incident response system (生產線異常即時反應系統) including: Backend (FastAPI): - User authentication with AD integration and session management - Chat room management (create, list, update, members, roles) - Real-time messaging via WebSocket (typing indicators, reactions) - File storage with MinIO (upload, download, image preview) Frontend (React + Vite): - Authentication flow with token management - Room list with filtering, search, and pagination - Real-time chat interface with WebSocket - File upload with drag-and-drop and image preview - Member management and room settings - Breadcrumb navigation - 53 unit tests (Vitest) Specifications: - authentication: AD auth, sessions, JWT tokens - chat-room: rooms, members, templates - realtime-messaging: WebSocket, messages, reactions - file-storage: MinIO integration, file management - frontend-core: React SPA structure 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,134 @@
|
||||
# Implementation Tasks
|
||||
|
||||
## 1. Database Schema
|
||||
- [x] 1.1 Create `user_sessions` table with columns:
|
||||
- [x] id (PK)
|
||||
- [x] username (email from AD)
|
||||
- [x] display_name (for chat display)
|
||||
- [x] internal_token (our own session token, UUID, indexed for fast lookup)
|
||||
- [x] ad_token (token from AD API)
|
||||
- [x] encrypted_password (AES-256 encrypted password for auto-refresh)
|
||||
- [x] ad_token_expires_at (timestamp when AD token expires)
|
||||
- [x] refresh_attempt_count (counter for failed refresh attempts, default 0)
|
||||
- [x] last_activity (timestamp of last API request, indexed)
|
||||
- [x] created_at
|
||||
- [x] 1.2 Add database migration script
|
||||
- [x] 1.3 Create SQLAlchemy model for UserSession in `app/modules/auth/models.py`
|
||||
|
||||
## 2. Backend API Implementation (Modular Structure)
|
||||
- [x] 2.1 Create standalone `app/modules/auth/` directory structure:
|
||||
- [x] `__init__.py` (export public interfaces)
|
||||
- [x] `router.py` (FastAPI router with auth endpoints)
|
||||
- [x] `models.py` (SQLAlchemy UserSession model)
|
||||
- [x] `schemas.py` (Pydantic request/response models)
|
||||
- [x] `services/` subdirectory:
|
||||
- [x] `ad_client.py` (AD API communication)
|
||||
- [x] `session_service.py` (session CRUD operations)
|
||||
- [x] `encryption.py` (password encryption/decryption)
|
||||
- [x] `middleware.py` (AuthMiddleware for protected routes)
|
||||
- [x] `dependencies.py` (FastAPI dependency injection for current user)
|
||||
|
||||
- [x] 2.2 Implement `services/encryption.py` - EncryptionService
|
||||
- [x] 2.2.1 Use `cryptography.fernet` for symmetric encryption
|
||||
- [x] 2.2.2 Load encryption key from environment variable (FERNET_KEY)
|
||||
- [x] 2.2.3 Function: `encrypt_password(plaintext: str) -> str`
|
||||
- [x] 2.2.4 Function: `decrypt_password(ciphertext: str) -> str`
|
||||
|
||||
- [x] 2.3 Implement `services/ad_client.py` - ADAuthService
|
||||
- [x] 2.3.1 Function: `authenticate(username: str, password: str) -> dict` (calls AD API)
|
||||
- [x] 2.3.2 Parse AD response and extract token, username
|
||||
- [x] 2.3.3 Estimate token expiry (assume 1 hour if not provided)
|
||||
- [x] 2.3.4 Handle connection errors and return appropriate exceptions
|
||||
|
||||
- [x] 2.4 Implement `services/session_service.py` - SessionService
|
||||
- [x] 2.4.1 Function: `create_session(username, display_name, ad_token, encrypted_pwd, expires_at)`
|
||||
- [x] 2.4.2 Function: `get_session_by_token(internal_token: str) -> UserSession`
|
||||
- [x] 2.4.3 Function: `update_activity(session_id: int)`
|
||||
- [x] 2.4.4 Function: `refresh_ad_token(session: UserSession) -> bool` (returns success/failure)
|
||||
- [x] 2.4.5 Function: `delete_session(session_id: int)`
|
||||
- [x] 2.4.6 Function: `increment_refresh_attempts(session_id: int)`
|
||||
- [x] 2.4.7 Function: `reset_refresh_attempts(session_id: int)`
|
||||
|
||||
- [x] 2.5 Implement `router.py` - Auth endpoints
|
||||
- [x] 2.5.1 `POST /api/auth/login`
|
||||
- [x] Accept LoginRequest (username, password)
|
||||
- [x] Call ADAuthService.authenticate()
|
||||
- [x] Encrypt password using EncryptionService
|
||||
- [x] Generate internal_token (UUID4)
|
||||
- [x] Call SessionService.create_session()
|
||||
- [x] Return LoginResponse (token, display_name)
|
||||
- [x] 2.5.2 `POST /api/auth/logout`
|
||||
- [x] Accept Authorization header
|
||||
- [x] Call SessionService.delete_session()
|
||||
- [x] Return success message
|
||||
|
||||
- [x] 2.6 Implement `middleware.py` - AuthMiddleware
|
||||
- [x] 2.6.1 Extract internal_token from Authorization header
|
||||
- [x] 2.6.2 Query session using SessionService.get_session_by_token()
|
||||
- [x] 2.6.3 Check if last_activity > 3 days → delete session, return 401
|
||||
- [x] 2.6.4 Check if refresh_attempt_count >= 3 → delete session, return 401 with message
|
||||
- [x] 2.6.5 Check if ad_token_expires_at < 5 minutes → trigger auto-refresh
|
||||
- [x] 2.6.6 Update last_activity timestamp
|
||||
- [x] 2.6.7 Attach user info to request.state.user
|
||||
|
||||
- [x] 2.7 Implement auto-refresh logic in middleware
|
||||
- [x] 2.7.1 Decrypt stored password using EncryptionService
|
||||
- [x] 2.7.2 Call ADAuthService.authenticate() with decrypted password
|
||||
- [x] 2.7.3 If success: update ad_token, expires_at, reset refresh_attempt_count to 0
|
||||
- [x] 2.7.4 If failure: increment refresh_attempt_count
|
||||
- [x] 2.7.5 If refresh_attempt_count reaches 3: delete session, return 401 with "Password may have changed"
|
||||
- [x] 2.7.6 Log all refresh attempts for security audit
|
||||
|
||||
- [x] 2.8 Implement `dependencies.py` - FastAPI dependency
|
||||
- [x] 2.8.1 `get_current_user()` dependency that retrieves request.state.user
|
||||
- [x] 2.8.2 Export for use in other modules: `from app.modules.auth import get_current_user`
|
||||
|
||||
## 3. Testing
|
||||
- [x] 3.1 Write unit tests for EncryptionService
|
||||
- [x] 3.1.1 Test encrypt/decrypt roundtrip
|
||||
- [x] 3.1.2 Test that encrypted output differs from plaintext
|
||||
- [x] 3.2 Write unit tests for ADAuthService
|
||||
- [x] 3.2.1 Mock successful AD API response
|
||||
- [x] 3.2.2 Mock failed authentication (401)
|
||||
- [x] 3.2.3 Mock network error (503)
|
||||
- [x] 3.3 Write unit tests for SessionService
|
||||
- [x] 3.3.1 Test create_session and get_session_by_token
|
||||
- [x] 3.3.2 Test update_activity
|
||||
- [x] 3.3.3 Test increment/reset refresh_attempts
|
||||
- [x] 3.4 Write integration test for login flow
|
||||
- [x] 3.4.1 Mock AD API response
|
||||
- [x] 3.4.2 Verify session created in database
|
||||
- [x] 3.4.3 Verify password is encrypted in DB
|
||||
- [x] 3.4.4 Verify response contains internal_token
|
||||
- [x] 3.5 Write integration test for logout flow
|
||||
- [x] 3.5.1 Create session, then logout
|
||||
- [x] 3.5.2 Verify session deleted from database
|
||||
- [x] 3.6 Write test for auto-refresh logic
|
||||
- [x] 3.6.1 Mock time to simulate token near expiry
|
||||
- [x] 3.6.2 Mock successful AD re-authentication
|
||||
- [x] 3.6.3 Verify ad_token updated and refresh_attempt_count reset
|
||||
- [x] 3.7 Write test for refresh failure and retry limit
|
||||
- [x] 3.7.1 Mock 3 consecutive AD auth failures
|
||||
- [x] 3.7.2 Verify session deleted after 3rd attempt
|
||||
- [x] 3.7.3 Verify 401 response with appropriate message
|
||||
- [x] 3.8 Write test for 3-day inactivity timeout
|
||||
- [x] 3.8.1 Mock time to simulate 72+ hours since last_activity
|
||||
- [x] 3.8.2 Verify session rejected with 401
|
||||
- [x] 3.9 Test with actual credentials: ymirliu@panjit.com.tw / 4RFV5tgb6yhn
|
||||
- [x] 3.10 Verify encrypted password storage and retrieval from database
|
||||
|
||||
## 4. Documentation
|
||||
- [x] 4.1 Document API endpoints in OpenAPI/Swagger format
|
||||
- [x] POST /api/auth/login (LoginRequest → LoginResponse)
|
||||
- [x] POST /api/auth/logout (requires Authorization header)
|
||||
- [x] 4.2 Write module-level README in `app/modules/auth/README.md`
|
||||
- [x] Explain dual-token architecture
|
||||
- [x] Document auto-refresh behavior and 3-retry limit
|
||||
- [x] Document 3-day inactivity policy
|
||||
- [x] Provide usage example for other modules
|
||||
- [x] 4.3 Add inline code comments explaining:
|
||||
- [x] Password encryption/decryption flow
|
||||
- [x] Auto-refresh trigger logic (5-minute threshold)
|
||||
- [x] Retry counter and forced logout mechanism
|
||||
- [x] 4.4 Document environment variable requirements
|
||||
- [x] FERNET_KEY (encryption key for passwords)
|
||||
Reference in New Issue
Block a user