mStream/modules/defaults.js
2019-11-02 19:52:43 -04:00

162 lines
4.8 KiB
JavaScript

const fs = require('fs');
const path = require('path');
const Joi = require('@hapi/joi');
exports.setup = function (config) {
config.filesDbName = 'files.loki-v1.db';
const storageJoi = Joi.object({
albumArtDirectory: Joi.string().default(path.join(__dirname, '../image-cache')),
dbDirectory: Joi.string().default(path.join(__dirname, '../save/db')),
logsDirectory: Joi.string().default(path.join(__dirname, '../save/logs')),
syncConfigDirectory: Joi.string().default(path.join(__dirname, '../save/sync')),
});
const scanOptions = Joi.object({
skipImg: Joi.boolean().default(false),
scanInterval: Joi.number().default(24),
saveInterval: Joi.number().default(250),
pause: Joi.number().default(0),
bootScanDelay: Joi.number().default(3)
});
const schema = Joi.object({
autoboot: Joi.boolean().optional(),
port: Joi.number().default(3000),
scanOptions: scanOptions.default(scanOptions.validate({}).value),
noUpload: Joi.boolean().optional(),
writeLogs: Joi.boolean().optional(),
storage: storageJoi.default(storageJoi.validate({}).value),
webAppDirectory: Joi.string().default(path.join(__dirname, '../public')),
ddns: Joi.object({
iniFile: Joi.string().default(path.join(__dirname, `../frp/frps.ini`)),
email: Joi.string().allow('').optional(),
password: Joi.string().allow('').optional(),
tested: Joi.boolean().optional(),
token: Joi.string().optional(),
url: Joi.string().optional(),
}),
transcode: Joi.object({
enabled: Joi.boolean().default(false),
ffmpegDirectory: Joi.string().default(path.join(__dirname, '../ffmpeg')),
defaultCodec: Joi.string().valid('mp3', 'opus', 'aac').default('opus'),
defaultBitrate: Joi.string().valid('64k', '128k', '192k', '96k').default('96k')
}).optional(),
secret: Joi.string().optional(),
folders: Joi.object().pattern(
Joi.string(),
Joi.object({
root: Joi.string().required()
})
).min(0),
users: Joi.object().pattern(
Joi.string(),
Joi.object({
password: Joi.string(),
guest: Joi.boolean().optional(),
salt: Joi.any(),
vpaths: Joi.array().items(Joi.string()),
'lastfm-user': Joi.string().allow('').optional(),
'lastfm-password': Joi.string().allow('').optional(),
})
).optional(),
ssl: Joi.object({
key: Joi.string().allow('').optional(),
cert: Joi.string().allow('').optional()
}).optional(),
federation: Joi.object({
folder: Joi.string().allow('').optional()
}).optional(),
'lastfm-user': Joi.string().allow('').optional(),
'lastfm-password': Joi.string().allow('').optional(),
filesDbName: Joi.string(),
configFile: Joi.string().optional()
});
const { error, value } = schema.validate(config);
if (error) {
throw new Error(error);
}
const program = value;
// Verify paths are real
for (let folder in program.folders) {
try {
if (!fs.statSync(program.folders[folder].root).isDirectory()) {
throw new Error('Path does not exist: ' + program.folders[folder].root);
}
} catch(err) {
throw new Error(err);
}
}
// Setup Secret for JWT
try {
// If user entered a filepath
if (fs.statSync(program.secret).isFile()) {
program.secret = fs.readFileSync(program.secret, 'utf8');
}
} catch (error) {
// If no secret was given, generate one
if (!program.secret) {
require('crypto').randomBytes(48, (err, buffer) => {
program.secret = buffer.toString('hex');
});
}
}
// This is a convenience function. It gets the vPath from any url string
program.getVPathInfo = function (url) {
// TODO: Verify user has access to this vpath
// remove leading slashes
if (url.charAt(0) === '/') {
url = url.substr(1);
}
const fileArray = url.split('/');
const vpath = fileArray.shift();
// Make sure the path exists
if (!program.folders[vpath]) {
return false;
}
const baseDir = program.folders[vpath].root;
let newPath = '';
for (const dir of fileArray) {
if (dir === '') {
continue;
}
newPath += dir + '/';
}
// TODO: There's gotta be a better way to construct the relative path
if (newPath.charAt(newPath.length - 1) === '/') {
newPath = newPath.slice(0, - 1);
}
return {
vpath: vpath,
basePath: baseDir,
relativePath: newPath,
fullPath: path.join(baseDir, newPath)
};
}
// Handle Exit Process
program.killThese = [];
process.on('exit', (code) => {
// Kill them all
program.killThese.forEach(func => {
if (typeof func === 'function') {
try {
func();
}catch (err) {
console.log('Error: Failed to run kill function');
}
}
});
});
return program;
}