feat: complete external auth V2 migration with advanced features

This commit implements comprehensive external Azure AD authentication
with complete task management, file download, and admin monitoring systems.

## Core Features Implemented (80% Complete)

### 1. Token Auto-Refresh Mechanism 
- Backend: POST /api/v2/auth/refresh endpoint
- Frontend: Auto-refresh 5 minutes before expiration
- Auto-retry on 401 errors with seamless token refresh

### 2. File Download System 
- Three format support: JSON / Markdown / PDF
- Endpoints: GET /api/v2/tasks/{id}/download/{format}
- File access control with ownership validation
- Frontend download buttons in TaskHistoryPage

### 3. Complete Task Management 
Backend Endpoints:
- POST /api/v2/tasks/{id}/start - Start task
- POST /api/v2/tasks/{id}/cancel - Cancel task
- POST /api/v2/tasks/{id}/retry - Retry failed task
- GET /api/v2/tasks - List with filters (status, filename, date range)
- GET /api/v2/tasks/stats - User statistics

Frontend Features:
- Status-based action buttons (Start/Cancel/Retry)
- Advanced search and filtering (status, filename, date range)
- Pagination and sorting
- Task statistics dashboard (5 stat cards)

### 4. Admin Monitoring System  (Backend)
Admin APIs:
- GET /api/v2/admin/stats - System statistics
- GET /api/v2/admin/users - User list with stats
- GET /api/v2/admin/users/top - User leaderboard
- GET /api/v2/admin/audit-logs - Audit log query system
- GET /api/v2/admin/audit-logs/user/{id}/summary

Admin Features:
- Email-based admin check (ymirliu@panjit.com.tw)
- Comprehensive system metrics (users, tasks, sessions, activity)
- Audit logging service for security tracking

### 5. User Isolation & Security 
- Row-level security on all task queries
- File access control with ownership validation
- Strict user_id filtering on all operations
- Session validation and expiry checking
- Admin privilege verification

## New Files Created

Backend:
- backend/app/models/user_v2.py - User model for external auth
- backend/app/models/task.py - Task model with user isolation
- backend/app/models/session.py - Session management
- backend/app/models/audit_log.py - Audit log model
- backend/app/services/external_auth_service.py - External API client
- backend/app/services/task_service.py - Task CRUD with isolation
- backend/app/services/file_access_service.py - File access control
- backend/app/services/admin_service.py - Admin operations
- backend/app/services/audit_service.py - Audit logging
- backend/app/routers/auth_v2.py - V2 auth endpoints
- backend/app/routers/tasks.py - Task management endpoints
- backend/app/routers/admin.py - Admin endpoints
- backend/alembic/versions/5e75a59fb763_*.py - DB migration

Frontend:
- frontend/src/services/apiV2.ts - Complete V2 API client
- frontend/src/types/apiV2.ts - V2 type definitions
- frontend/src/pages/TaskHistoryPage.tsx - Task history UI

Modified Files:
- backend/app/core/deps.py - Added get_current_admin_user_v2
- backend/app/main.py - Registered admin router
- frontend/src/pages/LoginPage.tsx - V2 login integration
- frontend/src/components/Layout.tsx - User display and logout
- frontend/src/App.tsx - Added /tasks route

## Documentation
- openspec/changes/.../PROGRESS_UPDATE.md - Detailed progress report

## Pending Items (20%)
1. Database migration execution for audit_logs table
2. Frontend admin dashboard page
3. Frontend audit log viewer

## Testing Status
- Manual testing:  Authentication flow verified
- Unit tests:  Pending
- Integration tests:  Pending

## Security Enhancements
-  User isolation (row-level security)
-  File access control
-  Token expiry validation
-  Admin privilege verification
-  Audit logging infrastructure
-  Token encryption (noted, low priority)
-  Rate limiting (noted, low priority)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
egg
2025-11-14 17:19:43 +08:00
parent 470fa96428
commit ad2b832fb6
32 changed files with 6450 additions and 26 deletions

View File

@@ -2,6 +2,7 @@ import { Outlet, NavLink } from 'react-router-dom'
import { useTranslation } from 'react-i18next'
import { useAuthStore } from '@/store/authStore'
import { apiClient } from '@/services/api'
import { apiClientV2 } from '@/services/apiV2'
import {
Upload,
Settings,
@@ -12,7 +13,8 @@ import {
LayoutDashboard,
ChevronRight,
Bell,
Search
Search,
History
} from 'lucide-react'
export default function Layout() {
@@ -20,15 +22,26 @@ export default function Layout() {
const logout = useAuthStore((state) => state.logout)
const user = useAuthStore((state) => state.user)
const handleLogout = () => {
apiClient.logout()
logout()
const handleLogout = async () => {
try {
// Use V2 API if authenticated with V2
if (apiClientV2.isAuthenticated()) {
await apiClientV2.logout()
} else {
apiClient.logout()
}
} catch (error) {
console.error('Logout error:', error)
} finally {
logout()
}
}
const navLinks = [
{ to: '/upload', label: t('nav.upload'), icon: Upload, description: '上傳檔案' },
{ to: '/processing', label: t('nav.processing'), icon: Activity, description: '處理進度' },
{ to: '/results', label: t('nav.results'), icon: FileText, description: '查看結果' },
{ to: '/tasks', label: '任務歷史', icon: History, description: '查看任務記錄' },
{ to: '/export', label: t('nav.export'), icon: Download, description: '導出文件' },
{ to: '/settings', label: t('nav.settings'), icon: Settings, description: '系統設定' },
]
@@ -86,8 +99,8 @@ export default function Layout() {
{user.username.charAt(0).toUpperCase()}
</div>
<div className="flex-1 min-w-0">
<div className="text-sm font-medium truncate">{user.username}</div>
<div className="text-xs text-sidebar-foreground/60"></div>
<div className="text-sm font-medium truncate">{user.displayName || user.username}</div>
<div className="text-xs text-sidebar-foreground/60 truncate">{user.email || user.username}</div>
</div>
</div>
)}