From dfb6b66a2478ce392bea59eada6917d59842e148 Mon Sep 17 00:00:00 2001 From: Kevin Barnoin Date: Wed, 22 Nov 2023 17:53:39 +0100 Subject: [PATCH] Fix zod preprocess (#846) * feat: downgrade zod * feat: patch zod email with version 3.22.4 * feat: test --- .talismanrc | 4 ++ .yarn/patches/zod-npm-3.21.4-9f570b215c.patch | 39 +++++++++++++ package.json | 3 + server/package.json | 2 +- server/tests/unit/external/zod.test.ts | 56 +++++++++++++++++++ shared/package.json | 2 +- ui/package.json | 2 +- yarn.lock | 21 ++++--- 8 files changed, 119 insertions(+), 10 deletions(-) create mode 100644 .yarn/patches/zod-npm-3.21.4-9f570b215c.patch create mode 100644 server/tests/unit/external/zod.test.ts diff --git a/.talismanrc b/.talismanrc index 369f1f374e..d2dc884df4 100644 --- a/.talismanrc +++ b/.talismanrc @@ -25,6 +25,8 @@ fileignoreconfig: checksum: 3679dcde17d9d606ef7b27ad632122fcf19a4180849ed4cd1cbc98c312dd0d29 - filename: .infra/vault/vault.yml checksum: 9ac87932d132cd238bc2194daadd08b26491985332c9ed15ccfd6f14a0645839 +- filename: .yarn/patches/zod-npm-3.21.4-9f570b215c.patch + checksum: d429ff982063e6476ea8d8d91ac1173a1279d1c9bf0488b6e05396affeb8c6cf - filename: server/.env.test checksum: 870b319418d2bd31728a0925d70ae4b6ef0ac6980ddf3feeb2702e32f868115d - filename: server/src/common/apis/Pe.ts @@ -51,6 +53,8 @@ fileignoreconfig: checksum: 5ea3eed110facafaa7c3cbe3a6cb9f4bca5984f9c34b5e6987355aaea90bdbf6 - filename: server/tests/integration/http/passwordRoutes.test.ts checksum: e9869aceb9bb23877dccf1c6e2de729bfe685f7e40231c465fc40cdcc7c68c14 +- filename: server/tests/unit/external/zod.test.ts + checksum: f77ba0fa55f1cbd5b708fdc9f0d5b229e84a1de6c433186d96aa94a7f6388f0c - filename: server/tests/unit/security/accessTokenService.test.ts checksum: 232b1bae52a4d4f961637f59b09da5e480147864c76980a2b86e77a73bb36923 - filename: server/tests/unit/security/authorisationService.test.ts diff --git a/.yarn/patches/zod-npm-3.21.4-9f570b215c.patch b/.yarn/patches/zod-npm-3.21.4-9f570b215c.patch new file mode 100644 index 0000000000..018e04bf30 --- /dev/null +++ b/.yarn/patches/zod-npm-3.21.4-9f570b215c.patch @@ -0,0 +1,39 @@ +diff --git a/lib/index.mjs b/lib/index.mjs +index 69078d509e93842067aa7de3c201c9f01c0e86b0..2ebb2228013de1c5a8c503b65deef73ae5dbead8 100644 +--- a/lib/index.mjs ++++ b/lib/index.mjs +@@ -819,7 +819,7 @@ const uuidRegex = /^([a-f0-9]{8}-[a-f0-9]{4}-[1-5][a-f0-9]{3}-[a-f0-9]{4}-[a-f0- + //old email regex + // const emailRegex = /^(([^<>()[\].,;:\s@"]+(\.[^<>()[\].,;:\s@"]+)*)|(".+"))@((?!-)([^<>()[\].,;:\s@"]+\.)+[^<>()[\].,;:\s@"]{1,})[^-<>()[\].,;:\s@"]$/i; + // eslint-disable-next-line +-const emailRegex = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[(((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2}))\.){3}((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2}))\])|(\[IPv6:(([a-f0-9]{1,4}:){7}|::([a-f0-9]{1,4}:){0,6}|([a-f0-9]{1,4}:){1}:([a-f0-9]{1,4}:){0,5}|([a-f0-9]{1,4}:){2}:([a-f0-9]{1,4}:){0,4}|([a-f0-9]{1,4}:){3}:([a-f0-9]{1,4}:){0,3}|([a-f0-9]{1,4}:){4}:([a-f0-9]{1,4}:){0,2}|([a-f0-9]{1,4}:){5}:([a-f0-9]{1,4}:){0,1})([a-f0-9]{1,4}|(((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2}))\.){3}((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2})))\])|([A-Za-z0-9]([A-Za-z0-9-]*[A-Za-z0-9])*(\.[A-Za-z]{2,})+))$/; ++const emailRegex = /^(?!\.)(?!.*\.\.)([A-Z0-9_+-\.]*)[A-Z0-9_+-]@([A-Z0-9][A-Z0-9\-]*\.)+[A-Z]{2,}$/i; + // from https://thekevinscott.com/emojis-in-javascript/#writing-a-regular-expression + const emojiRegex = /^(\p{Extended_Pictographic}|\p{Emoji_Component})+$/u; + const ipv4Regex = /^(((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2}))\.){3}((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2}))$/; +diff --git a/lib/index.umd.js b/lib/index.umd.js +index 4a2f51787608267d58f25515fa654dce8606653f..749b0bd0bb37426d69c350f8b8547177357883f1 100644 +--- a/lib/index.umd.js ++++ b/lib/index.umd.js +@@ -825,7 +825,7 @@ + //old email regex + // const emailRegex = /^(([^<>()[\].,;:\s@"]+(\.[^<>()[\].,;:\s@"]+)*)|(".+"))@((?!-)([^<>()[\].,;:\s@"]+\.)+[^<>()[\].,;:\s@"]{1,})[^-<>()[\].,;:\s@"]$/i; + // eslint-disable-next-line +- const emailRegex = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[(((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2}))\.){3}((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2}))\])|(\[IPv6:(([a-f0-9]{1,4}:){7}|::([a-f0-9]{1,4}:){0,6}|([a-f0-9]{1,4}:){1}:([a-f0-9]{1,4}:){0,5}|([a-f0-9]{1,4}:){2}:([a-f0-9]{1,4}:){0,4}|([a-f0-9]{1,4}:){3}:([a-f0-9]{1,4}:){0,3}|([a-f0-9]{1,4}:){4}:([a-f0-9]{1,4}:){0,2}|([a-f0-9]{1,4}:){5}:([a-f0-9]{1,4}:){0,1})([a-f0-9]{1,4}|(((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2}))\.){3}((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2})))\])|([A-Za-z0-9]([A-Za-z0-9-]*[A-Za-z0-9])*(\.[A-Za-z]{2,})+))$/; ++ const emailRegex = /^(?!\.)(?!.*\.\.)([A-Z0-9_+-\.]*)[A-Z0-9_+-]@([A-Z0-9][A-Z0-9\-]*\.)+[A-Z]{2,}$/i; + // from https://thekevinscott.com/emojis-in-javascript/#writing-a-regular-expression + const emojiRegex = /^(\p{Extended_Pictographic}|\p{Emoji_Component})+$/u; + const ipv4Regex = /^(((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2}))\.){3}((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2}))$/; +diff --git a/lib/types.js b/lib/types.js +index 5f89d3740b29e4419cccbb7b15e1d0ac0fea8936..eb6231ab7d0b148edaca29655ad5c52cd4c56774 100644 +--- a/lib/types.js ++++ b/lib/types.js +@@ -321,7 +321,7 @@ const cuidRegex = /^c[^\s-]{8,}$/i; + const cuid2Regex = /^[a-z][a-z0-9]*$/; + const ulidRegex = /[0-9A-HJKMNP-TV-Z]{26}/; + const uuidRegex = /^([a-f0-9]{8}-[a-f0-9]{4}-[1-5][a-f0-9]{3}-[a-f0-9]{4}-[a-f0-9]{12}|00000000-0000-0000-0000-000000000000)$/i; +-const emailRegex = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[(((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2}))\.){3}((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2}))\])|(\[IPv6:(([a-f0-9]{1,4}:){7}|::([a-f0-9]{1,4}:){0,6}|([a-f0-9]{1,4}:){1}:([a-f0-9]{1,4}:){0,5}|([a-f0-9]{1,4}:){2}:([a-f0-9]{1,4}:){0,4}|([a-f0-9]{1,4}:){3}:([a-f0-9]{1,4}:){0,3}|([a-f0-9]{1,4}:){4}:([a-f0-9]{1,4}:){0,2}|([a-f0-9]{1,4}:){5}:([a-f0-9]{1,4}:){0,1})([a-f0-9]{1,4}|(((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2}))\.){3}((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2})))\])|([A-Za-z0-9]([A-Za-z0-9-]*[A-Za-z0-9])*(\.[A-Za-z]{2,})+))$/; ++const emailRegex = /^(?!\.)(?!.*\.\.)([A-Z0-9_+-\.]*)[A-Z0-9_+-]@([A-Z0-9][A-Z0-9\-]*\.)+[A-Z]{2,}$/i; + const emojiRegex = /^(\p{Extended_Pictographic}|\p{Emoji_Component})+$/u; + const ipv4Regex = /^(((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2}))\.){3}((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2}))$/; + const ipv6Regex = /^(([a-f0-9]{1,4}:){7}|::([a-f0-9]{1,4}:){0,6}|([a-f0-9]{1,4}:){1}:([a-f0-9]{1,4}:){0,5}|([a-f0-9]{1,4}:){2}:([a-f0-9]{1,4}:){0,4}|([a-f0-9]{1,4}:){3}:([a-f0-9]{1,4}:){0,3}|([a-f0-9]{1,4}:){4}:([a-f0-9]{1,4}:){0,2}|([a-f0-9]{1,4}:){5}:([a-f0-9]{1,4}:){0,1})([a-f0-9]{1,4}|(((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2}))\.){3}((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2})))$/; diff --git a/package.json b/package.json index 292cd98471..75eb635a36 100644 --- a/package.json +++ b/package.json @@ -115,5 +115,8 @@ "*": [ "prettier --write -u" ] + }, + "resolutions": { + "zod@3.21.4": "patch:zod@npm%3A3.21.4#./.yarn/patches/zod-npm-3.21.4-9f570b215c.patch" } } diff --git a/server/package.json b/server/package.json index f6b9c259e7..26f64175d9 100644 --- a/server/package.json +++ b/server/package.json @@ -90,7 +90,7 @@ "type-fest": "^4.3.3", "xlsx": "^0.18.5", "xml2js": "^0.6.2", - "zod": "^3.22.2" + "zod": "3.21.4" }, "devDependencies": { "@sentry/types": "^7.72.0", diff --git a/server/tests/unit/external/zod.test.ts b/server/tests/unit/external/zod.test.ts new file mode 100644 index 0000000000..cac5c921f3 --- /dev/null +++ b/server/tests/unit/external/zod.test.ts @@ -0,0 +1,56 @@ +import { describe, expect, it } from "vitest" +import { z } from "zod" + +describe("zod", () => { + describe("z.email()", () => { + ;[ + { input: '" "@example.org', expectedOutput: false }, + { input: '"very.(),:;<>[]".VERY."very@\\ "very".unusual"@strange.example.com', expectedOutput: false }, + { input: "inconnu", expectedOutput: false }, + { input: "inconnu", expectedOutput: false }, + { input: "user@domain", expectedOutput: false }, + { input: "user+tag@domain.com", expectedOutput: true }, + { input: "user@domain.com", expectedOutput: true }, + { input: "user@domain-dash.com", expectedOutput: true }, + { input: "user@sub.domain.com", expectedOutput: true }, + { input: "user@sub.domain-dash.com", expectedOutput: true }, + { input: "user.dot@domain.com", expectedOutput: true }, + { input: "user-dash.dot@domain.com", expectedOutput: true }, + ].forEach(({ input, expectedOutput }) => { + it(`${input} => ${expectedOutput ? "valide" : "invalide"}`, () => { + expect(z.string().email().safeParse(input).success).toStrictEqual(expectedOutput) + }) + }) + }) + + // https://github.com/colinhacks/zod/pull/2719 + it("preprocess validates with sibling errors", () => { + expect(() => { + z.object({ + // Must be first + missing: z.string().refine(() => false), + preprocess: z.preprocess((data: any) => data?.trim(), z.string().regex(/ asdf/)), + }).parse({ preprocess: " asdf" }) + }).toThrow( + JSON.stringify( + [ + { + code: "invalid_type", + expected: "string", + received: "undefined", + path: ["missing"], + message: "Required", + }, + { + validation: "regex", + code: "invalid_string", + message: "Invalid", + path: ["preprocess"], + }, + ], + null, + 2 + ) + ) + }) +}) diff --git a/shared/package.json b/shared/package.json index 68eb51c099..aaf1ddc48b 100644 --- a/shared/package.json +++ b/shared/package.json @@ -22,7 +22,7 @@ "lodash-es": "^4.17.21", "luhn": "^2.4.1", "type-fest": "^4.3.1", - "zod": "^3.22.2" + "zod": "3.21.4" }, "devDependencies": { "@types/boom": "^7.3.3", diff --git a/ui/package.json b/ui/package.json index 35981319b4..319fe5f7c4 100644 --- a/ui/package.json +++ b/ui/package.json @@ -51,7 +51,7 @@ "react-table": "^7.8.0", "shared": "workspace:*", "yup": "^0.32.11", - "zod": "^3.22.2" + "zod": "3.21.4" }, "devDependencies": { "@testing-library/react": "^13.4.0", diff --git a/yarn.lock b/yarn.lock index e52d5f1248..4ac063c20f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -17767,7 +17767,7 @@ __metadata: vitest: ^0.34.5 xlsx: ^0.18.5 xml2js: ^0.6.2 - zod: ^3.22.2 + zod: 3.21.4 zod-fixture: ^2.5.0 languageName: unknown linkType: soft @@ -17848,7 +17848,7 @@ __metadata: type-fest: ^4.3.1 typescript: ^5.2.2 vitest: ^0.34.5 - zod: ^3.22.2 + zod: 3.21.4 languageName: unknown linkType: soft @@ -19485,7 +19485,7 @@ __metadata: typescript: ^5.2.2 vitest: ^0.34.5 yup: ^0.32.11 - zod: ^3.22.2 + zod: 3.21.4 languageName: unknown linkType: soft @@ -20591,10 +20591,17 @@ __metadata: languageName: node linkType: hard -"zod@npm:^3.22.2": - version: 3.22.4 - resolution: "zod@npm:3.22.4" - checksum: 80bfd7f8039b24fddeb0718a2ec7c02aa9856e4838d6aa4864335a047b6b37a3273b191ef335bf0b2002e5c514ef261ffcda5a589fb084a48c336ffc4cdbab7f +"zod@npm:3.21.4": + version: 3.21.4 + resolution: "zod@npm:3.21.4" + checksum: f185ba87342ff16f7a06686767c2b2a7af41110c7edf7c1974095d8db7a73792696bcb4a00853de0d2edeb34a5b2ea6a55871bc864227dace682a0a28de33e1f + languageName: node + linkType: hard + +"zod@patch:zod@npm%3A3.21.4#./.yarn/patches/zod-npm-3.21.4-9f570b215c.patch::locator=mna-lba%40workspace%3A.": + version: 3.21.4 + resolution: "zod@patch:zod@npm%3A3.21.4#./.yarn/patches/zod-npm-3.21.4-9f570b215c.patch::version=3.21.4&hash=45704f&locator=mna-lba%40workspace%3A." + checksum: 8ac3afb02adff75a1d562c3479f39331548f94cd1d7f5d52623834ec75007db83c35edd8789d47d96ccb4994eec0c0a8e0bfd17130cd1db5013fd4900e0181f5 languageName: node linkType: hard