diff --git a/server/src/common/validation/utils/frenchTelephoneNumber.ts b/server/src/common/validation/utils/frenchTelephoneNumber.ts index 6ab3161d3..4701945c3 100644 --- a/server/src/common/validation/utils/frenchTelephoneNumber.ts +++ b/server/src/common/validation/utils/frenchTelephoneNumber.ts @@ -1,24 +1,5 @@ -export const telephoneConverter = (telephone: string | null) => { - if (!telephone) return telephone; - let phone = String(telephone) +export const telephoneConverter = (telephone: string | null | undefined) => + telephone + ?.toString() .trim() - .replaceAll("-", "") - .replaceAll(".", "") - .replaceAll(" ", "") - .replaceAll("(+)", "+"); - - if (phone.length === 9) { - return `+33${phone}`; - } - - if (phone.length === 10 && phone[0] === "0") { - return `+33${phone.substr(1, 9)}`; - } - - // Gestion des téléphones au format 033xxxxxxxxx - if (phone.length === 12 && phone[0] === "0") { - return `+33${phone.substr(3, 12)}`; - } - - return phone; -}; + .replace(/[-.()\s]/g, "") ?? telephone; diff --git a/server/src/common/validation/utils/zodPrimitives.ts b/server/src/common/validation/utils/zodPrimitives.ts index ed66b89d4..b719d7193 100644 --- a/server/src/common/validation/utils/zodPrimitives.ts +++ b/server/src/common/validation/utils/zodPrimitives.ts @@ -11,6 +11,7 @@ import { UAI_REGEX, CODE_POSTAL_REGEX, DERNIER_ORGANISME_UAI_REGEX, + PHONE_REGEX_PATTERN, } from "shared"; import { z } from "zod"; @@ -37,10 +38,16 @@ export const extensions = { phone: () => z.coerce .string() - // On va vérifier que ça contient au moins un chiffre (ou que c'est une chaine vide, car on les accepte aussi) - .regex(/^$|.*[0-9].*/, "Format invalide") - // On passe à null en cas de chaine vide .transform((v: string) => (v ? telephoneConverter(v) : null)) + .refine( + (v: string | null | undefined) => { + const phoneRegex = new RegExp(PHONE_REGEX_PATTERN, "g"); + return v === null || v === undefined || phoneRegex.test(v); + }, + { + message: "Format invalide", + } + ) .openapi({ example: "0628000000", }), diff --git a/server/tests/integration/common/utils/validationUtils.test.ts b/server/tests/integration/common/utils/validationUtils.test.ts index eada6403a..5bf034a25 100644 --- a/server/tests/integration/common/utils/validationUtils.test.ts +++ b/server/tests/integration/common/utils/validationUtils.test.ts @@ -41,17 +41,29 @@ describe("Validation Utils", () => { }); describe("validation des numeros de telephone", () => { - [ + const testCases = [ { input: null, output: null }, { input: undefined, output: undefined }, - { input: 0, output: 0 }, + { input: 0, output: "0" }, { input: "", output: "" }, - { input: "033638424988", output: "+33638424988" }, - { input: "0638424988", output: "+33638424988" }, + { input: "033638424988", output: "033638424988" }, + { input: "0638424988", output: "0638424988" }, { input: "(+)33638424988", output: "+33638424988" }, + { input: "+33638424988", output: "+33638424988" }, + { input: "+33123456789", output: "+33123456789" }, + { input: "33 6 38 42 49 88", output: "33638424988" }, { input: "12345678", output: "12345678" }, { input: "ABCDEFGH", output: "ABCDEFGH" }, - ].forEach(({ input, output }) => { + { input: "06-38.42.49.88", output: "0638424988" }, + { input: "06.38.42.49.88", output: "0638424988" }, + { input: "06-38-42-49-88", output: "0638424988" }, + { input: "06 (38) 42 49 88", output: "0638424988" }, + { input: " 06 38 42 49 88 ", output: "0638424988" }, + { input: "06abc38424988", output: "06abc38424988" }, + { input: "+33(6)384-249-88", output: "+33638424988" }, + ]; + + testCases.forEach(({ input, output }) => { it(`Vérifie qu'un numero de téléphone ${JSON.stringify(input)} est transformé en ${output}`, () => { expect(telephoneConverter(input as any)).toStrictEqual(output); }); diff --git a/server/tests/integration/jobs/ingestion/process-ingestion.test.ts b/server/tests/integration/jobs/ingestion/process-ingestion.test.ts index e30ebaef0..7757cf3b6 100644 --- a/server/tests/integration/jobs/ingestion/process-ingestion.test.ts +++ b/server/tests/integration/jobs/ingestion/process-ingestion.test.ts @@ -549,7 +549,7 @@ describe("Processus d'ingestion", () => { date_de_naissance: new Date("2000-10-28T00:00:00.000Z"), code_postal_de_naissance: "44000", courriel: "johndoe@example.org", - telephone: "+33123456789", + telephone: "0123456789", adresse: { code_postal: "75000", complete: "1 rue de la paix", diff --git a/shared/constants/validations.ts b/shared/constants/validations.ts index f0f81c1f0..5d44b8651 100644 --- a/shared/constants/validations.ts +++ b/shared/constants/validations.ts @@ -15,6 +15,8 @@ export const NIR_LOOSE_REGEX_PATTERN = "^[0-9]{13}([0-9]{2})?$"; // Basé sur les recommandations SIFA export const DERNIER_ORGANISME_UAI_PATTERN = "^(0?[0-9][0-9]|0?2[AB]|0?9[012345]|97[1234678]|98[46789]|99[0135]|[0-9]{7}[a-zA-Z])$"; +export const PHONE_REGEX_PATTERN = + "(?:([+]\\d{1,4})[-.\\s]?)?(?:[(](\\d{1,3})[)][-.\\s]?)?(\\d{1,4})[-.\\s]?(\\d{1,4})[-.\\s]?(\\d{1,9})"; // Numero INE (Identifiant National Elève) // Le numero INE composé de 11 caractères,