from fastapi import APIRouter, Depends, HTTPException, Request from fastapi.responses import HTMLResponse, RedirectResponse from sqlmodel import Session, select from app.auth import TWITCH_AUTH_URL, exchange_code, get_twitch_user, get_current_user from app.database import get_session from app.models import Settings, User from app.templates import templates router = APIRouter(prefix="/auth") @router.get("/login", response_class=HTMLResponse) async def login_page(request: Request, user=Depends(get_current_user)): if user: return RedirectResponse(url="/") return templates.TemplateResponse("login.html", {"request": request}) @router.get("/twitch") async def twitch_redirect(): return RedirectResponse(url=TWITCH_AUTH_URL) @router.get("/callback") async def twitch_callback(request: Request, code: str, session: Session = Depends(get_session)): try: tokens = await exchange_code(code) twitch_user = await get_twitch_user(tokens["access_token"]) except Exception: raise HTTPException(status_code=400, detail="OAuth failed") user = session.exec(select(User).where(User.twitch_id == twitch_user["id"])).first() is_first = user is None if not user: user = User( twitch_id=twitch_user["id"], twitch_login=twitch_user["login"], twitch_display_name=twitch_user["display_name"], broadcaster_id=twitch_user["id"], access_token=tokens["access_token"], refresh_token=tokens.get("refresh_token", ""), is_admin=True, ) else: user.access_token = tokens["access_token"] user.refresh_token = tokens.get("refresh_token", user.refresh_token) user.twitch_display_name = twitch_user["display_name"] session.add(user) if is_first: settings = session.exec(select(Settings)).first() if not settings: settings = Settings() settings.twitch_channel = twitch_user["login"] session.add(settings) session.commit() session.refresh(user) request.session["user_id"] = user.id if is_first: from app.main import start_eventsub import asyncio asyncio.create_task(start_eventsub()) return RedirectResponse(url="/", status_code=303) @router.get("/logout") async def logout(request: Request): request.session.clear() return RedirectResponse(url="/auth/login")