diff --git a/app/models/user.py b/app/models/user.py index e549079..e693537 100644 --- a/app/models/user.py +++ b/app/models/user.py @@ -22,12 +22,12 @@ class UserInDB(BaseModel): is_active: bool = True created_at: datetime = datetime.utcnow() code: Optional[str] = None - telegram_chat_id: Optional[int] = None telegram_user_id: Optional[int] = None telegram_username: Optional[str] = None is_verified: bool = False code_expires_at: Optional[datetime] = None is_admin: bool = False + expires_at: Optional[datetime] = None class Session(BaseModel): access_token: str client_token: str @@ -37,4 +37,5 @@ class Session(BaseModel): class VerifyCode(BaseModel): username: str code: str - telegram_chat_id: int + telegram_user_id: int + telegram_username: Optional[str] = None \ No newline at end of file diff --git a/app/services/auth.py b/app/services/auth.py index 42f2c9e..09fec0d 100644 --- a/app/services/auth.py +++ b/app/services/auth.py @@ -43,6 +43,7 @@ class AuthService: is_verified=False, code=None, code_expires_at=None, + expires_at=datetime.utcnow() + timedelta(hours=1), is_admin=False ) await users_collection.insert_one(new_user.dict()) @@ -62,7 +63,6 @@ class AuthService: self, username: str, code: str, - telegram_chat_id: int, telegram_user_id: int | None = None, telegram_username: str | None = None, ): @@ -73,15 +73,26 @@ class AuthService: if user["is_verified"]: raise HTTPException(400, "User already verified") - if user.get("telegram_chat_id") and user["telegram_chat_id"] != telegram_chat_id: + if user.get("telegram_user_id") and user["telegram_user_id"] != telegram_user_id: raise HTTPException(403, "This account is linked to another Telegram") if user.get("code") != code: raise HTTPException(400, "Invalid code") + if telegram_user_id is not None: + existing = await users_collection.find_one({ + "telegram_user_id": telegram_user_id, + "username": {"$ne": username}, + }) + if existing: + raise HTTPException( + status_code=403, + detail="This Telegram account is already linked to another user", + ) + update = { "is_verified": True, - "telegram_chat_id": telegram_chat_id, + "telegram_user_id": telegram_user_id, "code": None, } if telegram_user_id is not None: @@ -89,7 +100,10 @@ class AuthService: if telegram_username is not None: update["telegram_username"] = telegram_username - await users_collection.update_one({"username": username}, {"$set": update}) + await users_collection.update_one( + {"username": username}, + {"$set": update, "$unset": {"expires_at": ""}}, + ) return {"status": "success"} async def get_verification_status(self, username: str): diff --git a/main.py b/main.py index 9fc1b17..13e4ea1 100644 --- a/main.py +++ b/main.py @@ -8,6 +8,7 @@ from fastapi.middleware.cors import CORSMiddleware from app.core.config import CAPES_DIR, CAPES_STORE_DIR, SKINS_DIR from app.webhooks import telegram +from app.db.database import users_collection app = FastAPI() @@ -21,6 +22,10 @@ WEBHOOK_SECRET = os.getenv("TELEGRAM_WEBHOOK_SECRET", "") @asynccontextmanager async def lifespan(app: FastAPI): # ===== STARTUP ===== + + await users_collection.create_index("expires_at", expireAfterSeconds=0) + await users_collection.create_index("telegram_user_id", unique=True, sparse=True) + if BOT_TOKEN and PUBLIC_WEBHOOK_URL: payload = {"url": PUBLIC_WEBHOOK_URL} if WEBHOOK_SECRET: