ProdLaunch

This commit is contained in:
2026-06-18 15:14:10 +02:00
parent d8f58640e5
commit 4c90a7c1a3
12 changed files with 1412 additions and 5 deletions
+11
View File
@@ -47,6 +47,7 @@ limiter = Limiter(key_func=get_remote_address)
summary="Login con email e password",
description="Autentica l'utente. Se 2FA è attivo, richiede anche il codice TOTP.",
)
@limiter.limit(settings.rate_limit_auth)
async def login(
request: Request,
body: LoginRequest,
@@ -64,6 +65,11 @@ async def login(
user_agent=ua,
)
# Commit esplicito prima di restituire la risposta: garantisce che il
# RefreshToken sia gia' in DB quando il client chiama /auth/refresh
# in sequenza rapida, evitando race condition.
await db.commit()
return TokenResponse(
access_token=access_token,
refresh_token=refresh_token,
@@ -83,6 +89,11 @@ async def refresh_tokens(
service = AuthService(db)
access_token, refresh_token = await service.refresh_tokens(body.refresh_token)
# Commit esplicito prima di restituire la risposta: garantisce che la
# revoca del vecchio token (rotation) sia persistita in DB prima che
# il client possa usare il nuovo token, evitando race condition.
await db.commit()
return TokenResponse(
access_token=access_token,
refresh_token=refresh_token,
+3 -1
View File
@@ -205,12 +205,14 @@ async def update_mailbox(
Se vengono fornite nuove credenziali, vengono ri-cifrate.
"""
svc = _svc(db)
mailbox = await svc.update_mailbox(
await svc.update_mailbox(
mailbox_id=mailbox_id,
tenant_id=current_user.tenant_id,
data=data,
)
await db.commit()
# Ricarica dal DB dopo il commit per evitare lazy-load su oggetto stale
mailbox = await svc.get_mailbox(mailbox_id, current_user.tenant_id)
return _build_response(mailbox, svc)
+6 -2
View File
@@ -923,9 +923,13 @@ async def get_thread(
# Carica ricorsivamente tutti i messaggi del thread dalla radice
# Limita a posta_certificata (esclude accettazioni, consegne, ecc.)
# Depth limit per evitare stack overflow su thread eccezionalmente profondi
_THREAD_MAX_DEPTH = 100
thread_messages: list[Message] = []
async def _collect(msg_id: uuid.UUID) -> None:
async def _collect(msg_id: uuid.UUID, depth: int = 0) -> None:
if depth >= _THREAD_MAX_DEPTH:
return
result = await db.execute(
select(Message)
.where(
@@ -951,7 +955,7 @@ async def get_thread(
)
children = list(children_result.scalars().all())
for child in children:
await _collect(child.id)
await _collect(child.id, depth + 1)
await _collect(root_id)