File size: 2,058 Bytes
3c23e28
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7856594
3c23e28
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
"""
Firebase Auth module for FocusFlow.
Handles Firebase Admin SDK initialization and ID token verification.
In local mode (no credentials), authentication is skipped entirely.
"""
import json
import logging

from fastapi import HTTPException

logger = logging.getLogger(__name__)

# ---------- Firebase Admin SDK Initialization ----------

_firebase_app = None

def _init_firebase():
    """Initialize Firebase Admin SDK from environment variable (called once)."""
    global _firebase_app
    from backend.config import FIREBASE_SERVICE_ACCOUNT_JSON

    if not FIREBASE_SERVICE_ACCOUNT_JSON:
        logger.warning(
            "FIREBASE_SERVICE_ACCOUNT_JSON not set — Firebase auth disabled (local mode)."
        )
        return

    try:
        import firebase_admin
        from firebase_admin import credentials

        cred_dict = json.loads(FIREBASE_SERVICE_ACCOUNT_JSON)
        cred = credentials.Certificate(cred_dict)
        _firebase_app = firebase_admin.initialize_app(cred)
        logger.info("✅ Firebase Admin SDK initialized successfully.")
    except Exception as e:
        logger.error(f"❌ Failed to initialize Firebase Admin SDK: {e}")
        # Don't raise — allow app to start without Firebase auth

# Run initialization at module load time
_init_firebase()


# ---------- Token Verification ----------

def verify_firebase_token(id_token: str) -> dict:
    """
    Verify a Firebase ID token and return decoded claims.
    Returns dict with at least: uid, email, name (if available).
    Raises HTTPException 401 on any failure.
    """
    try:
        from firebase_admin import auth
        decoded = auth.verify_id_token(id_token)
        return {
            "uid": decoded["uid"],
            "email": decoded.get("email", ""),
            "name": decoded.get("name", ""),
        }
    except Exception as e:
        logger.warning(f"Firebase token verification failed: {e}")
        raise HTTPException(
            status_code=401,
            detail=f"Invalid or expired authentication token: {e}",
        )