From be25b9578973b2261560bd8f9f141131ce29a1f5 Mon Sep 17 00:00:00 2001 From: Oliver Akins Date: Thu, 23 Jun 2022 11:40:09 -0600 Subject: [PATCH] Add data validation to the config --- server/src/main.ts | 12 ++----- server/src/utils/config.ts | 66 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+), 10 deletions(-) create mode 100644 server/src/utils/config.ts diff --git a/server/src/main.ts b/server/src/main.ts index f29bce0..3c2ddd3 100644 --- a/server/src/main.ts +++ b/server/src/main.ts @@ -2,19 +2,11 @@ import "module-alias/register"; import startWebsocketServer from "./websocket"; +import { loadConfig } from "./utils/config"; import { GameDB } from "./objects/GameDB"; import { Logger } from "tslog"; -import toml from "toml"; -import fs from "fs"; -// load the config -try { - var configData = toml.parse(fs.readFileSync("config.toml", "utf-8")); -} catch { - console.error("Can't find config file. Exiting"); - process.exit(1); -}; -export const config: IConfig = configData; +export const config: IConfig = loadConfig(); // Define the logger export const log = new Logger({ diff --git a/server/src/utils/config.ts b/server/src/utils/config.ts new file mode 100644 index 0000000..fa7ac7c --- /dev/null +++ b/server/src/utils/config.ts @@ -0,0 +1,66 @@ +import { readFileSync } from "fs"; +import { log } from "@/main"; +import toml from "toml"; +import Joi from "joi"; + +const schema = Joi.object({ + game: Joi.object({ + type: Joi + .string() + .allow( + `file:json`, + // `file:csv`, + // `web:json`, + // `web:csv` + ) + .required() + .message(`Invalid deck type`), + location: Joi + .string() + .required() + .message(`The deck location must be a string`), + }), + server: Joi.object({ + port: Joi + .number() + .port() + .required() + .message(`Invalid port number`), + cors: Joi.object({ + origins: Joi + .array() + .items(Joi.string()) + .message(`The CORS origins must be an array of strings`), + }), + }), + log: Joi.object({ + level: Joi + .string() + .allow( + `silly`, + `trace`, + `debug`, + `info`, + `warn`, + `error`, + `fatal` + ) + .optional() + .default(`info`) + .message(`Invalid log level`), + }), +}); + +export function loadConfig(): IConfig { + const data = toml.parse(readFileSync("config.toml", "utf-8")); + const { value, error } = schema.validate(data, { + abortEarly: false, + }); + + if (error) { + log.error(`Configuration object failed to validate`) + log.error(error); + process.exit(1); + }; + return value; +}; \ No newline at end of file