| from fastapi import Request, Depends, HTTPException, status |
| from sqlalchemy.ext.asyncio import AsyncSession |
| from sqlalchemy.future import select |
| from datetime import datetime, timedelta, timezone |
| from app.database import get_db |
| from app import models |
| from app.utils.auth import verify_supabase_jwt |
|
|
| async def get_current_user(request: Request, db: AsyncSession = Depends(get_db)) -> models.User: |
| session_cookie = request.cookies.get("archvise_session") |
| |
| if not session_cookie: |
| auth_header = request.headers.get("Authorization") |
| if auth_header and auth_header.startswith("Bearer "): |
| session_cookie = auth_header.split(" ")[1] |
|
|
| if not session_cookie: |
| raise HTTPException( |
| status_code=status.HTTP_401_UNAUTHORIZED, |
| detail="Not authenticated" |
| ) |
| |
| try: |
| |
| if session_cookie.startswith("guest_"): |
| import redis.asyncio as redis_async |
| from app.config import settings as cfg |
| try: |
| r = redis_async.Redis.from_url(cfg.REDIS_URL, decode_responses=True) |
| guest_uid = await r.get(f"guest_session:{session_cookie}") |
| await r.aclose() |
| except Exception: |
| guest_uid = None |
| if not guest_uid: |
| raise HTTPException( |
| status_code=status.HTTP_401_UNAUTHORIZED, |
| detail="Guest session expired. Please start a new session." |
| ) |
| decoded_claims = { |
| "uid": guest_uid, |
| "email": f"{guest_uid}@guest.archvise.com", |
| "name": "Archvise Guest", |
| "picture": None |
| } |
| else: |
| |
| decoded_claims = verify_supabase_jwt(session_cookie) |
| except HTTPException: |
| raise |
| except Exception as e: |
| raise HTTPException( |
| status_code=status.HTTP_401_UNAUTHORIZED, |
| detail="Session expired or invalid" |
| ) |
| |
| firebase_uid = decoded_claims.get("uid") |
| email = decoded_claims.get("email") |
| name = decoded_claims.get("name") |
| avatar_url = decoded_claims.get("picture") |
| |
| |
| result = await db.execute(select(models.User).where(models.User.firebase_uid == firebase_uid)) |
| user = result.scalars().first() |
| |
| if not user: |
| |
| user = models.User( |
| firebase_uid=firebase_uid, |
| email=email, |
| name=name, |
| avatar_url=avatar_url, |
| plan="free", |
| display_mode="founder", |
| credits_remaining=2, |
| credits_reset_at=datetime.now(timezone.utc) + timedelta(days=30), |
| is_active=True |
| ) |
| db.add(user) |
| await db.commit() |
| await db.refresh(user) |
| |
| |
| now_utc = datetime.now(timezone.utc) |
| reset_at = user.credits_reset_at |
| |
| if reset_at and reset_at.tzinfo is None: |
| reset_at = reset_at.replace(tzinfo=timezone.utc) |
| if reset_at and now_utc > reset_at: |
| if user.plan == "pro": |
| user.credits_remaining = -1 |
| elif user.plan == "starter": |
| user.credits_remaining = 15 |
| else: |
| user.credits_remaining = 2 |
| user.credits_reset_at = now_utc + timedelta(days=30) |
| db.add(user) |
| await db.commit() |
| |
| if not user.is_active: |
| raise HTTPException( |
| status_code=status.HTTP_403_FORBIDDEN, |
| detail="User account is deactivated" |
| ) |
| |
| return user |
|
|