File size: 3,703 Bytes
dd8dfa2
2262841
dd8dfa2
 
 
 
bbc9c59
dd8dfa2
 
 
2262841
dd8dfa2
2262841
dd8dfa2
 
bbc9c59
dd8dfa2
 
 
 
 
 
 
2262841
 
 
 
 
dd8dfa2
 
 
 
 
 
 
 
 
 
 
 
 
2262841
 
 
 
 
 
 
 
 
 
 
 
 
 
 
dd8dfa2
2262841
 
 
 
 
 
 
 
 
 
 
 
dd8dfa2
 
2262841
dd8dfa2
 
 
 
 
 
 
2262841
dd8dfa2
2262841
dd8dfa2
 
 
2262841
dd8dfa2
 
 
2262841
 
 
 
 
 
dd8dfa2
 
bbc9c59
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
dd8dfa2
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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
import os
import json
from typing import Optional

try:
    import firebase_admin
    from firebase_admin import credentials, auth
    # App Check verification is available in newer firebase_admin versions
    try:
        from firebase_admin import app_check
    except ImportError:
        app_check = None
except ImportError:
    firebase_admin = None
    credentials = None
    auth = None
    app_check = None

_initialized = False

def initialize_firebase() -> bool:
    """Initialize Firebase Admin SDK from env.

    Supports two ways to provide credentials:
    1. FIREBASE_CREDENTIALS_JSON: Full JSON content as string
    2. FIREBASE_CREDENTIALS: Path to service account JSON file
    
    Optional: FIREBASE_PROJECT_ID to override project ID
    """
    global _initialized
    if _initialized:
        return True

    if firebase_admin is None or credentials is None:
        return False

    # Skip if already has a default app
    if firebase_admin._apps:
        _initialized = True
        return True

    # Try JSON content first (for Hugging Face secrets)
    cred_json = os.getenv("FIREBASE_CREDENTIALS_JSON")
    if cred_json:
        try:
            cred_dict = json.loads(cred_json)
            cred = credentials.Certificate(cred_dict)
            firebase_admin.initialize_app(cred, {
                "projectId": os.getenv("FIREBASE_PROJECT_ID") or cred_dict.get("project_id")
            })
            _initialized = True
            return True
        except Exception as e:
            print(f"Warning: Failed to initialize Firebase from JSON: {e}")
    
    # Fallback to file path
    cred_path = os.getenv("FIREBASE_CREDENTIALS")
    if cred_path and os.path.exists(cred_path):
        try:
            cred = credentials.Certificate(cred_path)
            firebase_admin.initialize_app(cred, {
                "projectId": os.getenv("FIREBASE_PROJECT_ID")
            })
            _initialized = True
            return True
        except Exception as e:
            print(f"Warning: Failed to initialize Firebase from file: {e}")
    
    return False

def verify_app_check_token(token: Optional[str]) -> bool:
    """Verify Firebase App Check token.

    Returns True if verification succeeds. If App Check is not available or
    not initialized, returns False to indicate verification not possible.
    """
    if not token:
        return False

    # If App Check module is not available, skip verification
    if app_check is None:
        print("Warning: Firebase App Check module not available")
        return False

    if not initialize_firebase():
        print("Warning: Firebase not initialized, skipping App Check verification")
        return False

    try:
        # Verify the App Check token
        # Note: verify_token() returns decoded token claims if valid, raises exception if invalid
        decoded_token = app_check.verify_token(token)
        return decoded_token is not None
    except Exception as e:
        print(f"Warning: App Check token verification failed: {e}")
        return False

def verify_firebase_id_token(id_token: Optional[str]) -> Optional[dict]:
    """Verify Firebase ID token and return decoded claims.
    
    Returns:
        dict: Decoded token claims (user info) if valid, None if invalid/not available
    """
    if not id_token:
        return None
    
    if auth is None:
        return None
    
    if not initialize_firebase():
        return None
    
    try:
        # Verify the ID token
        decoded_token = auth.verify_id_token(id_token)
        return decoded_token
    except Exception as e:
        print(f"Warning: Firebase ID token verification failed: {e}")
        return None