Pushkar Pandey
fix: move backend files to root for HuggingFace
61ec498
Raw
History Blame Contribute Delete
2.86 kB
import os
import jwt
from fastapi import Depends, HTTPException
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
from sqlalchemy.orm import Session
from dotenv import load_dotenv
from app.db.database import get_db
from app.db.models import User
from app.services.coa_initializer import initialize_startup_coa
load_dotenv()
security = HTTPBearer()
NEXTAUTH_SECRET = os.getenv("NEXTAUTH_SECRET")
def get_current_user_claims(
credentials: HTTPAuthorizationCredentials = Depends(security)
) -> dict:
"""
Accepts the NextAuth session token.
NextAuth sends token.sub (the user UUID) as the Bearer token.
We try to decode it as a JWT first; if it's just a plain UUID, we wrap it.
"""
token = credentials.credentials
try:
# Try to decode as a signed JWT (future-proof for when we pass full JWTs)
decoded = jwt.decode(
token,
NEXTAUTH_SECRET,
algorithms=["HS256"],
options={"verify_aud": False}
)
return decoded
except Exception:
# If it's not a JWT (it's a plain UUID), wrap it in a dict so the rest works
if len(token) == 36 and token.count("-") == 4: # UUID format check
return {"sub": token}
raise HTTPException(status_code=401, detail="Invalid authentication token.")
def get_current_user_id(decoded_token: dict = Depends(get_current_user_claims)) -> str:
"""Returns the user UUID from the verified JWT."""
return decoded_token.get("sub")
def get_current_user(
decoded_token: dict = Depends(get_current_user_claims),
db: Session = Depends(get_db)
) -> User:
"""
Just-In-Time User Sync.
Intercepts the token, checks if the user exists in PostgreSQL,
and silently creates them (with their accounting buckets) if they don't!
"""
user_id = decoded_token.get("sub")
email = decoded_token.get("email", "unknown@user.com")
# 1. Check if user exists by UUID
user = db.query(User).filter(User.user_id == user_id).first()
if not user:
# 2. Check if they exist by email (orphaned account)
existing_email_user = db.query(User).filter(User.email == email).first()
if existing_email_user:
print(f"🔒 JIT AUTH: Relinking {email} to new ID...")
existing_email_user.user_id = user_id
db.commit()
db.refresh(existing_email_user)
return existing_email_user
# 3. Brand new user — create them instantly!
print(f"🔒 JIT AUTH: Registering new user {email}...")
user = User(
user_id=user_id,
email=email,
organization_name="New Startup"
)
db.add(user)
db.flush()
initialize_startup_coa(db, user_id=user_id)
db.commit()
db.refresh(user)
return user