diff --git a/Server/config_validator.py b/Server/config_validator.py new file mode 100644 index 0000000..183cd8b --- /dev/null +++ b/Server/config_validator.py @@ -0,0 +1,51 @@ +import os +import sys +import logging + +logging.basicConfig(level=logging.INFO) +logger = logging.getLogger("ConfigValidator") + +REQUIRED_ENV_VARS = { + "SUPABASE_URL": "Required to query database case records and render evidence graphs.", + "SUPABASE_ANON_KEY": "Required to authenticate database client connections securely.", + "ADMIN_TOKEN": "Required to authorize administration workflows (e.g. stats, reports).", + "INVESTIGATOR_TOKEN": "Required to validate forensic investigator operations." +} + +def validate_environment(): + """Verify presence of critical environment variables and print clean diagnostic logs.""" + missing_vars = [] + + print("\n" + "="*70) + print(" FORENSIC PRO SUITE - BACKEND BOOTSTRAP ENVIRONMENT SCAN") + print("="*70) + + for var, description in REQUIRED_ENV_VARS.items(): + value = os.getenv(var) + if not value: + missing_vars.append((var, description)) + status = " [ MISSING ] " + else: + # Mask token values for security + masked_value = value[:4] + "*"*8 if len(value) > 4 else "*"*8 + status = f" [ OK ] - {masked_value}" + print(f" -> {var:<22} {status}") + + print("="*70) + + if missing_vars: + print("\n" + "!"*70) + print(" WARNING: Configuration validation found missing required env keys:") + for var, description in missing_vars: + print(f" * {var}: {description}") + print(" Ensure you copy .env.example to .env and configure these parameters.") + print("!"*70 + "\n") + + # We will log a warning but allow local running for development fallback modes. + logger.warning("Server is starting up with incomplete environment variable settings.") + else: + logger.info("All core infrastructure environment configurations validated successfully.") + print("="*70 + "\n") + +if __name__ == "__main__": + validate_environment() diff --git a/Server/main.py b/Server/main.py index 665dc67..45e37e3 100644 --- a/Server/main.py +++ b/Server/main.py @@ -1,4 +1,6 @@ +# pyrefly: ignore [missing-import] from fastapi import FastAPI, UploadFile, File, HTTPException, Depends, Header, Request +# pyrefly: ignore [missing-import] from fastapi.middleware.cors import CORSMiddleware from security import ( inspect_archive_limits, @@ -17,6 +19,9 @@ logging.basicConfig(level=logging.INFO) logger = logging.getLogger(__name__) +from config_validator import validate_environment +validate_environment() + app = FastAPI() allowed_origin = os.getenv("ALLOWED_ORIGIN", "http://localhost:3000") @@ -41,6 +46,7 @@ MAX_FILE_SIZE = 500 * 1024 * 1024 +# pyrefly: ignore [parse-error] def get_api_user(authorization: str | None = Header(None)): if not authorization: raise HTTPException(status_code=401, detail="Authorization header missing") @@ -117,6 +123,7 @@ async def run_forensic_pipeline( # Record provenance to Supabase so it appears in the Evidence Graph try: + # pyrefly: ignore [missing-import] from supabase import create_client url = os.getenv("SUPABASE_URL") key = os.getenv("SUPABASE_ANON_KEY") @@ -178,6 +185,7 @@ async def get_graph_relationships(): try: cases = [] try: + # pyrefly: ignore [missing-import] from supabase import create_client url = os.getenv("SUPABASE_URL") key = os.getenv("SUPABASE_ANON_KEY") @@ -206,6 +214,7 @@ async def get_evidence_provenance(case_id: str): try: cases = [] try: + # pyrefly: ignore [missing-import] from supabase import create_client url = os.getenv("SUPABASE_URL") key = os.getenv("SUPABASE_ANON_KEY") @@ -259,6 +268,7 @@ async def expand_node(node_id: str): raise HTTPException(status_code=500, detail="Error expanding node.") +# pyrefly: ignore [missing-import] from fastapi import BackgroundTasks import asyncio @@ -278,5 +288,6 @@ async def trigger_graph_analysis(background_tasks: BackgroundTasks): if __name__ == "__main__": + # pyrefly: ignore [missing-import] import uvicorn uvicorn.run(app, host="0.0.0.0", port=8000) diff --git a/client/package-lock.json b/client/package-lock.json index ec22d54..3960e2b 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -47,6 +47,9 @@ "eslint-config-next": "16.1.6", "tailwindcss": "^4", "typescript": "^5" + }, + "engines": { + "node": ">=18.0.0" } }, "node_modules/@alloc/quick-lru": {