- 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
7.6 KiB
7.6 KiB
Bot API Integration - Complete Summary
🎯 What Was Done
1. Updated User Model (app/db/models/user.py)
- Added
emailfield (unique, nullable) for email/password authentication - Added
password_hashfield for secure password storage - Made
telegram_idoptional (nullable) - Added
email_verifiedfield for email verification tracking - Updated
__repr__to show authentication method
2. New API Endpoints (app/api/auth.py)
Email Registration
POST /api/v1/auth/register
- Registers new user with email/password
- Returns JWT tokens immediately
- Bot can use for quick user creation
Get Token for Telegram User
POST /api/v1/auth/token/get
- Get fresh JWT token by chat_id
- Useful after successful Telegram binding
- Returns access_token + expires_in
Telegram Token Refresh
POST /api/v1/auth/token/refresh-telegram
- Refresh access token for Telegram user
- Query parameter:
chat_id - Returns new access_token
3. New Bot Commands (app/bot/client.py)
/start
- Shows registration options (instead of binding flow)
- Options: Quick Register or Link Account
- Stores user state in Redis
/register
- One-tap registration for Telegram users
- Calls
POST /api/v1/auth/telegram/register - Automatically gets JWT token
- Stores in Redis for 30 days
/link
- Link existing account to Telegram
- Generates binding code
- User confirms in web with email login
- Stores JWT after confirmation
/help
- Updated to show registration options
- Different help for registered vs unregistered users
4. Database Migration (migrations/versions/003_add_email_auth.py)
- Adds
email,password_hashcolumns - Makes
telegram_idnullable - Adds
email_verifiedcolumn - Creates indexes and constraints
5. Documentation
docs/API_INTEGRATION_GUIDE.md- Complete integration guide with code examplesdocs/API_ENDPOINTS.md- Full API reference with cURL examples
🔄 Authentication Flow
Option 1: Quick Telegram Registration
User /start
↓
User /register
↓
Bot → POST /api/v1/auth/telegram/register
↓
Bot ← JWT Token
↓
Store JWT in Redis
↓
User can use bot immediately
Option 2: Email Registration
User /start
↓
User clicks web link (frontend)
↓
User signs up with email
↓
Frontend → POST /api/v1/auth/register
↓
Frontend ← JWT Tokens
↓
User /link
↓
User confirms binding
↓
Bot → POST /api/v1/auth/telegram/confirm
↓
Bot gets JWT
↓
Store in Redis
Option 3: Link Existing Account
User /link
↓
Bot → POST /api/v1/auth/telegram/start
↓
Bot ← Binding Code
↓
Bot sends link with code
↓
User clicks link (web)
↓
User logs in with email
↓
Frontend → POST /api/v1/auth/telegram/confirm
↓
Bot queries JWT
↓
Store in Redis
🔐 Token Storage
In Redis (Bot)
Key: chat_id:{chat_id}:jwt
Value: JWT Token
TTL: 30 days
Example Usage in Bot
# Store token after registration
redis.setex(f"chat_id:{chat_id}:jwt", 86400*30, jwt_token)
# Get token before API call
token = redis.get(f"chat_id:{chat_id}:jwt")
# Use in request
headers = {"Authorization": f"Bearer {token}"}
📝 API Endpoints Quick Reference
| Method | Endpoint | Purpose | Auth |
|---|---|---|---|
| POST | /api/v1/auth/register |
Email registration | No |
| POST | /api/v1/auth/login |
Email login | No |
| POST | /api/v1/auth/refresh |
Refresh access token | No (refresh_token in body) |
| POST | /api/v1/auth/telegram/register |
Quick Telegram registration | No |
| POST | /api/v1/auth/telegram/start |
Start binding process | No |
| POST | /api/v1/auth/telegram/confirm |
Confirm binding | Yes |
| POST | /api/v1/auth/token/get |
Get token by chat_id | No |
| POST | /api/v1/auth/token/refresh-telegram |
Refresh Telegram token | No |
| POST | /api/v1/auth/logout |
Logout | Yes |
🚀 Bot Flow Examples
User Wants Quick Registration
/start
→ Choose /register
→ One tap
→ ✅ Account created, JWT stored
→ /balance works immediately
User Has Email Account
/start
→ Choose /link
→ Click link with binding code
→ Log in to web with email
→ Confirm binding
→ Bot gets JWT
→ ✅ Ready to use
User Already Registered
/start
→ ✅ Already connected!
→ Can use /balance, /add, etc.
🔧 Deployment Checklist
- Apply migration:
alembic upgrade head - Update docker-compose.yml (already fixed version warning)
- Set environment variables
- Test endpoints with cURL
- Update bot with new commands
- Test bot /register command
- Test bot /link command
- Verify tokens stored in Redis
- Test API calls with token
💡 Key Improvements
-
Flexible Authentication
- Email/password for web users
- Telegram-only for bot users
- Mixed for both platforms
-
Seamless Bot Experience
- No web redirects needed
/registerfor instant access/linkfor existing users
-
Secure Token Management
- JWT tokens with 15min expiry
- Refresh tokens for 30 days
- Redis caching for fast access
-
Better API Design
- Clear endpoint purposes
- Consistent response formats
- Proper error handling
-
Complete Documentation
- Integration guide with code
- API reference with examples
- Python/Node.js implementations
📚 Files Modified/Created
Modified
app/db/models/user.py- Added email/password fieldsapp/api/auth.py- Added new endpointsapp/bot/client.py- Added /register, /link commandsapp/main.py- Already had proper router includesdocker-compose.yml- Fixed version warning, added web dependency for bot
Created
migrations/versions/003_add_email_auth.py- Database migrationdocs/API_INTEGRATION_GUIDE.md- Complete integration guidedocs/API_ENDPOINTS.md- API reference
✅ Next Steps
-
Run migration
docker exec finance_bot_migrations alembic upgrade head -
Rebuild containers
docker compose up -d --build -
Test registration
curl -X POST http://localhost:8000/api/v1/auth/register \ -H "Content-Type: application/json" \ -d '{"email":"test@example.com","password":"test123","first_name":"Test"}' -
Test bot /register
- Send
/registerto bot - Should get JWT token
- Verify in Redis:
redis-cli get "chat_id:{id}:jwt"
- Send
-
Monitor logs
docker logs -f finance_bot_bot docker logs -f finance_bot_web
🐛 Troubleshooting
Migration fails
# Check migration status
docker exec finance_bot_migrations alembic current
# Rollback if needed
docker exec finance_bot_migrations alembic downgrade -1
# Reapply
docker exec finance_bot_migrations alembic upgrade head
Bot can't reach web
- Check network connectivity
- Verify API_BASE_URL is correct
- Check logs:
docker logs finance_bot_bot
Token not stored in Redis
- Check Redis connection
- Verify Redis is running:
docker ps | grep redis - Check Redis key:
redis-cli get "chat_id:556399210:jwt"
Endpoint returns 404
- Check auth router is included in main.py ✓
- Verify endpoint path matches
- Check logs for routing errors
📞 Support
For API issues:
- Check
docs/API_ENDPOINTS.mdfor endpoint details - Review bot logs:
docker logs finance_bot_bot - Check web logs:
docker logs finance_bot_web - Test endpoint with cURL first
For bot issues:
- Verify bot token is set in environment
- Check Redis connection
- Monitor logs during command execution
- Verify API base URL in bot config