104 lines
2.7 KiB
TypeScript

import { promises as fs } from 'fs';
import { join as path_join } from 'path';
import { parse as parse_yaml } from 'yaml';
import { deep_merge } from './utilities/deep-merge';
import { OIDCConfig, validate_oidc_conf } from './security/openid-connect';
import { PKCECookieConfig, validate_pkce_cookie_conf } from './security/pkce-cookie';
import { SnowflakeConfig, validate_snowflake_conf } from './utilities/snowflake-uid';
import { StorageConfig } from './storage/config';
import { LoggingConfig, validate_logging_conf } from './logger';
import { Argon2HashConfig } from './security/argon-hash';
import { SessionCookieConfig, validate_session_cookie_conf } from './security/session';
import { HttpConfig } from './http/server';
import { ColorThemeConfig } from './utilities/color-themes';
const conf_dir = process.env.CONF_PATH;
if (! conf_dir) {
console.error('No CONF_PATH defined');
process.exit(1);
}
export const app_name = 'My Cool App';
export const app_version = '1.0.0-alpha.0';
export interface Conf {
http_web: HttpConfig;
http_meta: HttpConfig;
logging: LoggingConfig;
oidc: OIDCConfig;
pkce_cookie: PKCECookieConfig;
session_cookie: SessionCookieConfig;
snowflake_uid: SnowflakeConfig;
storage: StorageConfig;
argon2: Argon2HashConfig;
color_themes: ColorThemeConfig;
}
export async function load_conf() : Promise<unknown> {
const conf = Object.create(null);
const files = await fs.readdir(conf_dir, { recursive: true });
// Sort configuration files by file name for consistent load order (users should
// number prefix their config file names)
files.sort((a, b) => a.localeCompare(b));
// Load each config file in order, parse as YAML, and merge the contents into the
// results object
for (const file of files) {
const conf_yaml = await fs.readFile(path_join(conf_dir, file), 'utf8');
const conf_parsed = parse_yaml(conf_yaml);
deep_merge(conf, conf_parsed);
}
return conf;
}
export function validate_conf(conf: unknown) : asserts conf is Conf {
if (typeof conf !== 'object' || ! conf) {
throw new Error('`conf` is not an object');
}
if ('logging' in conf) {
validate_logging_conf(conf.logging);
}
else {
throw new Error('`conf.logging` is missing');
}
if ('oidc' in conf) {
validate_oidc_conf(conf.oidc)
}
else {
throw new Error('`conf.oidc` is missing');
}
if ('pkce_cookie' in conf) {
validate_pkce_cookie_conf(conf.pkce_cookie);
}
else {
throw new Error('`conf.pkce_cookie` is missing');
}
if ('snowflake_uid' in conf) {
validate_snowflake_conf(conf.snowflake_uid);
}
else {
throw new Error('`conf.snowflake_uid` is missing');
}
if ('session_cookie' in conf) {
validate_session_cookie_conf(conf.session_cookie);
}
else {
throw new Error('`conf.session_cookie` is missing');
}
}