mirror of
https://github.com/zoriya/flood.git
synced 2025-12-05 23:06:20 +00:00
185 lines
5.1 KiB
JavaScript
185 lines
5.1 KiB
JavaScript
const {spawn} = require('child_process');
|
|
const crypto = require('crypto');
|
|
const fs = require('fs');
|
|
const os = require('os');
|
|
const path = require('path');
|
|
const {argv} = require('yargs')
|
|
.env('FLOOD_OPTION_')
|
|
.option('baseuri', {
|
|
default: '/',
|
|
describe: "This URI will prefix all of Flood's HTTP requests",
|
|
type: 'string',
|
|
})
|
|
.option('rundir', {
|
|
alias: 'd',
|
|
default: path.join(os.homedir(), '.local/share/flood'),
|
|
describe: "Where to store Flood's runtime files (eg. database)",
|
|
type: 'string',
|
|
})
|
|
.option('host', {
|
|
alias: 'h',
|
|
default: '127.0.0.1',
|
|
describe: 'The host that Flood should listen for web connections on',
|
|
type: 'string',
|
|
})
|
|
.option('port', {
|
|
alias: 'p',
|
|
default: 3000,
|
|
describe: 'The port that Flood should listen for web connections on',
|
|
type: 'number',
|
|
})
|
|
.option('secret', {
|
|
alias: 's',
|
|
describe: 'A unique secret, a random one will be generated if not provided',
|
|
type: 'string',
|
|
})
|
|
.option('noauth', {
|
|
alias: 'n',
|
|
default: false,
|
|
describe: "Disable Flood's builtin access control system, needs rthost+rtport OR rtsocket.",
|
|
type: 'boolean',
|
|
})
|
|
.option('rthost', {
|
|
describe: "Depends on noauth: Host of rTorrent's SCGI interface",
|
|
type: 'string',
|
|
})
|
|
.option('rtport', {
|
|
describe: "Depends on noauth: Port of rTorrent's SCGI interface",
|
|
type: 'number',
|
|
})
|
|
.option('rtsocket', {
|
|
conflicts: ['rthost', 'rtport'],
|
|
describe: "Depends on noauth: Path to rTorrent's SCGI unix socket",
|
|
type: 'string',
|
|
})
|
|
.option('ssl', {
|
|
default: false,
|
|
describe: 'Enable SSL, key.pem and fullchain.pem needed in runtime directory',
|
|
type: 'boolean',
|
|
})
|
|
.option('sslkey', {
|
|
describe: 'Depends on ssl: Absolute path to private key for SSL',
|
|
implies: 'ssl',
|
|
hidden: true,
|
|
type: 'string',
|
|
})
|
|
.option('sslcert', {
|
|
describe: 'Depends on ssl: Absolute path to fullchain cert for SSL',
|
|
implies: 'ssl',
|
|
hidden: true,
|
|
type: 'string',
|
|
})
|
|
.option('allowedpath', {
|
|
describe: 'Allowed path for file operations, can be called multiple times',
|
|
type: 'string',
|
|
})
|
|
.option('dbclean', {
|
|
default: 1000 * 60 * 60,
|
|
describe: 'ADVANCED: Interval between database purge',
|
|
hidden: true,
|
|
type: 'number',
|
|
})
|
|
.option('maxhistorystates', {
|
|
default: 30,
|
|
describe: 'ADVANCED: Number of records of torrent download and upload speeds',
|
|
hidden: true,
|
|
type: 'number',
|
|
})
|
|
.option('clientpoll', {
|
|
default: 1000 * 2,
|
|
describe: 'ADVANCED: How often (in ms) Flood will request the torrent list',
|
|
hidden: true,
|
|
type: 'number',
|
|
})
|
|
.option('rtorrent', {
|
|
default: false,
|
|
describe: 'ADVANCED: rTorrent daemon managed by Flood',
|
|
hidden: true,
|
|
type: 'boolean',
|
|
})
|
|
.option('proxy', {
|
|
default: 'http://127.0.0.1:3000',
|
|
describe: 'DEV ONLY: See the "Local Development" section of README.md',
|
|
hidden: true,
|
|
type: 'string',
|
|
})
|
|
.version(require('./package.json').version)
|
|
.alias('v', 'version')
|
|
.help();
|
|
|
|
if (argv.rtorrent) {
|
|
const rTorrentProcess = spawn('rtorrent', ['-o', 'system.daemon.set=true']);
|
|
process.on('exit', () => {
|
|
console.log('Killing rTorrent daemon...');
|
|
rTorrentProcess.kill('SIGTERM');
|
|
});
|
|
}
|
|
|
|
process.on('SIGINT', () => {
|
|
process.exit();
|
|
});
|
|
|
|
try {
|
|
fs.mkdirSync(path.join(argv.rundir, 'db'), {recursive: true});
|
|
fs.mkdirSync(path.join(argv.rundir, 'temp'), {recursive: true});
|
|
} catch (error) {
|
|
console.error('Failed to access runtime directory');
|
|
process.exit(1);
|
|
}
|
|
|
|
const DEFAULT_SECRET_PATH = path.join(argv.rundir, 'flood.secret');
|
|
let secret;
|
|
|
|
if (!argv.secret) {
|
|
try {
|
|
if (fs.existsSync(DEFAULT_SECRET_PATH)) {
|
|
secret = fs.readFileSync(DEFAULT_SECRET_PATH, {encoding: 'utf8'});
|
|
} else {
|
|
const buf = Buffer.alloc(36);
|
|
crypto.randomFillSync(buf);
|
|
secret = buf.toString('hex');
|
|
fs.writeFileSync(DEFAULT_SECRET_PATH, secret, {mode: 0o600});
|
|
}
|
|
} catch (error) {
|
|
console.error('Failed to read or generate secret');
|
|
process.exit(1);
|
|
}
|
|
} else {
|
|
({secret} = argv);
|
|
}
|
|
|
|
const CONFIG = {
|
|
baseURI: argv.baseuri,
|
|
dbCleanInterval: argv.dbclean,
|
|
dbPath: path.resolve(path.join(argv.rundir, 'db')),
|
|
tempPath: path.resolve(path.join(argv.rundir, 'temp')),
|
|
disableUsersAndAuth: argv.noauth,
|
|
configUser:
|
|
argv.rtsocket != null
|
|
? {
|
|
client: 'rTorrent',
|
|
type: 'socket',
|
|
version: 1,
|
|
socket: argv.rtsocket || '/data/rtorrent.sock',
|
|
}
|
|
: {
|
|
client: 'rTorrent',
|
|
type: 'tcp',
|
|
version: 1,
|
|
host: argv.rthost || 'localhost',
|
|
port: argv.rtport || 5000,
|
|
},
|
|
floodServerHost: argv.host,
|
|
floodServerPort: argv.port,
|
|
floodServerProxy: argv.proxy,
|
|
maxHistoryStates: argv.maxhistorystates,
|
|
torrentClientPollInterval: argv.clientpoll,
|
|
secret,
|
|
ssl: argv.ssl,
|
|
sslKey: argv.sslkey || path.resolve(path.join(argv.rundir, 'key.pem')),
|
|
sslCert: argv.sslcert || path.resolve(path.join(argv.rundir, 'fullchain.pem')),
|
|
allowedPaths: argv.allowedpath ? [].concat(argv.allowedpath) : null,
|
|
};
|
|
|
|
module.exports = CONFIG;
|