import { config as dotenvConfig } from "dotenv";
import { z } from "zod";
// Load environment variables from .env file, if available
dotenvConfig({ quiet: true });
/**
* Environment variables schema and validation for K12 Auth Service.
* Defines the expected shape of environment variables.
* Uses `zod` for schema definition and runtime validation.
* All variables are required unless a default value is provided.
* Use {@link env} instead of accessing `process.env` directly.
* @see https://github.com/colinhacks/zod
*/
const envSchema = z.object({
/** HTTP server port */
PORT: z.coerce.number().default(3001),
/** gRPC server port */
GRPC_PORT: z.coerce.number().default(50051),
/** Node.js environment (development, production, test) */
NODE_ENV: z.enum(["development", "local", "production", "test"]).default("local"),
/** Environment prefix for GCS paths (qa, dev, etc.) */
ENV_PREFIX: z.string().optional().default(""),
/** MongoDB connection URI - must be provided */
MONGODB_URI: z.string().url().default("mongodb://localhost:27017/k12_auth"),
/** Redis connection URI - must be provided */
REDIS_URI: z.string().url().default("redis://localhost:6379"),
/** Redis database index */
REDIS_DB_INDEX: z.coerce.number().int().min(0).default(0),
/** JWT Configuration */
JWT_EXPIRES_IN: z
.string()
.default("1h")
.transform((val) => val),
JWT_REFRESH_EXPIRES_IN: z
.string()
.default("7d")
.transform((val) => val),
JWT_SECRET: z.string().default("secret"),
JWT_REFRESH_SECRET: z.string().default("refresh-secret"),
/** HashiCorp Vault Configuration */
/** HashiCorp Vault server URL */
VAULT_URL: z.string().url().default("http://localhost:8200"),
/** HashiCorp Vault authentication token */
VAULT_TOKEN: z.string().optional(),
/** HashiCorp Vault role ID for AppRole auth */
VAULT_ROLE_ID: z.string().optional(),
/** HashiCorp Vault secret ID for AppRole auth */
VAULT_SECRET_ID: z.string().optional(),
/** HashiCorp Vault secrets engine mount path */
VAULT_MOUNT_PATH: z.string().default("secret"),
/** HashiCorp Vault API version */
VAULT_API_VERSION: z.enum(["v1", "v2"]).default("v1"),
/** Google Cloud Storage Configuration */
GCS_BUCKET_NAME: z.string().default("k12-auth-avatars"),
GCS_PROJECT_ID: z.string().optional(),
/** Avatar Image Processing Configuration */
AVATAR_SIZE: z.coerce.number().int().min(128).max(2048).default(512),
AVATAR_QUALITY: z.coerce.number().int().min(1).max(100).default(80),
AVATAR_MAX_SIZE_MB: z.coerce.number().int().min(1).max(50).default(10),
AVATAR_FORMAT: z.enum(["webp", "jpeg", "png"]).default("webp"),
AVATAR_COMPRESSION_EFFORT: z.coerce.number().int().min(0).max(6).default(6),
/** Rate Limiting Configuration */
RATE_LIMIT_WINDOW_MS: z
.string()
.transform((val) => parseInt(val, 10))
.pipe(z.number().min(1000))
.default("900000"), // 15 minutes
RATE_LIMIT_MAX_REQUESTS: z
.string()
.transform((val) => parseInt(val, 10))
.pipe(z.number().min(1))
.default("100"),
/** CORS Configuration */
ALLOWED_ORIGINS: z
.string()
.default("http://localhost:3000,https://admin-panel.dev.k12.aaic.dev,https://admin-panel.qa.k12.aaic.dev"),
/** Logging Configuration */
LOG_LEVEL: z.enum(["error", "warn", "info", "debug"]).default("info"),
/** SMTP Configuration (optional) */
SMTP_HOST: z.string().optional(),
SMTP_PORT: z.coerce.number().optional(),
SMTP_USER: z.string().optional(),
SMTP_PASSWORD: z.string().optional(),
SMTP_FROM: z.string().optional(),
/** Admin User Configuration */
ADMIN_EMAIL: z.string().email().default("root-admin@gmail.com"),
ADMIN_PASSWORD: z.string().min(8).default("admin123456"),
/** Password Hashing Configuration */
BCRYPT_SALT_ROUNDS: z
.string()
.transform((val) => parseInt(val, 10))
.pipe(z.number().min(10).max(15))
.default("12"),
});
/** Parsed and validated environment variables. */
export const env = envSchema.parse(process.env);
Source