From b838f0e8ea6c75945ff98dcf1e511f4ac6616c8a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 4 May 2026 10:56:44 +0200 Subject: [PATCH] build(deps): bump zod from 3.25.76 to 4.4.3 in /backend * build(deps): bump zod from 3.25.76 to 4.4.3 in /backend Bumps [zod](https://github.com/colinhacks/zod) from 3.25.76 to 4.4.3. - [Release notes](https://github.com/colinhacks/zod/releases) - [Commits](https://github.com/colinhacks/zod/compare/v3.25.76...v4.4.3) --- updated-dependencies: - dependency-name: zod dependency-version: 4.4.3 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] * fix: adapt backend validation for zod v4 --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Daniel Volz --- backend/package-lock.json | 8 ++++---- backend/package.json | 2 +- backend/src/plugins/env.ts | 16 ++++++++-------- backend/src/routes/auth.ts | 4 ++-- backend/src/routes/doses.ts | 15 ++++++++++++--- backend/src/routes/medications.ts | 2 +- backend/src/routes/share.ts | 2 +- backend/src/test/env.test.ts | 14 +++++++------- 8 files changed, 36 insertions(+), 27 deletions(-) diff --git a/backend/package-lock.json b/backend/package-lock.json index e463cc2..e8a1c02 100644 --- a/backend/package-lock.json +++ b/backend/package-lock.json @@ -27,7 +27,7 @@ "nodemailer": "^8.0.7", "openid-client": "^6.8.4", "sharp": "^0.34.5", - "zod": "^3.23.8" + "zod": "^4.4.3" }, "devDependencies": { "@biomejs/biome": "^2.4.14", @@ -5317,9 +5317,9 @@ } }, "node_modules/zod": { - "version": "3.25.76", - "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", - "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/zod/-/zod-4.4.3.tgz", + "integrity": "sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ==", "license": "MIT", "funding": { "url": "https://github.com/sponsors/colinhacks" diff --git a/backend/package.json b/backend/package.json index d349961..d8cea7a 100644 --- a/backend/package.json +++ b/backend/package.json @@ -36,7 +36,7 @@ "nodemailer": "^8.0.7", "openid-client": "^6.8.4", "sharp": "^0.34.5", - "zod": "^3.23.8" + "zod": "^4.4.3" }, "devDependencies": { "@biomejs/biome": "^2.4.14", diff --git a/backend/src/plugins/env.ts b/backend/src/plugins/env.ts index f8c4ffe..f723b9d 100644 --- a/backend/src/plugins/env.ts +++ b/backend/src/plugins/env.ts @@ -11,7 +11,7 @@ const EnvSchema = z.object({ PORT: z .string() .transform((v) => parseInt(v, 10)) - .default("3000"), + .default(3000), CORS_ORIGINS: z.string().default("http://localhost:5173,http://localhost:4173"), LOG_LEVEL: z.string().default("info"), OPENAPI_DOCS_ENABLED: z @@ -26,17 +26,17 @@ const EnvSchema = z.object({ AUTH_ENABLED: z .string() .transform((v) => v === "true") - .default("false"), + .default(false), // Allow new user registrations (auto-enabled if no users exist) REGISTRATION_ENABLED: z .string() .transform((v) => v === "true") - .default("false"), + .default(false), // Disable username/password form login (useful for OIDC-only setups) FORM_LOGIN_ENABLED: z .string() .transform((v) => v === "true") - .default("true"), + .default(true), // JWT Secrets - only required when AUTH_ENABLED=true JWT_SECRET: z.string().min(10).optional(), @@ -47,11 +47,11 @@ const EnvSchema = z.object({ ACCESS_TOKEN_TTL_MINUTES: z .string() .transform((v) => parseInt(v, 10)) - .default("15"), + .default(15), REFRESH_TOKEN_TTL_DAYS: z .string() .transform((v) => parseInt(v, 10)) - .default("7"), + .default(7), // ========================================================================== // OIDC SSO Configuration (Pocket ID, Authelia, etc.) @@ -59,7 +59,7 @@ const EnvSchema = z.object({ OIDC_ENABLED: z .string() .transform((v) => v === "true") - .default("false"), + .default(false), OIDC_ISSUER_URL: z.string().url().optional(), // e.g., https://auth.example.com OIDC_CLIENT_ID: z.string().optional(), OIDC_CLIENT_SECRET: z.string().optional(), @@ -68,7 +68,7 @@ const EnvSchema = z.object({ OIDC_AUTO_CREATE_USERS: z .string() .transform((v) => v === "true") - .default("true"), + .default(true), OIDC_USERNAME_CLAIM: z.string().default("preferred_username"), // or 'email', 'sub' OIDC_PROVIDER_NAME: z.string().default("SSO"), // Display name for UI button }); diff --git a/backend/src/routes/auth.ts b/backend/src/routes/auth.ts index 95114d6..6b3a1e8 100644 --- a/backend/src/routes/auth.ts +++ b/backend/src/routes/auth.ts @@ -221,7 +221,7 @@ export async function authRoutes(app: FastifyInstance) { const parsed = registerSchema.safeParse(request.body); if (!parsed.success) { return reply.status(400).send({ - error: parsed.error.errors[0]?.message ?? "Invalid input", + error: parsed.error.issues[0]?.message ?? "Invalid input", code: "VALIDATION_ERROR", }); } @@ -616,7 +616,7 @@ export async function authRoutes(app: FastifyInstance) { const parsed = updateProfileSchema.safeParse(request.body); if (!parsed.success) { return reply.status(400).send({ - error: parsed.error.errors[0]?.message ?? "Invalid input", + error: parsed.error.issues[0]?.message ?? "Invalid input", code: "VALIDATION_ERROR", }); } diff --git a/backend/src/routes/doses.ts b/backend/src/routes/doses.ts index f214a8e..0048e49 100644 --- a/backend/src/routes/doses.ts +++ b/backend/src/routes/doses.ts @@ -61,6 +61,15 @@ const doseReadResponseSchema = { }, } as const; +function getValidationErrorMessage(error: z.ZodError): string { + const firstIssue = error.issues[0]; + if (!firstIssue) { + return "Invalid input"; + } + + return firstIssue.code === "invalid_type" && firstIssue.input === undefined ? "Required" : firstIssue.message; +} + // Helper to get user ID from request // Returns anonymous user ID when auth is disabled async function getUserId(request: FastifyRequest, reply: FastifyReply): Promise { @@ -301,7 +310,7 @@ export async function doseRoutes(app: FastifyInstance) { const parsed = markDoseSchema.safeParse(request.body); if (!parsed.success) { return reply.status(400).send({ - error: parsed.error.errors[0]?.message ?? "Invalid input", + error: getValidationErrorMessage(parsed.error), }); } @@ -423,7 +432,7 @@ export async function doseRoutes(app: FastifyInstance) { const parsed = dismissDosesSchema.safeParse(request.body); if (!parsed.success) { return reply.status(400).send({ - error: parsed.error.errors[0]?.message ?? "Invalid input", + error: getValidationErrorMessage(parsed.error), }); } @@ -590,7 +599,7 @@ export async function doseRoutes(app: FastifyInstance) { const parsed = shareDoseSchema.safeParse(request.body); if (!parsed.success) { return reply.status(400).send({ - error: parsed.error.errors[0]?.message ?? "Invalid input", + error: getValidationErrorMessage(parsed.error), }); } diff --git a/backend/src/routes/medications.ts b/backend/src/routes/medications.ts index 2331924..b1a2c73 100644 --- a/backend/src/routes/medications.ts +++ b/backend/src/routes/medications.ts @@ -1654,7 +1654,7 @@ export async function medicationRoutes(app: FastifyInstance) { async (req, reply) => { const parsed = dismissUntilSchema.safeParse(req.body); if (!parsed.success) { - return reply.status(400).send({ error: parsed.error.errors[0]?.message ?? "Invalid input" }); + return reply.status(400).send({ error: parsed.error.issues[0]?.message ?? "Invalid input" }); } const userId = await getUserId(req, reply); diff --git a/backend/src/routes/share.ts b/backend/src/routes/share.ts index b27ea43..b034d4b 100644 --- a/backend/src/routes/share.ts +++ b/backend/src/routes/share.ts @@ -385,7 +385,7 @@ export async function shareRoutes(app: FastifyInstance) { const parsed = createShareSchema.safeParse(request.body); if (!parsed.success) { return reply.status(400).send({ - error: parsed.error.errors[0]?.message ?? "Invalid input", + error: parsed.error.issues[0]?.message ?? "Invalid input", code: "VALIDATION_ERROR", }); } diff --git a/backend/src/test/env.test.ts b/backend/src/test/env.test.ts index 9a35881..ad4f070 100644 --- a/backend/src/test/env.test.ts +++ b/backend/src/test/env.test.ts @@ -11,32 +11,32 @@ const EnvSchema = z.object({ PORT: z .string() .transform((v) => parseInt(v, 10)) - .default("3000"), + .default(3000), CORS_ORIGINS: z.string().default("http://localhost:5173,http://localhost:4173"), LOG_LEVEL: z.string().default("info"), AUTH_ENABLED: z .string() .transform((v) => v === "true") - .default("false"), + .default(false), REGISTRATION_ENABLED: z .string() .transform((v) => v === "true") - .default("false"), + .default(false), JWT_SECRET: z.string().min(10).optional(), REFRESH_SECRET: z.string().min(10).optional(), COOKIE_SECRET: z.string().min(10).optional(), ACCESS_TOKEN_TTL_MINUTES: z .string() .transform((v) => parseInt(v, 10)) - .default("15"), + .default(15), REFRESH_TOKEN_TTL_DAYS: z .string() .transform((v) => parseInt(v, 10)) - .default("7"), + .default(7), OIDC_ENABLED: z .string() .transform((v) => v === "true") - .default("false"), + .default(false), OIDC_ISSUER_URL: z.string().url().optional(), OIDC_CLIENT_ID: z.string().optional(), OIDC_CLIENT_SECRET: z.string().optional(), @@ -45,7 +45,7 @@ const EnvSchema = z.object({ OIDC_AUTO_CREATE_USERS: z .string() .transform((v) => v === "true") - .default("true"), + .default(true), OIDC_USERNAME_CLAIM: z.string().default("preferred_username"), OIDC_PROVIDER_NAME: z.string().default("SSO"), });