diff --git a/docs/docs/administration/assets/theme-desc-1.png b/docs/docs/administration/assets/theme-desc-1.png index e83905e2803d..1ea957e39d70 100644 Binary files a/docs/docs/administration/assets/theme-desc-1.png and b/docs/docs/administration/assets/theme-desc-1.png differ diff --git a/docs/docs/administration/assets/theme-desc-2.png b/docs/docs/administration/assets/theme-desc-2.png index 6e83d6e0eaa0..e45c4226cfe8 100644 Binary files a/docs/docs/administration/assets/theme-desc-2.png and b/docs/docs/administration/assets/theme-desc-2.png differ diff --git a/docs/docs/administration/assets/theme-desc-3.png b/docs/docs/administration/assets/theme-desc-3.png new file mode 100644 index 000000000000..565986dfbaf8 Binary files /dev/null and b/docs/docs/administration/assets/theme-desc-3.png differ diff --git a/docs/docs/administration/assets/theme-login-1.png b/docs/docs/administration/assets/theme-login-1.png new file mode 100644 index 000000000000..0ea0ae6532ea Binary files /dev/null and b/docs/docs/administration/assets/theme-login-1.png differ diff --git a/docs/docs/administration/assets/theme-login-2.png b/docs/docs/administration/assets/theme-login-2.png new file mode 100644 index 000000000000..fe2632cfc03f Binary files /dev/null and b/docs/docs/administration/assets/theme-login-2.png differ diff --git a/docs/docs/administration/assets/theme-login-aside-config.png b/docs/docs/administration/assets/theme-login-aside-config.png new file mode 100644 index 000000000000..ddb770568c3c Binary files /dev/null and b/docs/docs/administration/assets/theme-login-aside-config.png differ diff --git a/docs/docs/administration/parameters.md b/docs/docs/administration/parameters.md index bfe473894c36..9d19d1438d40 100644 --- a/docs/docs/administration/parameters.md +++ b/docs/docs/administration/parameters.md @@ -87,9 +87,9 @@ Click on the **+** icon and configure your theme properties. | **Name** | Unique identifier for the theme (case-sensitive) | Theme selector | `My Theme` | | **Background color** | Main application background | Behind all content areas | `#122e52` | | **Paper color** | Background for content containers | Cards, side panels, dialog bodies | `#0a395f` | -| **Navigation color** | Navigation and header elements | Top app bar, dialog headers, right navigation panels | `#060b3f` | +| **Navigation color** | Navigation and header elements | Dialog headers, right navigation panels | `#060b3f` | | **Primary color** | Main interactive elements | Icon buttons, action buttons, highlights | `#e41682` | -| **Secondary color** | Secondary actions | Primary action buttons in dialogs | `#d1c71d` | +| **Secondary color** | Secondary actions | Badge color | `#d1c71d` | | **Accent color** | Highlight and emphasis | Copied items, history entries, selected items | `#e5abec` | | **Text color** | Primary text throughout the application | All text content | `#e0e0e0` | | **Logo URL** | Full-size logo | Expanded left navigation panel | URL or Base64 | @@ -101,6 +101,28 @@ Click on the **+** icon and configure your theme properties. ![Theme Colors in Dialog](assets/theme-desc-1.png) +![Theme Colors in Parameters](assets/theme-desc-3.png) + +#### Login aside customization + +The right panel of the login page can be customized with three options: + +- **Color**: a single solid background color +- **Gradient**: a linear gradient between two colors applied horizontally from the start color to the end color +- **Image**: full-cover background image via URL or Base64. The image is scaled to cover the entire panel and centered, so edges may be cropped on smaller screens. Prefer images with a centered subject. + +![Login Aside config](assets/theme-login-aside-config.png) + + +![Login Aside default](assets/theme-login-1.png) +*Login page with no aside config set* + +![Login Aside with gradient](assets/theme-login-2.png) +*Login page with a custom gradient background* + + + + #### Color requirements - **Format:** All colors must be in hexadecimal format (e.g., `#122e52`) - **Contrast:** Ensure adequate contrast between text and background colors for accessibility diff --git a/opencti-platform/opencti-front/lang/back/de.json b/opencti-platform/opencti-front/lang/back/de.json index 9e002e319013..592b2c013add 100644 --- a/opencti-platform/opencti-front/lang/back/de.json +++ b/opencti-platform/opencti-front/lang/back/de.json @@ -954,6 +954,10 @@ "Theme": "Thema", "Theme accent": "Thema Akzent", "Theme background": "Thema Hintergrund", + "Theme login aside color": "Thema Anmeldung neben Farbe", + "Theme login aside gradient end": "Theme login aside gradient end", + "Theme login aside gradient start": "Thema login aside gradient start", + "Theme login aside image": "Thema login aside Bild", "Theme logo": "Thema Logo", "Theme logo collapsed": "Theme-Logo kollabiert", "Theme logo login": "Themenlogo Anmeldung", diff --git a/opencti-platform/opencti-front/lang/back/en.json b/opencti-platform/opencti-front/lang/back/en.json index 2d1358030646..d76d648b32df 100644 --- a/opencti-platform/opencti-front/lang/back/en.json +++ b/opencti-platform/opencti-front/lang/back/en.json @@ -954,6 +954,10 @@ "Theme": "Theme", "Theme accent": "Theme accent", "Theme background": "Theme background", + "Theme login aside color": "Theme login aside color", + "Theme login aside gradient end": "Theme login aside gradient end", + "Theme login aside gradient start": "Theme login aside gradient start", + "Theme login aside image": "Theme login aside image", "Theme logo": "Theme logo", "Theme logo collapsed": "Theme logo collapsed", "Theme logo login": "Theme logo login", diff --git a/opencti-platform/opencti-front/lang/back/es.json b/opencti-platform/opencti-front/lang/back/es.json index f07082ea7a0d..245c8fa7137e 100644 --- a/opencti-platform/opencti-front/lang/back/es.json +++ b/opencti-platform/opencti-front/lang/back/es.json @@ -954,6 +954,10 @@ "Theme": "Tema", "Theme accent": "Acento temático", "Theme background": "Tema de fondo", + "Theme login aside color": "Tema login aparte color", + "Theme login aside gradient end": "Tema login aside gradient end", + "Theme login aside gradient start": "Inicio de degradado del tema de inicio de sesión", + "Theme login aside image": "Imagen de inicio de sesión", "Theme logo": "Tema logotipo", "Theme logo collapsed": "Logotipo del tema colapsado", "Theme logo login": "Inicio de sesión del logotipo del tema", diff --git a/opencti-platform/opencti-front/lang/back/fr.json b/opencti-platform/opencti-front/lang/back/fr.json index d909cfae8f50..97a81fb7f6ba 100644 --- a/opencti-platform/opencti-front/lang/back/fr.json +++ b/opencti-platform/opencti-front/lang/back/fr.json @@ -954,6 +954,10 @@ "Theme": "Thème", "Theme accent": "Accent thématique", "Theme background": "Arrière-plan du thème", + "Theme login aside color": "Couleur du côté de la page de connexion", + "Theme login aside gradient end": "Fin du dégradé de la page de connexion", + "Theme login aside gradient start": "Début du dégradé de la page de connexion", + "Theme login aside image": "Image de la page de connexion", "Theme logo": "Logo du thème", "Theme logo collapsed": "Logo du thème collapsé", "Theme logo login": "Logo du thème login", diff --git a/opencti-platform/opencti-front/lang/back/it.json b/opencti-platform/opencti-front/lang/back/it.json index 2398320d7945..c15777a2672d 100644 --- a/opencti-platform/opencti-front/lang/back/it.json +++ b/opencti-platform/opencti-front/lang/back/it.json @@ -954,6 +954,10 @@ "Theme": "Tema", "Theme accent": "Accento sul tema", "Theme background": "Sfondo del tema", + "Theme login aside color": "Tema login da parte colore", + "Theme login aside gradient end": "Tema login aside gradient end", + "Theme login aside gradient start": "Inizio gradiente tema login aside", + "Theme login aside image": "Tema login a parte immagine", "Theme logo": "Logo del tema", "Theme logo collapsed": "Logo del tema collassato", "Theme logo login": "Logo del tema login", diff --git a/opencti-platform/opencti-front/lang/back/ja.json b/opencti-platform/opencti-front/lang/back/ja.json index 39bd8db6055e..9ca5d7db4b7f 100644 --- a/opencti-platform/opencti-front/lang/back/ja.json +++ b/opencti-platform/opencti-front/lang/back/ja.json @@ -954,6 +954,10 @@ "Theme": "テーマ", "Theme accent": "テーマ・アクセント", "Theme background": "テーマ背景", + "Theme login aside color": "テーマログイン脇の色", + "Theme login aside gradient end": "テーマログイン脇グラデーション終了", + "Theme login aside gradient start": "テーマログイン脇グラデーション開始", + "Theme login aside image": "テーマログイン脇画像", "Theme logo": "テーマロゴ", "Theme logo collapsed": "テーマロゴ折りたたみ", "Theme logo login": "テーマロゴ", diff --git a/opencti-platform/opencti-front/lang/back/ko.json b/opencti-platform/opencti-front/lang/back/ko.json index 4c8b6c3652b2..56ec8573cdfd 100644 --- a/opencti-platform/opencti-front/lang/back/ko.json +++ b/opencti-platform/opencti-front/lang/back/ko.json @@ -954,6 +954,10 @@ "Theme": "테마", "Theme accent": "테마 악센트", "Theme background": "테마 배경", + "Theme login aside color": "테마 로그인 사이드 컬러", + "Theme login aside gradient end": "테마 로그인 옆 그라데이션 끝", + "Theme login aside gradient start": "테마 로그인 옆 그라데이션 시작", + "Theme login aside image": "테마 로그인 옆 이미지", "Theme logo": "테마 로고", "Theme logo collapsed": "테마 로고가 축소됨", "Theme logo login": "테마 로고 로그인", diff --git a/opencti-platform/opencti-front/lang/back/ru.json b/opencti-platform/opencti-front/lang/back/ru.json index 10a321dcd255..9a75eef5e734 100644 --- a/opencti-platform/opencti-front/lang/back/ru.json +++ b/opencti-platform/opencti-front/lang/back/ru.json @@ -954,6 +954,10 @@ "Theme": "Тема", "Theme accent": "Тематический акцент", "Theme background": "Тематический фон", + "Theme login aside color": "Тематический цвет входа в систему в стороне", + "Theme login aside gradient end": "Градиентный конец для входа в тему", + "Theme login aside gradient start": "Начало градиента для входа в тему", + "Theme login aside image": "Изображение в стороне от входа в тему", "Theme logo": "Логотип темы", "Theme logo collapsed": "Логотип темы свернут", "Theme logo login": "Логотип темы войти", diff --git a/opencti-platform/opencti-front/lang/back/zh.json b/opencti-platform/opencti-front/lang/back/zh.json index 773ddec7c001..8cd834715481 100644 --- a/opencti-platform/opencti-front/lang/back/zh.json +++ b/opencti-platform/opencti-front/lang/back/zh.json @@ -954,6 +954,10 @@ "Theme": "主题", "Theme accent": "主题口音", "Theme background": "主题背景", + "Theme login aside color": "主题登录颜色", + "Theme login aside gradient end": "主题登录时的渐变效果", + "Theme login aside gradient start": "主题登录旁渐变开始", + "Theme login aside image": "主题登录旁图像", "Theme logo": "主题徽标", "Theme logo collapsed": "主题徽标折叠", "Theme logo login": "主题徽标登录", diff --git a/opencti-platform/opencti-front/lang/front/de.json b/opencti-platform/opencti-front/lang/front/de.json index 26d4ecc2dd34..93d73e0f7992 100644 --- a/opencti-platform/opencti-front/lang/front/de.json +++ b/opencti-platform/opencti-front/lang/front/de.json @@ -125,6 +125,9 @@ "Add and complete": "Hinzufügen und ausfüllen", "Add attack patterns": "Angriffsmuster hinzufügen", "Add attributes of the instance": "Hinzufügen von Attributen der {type}", + "Add background color": "Hintergrundfarbe hinzufügen", + "Add background gradient": "Hintergrundfarbverlauf hinzufügen", + "Add background image": "Hintergrundbild hinzufügen", "Add citizenship": "Staatsbürgerschaft hinzufügen", "Add components": "Komponenten hinzufügen", "Add context": "Kontext hinzufügen", @@ -149,6 +152,7 @@ "Add generated and existing indicators in the container": "Generierte & hinzufügen; vorhandene Indikatoren im Container", "Add generated and existing observables in the container": "Hinzufügen von generierten & vorhandenen Observablen im Container", "Add header": "Kopfzeile hinzufügen", + "Add image URL": "Bild-URL hinzufügen", "Add in container": "Hinzufügen im Container", "Add indicators": "Indikatoren hinzufügen", "Add individual": "Einzelperson hinzufügen", @@ -1880,6 +1884,7 @@ "FINTEL template created": "FINTEL-Vorlage erstellt", "FINTEL Templates": "FINTEL-Vorlagen", "FINTEL templates are available with an Enterprise Edition subscription": "FINTEL Vorlagen sind mit einem Enterprise Edition Abonnement verfügbar", + "First color": "Erste Farbe", "First match": "Erstes Spiel", "First name expression": "Vornamensausdruck", "First obs.": "Erste Obs.", @@ -2119,6 +2124,7 @@ "If you want to keep the associated information, we recommend deactivating the user instead.": "Wenn Sie die zugehörigen Informationen behalten möchten, empfehlen wir, den Benutzer stattdessen zu deaktivieren.", "If your email address is found, an email will be sent to you.": "Wenn Ihre E-Mail-Adresse gefunden wurde, wird Ihnen eine E-Mail zugeschickt.", "if your service account has been created originally as a service account (not transformed), please also change the email of your service account before/after transforming it to a user to ensure that the future user will be able to receive an email in the forgot password workflow.": "wenn Ihr Dienstkonto ursprünglich als Dienstkonto angelegt wurde (nicht umgewandelt), ändern Sie bitte auch die E-Mail Ihres Dienstkontos vor/nach der Umwandlung in einen Benutzer, um sicherzustellen, dass der zukünftige Benutzer eine E-Mail im Workflow \"Passwort vergessen\" erhalten kann.", + "Image URL": "Bild-URL", "Impact": "Aufschlag", "Impacted": "Beeinflusst", "impacted by a modification to a linked entity (relation, added in container...)": "beeinflusst durch eine Änderung an einer verknüpften Entität (Beziehung, hinzugefügt in Container...)", @@ -2498,6 +2504,7 @@ "Login button label": "Anmeldeschaltflächenbeschriftung", "Login Button Name": "Name der Anmeldeschaltfläche", "Login messages": "Login-Meldungen", + "Login Page Customisation": "Anpassung der Login-Seite", "Login to the platform": "Anmeldung bei der Plattform", "Logo (png, jpg, svg or webp)": "Logo (png, jpg, svg oder webp)", "Logo URL": "Logo URL", @@ -3601,6 +3608,7 @@ "revoked": "Widerrufen", "RFI of type \"request access\" are subject to a specific workflow, that you can configure here. Request Access cases have 2 actions, Validate and Decline, that change the status automatically according to your configuration. Only specific groups of users are authorized to validate and decline Request Access cases.": "RFI des Typs \"Zugang beantragen\" unterliegen einem speziellen Workflow, den Sie hier konfigurieren können. Zugangsgesuche haben 2 Aktionen, Validieren und Ablehnen, die den Status automatisch entsprechend Ihrer Konfiguration ändern. Nur bestimmte Benutzergruppen sind berechtigt, Anträge auf Zugang zu validieren und abzulehnen.", "Rich editor": "Reichhaltiger Editor", + "Right panel customisation": "Anpassung des rechten Panels", "Role": "Rolle", "Roles": "Rollen", "roles": "rollen", @@ -3668,6 +3676,7 @@ "Search the platform": "Die Plattform durchsuchen", "Search these results": "Diese Ergebnisse durchsuchen", "second": "zweite", + "Second color": "Zweite Farbe", "Secondary color": "Sekundärfarbe", "Secondary motivations": "Sekundäre Motivationen", "seconds": "sekunden", @@ -3689,6 +3698,7 @@ "see metrics on your platform (coming soon)": "metriken auf Ihrer Plattform sehen (in Kürze)", "See more": "Mehr sehen", "Select": "Wählen Sie", + "Select a background type": "Wählen Sie einen Hintergrundtyp", "Select a column to add": "Wählen Sie eine Spalte zum Hinzufügen", "Select a configuration": "Wählen Sie eine Konfiguration", "Select a connector": "Wählen Sie einen Anschluss", diff --git a/opencti-platform/opencti-front/lang/front/en.json b/opencti-platform/opencti-front/lang/front/en.json index 3259e578fc0f..a8ddf6591b55 100644 --- a/opencti-platform/opencti-front/lang/front/en.json +++ b/opencti-platform/opencti-front/lang/front/en.json @@ -125,6 +125,9 @@ "Add and complete": "Add and complete", "Add attack patterns": "Add attack patterns", "Add attributes of the instance": "Add attributes of the {type}", + "Add background color": "Add background color", + "Add background gradient": "Add background gradient", + "Add background image": "Add background image", "Add citizenship": "Add citizenship", "Add components": "Add components", "Add context": "Add context", @@ -149,6 +152,7 @@ "Add generated and existing indicators in the container": "Add generated & existing indicators in the container", "Add generated and existing observables in the container": "Add generated & existing observables in the container", "Add header": "Add header", + "Add image URL": "Add image URL", "Add in container": "Add in container", "Add indicators": "Add indicators", "Add individual": "Add individual", @@ -1880,6 +1884,7 @@ "FINTEL template created": "FINTEL template created", "FINTEL Templates": "FINTEL Templates", "FINTEL templates are available with an Enterprise Edition subscription": "FINTEL templates are available with an Enterprise Edition subscription", + "First color": "First color", "First match": "First match", "First name expression": "First name expression", "First obs.": "First obs.", @@ -2119,6 +2124,7 @@ "If you want to keep the associated information, we recommend deactivating the user instead.": "If you want to keep the associated information, we recommend deactivating the user instead.", "If your email address is found, an email will be sent to you.": "If your email address is found, an email will be sent to you.", "if your service account has been created originally as a service account (not transformed), please also change the email of your service account before/after transforming it to a user to ensure that the future user will be able to receive an email in the forgot password workflow.": "if your service account has been created originally as a service account (not transformed), please also change the email of your service account before/after transforming it to a user to ensure that the future user will be able to receive an email in the forgot password workflow.", + "Image URL": "Image URL", "Impact": "Impact", "Impacted": "Impacted", "impacted by a modification to a linked entity (relation, added in container...)": "impacted by a modification to a linked entity (relation, added in container...)", @@ -2498,6 +2504,7 @@ "Login button label": "Login button label", "Login Button Name": "Login Button Name", "Login messages": "Login messages", + "Login Page Customisation": "Login Page Customisation", "Login to the platform": "Login to the platform", "Logo (png, jpg, svg or webp)": "Logo (png, jpg, svg or webp)", "Logo URL": "Logo URL", @@ -3601,6 +3608,7 @@ "revoked": "Revoked", "RFI of type \"request access\" are subject to a specific workflow, that you can configure here. Request Access cases have 2 actions, Validate and Decline, that change the status automatically according to your configuration. Only specific groups of users are authorized to validate and decline Request Access cases.": "RFI of type \"request access\" are subject to a specific workflow, that you can configure here. Request Access cases have 2 actions, Validate and Decline, that change the status automatically according to your configuration. Only specific groups of users are authorized to validate and decline Request Access cases.", "Rich editor": "Rich editor", + "Right panel customisation": "Right panel customisation", "Role": "Role", "Roles": "Roles", "roles": "roles", @@ -3668,6 +3676,7 @@ "Search the platform": "Search the platform", "Search these results": "Search these results", "second": "second", + "Second color": "Second color", "Secondary color": "Secondary color", "Secondary motivations": "Secondary motivations", "seconds": "seconds", @@ -3689,6 +3698,7 @@ "see metrics on your platform (coming soon)": "see metrics on your platform (coming soon)", "See more": "See more", "Select": "Select", + "Select a background type": "Select a background type", "Select a column to add": "Select a column to add", "Select a configuration": "Select a configuration", "Select a connector": "Select a connector", diff --git a/opencti-platform/opencti-front/lang/front/es.json b/opencti-platform/opencti-front/lang/front/es.json index 9191158654dc..8c285fe8faed 100644 --- a/opencti-platform/opencti-front/lang/front/es.json +++ b/opencti-platform/opencti-front/lang/front/es.json @@ -125,6 +125,9 @@ "Add and complete": "Agregar y completar", "Add attack patterns": "Añadir patrones de ataque", "Add attributes of the instance": "Añadir atributos de la {type}", + "Add background color": "Añadir color de fondo", + "Add background gradient": "Añadir degradado de fondo", + "Add background image": "Añadir imagen de fondo", "Add citizenship": "Añadir ciudadanía", "Add components": "Añadir componentes", "Add context": "Agregar contexto", @@ -149,6 +152,7 @@ "Add generated and existing indicators in the container": "Añadir & generado; indicadores existentes en el contenedor", "Add generated and existing observables in the container": "Añadir observables generados & existentes en el contenedor", "Add header": "Añadir cabecera", + "Add image URL": "Añadir URL de imagen", "Add in container": "Añadir en contenedor", "Add indicators": "Añadir indicadores", "Add individual": "Agregar individuo", @@ -1880,6 +1884,7 @@ "FINTEL template created": "Plantilla FINTEL creada", "FINTEL Templates": "Plantillas FINTEL", "FINTEL templates are available with an Enterprise Edition subscription": "Las plantillas FINTEL están disponibles con una suscripción Enterprise Edition", + "First color": "Primer color", "First match": "Primer partido", "First name expression": "Expresión de nombre", "First obs.": "Primera obs.", @@ -2119,6 +2124,7 @@ "If you want to keep the associated information, we recommend deactivating the user instead.": "Si desea conservar la información asociada, le recomendamos desactivar el usuario.", "If your email address is found, an email will be sent to you.": "Si su dirección de correo electrónico se encuentra, se le enviará un correo electrónico.", "if your service account has been created originally as a service account (not transformed), please also change the email of your service account before/after transforming it to a user to ensure that the future user will be able to receive an email in the forgot password workflow.": "si su cuenta de servicio se ha creado originalmente como una cuenta de servicio (no transformada), cambie también el correo electrónico de su cuenta de servicio antes/después de transformarla en un usuario para asegurarse de que el futuro usuario podrá recibir un correo electrónico en el flujo de trabajo de olvido de contraseña.", + "Image URL": "URL de la imagen", "Impact": "Impacto", "Impacted": "Impactado", "impacted by a modification to a linked entity (relation, added in container...)": "afectado por una modificación de una entidad vinculada (relación, añadido en contenedor...)", @@ -2498,6 +2504,7 @@ "Login button label": "Etiqueta del botón de inicio de sesión", "Login Button Name": "Nombre del botón de inicio de sesión", "Login messages": "Mensajes de inicio de sesión", + "Login Page Customisation": "Personalización de la página de inicio de sesión", "Login to the platform": "Inicio de sesión en la plataforma", "Logo (png, jpg, svg or webp)": "Logotipo (png, jpg, svg o webp)", "Logo URL": "Dirección URL del logo", @@ -3601,6 +3608,7 @@ "revoked": "Revocado", "RFI of type \"request access\" are subject to a specific workflow, that you can configure here. Request Access cases have 2 actions, Validate and Decline, that change the status automatically according to your configuration. Only specific groups of users are authorized to validate and decline Request Access cases.": "Las RFI de tipo \"solicitud de acceso\" están sujetas a un flujo de trabajo específico, que puede configurar aquí. Los casos de solicitud de acceso tienen 2 acciones, Validar y Rechazar, que cambian el estado automáticamente según su configuración. Sólo determinados grupos de usuarios están autorizados a validar y rechazar casos de solicitud de acceso.", "Rich editor": "Editor enriquecido", + "Right panel customisation": "Personalización del panel derecho", "Role": "Rol", "Roles": "Roles", "roles": "Roles", @@ -3668,6 +3676,7 @@ "Search the platform": "Buscar en la plataforma", "Search these results": "Buscar estos resultados", "second": "segundo", + "Second color": "Segundo color", "Secondary color": "Color secundario", "Secondary motivations": "Motivaciones secundarias", "seconds": "segundos", @@ -3689,6 +3698,7 @@ "see metrics on your platform (coming soon)": "ver métricas en su plataforma (próximamente)", "See more": "Ver más", "Select": "Seleccione", + "Select a background type": "Seleccione un tipo de fondo", "Select a column to add": "Seleccione una columna para añadir", "Select a configuration": "Seleccione una configuración", "Select a connector": "Seleccione un conector", diff --git a/opencti-platform/opencti-front/lang/front/fr.json b/opencti-platform/opencti-front/lang/front/fr.json index 4ec5a6754054..b8796d43b139 100644 --- a/opencti-platform/opencti-front/lang/front/fr.json +++ b/opencti-platform/opencti-front/lang/front/fr.json @@ -125,6 +125,9 @@ "Add and complete": "Ajouter et compléter", "Add attack patterns": "Ajouter des motifs d'attaque", "Add attributes of the instance": "Ajouter des attributs de l'élément {type}", + "Add background color": "Ajouter une couleur de fond", + "Add background gradient": "Ajouter un dégradé d'arrière-plan", + "Add background image": "Ajouter une image d'arrière-plan", "Add citizenship": "Ajouter la citoyenneté", "Add components": "Ajouter des composants", "Add context": "Ajouter du contexte", @@ -149,6 +152,7 @@ "Add generated and existing indicators in the container": "Ajouter les indicateurs générés et existants dans le conteneur", "Add generated and existing observables in the container": "Ajouter les observables générés et existants dans le conteneur", "Add header": "Ajouter un en-tête", + "Add image URL": "Ajouter l'image URL", "Add in container": "Ajout dans un conteneur", "Add indicators": "Ajouter des indicateurs", "Add individual": "Ajouter un individu", @@ -1880,6 +1884,7 @@ "FINTEL template created": "Création d'un modèle FINTEL", "FINTEL Templates": "Modèles FINTEL", "FINTEL templates are available with an Enterprise Edition subscription": "Les modèles FINTEL sont disponibles avec un abonnement à l'édition Entreprise", + "First color": "Première couleur", "First match": "Premier match", "First name expression": "Expression du prénom", "First obs.": "Première obs.", @@ -2119,6 +2124,7 @@ "If you want to keep the associated information, we recommend deactivating the user instead.": "Si vous souhaitez conserver les informations associées, nous vous recommandons plutôt de désactiver l’utilisateur.", "If your email address is found, an email will be sent to you.": "Si votre adresse électronique est trouvée, un courriel vous sera envoyé.", "if your service account has been created originally as a service account (not transformed), please also change the email of your service account before/after transforming it to a user to ensure that the future user will be able to receive an email in the forgot password workflow.": "si votre compte de service a été créé à l'origine en tant que compte de service (non transformé), veuillez également modifier l'adresse électronique de votre compte de service avant/après sa transformation en utilisateur afin de vous assurer que le futur utilisateur sera en mesure de recevoir un courrier électronique dans le flux de travail \"mot de passe oublié\".", + "Image URL": "URL de l'image", "Impact": "Impact", "Impacted": "Impactés", "impacted by a modification to a linked entity (relation, added in container...)": "impacté par une modification d'une entité liée (relation, ajout dans un conteneur...)", @@ -2498,6 +2504,7 @@ "Login button label": "Libellé du bouton de connexion", "Login Button Name": "Nom du bouton de connexion", "Login messages": "Messages de connexion", + "Login Page Customisation": "Personnalisation de la page de connexion", "Login to the platform": "Connexion à la plateforme", "Logo (png, jpg, svg or webp)": "Logo (png, jpg, svg ou webp)", "Logo URL": "URL du logo", @@ -3601,6 +3608,7 @@ "revoked": "Révoqué", "RFI of type \"request access\" are subject to a specific workflow, that you can configure here. Request Access cases have 2 actions, Validate and Decline, that change the status automatically according to your configuration. Only specific groups of users are authorized to validate and decline Request Access cases.": "Les demandes d'information de type \"demande d'accès\" sont soumises à un flux de travail spécifique, que vous pouvez configurer ici. Les demandes d'accès ont deux actions, Valider et Refuser, qui modifient automatiquement le statut en fonction de votre configuration. Seuls des groupes d'utilisateurs spécifiques sont autorisés à valider et à refuser les demandes d'accès.", "Rich editor": "Editeur enrichi", + "Right panel customisation": "Personnalisation du panneau de droite", "Role": "Rôle", "Roles": "Rôles", "roles": "Rôles", @@ -3668,6 +3676,7 @@ "Search the platform": "Rechercher dans la plateforme", "Search these results": "Rechercher ces résultats", "second": "deuxième", + "Second color": "Deuxième couleur", "Secondary color": "Couleur secondaire", "Secondary motivations": "Motivations secondaires", "seconds": "secondes", @@ -3689,6 +3698,7 @@ "see metrics on your platform (coming soon)": "voir les indicateurs sur votre plateforme (bientôt disponible)", "See more": "Voir plus de détails", "Select": "Sélectionnez", + "Select a background type": "Sélectionner un type d'arrière-plan", "Select a column to add": "Sélectionner une colonne à ajouter", "Select a configuration": "Sélectionner une configuration", "Select a connector": "Sélectionner un connecteur", diff --git a/opencti-platform/opencti-front/lang/front/it.json b/opencti-platform/opencti-front/lang/front/it.json index 70a9fa6edfe9..5c6a11020386 100644 --- a/opencti-platform/opencti-front/lang/front/it.json +++ b/opencti-platform/opencti-front/lang/front/it.json @@ -125,6 +125,9 @@ "Add and complete": "Aggiungi e completa", "Add attack patterns": "Aggiungi pattern di attacco", "Add attributes of the instance": "Aggiungi attributi all'istanza {type}", + "Add background color": "Aggiungere il colore di sfondo", + "Add background gradient": "Aggiungi gradiente di sfondo", + "Add background image": "Aggiungi immagine di sfondo", "Add citizenship": "Aggiungi cittadinanza", "Add components": "Aggiungi componenti", "Add context": "Aggiungi contesto", @@ -149,6 +152,7 @@ "Add generated and existing indicators in the container": "Aggiungi indicatori generati ed esistenti nel container", "Add generated and existing observables in the container": "Aggiungi osservabili generati ed esistenti nel container", "Add header": "Aggiungi intestazione", + "Add image URL": "Aggiungi URL immagine", "Add in container": "Aggiungi in un container", "Add indicators": "Aggiungi degli indicatori", "Add individual": "Aggiungi individuo", @@ -1880,6 +1884,7 @@ "FINTEL template created": "Template FINTEL creato", "FINTEL Templates": "Template FINTEL", "FINTEL templates are available with an Enterprise Edition subscription": "I template FINTEL sono disponibili con un abbonamento all'edizione Enterprise", + "First color": "Primo colore", "First match": "Prima corrispondenza", "First name expression": "Espressione nome", "First obs.": "Prima oss.", @@ -2119,6 +2124,7 @@ "If you want to keep the associated information, we recommend deactivating the user instead.": "Se vuoi mantenere le informazioni associate, ti consigliamo di disattivare l'utente invece.", "If your email address is found, an email will be sent to you.": "Se il vostro indirizzo e-mail viene trovato, vi verrà inviata un'e-mail.", "if your service account has been created originally as a service account (not transformed), please also change the email of your service account before/after transforming it to a user to ensure that the future user will be able to receive an email in the forgot password workflow.": "se il vostro account di servizio è stato creato originariamente come account di servizio (non trasformato), modificate anche l'e-mail del vostro account di servizio prima/dopo averlo trasformato in utente, per garantire che il futuro utente sia in grado di ricevere un'e-mail nel flusso di lavoro dimentica password.", + "Image URL": "URL immagine", "Impact": "Impatto", "Impacted": "Impattato", "impacted by a modification to a linked entity (relation, added in container...)": "impatto di una modifica a un'entità collegata (relazione, aggiunta in un contenitore...)", @@ -2498,6 +2504,7 @@ "Login button label": "Etichetta pulsante login", "Login Button Name": "Nome del pulsante di accesso", "Login messages": "Messaggi di login", + "Login Page Customisation": "Personalizzazione della pagina di accesso", "Login to the platform": "Accedi alla piattaforma", "Logo (png, jpg, svg or webp)": "Logo (png, jpg, svg o webp)", "Logo URL": "URL del logo", @@ -3601,6 +3608,7 @@ "revoked": "revocato", "RFI of type \"request access\" are subject to a specific workflow, that you can configure here. Request Access cases have 2 actions, Validate and Decline, that change the status automatically according to your configuration. Only specific groups of users are authorized to validate and decline Request Access cases.": "Le RFI di tipo \"richiesta di accesso\" sono soggette a un flusso di lavoro specifico, che si può configurare qui. I casi di richiesta di accesso hanno 2 azioni, Convalida e Rifiuta, che cambiano automaticamente lo stato in base alla configurazione. Solo gruppi specifici di utenti sono autorizzati a convalidare e rifiutare i casi di richiesta di accesso.", "Rich editor": "Editor ricco", + "Right panel customisation": "Personalizzazione del pannello destro", "Role": "Ruolo", "Roles": "Ruoli", "roles": "ruoli", @@ -3668,6 +3676,7 @@ "Search the platform": "Cerca nella piattaforma", "Search these results": "Cerca questi risultati", "second": "secondo", + "Second color": "Secondo colore", "Secondary color": "Colore secondario", "Secondary motivations": "Motivazioni secondarie", "seconds": "secondi", @@ -3689,6 +3698,7 @@ "see metrics on your platform (coming soon)": "vedere le metriche sulla vostra piattaforma (in arrivo)", "See more": "Vedere di più", "Select": "Seleziona", + "Select a background type": "Selezionare un tipo di sfondo", "Select a column to add": "Seleziona una colonna da aggiungere", "Select a configuration": "Selezionare una configurazione", "Select a connector": "Seleziona un connettore", diff --git a/opencti-platform/opencti-front/lang/front/ja.json b/opencti-platform/opencti-front/lang/front/ja.json index 446f4ce5ef41..52174106a337 100644 --- a/opencti-platform/opencti-front/lang/front/ja.json +++ b/opencti-platform/opencti-front/lang/front/ja.json @@ -125,6 +125,9 @@ "Add and complete": "追加して完成", "Add attack patterns": "攻撃パターンを追加", "Add attributes of the instance": "0}}の属性を追加", + "Add background color": "背景色の追加", + "Add background gradient": "背景グラデーションの追加", + "Add background image": "背景画像を追加", "Add citizenship": "市民権の追加", "Add components": "コンポーネントを追加する", "Add context": "コンテキストを追加", @@ -149,6 +152,7 @@ "Add generated and existing indicators in the container": "生成された&を追加; コンテナ内の既存のインジケータ", "Add generated and existing observables in the container": "生成された&既存の観測値をコンテナに追加する。", "Add header": "ヘッダーの追加", + "Add image URL": "画像URLを追加", "Add in container": "コンテナに追加", "Add indicators": "インジケータの追加", "Add individual": "個人を追加", @@ -1880,6 +1884,7 @@ "FINTEL template created": "FINTELテンプレート作成", "FINTEL Templates": "FINTELテンプレート", "FINTEL templates are available with an Enterprise Edition subscription": "FINTELテンプレートはEnterprise Editionのサブスクリプションでご利用いただけます。", + "First color": "最初の色", "First match": "最初のマッチ", "First name expression": "名式", "First obs.": "初観測日時", @@ -2119,6 +2124,7 @@ "If you want to keep the associated information, we recommend deactivating the user instead.": "関連情報を保持したい場合は、代わりにユーザーを非アクティブ化することをお勧めします。", "If your email address is found, an email will be sent to you.": "あなたのメールアドレスが見つかった場合、Eメールが送信されます。", "if your service account has been created originally as a service account (not transformed), please also change the email of your service account before/after transforming it to a user to ensure that the future user will be able to receive an email in the forgot password workflow.": "サービスアカウントが元々サービスアカウントとして作成されている(変換されていない)場合、パスワード忘れワークフローで将来のユーザーが確実にメールを受信できるように、ユーザーへの変換前/後のサービスアカウントのメールも変更してください。", + "Image URL": "画像URL", "Impact": "衝撃", "Impacted": "影響", "impacted by a modification to a linked entity (relation, added in container...)": "リンクされたエンティティ(関係、コンテナへの追加...)への変更により影響を受けた。", @@ -2498,6 +2504,7 @@ "Login button label": "ログインボタンのラベル", "Login Button Name": "ログインボタン名", "Login messages": "ログインメッセージ", + "Login Page Customisation": "ログインページのカスタマイズ", "Login to the platform": "プラットフォームへのログイン", "Logo (png, jpg, svg or webp)": "ロゴ (png, jpg, svg または webp)", "Logo URL": "ロゴURL", @@ -3601,6 +3608,7 @@ "revoked": "失効", "RFI of type \"request access\" are subject to a specific workflow, that you can configure here. Request Access cases have 2 actions, Validate and Decline, that change the status automatically according to your configuration. Only specific groups of users are authorized to validate and decline Request Access cases.": "quot;リクエストアクセス\"タイプのRFIは、ここで設定できる特定のワークフローの対象となります。リクエストアクセスケースには[有効化]と[拒否]の2つのアクションがあり、設定に従って自動的にステータスが変更されます。リクエストアクセスケースを検証および拒否する権限を持つのは、特定のユーザーグループのみです。", "Rich editor": "リッチエディタ", + "Right panel customisation": "右パネルのカスタマイズ", "Role": "ロール", "Roles": "ロール", "roles": "ロール", @@ -3668,6 +3676,7 @@ "Search the platform": "プラットフォーム内で検索する", "Search these results": "これらの結果を検索", "second": "第二に", + "Second color": "セカンドカラー", "Secondary color": "セカンダリーカラー", "Secondary motivations": "二次的動機", "seconds": "秒", @@ -3689,6 +3698,7 @@ "see metrics on your platform (coming soon)": "プラットフォーム上のメトリクスを見る(近日公開)", "See more": "もっと見る", "Select": "選択する", + "Select a background type": "背景タイプの選択", "Select a column to add": "追加する列を選択する", "Select a configuration": "コンフィギュレーションを選択する", "Select a connector": "コネクタを選択してください", diff --git a/opencti-platform/opencti-front/lang/front/ko.json b/opencti-platform/opencti-front/lang/front/ko.json index 82d1db29119a..525087ccf15b 100644 --- a/opencti-platform/opencti-front/lang/front/ko.json +++ b/opencti-platform/opencti-front/lang/front/ko.json @@ -125,6 +125,9 @@ "Add and complete": "추가 및 완료", "Add attack patterns": "공격 패턴 추가", "Add attributes of the instance": "{type}의 속성을 추가합니다", + "Add background color": "배경색 추가", + "Add background gradient": "배경 그라데이션 추가", + "Add background image": "배경 이미지 추가", "Add citizenship": "시민권 추가", "Add components": "구성 요소 추가", "Add context": "컨텍스트 추가", @@ -149,6 +152,7 @@ "Add generated and existing indicators in the container": "컨테이너에 생성된 & 기존 지표 추가", "Add generated and existing observables in the container": "컨테이너에 생성된 & 기존 지표 추가", "Add header": "헤더 추가", + "Add image URL": "이미지 URL 추가", "Add in container": "컨테이너에 추가", "Add indicators": "지표 추가", "Add individual": "개인 추가", @@ -1880,6 +1884,7 @@ "FINTEL template created": "핀텔 템플릿 생성", "FINTEL Templates": "FINTEL 템플릿", "FINTEL templates are available with an Enterprise Edition subscription": "FINTEL 템플릿은 엔터프라이즈 에디션 구독을 통해 사용할 수 있습니다", + "First color": "첫 번째 색상", "First match": "첫 번째 경기", "First name expression": "이름 표현식", "First obs.": "최초 관찰", @@ -2119,6 +2124,7 @@ "If you want to keep the associated information, we recommend deactivating the user instead.": "관련 정보를 유지하려면 사용자를 비활성화하는 것이 좋습니다.", "If your email address is found, an email will be sent to you.": "이메일 주소가 확인되면 이메일이 전송됩니다.", "if your service account has been created originally as a service account (not transformed), please also change the email of your service account before/after transforming it to a user to ensure that the future user will be able to receive an email in the forgot password workflow.": "서비스 계정을 원래 서비스 계정으로 만든 경우(변환하지 않은 경우), 서비스 계정을 사용자로 변환하기 전/후에 서비스 계정의 이메일도 변경하여 향후 사용자가 비밀번호 분실 워크플로에서 이메일을 받을 수 있도록 하세요.", + "Image URL": "이미지 URL", "Impact": "영향", "Impacted": "영향받음", "impacted by a modification to a linked entity (relation, added in container...)": "연결된 엔터티(관계, 컨테이너에 추가됨...)에 대한 수정으로 영향을 받았습니다", @@ -2498,6 +2504,7 @@ "Login button label": "로그인 버튼 레이블", "Login Button Name": "로그인 버튼 이름", "Login messages": "로그인 메시지", + "Login Page Customisation": "로그인 페이지 사용자 지정", "Login to the platform": "플랫폼에 로그인", "Logo (png, jpg, svg or webp)": "로고(png, jpg, svg 또는 webp)", "Logo URL": "로고 URL", @@ -3601,6 +3608,7 @@ "revoked": "취소됨", "RFI of type \"request access\" are subject to a specific workflow, that you can configure here. Request Access cases have 2 actions, Validate and Decline, that change the status automatically according to your configuration. Only specific groups of users are authorized to validate and decline Request Access cases.": "'액세스 요청' 유형의 RFI는 여기에서 구성할 수 있는 특정 워크플로우의 적용을 받습니다. 액세스 요청 케이스에는 유효성 검사 및 거부라는 두 가지 작업이 있으며, 구성에 따라 상태가 자동으로 변경됩니다. 특정 사용자 그룹만 액세스 요청 케이스를 유효성 검사하고 거부할 수 있는 권한이 있습니다.", "Rich editor": "리치 에디터", + "Right panel customisation": "오른쪽 패널 사용자 지정", "Role": "역할", "Roles": "역할", "roles": "역할", @@ -3668,6 +3676,7 @@ "Search the platform": "플랫폼 검색", "Search these results": "이 결과 검색", "second": "second", + "Second color": "두 번째 색상", "Secondary color": "보조 색상", "Secondary motivations": "부차적 동기", "seconds": "초", @@ -3689,6 +3698,7 @@ "see metrics on your platform (coming soon)": "플랫폼에서 메트릭 보기(곧 제공 예정)", "See more": "더 보기", "Select": "선택", + "Select a background type": "배경 유형 선택", "Select a column to add": "추가할 열을 선택합니다", "Select a configuration": "구성 선택", "Select a connector": "커넥터를 선택하세요", diff --git a/opencti-platform/opencti-front/lang/front/ru.json b/opencti-platform/opencti-front/lang/front/ru.json index c34644a27bed..f4cf8ac572d5 100644 --- a/opencti-platform/opencti-front/lang/front/ru.json +++ b/opencti-platform/opencti-front/lang/front/ru.json @@ -125,6 +125,9 @@ "Add and complete": "Добавить и завершить", "Add attack patterns": "Добавить шаблоны атак", "Add attributes of the instance": "Добавить атрибуты экземпляра", + "Add background color": "Добавьте цвет фона", + "Add background gradient": "Добавить фоновый градиент", + "Add background image": "Добавить фоновое изображение", "Add citizenship": "Добавить гражданство", "Add components": "Добавить компоненты", "Add context": "Добавить контекст", @@ -149,6 +152,7 @@ "Add generated and existing indicators in the container": "Добавить сгенерированные и существующие индикаторы в контейнер", "Add generated and existing observables in the container": "Добавить сгенерированные и существующие наблюдаемые объекты в контейнер", "Add header": "Добавить заголовок", + "Add image URL": "Добавить URL-адрес изображения", "Add in container": "Добавить в контейнер", "Add indicators": "Добавить индикаторы", "Add individual": "Добавить физическое лицо", @@ -1880,6 +1884,7 @@ "FINTEL template created": "Создан шаблон FINTEL", "FINTEL Templates": "Шаблоны FINTEL", "FINTEL templates are available with an Enterprise Edition subscription": "Шаблоны FINTEL доступны по подписке на Enterprise Edition", + "First color": "Первый цвет", "First match": "Первый матч", "First name expression": "Выражение имени", "First obs.": "Первые наблюдения.", @@ -2119,6 +2124,7 @@ "If you want to keep the associated information, we recommend deactivating the user instead.": "Если вы хотите сохранить связанную с ним информацию, мы рекомендуем отключить пользователя.", "If your email address is found, an email will be sent to you.": "Если ваш адрес электронной почты найден, вам будет отправлено письмо.", "if your service account has been created originally as a service account (not transformed), please also change the email of your service account before/after transforming it to a user to ensure that the future user will be able to receive an email in the forgot password workflow.": "если ваша учетная запись сервиса была создана изначально как учетная запись сервиса (не преобразована), пожалуйста, также измените электронную почту учетной записи сервиса до/после преобразования ее в пользователя, чтобы будущий пользователь смог получить электронное письмо в рабочем процессе \"Забыли пароль\".", + "Image URL": "URL-адрес изображения", "Impact": "Воздействие", "Impacted": "Пострадавшие", "impacted by a modification to a linked entity (relation, added in container...)": "под влиянием изменения связанной сущности (отношения, добавления в контейнер...)", @@ -2498,6 +2504,7 @@ "Login button label": "Метка кнопки входа", "Login Button Name": "Имя кнопки входа в систему", "Login messages": "Сообщения для входа в систему", + "Login Page Customisation": "Настройка страницы входа", "Login to the platform": "Вход на платформу", "Logo (png, jpg, svg or webp)": "Логотип (png, jpg, svg или webp)", "Logo URL": "URL-адрес логотипа", @@ -3601,6 +3608,7 @@ "revoked": "отозвано", "RFI of type \"request access\" are subject to a specific workflow, that you can configure here. Request Access cases have 2 actions, Validate and Decline, that change the status automatically according to your configuration. Only specific groups of users are authorized to validate and decline Request Access cases.": "RFI типа \"запрос доступа\" подчиняются определенному рабочему процессу, который вы можете настроить здесь. У случаев запроса доступа есть 2 действия, Validate и Decline, которые автоматически изменяют статус в соответствии с вашей конфигурацией. Только определенные группы пользователей имеют право подтверждать и отклонять запросы на доступ.", "Rich editor": "Богатый редактор", + "Right panel customisation": "Настройка правой панели", "Role": "Роль", "Roles": "Роли", "roles": "роли", @@ -3668,6 +3676,7 @@ "Search the platform": "Поиск по платформе", "Search these results": "Поиск по результатам", "second": "второй", + "Second color": "Второй цвет", "Secondary color": "Вторичный цвет", "Secondary motivations": "Вторичные мотивы", "seconds": "секунды", @@ -3689,6 +3698,7 @@ "see metrics on your platform (coming soon)": "просмотр показателей на вашей платформе (скоро)", "See more": "См. подробнее", "Select": "Выберите", + "Select a background type": "Выберите тип фона", "Select a column to add": "Выберите столбец для добавления", "Select a configuration": "Выберите конфигурацию", "Select a connector": "Выберите коннектор", diff --git a/opencti-platform/opencti-front/lang/front/zh.json b/opencti-platform/opencti-front/lang/front/zh.json index 120bdf95801b..71f859c49ab7 100644 --- a/opencti-platform/opencti-front/lang/front/zh.json +++ b/opencti-platform/opencti-front/lang/front/zh.json @@ -125,6 +125,9 @@ "Add and complete": "添加并完成", "Add attack patterns": "添加攻击模式", "Add attributes of the instance": "添加 {type} 的属性", + "Add background color": "添加背景颜色", + "Add background gradient": "添加背景渐变", + "Add background image": "添加背景图像", "Add citizenship": "添加公民身份", "Add components": "添加组件", "Add context": "添加上下文", @@ -149,6 +152,7 @@ "Add generated and existing indicators in the container": "添加生成的 & 容器中的现有指标", "Add generated and existing observables in the container": "在容器中添加生成的和现有的观测值", "Add header": "添加标题", + "Add image URL": "添加图像 URL", "Add in container": "添加到容器中", "Add indicators": "添加指标", "Add individual": "添加个人", @@ -1880,6 +1884,7 @@ "FINTEL template created": "创建 FINTEL 模板", "FINTEL Templates": "FINTEL 模板", "FINTEL templates are available with an Enterprise Edition subscription": "订购企业版可获得 FINTEL 模板", + "First color": "第一种颜色", "First match": "第一场比赛", "First name expression": "名字表达式", "First obs.": "首次观测.", @@ -2119,6 +2124,7 @@ "If you want to keep the associated information, we recommend deactivating the user instead.": "如果您想保留关联信息,我们建议您停用该用户。", "If your email address is found, an email will be sent to you.": "如果找到了您的电子邮件地址,我们将向您发送一封电子邮件。", "if your service account has been created originally as a service account (not transformed), please also change the email of your service account before/after transforming it to a user to ensure that the future user will be able to receive an email in the forgot password workflow.": "如果您的服务账户最初是作为服务账户创建的(未转换),请在将服务账户转换为用户之前/之后更改服务账户的电子邮件,以确保未来的用户能够在忘记密码工作流程中收到电子邮件。", + "Image URL": "图像 URL", "Impact": "影响", "Impacted": "影响", "impacted by a modification to a linked entity (relation, added in container...)": "受关联实体(关系、在容器中添加......)修改的影响", @@ -2498,6 +2504,7 @@ "Login button label": "登录按钮标签", "Login Button Name": "登录按钮名称", "Login messages": "登录信息", + "Login Page Customisation": "登录页面定制", "Login to the platform": "登录平台", "Logo (png, jpg, svg or webp)": "徽标(png、jpg、svg 或 webp)", "Logo URL": "徽标 URL", @@ -3601,6 +3608,7 @@ "revoked": "撤销", "RFI of type \"request access\" are subject to a specific workflow, that you can configure here. Request Access cases have 2 actions, Validate and Decline, that change the status automatically according to your configuration. Only specific groups of users are authorized to validate and decline Request Access cases.": "请求访问\"类型的 RFI 受制于特定的工作流程,您可以在此进行配置。请求访问 \"案例有 2 个操作:验证和拒绝,可根据您的配置自动更改状态。只有特定用户组才有权验证和拒绝请求访问个案。", "Rich editor": "富编辑器", + "Right panel customisation": "右侧面板定制", "Role": "角色", "Roles": "角色", "roles": "角色", @@ -3668,6 +3676,7 @@ "Search the platform": "在平台搜索", "Search these results": "搜索这些结果", "second": "第二个", + "Second color": "第二种颜色", "Secondary color": "次要颜色", "Secondary motivations": "次要动机", "seconds": "秒", @@ -3689,6 +3698,7 @@ "see metrics on your platform (coming soon)": "查看平台上的指标(即将推出)", "See more": "查看更多", "Select": "选择", + "Select a background type": "选择背景类型", "Select a column to add": "选择要添加的列", "Select a configuration": "选择配置", "Select a connector": "选择一个连接器", diff --git a/opencti-platform/opencti-front/src/private/components/settings/themes/ThemeCreation.tsx b/opencti-platform/opencti-front/src/private/components/settings/themes/ThemeCreation.tsx index 75b91d4001cb..84e302e26145 100644 --- a/opencti-platform/opencti-front/src/private/components/settings/themes/ThemeCreation.tsx +++ b/opencti-platform/opencti-front/src/private/components/settings/themes/ThemeCreation.tsx @@ -1,14 +1,15 @@ -import React, { FunctionComponent } from 'react'; -import { Formik, FormikHelpers } from 'formik'; -import { Disposable, graphql, RecordSourceSelectorProxy } from 'relay-runtime'; +import { ThemeManagerQuery$variables } from '@components/settings/themes/__generated__/ThemeManagerQuery.graphql'; import ThemeForm from '@components/settings/themes/ThemeForm'; import themeValidationSchema from '@components/settings/themes/themeValidation'; -import { ThemeManagerQuery$variables } from '@components/settings/themes/__generated__/ThemeManagerQuery.graphql'; -import useApiMutation from '../../../../utils/hooks/useApiMutation'; +import { Formik, FormikHelpers } from 'formik'; +import { FunctionComponent } from 'react'; +import { Disposable, graphql, RecordSourceSelectorProxy } from 'relay-runtime'; import { useFormatter } from '../../../../components/i18n'; +import useApiMutation from '../../../../utils/hooks/useApiMutation'; +import { insertNode } from '../../../../utils/store'; import Drawer from '../../common/drawer/Drawer'; import { ThemeCreationCreateMutation } from './__generated__/ThemeCreationCreateMutation.graphql'; -import { insertNode } from '../../../../utils/store'; +import { LoginAsideType, ThemeCreationInput } from './ThemeType'; export const createThemeMutation = graphql` mutation ThemeCreationCreateMutation($input: ThemeAddInput!) { @@ -42,7 +43,7 @@ const ThemeCreation: FunctionComponent = ({ const validator = themeValidationSchema(t_i18n); - const initialValues = { + const initialValues: ThemeCreationInput = { name: '', theme_background: '', theme_paper: '', @@ -54,11 +55,16 @@ const ThemeCreation: FunctionComponent = ({ theme_logo: '', theme_logo_collapsed: '', theme_logo_login: '', + theme_login_aside_type: '' as LoginAsideType, + theme_login_aside_color: '', + theme_login_aside_gradient_start: '', + theme_login_aside_gradient_end: '', + theme_login_aside_image: '', }; const handleSubmit = async ( - values: typeof initialValues, - { setSubmitting, resetForm }: FormikHelpers, + values: ThemeCreationInput, + { setSubmitting, resetForm }: FormikHelpers, ) => { try { await validator.validate(values); @@ -76,6 +82,10 @@ const ThemeCreation: FunctionComponent = ({ theme_logo_collapsed: values.theme_logo_collapsed, theme_logo_login: values.theme_logo_login, theme_text_color: values.theme_text_color, + theme_login_aside_color: values.theme_login_aside_color || null, + theme_login_aside_gradient_start: values.theme_login_aside_gradient_start || null, + theme_login_aside_gradient_end: values.theme_login_aside_gradient_end || null, + theme_login_aside_image: values.theme_login_aside_image || null, }, }, updater: (store: RecordSourceSelectorProxy) => insertNode( @@ -101,8 +111,9 @@ const ThemeCreation: FunctionComponent = ({ title={t_i18n('Create a custom theme')} open={open} onClose={handleClose} + size="medium" > - onSubmit={handleSubmit} initialValues={initialValues} validationSchema={validator} diff --git a/opencti-platform/opencti-front/src/private/components/settings/themes/ThemeEdition.tsx b/opencti-platform/opencti-front/src/private/components/settings/themes/ThemeEdition.tsx index 365d9d5290a0..bfb491cb83af 100644 --- a/opencti-platform/opencti-front/src/private/components/settings/themes/ThemeEdition.tsx +++ b/opencti-platform/opencti-front/src/private/components/settings/themes/ThemeEdition.tsx @@ -24,6 +24,10 @@ const editThemeMutation = graphql` theme_logo theme_logo_collapsed theme_logo_login + theme_login_aside_color + theme_login_aside_gradient_start + theme_login_aside_gradient_end + theme_login_aside_image } } `; @@ -69,6 +73,10 @@ const ThemeEdition: FunctionComponent = ({ { key: 'theme_logo_collapsed', value: values.theme_logo_collapsed }, { key: 'theme_logo_login', value: values.theme_logo_login }, { key: 'theme_text_color', value: values.theme_text_color }, + { key: 'theme_login_aside_color', value: values.theme_login_aside_color ?? '' }, + { key: 'theme_login_aside_gradient_start', value: values.theme_login_aside_gradient_start ?? '' }, + { key: 'theme_login_aside_gradient_end', value: values.theme_login_aside_gradient_end ?? '' }, + { key: 'theme_login_aside_image', value: values.theme_login_aside_image ?? '' }, ], }, onCompleted: () => resolve(), @@ -97,7 +105,9 @@ const ThemeEdition: FunctionComponent = ({ resetForm: (nextState?: Partial>) => void, ) => { try { - await validator.validate(values); + await validator.validate(values, { + stripUnknown: true, + }); await updateTheme(values); setSubmitting(false); } catch (error) { @@ -118,13 +128,13 @@ const ThemeEdition: FunctionComponent = ({ title={t_i18n('Update a theme')} open={open} onClose={handleClose} + size="medium" > - initialValues={theme} onSubmit={handleSubmit} validationSchema={validator} validateOnChange - validateOnSubmit enableReinitialize > {({ values, setSubmitting, setErrors, resetForm, errors, isSubmitting, submitForm }) => ( @@ -136,7 +146,7 @@ const ThemeEdition: FunctionComponent = ({ themeId={theme.id} onSubmit={submitForm} onCancel={handleClose} - onChange={() => handleOnChange(values, setSubmitting, setErrors, resetForm)} + onChange={(updatedValues) => handleOnChange(updatedValues ?? values, setSubmitting, setErrors, resetForm)} withButtons={false} /> )} diff --git a/opencti-platform/opencti-front/src/private/components/settings/themes/ThemeExportHandler.tsx b/opencti-platform/opencti-front/src/private/components/settings/themes/ThemeExportHandler.tsx index 19c7061f0833..418f6dce8c76 100644 --- a/opencti-platform/opencti-front/src/private/components/settings/themes/ThemeExportHandler.tsx +++ b/opencti-platform/opencti-front/src/private/components/settings/themes/ThemeExportHandler.tsx @@ -21,7 +21,11 @@ const ThemeExportHandlerQuery = graphql` theme_text_color theme_logo theme_logo_collapsed - theme_logo_login + theme_logo_login + theme_login_aside_color + theme_login_aside_gradient_end + theme_login_aside_gradient_start + theme_login_aside_image } } `; diff --git a/opencti-platform/opencti-front/src/private/components/settings/themes/ThemeForm.tsx b/opencti-platform/opencti-front/src/private/components/settings/themes/ThemeForm.tsx index b59547d34558..776251fb62d9 100644 --- a/opencti-platform/opencti-front/src/private/components/settings/themes/ThemeForm.tsx +++ b/opencti-platform/opencti-front/src/private/components/settings/themes/ThemeForm.tsx @@ -1,12 +1,18 @@ import Button from '@common/button/Button'; -import { Field, Form } from 'formik'; -import { FunctionComponent } from 'react'; +import { InputAdornment, MenuItem, Select, SelectChangeEvent, Stack, Typography } from '@mui/material'; +import { useTheme } from '@mui/styles'; +import { ClearIcon } from '@mui/x-date-pickers'; +import { Field, Form, useFormikContext } from 'formik'; +import { FunctionComponent, useRef, useState } from 'react'; import ColorPickerField from '../../../../components/ColorPickerField'; +import IconButton from '../../../../components/common/button/IconButton'; import FormButtonContainer from '../../../../components/common/form/FormButtonContainer'; +import Label from '../../../../components/common/label/Label'; import { useFormatter } from '../../../../components/i18n'; import TextField from '../../../../components/TextField'; -import { fieldSpacingContainerStyle } from '../../../../utils/field'; +import { Theme } from '../../../../components/Theme'; import ThemeDetectDuplicate from './ThemeDetectDuplicate'; +import ThemeType from './ThemeType'; interface ThemeFormProps { values: { @@ -21,6 +27,10 @@ interface ThemeFormProps { theme_logo?: string | null; theme_logo_collapsed?: string | null; theme_logo_login?: string | null; + theme_login_aside_color?: string | null; + theme_login_aside_gradient_start?: string | null; + theme_login_aside_gradient_end?: string | null; + theme_login_aside_image?: string | null; }; errors?: Record; isSubmitting: boolean; @@ -28,10 +38,17 @@ interface ThemeFormProps { themeId?: string; onSubmit: () => void; onCancel: () => void; - onChange?: () => void; + onChange?: (values?: ThemeType) => void; submitLabel?: string; withButtons?: boolean; } +const loginAsideFields = [ + 'theme_login_aside_type', + 'theme_login_aside_color', + 'theme_login_aside_gradient_start', + 'theme_login_aside_gradient_end', + 'theme_login_aside_image', +] as const; const ThemeForm: FunctionComponent = ({ values, @@ -46,161 +63,293 @@ const ThemeForm: FunctionComponent = ({ withButtons = true, }) => { const { t_i18n } = useFormatter(); + const theme = useTheme(); + + const fieldRef = useRef(null); + const { setFieldValue, initialValues, values: formikValues } = useFormikContext(); + + const [loginAsideType, setLoginAsideType] = useState( + formikValues.theme_login_aside_type || '', + ); const handleFieldSubmit = () => { - if (onChange) { - onChange(); + onChange?.(formikValues); + }; + + const getAsideTypeLabel = (value: string) => { + if (value === 'color') return t_i18n('Add background color'); + if (value === 'gradient') return t_i18n('Add background gradient'); + if (value === 'image') return t_i18n('Add background image'); + return null; + }; + + const handleLoginAsideTypeChange = (event: SelectChangeEvent) => { + const type = event.target.value as '' | 'color' | 'gradient' | 'image'; + setLoginAsideType(type); + + const clearedValues: ThemeType = { + ...formikValues, + theme_login_aside_type: type, + theme_login_aside_color: '', + theme_login_aside_gradient_start: '', + theme_login_aside_gradient_end: '', + theme_login_aside_image: '', + }; + + loginAsideFields.forEach((field) => setFieldValue(field, clearedValues[field])); + + const hadSavedValues = loginAsideFields.some((field) => !!initialValues[field]) + || !!initialValues.theme_login_aside_type; + + if (type || hadSavedValues) { + onChange?.(clearedValues); } + + setTimeout(() => { + fieldRef.current?.scrollIntoView({ behavior: 'smooth', block: 'start' }); + }, 50); }; return ( -
- - ) - } - fullWidth - disabled={isSystemDefault} - required - onSubmit={handleFieldSubmit} - /> - - - - - - - - - - - - - - - - - - - - - - { - withButtons && ( - - - - - ) - } + + + + ) + } + fullWidth + disabled={isSystemDefault} + required + onSubmit={handleFieldSubmit} + /> + + {/* COLORS */} + + + + + + + + + + + + + + + {/* LOGOS */} + + + + + + + + {/* LOGIN ASIDE TYPE */} + + + {t_i18n('Login Page Customisation')} + + + + + + + +
+ {loginAsideType === 'color' && ( + + )} + + {loginAsideType === 'gradient' && ( + + + + + + )} + + {loginAsideType === 'image' && ( + + )} +
+
+
+ + {withButtons && ( + + + + + + )} ); }; diff --git a/opencti-platform/opencti-front/src/private/components/settings/themes/ThemeManager.tsx b/opencti-platform/opencti-front/src/private/components/settings/themes/ThemeManager.tsx index 5bda41acae17..373d78beede6 100644 --- a/opencti-platform/opencti-front/src/private/components/settings/themes/ThemeManager.tsx +++ b/opencti-platform/opencti-front/src/private/components/settings/themes/ThemeManager.tsx @@ -37,6 +37,10 @@ export const refetchableThemesQuery = graphql` theme_logo theme_logo_collapsed theme_logo_login + theme_login_aside_color + theme_login_aside_gradient_end + theme_login_aside_gradient_start + theme_login_aside_image } } } @@ -103,6 +107,10 @@ const themesLineFragment = graphql` theme_logo_collapsed theme_logo_login theme_text_color + theme_login_aside_color + theme_login_aside_gradient_end + theme_login_aside_gradient_start + theme_login_aside_image built_in } `; diff --git a/opencti-platform/opencti-front/src/private/components/settings/themes/ThemePopover.tsx b/opencti-platform/opencti-front/src/private/components/settings/themes/ThemePopover.tsx index 56ecf17d95f3..c27578ae0ba8 100644 --- a/opencti-platform/opencti-front/src/private/components/settings/themes/ThemePopover.tsx +++ b/opencti-platform/opencti-front/src/private/components/settings/themes/ThemePopover.tsx @@ -15,6 +15,7 @@ import useApiMutation from '../../../../utils/hooks/useApiMutation'; import { deleteNode } from '../../../../utils/store'; import DeleteDialog from '../../../../components/DeleteDialog'; import { UserContext, UserContextType } from '../../../../utils/hooks/useAuth'; +import { getLoginAsideType } from './theme-utils'; const deleteUserThemeMutation = graphql` mutation ThemePopoverUserDeletionMutation($input: [EditInput!]!) { @@ -69,6 +70,19 @@ const ThemePopover: FunctionComponent = ({ theme_logo_login: themeData.theme_logo_login, theme_text_color: themeData.theme_text_color, system_default: themeData.built_in, + theme_login_aside_color: themeData.theme_login_aside_color, + theme_login_aside_gradient_end: themeData.theme_login_aside_gradient_end, + theme_login_aside_gradient_start: themeData.theme_login_aside_gradient_start, + theme_login_aside_image: themeData.theme_login_aside_image, + + theme_login_aside_type: getLoginAsideType({ + theme_login_aside_color: themeData.theme_login_aside_color, + theme_login_aside_gradient_start: + themeData.theme_login_aside_gradient_start, + theme_login_aside_gradient_end: + themeData.theme_login_aside_gradient_end, + theme_login_aside_image: themeData.theme_login_aside_image, + }), }; const deleteSuccessMessage = t_i18n('', { diff --git a/opencti-platform/opencti-front/src/private/components/settings/themes/ThemeType.ts b/opencti-platform/opencti-front/src/private/components/settings/themes/ThemeType.ts index 9959150a7df3..11b4562822cf 100644 --- a/opencti-platform/opencti-front/src/private/components/settings/themes/ThemeType.ts +++ b/opencti-platform/opencti-front/src/private/components/settings/themes/ThemeType.ts @@ -11,7 +11,17 @@ interface ThemeType { theme_logo_collapsed?: string | null; theme_logo_login?: string | null; theme_text_color: string; + theme_login_aside_color?: string | null; + theme_login_aside_gradient_end?: string | null; + theme_login_aside_gradient_start?: string | null; + theme_login_aside_image?: string | null; system_default?: boolean | null; + // UI only, but single source of truth for formik + theme_login_aside_type: LoginAsideType; } +export type ThemeCreationInput = Omit; + +export type LoginAsideType = '' | 'color' | 'gradient' | 'image'; + export default ThemeType; diff --git a/opencti-platform/opencti-front/src/private/components/settings/themes/theme-utils.ts b/opencti-platform/opencti-front/src/private/components/settings/themes/theme-utils.ts new file mode 100644 index 000000000000..7926a025df20 --- /dev/null +++ b/opencti-platform/opencti-front/src/private/components/settings/themes/theme-utils.ts @@ -0,0 +1,11 @@ +export const getLoginAsideType = (values: { + theme_login_aside_color?: string | null; + theme_login_aside_gradient_start?: string | null; + theme_login_aside_gradient_end?: string | null; + theme_login_aside_image?: string | null; +}) => { + if (values.theme_login_aside_image) return 'image'; + if (values.theme_login_aside_gradient_start || values.theme_login_aside_gradient_end) return 'gradient'; + if (values.theme_login_aside_color) return 'color'; + return ''; +}; diff --git a/opencti-platform/opencti-front/src/private/components/settings/themes/themeValidation.ts b/opencti-platform/opencti-front/src/private/components/settings/themes/themeValidation.ts index 7466374aa9c7..d17d724dd6d0 100644 --- a/opencti-platform/opencti-front/src/private/components/settings/themes/themeValidation.ts +++ b/opencti-platform/opencti-front/src/private/components/settings/themes/themeValidation.ts @@ -3,34 +3,101 @@ import * as Yup from 'yup'; const HEX_COLOR_REGEX = /^#[0-9a-fA-F]{6}$/; const themeValidationSchema = (t_i18n: (key: string) => string) => { - return Yup.object().shape({ + const requiredMsg = t_i18n('This field is required'); + const invalidColorMsg = t_i18n('Invalid color format'); + + return Yup.object({ name: Yup.string() .trim() .min(2) - .required(t_i18n('This field is required')), + .required(requiredMsg), + theme_background: Yup.string() - .matches(HEX_COLOR_REGEX) - .required(t_i18n('This field is required')), + .matches(HEX_COLOR_REGEX, invalidColorMsg) + .required(requiredMsg), + theme_paper: Yup.string() - .matches(HEX_COLOR_REGEX) - .required(t_i18n('This field is required')), + .matches(HEX_COLOR_REGEX, invalidColorMsg) + .required(requiredMsg), + theme_nav: Yup.string() - .matches(HEX_COLOR_REGEX) - .required(t_i18n('This field is required')), + .matches(HEX_COLOR_REGEX, invalidColorMsg) + .required(requiredMsg), + theme_primary: Yup.string() - .matches(HEX_COLOR_REGEX) - .required(t_i18n('This field is required')), + .matches(HEX_COLOR_REGEX, invalidColorMsg) + .required(requiredMsg), + theme_secondary: Yup.string() - .matches(HEX_COLOR_REGEX) - .required(t_i18n('This field is required')), + .matches(HEX_COLOR_REGEX, invalidColorMsg) + .required(requiredMsg), + theme_accent: Yup.string() - .matches(HEX_COLOR_REGEX) - .required(t_i18n('This field is required')), + .matches(HEX_COLOR_REGEX, invalidColorMsg) + .required(requiredMsg), + theme_text_color: Yup.string() - .required(t_i18n('This field is required')), + .matches(HEX_COLOR_REGEX, invalidColorMsg) + .required(requiredMsg), + theme_logo: Yup.string().nullable(), theme_logo_collapsed: Yup.string().nullable(), theme_logo_login: Yup.string().nullable(), + + // the theme login aside validation is based on the type of aside selected, + // because depeding on the type, the required fields are different + theme_login_aside_type: Yup.mixed< + '' | 'color' | 'gradient' | 'image' + >().oneOf(['', 'color', 'gradient', 'image']), + + /** + * COLOR + */ + theme_login_aside_color: Yup.string() + .nullable() + .when('theme_login_aside_type', { + is: 'color', + then: (schema) => + schema + .matches(HEX_COLOR_REGEX, invalidColorMsg) + .required(requiredMsg), + otherwise: (schema) => schema.strip(), + }), + + /** + * GRADIENT START & END + */ + theme_login_aside_gradient_start: Yup.string() + .nullable() + .when('theme_login_aside_type', { + is: 'gradient', + then: (schema) => + schema + .matches(HEX_COLOR_REGEX, invalidColorMsg) + .required(requiredMsg), + otherwise: (schema) => schema.strip(), + }), + theme_login_aside_gradient_end: Yup.string() + .nullable() + .when('theme_login_aside_type', { + is: 'gradient', + then: (schema) => + schema + .matches(HEX_COLOR_REGEX, invalidColorMsg) + .required(requiredMsg), + otherwise: (schema) => schema.strip(), + }), + + /** + * IMAGE + */ + theme_login_aside_image: Yup.string() + .nullable() + .when('theme_login_aside_type', { + is: 'image', + then: (schema) => schema.required(requiredMsg), + otherwise: (schema) => schema.strip(), + }), }); }; diff --git a/opencti-platform/opencti-front/src/public/LoginRoot.tsx b/opencti-platform/opencti-front/src/public/LoginRoot.tsx index 54e4fcd42c1c..80cac87fe57e 100644 --- a/opencti-platform/opencti-front/src/public/LoginRoot.tsx +++ b/opencti-platform/opencti-front/src/public/LoginRoot.tsx @@ -28,6 +28,10 @@ export const rootPublicQuery = graphql` theme_logo theme_logo_collapsed theme_logo_login + theme_login_aside_color + theme_login_aside_gradient_end + theme_login_aside_gradient_start + theme_login_aside_image } platform_login_message platform_consent_message diff --git a/opencti-platform/opencti-front/src/public/components/login/LoginLayout.tsx b/opencti-platform/opencti-front/src/public/components/login/LoginLayout.tsx index 45c9ae137754..f7dfcd807868 100644 --- a/opencti-platform/opencti-front/src/public/components/login/LoginLayout.tsx +++ b/opencti-platform/opencti-front/src/public/components/login/LoginLayout.tsx @@ -10,6 +10,7 @@ import SystemBanners from '../SystemBanners'; import { LoginRootPublicQuery$data } from '../../__generated__/LoginRootPublicQuery.graphql'; import LoginLogo from './LoginLogo'; import { hasCustomColor } from '../../../utils/theme'; +import { getLoginAsideType } from '../../../private/components/settings/themes/theme-utils'; const LogoBaseline = () => { const theme = useTheme(); @@ -66,6 +67,31 @@ const LoginLayout = ({ settings, children }: LoginLayoutProps) => { const isEnterpriseEdition = settings.platform_enterprise_edition_license_validated; const isWhitemarkEnable = settings.platform_whitemark && isEnterpriseEdition; + const loginAsideType = getLoginAsideType({ + theme_login_aside_color: settings.platform_theme?.theme_login_aside_color, + theme_login_aside_gradient_start: settings.platform_theme?.theme_login_aside_gradient_start, + theme_login_aside_gradient_end: settings.platform_theme?.theme_login_aside_gradient_end, + theme_login_aside_image: settings.platform_theme?.theme_login_aside_image, + }); + + const getAsideBackground = () => { + if (loginAsideType === 'color') { + return settings.platform_theme?.theme_login_aside_color; + } + + if (loginAsideType === 'gradient') { + return `linear-gradient(100deg, ${settings.platform_theme?.theme_login_aside_gradient_start} 0%, ${settings.platform_theme?.theme_login_aside_gradient_end} 100%)`; + } + + if (loginAsideType === 'image') { + return `url(${settings.platform_theme?.theme_login_aside_image})`; + } + // fallback to default + return theme.palette.mode === 'dark' + ? 'linear-gradient(100deg, #050A14 0%, #0C1728 100%)' + : 'linear-gradient(100deg, #EAEAED 0%, #FEFEFF 100%)'; + }; + const hasCustomBackground = hasCustomColor(theme, 'theme_background'); const backgroundContent = hasCustomBackground ? theme.palette.background.default @@ -75,16 +101,14 @@ const LoginLayout = ({ settings, children }: LoginLayoutProps) => { minWidth: 500, overflow: 'hidden', background: backgroundContent, - boxShadow: '8px 0px 9px 0px #0000000F', + boxShadow: '8px 0px 9px 0px #0000002F', zIndex: 2, }; - const background = theme.palette.mode === 'dark' - ? 'linear-gradient(100deg, #050A14 0%, #0C1728 100%);' - : 'linear-gradient(100deg, #EAEAED 0%, #FEFEFF 100%)'; - const asideSx: SxProps = { - background, + background: getAsideBackground(), + backgroundSize: loginAsideType === 'image' ? 'cover' : undefined, + backgroundPosition: loginAsideType === 'image' ? 'center' : undefined, position: 'relative', overflow: 'hidden', }; @@ -104,12 +128,8 @@ const LoginLayout = ({ settings, children }: LoginLayoutProps) => { {children} - {!isWhitemarkEnable && ( - <> - - - - )} + {loginAsideType === '' && } + {!isWhitemarkEnable && } diff --git a/opencti-platform/opencti-front/src/schema/relay.schema.graphql b/opencti-platform/opencti-front/src/schema/relay.schema.graphql index c82d766199ca..fdc2a1edc8ee 100644 --- a/opencti-platform/opencti-front/src/schema/relay.schema.graphql +++ b/opencti-platform/opencti-front/src/schema/relay.schema.graphql @@ -14692,6 +14692,10 @@ type Theme implements InternalObject & BasicObject { theme_logo_collapsed: String theme_logo_login: String theme_text_color: String! + theme_login_aside_color: String + theme_login_aside_gradient_start: String + theme_login_aside_gradient_end: String + theme_login_aside_image: String toConfigurationExport: String! built_in: Boolean metrics: [Metric] @@ -14726,6 +14730,10 @@ input ThemeAddInput { theme_logo_collapsed: String theme_logo_login: String theme_text_color: String! + theme_login_aside_color: String + theme_login_aside_gradient_start: String + theme_login_aside_gradient_end: String + theme_login_aside_image: String built_in: Boolean } diff --git a/opencti-platform/opencti-graphql/src/generated/graphql.ts b/opencti-platform/opencti-graphql/src/generated/graphql.ts index d035f4e6649d..2c64fefdf40d 100644 --- a/opencti-platform/opencti-graphql/src/generated/graphql.ts +++ b/opencti-platform/opencti-graphql/src/generated/graphql.ts @@ -32657,6 +32657,10 @@ export type Theme = BasicObject & InternalObject & { standard_id: Scalars['String']['output']; theme_accent: Scalars['String']['output']; theme_background: Scalars['String']['output']; + theme_login_aside_color?: Maybe; + theme_login_aside_gradient_end?: Maybe; + theme_login_aside_gradient_start?: Maybe; + theme_login_aside_image?: Maybe; theme_logo?: Maybe; theme_logo_collapsed?: Maybe; theme_logo_login?: Maybe; @@ -32673,6 +32677,10 @@ export type ThemeAddInput = { name: Scalars['String']['input']; theme_accent: Scalars['String']['input']; theme_background: Scalars['String']['input']; + theme_login_aside_color?: InputMaybe; + theme_login_aside_gradient_end?: InputMaybe; + theme_login_aside_gradient_start?: InputMaybe; + theme_login_aside_image?: InputMaybe; theme_logo?: InputMaybe; theme_logo_collapsed?: InputMaybe; theme_logo_login?: InputMaybe; @@ -49246,6 +49254,10 @@ export type ThemeResolvers; theme_accent?: Resolver; theme_background?: Resolver; + theme_login_aside_color?: Resolver, ParentType, ContextType>; + theme_login_aside_gradient_end?: Resolver, ParentType, ContextType>; + theme_login_aside_gradient_start?: Resolver, ParentType, ContextType>; + theme_login_aside_image?: Resolver, ParentType, ContextType>; theme_logo?: Resolver, ParentType, ContextType>; theme_logo_collapsed?: Resolver, ParentType, ContextType>; theme_logo_login?: Resolver, ParentType, ContextType>; diff --git a/opencti-platform/opencti-graphql/src/modules/theme/theme-constants.ts b/opencti-platform/opencti-graphql/src/modules/theme/theme-constants.ts index 240222319d41..8bcca5af0c17 100644 --- a/opencti-platform/opencti-graphql/src/modules/theme/theme-constants.ts +++ b/opencti-platform/opencti-graphql/src/modules/theme/theme-constants.ts @@ -10,6 +10,10 @@ export const DARK_DEFAULTS = { theme_logo: '', theme_logo_collapsed: '', theme_logo_login: '', + theme_login_aside_color: '', + theme_login_aside_gradient_start: '', + theme_login_aside_gradient_end: '', + theme_login_aside_image: '', }; // Default values for Light theme @@ -24,4 +28,8 @@ export const LIGHT_DEFAULTS = { theme_logo: '', theme_logo_collapsed: '', theme_logo_login: '', + theme_login_aside_color: '', + theme_login_aside_gradient_start: '', + theme_login_aside_gradient_end: '', + theme_login_aside_image: '', }; diff --git a/opencti-platform/opencti-graphql/src/modules/theme/theme-converter.ts b/opencti-platform/opencti-graphql/src/modules/theme/theme-converter.ts index abc925b6e17e..591a27269a51 100644 --- a/opencti-platform/opencti-graphql/src/modules/theme/theme-converter.ts +++ b/opencti-platform/opencti-graphql/src/modules/theme/theme-converter.ts @@ -18,6 +18,10 @@ const convertThemeToStix = (instance: StoreEntityTheme): StixTheme => { theme_logo_collapsed: instance.theme_logo_collapsed, theme_logo_login: instance.theme_logo_login, theme_text_color: instance.theme_text_color, + theme_login_aside_color: instance.theme_login_aside_color, + theme_login_aside_gradient_end: instance.theme_login_aside_gradient_end, + theme_login_aside_gradient_start: instance.theme_login_aside_gradient_start, + theme_login_aside_image: instance.theme_login_aside_image, built_in: instance.built_in, extensions: { [STIX_EXT_OCTI]: cleanObject({ diff --git a/opencti-platform/opencti-graphql/src/modules/theme/theme-domain.ts b/opencti-platform/opencti-graphql/src/modules/theme/theme-domain.ts index 341cd6f2e738..660cb88aecb8 100644 --- a/opencti-platform/opencti-graphql/src/modules/theme/theme-domain.ts +++ b/opencti-platform/opencti-graphql/src/modules/theme/theme-domain.ts @@ -52,6 +52,10 @@ export const addTheme = async (context: AuthContext, user: AuthUser, input: Them theme_logo_collapsed: input.theme_logo_collapsed, theme_logo_login: input.theme_logo_login, theme_text_color: input.theme_text_color, + theme_login_aside_color: input.theme_login_aside_color ?? null, + theme_login_aside_gradient_start: input.theme_login_aside_gradient_start ?? null, + theme_login_aside_gradient_end: input.theme_login_aside_gradient_end ?? null, + theme_login_aside_image: input.theme_login_aside_image ?? null, built_in: input.built_in ?? false, }; @@ -74,6 +78,10 @@ export const initDefaultTheme = async (context: AuthContext, user = SYSTEM_USER) theme_logo: DARK_DEFAULTS.theme_logo, theme_logo_collapsed: DARK_DEFAULTS.theme_logo_collapsed, theme_logo_login: DARK_DEFAULTS.theme_logo_login, + theme_login_aside_color: DARK_DEFAULTS.theme_login_aside_color, + theme_login_aside_gradient_start: DARK_DEFAULTS.theme_login_aside_gradient_start, + theme_login_aside_gradient_end: DARK_DEFAULTS.theme_login_aside_gradient_end, + theme_login_aside_image: DARK_DEFAULTS.theme_login_aside_image, built_in: true, }; @@ -91,6 +99,10 @@ export const initDefaultTheme = async (context: AuthContext, user = SYSTEM_USER) theme_logo: LIGHT_DEFAULTS.theme_logo, theme_logo_collapsed: LIGHT_DEFAULTS.theme_logo_collapsed, theme_logo_login: LIGHT_DEFAULTS.theme_logo_login, + theme_login_aside_color: LIGHT_DEFAULTS.theme_login_aside_color, + theme_login_aside_gradient_start: LIGHT_DEFAULTS.theme_login_aside_gradient_start, + theme_login_aside_gradient_end: LIGHT_DEFAULTS.theme_login_aside_gradient_end, + theme_login_aside_image: LIGHT_DEFAULTS.theme_login_aside_image, built_in: true, }; @@ -141,6 +153,10 @@ const themeImportSchema = z.object({ theme_logo: z.string().optional().default(''), theme_logo_collapsed: z.string().optional().default(''), theme_logo_login: z.string().optional().default(''), + theme_login_aside_color: z.string().nullable().optional().default(null), + theme_login_aside_gradient_start: z.string().nullable().optional().default(null), + theme_login_aside_gradient_end: z.string().nullable().optional().default(null), + theme_login_aside_image: z.string().nullable().optional().default(null), }); export const themeImport = async (context: AuthContext, user: AuthUser, file: Promise) => { diff --git a/opencti-platform/opencti-graphql/src/modules/theme/theme-types.ts b/opencti-platform/opencti-graphql/src/modules/theme/theme-types.ts index b0ca6b8f603d..b4bff25e45d7 100644 --- a/opencti-platform/opencti-graphql/src/modules/theme/theme-types.ts +++ b/opencti-platform/opencti-graphql/src/modules/theme/theme-types.ts @@ -15,6 +15,10 @@ export interface BasicStoreEntityTheme extends BasicStoreEntity { theme_logo_collapsed: string; theme_logo_login: string; theme_text_color: string; + theme_login_aside_color: string; + theme_login_aside_gradient_start: string; + theme_login_aside_gradient_end: string; + theme_login_aside_image: string; built_in: boolean; } @@ -30,6 +34,10 @@ export interface StoreEntityTheme extends StoreEntity { theme_logo_collapsed: string; theme_logo_login: string; theme_text_color: string; + theme_login_aside_color: string; + theme_login_aside_gradient_start: string; + theme_login_aside_gradient_end: string; + theme_login_aside_image: string; built_in: boolean; } // endregion @@ -47,6 +55,10 @@ export interface StixTheme extends StixObject { theme_logo_collapsed: string; theme_logo_login: string; theme_text_color: string; + theme_login_aside_color: string; + theme_login_aside_gradient_start: string; + theme_login_aside_gradient_end: string; + theme_login_aside_image: string; built_in: boolean; extensions: { [STIX_EXT_OCTI]: StixOpenctiExtensionSDO; diff --git a/opencti-platform/opencti-graphql/src/modules/theme/theme.graphql b/opencti-platform/opencti-graphql/src/modules/theme/theme.graphql index 22e0e3bc355c..b64be314fcff 100644 --- a/opencti-platform/opencti-graphql/src/modules/theme/theme.graphql +++ b/opencti-platform/opencti-graphql/src/modules/theme/theme.graphql @@ -15,6 +15,10 @@ type Theme implements InternalObject & BasicObject { theme_logo_collapsed: String theme_logo_login: String theme_text_color: String! + theme_login_aside_color: String + theme_login_aside_gradient_start: String + theme_login_aside_gradient_end: String + theme_login_aside_image: String toConfigurationExport: String! built_in: Boolean metrics:[Metric] @@ -65,6 +69,10 @@ input ThemeAddInput { theme_logo_collapsed: String theme_logo_login: String theme_text_color: String! + theme_login_aside_color: String + theme_login_aside_gradient_start: String + theme_login_aside_gradient_end: String + theme_login_aside_image: String built_in: Boolean } diff --git a/opencti-platform/opencti-graphql/src/modules/theme/theme.ts b/opencti-platform/opencti-graphql/src/modules/theme/theme.ts index 5bc8d22962da..cf8a34bc5778 100644 --- a/opencti-platform/opencti-graphql/src/modules/theme/theme.ts +++ b/opencti-platform/opencti-graphql/src/modules/theme/theme.ts @@ -30,7 +30,10 @@ const THEME_DEFINITION: ModuleDefinition = { { name: 'theme_logo_login', label: 'Theme logo login', type: 'string', format: 'short', mandatoryType: 'no', editDefault: false, multiple: false, upsert: false, isFilterable: false }, { name: 'theme_text_color', label: 'Theme text color', type: 'string', format: 'short', mandatoryType: 'external', editDefault: false, multiple: false, upsert: false, isFilterable: false }, { name: 'built_in', label: 'Built-in', type: 'boolean', mandatoryType: 'no', editDefault: false, multiple: false, upsert: false, isFilterable: false }, - + { name: 'theme_login_aside_color', label: 'Theme login aside color', type: 'string', format: 'short', mandatoryType: 'no', editDefault: false, multiple: false, upsert: false, isFilterable: false }, + { name: 'theme_login_aside_gradient_start', label: 'Theme login aside gradient start', type: 'string', format: 'short', mandatoryType: 'no', editDefault: false, multiple: false, upsert: false, isFilterable: false }, + { name: 'theme_login_aside_gradient_end', label: 'Theme login aside gradient end', type: 'string', format: 'short', mandatoryType: 'no', editDefault: false, multiple: false, upsert: false, isFilterable: false }, + { name: 'theme_login_aside_image', label: 'Theme login aside image', type: 'string', format: 'short', mandatoryType: 'no', editDefault: false, multiple: false, upsert: false, isFilterable: false }, ], relations: [], representative: (stix: StixTheme) => { diff --git a/opencti-platform/opencti-graphql/tests/03-integration/02-resolvers/theme-test.ts b/opencti-platform/opencti-graphql/tests/03-integration/02-resolvers/theme-test.ts index 9e0e0d1afce6..d7d7a085f8f5 100644 --- a/opencti-platform/opencti-graphql/tests/03-integration/02-resolvers/theme-test.ts +++ b/opencti-platform/opencti-graphql/tests/03-integration/02-resolvers/theme-test.ts @@ -18,6 +18,10 @@ const CREATE_THEME_MUTATION = gql` theme_logo theme_logo_collapsed theme_logo_login + theme_login_aside_color + theme_login_aside_gradient_start + theme_login_aside_gradient_end + theme_login_aside_image built_in } } @@ -35,6 +39,10 @@ const UPDATE_THEME_MUTATION = gql` theme_secondary theme_accent theme_text_color + theme_login_aside_color + theme_login_aside_gradient_start + theme_login_aside_gradient_end + theme_login_aside_image } } `; @@ -60,6 +68,10 @@ const READ_THEME_QUERY = gql` theme_logo theme_logo_collapsed theme_logo_login + theme_login_aside_color + theme_login_aside_gradient_start + theme_login_aside_gradient_end + theme_login_aside_image built_in } } @@ -120,6 +132,10 @@ const IMPORT_THEME_MUTATION = gql` theme_logo theme_logo_collapsed theme_logo_login + theme_login_aside_color + theme_login_aside_gradient_start + theme_login_aside_gradient_end + theme_login_aside_image built_in } } @@ -133,16 +149,16 @@ describe('Themes resolver testing', () => { beforeAll(async () => { const themes = await queryAsAdmin({ query: LIST_THEMES_QUERY, - variables: { first: 10 } + variables: { first: 10 }, }); const darkTheme = themes.data?.themes.edges.find( - (edge: any) => edge.node.name === 'Dark' + (edge: any) => edge.node.name === 'Dark', ); darkThemeId = darkTheme?.node.id; const lightTheme = themes.data?.themes.edges.find( - (edge: any) => edge.node.name === 'Light' + (edge: any) => edge.node.name === 'Light', ); lightThemeId = lightTheme?.node.id; @@ -154,7 +170,7 @@ describe('Themes resolver testing', () => { it('should list default themes', async () => { const queryResult = await queryAsAdmin({ query: LIST_THEMES_QUERY, - variables: { first: 10 } + variables: { first: 10 }, }); expect(queryResult.data?.themes.edges.length).toBeGreaterThanOrEqual(2); @@ -167,7 +183,7 @@ describe('Themes resolver testing', () => { it('should read a specific theme', async () => { const queryResult = await queryAsAdminWithSuccess({ query: READ_THEME_QUERY, - variables: { id: darkThemeId } + variables: { id: darkThemeId }, }); expect(queryResult.data?.theme).toBeDefined(); @@ -191,12 +207,14 @@ describe('Themes resolver testing', () => { theme_logo: 'https://example.com/logo.png', theme_logo_collapsed: 'https://example.com/logo-small.png', theme_logo_login: 'https://example.com/logo-login.png', + theme_login_aside_gradient_start: '#050A14', + theme_login_aside_gradient_end: '#0C1728', }, }; const theme = await queryAsAdmin({ query: CREATE_THEME_MUTATION, - variables: THEME_TO_CREATE + variables: THEME_TO_CREATE, }); customThemeId = theme.data?.themeAdd.id; @@ -206,12 +224,14 @@ describe('Themes resolver testing', () => { expect(theme.data?.themeAdd.theme_background).toBe('#1a1a1a'); expect(theme.data?.themeAdd.theme_primary).toBe('#ff6b6b'); expect(theme.data?.themeAdd.built_in).toBe(false); + expect(theme.data?.themeAdd.theme_login_aside_gradient_start).toBe('#050A14'); + expect(theme.data?.themeAdd.theme_login_aside_gradient_end).toBe('#0C1728'); }); it('should not create a theme with duplicate name', async () => { const DUPLICATE_THEME = { input: { - name: 'Custom Test Theme', // Same name as above + name: 'Custom Test Theme', theme_background: '#000000', theme_paper: '#111111', theme_nav: '#000000', @@ -224,7 +244,7 @@ describe('Themes resolver testing', () => { const result = await queryAsAdmin({ query: CREATE_THEME_MUTATION, - variables: DUPLICATE_THEME + variables: DUPLICATE_THEME, }); expect(result.errors).toBeDefined(); @@ -242,7 +262,7 @@ describe('Themes resolver testing', () => { const updated = await queryAsAdmin({ query: UPDATE_THEME_MUTATION, - variables: UPDATE_INPUT + variables: UPDATE_INPUT, }); expect(updated.data?.themeFieldPatch.id).toBe(customThemeId); @@ -250,13 +270,49 @@ describe('Themes resolver testing', () => { expect(updated.data?.themeFieldPatch.theme_primary).toBe('#00ff00'); }); + it('should update theme login aside to color', async () => { + const UPDATE_INPUT = { + id: customThemeId, + input: [ + { key: 'theme_login_aside_color', value: '#ff0000' }, + { key: 'theme_login_aside_gradient_start', value: '' }, + { key: 'theme_login_aside_gradient_end', value: '' }, + ], + }; + + const updated = await queryAsAdmin({ + query: UPDATE_THEME_MUTATION, + variables: UPDATE_INPUT, + }); + + expect(updated.data?.themeFieldPatch.theme_login_aside_color).toBe('#ff0000'); + expect(updated.data?.themeFieldPatch.theme_login_aside_gradient_start).toBeFalsy(); + expect(updated.data?.themeFieldPatch.theme_login_aside_gradient_end).toBeFalsy(); + }); + + it('should clear theme login aside fields', async () => { + const UPDATE_INPUT = { + id: customThemeId, + input: [ + { key: 'theme_login_aside_color', value: '' }, + ], + }; + + const updated = await queryAsAdmin({ + query: UPDATE_THEME_MUTATION, + variables: UPDATE_INPUT, + }); + + expect(updated.data?.themeFieldPatch.theme_login_aside_color).toBeFalsy(); + }); + it('should search themes by name', async () => { const queryResult = await queryAsAdmin({ query: LIST_THEMES_QUERY, variables: { search: 'Updated Custom', - first: 10 - } + first: 10, + }, }); expect(queryResult.data?.themes.edges.length).toBeGreaterThanOrEqual(1); @@ -266,7 +322,7 @@ describe('Themes resolver testing', () => { it('should not delete a built-in theme', async () => { const result = await queryAsAdmin({ query: DELETE_THEME_MUTATION, - variables: { id: darkThemeId } + variables: { id: darkThemeId }, }); expect(result.errors).toBeDefined(); @@ -276,14 +332,14 @@ describe('Themes resolver testing', () => { it('should delete a custom theme', async () => { const result = await queryAsAdmin({ query: DELETE_THEME_MUTATION, - variables: { id: customThemeId } + variables: { id: customThemeId }, }); expect(result.data?.themeDelete).toBe(customThemeId); const queryResult = await queryAsAdmin({ query: READ_THEME_QUERY, - variables: { id: customThemeId } + variables: { id: customThemeId }, }); expect(queryResult.data?.theme).toBeNull(); @@ -292,7 +348,7 @@ describe('Themes resolver testing', () => { it('should not delete a non-existent theme', async () => { const result = await queryAsAdmin({ query: DELETE_THEME_MUTATION, - variables: { id: 'non-existent-id' } + variables: { id: 'non-existent-id' }, }); expect(result.errors).toBeDefined(); @@ -313,8 +369,8 @@ describe('Themes resolver testing', () => { mode: 'or', }], filterGroups: [], - } - } + }, + }, }); expect(queryResult.data?.themes.edges.length).toBeGreaterThanOrEqual(2); @@ -329,8 +385,8 @@ describe('Themes resolver testing', () => { variables: { first: 10, orderBy: 'name', - orderMode: 'asc' - } + orderMode: 'asc', + }, }); const names = queryResult.data?.themes.edges.map((edge: any) => edge.node.name); @@ -344,9 +400,7 @@ describe('Themes resolver testing', () => { const theme = await queryAsAdmin({ query: IMPORT_THEME_MUTATION, - variables: { - file: upload - } + variables: { file: upload }, }); const importThemeId = theme.data?.themeImport.id; @@ -358,17 +412,16 @@ describe('Themes resolver testing', () => { expect(theme.data?.themeImport.theme_logo).toBe('http://www.test.com/image.svg'); expect(theme.data?.themeImport.built_in).toBe(false); - // delete the imported theme const result = await queryAsAdmin({ query: DELETE_THEME_MUTATION, - variables: { id: importThemeId } + variables: { id: importThemeId }, }); expect(result.data?.themeDelete).toBe(importThemeId); const queryResult = await queryAsAdmin({ query: READ_THEME_QUERY, - variables: { id: importThemeId } + variables: { id: importThemeId }, }); expect(queryResult.data?.theme).toBeNull();