diff --git a/backend/app/routers/auth.py b/backend/app/routers/auth.py index b17584a..b349ebf 100644 --- a/backend/app/routers/auth.py +++ b/backend/app/routers/auth.py @@ -34,7 +34,16 @@ from app.schemas.user import PasswordChange router = APIRouter(prefix="/auth", tags=["auth"]) -_IS_HTTPS = os.environ.get("AEGIS_ENV", "").lower() == "production" +# SECURE_COOKIES desacopla la seguridad de la cookie del entorno de ejecucion. +# Por defecto activo en produccion; ponlo en "false" para servidores HTTP. +_aegis_env = os.environ.get("AEGIS_ENV", "development").lower() +_secure_cookie_env = os.environ.get("SECURE_COOKIES", "auto").lower() +if _secure_cookie_env == "false": + _IS_HTTPS = False +elif _secure_cookie_env == "true": + _IS_HTTPS = True +else: # "auto" — activo solo si AEGIS_ENV=production + _IS_HTTPS = _aegis_env == "production" _COOKIE_NAME = "aegis_token" diff --git a/frontend/nginx.conf b/frontend/nginx.conf index 09124d9..872dc2d 100644 --- a/frontend/nginx.conf +++ b/frontend/nginx.conf @@ -14,7 +14,7 @@ server { # add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; # CSP: allow self + inline styles (React build) + data: URIs for fonts/images - add_header Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data: blob:; font-src 'self' data:; connect-src 'self'; frame-ancestors 'none'; base-uri 'self'; form-action 'self';" always; + add_header Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data: blob:; font-src 'self' data:; connect-src 'self' ws: wss:; frame-ancestors 'none'; base-uri 'self'; form-action 'self';" always; # Hide Nginx version server_tokens off; diff --git a/frontend/src/components/TechniqueCell.tsx b/frontend/src/components/TechniqueCell.tsx index 95158c1..aa8b129 100644 --- a/frontend/src/components/TechniqueCell.tsx +++ b/frontend/src/components/TechniqueCell.tsx @@ -1,4 +1,4 @@ -import { useNavigate } from "react-router-dom"; +import { Link } from "react-router-dom"; import { AlertTriangle } from "lucide-react"; import type { TechniqueStatus } from "../types/models"; @@ -48,18 +48,13 @@ export default function TechniqueCell({ status, reviewRequired = false, }: TechniqueCellProps) { - const navigate = useNavigate(); const colors = statusColors[status] || statusColors.not_evaluated; - const handleClick = () => { - navigate(`/techniques/${mitreId}`); - }; - return ( - + ); } diff --git a/frontend/src/pages/TechniquesPage.tsx b/frontend/src/pages/TechniquesPage.tsx index 60292e0..7e5d5c3 100644 --- a/frontend/src/pages/TechniquesPage.tsx +++ b/frontend/src/pages/TechniquesPage.tsx @@ -4,7 +4,7 @@ import { Loader2, AlertCircle, Filter, X, Grid3X3, List } from "lucide-react"; import { getTechniques, type TechniqueSummary } from "../api/techniques"; import AttackMatrix from "../components/AttackMatrix"; import type { TechniqueStatus } from "../types/models"; -import { useNavigate } from "react-router-dom"; +import { useNavigate, Link } from "react-router-dom"; const STATUS_OPTIONS: { value: TechniqueStatus | "all"; label: string; color: string }[] = [ { value: "all", label: "All Statuses", color: "text-gray-400" }, @@ -224,7 +224,13 @@ export default function TechniquesPage() { className="cursor-pointer border-b border-gray-800/50 hover:bg-gray-800/50 transition-colors" > - {tech.mitre_id} + e.stopPropagation()} + className="font-mono text-cyan-400 hover:underline" + > + {tech.mitre_id} + {tech.name}