Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: outils de sanitization #929

Merged
merged 9 commits into from
Dec 15, 2023
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .talismanrc
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ fileignoreconfig:
- filename: server/tests/unit/security/authorisationService.test.ts
checksum: 581074420be582973bbfcdfafe1f700ca32f56e331911609cdc1cb2fb2626383
- filename: server/tests/unit/util.test.ts
checksum: f248ec16629759106d43b02aafc092d55316aeb147dd75fa44f4acc990b4ece0
checksum: 20e4537a925df70164f6148101a31b260102d92d62aa2adaa39292f96f95a056
- filename: shared/constants/recruteur.ts
checksum: 28af032d2eb26aec7dd3bb1d32253f992a036626c36a92eb1e7ff07599fd0b2b
- filename: shared/helpers/generateUri.ts
Expand Down
29 changes: 28 additions & 1 deletion server/tests/unit/util.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import assert from "assert"

import { cleanEmail } from "shared/helpers/common"
import { cleanEmail, removeUrlsFromText, addBracketsToUrls } from "shared/helpers/common"
import { describe, it } from "vitest"

import __filename from "../../src/common/filename"
Expand Down Expand Up @@ -39,6 +39,33 @@ describe(__filename(import.meta.url), () => {
assert.strictEqual(cleanEmail("jhönœ.dôœ.’£'^&/=!*?}ù@têst .com "), "[email protected]")
})

it("Suppression des différentes formes d'URL dans un texte", () => {
assert.strictEqual(removeUrlsFromText(undefined), undefined)
assert.strictEqual(removeUrlsFromText(null), null)
assert.strictEqual(removeUrlsFromText(""), "")
assert.strictEqual(removeUrlsFromText("clean text"), "clean text")
assert.strictEqual(removeUrlsFromText("text https://url.com end"), "text end")
assert.strictEqual(removeUrlsFromText("text http://www.url.com https://url.com [email protected] end"), "text end")
assert.strictEqual(removeUrlsFromText("text https://url.com www.url.com/?meh=lah mailto:[email protected] ftp://bad-ressource.com/path/path"), "text ")
})

it("Mise entre [] des différentes formes d'URL dans un texte", () => {
assert.strictEqual(addBracketsToUrls(undefined), undefined)
assert.strictEqual(addBracketsToUrls(null), null)
assert.strictEqual(addBracketsToUrls(""), "")
assert.strictEqual(addBracketsToUrls("clean text"), "clean text")
assert.strictEqual(addBracketsToUrls("clean [email protected] text"), "clean [[email protected]] text")
assert.strictEqual(addBracketsToUrls("text https://url.com end"), "text [https://url.com] end")
assert.strictEqual(
addBracketsToUrls("text http://www.url.com https://url.com [email protected] end"),
"text [http://[www.url.com]] [https://url.com] [[email protected]] end"
)
assert.strictEqual(
addBracketsToUrls("text https://url.com www.url.com/?meh=lah mailto:[email protected] ftp://bad-ressource.com/path/path"),
"text [https://url.com] [www.url.com/?meh=lah] [mailto:[[email protected]]] [ftp://bad-ressource.com/path/path]"
)
})

it.skip("Encryption décryption fonctionne", () => {
const value = "Chaîne@crypter"

Expand Down
24 changes: 24 additions & 0 deletions shared/helpers/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,27 @@ export const cleanEmail = (email: string) => {
cleanedEmail = cleanedEmail.replace(new RegExp("œ", "gi"), "o")
return cleanedEmail
}

const httpLinkRegex = /\b(https?:\/\/[^\s]+\b)/g
const wwwLinkRegex = /\bwww\.[^\s]+\b/g
const emailRegex = /\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b/g
const ftpLinkRegex = /\bftp:\/\/[^\s]+\b/g
const mailtoRegex = /\bmailto:([^\s<>]+)\b/g

export const removeUrlsFromText = (text: string | null | undefined) => {
if (!text) return text
const cleanedText = text.replace(httpLinkRegex, "").replace(wwwLinkRegex, "").replace(mailtoRegex, "").replace(emailRegex, "").replace(ftpLinkRegex, "")
return cleanedText
}

export const addBracketsToUrls = (text: string | null | undefined) => {
if (!text) return text
const textWithSanitizedUrls = text
.replace(httpLinkRegex, "[$&]")
.replace(wwwLinkRegex, "[$&]")
.replace(mailtoRegex, "[$&]")
.replace(emailRegex, "[$&]")
.replace(ftpLinkRegex, "[$&]")

return textWithSanitizedUrls
}
alanlr marked this conversation as resolved.
Show resolved Hide resolved
7 changes: 6 additions & 1 deletion shared/helpers/zodHelpers/zodPrimitives.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { capitalize } from "lodash-es"

import { CODE_NAF_REGEX, SIRET_REGEX, UAI_REGEX } from "../../constants/regex"
import { validateSIRET } from "../../validators/siretValidator"
import { removeUrlsFromText } from "../common"
import { z } from "../zodWithOpenApi"

// custom error map to translate zod errors to french
Expand Down Expand Up @@ -34,7 +35,11 @@ export const extensions = {
example: "78424186100011",
}),
uai: () => z.string().trim().regex(UAI_REGEX, "UAI invalide"), // e.g 0123456B
phone: () => z.string().trim() /*.regex(phoneRegex)*/,
phone: () =>
z
.string()
.trim()
.transform((value) => removeUrlsFromText(value)) /*.regex(phoneRegex)*/,
code_naf: () =>
z.preprocess(
(v: unknown) => (typeof v === "string" ? v.replace(".", "") : v), // parfois, le code naf contient un point
Expand Down
27 changes: 18 additions & 9 deletions shared/models/applications.model.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { addBracketsToUrls, removeUrlsFromText } from "../helpers/common"
import { extensions } from "../helpers/zodHelpers/zodPrimitives"
import { z } from "../helpers/zodWithOpenApi"
import { zCallerParam } from "../routes/_params"
Expand All @@ -11,14 +12,22 @@ export const ZApplication = z
description: "L'adresse email du candidat à laquelle l'entreprise contactée pourra répondre. Les adresses emails temporaires ne sont pas acceptées.",
example: "[email protected]",
}),
applicant_first_name: z.string().max(50).openapi({
description: "Le prénom du candidat.",
example: "Jean",
}),
applicant_last_name: z.string().max(50).openapi({
description: "Le nom du candidat.",
example: "Dupont",
}),
applicant_first_name: z
.string()
.max(50)
.transform((value) => removeUrlsFromText(value))
.openapi({
description: "Le prénom du candidat.",
example: "Jean",
}),
applicant_last_name: z
.string()
.max(50)
.transform((value) => removeUrlsFromText(value))
.openapi({
description: "Le nom du candidat.",
example: "Dupont",
}),
applicant_phone: extensions.phone().openapi({
description: "Le numéro de téléphone du candidat.",
example: "0101010101",
Expand Down Expand Up @@ -82,7 +91,7 @@ export const ZApplication = z
.openapi("Application")

export const ZApplicationUI = ZApplication.extend({
message: ZApplication.shape.applicant_message_to_company.optional(),
message: ZApplication.shape.applicant_message_to_company.optional().transform((value) => addBracketsToUrls(value)),
applicant_file_name: ZApplication.shape.applicant_attachment_name,
applicant_file_content: z.string().max(4215276).openapi({
description: "Le contenu du fichier du CV du candidat. La taille maximale autorisée est de 3 Mo.",
Expand Down
7 changes: 4 additions & 3 deletions shared/routes/application.routes.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { addBracketsToUrls } from "../helpers/common"
import { extensions } from "../helpers/zodHelpers/zodPrimitives"
import { z } from "../helpers/zodWithOpenApi"
import { ZLbacError } from "../models"
Expand Down Expand Up @@ -64,10 +65,10 @@ export const zApplicationRoutes = {
params: z.object({ id: z.string() }).strict(),
body: z
.object({
company_feedback: z.string(),
company_feedback: z.string().transform((value) => addBracketsToUrls(value)),
company_recruitment_intention: z.string(),
email: z.string(),
phone: z.string(),
email: z.string().email(),
phone: extensions.phone(),
})
.strict(),
response: {
Expand Down
Loading