mirror of
https://github.com/PretendoNetwork/account.git
synced 2026-10-01 06:38:00 -05:00
Remade config manager. Removed JSON file support
This commit is contained in:
@@ -1,289 +1,163 @@
|
||||
import fs from 'fs-extra';
|
||||
import get from 'lodash.get';
|
||||
import set from 'lodash.set';
|
||||
import mongoose from 'mongoose';
|
||||
import dotenv from 'dotenv';
|
||||
import logger from '@/logger';
|
||||
import { Config, DisabledFeatures } from '@/types/common/config';
|
||||
|
||||
dotenv.config();
|
||||
|
||||
export let config: Record<string, any> = {};
|
||||
|
||||
export const disabledFeatures = {
|
||||
export const disabledFeatures: DisabledFeatures = {
|
||||
redis: false,
|
||||
email: false,
|
||||
captcha: false,
|
||||
s3: false
|
||||
};
|
||||
|
||||
const requiredFields = [
|
||||
['http.port', 'PN_ACT_CONFIG_HTTP_PORT', Number],
|
||||
['mongoose.connection_string', 'PN_ACT_CONFIG_MONGO_CONNECTION_STRING'],
|
||||
['cdn.base_url', 'PN_ACT_CONFIG_CDN_BASE_URL']
|
||||
];
|
||||
logger.info('Loading config');
|
||||
|
||||
export function configure() {
|
||||
const usingEnv = process.env.PN_ACT_PREFER_ENV_CONFIG === 'true';
|
||||
let mongooseConnectOptions: mongoose.ConnectOptions;
|
||||
|
||||
if (usingEnv) {
|
||||
logger.info('Loading config from environment variable');
|
||||
if (process.env.PN_ACT_CONFIG_MONGOOSE_CONNECT_OPTIONS_PATH) {
|
||||
mongooseConnectOptions = fs.readJSONSync(process.env.PN_ACT_CONFIG_MONGOOSE_CONNECT_OPTIONS_PATH);
|
||||
}
|
||||
|
||||
config = {
|
||||
http: {
|
||||
port: Number(process.env.PN_ACT_CONFIG_HTTP_PORT)
|
||||
},
|
||||
mongoose: {
|
||||
connection_string: process.env.PN_ACT_CONFIG_MONGO_CONNECTION_STRING,
|
||||
options: Object.keys(process.env)
|
||||
.filter(key => key.startsWith('PN_ACT_CONFIG_MONGOOSE_OPTION_'))
|
||||
.reduce((obj, key) => {
|
||||
obj[key.split('_').pop()] = process.env[key];
|
||||
return obj;
|
||||
}, {})
|
||||
},
|
||||
redis: {
|
||||
client: {
|
||||
url: process.env.PN_ACT_CONFIG_REDIS_URL
|
||||
}
|
||||
},
|
||||
email: {
|
||||
host: process.env.PN_ACT_CONFIG_EMAIL_HOST,
|
||||
port: Number(process.env.PN_ACT_CONFIG_EMAIL_PORT),
|
||||
secure: Boolean(process.env.PN_ACT_CONFIG_EMAIL_SECURE),
|
||||
auth: {
|
||||
user: process.env.PN_ACT_CONFIG_EMAIL_USERNAME,
|
||||
pass: process.env.PN_ACT_CONFIG_EMAIL_PASSWORD
|
||||
},
|
||||
from: process.env.PN_ACT_CONFIG_EMAIL_FROM
|
||||
},
|
||||
s3: {
|
||||
endpoint: process.env.PN_ACT_CONFIG_S3_ENDPOINT,
|
||||
key: process.env.PN_ACT_CONFIG_S3_ACCESS_KEY,
|
||||
secret: process.env.PN_ACT_CONFIG_S3_ACCESS_SECRET
|
||||
},
|
||||
hcaptcha: {
|
||||
secret: process.env.PN_ACT_CONFIG_HCAPTCHA_SECRET
|
||||
},
|
||||
cdn: {
|
||||
subdomain: process.env.PN_ACT_CONFIG_CDN_SUBDOMAIN,
|
||||
disk_path: process.env.PN_ACT_CONFIG_CDN_DISK_PATH,
|
||||
base_url: process.env.PN_ACT_CONFIG_CDN_BASE_URL
|
||||
},
|
||||
website_base: process.env.PN_ACT_CONFIG_WEBSITE_BASE
|
||||
};
|
||||
} else {
|
||||
logger.info('Loading config from config.json');
|
||||
|
||||
if (!fs.pathExistsSync(`${__dirname}/../config.json`)) {
|
||||
logger.error('Failed to locate config.json file');
|
||||
process.exit(0);
|
||||
export const config: Config = {
|
||||
http: {
|
||||
port: Number(process.env.PN_ACT_CONFIG_HTTP_PORT)
|
||||
},
|
||||
mongoose: {
|
||||
connection_string: process.env.PN_ACT_CONFIG_MONGO_CONNECTION_STRING,
|
||||
options: mongooseConnectOptions
|
||||
},
|
||||
redis: {
|
||||
client: {
|
||||
url: process.env.PN_ACT_CONFIG_REDIS_URL
|
||||
}
|
||||
},
|
||||
email: {
|
||||
host: process.env.PN_ACT_CONFIG_EMAIL_HOST,
|
||||
port: Number(process.env.PN_ACT_CONFIG_EMAIL_PORT),
|
||||
secure: Boolean(process.env.PN_ACT_CONFIG_EMAIL_SECURE),
|
||||
auth: {
|
||||
user: process.env.PN_ACT_CONFIG_EMAIL_USERNAME,
|
||||
pass: process.env.PN_ACT_CONFIG_EMAIL_PASSWORD
|
||||
},
|
||||
from: process.env.PN_ACT_CONFIG_EMAIL_FROM
|
||||
},
|
||||
s3: {
|
||||
endpoint: process.env.PN_ACT_CONFIG_S3_ENDPOINT,
|
||||
key: process.env.PN_ACT_CONFIG_S3_ACCESS_KEY,
|
||||
secret: process.env.PN_ACT_CONFIG_S3_ACCESS_SECRET
|
||||
},
|
||||
hcaptcha: {
|
||||
secret: process.env.PN_ACT_CONFIG_HCAPTCHA_SECRET
|
||||
},
|
||||
cdn: {
|
||||
subdomain: process.env.PN_ACT_CONFIG_CDN_SUBDOMAIN,
|
||||
disk_path: process.env.PN_ACT_CONFIG_CDN_DISK_PATH,
|
||||
base_url: process.env.PN_ACT_CONFIG_CDN_BASE_URL
|
||||
},
|
||||
website_base: process.env.PN_ACT_CONFIG_WEBSITE_BASE
|
||||
};
|
||||
|
||||
config = require(`${__dirname}/../config.json`);
|
||||
logger.info('Config loaded, checking integrity');
|
||||
|
||||
if (!config.http.port) {
|
||||
logger.error('Failed to find HTTP port. Set the PN_ACT_CONFIG_HTTP_PORT environment variable');
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
if (!config.mongoose.connection_string) {
|
||||
logger.error('Failed to find MongoDB connection string. Set the PN_ACT_CONFIG_MONGO_CONNECTION_STRING environment variable');
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
if (!config.cdn.base_url) {
|
||||
logger.error('Failed to find asset CDN base URL. Set the PN_ACT_CONFIG_CDN_BASE_URL environment variable');
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
if (!config.redis.client.url) {
|
||||
logger.warn('Failed to find Redis connection url. Disabling feature and using in-memory cache. To enable feature set the PN_ACT_CONFIG_REDIS_URL environment variable');
|
||||
disabledFeatures.redis = true;
|
||||
}
|
||||
|
||||
if (!config.email.host) {
|
||||
logger.warn('Failed to find email SMTP host. Disabling feature. To enable feature set the PN_ACT_CONFIG_EMAIL_HOST environment variable');
|
||||
disabledFeatures.email = true;
|
||||
}
|
||||
|
||||
if (!config.email.port) {
|
||||
logger.warn('Failed to find email SMTP port. Disabling feature. To enable feature set the PN_ACT_CONFIG_EMAIL_PORT environment variable');
|
||||
disabledFeatures.email = true;
|
||||
}
|
||||
|
||||
if (config.email.secure === undefined) {
|
||||
logger.warn('Failed to find email SMTP secure flag. Disabling feature. To enable feature set the PN_ACT_CONFIG_EMAIL_SECURE environment variable');
|
||||
disabledFeatures.email = true;
|
||||
}
|
||||
|
||||
if (!config.email.auth.user) {
|
||||
logger.warn('Failed to find email account username. Disabling feature. To enable feature set the auth.user environment variable');
|
||||
disabledFeatures.email = true;
|
||||
}
|
||||
|
||||
if (!config.email.auth.pass) {
|
||||
logger.warn('Failed to find email account password. Disabling feature. To enable feature set the PN_ACT_CONFIG_EMAIL_PASSWORD environment variable');
|
||||
disabledFeatures.email = true;
|
||||
}
|
||||
|
||||
if (!config.email.from) {
|
||||
logger.warn('Failed to find email from config. Disabling feature. To enable feature set the PN_ACT_CONFIG_EMAIL_FROM environment variable');
|
||||
disabledFeatures.email = true;
|
||||
}
|
||||
|
||||
if (!disabledFeatures.email) {
|
||||
if (!config.website_base) {
|
||||
logger.error('Email sending is enabled and no website base was configured. Set the PN_ACT_CONFIG_WEBSITE_BASE environment variable');
|
||||
process.exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
if (!config.hcaptcha.secret) {
|
||||
logger.warn('Failed to find captcha secret config. Disabling feature. To enable feature set the PN_ACT_CONFIG_HCAPTCHA_SECRET environment variable');
|
||||
disabledFeatures.captcha = true;
|
||||
}
|
||||
|
||||
if (!config.s3.endpoint) {
|
||||
logger.warn('Failed to find s3 endpoint config. Disabling feature. To enable feature set the PN_ACT_CONFIG_S3_ENDPOINT environment variable');
|
||||
disabledFeatures.s3 = true;
|
||||
}
|
||||
|
||||
if (!config.s3.key) {
|
||||
logger.warn('Failed to find s3 access key config. Disabling feature. To enable feature set the PN_ACT_CONFIG_S3_ACCESS_KEY environment variable');
|
||||
disabledFeatures.s3 = true;
|
||||
}
|
||||
|
||||
if (!config.s3.secret) {
|
||||
logger.warn('Failed to find s3 secret key config. Disabling feature. To enable feature set the PN_ACT_CONFIG_S3_ACCESS_SECRET environment variable');
|
||||
disabledFeatures.s3 = true;
|
||||
}
|
||||
|
||||
if (disabledFeatures.s3) {
|
||||
if (!config.cdn.subdomain) {
|
||||
logger.error('s3 file storage is disabled and no CDN subdomain was set. Set the PN_ACT_CONFIG_CDN_SUBDOMAIN environment variable');
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
logger.info('Config loaded, checking integrity');
|
||||
|
||||
// * Check for required settings
|
||||
for (const requiredField of requiredFields) {
|
||||
const [keyPath, envVarName, convertType] = requiredField;
|
||||
|
||||
const configValue = get(config, keyPath);
|
||||
const envValue = get(process.env, envVarName);
|
||||
|
||||
if (!configValue || (typeof configValue === 'string' && configValue.trim() === '')) {
|
||||
if (!envValue || envValue.trim() === '') {
|
||||
logger.error(`Failed to locate required field ${keyPath}. Set ${keyPath} in config.json or the ${envVarName} environment variable`);
|
||||
|
||||
process.exit(0);
|
||||
} else {
|
||||
logger.info(`${keyPath} not found in config, using environment variable ${envVarName}`);
|
||||
|
||||
const newValue = envValue;
|
||||
|
||||
set(config, keyPath, convertType ? (convertType as Function)(newValue) : newValue);
|
||||
}
|
||||
}
|
||||
if (!config.cdn.disk_path) {
|
||||
logger.error('s3 file storage is disabled and no CDN disk path was set. Set the PN_ACT_CONFIG_CDN_DISK_PATH environment variable');
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
// * Check for optional settings
|
||||
logger.warn(`s3 file storage disabled. Using disk-based file storage. Please ensure cdn.base_url config or PN_ACT_CONFIG_CDN_BASE env variable is set to point to this server with the subdomain being ${config.cdn.subdomain}`);
|
||||
|
||||
const redisCheck = get(config, 'redis.client.url');
|
||||
|
||||
if (!redisCheck || redisCheck.trim() === '') {
|
||||
if (usingEnv) {
|
||||
logger.warn('Failed to find Redis connection url. Disabling feature and using in-memory cache. To enable feature set the PN_ACT_CONFIG_REDIS_URL environment variable');
|
||||
|
||||
} else {
|
||||
logger.warn('Failed to find Redis connection url. Disabling feature and using in-memory cache. To enable feature set redis.client.url in your config.json');
|
||||
|
||||
}
|
||||
|
||||
disabledFeatures.redis = true;
|
||||
}
|
||||
|
||||
const emailHostCheck = get(config, 'email.host');
|
||||
|
||||
if (!emailHostCheck || emailHostCheck.trim() === '') {
|
||||
if (usingEnv) {
|
||||
logger.warn('Failed to find email SMTP host. Disabling feature. To enable feature set the PN_ACT_CONFIG_EMAIL_HOST environment variable');
|
||||
} else {
|
||||
logger.warn('Failed to find email SMTP host. Disabling feature. To enable feature set email.host in your config.json');
|
||||
}
|
||||
|
||||
|
||||
disabledFeatures.email = true;
|
||||
}
|
||||
|
||||
const emailPortCheck = get(config, 'email.port');
|
||||
|
||||
if (!emailPortCheck) {
|
||||
if (usingEnv) {
|
||||
logger.warn('Failed to find email SMTP port. Disabling feature. To enable feature set the PN_ACT_CONFIG_EMAIL_PORT environment variable');
|
||||
} else {
|
||||
logger.warn('Failed to find email SMTP port. Disabling feature. To enable feature set email.port in your config.json');
|
||||
}
|
||||
|
||||
disabledFeatures.email = true;
|
||||
}
|
||||
|
||||
const emailSecureCheck = get(config, 'email.secure');
|
||||
|
||||
if (emailSecureCheck === undefined) {
|
||||
if (usingEnv) {
|
||||
logger.warn('Failed to find email SMTP secure flag. Disabling feature. To enable feature set the PN_ACT_CONFIG_EMAIL_SECURE environment variable');
|
||||
} else {
|
||||
|
||||
logger.warn('Failed to find email SMTP secure flag. Disabling feature. To enable feature set email.secure in your config.json');
|
||||
}
|
||||
|
||||
disabledFeatures.email = true;
|
||||
}
|
||||
|
||||
const emailUsernameCheck = get(config, 'email.auth.user');
|
||||
|
||||
if (!emailUsernameCheck || emailUsernameCheck.trim() === '') {
|
||||
if (usingEnv) {
|
||||
logger.warn('Failed to find email account username. Disabling feature. To enable feature set the auth.user environment variable');
|
||||
} else {
|
||||
|
||||
logger.warn('Failed to find email account username. Disabling feature. To enable feature set email.auth.user in your config.json');
|
||||
}
|
||||
|
||||
disabledFeatures.email = true;
|
||||
}
|
||||
|
||||
const emailPasswordCheck = get(config, 'email.auth.pass');
|
||||
|
||||
if (!emailPasswordCheck || emailPasswordCheck.trim() === '') {
|
||||
if (usingEnv) {
|
||||
logger.warn('Failed to find email account password. Disabling feature. To enable feature set the PN_ACT_CONFIG_EMAIL_PASSWORD environment variable');
|
||||
} else {
|
||||
|
||||
logger.warn('Failed to find email account password. Disabling feature. To enable feature set email.auth.pass in your config.json');
|
||||
}
|
||||
|
||||
disabledFeatures.email = true;
|
||||
}
|
||||
|
||||
const emailFromCheck = get(config, 'email.from');
|
||||
|
||||
if (!emailFromCheck || emailFromCheck.trim() === '') {
|
||||
if (usingEnv) {
|
||||
logger.warn('Failed to find email from config. Disabling feature. To enable feature set the PN_ACT_CONFIG_EMAIL_FROM environment variable');
|
||||
} else {
|
||||
|
||||
logger.warn('Failed to find email from config. Disabling feature. To enable feature set email.from in your config.json');
|
||||
}
|
||||
|
||||
disabledFeatures.email = true;
|
||||
}
|
||||
|
||||
if (!disabledFeatures.email) {
|
||||
const websiteBaseCheck = get(config, 'website_base');
|
||||
|
||||
if (!websiteBaseCheck || websiteBaseCheck.trim() === '') {
|
||||
if (usingEnv) {
|
||||
logger.error('Email sending is enabled and no website base was configured. Set the PN_ACT_CONFIG_WEBSITE_BASE environment variable');
|
||||
} else {
|
||||
logger.error('Email sending is enabled and no website base was configured. Set website_base in your config.json');
|
||||
}
|
||||
|
||||
process.exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
const captchaSecretCheck = get(config, 'hcaptcha.secret');
|
||||
|
||||
if (!captchaSecretCheck || captchaSecretCheck.trim() === '') {
|
||||
if (usingEnv) {
|
||||
logger.warn('Failed to find captcha secret config. Disabling feature. To enable feature set the PN_ACT_CONFIG_HCAPTCHA_SECRET environment variable');
|
||||
} else {
|
||||
logger.warn('Failed to find captcha secret config. Disabling feature. To enable feature set hcaptcha.secret in your config.json');
|
||||
}
|
||||
|
||||
disabledFeatures.captcha = true;
|
||||
}
|
||||
|
||||
const s3EndpointCheck = get(config, 's3.endpoint');
|
||||
|
||||
if (!s3EndpointCheck || s3EndpointCheck.trim() === '') {
|
||||
if (usingEnv) {
|
||||
logger.warn('Failed to find s3 endpoint config. Disabling feature. To enable feature set the PN_ACT_CONFIG_S3_ENDPOINT environment variable');
|
||||
} else {
|
||||
logger.warn('Failed to find s3 endpoint config. Disabling feature. To enable feature set s3.endpoint in your config.json');
|
||||
}
|
||||
|
||||
disabledFeatures.s3 = true;
|
||||
} else {
|
||||
}
|
||||
|
||||
const s3AccessKeyCheck = get(config, 's3.key');
|
||||
|
||||
if (!s3AccessKeyCheck || s3AccessKeyCheck.trim() === '') {
|
||||
if (usingEnv) {
|
||||
logger.warn('Failed to find s3 access key config. Disabling feature. To enable feature set the PN_ACT_CONFIG_S3_ACCESS_KEY environment variable');
|
||||
} else {
|
||||
logger.warn('Failed to find s3 access key config. Disabling feature. To enable feature set s3.key in your config.json');
|
||||
}
|
||||
|
||||
disabledFeatures.s3 = true;
|
||||
}
|
||||
|
||||
const s3SecretKeyCheck = get(config, 's3.secret');
|
||||
|
||||
if (!s3SecretKeyCheck || s3SecretKeyCheck.trim() === '') {
|
||||
if (usingEnv) {
|
||||
logger.warn('Failed to find s3 secret key config. Disabling feature. To enable feature set the PN_ACT_CONFIG_S3_ACCESS_SECRET environment variable');
|
||||
} else {
|
||||
logger.warn('Failed to find s3 secret key config. Disabling feature. To enable feature set s3.secret in your config.json');
|
||||
}
|
||||
|
||||
disabledFeatures.s3 = true;
|
||||
}
|
||||
|
||||
if (disabledFeatures.s3) {
|
||||
const cdnSubdomainCheck = get(config, 'cdn.subdomain');
|
||||
|
||||
if (!cdnSubdomainCheck || cdnSubdomainCheck.trim() === '') {
|
||||
if (usingEnv) {
|
||||
logger.error('s3 file storage is disabled and no CDN subdomain was set. Set the PN_ACT_CONFIG_CDN_SUBDOMAIN environment variable');
|
||||
} else {
|
||||
logger.error('s3 file storage is disabled and no CDN subdomain was set. Set cdn.subdomain in your config.json');
|
||||
}
|
||||
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
if (disabledFeatures.redis) {
|
||||
logger.warn('Both s3 and Redis are disabled. Large CDN files will use the in-memory cache, which may result in high memory use. Please enable s3 if you\'re running a production server.');
|
||||
}
|
||||
|
||||
logger.warn(`s3 file storage disabled. Using disk-based file storage. Please ensure cdn.base_url config or PN_ACT_CONFIG_CDN_BASE env variable is set to point to this server with the subdomain being ${config.cdn.subdomain}`);
|
||||
if (disabledFeatures.redis) {
|
||||
logger.warn('Both s3 and Redis are disabled. Large CDN files will use the in-memory cache, which may result in high memory use. Please enable s3 if you\'re running a production server.');
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
configure,
|
||||
config,
|
||||
disabledFeatures
|
||||
};
|
||||
47
src/types/common/config.ts
Normal file
47
src/types/common/config.ts
Normal file
@@ -0,0 +1,47 @@
|
||||
import mongoose from 'mongoose';
|
||||
|
||||
export interface Config {
|
||||
http: {
|
||||
port: number;
|
||||
};
|
||||
mongoose: {
|
||||
connection_string: string;
|
||||
options: mongoose.ConnectOptions;
|
||||
};
|
||||
redis: {
|
||||
client: {
|
||||
url: string;
|
||||
}
|
||||
};
|
||||
email: {
|
||||
host: string;
|
||||
port: number;
|
||||
secure: boolean;
|
||||
auth: {
|
||||
user: string;
|
||||
pass: string;
|
||||
};
|
||||
from: string;
|
||||
};
|
||||
s3: {
|
||||
endpoint: string;
|
||||
key: string;
|
||||
secret: string;
|
||||
};
|
||||
hcaptcha: {
|
||||
secret: string;
|
||||
};
|
||||
cdn: {
|
||||
subdomain: string;
|
||||
disk_path: string;
|
||||
base_url: string;
|
||||
};
|
||||
website_base: string;
|
||||
};
|
||||
|
||||
export interface DisabledFeatures {
|
||||
redis: boolean;
|
||||
email: boolean;
|
||||
captcha: boolean;
|
||||
s3: boolean
|
||||
}
|
||||
Reference in New Issue
Block a user