Import ClientFlow production v4928.1.5.132.4
This commit is contained in:
55
app/main.py
55
app/main.py
@@ -1,4 +1,5 @@
|
||||
from fastapi import FastAPI
|
||||
from fastapi import FastAPI, Request
|
||||
from fastapi.responses import PlainTextResponse
|
||||
|
||||
from app.analyzer import analyze
|
||||
from app.config import settings
|
||||
@@ -9,6 +10,22 @@ from app.admin_ui.router import router as admin_dashboard_router
|
||||
from app.api.internal import router as internal_api_router
|
||||
|
||||
|
||||
def _looks_like_invalid_uuid_error(exc: Exception) -> bool:
|
||||
text_value = str(exc)
|
||||
lowered = text_value.lower()
|
||||
return (
|
||||
"invalid input syntax for type uuid" in lowered
|
||||
or "badly formed hexadecimal uuid" in lowered
|
||||
or "valueerror: badly formed hexadecimal uuid" in lowered
|
||||
or "could not parse uuid" in lowered
|
||||
)
|
||||
|
||||
|
||||
def _is_browser_request(request: Request) -> bool:
|
||||
accept = str(request.headers.get("accept") or "")
|
||||
return "text/html" in accept and "application/json" not in accept
|
||||
|
||||
|
||||
app = FastAPI(
|
||||
title="ClientFlow MVP",
|
||||
description="Motor de contexto comercial com Qwen3 30B + regras ClientFlow.",
|
||||
@@ -16,6 +33,42 @@ app = FastAPI(
|
||||
)
|
||||
|
||||
|
||||
|
||||
@app.middleware("http")
|
||||
async def security_headers_middleware(request: Request, call_next):
|
||||
response = await call_next(request)
|
||||
response.headers.setdefault("X-Content-Type-Options", "nosniff")
|
||||
response.headers.setdefault("X-Frame-Options", "DENY")
|
||||
response.headers.setdefault("Referrer-Policy", "strict-origin-when-cross-origin")
|
||||
response.headers.setdefault("Permissions-Policy", "camera=(), microphone=(), geolocation=()")
|
||||
# A UI atual carrega Bootstrap, Bootstrap Icons e HTMX por CDN.
|
||||
# A CSP deve refletir explicitamente essas dependências para evitar erros reais
|
||||
# no browser/Playwright, mantendo frame-ancestors e defaults restritos.
|
||||
response.headers.setdefault(
|
||||
"Content-Security-Policy",
|
||||
"default-src 'self'; "
|
||||
"img-src 'self' data:; "
|
||||
"style-src 'self' 'unsafe-inline' https://cdn.jsdelivr.net; "
|
||||
"style-src-elem 'self' 'unsafe-inline' https://cdn.jsdelivr.net; "
|
||||
"script-src 'self' 'unsafe-inline' https://cdn.jsdelivr.net https://unpkg.com; "
|
||||
"script-src-elem 'self' 'unsafe-inline' https://cdn.jsdelivr.net https://unpkg.com; "
|
||||
"font-src 'self' data: https://cdn.jsdelivr.net; "
|
||||
"connect-src 'self' ws: wss:; "
|
||||
"frame-ancestors 'none'",
|
||||
)
|
||||
path = str(request.url.path or "")
|
||||
if path in {"/", "/tasks", "/customers", "/opportunities", "/finance", "/system", "/settings"} or path.startswith(("/tasks", "/customers", "/opportunities", "/outbox", "/finance", "/financeiro")):
|
||||
response.headers.setdefault("Cache-Control", "private, no-store")
|
||||
return response
|
||||
|
||||
|
||||
@app.exception_handler(Exception)
|
||||
async def controlled_exception_handler(request: Request, exc: Exception):
|
||||
if _looks_like_invalid_uuid_error(exc):
|
||||
return PlainTextResponse("Identificador inválido.", status_code=422)
|
||||
# Keep unexpected errors visible during development/test while avoiding raw tracebacks in HTML.
|
||||
raise exc
|
||||
|
||||
app.include_router(chatwoot_router)
|
||||
app.include_router(internal_api_router)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user