diff --git a/server/auth.py b/server/auth.py index 4781808..9c3a2ce 100644 --- a/server/auth.py +++ b/server/auth.py @@ -35,15 +35,15 @@ async def _verify_firebase_id_token(token: str) -> FirebaseIDTokenData: auth.InvalidIdTokenError, auth.ExpiredIdTokenError, auth.RevokedIdTokenError, - ) as e: + ): raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid or expired token" ) - except auth.UserDisabledError as e: + except auth.UserDisabledError: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail="User disabled" ) - except (ValueError, auth.CertificateFetchError, auth.FirebaseError) as e: + except (ValueError, auth.CertificateFetchError, auth.FirebaseError): raise HTTPException( status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail="Internal server error", diff --git a/server/fastapi_server.py b/server/fastapi_server.py index 6d01da8..705453a 100644 --- a/server/fastapi_server.py +++ b/server/fastapi_server.py @@ -4,6 +4,7 @@ import traceback import logging import asyncio +import re from fastapi import FastAPI, Request, HTTPException, Depends, Header from fastapi.middleware.cors import CORSMiddleware @@ -81,21 +82,51 @@ def create_fastapi_app() -> FastAPI: app = FastAPI() # Configure CORS + # FastAPI CORSMiddleware doesn't support regex patterns, so we list all allowed origins + allowed_origins = [ + "https://bitquant.io", + "https://www.bitquant.io", + # Localhost ports for development + "http://localhost:3000", + "http://localhost:3001", + "http://localhost:3002", + "http://localhost:4000", + "http://localhost:4200", + "http://localhost:5000", + "http://localhost:5173", + "http://localhost:8000", + "http://localhost:8080", + "http://localhost:8081", + "http://localhost:9000", + ] + + # Vercel preview deployments pattern (will be checked in custom middleware) + vercel_pattern = re.compile(r"^https://defi-chat-hub-git-[\w-]+-open-gradient\.vercel\.app$") + app.add_middleware( CORSMiddleware, - allow_origins=[ - "https://bitquant.io", - "https://www.bitquant.io", - r"^http://localhost:(3000|3001|3002|4000|4200|5000|5173|8000|8080|8081|9000)$", - r"^https://defi-chat-hub-git-[\w-]+-open-gradient\.vercel\.app$", - ], + allow_origins=allowed_origins, allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) - + # Add Datadog metrics middleware app.add_middleware(DatadogMetricsMiddleware) + + # Add custom CORS check for Vercel preview deployments + # This middleware runs after CORSMiddleware to handle regex patterns + @app.middleware("http") + async def cors_vercel_middleware(request: Request, call_next): + origin = request.headers.get("origin") + if origin and vercel_pattern.match(origin): + response = await call_next(request) + response.headers["Access-Control-Allow-Origin"] = origin + response.headers["Access-Control-Allow-Credentials"] = "true" + response.headers["Access-Control-Allow-Methods"] = "*" + response.headers["Access-Control-Allow-Headers"] = "*" + return response + return await call_next(request) # Initialize DynamoDB session database_manager = DatabaseManager() diff --git a/server/service.py b/server/service.py index 831985d..6383d90 100644 --- a/server/service.py +++ b/server/service.py @@ -5,24 +5,32 @@ def verify_solana_signature(verify_request: SolanaVerifyRequest) -> str: - try: - public_key = b58decode(verify_request.address) - signature = b58decode(verify_request.signature) - message = verify_request.message.encode("utf-8") + """Verify Solana signature and create Firebase custom token. + + Args: + verify_request: Solana verification request containing address, signature, and message. + + Returns: + Firebase custom token as string. + + Raises: + ValueError: If signature verification fails or token creation fails. + """ + public_key = b58decode(verify_request.address) + signature = b58decode(verify_request.signature) + message = verify_request.message.encode("utf-8") - verify_key = VerifyKey(public_key) - verify_key.verify(message, signature) + verify_key = VerifyKey(public_key) + verify_key.verify(message, signature) - uid = f"wallet_{verify_request.address}" - custom_token = auth.create_custom_token(uid) + uid = f"wallet_{verify_request.address}" + custom_token = auth.create_custom_token(uid) - if isinstance(custom_token, bytes): - token_bytes = custom_token - elif isinstance(custom_token, str): - token_bytes = custom_token.encode("utf-8") - else: - token_bytes = str(custom_token).encode("utf-8") + if isinstance(custom_token, bytes): + token_bytes = custom_token + elif isinstance(custom_token, str): + token_bytes = custom_token.encode("utf-8") + else: + token_bytes = str(custom_token).encode("utf-8") - return token_bytes.decode("utf-8") - except Exception: - raise + return token_bytes.decode("utf-8")