From a223923fd6305b6ba7860ac5b07f7c5023cf015b Mon Sep 17 00:00:00 2001 From: DevEnv nis2-agile Date: Sat, 27 Jun 2026 17:18:47 +0200 Subject: [PATCH] [FIX] ARIA data-aware via chat: AiController risolve l'org per org_data_ok MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ask() chiamava requireAuth() ma non requireOrgAccess(), quindi getCurrentOrgId() restava null → org_data_ok sempre falso → ARIA rispondeva "non ho accesso ai dati" anche con membership valida. Ora l'org si risolve da X-Organization-Id → param org_id → currentOrgId → org primaria dell'utente; lo spoofing resta neutralizzato dal controllo membership esistente. Verificato: ARIA ora cita i numeri reali (rischi/incidenti/asset...) via /api/ai/ask. Bug pre-esistente (Fase B 24/6), emerso nel test di rilascio V3. Co-Authored-By: Claude Opus 4.8 (1M context) --- application/controllers/AiController.php | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/application/controllers/AiController.php b/application/controllers/AiController.php index 4ea209e..3211292 100644 --- a/application/controllers/AiController.php +++ b/application/controllers/AiController.php @@ -45,9 +45,23 @@ class AiController extends BaseController // pageId canonico + testo dell'help "?" della pagina (allineamento ARIA↔Help). $pageId = mb_substr(trim((string) $this->getParam('page_id', '')), 0, 40); $pageHelp = mb_substr(trim((string) $this->getParam('page_help', '')), 0, 2500); + // Org attiva per lo snapshot dati di ARIA. ask() chiama requireAuth() ma NON + // requireOrgAccess(), quindi getCurrentOrgId() resta null e org_data_ok sarebbe + // sempre falso (ARIA cieca sui dati org). Risolviamo a mano: header + // X-Organization-Id → param org_id → currentOrgId → org primaria dell'utente. + // Lo spoofing è neutralizzato dal controllo membership qui sotto. + $orgId = (int) ($_SERVER['HTTP_X_ORGANIZATION_ID'] ?? $this->getParam('org_id') ?? 0); + if ($orgId <= 0) $orgId = (int) ($this->getCurrentOrgId() ?? 0); + if ($orgId <= 0) { + $primary = Database::fetchOne( + 'SELECT organization_id FROM user_organizations WHERE user_id = ? ORDER BY is_primary DESC, id ASC LIMIT 1', + [$userId] + ); + $orgId = (int) ($primary['organization_id'] ?? 0); + } $userContext = [ 'user_id' => $userId, - 'organization_id' => $this->getCurrentOrgId(), // può essere null + 'organization_id' => $orgId ?: null, 'consulting_firm_id' => $user['consulting_firm_id'] ?? null, 'page' => $page, 'page_id' => $pageId,