feat: Complete API authentication system with email & Telegram support

- Add email/password registration endpoint (/api/v1/auth/register)
- Add JWT token endpoints for Telegram users (/api/v1/auth/token/get, /api/v1/auth/token/refresh-telegram)
- Enhance User model to support both email and Telegram authentication
- Fix JWT token handling: convert sub to string (RFC compliance with PyJWT 2.10.1+)
- Fix bot API calls: filter None values from query parameters
- Fix JWT extraction from Redis: handle both bytes and string returns
- Add public endpoints to JWT middleware: /api/v1/auth/register, /api/v1/auth/token/*
- Update bot commands: /register (one-tap), /link (account linking), /start (options)
- Create complete database schema migration with email auth support
- Remove deprecated version attribute from docker-compose.yml
- Add service dependency: bot waits for web service startup

Features:
- Dual authentication: email/password OR Telegram ID
- JWT tokens with 15-min access + 30-day refresh lifetime
- Redis-based token storage with TTL
- Comprehensive API documentation and integration guides
- Test scripts and Python examples
- Full deployment checklist

Database changes:
- User model: added email, password_hash, email_verified (nullable fields)
- telegram_id now nullable to support email-only users
- Complete schema with families, accounts, categories, transactions, budgets, goals

Status: Production-ready with all tests passing
This commit is contained in:
2025-12-11 21:00:34 +09:00
parent b642d1e9e9
commit 23a9d975a9
21 changed files with 4832 additions and 480 deletions

View File

@@ -17,7 +17,7 @@ class TokenType(str, Enum):
class TokenPayload(BaseModel):
"""JWT Token Payload Structure"""
sub: int # user_id
sub: str # user_id as string (RFC compliance)
type: TokenType
device_id: Optional[str] = None
scope: str = "default" # For granular permissions
@@ -114,7 +114,7 @@ class JWTManager:
expire = now + expires_delta
payload = {
"sub": user_id,
"sub": str(user_id), # RFC requires string, convert int to str
"type": token_type.value,
"device_id": device_id,
"family_ids": family_ids or [],

View File

@@ -166,6 +166,9 @@ class JWTAuthenticationMiddleware(BaseHTTPMiddleware):
"/docs",
"/openapi.json",
"/api/v1/auth/login",
"/api/v1/auth/register",
"/api/v1/auth/token/get",
"/api/v1/auth/token/refresh-telegram",
"/api/v1/auth/telegram/start",
"/api/v1/auth/telegram/register",
"/api/v1/auth/telegram/authenticate",