mirror of
https://github.com/IrosTheBeggar/mStream.git
synced 2025-10-27 07:31:02 +00:00
473 lines
13 KiB
JavaScript
473 lines
13 KiB
JavaScript
const path = require('path');
|
|
const Joi = require('joi');
|
|
const fileExplorer = require('../util/file-explorer');
|
|
const admin = require('../util/admin');
|
|
const config = require('../state/config');
|
|
const dbQueue = require('../db/task-queue');
|
|
const winston = require('winston');
|
|
|
|
exports.setup = (mstream) => {
|
|
// The admin file explorer can view the entire system
|
|
mstream.post("/api/v1/admin/file-explorer", async (req, res) => {
|
|
try {
|
|
const schema = Joi.object({
|
|
directory: Joi.string().required(),
|
|
joinDirectory: Joi.string().optional()
|
|
});
|
|
await schema.validateAsync(req.body);
|
|
}catch (err) {
|
|
return res.status(500).json({ error: 'Validation Error' });
|
|
}
|
|
|
|
try {
|
|
// Handle home directory
|
|
let thisDirectory = req.body.directory;
|
|
if (req.body.directory === '~') {
|
|
thisDirectory = require('os').homedir();
|
|
}
|
|
|
|
if (req.body.joinDirectory) {
|
|
thisDirectory = path.join(thisDirectory, req.body.joinDirectory);
|
|
}
|
|
|
|
const folderContents = await fileExplorer.getDirectoryContents(thisDirectory, {}, true);
|
|
|
|
res.json({
|
|
path: thisDirectory,
|
|
directories: folderContents.directories,
|
|
files: folderContents.files
|
|
});
|
|
}catch (err) {
|
|
console.log(err);
|
|
return res.status(500).json({ error: 'Failed to get directory contents' });
|
|
}
|
|
});
|
|
|
|
mstream.get("/api/v1/admin/directories", async (req, res) => {
|
|
try {
|
|
res.json(config.program.folders);
|
|
} catch (err) {
|
|
console.log(err)
|
|
return res.status(500).json({ error: 'Failed to get vpaths' });
|
|
}
|
|
});
|
|
|
|
mstream.get("/api/v1/admin/db/params", async (req, res) => {
|
|
try {
|
|
res.json(config.program.scanOptions);
|
|
} catch (err) {
|
|
console.log(err)
|
|
return res.status(500).json({ error: 'Failed to get scan options' });
|
|
}
|
|
});
|
|
|
|
mstream.post("/api/v1/admin/db/params/scan-interval", async (req, res) => {
|
|
try {
|
|
const schema = Joi.object({
|
|
scanInterval: Joi.number().integer().min(0).required()
|
|
});
|
|
await schema.validateAsync(req.body);
|
|
}catch (err) {
|
|
return res.status(500).json({ error: 'Validation Error' });
|
|
}
|
|
|
|
try {
|
|
await admin.editScanInterval(req.body.scanInterval);
|
|
res.json({});
|
|
} catch (err) {
|
|
console.log(err);
|
|
return res.status(500).json({ error: 'Failed' });
|
|
}
|
|
});
|
|
|
|
mstream.post("/api/v1/admin/db/params/save-interval", async (req, res) => {
|
|
try {
|
|
const schema = Joi.object({
|
|
saveInterval: Joi.number().integer().min(0).required()
|
|
});
|
|
await schema.validateAsync(req.body);
|
|
}catch (err) {
|
|
return res.status(500).json({ error: 'Validation Error' });
|
|
}
|
|
|
|
try {
|
|
await admin.editSaveInterval(req.body.saveInterval);
|
|
res.json({});
|
|
} catch (err) {
|
|
console.log(err);
|
|
return res.status(500).json({ error: 'Failed' });
|
|
}
|
|
});
|
|
|
|
mstream.post("/api/v1/admin/db/params/skip-img", async (req, res) => {
|
|
try {
|
|
const schema = Joi.object({
|
|
skipImg: Joi.boolean().required()
|
|
});
|
|
await schema.validateAsync(req.body);
|
|
}catch (err) {
|
|
return res.status(500).json({ error: 'Validation Error' });
|
|
}
|
|
|
|
try {
|
|
await admin.editSkipImg(req.body.skipImg);
|
|
res.json({});
|
|
} catch (err) {
|
|
console.log(err);
|
|
return res.status(500).json({ error: 'Failed' });
|
|
}
|
|
});
|
|
|
|
mstream.post("/api/v1/admin/db/params/pause", async (req, res) => {
|
|
try {
|
|
const schema = Joi.object({
|
|
pause: Joi.number().integer().min(0).required()
|
|
});
|
|
await schema.validateAsync(req.body);
|
|
}catch (err) {
|
|
return res.status(500).json({ error: 'Validation Error' });
|
|
}
|
|
|
|
try {
|
|
await admin.editPause(req.body.pause);
|
|
res.json({});
|
|
} catch (err) {
|
|
console.log(err);
|
|
return res.status(500).json({ error: 'Failed' });
|
|
}
|
|
});
|
|
|
|
mstream.post("/api/v1/admin/db/params/boot-scan-delay", async (req, res) => {
|
|
try {
|
|
const schema = Joi.object({
|
|
bootScanDelay: Joi.number().integer().min(0).required()
|
|
});
|
|
await schema.validateAsync(req.body);
|
|
}catch (err) {
|
|
return res.status(500).json({ error: 'Validation Error' });
|
|
}
|
|
|
|
try {
|
|
await admin.editBootScanDelay(req.body.bootScanDelay);
|
|
res.json({});
|
|
} catch (err) {
|
|
console.log(err);
|
|
return res.status(500).json({ error: 'Failed' });
|
|
}
|
|
});
|
|
|
|
mstream.post("/api/v1/admin/db/params/max-concurrent-scans", async (req, res) => {
|
|
try {
|
|
const schema = Joi.object({
|
|
maxConcurrentTasks: Joi.number().integer().min(0).required()
|
|
});
|
|
await schema.validateAsync(req.body);
|
|
}catch (err) {
|
|
return res.status(500).json({ error: 'Validation Error' });
|
|
}
|
|
|
|
try {
|
|
await admin.editMaxConcurrentTasks(req.body.maxConcurrentTasks);
|
|
res.json({});
|
|
} catch (err) {
|
|
console.log(err);
|
|
return res.status(500).json({ error: 'Failed' });
|
|
}
|
|
});
|
|
|
|
mstream.get("/api/v1/admin/users", async (req, res) => {
|
|
try {
|
|
// Scrub passwords
|
|
const memClone = JSON.parse(JSON.stringify(config.program.users));
|
|
Object.keys(memClone).forEach(key => {
|
|
if(key === 'password' || key === 'salt') {
|
|
delete memClone[key];
|
|
}
|
|
});
|
|
|
|
res.json(memClone);
|
|
} catch (err) {
|
|
console.log(err)
|
|
return res.status(500).json({ error: 'Failed to get vpaths' });
|
|
}
|
|
});
|
|
|
|
mstream.put("/api/v1/admin/directory", async (req, res) => {
|
|
try {
|
|
const schema = Joi.object({
|
|
directory: Joi.string().required(),
|
|
vpath: Joi.string().pattern(/[a-zA-Z0-9-]+/).required(),
|
|
autoAccess: Joi.boolean().default(false)
|
|
});
|
|
var input = await schema.validateAsync(req.body);
|
|
}catch (err) {
|
|
console.log(err)
|
|
return res.status(500).json({ error: 'Validation Error' });
|
|
}
|
|
|
|
try {
|
|
await admin.addDirectory(input.directory, input.vpath, input.autoAccess, mstream);
|
|
res.json({});
|
|
} catch (err) {
|
|
console.log(err)
|
|
return res.status(500).json({ error: 'Failed to set new directory' });
|
|
}
|
|
|
|
try {
|
|
dbQueue.scanVPath(input.vpath);
|
|
}catch (err) {
|
|
winston.error('/api/v1/admin/directory failed to add ', { stack: err });
|
|
}
|
|
});
|
|
|
|
mstream.delete("/api/v1/admin/directory", async (req, res) => {
|
|
try {
|
|
const schema = Joi.object({
|
|
vpath: Joi.string().pattern(/[a-zA-Z0-9-]+/).required()
|
|
});
|
|
await schema.validateAsync(req.body);
|
|
}catch (err) {
|
|
console.log(err)
|
|
return res.status(500).json({ error: 'Validation Error' });
|
|
}
|
|
|
|
try {
|
|
await admin.removeDirectory(req.body.vpath);
|
|
res.json({});
|
|
} catch (err) {
|
|
console.log(err)
|
|
return res.status(500).json({ error: 'Failed to set new directory' });
|
|
}
|
|
});
|
|
|
|
mstream.put("/api/v1/admin/users", async (req, res) => {
|
|
try {
|
|
const schema = Joi.object({
|
|
username: Joi.string().required(),
|
|
password: Joi.string().required(),
|
|
vpaths: Joi.array().items(Joi.string()).required(),
|
|
admin: Joi.boolean().optional().default(false),
|
|
guest: Joi.boolean().optional().default(false)
|
|
});
|
|
var input = await schema.validateAsync(req.body);
|
|
}catch (err) {
|
|
console.log(err)
|
|
return res.status(500).json({ error: 'Validation Error' });
|
|
}
|
|
|
|
try {
|
|
await admin.addUser(
|
|
input.username,
|
|
input.password,
|
|
input.admin,
|
|
input.guest,
|
|
input.vpaths
|
|
);
|
|
res.json({});
|
|
} catch (err) {
|
|
console.log(err)
|
|
return res.status(500).json({ error: 'Failed to set new directory' });
|
|
}
|
|
});
|
|
|
|
mstream.post("/api/v1/admin/db/scan/all", async (req, res) => {
|
|
try {
|
|
dbQueue.scanAll();
|
|
res.json({});
|
|
} catch(err) {
|
|
res.status(500).json({});
|
|
}
|
|
});
|
|
|
|
mstream.delete("/api/v1/admin/users", async (req, res) => {
|
|
try {
|
|
const schema = Joi.object({
|
|
username: Joi.string().required()
|
|
});
|
|
await schema.validateAsync(req.body);
|
|
}catch (err) {
|
|
return res.status(500).json({ error: 'Validation Error' });
|
|
}
|
|
|
|
try {
|
|
await admin.deleteUser(req.body.username);
|
|
res.json({});
|
|
} catch (err) {
|
|
console.log(err)
|
|
return res.status(500).json({ error: 'Failed to delete user' });
|
|
}
|
|
});
|
|
|
|
mstream.post("/api/v1/admin/users/password", async (req, res) => {
|
|
try {
|
|
const schema = Joi.object({
|
|
username: Joi.string().required(),
|
|
password: Joi.string().required()
|
|
});
|
|
await schema.validateAsync(req.body);
|
|
}catch (err) {
|
|
return res.status(500).json({ error: 'Validation Error' });
|
|
}
|
|
|
|
try {
|
|
await admin.editUserPassword(req.body.username, req.body.password);
|
|
res.json({});
|
|
} catch (err) {
|
|
console.log(err);
|
|
return res.status(500).json({ error: 'Failed to update password' });
|
|
}
|
|
});
|
|
|
|
mstream.post("/api/v1/admin/users/vpaths", async (req, res) => {
|
|
try {
|
|
const schema = Joi.object({
|
|
username: Joi.string().required(),
|
|
vpaths: Joi.array().items(Joi.string()).required()
|
|
});
|
|
await schema.validateAsync(req.body);
|
|
}catch (err) {
|
|
return res.status(500).json({ error: 'Validation Error' });
|
|
}
|
|
|
|
try {
|
|
await admin.editUserVPaths(req.body.username, req.body.vpaths);
|
|
res.json({});
|
|
} catch (err) {
|
|
console.log(err);
|
|
return res.status(500).json({ error: 'Failed to update user' });
|
|
}
|
|
});
|
|
|
|
mstream.post("/api/v1/admin/users/access", async (req, res) => {
|
|
try {
|
|
const schema = Joi.object({
|
|
username: Joi.string().required(),
|
|
admin: Joi.boolean().required(),
|
|
guest: Joi.boolean().required()
|
|
});
|
|
await schema.validateAsync(req.body);
|
|
}catch (err) {
|
|
return res.status(500).json({ error: 'Validation Error' });
|
|
}
|
|
|
|
try {
|
|
await admin.editUserAccess(req.body.username, req.body.admin, req.body.guest);
|
|
res.json({});
|
|
} catch (err) {
|
|
console.log(err);
|
|
return res.status(500).json({ error: 'Failed to update user' });
|
|
}
|
|
});
|
|
|
|
mstream.get("/api/v1/admin/config", async (req, res) => {
|
|
try {
|
|
res.json({
|
|
address: config.program.address,
|
|
port: config.program.port,
|
|
noUpload: config.program.noUpload,
|
|
writeLogs: config.program.writeLogs,
|
|
secret: config.program.secret.slice(-4),
|
|
ssl: config.program.ssl
|
|
});
|
|
} catch (err) {
|
|
console.log(err);
|
|
return res.status(500).json({ error: 'Failed' });
|
|
}
|
|
});
|
|
|
|
mstream.post("/api/v1/admin/config/port", async (req, res) => {
|
|
try {
|
|
const schema = Joi.object({
|
|
port: Joi.number().required()
|
|
});
|
|
await schema.validateAsync(req.body);
|
|
}catch (err) {
|
|
return res.status(500).json({ error: 'Validation Error' });
|
|
}
|
|
|
|
try {
|
|
await admin.editPort(req.body.port);
|
|
res.json({});
|
|
} catch (err) {
|
|
console.log(err);
|
|
return res.status(500).json({ error: 'Failed' });
|
|
}
|
|
});
|
|
|
|
mstream.post("/api/v1/admin/config/address", async (req, res) => {
|
|
try {
|
|
const schema = Joi.object({
|
|
address: Joi.string().ip({ cidr: 'forbidden' }).required(),
|
|
});
|
|
await schema.validateAsync(req.body);
|
|
}catch (err) {
|
|
return res.status(500).json({ error: 'Validation Error' });
|
|
}
|
|
|
|
try {
|
|
await admin.editAddress(req.body.address);
|
|
res.json({});
|
|
} catch (err) {
|
|
console.log(err);
|
|
return res.status(500).json({ error: 'Failed' });
|
|
}
|
|
});
|
|
|
|
mstream.post("/api/v1/admin/config/noupload", async (req, res) => {
|
|
try {
|
|
const schema = Joi.object({
|
|
noUpload: Joi.boolean().required()
|
|
});
|
|
await schema.validateAsync(req.body);
|
|
}catch (err) {
|
|
return res.status(500).json({ error: 'Validation Error' });
|
|
}
|
|
|
|
try {
|
|
await admin.editUpload(req.body.noUpload);
|
|
res.json({});
|
|
} catch (err) {
|
|
console.log(err);
|
|
return res.status(500).json({ error: 'Failed' });
|
|
}
|
|
});
|
|
|
|
mstream.post("/api/v1/admin/config/write-logs", async (req, res) => {
|
|
try {
|
|
const schema = Joi.object({
|
|
writeLogs: Joi.boolean().required()
|
|
});
|
|
await schema.validateAsync(req.body);
|
|
}catch (err) {
|
|
return res.status(500).json({ error: 'Validation Error' });
|
|
}
|
|
|
|
try {
|
|
await admin.editWriteLogs(req.body.writeLogs);
|
|
res.json({});
|
|
} catch (err) {
|
|
console.log(err);
|
|
return res.status(500).json({ error: 'Failed' });
|
|
}
|
|
});
|
|
|
|
mstream.post("/api/v1/admin/config/secret", async (req, res) => {
|
|
try {
|
|
const schema = Joi.object({
|
|
strength: Joi.number().integer().positive().required()
|
|
});
|
|
await schema.validateAsync(req.body);
|
|
}catch (err) {
|
|
return res.status(500).json({ error: 'Validation Error' });
|
|
}
|
|
|
|
try {
|
|
const secret = await config.asyncRandom(req.body.strength);
|
|
await admin.editSecret(secret);
|
|
res.json({});
|
|
} catch (err) {
|
|
console.log(err);
|
|
return res.status(500).json({ error: 'Failed' });
|
|
}
|
|
});
|
|
} |