#main.py from fastapi import FastAPI, Form, Depends, HTTPException from fastapi.requests import Request from fastapi.responses import HTMLResponse, RedirectResponse from fastapi.templating import Jinja2Templates from sqlalchemy.orm import Session from auth import verify_token, oauth2_scheme, auth_views, register, UserCreate, authenticate_user, get_user_by_verification_token from database import get_db, get_user_by_email from datetime import timedelta #import auth #import tts import os my_secret_key = os.environ['my_secret_key'] app = FastAPI() #router = APIRouter() templates = Jinja2Templates(directory="templates") # Include the authentication router with the prefix '/auth' #app.include_router(auth.router, prefix="") # Include the TTS router with the prefix '/tts' #app.include_router(tts.router, prefix="/tts") # Dependency for verifying the user's token def get_current_user(token: str = Depends(verify_token)): if not token: raise HTTPException(status_code=401, detail="Token not valid") return token # Route for the landing page @app.get("/", response_class=HTMLResponse) async def landing(request: Request): return templates.TemplateResponse("landing.html", {"request": request}) # Your other routes and app configuration go here @app.get("/login", response_class=HTMLResponse) async def login(request: Request): return templates.TemplateResponse("login.html", {"request": request}) @app.post("/login", response_class=HTMLResponse) async def login_post( request: Request, email: str = Form(...), password: str = Form(...), db: Session = Depends(get_db), # token: str = Depends(oauth2_scheme) # Check if the user has a valid token ): # if token: # If the user already has a valid token, redirect to protected.html # return templates.TemplateResponse("protected.html", {"request": request, "user": token}) # Validate the email and password if not email or not password: raise HTTPException(status_code=400, detail="Invalid email or password") # Check user authentication using the provided email and password user = authenticate_user(db, email, password) if user is not None: # Authentication succeeded # Create an access token and handle login success access_token = auth_views.create_access_token( data={"sub": user.email}, expires_delta=timedelta(minutes=auth_views.ACCESS_TOKEN_EXPIRE_MINUTES), ) # Set the access_token (if desired) user.token = access_token # Commit the changes to the database db.commit() # Handle the login success as needed return templates.TemplateResponse("protected.html", {"request": request, "user": user.username}) else: # Authentication failed # Handle login failure, e.g., display an error message return templates.TemplateResponse("login.html", {"request": request, "error_message": "Invalid email or password"}) @app.get("/register", response_class=HTMLResponse) async def register_get(request: Request): return templates.TemplateResponse("register.html", {"request": request}) @app.post("/register", response_class=HTMLResponse) async def register_post( request: Request, username: str = Form(...), email: str = Form(...), password: str = Form(...), confirm_password: str = Form(...), db: Session = Depends(get_db) ): if password != confirm_password: # Return to the registration page with an error return templates.TemplateResponse("register.html", { "request": request, "error_message": "Passwords do not match." }) try: user = UserCreate(username=username, email=email, password=password, confirm_password=confirm_password) register(user, db) # If this function raises an HTTPException, it should be handled except HTTPException as e: # Return to the registration page with the error detail return templates.TemplateResponse("register.html", { "request": request, "error_message": e.detail }) # Redirect to the successful registration page response = RedirectResponse("/registration_successful", status_code=status.HTTP_302_FOUND) return response @app.post("/registration_successful", response_class=HTMLResponse) async def registration_successful(request: Request): return templates.TemplateResponse("registration_successful.html", {"request": request}) @app.get("/verify/{verification_token}", response_class=HTMLResponse) async def verify_email(verification_token: str, request: Request, db: Session = Depends(get_db)): # Verify the email using the token user = get_user_by_verification_token(db, verification_token) if not user: raise HTTPException(status_code=400, detail="Invalid verification token") if user.is_verified: raise HTTPException(status_code=400, detail="Email already verified") # Mark the email as verified in the database user.is_verified = True #user.email_verification_token = None # Optionally clear the verification token db.commit() # Handle a successful verification # return templates.TemplateResponse("verification_successful.html", {"request": request}) return RedirectResponse("/protected") # User authentication (protected route) @app.post("/protected", response_class=HTMLResponse) # Specify response_class as HTMLResponse async def protected_route(request: Request, token: str = Depends(oauth2_scheme), db: Session = Depends(get_db)): # Verify the access token user = verify_token(token, my_secret_key, "HS256") if user is None: raise HTTPException(status_code=401, detail="Invalid or expired token") # Check if the user exists in the database db_user = get_user_by_email(db, user) # Modify this to match your database query if db_user is None: raise HTTPException(status_code=401, detail="User not found in the database") # The user exists in the database, and you can render the protected route template return templates.TemplateResponse("protected.html", {"request": request, "user": user.email})