diff --git a/cypress/e2e/profile/personalInformation.cy.ts b/cypress/e2e/profile/personalInformation.cy.ts index a4c9b257b..8a63a769e 100644 --- a/cypress/e2e/profile/personalInformation.cy.ts +++ b/cypress/e2e/profile/personalInformation.cy.ts @@ -65,6 +65,15 @@ describe('Edit personal information', () => { cy.get(`#${PERSONAL_INFO_SAVE_BUTTON_ID}`).should('be.disabled'); }); + it('Username can not contain special characters', () => { + const badUsername = '<
%^\'"'; + changeUsername(badUsername); + + // The save button should be disabled and the helper text should display the message + cy.get(`#${PERSONAL_INFO_SAVE_BUTTON_ID}`).should('be.disabled'); + cy.get('[id$=-helper-text]').should('have.text', 'User name must not contain " ", ", <, >, ^, %, \\'); + }) + it('Valid username can be saved', () => { const validUsername = 'validUsername'; changeUsername(validUsername); diff --git a/src/langs/de.json b/src/langs/de.json index 5a158d7d0..6ab033bf6 100644 --- a/src/langs/de.json +++ b/src/langs/de.json @@ -76,6 +76,7 @@ "DESTRUCTIVE_SETTINGS_DETAILS": "Bitte beachten Sie, dass die hier beschriebenen Maßnahmen möglicherweise irreversible Folgen haben. Stellen Sie sicher, dass Sie alle Einschränkungen gründlich prüfen, bevor Sie fortfahren, und ergreifen Sie erst dann Maßnahmen, wenn Sie sicher sind.", "USERNAME_EMPTY_ERROR": "Das Feld darf nicht leer sein", "USERNAME_LENGTH_ERROR": "Der Benutzername muss zwischen {{min}} und {{max}} Zeichen lang sein", + "USERNAME_SPECIAL_CHARACTERS_ERROR": "Der Benutzername darf nicht enthalten \" \", \", <, >, ^, %, \\", "EDIT_BUTTON_LABEL": "Bearbeiten", "UPLOAD_PICTURE_TEXT": "Bild hochladen", "SECURITY_TIPS_TITLE": "Sicherheitstipps sind verfügbar", diff --git a/src/langs/en.json b/src/langs/en.json index 64d208028..2287d00d7 100644 --- a/src/langs/en.json +++ b/src/langs/en.json @@ -77,6 +77,7 @@ "DESTRUCTIVE_SETTINGS_DETAILS": "Please be aware that the actions outlined here have potentially irreversible consequences. Ensure you thoroughly review any restrictions before proceeding, and only take action once you are certain.", "USERNAME_EMPTY_ERROR": "The field cannot be empty", "USERNAME_LENGTH_ERROR": "Username must be between {{min}} and {{max}} characters long", + "USERNAME_SPECIAL_CHARACTERS_ERROR": "User name must not contain \" \", \", <, >, ^, %, \\", "EDIT_BUTTON_LABEL": "Edit", "CONFIGURE_BUTTON_LABEL": "Configure", "UPLOAD_PICTURE_TEXT": "Upload picture", diff --git a/src/langs/es.json b/src/langs/es.json index 4fb384bdb..46bae39b4 100644 --- a/src/langs/es.json +++ b/src/langs/es.json @@ -76,6 +76,7 @@ "DESTRUCTIVE_SETTINGS_DETAILS": "Ten en cuenta que las acciones descritas aquí tienen consecuencias potencialmente irreversibles. Asegúrate de revisar detenidamente cualquier restricción antes de continuar y solo toma medidas una vez que estés seguro.", "USERNAME_EMPTY_ERROR": "El campo no puede estar vacío.", "USERNAME_LENGTH_ERROR": "El nombre de usuario debe tener entre {{min}} y {{max}} caracteres", + "USERNAME_SPECIAL_CHARACTERS_ERROR": "El nombre de usuario no debe contener \" \", \", <, >, ^, %, \\", "EDIT_BUTTON_LABEL": "Editar", "UPLOAD_PICTURE_TEXT": "Subir foto", "SECURITY_TIPS_TITLE": "Hay consejos de seguridad disponibles", diff --git a/src/langs/fr.json b/src/langs/fr.json index aee5e41d8..41784e18e 100644 --- a/src/langs/fr.json +++ b/src/langs/fr.json @@ -77,6 +77,7 @@ "DESTRUCTIVE_SETTINGS_DETAILS": "Veuillez noter que les opérations décrites ici ont des conséquences potentiellement irréversibles. Assurez-vous d’examiner attentivement toutes les restrictions avant de continuer avant de continuer.", "USERNAME_EMPTY_ERROR": "Le champ ne peut pas être vide", "USERNAME_LENGTH_ERROR": "Le nom d'utilisateur doit contenir entre {{min}} et {{max}} caractères", + "USERNAME_SPECIAL_CHARACTERS_ERROR": "Le nom d'utilisateur ne doit pas contenir \" \", \", <, >, ^, %, \\", "EDIT_BUTTON_LABEL": "Modifier", "CONFIGURE_BUTTON_LABEL": "Configurer", "UPLOAD_PICTURE_TEXT": "Choisir photo", diff --git a/src/langs/it.json b/src/langs/it.json index 00b0d05f1..dd23cad60 100644 --- a/src/langs/it.json +++ b/src/langs/it.json @@ -76,6 +76,7 @@ "DESTRUCTIVE_SETTINGS_DETAILS": "Tieni presente che le azioni qui descritte hanno conseguenze potenzialmente irreversibili. Assicurati di esaminare attentamente eventuali restrizioni prima di procedere, e di agire solo quando hai certezza.", "USERNAME_EMPTY_ERROR": "Il campo non può essere vuoto", "USERNAME_LENGTH_ERROR": "Il nome utente deve contenere tra {{min}} e {{max}} caratteri", + "USERNAME_SPECIAL_CHARACTERS_ERROR": "Il nome utente non deve contenere \" \", \", <, >, ^, %, \\", "EDIT_BUTTON_LABEL": "Modificare", "UPLOAD_PICTURE_TEXT": "Carica l'immagine", "SECURITY_TIPS_TITLE": "Sono disponibili suggerimenti sulla sicurezza", diff --git a/src/modules/profile/EditPersonalInformation.tsx b/src/modules/profile/EditPersonalInformation.tsx index 7928db38e..fba5bac0e 100644 --- a/src/modules/profile/EditPersonalInformation.tsx +++ b/src/modules/profile/EditPersonalInformation.tsx @@ -6,6 +6,7 @@ import { CompleteMember, MAX_USERNAME_LENGTH, MIN_USERNAME_LENGTH, + MemberConstants, } from '@graasp/sdk'; import BorderedSection from '@/components/layout/BorderedSection'; @@ -20,6 +21,8 @@ import { PERSONAL_INFO_SAVE_BUTTON_ID, } from '@/config/selectors'; +const USER_NAME_REGEX = MemberConstants.USERNAME_FORBIDDEN_CHARS_REGEX; + const verifyUsername = (username: string): string | null => { const trimmedUsername = username.trim(); if (trimmedUsername === '') { @@ -32,6 +35,11 @@ const verifyUsername = (username: string): string | null => { ) { return 'USERNAME_LENGTH_ERROR'; } + + if (USER_NAME_REGEX.test(trimmedUsername)) { + return 'USERNAME_SPECIAL_CHARACTERS_ERROR'; + } + return null; };