diff --git a/backend/core/helpers.py b/backend/core/helpers.py index 99e5a1d74..f40d2f7d4 100644 --- a/backend/core/helpers.py +++ b/backend/core/helpers.py @@ -543,7 +543,6 @@ def risks_count_per_level(user: User, risk_assessments: list | None = None): "name": r[0], "value": r[1]["count"], "color": r[1]["color"], - "localName": camel_case(r[0]), } ) @@ -555,7 +554,6 @@ def risks_count_per_level(user: User, risk_assessments: list | None = None): "name": r[0], "value": r[1]["count"], "color": r[1]["color"], - "localName": camel_case(r[0]), } ) return {"current": current_level, "residual": residual_level} diff --git a/backend/core/migrations/0005_alter_project_lc_status_alter_securitymeasure_effort.py b/backend/core/migrations/0005_alter_project_lc_status_alter_securitymeasure_effort.py new file mode 100644 index 000000000..57e8da58f --- /dev/null +++ b/backend/core/migrations/0005_alter_project_lc_status_alter_securitymeasure_effort.py @@ -0,0 +1,23 @@ +# Generated by Django 5.0.2 on 2024-03-04 10:28 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('core', '0004_complianceassessment_is_published_and_more'), + ] + + operations = [ + migrations.AlterField( + model_name='project', + name='lc_status', + field=models.CharField(choices=[('undefined', 'Undefined'), ('in_design', 'Design'), ('in_dev', 'Development'), ('in_prod', 'Production'), ('eol', 'EndOfLife'), ('dropped', 'Dropped')], default='in_design', max_length=20, verbose_name='Status'), + ), + migrations.AlterField( + model_name='securitymeasure', + name='effort', + field=models.CharField(blank=True, choices=[('S', 'Small'), ('M', 'Medium'), ('L', 'Large'), ('XL', 'Extra Large')], help_text='Relative effort of the measure (using T-Shirt sizing)', max_length=2, null=True, verbose_name='Effort'), + ), + ] diff --git a/backend/core/models.py b/backend/core/models.py index 12be40c1b..ba9fefb21 100644 --- a/backend/core/models.py +++ b/backend/core/models.py @@ -358,11 +358,11 @@ class Meta: class Project(NameDescriptionMixin, FolderMixin): PRJ_LC_STATUS = [ - ("undefined", _("--")), + ("undefined", _("Undefined")), ("in_design", _("Design")), ("in_dev", _("Development")), ("in_prod", _("Production")), - ("eol", _("End Of Life")), + ("eol", _("EndOfLife")), ("dropped", _("Dropped")), ] internal_reference = models.CharField( @@ -527,7 +527,7 @@ class Status(models.TextChoices): ("S", _("Small")), ("M", _("Medium")), ("L", _("Large")), - ("XL", _("Extra-Large")), + ("XL", _("Extra Large")), ] MAP_EFFORT = {None: -1, "S": 1, "M": 2, "L": 4, "XL": 8} diff --git a/frontend/messages/en.json b/frontend/messages/en.json index 955bff10e..1ef8623f5 100644 --- a/frontend/messages/en.json +++ b/frontend/messages/en.json @@ -157,11 +157,6 @@ "securityMeasuresStatus": "Security measures status", "currentRisk": "Current risk", "residualRisk": "Residual risk", - "veryLow": "Very low", - "low": "Low", - "medium": "Medium", - "high": "High", - "veryHigh": "Very high", "planned": "Planned", "active": "Active", "inactive": "Inactive", @@ -177,7 +172,7 @@ "noSecurityMeasureYet": "No security measure yet", "authors": "Authors", "reviewers": "Reviewers", - "process": "Process", + "processButton": "Process", "selectTargets": "Select your targets", "composerDescription": "This will help you aggregate multiple components (projects) to get the compiled view on your risk. This is particularly useful for two use cases", "composerDescription1": "business intelligence approach to focus on a specific subset across different project domains (eg. across divisions)", @@ -344,6 +339,24 @@ "copyright": "Copyright", "uploadYourLibrary": "Upload your own library", "libraryFileInYaml": "Library file in YAML format", + "importBackup": "Import backup", + "exportBackup": "Export backup", + "confirmImportBackup": "Are you sure you want to import this backup? This will overwrite all existing data.", + "exportDatabase": "Export database", + "upload": "Upload", + "undefined": "--", + "production": "Production", + "design": "Design", + "development": "Development", + "endOfLife": "End of life", + "dropped": "Dropped", + "technical": "Technical", + "physical": "Physical", + "process": "Process", + "small": "Small", + "medium": "Medium", + "large": "Large", + "extraLarge": "Extra-large", "rid": "RID", "scope": "Scope", "auditor": "Auditor", @@ -371,6 +384,54 @@ "residual": "Residual", "jumpToRiskAssessment": "Jump to risk assessment", "additionalMeasures": "Additional measures", + "riskAssessmentMatrixHelpText": "WARNING: You will not be able to change the risk matrix after the risk assessment is created", + "etaHelpText": "Estimated time of arrival", + "dueDateHelpText": "Date by which the assessment must be completed", + "expiryDateHelpText": "Date by which the object is no longer valid", + "linkHelpText": "External URL for action follow-up (eg. Jira ticket)", + "effortHelpText": "The effort required to implement the security measure", + "riskAcceptanceJusitficationHelpText": "Justification for the risk acceptance. Only the approver can edit this field.", + "approverHelpText": "Risk owner and approver identity", + "riskAcceptanceRiskScenariosHelpText": "The risk scenarios that are accepted", + "attachmentHelpText": "File for evidence (eg. screenshot, log file, etc.)", + "attachmentWarningText": "WARNING: Uploading a new file will overwrite the existing one", + "isActiveHelpText": "Designates whether this user should be treated as active", + "helloThere": "Hello there 👋", + "thisIsCisoAssistant": "This is CISO Assistant.", + "yourStreamlined": "Your streamlined", + "oneStopShop": "one-stop shop", + "forComplianceRiskManagement": "for compliance and risk management.", + "youCanSetPAsswordHere": "You can set your password here", + "setPassword": "Set password", + "logIntoYourAccount": "Log into your account", + "youNeedToLogIn": "You need to login to access all the features", + "forgtPassword": "Forgot password", + "login": "Login", + "password": "Password", + "enterYourEmail": "Enter your email address below, and we'll send instructions for setting a new one", + "send": "Send", + "goBackToLogin": "Go back to login", + "riskAcceptanceReviewMessage": "This risk acceptance is awaiting processing. Remember to review it before validating or rejecting it, you will not be able to go back.", + "validate": "Validate", + "reject": "Reject", + "revoke": "Revoke", + "riskAcceptanceValidatedMessage": "This risk acceptance is currently validated. It can be revoked at any time, but this will be irrevocable. You will need to duplicate it with a different verison if necessary.", + "confirmModalTitle": "Confirm", + "confirmModalMessage": "Are you sure? This action will permanently affect the following object", + "submit": "Submit", + "requirementAssessment": "Requirement assessment", + "requirementAssessments": "Requirement assessments", + "deleteModalTitle": "Delete", + "deleteModalMessage": "Are you sure you want to delete the following object", + "download": "Download", + "loading": "Loading", + "open": "Opened", + "mitigate": "Mitigated", + "accept": "Accepted", + "avoid": "Avoided", + "transfer": "Shared", + "primary": "Primary", + "support": "Support", "toDo": "To do", "inProgress": "In progress", "nonCompliant": "Non compliant", diff --git a/frontend/messages/fr.json b/frontend/messages/fr.json index 7758632e7..9fe191b4c 100644 --- a/frontend/messages/fr.json +++ b/frontend/messages/fr.json @@ -3,8 +3,8 @@ "french": "Français", "english": "Anglais", "addThreat": "Ajouter une menace", - "addSecurityFunction": "Ajouter une fonction de sécurité", - "addSecurityMeasure": "Ajouter une mesure de sécurité", + "addSecurityFunction": "Ajouter une mesure de référence", + "addSecurityMeasure": "Ajouter une mesure appliquée", "addAsset": "Ajouter un bien sensible", "addRiskAssessment": "Ajouter une évaluation de risque", "addRiskScenario": "Ajouter un scénario de risque", @@ -16,8 +16,8 @@ "addUser": "Ajouter un utilisateur", "addPolicy": "Ajouter une politique", "associatedThreats": "Menaces associées", - "associatedSecurityFunctions": "Fonctions de sécurité associées", - "associatedSecurityMeasures": "Mesures de sécurité associées", + "associatedSecurityFunctions": "Mesures de référence associées", + "associatedSecurityMeasures": "Mesures appliquées associées", "associatedAssets": "Biens sensibles associés", "associatedRiskAssessments": "Évaluations de risque associées", "associatedRiskScenarios": "Scénarios de risque associés", @@ -40,8 +40,8 @@ "analytics": "Analytiques", "calendar": "Calendrier", "threats": "Menaces", - "securityFunctions": "Fonctions de sécurité", - "securityMeasures": "Mesures de sécurité", + "securityFunctions": "Mesures de référence", + "securityMeasures": "Mesures appliquées", "assets": "Biens sensibles", "asset": "Bien sensible", "policy": "Politique", @@ -81,8 +81,8 @@ "lastName": "Nom de famille", "category": "Catégorie", "eta": "ETA", - "securityFunction": "Fonction de sécurité", - "securityMeasure": "Mesure de sécurité", + "securityFunction": "Mesure de référence", + "securityMeasure": "Mesure appliquée", "provider": "Fournisseur", "domain": "Domaine", "urn": "URN", @@ -154,14 +154,9 @@ "assignedProjects": "Assigné à {number} projet{s}", "currentRiskLevelPerScenario": "Niveau de risque courant par scénario de risque", "residualRiskLevelPerScenario": "Niveau de risque résiduel par scénario de risque", - "securityMeasuresStatus": "Statut des mesures de sécurité", + "securityMeasuresStatus": "Statut des mesures appliquées", "currentRisk": "Risque courant", "residualRisk": "Risque résiduel", - "veryLow": "Très faible", - "low": "Faible", - "medium": "Moyen", - "high": "Élevé", - "veryHigh": "Très élevé", "planned": "Planifié", "active": "Active", "inactive": "Inactive", @@ -174,10 +169,10 @@ "today": "Aujourd'hui", "actionRequested": "Action requise", "noRiskAcceptanceYet": "Aucune acceptation de risque pour le moment", - "noSecurityMeasureYet": "Aucune mesure de sécurité pour le moment", + "noSecurityMeasureYet": "Aucune mesure appliquée pour le moment", "authors": "Auteurs", "reviewers": "Relecteurs", - "process": "Traiter", + "processButton": "Traiter", "selectTargets": "Selectionnez vos cibles", "composerDescription": "Cela vous aidera à agréger plusieurs composants (projets) pour obtenir une vue d'ensemble de vos risques. Ceci est particulièrement utile pour deux cas d'utilisation", "composerDescription1": "une approche de veille stratégique pour se concentrer sur un sous-ensemble spécifique à travers différents domaines de projet (par exemple, à travers les divisions)", @@ -188,7 +183,7 @@ "pendingMeasures": "Vos mesures en attente", "orderdByRankingScore": "Classées par score", "rankingScore": "Score de classement", - "noPendingSecurityMeasure": "Aucune mesure de sécurité en attente", + "noPendingSecurityMeasure": "Aucune mesure appliquée en attente", "rankingScoreDefintion": "Le score de classement est une mesure adaptative qui combine les informations relatives à l'effort et au niveau de risque actuel, et les croise avec d'autres données pour vous aider à établir des priorités", "actions": "Actions", "projectsSummaryEmpty": "Le résumé des projets est vide", @@ -344,12 +339,30 @@ "copyright": "Droits d'auteur", "uploadYourLibrary": "Téléchargez votre propre bibliothèque", "libraryFileInYaml": "Fichier de librairie en format YAML", + "importBackup": "Importer une sauvegarde", + "exportBackup": "Exporter une sauvegarde", + "confirmImportBackup": "Êtes-vous sûr de vouloir importer cette sauvegarde ? Cela écrasera toutes les données existantes.", + "exportDatabase": "Exporter la base de données", + "upload": "Télécharger", + "undefined": "--", + "production": "Production", + "design": "Conception", + "development": "Développement", + "endOfLife": "Fin de vie", + "dropped": "Abandonné", + "technical": "Technique", + "physical": "Physique", + "process": "Processus", + "small": "Petit", + "medium": "Moyen", + "large": "Grand", + "extraLarge": "Extra large", "rid": "RID", "scope": "Périmètre", "auditor": "Auditeur", "lastUpdate": "Dernière mise à jour", "riskScenarioAssetHelpText": "Biens sensibles impactés par ce scénario de risque", - "riskScenarioMeasureHelpText": "Les mesures de sécurité existantes pour gérer ce risque", + "riskScenarioMeasureHelpText": "Les mesures appliquées existantes pour gérer ce risque", "currentAssessment": "Évaluation actuelle", "targetAssessment": "Évaluation cible", "currentRiskLevel": "Niveau de risque courrant", @@ -371,10 +384,58 @@ "residual": "Résiduel", "jumpToRiskAssessment": "Passer à l'évaluation des risques", "additionalMeasures": "Mesures supplémentaires", + "riskAssessmentMatrixHelpText": "ATTENTION: Vous ne pourrez pas changer la matrice de risque une fois l'évaluation de risque créée.", + "etaHelpText": "Date d'arrivée estimée", + "dueDateHelpText": "Date à laquelle l'évaluation doit être complétée", + "expiryDateHelpText": "Date à laquelle l'objet n'est plus valide", + "linkHelpText": "URL externe pour le suivi des actions (ex. ticket Jira)", + "effortHelpText": "L'effort requis pour mettre en œuvre la mesure appliquée", + "riskAcceptanceJusitficationHelpText": "Justification de l'acceptation du risque. Seul l'approbateur peut modifier ce champ.", + "approverHelpText": "Identité du propriétaire du risque et de l’approbateur", + "riskAcceptanceRiskScenariosHelpText": "Les scénarios de risques acceptés", + "attachmentHelpText": "Fichier de preuve (eg. capture d'écran, fichier journal, etc.)", + "attachmentWarningText": "ATTENTION: le téléchargement d'un nouveau fichier écrasera celui existant", + "isActiveHelpText": "Désigne si cet utilisateur doit être traité comme actif", + "helloThere": "Bonjour 👋", + "thisIsCisoAssistant": "Voici CISO Assistant.", + "yourStreamlined": "Votre solution", + "oneStopShop": "tout en un", + "forComplianceRiskManagement": "pour la conformité et la gestion des risques.", + "youCanSetPAsswordHere": "Vous pouvez définir votre mot de passe ici", + "setPassword": "Définir le mot de passe", + "logIntoYourAccount": "Connectez-vous à votre compte", + "youNeedToLogIn": "Vous devez vous connecter pour accéder à toutes les fonctionnalités", + "forgtPassword": "Mot de passe oublié", + "login": "Se connecter", + "password": "Mot de passe", + "enterYourEmail": "Entrez votre adresse e-mail ci-dessous et nous vous enverrons des instructions pour en définir un nouveau", + "send": "Envoyer", + "goBackToLogin": "Revenir à la page de connexion", + "riskAcceptanceReviewMessage": "Cette acceptation de risque est en attente de traitement. Pensez à la consulter avant de la valider ou de la rejeter, vous ne pourrez pas revenir en arrière.", + "validate": "Valider", + "reject": "Rejeter", + "revoke": "Révoquer", + "riskAcceptanceValidatedMessage": "Cette acceptation de risque est actuellement validée. Elle peut être révoquée à tout moment, mais cela sera irrévocable. Vous devrez la dupliquer avec une version différente si nécessaire.", + "confirmModalTitle": "Confirmer", + "confirmModalMessage": "Êtes-vous sûr? Cette action affectera définitivement l'objet suivant", + "submit": "Soumettre", + "requirementAssessment": "Évaluation d'exigence", + "requirementAssessments": "Évaluations des exigences", + "deleteModalTitle": "Supprimer", + "deleteModalMessage": "Etes-vous sûr de vouloir supprimer l'objet suivant", + "download": "Télécharger", + "loading": "Chargement", + "open": "Ouvert", + "mitigate": "Atténué", + "accept": "Accepté", + "avoid": "Refusé", + "transfer": "Partagé", "toDo": "À faire", "inProgress": "En cours", "nonCompliant": "Non conforme", "partiallyCompliant": "Partiellement conforme", "compliant": "Conforme", - "notApplicable": "Non applicable" + "notApplicable": "Non applicable", + "primary": "Primaire", + "support": "Support" } diff --git a/frontend/src/lib/components/Chart/DonutChart.svelte b/frontend/src/lib/components/Chart/DonutChart.svelte index c5d9fb1eb..ec283d665 100644 --- a/frontend/src/lib/components/Chart/DonutChart.svelte +++ b/frontend/src/lib/components/Chart/DonutChart.svelte @@ -1,18 +1,12 @@ @@ -19,15 +21,15 @@
- Hello there đź‘‹ - This is CISO Assistant. + {m.helloThere()} đź‘‹ + {m.thisIsCisoAssistant()}.
- Your streamlined - one-stop shop - for compliance and risk management. + {m.yourStreamlined()} + {m.oneStopShop()} + {m.forComplianceRiskManagement()}.
@@ -36,7 +38,7 @@

- You can set your password here.
+ {m.youCanSetPAsswordHere()}.

@@ -56,7 +58,7 @@ />

{m.setPassword()}

diff --git a/frontend/src/routes/(authentication)/login/+page.svelte b/frontend/src/routes/(authentication)/login/+page.svelte index f03194169..5bb6fd174 100644 --- a/frontend/src/routes/(authentication)/login/+page.svelte +++ b/frontend/src/routes/(authentication)/login/+page.svelte @@ -6,6 +6,8 @@ import SuperForm from '$lib/components/Forms/Form.svelte'; import Typewriter from 'svelte-typewriter'; + import * as m from '$paraglide/messages.js'; + export let data: PageData; const cursor = false; @@ -22,29 +24,29 @@
- Hello there đź‘‹ - This is CISO Assistant. + {m.helloThere()} + {m.thisIsCisoAssistant()}
- Your streamlined - one-stop shop - for compliance and risk management. + {m.yourStreamlined()} + {m.oneStopShop()} + {m.forComplianceRiskManagement()}
-
+

- Login into your account + {m.logIntoYourAccount()}

- You need to login to access all the features + {m.youNeedToLogIn()}

@@ -55,19 +57,19 @@ let:form validators={loginSchema} > - - + +

{m.login()}

diff --git a/frontend/src/routes/(authentication)/password-reset/+page.svelte b/frontend/src/routes/(authentication)/password-reset/+page.svelte index 716cfda74..80f0424b5 100644 --- a/frontend/src/routes/(authentication)/password-reset/+page.svelte +++ b/frontend/src/routes/(authentication)/password-reset/+page.svelte @@ -5,6 +5,8 @@ import TextField from '$lib/components/Forms/TextField.svelte'; import SuperForm from '$lib/components/Forms/Form.svelte'; + import * as m from '$paraglide/messages.js'; + export let data: PageData; @@ -21,10 +23,10 @@

- Forgot your password? + {m.forgtPassword()}

- Enter your email address below, and we'll email instructions for setting a new one. + {m.enterYourEmail()}.

@@ -35,10 +37,10 @@ let:form validators={emailSchema} > - +

{m.send()}

@@ -48,7 +50,7 @@ class="flex items-center space-x-2 text-primary-800 hover:text-primary-600" > -

go back to login

+

{m.goBackToLogin()}

diff --git a/frontend/tests/functional/detailed/login.test.ts b/frontend/tests/functional/detailed/login.test.ts index 1c47dba4f..55a9e8189 100644 --- a/frontend/tests/functional/detailed/login.test.ts +++ b/frontend/tests/functional/detailed/login.test.ts @@ -10,7 +10,7 @@ baseTest.skip('login page as expected title', async ({ page }) => { test('login / logout process is working properly', async ({ loginPage, analyticsPage, sideBar, page }) => { await loginPage.hasUrl(1); - await expect.soft(page.getByRole('heading', { name: 'Login into your account' })).toBeVisible(); + await expect.soft(page.getByTestId('login')).toBeVisible(); await loginPage.checkForUndefinedText(); await loginPage.login(); await analyticsPage.hasUrl(); diff --git a/frontend/tests/utils/test-utils.ts b/frontend/tests/utils/test-utils.ts index 5d92be2bf..576322df6 100644 --- a/frontend/tests/utils/test-utils.ts +++ b/frontend/tests/utils/test-utils.ts @@ -344,7 +344,7 @@ export class TestContent { name: '', description: '', internal_reference: '', - lc_status: 'End Of Life' + lc_status: 'End of life' } }, assetsPage: { @@ -508,7 +508,7 @@ export class TestContent { editParams: { name: '', description: '', - treatment: 'Accept', + treatment: 'Accepted', //TODO add risk_assessment & threats assets: [vars.assetName], existing_measures: 'Test existing measures',