fix(config): new opts: admin_limit, user_limit, disabled_extensions (#68)

This commit is contained in:
diced 2021-08-28 21:02:04 -07:00
parent 4728f1cc46
commit e71590b9fb
No known key found for this signature in database
GPG key ID: 85AB64C74535D76E
6 changed files with 42 additions and 16 deletions

View file

@ -9,4 +9,7 @@ database_url = 'postgres://postgres:postgres@postgres/postgres'
route = '/u' route = '/u'
embed_route = '/a' embed_route = '/a'
length = 6 length = 6
directory = './uploads' directory = './uploads'
user_limit = 104900000 # 100mb
admin_limit = 104900000 # 100mb
disabled_extentions = ['jpg']

View file

@ -16,7 +16,10 @@ module.exports = async config => {
path('uploader.route', 'string'), path('uploader.route', 'string'),
path('uploader.embed_route', 'string'), path('uploader.embed_route', 'string'),
path('uploader.length', 'number'), path('uploader.length', 'number'),
path('uploader.directory', 'string') path('uploader.directory', 'string'),
path('uploader.admin_limit', 'number'),
path('uploader.user_limit', 'number'),
path('uploader.disabled_extentions', 'object'),
]; ];
let errors = 0; let errors = 0;
@ -25,11 +28,11 @@ module.exports = async config => {
const path = paths[i]; const path = paths[i];
const value = dot(path.path, config); const value = dot(path.path, config);
if (value === undefined) { if (value === undefined) {
Logger.get('config').error(`there was no ${path.path} in config`); Logger.get('config').error(`there was no ${path.path} in config which was required`);
++errors; ++errors;
} }
const type = typeof value;
const type = typeof value;
if (value !== undefined && type !== path.type) { if (value !== undefined && type !== path.type) {
Logger.get('config').error(`expected ${path.type} on ${path.path}, but got ${type}`); Logger.get('config').error(`expected ${path.type} on ${path.path}, but got ${type}`);
++errors; ++errors;

View file

@ -2,7 +2,7 @@ const { existsSync, readFileSync } = require('fs');
const { join } = require('path'); const { join } = require('path');
const Logger = require('./logger'); const Logger = require('./logger');
const e = (val, type, fn) => ({ val, type, fn }); const e = (val, type, fn, required = true) => ({ val, type, fn, required });
const envValues = [ const envValues = [
e('SECURE', 'boolean', (c, v) => c.core.secure = v), e('SECURE', 'boolean', (c, v) => c.core.secure = v),
@ -13,7 +13,10 @@ const envValues = [
e('UPLOADER_ROUTE', 'string', (c, v) => c.uploader.route = v), e('UPLOADER_ROUTE', 'string', (c, v) => c.uploader.route = v),
e('UPLOADER_EMBED_ROUTE', 'string', (c, v) => c.uploader.embed_route = v), e('UPLOADER_EMBED_ROUTE', 'string', (c, v) => c.uploader.embed_route = v),
e('UPLOADER_LENGTH', 'number', (c, v) => c.uploader.length = v), e('UPLOADER_LENGTH', 'number', (c, v) => c.uploader.length = v),
e('UPLOADER_DIRECTORY', 'string', (c, v) => c.uploader.directory = v) e('UPLOADER_DIRECTORY', 'string', (c, v) => c.uploader.directory = v),
e('UPLOADER_ADMIN_LIMIT', 'number', (c, v) => c.uploader.admin_limit = v),
e('UPLOADER_USER_LIMIT', 'number', (c, v) => c.uploader.user_limit = v),
e('UPLOADER_DISABLED_EXTS', 'array', (c, v) => c.uploader.disabled_extentions = v),
]; ];
module.exports = () => { module.exports = () => {
@ -35,17 +38,17 @@ function tryReadEnv() {
secure: undefined, secure: undefined,
secret: undefined, secret: undefined,
host: undefined, host: undefined,
port: undefined port: undefined,
}, database_url: undefined,
database: {
type: undefined,
url: undefined
}, },
uploader: { uploader: {
route: undefined, route: undefined,
embed_route: undefined, embed_route: undefined,
length: undefined, length: undefined,
directory: undefined directory: undefined,
admin_limit: undefined,
user_limit: undefined,
disabled_extentions: undefined
} }
}; };
@ -53,7 +56,7 @@ function tryReadEnv() {
const envValue = envValues[i]; const envValue = envValues[i];
let value = process.env[envValue.val]; let value = process.env[envValue.val];
if (!value) { if (envValue.required && !value) {
Logger.get('config').error('there is no config file or required environment variables... exiting...'); Logger.get('config').error('there is no config file or required environment variables... exiting...');
process.exit(1); process.exit(1);
@ -62,6 +65,7 @@ function tryReadEnv() {
envValues[i].fn(config, value); envValues[i].fn(config, value);
if (envValue.type === 'number') value = parseToNumber(value); if (envValue.type === 'number') value = parseToNumber(value);
else if (envValue.type === 'boolean') value = parseToBoolean(value); else if (envValue.type === 'boolean') value = parseToBoolean(value);
else if (envValue.type === 'array') value = parseToArray(value);
envValues[i].fn(config, value); envValues[i].fn(config, value);
} }
@ -79,4 +83,8 @@ function parseToBoolean(value) {
// infer that it is a string since env values are only strings // infer that it is a string since env values are only strings
if (!value || value === 'false') return false; if (!value || value === 'false') return false;
else return true; else return true;
}
function parseToArray(value) {
return value.split(',');
} }

View file

@ -27,6 +27,15 @@ export interface ConfigUploader {
// Where uploads are stored // Where uploads are stored
directory: string; directory: string;
// Admin file upload limit
admin_limit: number;
// User file upload limit
user_limit: number;
// Disabled extensions to block from uploading
disabled_extentions: string[];
} }
export interface Config { export interface Config {

View file

@ -22,11 +22,12 @@ async function handler(req: NextApiReq, res: NextApiRes) {
}); });
if (!user) return res.forbid('authorization incorect'); if (!user) return res.forbid('authorization incorect');
if (!req.file) return res.error('no file'); if (!req.file) return res.error('no file');
if (req.file.size > zconfig.uploader[user.administrator ? 'admin_limit' : 'user_limit']) return res.error('file size too big');
const ext = req.file.originalname.split('.').pop(); const ext = req.file.originalname.split('.').pop();
if (zconfig.uploader.disabled_extentions.includes(ext)) return res.error('disabled extension recieved: ' + ext);
const rand = randomChars(zconfig.uploader.length); const rand = randomChars(zconfig.uploader.length);
const image = await prisma.image.create({ const image = await prisma.image.create({
data: { data: {
file: `${rand}.${ext}`, file: `${rand}.${ext}`,

View file

@ -35,7 +35,9 @@ async function handler(req: NextApiReq, res: NextApiRes) {
administrator: true, administrator: true,
token: true, token: true,
embedColor: true, embedColor: true,
embedTitle: true embedTitle: true,
customTheme: true,
systemTheme: true
} }
}); });
return res.json(all_users); return res.json(all_users);