diff --git a/opencti-platform/opencti-front/lang/back/de.json b/opencti-platform/opencti-front/lang/back/de.json
index ecb9440ea1b5..9bcbe3d0152a 100644
--- a/opencti-platform/opencti-front/lang/back/de.json
+++ b/opencti-platform/opencti-front/lang/back/de.json
@@ -108,6 +108,10 @@
"Card number": "Kartennummer",
"Carousel order": "Karussell-Reihenfolge",
"Case template": "Fallvorlage",
+ "Catalog Contract content hash": "Hash des Inhalts des Katalogvertrags",
+ "Catalog Contract ID": "ID des Katalogvertrags",
+ "Catalog ID": "Katalog-ID",
+ "Catalog product version": "Produktversion des Katalogs",
"Category": "Kategorie",
"CC": "CC",
"Certifiate policies": "Zertifizierungsrichtlinien",
@@ -130,11 +134,13 @@
"Confidence level": "Konfidenzniveau",
"Confidentiality impact": "Auswirkungen auf die Vertraulichkeit",
"Configuration": "Konfiguration",
+ "Configuration schema": "Konfigurationsschema",
"Configuration version": "Version der Konfiguration",
"Connector catalog": "Stecker-Katalog",
"Connector ID": "Anschluss-ID",
"Connector information": "Informationen zum Anschluss",
"Connector manager": "Stecker-Manager",
+ "Connector manager contract": "Vertrag des Connector-Managers",
"Connector manager current status": "Aktueller Status des Verbindungsmanagers",
"Connector manager image": "Bild des Verbindungsmanagers",
"Connector manager requested status": "Verbindungsmanager angeforderter Status",
@@ -143,10 +149,12 @@
"Connector state": "Zustand des Verbinders",
"Connector trigger filters": "Anschluss Triggerfilter",
"Connector type": "Steckertyp",
+ "Connector upgrade strategy": "Upgrade-Strategie für den Connector",
"Connector user id": "Connector Benutzer-ID",
"Connectors": "Verbinder",
"Consent confirm text": "Text zur Bestätigung der Zustimmung",
"Consent message": "Zustimmungsnachricht",
+ "Contact": "Kontakt",
"Contact information": "Kontaktinformationen",
"Contains": "Enthält",
"Contains observable": "Enthält beobachtbar",
@@ -160,6 +168,7 @@
"Context": "Kontext",
"Context data": "Kontextdaten",
"Contextual only": "Nur kontextabhängig",
+ "Contract version": "Vertragsversion",
"Copy confidence level to OpenCTI scores for indicators": "Kopieren des Konfidenzniveaus in OpenCTI-Bewertungen für Indikatoren",
"Copy OpenCTI scores to confidence level for indicators": "Kopieren der OpenCTI-Ergebnisse in das Konfidenzniveau der Indikatoren",
"Count": "Zählung",
@@ -562,12 +571,14 @@
"Last score evolution": "Entwicklung des letzten Punktestandes",
"Last seen": "Zuletzt gesehen",
"Last update": "Letzte Aktualisierung",
+ "Last verified date": "Datum der letzten Überprüfung",
"Lastname": "Nachname",
"Latest containers": "Letzte Container",
"Latest created relationships": "Zuletzt erstellte Beziehungen",
"Latitude": "Breitengrad",
"Layers": "Ebenen",
"LdapStrategy": "LDAP-Strategie",
+ "License type": "Lizenztyp",
"Lifetime": "Lebenszeit",
"Light accent": "Hell akzentuiert",
"Light background": "Heller Hintergrund",
@@ -592,6 +603,7 @@
"Locations propagation in reports": "Ortsausbreitung in Berichten",
"Log sources": "Protokollquellen",
"Login message": "Login-Nachricht",
+ "Logo URI in file storage": "Logo-URI im Dateispeicher",
"Logout remote": "Fernabmeldung",
"Longitude": "Längengrad",
"LZJD": "LZJD",
@@ -607,8 +619,11 @@
"Manager contracts": "Manager-Verträge",
"Manager ID": "Manager-ID",
"Manager running": "Manager läuft",
+ "Manager supported": "Unterstützter Manager",
"Mandatory": "Erforderlich",
"Manifest": "Manifest",
+ "Manifest schema version": "Manifest-Schema-Version",
+ "Manifest version": "Manifest-Version",
"Mappings": "Mappings",
"Marital status": "Familienstand",
"Marked for deletion at": "Zur Löschung vorgemerkt unter",
@@ -626,6 +641,7 @@
"Match Pir with source of relationship": "Pirat mit Quelle der Beziehung abgleichen",
"Max concurrent sessions (0 equals no maximum)": "Max. gleichzeitige Sitzungen (0 entspricht keinem Maximum)",
"Max Confidence": "Maximale Konfidenz",
+ "Max confidence level": "Maximales Konfidenzniveau",
"Max policy length": "Max policy length",
"Max shareable markings": "Maximal teilbare Markierungen",
"Max value": "Maximalwert",
@@ -807,6 +823,7 @@
"Platforms": "Plattformen",
"Playbook definition": "Spielbuch-Definition",
"Playbook running": "Spielbuch läuft",
+ "Playbook supported": "Unterstütztes Playbook",
"Policy constraints": "Policy-Beschränkungen",
"Policy mappings": "Richtlinien-Zuordnungen",
"Port": "Port",
@@ -914,6 +931,7 @@
"Result": "Ergebnis",
"Result name": "Name des Ergebnisses",
"Retention manager": "Leiter der Personalabteilung",
+ "Revision": "Revision",
"Revoke score": "Widerrufener Punktestand",
"Revoked": "Widerrufen",
"RIR": "RIR",
@@ -959,6 +977,7 @@
"SHA3-256": "SHA3-256",
"SHA3-512": "SHA3-512",
"Shared with": "Freigegeben für",
+ "Short description": "Kurzbeschreibung",
"Show submenu icons": "Symbole für Untermenüs anzeigen",
"Sightings of observables via observed data": "Sichtungen von Observablen über beobachtete Daten",
"Sightings propagation from indicator": "Fortpflanzung von Beobachtungen über einen Indikator",
@@ -970,12 +989,15 @@
"SMTP configuration": "SMTP-Konfiguration",
"SMTP enabled": "SMTP aktiviert",
"Software Vulnerability propagation to Infrastructure": "Ausbreitung von Software-Sicherheitslücken auf die Infrastruktur",
+ "Solution categories": "Lösungskategorien",
"Sophistication": "Raffinesse",
"Source": "Quelle",
+ "Source code": "Quellcode",
"Source connector": "Quellverbinder",
"Source entity": "Quelle Entität",
"Source name": "Name der Quelle",
"Source type": "Quellentyp",
+ "Source URI": "Quell-URI",
"SRC": "SRC",
"SRC byte count": "SRC-Bytezahl",
"SRC packets": "SRC-Pakete",
@@ -1015,6 +1037,8 @@
"Subject public key exponent": "Thema Exponent des öffentlichen Schlüssels",
"Subject public key modulus": "Betreff öffentlicher Schlüsselmodul",
"Submission date": "Datum der Einreichung",
+ "Subscription link": "Abonnement-Link",
+ "Support version": "Unterstützte Version",
"SWID": "SWID",
"Sync workflow statuses by name": "Workflow-Status nach Namen synchronisieren",
"Synchronized": "Synchronisiert",
@@ -1104,6 +1128,7 @@
"URL": "URL",
"Usage propagation of parent techniques": "Verwendungspropagierung von übergeordneten Techniken",
"Usage propagation via attribution": "Weitergabe der Nutzung über Attribution",
+ "Use cases": "Anwendungsfälle",
"Use DB configuration": "DB-Konfiguration verwenden",
"Use SSL": "SSL verwenden",
"User": "Benutzer",
@@ -1136,6 +1161,7 @@
"Variables": "Variablen",
"Vendor": "Anbieter",
"verb": "verb",
+ "Verified": "Verifiziert",
"Verify SSL certificate": "SSL-Zertifikat verifizieren",
"Version": "Version",
"Version History": "Versionsgeschichte",
@@ -1181,4 +1207,5 @@
"XTM One intent": "XTM Eine Absicht",
"XTM One registration manager": "XTM One Registrierungsmanager",
"XTM1 CGU acceptance status": "XTM1 CGU-Annahmestatus"
-}
\ No newline at end of file
+}
+
diff --git a/opencti-platform/opencti-front/lang/back/en.json b/opencti-platform/opencti-front/lang/back/en.json
index f9d39eda4774..cb33c4af0384 100644
--- a/opencti-platform/opencti-front/lang/back/en.json
+++ b/opencti-platform/opencti-front/lang/back/en.json
@@ -108,6 +108,10 @@
"Card number": "Card number",
"Carousel order": "Carousel order",
"Case template": "Case template",
+ "Catalog Contract content hash": "Catalog Contract content hash",
+ "Catalog Contract ID": "Catalog Contract ID",
+ "Catalog ID": "Catalog ID",
+ "Catalog product version": "Catalog product version",
"Category": "Category",
"CC": "CC",
"Certifiate policies": "Certifiate policies",
@@ -130,11 +134,13 @@
"Confidence level": "Confidence level",
"Confidentiality impact": "Confidentiality impact",
"Configuration": "Configuration",
+ "Configuration schema": "Configuration schema",
"Configuration version": "Configuration version",
"Connector catalog": "Connector catalog",
"Connector ID": "Connector ID",
"Connector information": "Connector information",
"Connector manager": "Connector manager",
+ "Connector manager contract": "Connector manager contract",
"Connector manager current status": "Connector manager current status",
"Connector manager image": "Connector manager image",
"Connector manager requested status": "Connector manager requested status",
@@ -143,10 +149,12 @@
"Connector state": "Connector state",
"Connector trigger filters": "Connector trigger filters",
"Connector type": "Connector type",
+ "Connector upgrade strategy": "Connector upgrade strategy",
"Connector user id": "Connector user id",
"Connectors": "Connectors",
"Consent confirm text": "Consent confirm text",
"Consent message": "Consent message",
+ "Contact": "Contact",
"Contact information": "Contact information",
"Contains": "Contains",
"Contains observable": "Contains observable",
@@ -160,6 +168,7 @@
"Context": "Context",
"Context data": "Context data",
"Contextual only": "Contextual only",
+ "Contract version": "Contract version",
"Copy confidence level to OpenCTI scores for indicators": "Copy confidence level to OpenCTI scores for indicators",
"Copy OpenCTI scores to confidence level for indicators": "Copy OpenCTI scores to confidence level for indicators",
"Count": "Count",
@@ -562,12 +571,14 @@
"Last score evolution": "Last score evolution",
"Last seen": "Last seen",
"Last update": "Last update",
+ "Last verified date": "Last verified date",
"Lastname": "Lastname",
"Latest containers": "Latest containers",
"Latest created relationships": "Latest created relationships",
"Latitude": "Latitude",
"Layers": "Layers",
"LdapStrategy": "LDAP Strategy",
+ "License type": "License type",
"Lifetime": "Lifetime",
"Light accent": "Light accent",
"Light background": "Light background",
@@ -592,6 +603,7 @@
"Locations propagation in reports": "Locations propagation in reports",
"Log sources": "Log sources",
"Login message": "Login message",
+ "Logo URI in file storage": "Logo URI in file storage",
"Logout remote": "Logout remote",
"Longitude": "Longitude",
"LZJD": "LZJD",
@@ -607,8 +619,11 @@
"Manager contracts": "Manager contracts",
"Manager ID": "Manager ID",
"Manager running": "Manager running",
+ "Manager supported": "Manager supported",
"Mandatory": "Mandatory",
"Manifest": "Manifest",
+ "Manifest schema version": "Manifest schema version",
+ "Manifest version": "Manifest version",
"Mappings": "Mappings",
"Marital status": "Marital status",
"Marked for deletion at": "Marked for deletion at",
@@ -626,6 +641,7 @@
"Match Pir with source of relationship": "Match Pir with source of relationship",
"Max concurrent sessions (0 equals no maximum)": "Max concurrent sessions (0 equals no maximum)",
"Max Confidence": "Max Confidence",
+ "Max confidence level": "Max confidence level",
"Max policy length": "Max policy length",
"Max shareable markings": "Max shareable markings",
"Max value": "Max value",
@@ -807,6 +823,7 @@
"Platforms": "Platforms",
"Playbook definition": "Playbook definition",
"Playbook running": "Playbook running",
+ "Playbook supported": "Playbook supported",
"Policy constraints": "Policy constraints",
"Policy mappings": "Policy mappings",
"Port": "Port",
@@ -914,6 +931,7 @@
"Result": "Result",
"Result name": "Result name",
"Retention manager": "Retention manager",
+ "Revision": "Revision",
"Revoke score": "Revoke score",
"Revoked": "Revoked",
"RIR": "RIR",
@@ -959,6 +977,7 @@
"SHA3-256": "SHA3-256",
"SHA3-512": "SHA3-512",
"Shared with": "Shared with",
+ "Short description": "Short description",
"Show submenu icons": "Show submenu icons",
"Sightings of observables via observed data": "Sightings of observables via observed data",
"Sightings propagation from indicator": "Sightings propagation from indicator",
@@ -970,12 +989,15 @@
"SMTP configuration": "SMTP configuration",
"SMTP enabled": "SMTP enabled",
"Software Vulnerability propagation to Infrastructure": "Software Vulnerability propagation to Infrastructure",
+ "Solution categories": "Solution categories",
"Sophistication": "Sophistication",
"Source": "Source",
+ "Source code": "Source code",
"Source connector": "Source connector",
"Source entity": "Source entity",
"Source name": "Source name",
"Source type": "Source type",
+ "Source URI": "Source URI",
"SRC": "SRC",
"SRC byte count": "SRC byte count",
"SRC packets": "SRC packets",
@@ -1015,6 +1037,8 @@
"Subject public key exponent": "Subject public key exponent",
"Subject public key modulus": "Subject public key modulus",
"Submission date": "Submission date",
+ "Subscription link": "Subscription link",
+ "Support version": "Support version",
"SWID": "SWID",
"Sync workflow statuses by name": "Sync workflow statuses by name",
"Synchronized": "Synchronized",
@@ -1104,6 +1128,7 @@
"URL": "URL",
"Usage propagation of parent techniques": "Usage propagation of parent techniques",
"Usage propagation via attribution": "Usage propagation via attribution",
+ "Use cases": "Use cases",
"Use DB configuration": "Use DB configuration",
"Use SSL": "Use SSL",
"User": "User",
@@ -1136,6 +1161,7 @@
"Variables": "Variables",
"Vendor": "Vendor",
"verb": "verb",
+ "Verified": "Verified",
"Verify SSL certificate": "Verify SSL certificate",
"Version": "Version",
"Version History": "Version History",
@@ -1181,4 +1207,5 @@
"XTM One intent": "XTM One intent",
"XTM One registration manager": "XTM One registration manager",
"XTM1 CGU acceptance status": "XTM1 CGU acceptance status"
-}
\ No newline at end of file
+}
+
diff --git a/opencti-platform/opencti-front/lang/back/es.json b/opencti-platform/opencti-front/lang/back/es.json
index 333202b9d697..cb5f9c042208 100644
--- a/opencti-platform/opencti-front/lang/back/es.json
+++ b/opencti-platform/opencti-front/lang/back/es.json
@@ -108,6 +108,10 @@
"Card number": "Número de tarjeta",
"Carousel order": "Orden del carrusel",
"Case template": "Plantilla de casos",
+ "Catalog Contract content hash": "Hash del contenido del contrato del catálogo",
+ "Catalog Contract ID": "ID del contrato del catálogo",
+ "Catalog ID": "ID del catálogo",
+ "Catalog product version": "Versión del producto del catálogo",
"Category": "Categoría",
"CC": "CC",
"Certifiate policies": "Políticas de certificación",
@@ -130,11 +134,13 @@
"Confidence level": "Nivel de confianza",
"Confidentiality impact": "Impacto en la confidencialidad",
"Configuration": "Configuración",
+ "Configuration schema": "Esquema de configuración",
"Configuration version": "Versión de configuración",
"Connector catalog": "Catálogo de conectores",
"Connector ID": "ID del conector",
"Connector information": "Información sobre el conector",
"Connector manager": "Gestor de conectores",
+ "Connector manager contract": "Contrato del gestor de conectores",
"Connector manager current status": "Estado actual del gestor de conectores",
"Connector manager image": "Imagen del gestor de conectores",
"Connector manager requested status": "Estado solicitado del gestor de conectores",
@@ -143,10 +149,12 @@
"Connector state": "Estado del conector",
"Connector trigger filters": "Filtros de activación de conectores",
"Connector type": "Tipo de conector",
+ "Connector upgrade strategy": "Estrategia de actualización de conectores",
"Connector user id": "ID de usuario del conector",
"Connectors": "Conectores",
"Consent confirm text": "Texto de confirmación del consentimiento",
"Consent message": "Mensaje de consentimiento",
+ "Contact": "Contacto",
"Contact information": "Información de contacto",
"Contains": "Contiene",
"Contains observable": "Contiene observable",
@@ -160,6 +168,7 @@
"Context": "Contexto",
"Context data": "Datos contextuales",
"Contextual only": "Sólo contextual",
+ "Contract version": "Versión del contrato",
"Copy confidence level to OpenCTI scores for indicators": "Copiar el nivel de confianza a las puntuaciones OpenCTI para los indicadores",
"Copy OpenCTI scores to confidence level for indicators": "Copiar las puntuaciones de OpenCTI en el nivel de confianza de los indicadores",
"Count": "Cuenta",
@@ -562,12 +571,14 @@
"Last score evolution": "Evolución de la última puntuación",
"Last seen": "Visto por última vez",
"Last update": "Última actualización",
+ "Last verified date": "Fecha de la última verificación",
"Lastname": "Apellido",
"Latest containers": "Últimos contenedores",
"Latest created relationships": "Últimas relaciones creadas",
"Latitude": "Latitud",
"Layers": "Capas",
"LdapStrategy": "Estrategia LDAP",
+ "License type": "Tipo de licencia",
"Lifetime": "De por vida",
"Light accent": "Acento claro",
"Light background": "Fondo claro",
@@ -592,6 +603,7 @@
"Locations propagation in reports": "Propagación de localizaciones en informes",
"Log sources": "Fuentes de registro",
"Login message": "Mensaje de inicio de sesión",
+ "Logo URI in file storage": "URI del logotipo en el almacenamiento de archivos",
"Logout remote": "Cerrar sesión remota",
"Longitude": "Longitud",
"LZJD": "LZJD",
@@ -607,8 +619,11 @@
"Manager contracts": "Gestor contratos",
"Manager ID": "ID Gestor",
"Manager running": "Gestor en funcionamiento",
+ "Manager supported": "Gestor compatible",
"Mandatory": "Obligatorio",
"Manifest": "Manifiesto",
+ "Manifest schema version": "Versión del esquema del manifiesto",
+ "Manifest version": "Versión del manifiesto",
"Mappings": "Asignaciones",
"Marital status": "Estado civil",
"Marked for deletion at": "Marcado para eliminación en",
@@ -626,6 +641,7 @@
"Match Pir with source of relationship": "Emparejar Pir con la fuente de relación",
"Max concurrent sessions (0 equals no maximum)": "Máximo de sesiones simultáneas (0 equivale a ningún máximo)",
"Max Confidence": "Confianza máxima",
+ "Max confidence level": "Nivel máximo de confianza",
"Max policy length": "Longitud máxima de la política",
"Max shareable markings": "Marcas máximas compartibles",
"Max value": "Valor máximo",
@@ -807,6 +823,7 @@
"Platforms": "Plataformas",
"Playbook definition": "Definición de Playbook",
"Playbook running": "Ejecución de Playbook",
+ "Playbook supported": "Guía de procedimientos compatible",
"Policy constraints": "Restricciones políticas",
"Policy mappings": "Asignación de políticas",
"Port": "Puerto",
@@ -914,6 +931,7 @@
"Result": "Resultado",
"Result name": "Nombre del resultado",
"Retention manager": "Responsable de retención",
+ "Revision": "Revisión",
"Revoke score": "Puntuación de revocación",
"Revoked": "Revocado",
"RIR": "RIR",
@@ -959,6 +977,7 @@
"SHA3-256": "SHA3-256",
"SHA3-512": "SHA3-512",
"Shared with": "Compartido con",
+ "Short description": "Breve descripción",
"Show submenu icons": "Mostrar iconos de submenú",
"Sightings of observables via observed data": "Avistamientos de observables a través de datos observados",
"Sightings propagation from indicator": "Propagación de avistamientos a partir de un indicador",
@@ -970,12 +989,15 @@
"SMTP configuration": "Configuración SMTP",
"SMTP enabled": "SMTP habilitado",
"Software Vulnerability propagation to Infrastructure": "Propagación de vulnerabilidades de software a la infraestructura",
+ "Solution categories": "Categorías de la solución",
"Sophistication": "Sofisticación",
"Source": "Fuente",
+ "Source code": "Código fuente",
"Source connector": "Conector fuente",
"Source entity": "Entidad de origen",
"Source name": "Nombre de la fuente",
"Source type": "Tipo de fuente",
+ "Source URI": "URI de origen",
"SRC": "SRC",
"SRC byte count": "Recuento de bytes SRC",
"SRC packets": "Paquetes SRC",
@@ -1015,6 +1037,8 @@
"Subject public key exponent": "Tema exponente de clave pública",
"Subject public key modulus": "Sujeto módulo de clave pública",
"Submission date": "Fecha de envío",
+ "Subscription link": "Enlace de suscripción",
+ "Support version": "Versión compatible",
"SWID": "SWID",
"Sync workflow statuses by name": "Sincronizar los estados del flujo de trabajo por nombre",
"Synchronized": "Sincronizado",
@@ -1104,6 +1128,7 @@
"URL": "URL",
"Usage propagation of parent techniques": "Propagación de uso de técnicas parentales",
"Usage propagation via attribution": "Propagación del uso mediante atribución",
+ "Use cases": "Casos de uso",
"Use DB configuration": "Usar configuración de la base de datos",
"Use SSL": "Usar SSL",
"User": "Usuario",
@@ -1136,6 +1161,7 @@
"Variables": "Variables",
"Vendor": "Proveedor",
"verb": "verbo",
+ "Verified": "Verificado",
"Verify SSL certificate": "Verificar certificado SSL",
"Version": "Versión",
"Version History": "Historial de versiones",
@@ -1181,4 +1207,5 @@
"XTM One intent": "Intento de XTM One",
"XTM One registration manager": "Gestor de inscripciones XTM One",
"XTM1 CGU acceptance status": "XTM1 Estado de aceptación de la UGC"
-}
\ No newline at end of file
+}
+
diff --git a/opencti-platform/opencti-front/lang/back/fr.json b/opencti-platform/opencti-front/lang/back/fr.json
index e8f2339a5074..a703b821655a 100644
--- a/opencti-platform/opencti-front/lang/back/fr.json
+++ b/opencti-platform/opencti-front/lang/back/fr.json
@@ -108,6 +108,10 @@
"Card number": "Numéro de carte",
"Carousel order": "Ordre du carrousel",
"Case template": "Modèle de cas",
+ "Catalog Contract content hash": "Hachage du contenu du contrat de catalogue",
+ "Catalog Contract ID": "ID du contrat de catalogue",
+ "Catalog ID": "ID du catalogue",
+ "Catalog product version": "Version du produit du catalogue",
"Category": "Catégorie",
"CC": "CC",
"Certifiate policies": "Politiques de certification",
@@ -130,11 +134,13 @@
"Confidence level": "Niveau de confiance",
"Confidentiality impact": "Impact sur la confidentialité",
"Configuration": "Configuration",
+ "Configuration schema": "Schéma de configuration",
"Configuration version": "Version de la configuration",
"Connector catalog": "Catalogue des connecteurs",
"Connector ID": "ID du connecteur",
"Connector information": "Informations sur le connecteur",
"Connector manager": "Gestionnaire du connecteur",
+ "Connector manager contract": "Contrat du gestionnaire de connecteurs",
"Connector manager current status": "Statut actuel du gestionnaire de connecteur",
"Connector manager image": "Image du gestionnaire de connecteur",
"Connector manager requested status": "Statut demandé par le gestionnaire de connecteur",
@@ -143,10 +149,12 @@
"Connector state": "État du connecteur",
"Connector trigger filters": "Filtres de déclenchement du connecteur",
"Connector type": "Type de connecteur",
+ "Connector upgrade strategy": "Stratégie de mise à niveau des connecteurs",
"Connector user id": "Identifiant de l'utilisateur du connecteur",
"Connectors": "Connecteurs",
"Consent confirm text": "Texte de confirmation du consentement",
"Consent message": "Message de consentement",
+ "Contact": "Contact",
"Contact information": "Informations de contact",
"Contains": "Contient",
"Contains observable": "Contient des observables",
@@ -160,6 +168,7 @@
"Context": "Contexte",
"Context data": "Données contextuelles",
"Contextual only": "Contextuel uniquement",
+ "Contract version": "Version du contrat",
"Copy confidence level to OpenCTI scores for indicators": "Copier le niveau de confiance dans les scores OpenCTI pour les indicateurs",
"Copy OpenCTI scores to confidence level for indicators": "Copier les scores OpenCTI vers le niveau de confiance pour les indicateurs",
"Count": "Nombre",
@@ -562,12 +571,14 @@
"Last score evolution": "Evolution du dernier score",
"Last seen": "Dernière fois qu'il a été vu",
"Last update": "Dernière mise à jour",
+ "Last verified date": "Date de la dernière vérification",
"Lastname": "Nom",
"Latest containers": "Derniers conteneurs",
"Latest created relationships": "Dernières relations créées",
"Latitude": "Latitude",
"Layers": "Couches",
"LdapStrategy": "Stratégie LDAP",
+ "License type": "Type de licence",
"Lifetime": "Durée de vie",
"Light accent": "Accentuation de la lumière",
"Light background": "Fond clair",
@@ -592,6 +603,7 @@
"Locations propagation in reports": "Propagation de l'emplacement dans les rapports",
"Log sources": "Sources de logs",
"Login message": "Message de connexion",
+ "Logo URI in file storage": "URI du logo dans le stockage de fichiers",
"Logout remote": "Déconnexion à distance",
"Longitude": "Longitude",
"LZJD": "LZJD",
@@ -607,8 +619,11 @@
"Manager contracts": "Contrats du gestionnaire",
"Manager ID": "Manager ID",
"Manager running": "Gestionnaire en cours d'exécution",
+ "Manager supported": "Gestionnaire pris en charge",
"Mandatory": "Obligatoire",
"Manifest": "Manifeste",
+ "Manifest schema version": "Version du schéma du manifeste",
+ "Manifest version": "Version du manifeste",
"Mappings": "Mappages",
"Marital status": "État civil",
"Marked for deletion at": "Marqué pour suppression à",
@@ -626,6 +641,7 @@
"Match Pir with source of relationship": "Faire correspondre Pir à la source de la relation",
"Max concurrent sessions (0 equals no maximum)": "Nombre maximal de sessions simultanées (0 signifie qu'il n'y a pas de maximum)",
"Max Confidence": "Confiance maximale",
+ "Max confidence level": "Niveau de confiance maximal",
"Max policy length": "Longueur maximale de la politique",
"Max shareable markings": "Marques maximales partageables",
"Max value": "Valeur maximale",
@@ -807,6 +823,7 @@
"Platforms": "Plateformes",
"Playbook definition": "Définition du Playbook",
"Playbook running": "Playbook en cours d'exécution",
+ "Playbook supported": "Guide de procédures pris en charge",
"Policy constraints": "Contraintes de politique",
"Policy mappings": "Mappages de politiques",
"Port": "Port",
@@ -914,6 +931,7 @@
"Result": "Résultat",
"Result name": "Nom du résultat",
"Retention manager": "Responsable de la rétention",
+ "Revision": "Révision",
"Revoke score": "Score de révocation",
"Revoked": "Révoqué",
"RIR": "RIR",
@@ -959,6 +977,7 @@
"SHA3-256": "SHA3-256",
"SHA3-512": "SHA3-512",
"Shared with": "Partagé avec",
+ "Short description": "Brève description",
"Show submenu icons": "Afficher les icônes des sous-menus",
"Sightings of observables via observed data": "Observations d'observables via des données observées",
"Sightings propagation from indicator": "Propagation des observations à partir d'un indicateur",
@@ -970,12 +989,15 @@
"SMTP configuration": "Configuration SMTP",
"SMTP enabled": "SMTP activé",
"Software Vulnerability propagation to Infrastructure": "Propagation d'une vulnérabilité d'un logiciel à une infrastructure",
+ "Solution categories": "Catégories de solutions",
"Sophistication": "Sophistication",
"Source": "Source",
+ "Source code": "Code source",
"Source connector": "Connecteur source",
"Source entity": "Entité source",
"Source name": "Nom de la source",
"Source type": "Type de source",
+ "Source URI": "URI de la source",
"SRC": "SRC",
"SRC byte count": "Nombre d'octets SRC",
"SRC packets": "Paquets SRC",
@@ -1015,6 +1037,8 @@
"Subject public key exponent": "Sujet clé publique exposant",
"Subject public key modulus": "Sujet modulus de clé publique",
"Submission date": "Date de soumission",
+ "Subscription link": "Lien d’abonnement",
+ "Support version": "Version prise en charge",
"SWID": "SWID",
"Sync workflow statuses by name": "Synchroniser les statuts des flux de travail par nom",
"Synchronized": "Synchronisé",
@@ -1104,6 +1128,7 @@
"URL": "URL",
"Usage propagation of parent techniques": "Propagation de l'usage des techniques parentales",
"Usage propagation via attribution": "Propagation de l'usage par attribution",
+ "Use cases": "Cas d’utilisation",
"Use DB configuration": "Utiliser la configuration en base",
"Use SSL": "Utiliser SSL",
"User": "Utilisateur",
@@ -1136,6 +1161,7 @@
"Variables": "Variables",
"Vendor": "Vendeur",
"verb": "verbe",
+ "Verified": "Vérifié",
"Verify SSL certificate": "Vérifier le certificat SSL",
"Version": "Version",
"Version History": "Historique de la version",
@@ -1181,4 +1207,5 @@
"XTM One intent": "XTM One intent",
"XTM One registration manager": "Gestionnaire d'enregistrement XTM One",
"XTM1 CGU acceptance status": "Statut d'acceptation des CGU XTM1"
-}
\ No newline at end of file
+}
+
diff --git a/opencti-platform/opencti-front/lang/back/it.json b/opencti-platform/opencti-front/lang/back/it.json
index 1a0b8e3acd8e..fc52545ab595 100644
--- a/opencti-platform/opencti-front/lang/back/it.json
+++ b/opencti-platform/opencti-front/lang/back/it.json
@@ -108,6 +108,10 @@
"Card number": "Numero di carta",
"Carousel order": "Ordine del carosello",
"Case template": "Modello di caso",
+ "Catalog Contract content hash": "Hash del contenuto del contratto del catalogo",
+ "Catalog Contract ID": "ID del contratto del catalogo",
+ "Catalog ID": "ID del catalogo",
+ "Catalog product version": "Versione del prodotto del catalogo",
"Category": "Categoria",
"CC": "CC",
"Certifiate policies": "Politiche del certificato",
@@ -130,11 +134,13 @@
"Confidence level": "Livello di fiducia",
"Confidentiality impact": "Impatto sulla riservatezza",
"Configuration": "Configurazione",
+ "Configuration schema": "Schema di configurazione",
"Configuration version": "Versione della configurazione",
"Connector catalog": "Catalogo dei connettori",
"Connector ID": "ID connettore",
"Connector information": "Informazioni sul connettore",
"Connector manager": "Gestore del connettore",
+ "Connector manager contract": "Contratto del gestore dei connettori",
"Connector manager current status": "Stato attuale del gestore di connettori",
"Connector manager image": "Immagine del gestore del connettore",
"Connector manager requested status": "Stato richiesto dal gestore del connettore",
@@ -143,10 +149,12 @@
"Connector state": "Stato del connettore",
"Connector trigger filters": "Filtri di attivazione del connettore",
"Connector type": "Tipo di connettore",
+ "Connector upgrade strategy": "Strategia di aggiornamento dei connettori",
"Connector user id": "ID utente del connettore",
"Connectors": "Connettori",
"Consent confirm text": "Testo di conferma del consenso",
"Consent message": "Messaggio di consenso",
+ "Contact": "Contatti",
"Contact information": "Informazioni di contatto",
"Contains": "Contiene",
"Contains observable": "Contiene osservabile",
@@ -160,6 +168,7 @@
"Context": "Contesto",
"Context data": "Dati di contesto",
"Contextual only": "Solo contestuale",
+ "Contract version": "Versione del contratto",
"Copy confidence level to OpenCTI scores for indicators": "Copia il livello di fiducia nei punteggi OpenCTI per gli indicatori",
"Copy OpenCTI scores to confidence level for indicators": "Copia i punteggi OpenCTI nel livello di fiducia per gli indicatori",
"Count": "Conteggio",
@@ -562,12 +571,14 @@
"Last score evolution": "Evoluzione dell'ultimo punteggio",
"Last seen": "Visto per l'ultima volta",
"Last update": "Ultimo aggiornamento",
+ "Last verified date": "Data dell’ultima verifica",
"Lastname": "Cognome",
"Latest containers": "Ultimi contenitori",
"Latest created relationships": "Ultime relazioni create",
"Latitude": "Latitudine",
"Layers": "Livelli",
"LdapStrategy": "Strategia LDAP",
+ "License type": "Tipo di licenza",
"Lifetime": "Durata",
"Light accent": "Accento chiaro",
"Light background": "Sfondo chiaro",
@@ -592,6 +603,7 @@
"Locations propagation in reports": "Propagazione della posizione nei rapporti",
"Log sources": "Fonti di log",
"Login message": "Messaggio di login",
+ "Logo URI in file storage": "URI del logo nell’archivio file",
"Logout remote": "Logout remoto",
"Longitude": "Longitudine",
"LZJD": "LZJD",
@@ -607,8 +619,11 @@
"Manager contracts": "Contratti del gestore",
"Manager ID": "ID manager",
"Manager running": "Manager in esecuzione",
+ "Manager supported": "Manager supportato",
"Mandatory": "Obbligatorio",
"Manifest": "Manifesto",
+ "Manifest schema version": "Versione dello schema del manifesto",
+ "Manifest version": "Versione del manifesto",
"Mappings": "Mappature",
"Marital status": "Stato civile",
"Marked for deletion at": "Contrassegnato per la cancellazione in",
@@ -626,6 +641,7 @@
"Match Pir with source of relationship": "Abbinare il Pir alla fonte della relazione",
"Max concurrent sessions (0 equals no maximum)": "Sessioni massime contemporanee (0 equivale a nessun massimo)",
"Max Confidence": "Massima fiducia",
+ "Max confidence level": "Livello massimo di affidabilità",
"Max policy length": "Lunghezza massima della politica",
"Max shareable markings": "Marcature massime condivisibili",
"Max value": "Valore massimo",
@@ -807,6 +823,7 @@
"Platforms": "Piattaforme",
"Playbook definition": "Definizione del playbook",
"Playbook running": "Playbook in esecuzione",
+ "Playbook supported": "Playbook supportato",
"Policy constraints": "Vincoli della policy",
"Policy mappings": "Mappature della policy",
"Port": "Porta",
@@ -914,6 +931,7 @@
"Result": "Risultato",
"Result name": "Nome del risultato",
"Retention manager": "Gestore della conservazione",
+ "Revision": "Revisione",
"Revoke score": "Revoca punteggio",
"Revoked": "Revocato",
"RIR": "RIR",
@@ -959,6 +977,7 @@
"SHA3-256": "SHA3-256",
"SHA3-512": "SHA3-512",
"Shared with": "Condiviso con",
+ "Short description": "Breve descrizione",
"Show submenu icons": "Mostra icone del sottomenu",
"Sightings of observables via observed data": "Avvistamenti di osservabili tramite dati osservati",
"Sightings propagation from indicator": "Propagazione degli osservabili da un indicatore",
@@ -970,12 +989,15 @@
"SMTP configuration": "Configurazione SMTP",
"SMTP enabled": "SMTP abilitato",
"Software Vulnerability propagation to Infrastructure": "Propagazione delle vulnerabilità del software all'infrastruttura",
+ "Solution categories": "Categorie di soluzioni",
"Sophistication": "Sofisticazione",
"Source": "Fonte",
+ "Source code": "Codice sorgente",
"Source connector": "Connettore di origine",
"Source entity": "Entità di origine",
"Source name": "Nome della fonte",
"Source type": "Tipo di fonte",
+ "Source URI": "URI sorgente",
"SRC": "SRC",
"SRC byte count": "Conteggio byte SRC",
"SRC packets": "Pacchetti SRC",
@@ -1015,6 +1037,8 @@
"Subject public key exponent": "Esponente della chiave pubblica del soggetto",
"Subject public key modulus": "Modulo della chiave pubblica del soggetto",
"Submission date": "Data di invio",
+ "Subscription link": "Link di abbonamento",
+ "Support version": "Versione supportata",
"SWID": "SWID",
"Sync workflow statuses by name": "Sincronizza gli stati del flusso di lavoro in base al nome",
"Synchronized": "Sincronizzato",
@@ -1104,6 +1128,7 @@
"URL": "URL",
"Usage propagation of parent techniques": "Propagazione d'uso delle tecniche parentali",
"Usage propagation via attribution": "Propagazione dell'uso tramite attribuzione",
+ "Use cases": "Casi d'uso",
"Use DB configuration": "Usa configurazione DB",
"Use SSL": "Usa SSL",
"User": "Utente",
@@ -1136,6 +1161,7 @@
"Variables": "Variabili",
"Vendor": "Fornitore",
"verb": "verbo",
+ "Verified": "Verificato",
"Verify SSL certificate": "Verifica del certificato SSL",
"Version": "Versione",
"Version History": "Storia della versione",
@@ -1181,4 +1207,5 @@
"XTM One intent": "Intento di XTM One",
"XTM One registration manager": "Gestore delle registrazioni XTM One",
"XTM1 CGU acceptance status": "XTM1 Stato di accettazione della CGU"
-}
\ No newline at end of file
+}
+
diff --git a/opencti-platform/opencti-front/lang/back/ja.json b/opencti-platform/opencti-front/lang/back/ja.json
index 2439d55c6f57..b5731cf27476 100644
--- a/opencti-platform/opencti-front/lang/back/ja.json
+++ b/opencti-platform/opencti-front/lang/back/ja.json
@@ -108,6 +108,10 @@
"Card number": "カード番号",
"Carousel order": "インデックスの日付",
"Case template": "評価",
+ "Catalog Contract content hash": "カタログ契約の内容ハッシュ",
+ "Catalog Contract ID": "カタログ契約ID",
+ "Catalog ID": "カタログID",
+ "Catalog product version": "カタログ製品のバージョン",
"Category": "マニフェスト",
"CC": "CC",
"Certifiate policies": "認証ポリシー",
@@ -130,11 +134,13 @@
"Confidence level": "信頼度",
"Confidentiality impact": "インシデントタイプ",
"Configuration": "組織タイプ",
+ "Configuration schema": "構成スキーマ",
"Configuration version": "モジュール",
"Connector catalog": "コネクタカタログ",
"Connector ID": "コネクタID",
"Connector information": "コネクタ情報",
"Connector manager": "コネクター・マネージャー",
+ "Connector manager contract": "コネクタマネージャー契約",
"Connector manager current status": "コネクタマネージャの現在のステータス",
"Connector manager image": "コネクタマネージャイメージ",
"Connector manager requested status": "コネクタマネージャ要求ステータス",
@@ -143,10 +149,12 @@
"Connector state": "コネクタの状態",
"Connector trigger filters": "コネクター・トリガー・フィルター",
"Connector type": "コネクタタイプ",
+ "Connector upgrade strategy": "コネクタのアップグレード戦略",
"Connector user id": "コネクター・ユーザーID",
"Connectors": "コネクタ",
"Consent confirm text": "同意確認テキスト",
"Consent message": "同意メッセージ",
+ "Contact": "連絡先",
"Contact information": "連絡先情報",
"Contains": "含む",
"Contains observable": "観測値を含む",
@@ -160,6 +168,7 @@
"Context": "コンテキスト",
"Context data": "コンテキストデータ",
"Contextual only": "コンテキストのみ",
+ "Contract version": "契約バージョン",
"Copy confidence level to OpenCTI scores for indicators": "指標の信頼度をOpenCTIのスコアにコピーする",
"Copy OpenCTI scores to confidence level for indicators": "OpenCTIのスコアを指標の信頼度にコピーする",
"Count": "偽陽性",
@@ -562,12 +571,14 @@
"Last score evolution": "最終スコアの推移",
"Last seen": "目的",
"Last update": "最終更新日",
+ "Last verified date": "最終検証日",
"Lastname": "姓",
"Latest containers": "最新コンテナ",
"Latest created relationships": "最新作成リレーションシップ",
"Latitude": "緯度",
"Layers": "6 - 真実は判断できない",
"LdapStrategy": "LDAP戦略",
+ "License type": "ライセンスタイプ",
"Lifetime": "生涯",
"Light accent": "ライトアクセント",
"Light background": "明るい背景",
@@ -592,6 +603,7 @@
"Locations propagation in reports": "レポートにおける位置情報の伝播",
"Log sources": "インフラの種類",
"Login message": "ログインメッセージ",
+ "Logo URI in file storage": "ファイルストレージ内のロゴ URI",
"Logout remote": "ログアウト・リモート",
"Longitude": "経度",
"LZJD": "LZJD",
@@ -607,8 +619,11 @@
"Manager contracts": "マネージャー契約",
"Manager ID": "設定",
"Manager running": "マネージャー実行中",
+ "Manager supported": "対応マネージャー",
"Mandatory": "必須",
"Manifest": "タグ",
+ "Manifest schema version": "マニフェストスキーマバージョン",
+ "Manifest version": "マニフェストバージョン",
"Mappings": "マッピング",
"Marital status": "目の色",
"Marked for deletion at": "削除対象としてマークされました",
@@ -626,6 +641,7 @@
"Match Pir with source of relationship": "海賊と関係元を一致させる",
"Max concurrent sessions (0 equals no maximum)": "最大同時セッション数(0は最大なし)",
"Max Confidence": "最大信頼度",
+ "Max confidence level": "最大信頼度",
"Max policy length": "最大ポリシー長",
"Max shareable markings": "共有可能な最大マーキング",
"Max value": "最大値",
@@ -807,6 +823,7 @@
"Platforms": "必要なパーミッション",
"Playbook definition": "プレイブックの定義",
"Playbook running": "プレイブックの実行",
+ "Playbook supported": "対応プレイブック",
"Policy constraints": "ポリシー制約",
"Policy mappings": "ポリシーのマッピング",
"Port": "ポート",
@@ -914,6 +931,7 @@
"Result": "VMホスト",
"Result name": "分析結果",
"Retention manager": "リテンション・マネージャー",
+ "Revision": "リビジョン",
"Revoke score": "失効点数",
"Revoked": "ラング",
"RIR": "RIR",
@@ -959,6 +977,7 @@
"SHA3-256": "SHA3-256",
"SHA3-512": "SHA3-512",
"Shared with": "と共有",
+ "Short description": "概要",
"Show submenu icons": "サブメニューアイコンを表示する",
"Sightings of observables via observed data": "観測データを介した観測可能性の目撃",
"Sightings propagation from indicator": "指標からの目撃伝播",
@@ -970,12 +989,15 @@
"SMTP configuration": "SMTP設定",
"SMTP enabled": "SMTPを有効にする",
"Software Vulnerability propagation to Infrastructure": "ソフトウェアの脆弱性がインフラストラクチャに波及する",
+ "Solution categories": "ソリューションカテゴリ",
"Sophistication": "個人的な動機",
"Source": "有効",
+ "Source code": "ソースコード",
"Source connector": "ソースコネクター",
"Source entity": "ソースエンティティ",
"Source name": "ハッシュ",
"Source type": "ソースタイプ",
+ "Source URI": "ソースURI",
"SRC": "SRC",
"SRC byte count": "SRCバイト数",
"SRC packets": "SRCパケット数",
@@ -1015,6 +1037,8 @@
"Subject public key exponent": "主題の公開鍵の指数",
"Subject public key modulus": "対象公開鍵モジュラス",
"Submission date": "分析開始日",
+ "Subscription link": "サブスクリプションリンク",
+ "Support version": "サポート対象バージョン",
"SWID": "SWID",
"Sync workflow statuses by name": "ワークフローのステータスを名前で同期する",
"Synchronized": "同期",
@@ -1104,6 +1128,7 @@
"URL": "URL",
"Usage propagation of parent techniques": "親テクニックの利用伝播",
"Usage propagation via attribution": "アトリビューションによる利用伝播",
+ "Use cases": "ユースケース",
"Use DB configuration": "DB設定を使用する",
"Use SSL": "SSLを使用する",
"User": "内蔵",
@@ -1136,6 +1161,7 @@
"Variables": "変数",
"Vendor": "ベンダー",
"verb": "動詞",
+ "Verified": "検証済み",
"Verify SSL certificate": "SSL証明書の検証",
"Version": "バージョン",
"Version History": "バージョン履歴",
@@ -1181,4 +1207,5 @@
"XTM One intent": "XTMワンの意図",
"XTM One registration manager": "XTM One登録マネージャー",
"XTM1 CGU acceptance status": "XTM1 CGU受入状況"
-}
\ No newline at end of file
+}
+
diff --git a/opencti-platform/opencti-front/lang/back/ko.json b/opencti-platform/opencti-front/lang/back/ko.json
index 816ca35c4723..bbc321d3c5db 100644
--- a/opencti-platform/opencti-front/lang/back/ko.json
+++ b/opencti-platform/opencti-front/lang/back/ko.json
@@ -108,6 +108,10 @@
"Card number": "카드 번호",
"Carousel order": "캐러셀 순서",
"Case template": "사례 템플릿",
+ "Catalog Contract content hash": "카탈로그 계약 내용 해시",
+ "Catalog Contract ID": "카탈로그 계약 ID",
+ "Catalog ID": "카탈로그 ID",
+ "Catalog product version": "카탈로그 제품 버전",
"Category": "카테고리",
"CC": "CC",
"Certifiate policies": "인증서 정책",
@@ -130,11 +134,13 @@
"Confidence level": "신뢰 수준",
"Confidentiality impact": "기밀성 영향",
"Configuration": "구성",
+ "Configuration schema": "구성 스키마",
"Configuration version": "구성 버전",
"Connector catalog": "커넥터 카탈로그",
"Connector ID": "커넥터 ID",
"Connector information": "커넥터 정보",
"Connector manager": "커넥터 관리자",
+ "Connector manager contract": "커넥터 관리자 계약",
"Connector manager current status": "커넥터 관리자 현재 상태",
"Connector manager image": "커넥터 관리자 이미지",
"Connector manager requested status": "커넥터 관리자 요청 상태",
@@ -143,10 +149,12 @@
"Connector state": "커넥터 상태",
"Connector trigger filters": "커넥터 트리거 필터",
"Connector type": "커넥터 유형",
+ "Connector upgrade strategy": "커넥터 업그레이드 전략",
"Connector user id": "커넥터 사용자 ID",
"Connectors": "커넥터",
"Consent confirm text": "동의 확인 텍스트",
"Consent message": "동의 메시지",
+ "Contact": "연락처",
"Contact information": "연락처 정보",
"Contains": "포함",
"Contains observable": "관찰 가능 항목 포함",
@@ -160,6 +168,7 @@
"Context": "컨텍스트",
"Context data": "컨텍스트 데이터",
"Contextual only": "컨텍스트 전용",
+ "Contract version": "계약 버전",
"Copy confidence level to OpenCTI scores for indicators": "지표에 대한 신뢰 수준을 OpenCTI 점수로 복사합니다",
"Copy OpenCTI scores to confidence level for indicators": "지표의 신뢰 수준에 OpenCTI 점수를 복사합니다",
"Count": "개수",
@@ -562,12 +571,14 @@
"Last score evolution": "마지막 점수 진화",
"Last seen": "마지막 목격",
"Last update": "마지막 업데이트",
+ "Last verified date": "최종 검증 날짜",
"Lastname": "성",
"Latest containers": "최신 컨테이너",
"Latest created relationships": "최근에 생성된 관계",
"Latitude": "위도",
"Layers": "레이어",
"LdapStrategy": "LDAP 전략",
+ "License type": "라이선스 유형",
"Lifetime": "수명",
"Light accent": "밝은 강조",
"Light background": "밝은 배경",
@@ -592,6 +603,7 @@
"Locations propagation in reports": "보고서 내 위치 전파",
"Log sources": "로그 소스",
"Login message": "로그인 메시지",
+ "Logo URI in file storage": "파일 저장소의 로고 URI",
"Logout remote": "원격 로그아웃",
"Longitude": "경도",
"LZJD": "LZJD",
@@ -607,8 +619,11 @@
"Manager contracts": "관리자 컨트랙트",
"Manager ID": "관리자 ID",
"Manager running": "관리자 실행 중",
+ "Manager supported": "지원되는 관리자",
"Mandatory": "필수",
"Manifest": "매니페스트",
+ "Manifest schema version": "매니페스트 스키마 버전",
+ "Manifest version": "매니페스트 버전",
"Mappings": "매핑",
"Marital status": "결혼 상태",
"Marked for deletion at": "다음 위치에서 삭제 대상으로 표시됨",
@@ -626,6 +641,7 @@
"Match Pir with source of relationship": "Pir와 관계 소스 일치",
"Max concurrent sessions (0 equals no maximum)": "최대 동시 세션(0은 최대값 없음)",
"Max Confidence": "최대 신뢰도",
+ "Max confidence level": "최대 신뢰 수준",
"Max policy length": "최대 정책 길이",
"Max shareable markings": "최대 공유 가능 마킹",
"Max value": "최대값",
@@ -807,6 +823,7 @@
"Platforms": "플랫폼",
"Playbook definition": "플레이북 정의",
"Playbook running": "플레이북 실행 중",
+ "Playbook supported": "지원되는 플레이북",
"Policy constraints": "정책 제약 조건",
"Policy mappings": "정책 매핑",
"Port": "포트",
@@ -914,6 +931,7 @@
"Result": "결과",
"Result name": "결과 이름",
"Retention manager": "리텐션 관리자",
+ "Revision": "개정판",
"Revoke score": "점수 취소",
"Revoked": "취소됨",
"RIR": "RIR",
@@ -959,6 +977,7 @@
"SHA3-256": "SHA3-256",
"SHA3-512": "SHA3-512",
"Shared with": "공유됨",
+ "Short description": "간략한 설명",
"Show submenu icons": "서브메뉴 아이콘 표시",
"Sightings of observables via observed data": "관측 데이터를 통한 관측 가능 항목 발견",
"Sightings propagation from indicator": "인디케이터를 통한 관측값 전파",
@@ -970,12 +989,15 @@
"SMTP configuration": "SMTP 구성",
"SMTP enabled": "SMTP 사용",
"Software Vulnerability propagation to Infrastructure": "인프라로 전파되는 소프트웨어 취약점",
+ "Solution categories": "솔루션 카테고리",
"Sophistication": "정교함",
"Source": "출처",
+ "Source code": "소스 코드",
"Source connector": "출처 커넥터",
"Source entity": "출처 엔터티",
"Source name": "출처 이름",
"Source type": "출처 유형",
+ "Source URI": "소스 URI",
"SRC": "SRC",
"SRC byte count": "SRC 바이트 수",
"SRC packets": "SRC 패킷",
@@ -1015,6 +1037,8 @@
"Subject public key exponent": "주제 공개 키 지수",
"Subject public key modulus": "주제 공개 키 모듈러스",
"Submission date": "제출 날짜",
+ "Subscription link": "구독 링크",
+ "Support version": "지원 버전",
"SWID": "SWID",
"Sync workflow statuses by name": "이름별로 워크플로 상태 동기화",
"Synchronized": "동기화됨",
@@ -1104,6 +1128,7 @@
"URL": "URL",
"Usage propagation of parent techniques": "상위 기술의 사용 전파",
"Usage propagation via attribution": "어트리뷰션을 통한 사용량 전파",
+ "Use cases": "사용 사례",
"Use DB configuration": "DB 구성 사용",
"Use SSL": "SSL 사용",
"User": "사용자",
@@ -1136,6 +1161,7 @@
"Variables": "변수",
"Vendor": "공급업체",
"verb": "동사",
+ "Verified": "검증됨",
"Verify SSL certificate": "SSL 인증서 확인",
"Version": "버전",
"Version History": "버전 기록",
@@ -1181,4 +1207,5 @@
"XTM One intent": "XTM One 의도",
"XTM One registration manager": "XTM One 등록 관리자",
"XTM1 CGU acceptance status": "XTM1 CGU 승인 상태"
-}
\ No newline at end of file
+}
+
diff --git a/opencti-platform/opencti-front/lang/back/ru.json b/opencti-platform/opencti-front/lang/back/ru.json
index dde2ed666f5a..721e4a465d7f 100644
--- a/opencti-platform/opencti-front/lang/back/ru.json
+++ b/opencti-platform/opencti-front/lang/back/ru.json
@@ -108,6 +108,10 @@
"Card number": "Номер карты",
"Carousel order": "Порядок в карусели",
"Case template": "Шаблон кейса",
+ "Catalog Contract content hash": "Хеш содержимого контракта каталога",
+ "Catalog Contract ID": "Идентификатор контракта каталога",
+ "Catalog ID": "Идентификатор каталога",
+ "Catalog product version": "Версия продукта в каталоге",
"Category": "Категория",
"CC": "CC",
"Certifiate policies": "Политики сертификации",
@@ -130,11 +134,13 @@
"Confidence level": "Уровень доверия",
"Confidentiality impact": "Влияние на конфиденциальность",
"Configuration": "Конфигурация",
+ "Configuration schema": "Схема конфигурации",
"Configuration version": "Версия конфигурации",
"Connector catalog": "Каталог коннекторов",
"Connector ID": "Идентификатор коннектора",
"Connector information": "Информация о коннекторе",
"Connector manager": "Менеджер коннектора",
+ "Connector manager contract": "Контракт диспетчера коннекторов",
"Connector manager current status": "Текущее состояние менеджера коннектора",
"Connector manager image": "Изображение менеджера коннекторов",
"Connector manager requested status": "Запрошенное состояние менеджера коннектора",
@@ -143,10 +149,12 @@
"Connector state": "Состояние коннектора",
"Connector trigger filters": "Триггерные фильтры коннектора",
"Connector type": "Тип коннектора",
+ "Connector upgrade strategy": "Стратегия обновления коннекторов",
"Connector user id": "Идентификатор пользователя коннектора",
"Connectors": "Коннекторы",
"Consent confirm text": "Согласие подтвердить текст",
"Consent message": "Сообщение о согласии",
+ "Contact": "Контактные данные",
"Contact information": "Контактная информация",
"Contains": "Содержит",
"Contains observable": "Содержит наблюдаемые",
@@ -160,6 +168,7 @@
"Context": "Контекст",
"Context data": "Контекстные данные",
"Contextual only": "Только контекст",
+ "Contract version": "Версия контракта",
"Copy confidence level to OpenCTI scores for indicators": "Копирование уровня доверия к показателям OpenCTI",
"Copy OpenCTI scores to confidence level for indicators": "Скопируйте оценки OpenCTI в уровень доверия для индикаторов",
"Count": "Количество",
@@ -562,12 +571,14 @@
"Last score evolution": "Эволюция последней оценки",
"Last seen": "Последний раз видели",
"Last update": "Последнее обновление",
+ "Last verified date": "Дата последней проверки",
"Lastname": "Фамилия",
"Latest containers": "Последние контейнеры",
"Latest created relationships": "Последние созданные отношения",
"Latitude": "Широта",
"Layers": "Слои",
"LdapStrategy": "LdapStrategy",
+ "License type": "Тип лицензии",
"Lifetime": "Пожизненный",
"Light accent": "Светлый акцент",
"Light background": "Светлый фон",
@@ -592,6 +603,7 @@
"Locations propagation in reports": "Распространение местоположений в отчетах",
"Log sources": "Источники журналов",
"Login message": "Сообщение о входе в систему",
+ "Logo URI in file storage": "URI логотипа в хранилище файлов",
"Logout remote": "Удаленный выход из системы",
"Longitude": "Долгота",
"LZJD": "LZJD",
@@ -607,8 +619,11 @@
"Manager contracts": "Договоры с менеджерами",
"Manager ID": "Идентификатор менеджера",
"Manager running": "Менеджер работает",
+ "Manager supported": "Поддерживаемый менеджер",
"Mandatory": "Обязательное поле",
"Manifest": "Манифест",
+ "Manifest schema version": "Версия схемы манифеста",
+ "Manifest version": "Версия манифеста",
"Mappings": "Отображения",
"Marital status": "Семейное положение",
"Marked for deletion at": "Отмечено для удаления в",
@@ -626,6 +641,7 @@
"Match Pir with source of relationship": "Сопоставьте Пир с источником отношений",
"Max concurrent sessions (0 equals no maximum)": "Максимальное количество одновременных сеансов (0 означает отсутствие максимума)",
"Max Confidence": "Максимальная уверенность",
+ "Max confidence level": "Максимальный уровень достоверности",
"Max policy length": "Максимальная длина полиса",
"Max shareable markings": "Максимально разделяемые метки",
"Max value": "Максимальное значение",
@@ -807,6 +823,7 @@
"Platforms": "Платформы",
"Playbook definition": "Определение игровой книги",
"Playbook running": "Работа с игровыми книгами",
+ "Playbook supported": "Поддерживаемые руководства",
"Policy constraints": "Политические ограничения",
"Policy mappings": "Сопоставление политик",
"Port": "Порт",
@@ -914,6 +931,7 @@
"Result": "Результат",
"Result name": "Название результата",
"Retention manager": "Менеджер по удержанию персонала",
+ "Revision": "Ревизия",
"Revoke score": "Отменить оценку",
"Revoked": "Отозвано",
"RIR": "RIR",
@@ -959,6 +977,7 @@
"SHA3-256": "SHA3-256",
"SHA3-512": "SHA3-512",
"Shared with": "Разделена с",
+ "Short description": "Краткое описание",
"Show submenu icons": "Показать значки подменю",
"Sightings of observables via observed data": "Наблюдения наблюдаемых через наблюдаемые данные",
"Sightings propagation from indicator": "Распространение наблюдений через индикатор",
@@ -970,12 +989,15 @@
"SMTP configuration": "Конфигурация SMTP",
"SMTP enabled": "SMTP включен",
"Software Vulnerability propagation to Infrastructure": "Распространение уязвимостей программного обеспечения на инфраструктуру",
+ "Solution categories": "Категории решений",
"Sophistication": "Изысканность",
"Source": "Источник",
+ "Source code": "Исходный код",
"Source connector": "Исходный коннектор",
"Source entity": "Источник",
"Source name": "Название источника",
"Source type": "Тип источника",
+ "Source URI": "URI источника",
"SRC": "SRC",
"SRC byte count": "Счетчик байтов SRC",
"SRC packets": "Пакеты SRC",
@@ -1015,6 +1037,8 @@
"Subject public key exponent": "Экспонента открытого ключа субъекта",
"Subject public key modulus": "Модуль открытого ключа субъекта",
"Submission date": "Дата представления",
+ "Subscription link": "Ссылка на подписку",
+ "Support version": "Поддерживаемая версия",
"SWID": "SWID",
"Sync workflow statuses by name": "Синхронизация статусов рабочих процессов по названию",
"Synchronized": "Синхронизированный",
@@ -1104,6 +1128,7 @@
"URL": "URL",
"Usage propagation of parent techniques": "Распространение использования родительских техник",
"Usage propagation via attribution": "Распространение использования через атрибуцию",
+ "Use cases": "Варианты использования",
"Use DB configuration": "Использовать настройки БД",
"Use SSL": "Использовать SSL",
"User": "Пользователь",
@@ -1136,6 +1161,7 @@
"Variables": "Переменные",
"Vendor": "Поставщик",
"verb": "глагол",
+ "Verified": "Проверено",
"Verify SSL certificate": "Проверка сертификата SSL",
"Version": "Версия",
"Version History": "История версий",
@@ -1181,4 +1207,5 @@
"XTM One intent": "Намерение XTM One",
"XTM One registration manager": "Менеджер регистрации XTM One",
"XTM1 CGU acceptance status": "Статус принятия XTM1 CGU"
-}
\ No newline at end of file
+}
+
diff --git a/opencti-platform/opencti-front/lang/back/zh.json b/opencti-platform/opencti-front/lang/back/zh.json
index a1011d4c0fa8..56780f82d937 100644
--- a/opencti-platform/opencti-front/lang/back/zh.json
+++ b/opencti-platform/opencti-front/lang/back/zh.json
@@ -108,6 +108,10 @@
"Card number": "卡号",
"Carousel order": "传送带顺序",
"Case template": "案例模板",
+ "Catalog Contract content hash": "目录合同内容哈希",
+ "Catalog Contract ID": "目录合同 ID",
+ "Catalog ID": "目录 ID",
+ "Catalog product version": "目录产品版本",
"Category": "类别",
"CC": "抄送",
"Certifiate policies": "认证策略",
@@ -130,11 +134,13 @@
"Confidence level": "置信度",
"Confidentiality impact": "保密性影响",
"Configuration": "配置",
+ "Configuration schema": "配置模式",
"Configuration version": "配置版本",
"Connector catalog": "连接器目录",
"Connector ID": "连接器 ID",
"Connector information": "连接器信息",
"Connector manager": "连接器管理器",
+ "Connector manager contract": "连接器管理器合同",
"Connector manager current status": "连接器管理器当前状态",
"Connector manager image": "连接器管理器图像",
"Connector manager requested status": "连接器管理器请求状态",
@@ -143,10 +149,12 @@
"Connector state": "连接器状态",
"Connector trigger filters": "连接器触发滤波器",
"Connector type": "连接器类型",
+ "Connector upgrade strategy": "连接器升级策略",
"Connector user id": "连接器用户 ID",
"Connectors": "连接器",
"Consent confirm text": "同意确认文本",
"Consent message": "同意信息",
+ "Contact": "联系方式",
"Contact information": "联系信息",
"Contains": "包含",
"Contains observable": "包含观测值",
@@ -160,6 +168,7 @@
"Context": "上下文",
"Context data": "上下文数据",
"Contextual only": "仅根据上下文",
+ "Contract version": "合同版本",
"Copy confidence level to OpenCTI scores for indicators": "将置信度复制到指标的 OpenCTI 分数",
"Copy OpenCTI scores to confidence level for indicators": "将 OpenCTI 分数复制到指标的置信度",
"Count": "计数",
@@ -562,12 +571,14 @@
"Last score evolution": "最后分数演变",
"Last seen": "最近出现",
"Last update": "最后更新",
+ "Last verified date": "最后验证日期",
"Lastname": "姓氏",
"Latest containers": "最新容器",
"Latest created relationships": "最近创建的关系",
"Latitude": "纬度",
"Layers": "层级",
"LdapStrategy": "LDAP Strategy",
+ "License type": "许可证类型",
"Lifetime": "生命周期",
"Light accent": "淡色调",
"Light background": "淡色背景",
@@ -592,6 +603,7 @@
"Locations propagation in reports": "报告中的位置传播",
"Log sources": "日志来源",
"Login message": "登录信息",
+ "Logo URI in file storage": "文件存储中的徽标 URI",
"Logout remote": "远程注销",
"Longitude": "经度",
"LZJD": "LZJD",
@@ -607,8 +619,11 @@
"Manager contracts": "管理器合同",
"Manager ID": "管理者 ID",
"Manager running": "管理器运行",
+ "Manager supported": "支持的管理器",
"Mandatory": "必填",
"Manifest": "内容",
+ "Manifest schema version": "清单架构版本",
+ "Manifest version": "清单版本",
"Mappings": "映射",
"Marital status": "婚姻状况",
"Marked for deletion at": "已标记为删除,位置在",
@@ -626,6 +641,7 @@
"Match Pir with source of relationship": "将 Pir 与关系源匹配",
"Max concurrent sessions (0 equals no maximum)": "最大并发会话数(0 表示无最大值)",
"Max Confidence": "最大置信度",
+ "Max confidence level": "最大置信度",
"Max policy length": "最多长度要求",
"Max shareable markings": "最大可共享标记",
"Max value": "最大值",
@@ -807,6 +823,7 @@
"Platforms": "平台",
"Playbook definition": "游戏本定义",
"Playbook running": "运行游戏本",
+ "Playbook supported": "支持的剧本",
"Policy constraints": "策略约束",
"Policy mappings": "策略映射",
"Port": "端口",
@@ -914,6 +931,7 @@
"Result": "结果",
"Result name": "结果名称",
"Retention manager": "留用经理",
+ "Revision": "修订版",
"Revoke score": "撤销得分",
"Revoked": "撤销",
"RIR": "RIR",
@@ -959,6 +977,7 @@
"SHA3-256": "SHA3-256",
"SHA3-512": "SHA3-512",
"Shared with": "共享对象",
+ "Short description": "简要描述",
"Show submenu icons": "显示子菜单图标",
"Sightings of observables via observed data": "通过观察数据看到可观察数据",
"Sightings propagation from indicator": "从指标传播观察结果",
@@ -970,12 +989,15 @@
"SMTP configuration": "SMTP配置",
"SMTP enabled": "已启用 SMTP",
"Software Vulnerability propagation to Infrastructure": "软件漏洞向基础设施的传播",
+ "Solution categories": "解决方案类别",
"Sophistication": "复杂性",
"Source": "来源",
+ "Source code": "源代码",
"Source connector": "源连接器",
"Source entity": "来源实体",
"Source name": "源名称",
"Source type": "源类型",
+ "Source URI": "源代码 URI",
"SRC": "SRC",
"SRC byte count": "SRC 字节数",
"SRC packets": "SRC 数据包",
@@ -1015,6 +1037,8 @@
"Subject public key exponent": "主体公钥指数",
"Subject public key modulus": "主体公钥模数",
"Submission date": "提交日期",
+ "Subscription link": "订阅链接",
+ "Support version": "支持版本",
"SWID": "SWID",
"Sync workflow statuses by name": "按名称同步工作流状态",
"Synchronized": "同步",
@@ -1104,6 +1128,7 @@
"URL": "URL",
"Usage propagation of parent techniques": "父技术的使用传播",
"Usage propagation via attribution": "通过归属进行使用传播",
+ "Use cases": "用例",
"Use DB configuration": "使用数据库配置",
"Use SSL": "使用 SSL",
"User": "用户",
@@ -1136,6 +1161,7 @@
"Variables": "变量",
"Vendor": "供应商",
"verb": "动词",
+ "Verified": "已验证",
"Verify SSL certificate": "验证 SSL 证书",
"Version": "版本",
"Version History": "版本历史",
@@ -1181,4 +1207,5 @@
"XTM One intent": "XTM 一个意图",
"XTM One registration manager": "XTM One 注册管理器",
"XTM1 CGU acceptance status": "XTM1 CGU 验收状态"
-}
\ No newline at end of file
+}
+
diff --git a/opencti-platform/opencti-front/lang/front/de.json b/opencti-platform/opencti-front/lang/front/de.json
index 6456ef123f42..28a38a584d80 100644
--- a/opencti-platform/opencti-front/lang/front/de.json
+++ b/opencti-platform/opencti-front/lang/front/de.json
@@ -639,6 +639,7 @@
"Cases": "Fälle",
"Cases & Analyses": "Fälle & Analysen",
"CaseTemplate": "CaseTemplate",
+ "CATALOG_MANAGER": "Katalogmanager",
"Category": "Kategorie",
"category": "Kategorie",
"Center latitude": "Mittlere geographische Breite",
diff --git a/opencti-platform/opencti-front/lang/front/en.json b/opencti-platform/opencti-front/lang/front/en.json
index 82ee7bfaa1b9..8615ef712106 100644
--- a/opencti-platform/opencti-front/lang/front/en.json
+++ b/opencti-platform/opencti-front/lang/front/en.json
@@ -639,6 +639,7 @@
"Cases": "Cases",
"Cases & Analyses": "Cases & Analyses",
"CaseTemplate": "CaseTemplate",
+ "CATALOG_MANAGER": "Catalog manager",
"Category": "Category",
"category": "Category",
"Center latitude": "Center latitude",
diff --git a/opencti-platform/opencti-front/lang/front/es.json b/opencti-platform/opencti-front/lang/front/es.json
index fdc3db47522a..30ac9dabf0a4 100644
--- a/opencti-platform/opencti-front/lang/front/es.json
+++ b/opencti-platform/opencti-front/lang/front/es.json
@@ -639,6 +639,7 @@
"Cases": "Casos",
"Cases & Analyses": "Casos y Análisis",
"CaseTemplate": "CaseTemplate",
+ "CATALOG_MANAGER": "Gestor del catálogo",
"Category": "Catégorie",
"category": "Categoría",
"Center latitude": "Latitud central",
diff --git a/opencti-platform/opencti-front/lang/front/fr.json b/opencti-platform/opencti-front/lang/front/fr.json
index 9922f5673617..cb48ad9eeddc 100644
--- a/opencti-platform/opencti-front/lang/front/fr.json
+++ b/opencti-platform/opencti-front/lang/front/fr.json
@@ -639,6 +639,7 @@
"Cases": "Cases",
"Cases & Analyses": "Cases et analyse",
"CaseTemplate": "Modèle de cas",
+ "CATALOG_MANAGER": "Manager du catalogue",
"Category": "Catégorie",
"category": "Catégorie",
"Center latitude": "Latitude centrale",
diff --git a/opencti-platform/opencti-front/lang/front/it.json b/opencti-platform/opencti-front/lang/front/it.json
index fbb4c8409053..0afd9f5b8e86 100644
--- a/opencti-platform/opencti-front/lang/front/it.json
+++ b/opencti-platform/opencti-front/lang/front/it.json
@@ -639,6 +639,7 @@
"Cases": "Casi",
"Cases & Analyses": "Casi & Analisi",
"CaseTemplate": "Modello di caso",
+ "CATALOG_MANAGER": "Gestione del catalogo",
"Category": "Categoria",
"category": "categoria",
"Center latitude": "Latitudine centrale",
diff --git a/opencti-platform/opencti-front/lang/front/ja.json b/opencti-platform/opencti-front/lang/front/ja.json
index 3c24758d64b8..3271d829325c 100644
--- a/opencti-platform/opencti-front/lang/front/ja.json
+++ b/opencti-platform/opencti-front/lang/front/ja.json
@@ -639,6 +639,7 @@
"Cases": "事例",
"Cases & Analyses": "事例と分析",
"CaseTemplate": "ケーステンプレート",
+ "CATALOG_MANAGER": "カタログマネージャー",
"Category": "カテゴリー",
"category": "カテゴリー",
"Center latitude": "中心緯度",
diff --git a/opencti-platform/opencti-front/lang/front/ko.json b/opencti-platform/opencti-front/lang/front/ko.json
index 56186620ae2d..869a0396e50d 100644
--- a/opencti-platform/opencti-front/lang/front/ko.json
+++ b/opencti-platform/opencti-front/lang/front/ko.json
@@ -639,6 +639,7 @@
"Cases": "사례",
"Cases & Analyses": "사례 및 분석",
"CaseTemplate": "케이스 템플릿",
+ "CATALOG_MANAGER": "카탈로그 관리자",
"Category": "카테고리",
"category": "카테고리",
"Center latitude": "중심 위도",
diff --git a/opencti-platform/opencti-front/lang/front/ru.json b/opencti-platform/opencti-front/lang/front/ru.json
index 79b98d6c202c..a4664f1f96a1 100644
--- a/opencti-platform/opencti-front/lang/front/ru.json
+++ b/opencti-platform/opencti-front/lang/front/ru.json
@@ -639,6 +639,7 @@
"Cases": "Кейсы",
"Cases & Analyses": "Кейсы и анализы",
"CaseTemplate": "CaseTemplate",
+ "CATALOG_MANAGER": "Менеджер каталога",
"Category": "Категория",
"category": "категория",
"Center latitude": "Центральная широта",
diff --git a/opencti-platform/opencti-front/lang/front/zh.json b/opencti-platform/opencti-front/lang/front/zh.json
index f92dff994ee7..1205a233f77d 100644
--- a/opencti-platform/opencti-front/lang/front/zh.json
+++ b/opencti-platform/opencti-front/lang/front/zh.json
@@ -639,6 +639,7 @@
"Cases": "案例",
"Cases & Analyses": "案例与分析",
"CaseTemplate": "案例模板",
+ "CATALOG_MANAGER": "目录管理器",
"Category": "类别",
"category": "类别",
"Center latitude": "中心纬度",
diff --git a/opencti-platform/opencti-front/src/private/components/integrations/Integrations.tsx b/opencti-platform/opencti-front/src/private/components/integrations/Integrations.tsx
index b67a44642ea2..2d484011e5df 100644
--- a/opencti-platform/opencti-front/src/private/components/integrations/Integrations.tsx
+++ b/opencti-platform/opencti-front/src/private/components/integrations/Integrations.tsx
@@ -1,5 +1,5 @@
-import React, { Suspense, useEffect, useMemo } from 'react';
-import { Link, Navigate, useParams } from 'react-router';
+import React, { Suspense, useCallback, useEffect, useMemo } from 'react';
+import { Link, Navigate, useParams } from 'react-router';
import { Box, Stack, Typography } from '@mui/material';
import { alpha, useTheme } from '@mui/material/styles';
import { useQueryLoader } from 'react-relay';
@@ -42,6 +42,7 @@ export interface IntegrationsData {
deploymentData: IngestionConnectorsQuery['response'] | null;
feedsData: IngestionFeedsData | null;
formsData: IngestionFeedsFormsData | null;
+ refetchCatalogs: () => void;
refetchFeeds: () => void;
refetchForms: () => void;
}
@@ -78,16 +79,21 @@ const IntegrationsDataProvider = ({ children }: IntegrationsDataProviderProps) =
// store-and-network: the previous data keeps rendering while the refresh
// happens in the background, so refetching never suspends the whole page.
- const refetchFeeds = () => {
+ const refetchFeeds = useCallback(() => {
if (isIngestionReader) {
loadFeeds({ first: FEEDS_PAGE_SIZE }, { fetchPolicy: 'store-and-network' });
}
- };
- const refetchForms = () => {
+ }, [isIngestionReader, loadFeeds]);
+ const refetchForms = useCallback(() => {
if (isFormReader) {
loadForms({ first: FEEDS_PAGE_SIZE }, { fetchPolicy: 'store-and-network' });
}
- };
+ }, [isFormReader, loadForms]);
+ const refetchCatalogs = useCallback(() => {
+ if (isConnectorReader) {
+ loadCatalogs({}, { fetchPolicy: 'store-and-network' });
+ }
+ }, [isConnectorReader, loadCatalogs]);
const renderWithForms = (
catalogsData: IngestionConnectorsCatalogsQuery['response'] | null,
@@ -97,11 +103,27 @@ const IntegrationsDataProvider = ({ children }: IntegrationsDataProviderProps) =
if (formsRef) {
return (
- {({ data: formsData }) => children({ catalogsData, deploymentData, feedsData, formsData, refetchFeeds, refetchForms })}
+ {({ data: formsData }) => children({
+ catalogsData,
+ deploymentData,
+ feedsData,
+ formsData,
+ refetchCatalogs,
+ refetchFeeds,
+ refetchForms,
+ })}
);
}
- return children({ catalogsData, deploymentData, feedsData, formsData: null, refetchFeeds, refetchForms });
+ return children({
+ catalogsData,
+ deploymentData,
+ feedsData,
+ formsData: null,
+ refetchCatalogs,
+ refetchFeeds,
+ refetchForms,
+ });
};
const renderWithFeeds = (
diff --git a/opencti-platform/opencti-front/src/private/components/integrations/available/IntegrationsAvailable.tsx b/opencti-platform/opencti-front/src/private/components/integrations/available/IntegrationsAvailable.tsx
index 5cd197461fcd..1397f8fb2935 100644
--- a/opencti-platform/opencti-front/src/private/components/integrations/available/IntegrationsAvailable.tsx
+++ b/opencti-platform/opencti-front/src/private/components/integrations/available/IntegrationsAvailable.tsx
@@ -10,6 +10,7 @@ import IngestionCatalogCard from '@components/integrations/catalog/IngestionCata
import IngestionCatalogConnectorCreation from '@components/integrations/catalog/IngestionCatalogConnectorCreation';
import IngestionCatalogFacetSidebar from '@components/integrations/catalog/IngestionCatalogFacetSidebar';
import useConnectorDeployDialog from '@components/integrations/catalog/hooks/useConnectorDeployDialog';
+import useCatalogPolling from '@components/integrations/catalog/hooks/useCatalogPolling';
import useIngestionCatalogFilters, {
BUILT_IN_SECTION_KEY,
BuiltInCatalogInput,
@@ -46,7 +47,20 @@ const IntegrationsAvailable = ({ data }: IntegrationsAvailableProps) => {
const theme = useTheme();
const [searchParams] = useSearchParams();
const { hasActiveManagers } = useConnectorManagerStatus();
- const { catalogsData, deploymentData, feedsData, formsData, refetchFeeds, refetchForms } = data;
+ const {
+ catalogsData,
+ deploymentData,
+ feedsData,
+ formsData,
+ refetchCatalogs,
+ refetchFeeds,
+ refetchForms,
+ } = data;
+
+ useCatalogPolling({
+ enabled: catalogsData !== null,
+ onCatalogRevisionsChanged: refetchCatalogs,
+ });
const { catalogState, handleOpenDeployDialog, handleCloseDeployDialog, handleCreate } = useConnectorDeployDialog();
const [builtInCreationKind, setBuiltInCreationKind] = useState(null);
diff --git a/opencti-platform/opencti-front/src/private/components/integrations/catalog/IngestionConnectorsCatalog.tsx b/opencti-platform/opencti-front/src/private/components/integrations/catalog/IngestionConnectorsCatalog.tsx
index 82261c51e4f3..7fc8f1a48b7a 100644
--- a/opencti-platform/opencti-front/src/private/components/integrations/catalog/IngestionConnectorsCatalog.tsx
+++ b/opencti-platform/opencti-front/src/private/components/integrations/catalog/IngestionConnectorsCatalog.tsx
@@ -3,6 +3,15 @@ import type { PreloadedQuery } from 'react-relay';
import React from 'react';
import { IngestionConnectorsCatalogsQuery } from '@components/integrations/catalog/__generated__/IngestionConnectorsCatalogsQuery.graphql';
+export const ingestionConnectorsCatalogRevisionsQuery = graphql`
+ query IngestionConnectorsCatalogRevisionsQuery {
+ catalogsRevisions {
+ catalog_id
+ revision
+ }
+ }
+`;
+
export const ingestionConnectorsCatalogsQuery = graphql`
query IngestionConnectorsCatalogsQuery {
catalogs {
diff --git a/opencti-platform/opencti-front/src/private/components/integrations/catalog/catalog-constants.ts b/opencti-platform/opencti-front/src/private/components/integrations/catalog/catalog-constants.ts
new file mode 100644
index 000000000000..9b441047a314
--- /dev/null
+++ b/opencti-platform/opencti-front/src/private/components/integrations/catalog/catalog-constants.ts
@@ -0,0 +1 @@
+export const CATALOG_POLLING_INTERVAL_MS = 60000;
diff --git a/opencti-platform/opencti-front/src/private/components/integrations/catalog/hooks/useCatalogPolling.test.ts b/opencti-platform/opencti-front/src/private/components/integrations/catalog/hooks/useCatalogPolling.test.ts
new file mode 100644
index 000000000000..07dd1a4b4d9c
--- /dev/null
+++ b/opencti-platform/opencti-front/src/private/components/integrations/catalog/hooks/useCatalogPolling.test.ts
@@ -0,0 +1,181 @@
+import { act, renderHook } from '@testing-library/react';
+import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
+import { CATALOG_POLLING_INTERVAL_MS } from '../catalog-constants';
+import useCatalogPolling from './useCatalogPolling';
+
+const mocks = vi.hoisted(() => ({
+ fetchQuery: vi.fn(),
+}));
+
+vi.mock('../../../../../relay/environment', () => ({
+ fetchQuery: mocks.fetchQuery,
+}));
+
+type RevisionsPayload = {
+ catalogsRevisions: Array<{ catalog_id: string; revision: string | null }>;
+};
+
+const setDocumentHidden = (hidden: boolean) => {
+ Object.defineProperty(document, 'hidden', {
+ configurable: true,
+ get: () => hidden,
+ });
+};
+
+const mockFetchSequence = (steps: Array) => {
+ let index = 0;
+ mocks.fetchQuery.mockImplementation(() => ({
+ toPromise: () => {
+ const current = steps[Math.min(index, steps.length - 1)];
+ index += 1;
+ if (current instanceof Error) {
+ return Promise.reject(current);
+ }
+ return Promise.resolve(current);
+ },
+ }));
+};
+
+const flushPromises = async () => {
+ await Promise.resolve();
+ await Promise.resolve();
+};
+
+describe('useCatalogPolling', () => {
+ beforeEach(() => {
+ vi.useFakeTimers();
+ vi.clearAllMocks();
+ setDocumentHidden(false);
+ });
+
+ afterEach(() => {
+ vi.useRealTimers();
+ vi.restoreAllMocks();
+ });
+
+ it('seeds baseline without triggering a full catalogs refresh', async () => {
+ mockFetchSequence([
+ { catalogsRevisions: [{ catalog_id: 'catalog-1', revision: 'rev-1' }] },
+ { catalogsRevisions: [{ catalog_id: 'catalog-1', revision: 'rev-1' }] },
+ ]);
+ const onChanged = vi.fn();
+
+ renderHook(() => useCatalogPolling({ enabled: true, onCatalogRevisionsChanged: onChanged }));
+ await act(async () => {
+ await flushPromises();
+ });
+
+ expect(mocks.fetchQuery).toHaveBeenCalledWith(
+ expect.anything(),
+ {},
+ { fetchPolicy: 'network-only' },
+ );
+
+ expect(onChanged).not.toHaveBeenCalled();
+
+ await act(async () => {
+ vi.advanceTimersByTime(CATALOG_POLLING_INTERVAL_MS);
+ await flushPromises();
+ });
+
+ expect(onChanged).not.toHaveBeenCalled();
+ });
+
+ it('refreshes catalogs when a revision changes and updates baseline', async () => {
+ mockFetchSequence([
+ { catalogsRevisions: [{ catalog_id: 'catalog-1', revision: 'rev-1' }] },
+ { catalogsRevisions: [{ catalog_id: 'catalog-1', revision: 'rev-2' }] },
+ { catalogsRevisions: [{ catalog_id: 'catalog-1', revision: 'rev-2' }] },
+ ]);
+ const onChanged = vi.fn();
+
+ renderHook(() => useCatalogPolling({ enabled: true, onCatalogRevisionsChanged: onChanged }));
+ await act(async () => {
+ await flushPromises();
+ });
+
+ await act(async () => {
+ vi.advanceTimersByTime(CATALOG_POLLING_INTERVAL_MS);
+ await flushPromises();
+ });
+ expect(onChanged).toHaveBeenCalledTimes(1);
+
+ await act(async () => {
+ vi.advanceTimersByTime(CATALOG_POLLING_INTERVAL_MS);
+ await flushPromises();
+ });
+ expect(onChanged).toHaveBeenCalledTimes(1);
+ });
+
+ it('retries after a failed seed without triggering a refresh', async () => {
+ mockFetchSequence([
+ new Error('network down'),
+ { catalogsRevisions: [{ catalog_id: 'catalog-1', revision: 'rev-1' }] },
+ { catalogsRevisions: [{ catalog_id: 'catalog-1', revision: 'rev-1' }] },
+ ]);
+ const onChanged = vi.fn();
+
+ renderHook(() => useCatalogPolling({ enabled: true, onCatalogRevisionsChanged: onChanged }));
+ await act(async () => {
+ await flushPromises();
+ });
+
+ await act(async () => {
+ vi.advanceTimersByTime(CATALOG_POLLING_INTERVAL_MS);
+ await flushPromises();
+ });
+
+ expect(onChanged).not.toHaveBeenCalled();
+ expect(mocks.fetchQuery).toHaveBeenCalledTimes(2);
+ });
+
+ it('pauses polling while hidden and performs an immediate check when visible again', async () => {
+ mockFetchSequence([
+ { catalogsRevisions: [{ catalog_id: 'catalog-1', revision: 'rev-1' }] },
+ { catalogsRevisions: [{ catalog_id: 'catalog-1', revision: 'rev-1' }] },
+ { catalogsRevisions: [{ catalog_id: 'catalog-1', revision: 'rev-1' }] },
+ ]);
+
+ renderHook(() => useCatalogPolling({ enabled: true, onCatalogRevisionsChanged: vi.fn() }));
+ await act(async () => {
+ await flushPromises();
+ });
+ expect(mocks.fetchQuery).toHaveBeenCalledTimes(1);
+
+ await act(async () => {
+ setDocumentHidden(true);
+ document.dispatchEvent(new Event('visibilitychange'));
+ vi.advanceTimersByTime(CATALOG_POLLING_INTERVAL_MS * 2);
+ await flushPromises();
+ });
+ expect(mocks.fetchQuery).toHaveBeenCalledTimes(1);
+
+ await act(async () => {
+ setDocumentHidden(false);
+ document.dispatchEvent(new Event('visibilitychange'));
+ await flushPromises();
+ });
+ expect(mocks.fetchQuery).toHaveBeenCalledTimes(2);
+ });
+
+ it('stops polling on unmount', async () => {
+ mockFetchSequence([
+ { catalogsRevisions: [{ catalog_id: 'catalog-1', revision: 'rev-1' }] },
+ { catalogsRevisions: [{ catalog_id: 'catalog-1', revision: 'rev-1' }] },
+ ]);
+
+ const { unmount } = renderHook(() => useCatalogPolling({ enabled: true, onCatalogRevisionsChanged: vi.fn() }));
+ await act(async () => {
+ await flushPromises();
+ });
+
+ unmount();
+
+ await act(async () => {
+ vi.advanceTimersByTime(CATALOG_POLLING_INTERVAL_MS * 2);
+ await flushPromises();
+ });
+
+ expect(mocks.fetchQuery).toHaveBeenCalledTimes(1);
+ });
+});
diff --git a/opencti-platform/opencti-front/src/private/components/integrations/catalog/hooks/useCatalogPolling.ts b/opencti-platform/opencti-front/src/private/components/integrations/catalog/hooks/useCatalogPolling.ts
new file mode 100644
index 000000000000..012fd9b78ecc
--- /dev/null
+++ b/opencti-platform/opencti-front/src/private/components/integrations/catalog/hooks/useCatalogPolling.ts
@@ -0,0 +1,121 @@
+import { useEffect, useRef } from 'react';
+import { fetchQuery } from '../../../../../relay/environment';
+import { ingestionConnectorsCatalogRevisionsQuery } from '../IngestionConnectorsCatalog';
+import { CATALOG_POLLING_INTERVAL_MS } from '../catalog-constants';
+import type { IngestionConnectorsCatalogRevisionsQuery } from '../__generated__/IngestionConnectorsCatalogRevisionsQuery.graphql';
+
+type UseCatalogPollingProps = {
+ enabled: boolean;
+ onCatalogRevisionsChanged: () => Promise | void;
+};
+
+type RevisionByCatalogId = Map;
+
+const toRevisionMap = (
+ revisions: ReadonlyArray<{ catalog_id: string; revision: string | null | undefined }> | null | undefined,
+): RevisionByCatalogId => {
+ return new Map((revisions ?? []).map((entry) => [entry.catalog_id, entry.revision ?? null]));
+};
+
+const haveRevisionsChanged = (baseline: RevisionByCatalogId, next: RevisionByCatalogId): boolean => {
+ if (baseline.size !== next.size) {
+ return true;
+ }
+ for (const [catalogId, revision] of next) {
+ if (!baseline.has(catalogId) || baseline.get(catalogId) !== revision) {
+ return true;
+ }
+ }
+ return false;
+};
+
+const useCatalogPolling = ({ enabled, onCatalogRevisionsChanged }: UseCatalogPollingProps) => {
+ const baselineRef = useRef(null);
+ const timeoutRef = useRef | null>(null);
+ const isUnmountedRef = useRef(false);
+ const isCheckInFlightRef = useRef(false);
+ const wasPausedRef = useRef(false);
+
+ useEffect(() => {
+ if (!enabled) {
+ return undefined;
+ }
+
+ isUnmountedRef.current = false;
+
+ const clearScheduledCheck = () => {
+ if (timeoutRef.current) {
+ clearTimeout(timeoutRef.current);
+ timeoutRef.current = null;
+ }
+ };
+
+ const scheduleNextCheck = () => {
+ if (isUnmountedRef.current || document.hidden) {
+ return;
+ }
+ clearScheduledCheck();
+ timeoutRef.current = setTimeout(() => {
+ void checkCatalogRevisions();
+ }, CATALOG_POLLING_INTERVAL_MS);
+ };
+
+ const checkCatalogRevisions = async () => {
+ if (isCheckInFlightRef.current || isUnmountedRef.current || document.hidden) {
+ return;
+ }
+ isCheckInFlightRef.current = true;
+ try {
+ const result = await fetchQuery(
+ ingestionConnectorsCatalogRevisionsQuery,
+ {},
+ { fetchPolicy: 'network-only' },
+ ).toPromise().catch(() => null);
+
+ if (!result) {
+ return;
+ }
+
+ const nextBaseline = toRevisionMap(result.catalogsRevisions ?? []);
+
+ if (!baselineRef.current) {
+ baselineRef.current = nextBaseline;
+ return;
+ }
+
+ if (!haveRevisionsChanged(baselineRef.current, nextBaseline)) {
+ return;
+ }
+
+ await onCatalogRevisionsChanged();
+ baselineRef.current = nextBaseline;
+ } finally {
+ isCheckInFlightRef.current = false;
+ scheduleNextCheck();
+ }
+ };
+
+ const onVisibilityChange = () => {
+ if (document.hidden) {
+ wasPausedRef.current = true;
+ clearScheduledCheck();
+ return;
+ }
+ if (wasPausedRef.current) {
+ wasPausedRef.current = false;
+ void checkCatalogRevisions();
+ }
+ };
+
+ document.addEventListener('visibilitychange', onVisibilityChange);
+ void checkCatalogRevisions();
+
+ return () => {
+ isUnmountedRef.current = true;
+ clearScheduledCheck();
+ document.removeEventListener('visibilitychange', onVisibilityChange);
+ };
+ }, [enabled, onCatalogRevisionsChanged]);
+};
+
+export default useCatalogPolling;
diff --git a/opencti-platform/opencti-front/src/relay/environment.tsx b/opencti-platform/opencti-front/src/relay/environment.tsx
index d49a8a1ddf67..a0c2efdc4bba 100644
--- a/opencti-platform/opencti-front/src/relay/environment.tsx
+++ b/opencti-platform/opencti-front/src/relay/environment.tsx
@@ -121,6 +121,8 @@ interface QueryRendererProps {
fetchPolicy?: FetchPolicy;
}
+type FetchQueryOptions = NonNullable[3]>;
+
export const QueryRenderer = ({
variables,
query,
@@ -227,7 +229,8 @@ export const requestSubscription = (args) => RS(environment, args);
export const fetchQuery = (
query: GraphQLTaggedNode,
args: T['variables'] = {},
-) => FQ(environment, query, args);
+ options?: FetchQueryOptions,
+) => FQ(environment, query, args, options);
export const commitLocalUpdate = (updater: SelectorStoreUpdater) => CLU(environment, updater);
diff --git a/opencti-platform/opencti-front/src/schema/relay.schema.graphql b/opencti-platform/opencti-front/src/schema/relay.schema.graphql
index 3edda2c6b229..65caf4c5d5f6 100644
--- a/opencti-platform/opencti-front/src/schema/relay.schema.graphql
+++ b/opencti-platform/opencti-front/src/schema/relay.schema.graphql
@@ -9469,6 +9469,7 @@ type Query {
channels(first: Int, after: ID, orderBy: ChannelsOrdering, orderMode: OrderingMode, filters: FilterGroup, search: String): ChannelConnection
catalog(id: String!): Catalog
catalogs: [Catalog!]!
+ catalogsRevisions: [CatalogRevision!]!
contract(slug: String!): ExtendedContract
language(id: String!): Language
languages(first: Int, after: ID, orderBy: LanguagesOrdering, orderMode: OrderingMode, filters: FilterGroup, search: String): LanguageConnection
@@ -10968,6 +10969,11 @@ type ExtendedContract {
contract: String!
}
+type CatalogRevision {
+ catalog_id: String!
+ revision: String
+}
+
enum CatalogsOrdering {
name
_score
diff --git a/opencti-platform/opencti-front/vite.config.ts b/opencti-platform/opencti-front/vite.config.ts
index 2902a648bfb1..e0bef487e167 100644
--- a/opencti-platform/opencti-front/vite.config.ts
+++ b/opencti-platform/opencti-front/vite.config.ts
@@ -77,6 +77,7 @@ export default defineConfig(({ mode, command }) => {
[`${basePath}/logout`]: backProxy(),
[`${basePath}/stream`]: backProxy(),
[`${basePath}/storage`]: backProxy(),
+ [`${basePath}/catalog`]: backProxy(),
[`${basePath}/schema`]: backProxy(),
'^/.*/embedded/.*': backProxy(),
[`${basePath}/taxii2`]: backProxy(),
diff --git a/opencti-platform/opencti-graphql/config/default.json b/opencti-platform/opencti-graphql/config/default.json
index ad7032cd39fa..a7a9463c6952 100644
--- a/opencti-platform/opencti-graphql/config/default.json
+++ b/opencti-platform/opencti-graphql/config/default.json
@@ -373,6 +373,13 @@
"lock_key": "exclusion_list_cache_sync_manager_lock",
"interval": 10000
},
+ "catalog_manager": {
+ "enabled": true,
+ "lock_key": "catalog_manager_lock",
+ "interval": 60000,
+ "custom_catalog_refresh_endpoint_uri": null,
+ "catalog_sync_remote_timeout": 30000
+ },
"redis": {
"mode": "single",
"namespace": "",
diff --git a/opencti-platform/opencti-graphql/config/schema/opencti.graphql b/opencti-platform/opencti-graphql/config/schema/opencti.graphql
index e0c94f1a27c0..f3ae008f553d 100644
--- a/opencti-platform/opencti-graphql/config/schema/opencti.graphql
+++ b/opencti-platform/opencti-graphql/config/schema/opencti.graphql
@@ -2249,7 +2249,7 @@ type Connector implements BasicObject & InternalObject {
manager_current_status: String
manager_requested_status: String
manager_contract_image: String
- manager_contract_definition: String
+ manager_contract_definition: String # JSON.Stringified GraphqlCatalogContract item
manager_contract_excerpt: ManagerContractExcerpt
manager_contract_configuration: [ManagerContractConfiguration!]
manager_connector_logs: [String!]
diff --git a/opencti-platform/opencti-graphql/src/config/conf.js b/opencti-platform/opencti-graphql/src/config/conf.js
index bbd80d288578..f047b2746318 100644
--- a/opencti-platform/opencti-graphql/src/config/conf.js
+++ b/opencti-platform/opencti-graphql/src/config/conf.js
@@ -542,6 +542,7 @@ export const ENABLED_TRACING = booleanConf('app:telemetry:tracing:enabled', fals
export const ENABLED_METRICS = booleanConf('app:telemetry:metrics:enabled', false);
export const ENABLED_NOTIFICATION_MANAGER = booleanConf('notification_manager:enabled', true);
export const ENABLED_PUBLISHER_MANAGER = booleanConf('publisher_manager:enabled', true);
+export const ENABLED_CATALOG_MANAGER = booleanConf('catalog_manager:enabled', true);
export const ENABLED_CONNECTOR_MANAGER = booleanConf('connector_manager:enabled', true);
export const ENABLED_FILE_INDEX_MANAGER = booleanConf('file_index_manager:enabled', true);
diff --git a/opencti-platform/opencti-graphql/src/database/engine-mapping-generator.ts b/opencti-platform/opencti-graphql/src/database/engine-mapping-generator.ts
index 32b318e70529..3c2c745aba04 100644
--- a/opencti-platform/opencti-graphql/src/database/engine-mapping-generator.ts
+++ b/opencti-platform/opencti-graphql/src/database/engine-mapping-generator.ts
@@ -48,6 +48,10 @@ const attributeMappingGenerator = (entityAttribute: AttributeDefinition, engine:
if (entityAttribute.format === 'flat') {
return { type: engine instanceof ElkClient ? 'flattened' : 'flat_object' };
}
+ // For non-indexed objects
+ if (entityAttribute.format === 'raw') {
+ return { type: 'object', enabled: false };
+ }
// For standard object
const properties: Record = {};
for (let i = 0; i < entityAttribute.mappings.length; i += 1) {
diff --git a/opencti-platform/opencti-graphql/src/database/engine.ts b/opencti-platform/opencti-graphql/src/database/engine.ts
index 2a6c968f18a3..0bc61817bfbd 100644
--- a/opencti-platform/opencti-graphql/src/database/engine.ts
+++ b/opencti-platform/opencti-graphql/src/database/engine.ts
@@ -131,6 +131,7 @@ import {
isDateNumericOrBooleanAttribute,
isNumericAttribute,
isObjectFlatAttribute,
+ isObjectRawAttribute,
schemaAttributesDefinition,
validateDataBeforeIndexing,
} from '../schema/schema-attributes';
@@ -3204,7 +3205,7 @@ export const elLoadBy = async (
user: AuthUser,
field: string,
value: any,
- type = null,
+ type: string | null = null,
indices: string[] = READ_DATA_INDICES,
) => {
const filters = {
@@ -4493,7 +4494,7 @@ export const prepareElementForIndexing = async (element: Record) =>
thing[key] = typeof value === 'boolean' ? value : value?.toLowerCase() === 'true';
} else if (isNumericAttribute(key)) {
thing[key] = isNotEmptyField(value) ? Number(value) : undefined;
- } else if (R.is(Object, value) && Object.keys(value).length > 0) { // For complex object, prepare inner elements
+ } else if (R.is(Object, value) && Object.keys(value).length > 0 && !isObjectRawAttribute(key)) { // For complex object, prepare inner elements
thing[key] = await prepareElementForIndexing(value);
} else if (R.is(String, value)) { // For string, trim by default
thing[key] = value.trim();
diff --git a/opencti-platform/opencti-graphql/src/database/repository.js b/opencti-platform/opencti-graphql/src/database/repository.js
index 603446259b26..f30a7853ed3c 100644
--- a/opencti-platform/opencti-graphql/src/database/repository.js
+++ b/opencti-platform/opencti-graphql/src/database/repository.js
@@ -9,11 +9,11 @@ import { BUILTIN_NOTIFIERS_CONNECTORS } from '../modules/notifier/notifier-stati
import { builtInConnector, builtInConnectorsRuntime } from '../connector/connector-domain';
import { ENTITY_TYPE_PLAYBOOK } from '../modules/playbook/playbook-types';
import { shortHash } from '../schema/schemaUtils';
-import { encryptValue, getSupportedContractsByImage } from '../modules/catalog/catalog-domain';
+import { encryptValue, mapContractEntityFieldsToGraphqlCatalogContract } from '../modules/catalog/catalog-domain';
import { ENTITY_TYPE_PIR } from '../modules/pir/pir-types';
import { getEntitiesMapFromCache } from './cache';
import { SYSTEM_USER } from '../utils/access';
-import conf, { booleanConf, logApp } from '../config/conf';
+import conf, { booleanConf } from '../config/conf';
import { ConnectorPriorityGroup } from '../generated/graphql';
import { injectProxyConfiguration } from '../config/proxy-config';
import { getPlatformCrypto } from '../utils/platformCrypto';
@@ -22,7 +22,7 @@ import { memoize } from '../utils/memoize';
import { addUserTokenByAdmin, revokeUserTokenByAdmin } from '../modules/user/user-domain';
import { getClientBase } from './redis';
import { lockResources } from '../lock/master-lock';
-import { LockTimeoutError, TYPE_LOCK_ERROR } from '../config/errors';
+import { FunctionalError, LockTimeoutError, TYPE_LOCK_ERROR } from '../config/errors';
const getJWTKeyPair = memoize(async () => {
const factory = await getPlatformCrypto();
@@ -76,28 +76,22 @@ export const connector = async (context, user, id) => {
};
export const computeManagerConnectorContract = async (_context, _user, cn) => {
- const contracts = await getSupportedContractsByImage();
- const contract = contracts.get(cn.manager_contract_image);
- return contract ? JSON.stringify(contract) : contract;
-};
-
-export const computeManagerConnectorExcerpt = async (_context, _user, cn) => {
- if (!cn.manager_contract_image) {
+ if (!cn.manager_contract) {
return null;
}
+ return JSON.stringify(mapContractEntityFieldsToGraphqlCatalogContract(cn.manager_contract, { excludeRuntimeConfigVars: true }));
+};
- const contracts = await getSupportedContractsByImage();
- const contract = contracts.get(cn.manager_contract_image);
-
- if (!contract) {
- logApp.warn('No contract found for', { connectorName: cn.name });
+export const computeManagerConnectorExcerpt = async (_context, _user, cn) => {
+ if (!cn.manager_contract) {
return null;
}
+ const managerContract = cn.manager_contract;
return {
- title: contract.title,
- slug: contract.slug,
- logo: contract.logo,
+ title: managerContract.title,
+ slug: managerContract.slug,
+ logo: managerContract.logo_uri ?? '',
};
};
@@ -171,10 +165,18 @@ export const computeManagerConnectorConfiguration = async (context, _, cn, { wit
};
export const computeManagerConnectorImage = async (cn) => {
- const contracts = await getSupportedContractsByImage();
- const contract = contracts.get(cn.manager_contract_image);
- if (!contract) return '';
- return isNotEmptyField(cn.manager_contract_image) ? `${cn.manager_contract_image}:${contract.container_version}` : null;
+ if (!cn.manager_contract) {
+ return '';
+ }
+ const managerContract = cn.manager_contract;
+ if (!managerContract.image || !managerContract.contract_version) {
+ throw FunctionalError('Invalid manager contract snapshot', {
+ connectorId: cn.id ?? cn.internal_id,
+ image: managerContract.image,
+ version: managerContract.contract_version,
+ });
+ }
+ return `${managerContract.image}:${managerContract.contract_version}`;
};
export const computeManagerContractHash = async (context, user, cn) => {
diff --git a/opencti-platform/opencti-graphql/src/domain/connector-migration.ts b/opencti-platform/opencti-graphql/src/domain/connector-migration.ts
index 45b1bcaf5683..81144ee9df50 100644
--- a/opencti-platform/opencti-graphql/src/domain/connector-migration.ts
+++ b/opencti-platform/opencti-graphql/src/domain/connector-migration.ts
@@ -7,13 +7,19 @@ import { completeConnector, connector, connectors } from '../database/repository
import type { Connector, ConnectorContractConfiguration, ContractConfigInput } from '../generated/graphql';
import { publishUserAction } from '../listener/UserActionListener';
import { addConnectorDeployedCount } from '../manager/telemetryManager';
-import { computeConnectorTargetContract, findContractByContainerImage } from '../modules/catalog/catalog-domain';
+import {
+ computeConnectorTargetContract,
+ mapContractEntityFieldsToEmbeddedConnectorManagerContract,
+ mapContractEntityFieldsToGraphqlCatalogContract,
+} from '../modules/catalog/catalog-domain';
import { ABSTRACT_INTERNAL_OBJECT } from '../schema/general';
import { ENTITY_TYPE_CONNECTOR, ENTITY_TYPE_CONNECTOR_MANAGER } from '../schema/internalObject';
import type { BasicStoreEntityConnectorManager } from '../types/connector';
import type { AuthContext, AuthUser } from '../types/user';
import { isServiceAccountUser } from '../utils/access';
import { resolveUserByIdFromCache, userEditField } from './user';
+import { now } from '../utils/format';
+import { findLatestCompatibleCatalogContractByImageName } from '../modules/catalog/catalog-repository';
type ConfigInput = {
key: string;
@@ -22,6 +28,7 @@ type ConfigInput = {
type MappedKey = {
key: string;
+ sourceKey: string;
value: string;
type: string;
required: boolean;
@@ -89,6 +96,7 @@ const categorizeKeys = (
if (value !== null && value !== undefined) {
mapped.push({
key: schemaKey,
+ sourceKey: keyUpper,
value: String(value),
type: propSchema.type,
required: requiredKeys.includes(schemaKey),
@@ -139,17 +147,12 @@ export const assessConnectorMigration = async (context: AuthContext, user: AuthU
throw FunctionalError('Connector is already managed', { id: connectorId });
}
- const contractData = await findContractByContainerImage(context, user, containerImage);
+ const contractData = await findLatestCompatibleCatalogContractByImageName(context, user, containerImage);
if (!contractData) {
throw FunctionalError('Contract not found', { container_image: containerImage });
}
- let contract;
- try {
- contract = JSON.parse(contractData.contract);
- } catch {
- throw FunctionalError('Cannot parse contract found');
- }
+ const contract = mapContractEntityFieldsToGraphqlCatalogContract(contractData, { excludeRuntimeConfigVars: true });
// Check type are correct
if (existingConnector.connector_type !== contract.container_type) {
@@ -185,7 +188,7 @@ export const assessConnectorMigration = async (context: AuthContext, user: AuthU
connector_id: connectorId,
connector_name: existingConnector.name,
connector_type: existingConnector.connector_type,
- contract_slug: contract.contract_slug,
+ contract_slug: contract.slug,
contract_title: contract.title,
contract_image: contract.container_image,
summary: {
@@ -193,6 +196,7 @@ export const assessConnectorMigration = async (context: AuthContext, user: AuthU
mapped_keys: mapped.length,
ignored_keys: ignored.length,
missing_mandatory_keys: missingMandatory.length,
+ assessment_date: now(),
missing_optional_keys: missing.length - missingMandatory.length,
can_migrate: missingMandatory.length === 0,
configuration_provided: configuration !== null,
@@ -251,17 +255,12 @@ export const migrateConnectorToManaged = async (
convertUserToServiceAccount: boolean = true,
resetConnectorState: boolean = false,
) => {
- const contractData = await findContractByContainerImage(context, user, containerImage);
+ const contractData = await findLatestCompatibleCatalogContractByImageName(context, user, containerImage);
if (!contractData) {
throw FunctionalError('Contract not found', { container_image: containerImage });
}
- let contract;
- try {
- contract = JSON.parse(contractData.contract);
- } catch {
- throw FunctionalError('Cannot parse contract');
- }
+ const contract = mapContractEntityFieldsToGraphqlCatalogContract(contractData, { excludeRuntimeConfigVars: true });
if (!contract.manager_supported) {
throw FunctionalError('Connector is not managed by composer');
@@ -304,7 +303,7 @@ export const migrateConnectorToManaged = async (
);
const invalidKeys: string[] = [];
- userConfig.forEach((value: string, key: string) => {
+ userConfig.forEach((_value: string, key: string) => {
if (!schemaKeysUpper.has(key)) {
invalidKeys.push(key);
}
@@ -362,6 +361,7 @@ export const migrateConnectorToManaged = async (
title: existingConnector.name,
catalog_id: contractData.catalog_id,
manager_contract_image: contract.container_image,
+ manager_contract: mapContractEntityFieldsToEmbeddedConnectorManagerContract(contractData),
manager_contract_configuration: filteredConfigurations,
manager_requested_status: 'stopped',
};
diff --git a/opencti-platform/opencti-graphql/src/domain/connector.ts b/opencti-platform/opencti-graphql/src/domain/connector.ts
index 550025a56234..ef515924ae0c 100644
--- a/opencti-platform/opencti-graphql/src/domain/connector.ts
+++ b/opencti-platform/opencti-graphql/src/domain/connector.ts
@@ -55,7 +55,7 @@ import { isCompatibleVersionWithMinimal } from '../utils/version';
import { extractEntityRepresentativeName } from '../database/entity-representative';
import type { BasicStoreCommon, StoreEntity } from '../types/store';
import { addConnectorDeployedCount, addWorkbenchDraftConvertionCount, addWorkbenchValidationCount } from '../manager/telemetryManager';
-import { computeConnectorTargetContract, getSupportedContractsByImage } from '../modules/catalog/catalog-domain';
+import { computeConnectorTargetContract, mapContractEntityFieldsToEmbeddedConnectorManagerContract } from '../modules/catalog/catalog-domain';
import { getEntitiesMapFromCache } from '../database/cache';
import { createOnTheFlyUser } from '../modules/user/user-domain';
@@ -67,6 +67,7 @@ import { extractContentFrom } from '../utils/fileToContent';
import type { FileHandle } from 'fs/promises';
import { encryptSynchronizerCredential } from './connector-sync-crypto';
import { verifyIngestionUri } from '../modules/ingestion/ingestion-common';
+import { findLatestCompatibleCatalogContractByImageName } from '../modules/catalog/catalog-repository';
const MINIMAL_SYNCHRONIZER_COMPATIBLE_VERSION = '6.9.6';
// Sanitize name for K8s/Docker
@@ -202,13 +203,12 @@ export const managedConnectorEdit = async (
user: AuthUser,
input: EditManagedConnectorInput,
) => {
- const conn: any = await storeLoadById(context, user, input.id, ENTITY_TYPE_CONNECTOR);
+ const conn = await storeLoadById(context, user, input.id, ENTITY_TYPE_CONNECTOR);
if (isEmptyField(conn)) {
throw UnsupportedError('Connector not found', { id: input.id });
}
- const contractsMap = await getSupportedContractsByImage();
- const targetContract: any = contractsMap.get(conn.manager_contract_image);
- if (isEmptyField(targetContract)) {
+ const targetContract = conn.manager_contract;
+ if (!targetContract) {
throw UnsupportedError('Target contract not found');
}
const connectorManagers = await fullEntitiesList(context, user, [ENTITY_TYPE_CONNECTOR_MANAGER]);
@@ -225,7 +225,7 @@ export const managedConnectorEdit = async (
const patch: any = {
name: input.name,
title: input.title,
- connector_type: targetContract.container_type,
+ connector_type: targetContract.connector_type,
connector_user_id: input.connector_user_id,
manager_contract_configuration: contractConfigurations,
};
@@ -258,8 +258,7 @@ export const managedConnectorAdd = async (
input: AddManagedConnectorInput,
) => {
// Get contract
- const contractsMap = await getSupportedContractsByImage();
- const targetContract: any = contractsMap.get(input.manager_contract_image);
+ const targetContract = await findLatestCompatibleCatalogContractByImageName(context, user, input.manager_contract_image);
if (isEmptyField(targetContract)) {
throw UnsupportedError('Target contract not found');
}
@@ -306,11 +305,12 @@ export const managedConnectorAdd = async (
const connectorToCreate: any = {
title: input.name,
name: sanitizedName,
- connector_type: targetContract.container_type,
+ connector_type: targetContract.connector_type,
catalog_id: input.catalog_id,
connector_user_id: connectorUser.id,
manager_contract_image: input.manager_contract_image,
manager_contract_configuration: contractConfigurations,
+ manager_contract: mapContractEntityFieldsToEmbeddedConnectorManagerContract(targetContract),
manager_requested_status: 'stopped',
connector_state_timestamp: now(),
built_in: false,
diff --git a/opencti-platform/opencti-graphql/src/domain/filterKeysSchema.ts b/opencti-platform/opencti-graphql/src/domain/filterKeysSchema.ts
index 772bc777e99f..0ce3416e6808 100644
--- a/opencti-platform/opencti-graphql/src/domain/filterKeysSchema.ts
+++ b/opencti-platform/opencti-graphql/src/domain/filterKeysSchema.ts
@@ -63,7 +63,7 @@ import { CUSTOM_FIELDS_FEATURE_FLAG, isFeatureEnabled } from '../config/conf';
export type FilterDefinition = {
filterKey: string;
- type: string; // possible values: boolean, date, integer, float, string, id, vocabulary, text, enum, object, nested
+ type: string; // possible values: boolean, date, integer, float, version, string, id, vocabulary, text, enum, object, nested
label: string; // filter key translation in English
multiple: boolean; // if the field can have multiple values
subEntityTypes: string[]; // entity types that have the given type as parent and have this filter key in their schema
diff --git a/opencti-platform/opencti-graphql/src/generated/graphql.ts b/opencti-platform/opencti-graphql/src/generated/graphql.ts
index 8beaa3bc28ac..e796597d9a55 100644
--- a/opencti-platform/opencti-graphql/src/generated/graphql.ts
+++ b/opencti-platform/opencti-graphql/src/generated/graphql.ts
@@ -3880,6 +3880,12 @@ export type CatalogEdge = {
node: Catalog;
};
+export type CatalogRevision = {
+ __typename?: 'CatalogRevision';
+ catalog_id: Scalars['String']['output'];
+ revision?: Maybe;
+};
+
export enum CatalogsOrdering {
Score = '_score',
Name = 'name'
@@ -24752,6 +24758,7 @@ export type Query = {
cases?: Maybe;
catalog?: Maybe;
catalogs: Array;
+ catalogsRevisions: Array;
channel?: Maybe;
channels?: Maybe;
cities?: Maybe;
@@ -40617,6 +40624,7 @@ export type ResolversTypes = ResolversObject<{
Catalog: ResolverTypeWrapper;
CatalogConnection: ResolverTypeWrapper & { edges: Array }>;
CatalogEdge: ResolverTypeWrapper & { node: ResolversTypes['Catalog'] }>;
+ CatalogRevision: ResolverTypeWrapper;
CatalogsOrdering: CatalogsOrdering;
CertAuthConfig: ResolverTypeWrapper;
CertAuthConfigInput: CertAuthConfigInput;
@@ -41788,6 +41796,7 @@ export type ResolversParentTypes = ResolversObject<{
Catalog: GraphqlCatalog;
CatalogConnection: Omit & { edges: Array };
CatalogEdge: Omit & { node: ResolversParentTypes['Catalog'] };
+ CatalogRevision: CatalogRevision;
CertAuthConfig: CertAuthConfig;
CertAuthConfigInput: CertAuthConfigInput;
ChangePasswordInput: ChangePasswordInput;
@@ -43954,6 +43963,11 @@ export type CatalogEdgeResolvers;
}>;
+export type CatalogRevisionResolvers = ResolversObject<{
+ catalog_id?: Resolver;
+ revision?: Resolver, ParentType, ContextType>;
+}>;
+
export type CertAuthConfigResolvers = ResolversObject<{
button_label_override?: Resolver, ParentType, ContextType>;
description?: Resolver, ParentType, ContextType>;
@@ -50597,6 +50611,7 @@ export type QueryResolvers, ParentType, ContextType, Partial>;
catalog?: Resolver, ParentType, ContextType, RequireFields>;
catalogs?: Resolver, ParentType, ContextType>;
+ catalogsRevisions?: Resolver, ParentType, ContextType>;
channel?: Resolver, ParentType, ContextType, RequireFields>;
channels?: Resolver, ParentType, ContextType, Partial>;
cities?: Resolver, ParentType, ContextType, Partial>;
@@ -54873,6 +54888,7 @@ export type Resolvers = ResolversObject<{
Catalog?: CatalogResolvers;
CatalogConnection?: CatalogConnectionResolvers;
CatalogEdge?: CatalogEdgeResolvers;
+ CatalogRevision?: CatalogRevisionResolvers;
CertAuthConfig?: CertAuthConfigResolvers;
Channel?: ChannelResolvers;
ChannelConnection?: ChannelConnectionResolvers;
diff --git a/opencti-platform/opencti-graphql/src/http/httpPlatform.js b/opencti-platform/opencti-graphql/src/http/httpPlatform.js
index c589cb16c712..d2dda29cf020 100644
--- a/opencti-platform/opencti-graphql/src/http/httpPlatform.js
+++ b/opencti-platform/opencti-graphql/src/http/httpPlatform.js
@@ -52,6 +52,7 @@ import { CERT_PROVIDER } from '../modules/authenticationProvider/provider-cert';
import { HEADERS_PROVIDER } from '../modules/authenticationProvider/provider-headers';
import { AuthenticationProviderError } from '../modules/authenticationProvider/providers-logger';
import { buildDefaultHelmetParameters, buildPublicHelmetParameters } from './httpUtils';
+import { CATALOG_LOGO_VIEW_PATH, handleCatalogLogoViewRequest } from '../modules/catalog/catalog-http';
const publicDir = DEV_MODE ? '../opencti-front/dist' : 'public';
@@ -300,6 +301,9 @@ const createApp = async (app, schema) => {
}
});
+ // -- Catalog logo view
+ app.get(`${basePath}${CATALOG_LOGO_VIEW_PATH}`, handleCatalogLogoViewRequest);
+
// -- embedded loader
const uuidPattern = '[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}';
const embeddedFileGetPath = new RegExp(`${basePath}/(.*)/(${uuidPattern})/(.*)embedded/(.*)$`, 'i');
diff --git a/opencti-platform/opencti-graphql/src/manager/index.ts b/opencti-platform/opencti-graphql/src/manager/index.ts
index 66e1d53ff9a6..ca490ba82c32 100644
--- a/opencti-platform/opencti-graphql/src/manager/index.ts
+++ b/opencti-platform/opencti-graphql/src/manager/index.ts
@@ -9,3 +9,5 @@ import './retentionManager';
import './telemetryManager';
import './workflowStatusCleanupManager';
import './xtmOneRegistrationManager';
+import './dataSanityManager';
+import '../modules/catalog/catalog-manager';
diff --git a/opencti-platform/opencti-graphql/src/manager/managerModule.ts b/opencti-platform/opencti-graphql/src/manager/managerModule.ts
index ff7e21d909ba..ee8183cbf1e1 100644
--- a/opencti-platform/opencti-graphql/src/manager/managerModule.ts
+++ b/opencti-platform/opencti-graphql/src/manager/managerModule.ts
@@ -63,6 +63,7 @@ const initManager = (manager: ManagerDefinition) => {
let streamProcessor: StreamProcessor;
let running = false;
let shutdown = false;
+ let enterpriseBlockedLogged = false;
const cronTimer = new InterruptibleTimer();
const streamTimer = new InterruptibleTimer();
@@ -70,8 +71,13 @@ const initManager = (manager: ManagerDefinition) => {
const cronHandler = async (cronInputFn?: () => Promise) => {
if (manager.cronSchedulerHandler) {
if (!(await isEnterpriseEditionAuthorized(manager))) {
+ if (!enterpriseBlockedLogged) {
+ logApp.info(`[OPENCTI-MODULE] ${manager.label} not running (enterprise edition license required)`);
+ enterpriseBlockedLogged = true;
+ }
return;
}
+ enterpriseBlockedLogged = false;
let lock;
let cronInput;
const startDate = utcDate();
@@ -113,8 +119,13 @@ const initManager = (manager: ManagerDefinition) => {
const streamHandler = async () => {
if (manager.streamSchedulerHandler) {
if (!(await isEnterpriseEditionAuthorized(manager))) {
+ if (!enterpriseBlockedLogged) {
+ logApp.info(`[OPENCTI-MODULE] ${manager.label} not running (enterprise edition license required)`);
+ enterpriseBlockedLogged = true;
+ }
return;
}
+ enterpriseBlockedLogged = false;
let lock;
try {
// Lock the manager
diff --git a/opencti-platform/opencti-graphql/src/manager/telemetryManager.ts b/opencti-platform/opencti-graphql/src/manager/telemetryManager.ts
index 33f04de1ba5f..a93f2de1cafb 100644
--- a/opencti-platform/opencti-graphql/src/manager/telemetryManager.ts
+++ b/opencti-platform/opencti-graphql/src/manager/telemetryManager.ts
@@ -57,7 +57,6 @@ import {
ENTITY_TYPE_INGESTION_TAXII_COLLECTION,
} from '../modules/ingestion/ingestion-types';
import { ENTITY_TYPE_MANAGER_CONFIGURATION } from '../modules/managerConfiguration/managerConfiguration-types';
-import { getSupportedContractsByImage } from '../modules/catalog/catalog-domain';
import { FilterMode } from '../generated/graphql';
import { redisClearTelemetry, redisGetTelemetry, redisSetTelemetryAdd } from '../database/redis';
import { countOffloadedStreamEvents, rawFetchStreamInfo } from '../database/redis-stream';
@@ -496,8 +495,7 @@ export const fetchTelemetryData = async (manager: TelemetryMeterManager) => {
// composer-managed connectors resolve to the catalog contract slug
// through their stored container image; manually registered connectors
// fall back to their registered name, flagged managed=false.
- const contractsByImage = await getSupportedContractsByImage();
- manager.setActiveConnectorsByIdentity(computeActiveConnectorsByIdentity(activeConnectors, contractsByImage));
+ manager.setActiveConnectorsByIdentity(computeActiveConnectorsByIdentity(activeConnectors));
// endregion
// region Roles with draft capability information
diff --git a/opencti-platform/opencti-graphql/src/migrations/1789637887081-embed-catalog-contract-in-connector-entity.ts b/opencti-platform/opencti-graphql/src/migrations/1789637887081-embed-catalog-contract-in-connector-entity.ts
new file mode 100644
index 000000000000..af61cb5356b7
--- /dev/null
+++ b/opencti-platform/opencti-graphql/src/migrations/1789637887081-embed-catalog-contract-in-connector-entity.ts
@@ -0,0 +1,84 @@
+import { logMigration } from '../config/conf';
+import { READ_INDEX_INTERNAL_OBJECTS } from '../database/utils';
+import { FilterMode } from '../generated/graphql';
+import { fullEntitiesList } from '../database/middleware-loader';
+import { executionContext, SYSTEM_USER } from '../utils/access';
+import { ENTITY_TYPE_CONNECTOR } from '../schema/internalObject';
+import { patchAttribute } from '../database/middleware';
+import type { BasicStoreEntityConnector } from '../types/connector';
+import openCtiManifest from '../__generated__/opencti-manifest.json';
+import type { CatalogContract, CatalogDefinition } from '../modules/catalog/catalog-types';
+import { mapContractDtoV0ToContractEntityFields } from '../modules/catalog/catalog-domain';
+import { listCatalogContractLogos, storeCatalogContractLogo } from '../modules/catalog/catalog-logo-storage';
+import { computeContractContentHash } from '../modules/catalog/sync/catalog-sync-domain';
+import { mapCatalogContractDtoToCatalogContractSyncSource } from '../modules/catalog/sync/catalog-sync-source-gateway';
+
+const message = '[MIGRATION] managed connectors contract snapshot';
+
+export const up = async (next: (error?: Error) => void) => {
+ const start = new Date().getTime();
+ logMigration.info(`${message} > started`);
+ const context = executionContext('migration');
+
+ const filigranCatalog = openCtiManifest as unknown as CatalogDefinition;
+
+ // Load all managed connectors which have their contract definition in the embedded catalog manifest
+ const managedConnectorsArgs = {
+ indices: [READ_INDEX_INTERNAL_OBJECTS],
+ filters: { mode: FilterMode.And, filters: [{ key: ['catalog_id'], values: [filigranCatalog.id] }], filterGroups: [] },
+ };
+ const managedConnectors = await fullEntitiesList(context, SYSTEM_USER, [ENTITY_TYPE_CONNECTOR], managedConnectorsArgs);
+ logMigration.info(`${message} > ${managedConnectors.length} managed connector(s) to evaluate`);
+
+ // Read the contracts from the embedded catalog file
+ const contractsByImage: Record = {};
+ filigranCatalog.contracts.forEach((contract: CatalogContract) => {
+ contractsByImage[contract.container_image] = contract;
+ });
+
+ const storedLogos = managedConnectors.length > 0 ? (await listCatalogContractLogos()) : new Set();
+ for (let i = 0; i < managedConnectors.length; i += 1) {
+ const connector = managedConnectors[i];
+ logMigration.info(`${message} > processing connector ${connector.id} (${i + 1}/${managedConnectors.length})`);
+ const patch: Pick = {};
+ if (!connector.manager_contract && connector.manager_contract_image) {
+ const contractDto = contractsByImage[connector.manager_contract_image];
+ if (!contractDto) {
+ logMigration.info(`${message} > connector ${connector.id} missing catalog contract ${connector.manager_contract_image}`);
+ } else {
+ const result = await storeCatalogContractLogo(contractDto, storedLogos);
+ if (result.result === 'failed') {
+ logMigration.info(`${message} > failed to store logo into file storage for connector ${connector.id} (${result.error?.message ?? 'Unknown error'})`);
+ } else if (result.result === 'success') {
+ if (result.existed) {
+ logMigration.info(`${message} > deduped logo file for connector ${connector.id}`);
+ } else {
+ storedLogos.add(result.filename);
+ }
+ }
+ const contractContentHash = computeContractContentHash(
+ mapCatalogContractDtoToCatalogContractSyncSource(contractDto),
+ );
+ patch.manager_contract = mapContractDtoV0ToContractEntityFields({
+ catalogId: filigranCatalog.id,
+ contractDto,
+ contractContentHash,
+ logoUri: result.logoUri,
+ });
+ }
+ }
+ if (!connector.manager_upgrade_strategy) {
+ patch.manager_upgrade_strategy = 'latest';
+ }
+ if (Object.keys(patch).length > 0) {
+ await patchAttribute(context, SYSTEM_USER, connector.id, ENTITY_TYPE_CONNECTOR, patch);
+ logMigration.info(`${message} > connector ${connector.id} patched`);
+ }
+ }
+ logMigration.info(`${message} > done in ${new Date().getTime() - start} ms`);
+ next();
+};
+
+export const down = async (next: (error?: Error) => void) => {
+ next();
+};
diff --git a/opencti-platform/opencti-graphql/src/modules/attributes/internalObject-registrationAttributes.ts b/opencti-platform/opencti-graphql/src/modules/attributes/internalObject-registrationAttributes.ts
index 0cfd596a4fba..03c55002ab75 100644
--- a/opencti-platform/opencti-graphql/src/modules/attributes/internalObject-registrationAttributes.ts
+++ b/opencti-platform/opencti-graphql/src/modules/attributes/internalObject-registrationAttributes.ts
@@ -41,6 +41,7 @@ import { schemaAttributesDefinition } from '../../schema/schema-attributes';
import { ENTITY_TYPE_MARKING_DEFINITION } from '../../schema/stixMetaObject';
import { ENTITY_TYPE_IDENTITY_ORGANIZATION } from '../organization/organization-types';
import { ENTITY_TYPE_PIR } from '../pir/pir-types';
+import { CATALOG_CONTRACT_MAPPINGS } from '../catalog/catalog';
const HistoryDefinition: AttributeDefinition[] = [
{ name: 'event_type', label: 'Event type', type: 'string', format: 'enum', values: EVENT_TYPE_VALUES, editDefault: false, mandatoryType: 'internal', multiple: false, upsert: false, isFilterable: true },
@@ -464,6 +465,9 @@ const internalObjectsAttributes: { [k: string]: Array>
{ name: 'manager_requested_status', label: 'Connector manager requested status', type: 'string', format: 'short', mandatoryType: 'no', editDefault: false, multiple: false, upsert: false, isFilterable: true },
{ name: 'manager_contract_image', label: 'Connector manager image', type: 'string', format: 'short', mandatoryType: 'no', editDefault: false, multiple: false, upsert: false, isFilterable: true },
{ name: 'manager_contract_configuration', label: 'Connector manager', type: 'object', format: 'flat', mandatoryType: 'no', editDefault: false, multiple: true, upsert: false, isFilterable: true },
+ { name: 'manager_contract', label: 'Connector manager contract', type: 'object', format: 'standard', mandatoryType: 'no', editDefault: false, multiple: false, upsert: false, isFilterable: false, mappings: CATALOG_CONTRACT_MAPPINGS },
+ { name: 'manager_upgrade_strategy', label: 'Connector upgrade strategy', type: 'string', format: 'enum', values: ['latest'], mandatoryType: 'no', editDefault: false, multiple: false, upsert: false, isFilterable: false },
+
// endregion
],
[ENTITY_TYPE_CONNECTOR_MANAGER]: [
diff --git a/opencti-platform/opencti-graphql/src/modules/catalog/catalog-domain.ts b/opencti-platform/opencti-graphql/src/modules/catalog/catalog-domain.ts
index ed6215dab673..beeb3e9d6b87 100644
--- a/opencti-platform/opencti-graphql/src/modules/catalog/catalog-domain.ts
+++ b/opencti-platform/opencti-graphql/src/modules/catalog/catalog-domain.ts
@@ -2,24 +2,67 @@ import Ajv from 'ajv';
import addFormats from 'ajv-formats';
import crypto from 'crypto';
import type { AuthContext, AuthUser } from '../../types/user';
-import { type CatalogContract, type CatalogDefinition, type CatalogType } from './catalog-types';
+import {
+ type BasicStoreEntityCatalogContract,
+ type BasicStoreEntityCatalog,
+ type CatalogContract,
+ type CatalogContractEntityFields,
+ type GraphqlCatalog,
+ type GraphqlCatalogRevision,
+ type GraphqlCatalogContract,
+} from './catalog-types';
import { isEmptyField } from '../../database/utils';
import { UnsupportedError } from '../../config/errors';
-import { idGenFromData } from '../../schema/identifier';
-import filigranCatalog from '../../__generated__/opencti-manifest.json';
-import conf, { logApp } from '../../config/conf';
import type { ConnectorContractConfiguration, ContractConfigInput } from '../../generated/graphql';
-import { readFile } from 'node:fs/promises';
import type { ValidateFunction } from 'ajv';
+import {
+ findAllCatalogs,
+ findCatalogByCatalogId,
+ findCatalogsRevisions,
+ findLatestCompatibleCatalogContractBySlug,
+ findLatestCompatibleCatalogContractsByCatalogId,
+} from './catalog-repository';
+import { logApp } from '../../config/conf';
const validatorCache = new Map();
+const EXCLUDED_CONFIG_VARS = ['OPENCTI_TOKEN', 'OPENCTI_URL', 'CONNECTOR_TYPE', 'CONNECTOR_RUN_AND_TERMINATE'];
+
+const normalizeContractConfigSchema = (
+ configSchema: CatalogContract['config_schema'] | null | undefined,
+): CatalogContract['config_schema'] => {
+ const schema = (configSchema && typeof configSchema === 'object') ? configSchema : {} as CatalogContract['config_schema'];
+ const properties = (schema.properties && typeof schema.properties === 'object' && !Array.isArray(schema.properties))
+ ? schema.properties
+ : {};
+ const required = Array.isArray(schema.required) ? schema.required.filter((property) => typeof property === 'string') : [];
+ return {
+ $schema: typeof schema.$schema === 'string' ? schema.$schema : 'https://json-schema.org/draft/2020-12/schema',
+ $id: typeof schema.$id === 'string' ? schema.$id : '',
+ type: typeof schema.type === 'string' ? schema.type : 'object',
+ properties,
+ required,
+ additionalProperties: typeof schema.additionalProperties === 'boolean' ? schema.additionalProperties : true,
+ };
+};
+
+const getContractConfigSchemaWithoutExcludedRuntimeVars = (configSchema: CatalogContract['config_schema'] | null | undefined) => {
+ const normalizedConfigSchema = normalizeContractConfigSchema(configSchema);
+ const filteredProperties = Object.fromEntries(
+ Object.entries(normalizedConfigSchema.properties).filter(([property]) => !EXCLUDED_CONFIG_VARS.includes(property)),
+ );
+ return {
+ ...normalizedConfigSchema,
+ properties: filteredProperties,
+ required: normalizedConfigSchema.required.filter((property) => !EXCLUDED_CONFIG_VARS.includes(property)),
+ };
+};
/**
* Compiles (or retrieves from cache) an AJV validator for a given schema.
* The cacheKey must accurately reflect the exact shape of the schema (properties + required)
* to avoid cache false positives.
*/
-const getOrCompileValidator = (cacheKey: string, jsonValidation: object): ValidateFunction => {
+export const getOrCompileValidator = (cacheKey: string, jsonValidation: object): ValidateFunction => {
let validate = validatorCache.get(cacheKey);
if (!validate) {
validate = ajv.compile(jsonValidation);
@@ -28,111 +71,9 @@ const getOrCompileValidator = (cacheKey: string, jsonValidation: object): Valida
return validate;
};
-const CUSTOM_CATALOGS: string[] = conf.get('app:custom_catalogs') ?? [];
const ajv = new Ajv({ coerceTypes: true });
addFormats(ajv, ['password', 'uri', 'duration', 'email', 'date-time', 'date']);
-// Cache of catalog to read on disk and parse only once
-let catalogMap: Promise> | undefined;
-// cache for contracts by image map
-let contractsByImageCache: Promise