From e210f1f95f07b54f8a4e3700d29aa7d458f452ad Mon Sep 17 00:00:00 2001 From: Mathis HERRIOT <197931332+0x485254@users.noreply.github.com> Date: Thu, 8 Jan 2026 15:25:16 +0100 Subject: [PATCH] feat: add env schema for environment variable validation Introduced `env.schema.ts` for structured validation of environment variables using Zod. Includes defaults and validations for database, S3, security, mail, Redis, and session configurations. --- backend/src/config/env.schema.ts | 63 ++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 backend/src/config/env.schema.ts diff --git a/backend/src/config/env.schema.ts b/backend/src/config/env.schema.ts new file mode 100644 index 0000000..4c67cdb --- /dev/null +++ b/backend/src/config/env.schema.ts @@ -0,0 +1,63 @@ +import { z } from "zod"; + +export const envSchema = z.object({ + NODE_ENV: z.enum(["development", "production", "test"]).default("development"), + PORT: z.coerce.number().default(3000), + + // Database + POSTGRES_HOST: z.string(), + POSTGRES_PORT: z.coerce.number().default(5432), + POSTGRES_DB: z.string(), + POSTGRES_USER: z.string(), + POSTGRES_PASSWORD: z.string(), + + // S3 + S3_ENDPOINT: z.string().default("localhost"), + S3_PORT: z.coerce.number().default(9000), + S3_USE_SSL: z.preprocess((val) => val === "true", z.boolean()).default(false), + S3_ACCESS_KEY: z.string().default("minioadmin"), + S3_SECRET_KEY: z.string().default("minioadmin"), + S3_BUCKET_NAME: z.string().default("memegoat"), + + // Security + JWT_SECRET: z.string().min(32), + ENCRYPTION_KEY: z.string().length(32), + PGP_ENCRYPTION_KEY: z.string().min(16), + + // Mail + MAIL_HOST: z.string(), + MAIL_PORT: z.coerce.number(), + MAIL_SECURE: z.preprocess((val) => val === "true", z.boolean()).default(false), + MAIL_USER: z.string(), + MAIL_PASS: z.string(), + MAIL_FROM: z.string().email(), + + DOMAIN_NAME: z.string(), + + // Sentry + SENTRY_DSN: z.string().optional(), + + // Redis + REDIS_HOST: z.string().default("localhost"), + REDIS_PORT: z.coerce.number().default(6379), + + // Session + SESSION_PASSWORD: z.string().min(32), + + // Media Limits + MAX_IMAGE_SIZE_KB: z.coerce.number().default(512), + MAX_GIF_SIZE_KB: z.coerce.number().default(1024), +}); + +export type Env = z.infer; + +export function validateEnv(config: Record) { + const result = envSchema.safeParse(config); + + if (!result.success) { + console.error("❌ Invalid environment variables:", result.error.format()); + throw new Error("Invalid environment variables"); + } + + return result.data; +}