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

93
test_api.sh Normal file
View File

@@ -0,0 +1,93 @@
#!/bin/bash
# Test Bot API Endpoints
API_BASE_URL="http://localhost:8000"
CHAT_ID=556399210
echo "🧪 Finance Bot API Tests"
echo "========================"
echo ""
# Test 1: Register new email user
echo "1⃣ Register with Email"
echo "Request: POST /api/v1/auth/register"
curl -s -X POST "$API_BASE_URL/api/v1/auth/register" \
-H "Content-Type: application/json" \
-d '{
"email": "test.user@example.com",
"password": "TestPassword123",
"first_name": "Test",
"last_name": "User"
}' | jq '.' || echo "Failed"
echo ""
echo "---"
echo ""
# Test 2: Get token for Telegram user
echo "2⃣ Get Token for Telegram User"
echo "Request: POST /api/v1/auth/token/get"
TOKEN_RESPONSE=$(curl -s -X POST "$API_BASE_URL/api/v1/auth/token/get" \
-H "Content-Type: application/json" \
-d "{\"chat_id\": $CHAT_ID}")
echo "$TOKEN_RESPONSE" | jq '.' || echo "Failed"
# Extract token for next test
TOKEN=$(echo "$TOKEN_RESPONSE" | jq -r '.access_token // empty')
echo ""
echo "---"
echo ""
# Test 3: Quick Telegram registration
echo "3⃣ Quick Telegram Registration"
echo "Request: POST /api/v1/auth/telegram/register"
REG_RESPONSE=$(curl -s -X POST "$API_BASE_URL/api/v1/auth/telegram/register" \
-H "Content-Type: application/json" \
-d "" \
-G \
--data-urlencode "chat_id=$CHAT_ID" \
--data-urlencode "username=john_doe" \
--data-urlencode "first_name=John")
echo "$REG_RESPONSE" | jq '.' || echo "Failed"
# Extract JWT token if registration successful
JWT_TOKEN=$(echo "$REG_RESPONSE" | jq -r '.jwt_token // empty')
echo ""
echo "---"
echo ""
# Test 4: Health check
echo "4⃣ Health Check"
echo "Request: GET /health"
curl -s -X GET "$API_BASE_URL/health" | jq '.' || echo "Failed"
echo ""
echo "---"
echo ""
# Test 5: Make authenticated request (if we have a token)
if [ ! -z "$TOKEN" ]; then
echo "5⃣ Authenticated Request (with token)"
echo "Request: GET /api/v1/accounts"
echo "Authorization: Bearer $TOKEN"
curl -s -X GET "$API_BASE_URL/api/v1/accounts" \
-H "Authorization: Bearer $TOKEN" | jq '.' || echo "Failed"
echo ""
else
echo "5⃣ Authenticated Request - Skipped (no token)"
fi
echo ""
echo "---"
echo ""
echo "✅ Tests Complete"
echo ""
echo "📝 Notes:"
echo "- Replace http://localhost:8000 with your API URL"
echo "- You need jq installed: sudo apt install jq"
echo "- Check logs: docker logs finance_bot_web"
echo "- Check Redis: redis-cli get \"chat_id:$CHAT_ID:jwt\""