mirror of
https://github.com/IrosTheBeggar/mStream.git
synced 2025-10-27 07:31:02 +00:00
Breaking out everything into modules
This commit is contained in:
parent
dbb1fc3d01
commit
d47c465ed8
46
modules/download.js
Normal file
46
modules/download.js
Normal file
@ -0,0 +1,46 @@
|
||||
exports.setup = function(mstream, program){
|
||||
const archiver = require('archiver'); // Zip Compression
|
||||
const fe = require('path');
|
||||
|
||||
|
||||
// Download a zip file of music
|
||||
mstream.post('/download', function (req, res){
|
||||
var archive = archiver('zip');
|
||||
|
||||
archive.on('error', function(err) {
|
||||
console.log(err.message);
|
||||
res.status(500).send('{error: '+err.message+'}');
|
||||
});
|
||||
|
||||
archive.on('end', function() {
|
||||
// TODO: add logging
|
||||
});
|
||||
|
||||
//set the archive name
|
||||
// TODO: Rename this
|
||||
res.attachment('zipped-playlist.zip');
|
||||
|
||||
//streaming magic
|
||||
archive.pipe(res);
|
||||
|
||||
var fileArray;
|
||||
|
||||
|
||||
// Get the POSTed files
|
||||
if(req.allowedFiles){
|
||||
fileArray = allowedFiles;
|
||||
}else{
|
||||
fileArray = JSON.parse(req.body.fileArray);
|
||||
}
|
||||
|
||||
for(var i in fileArray) {
|
||||
// TODO: Confirm each item in posted data is a real file
|
||||
var fileString = fileArray[i];
|
||||
|
||||
// TODO: Add file by ataching user's musicdir to the relative directory supplied
|
||||
archive.file(fe.normalize( fileString), { name: fe.basename(fileString) });
|
||||
}
|
||||
|
||||
archive.finalize();
|
||||
});
|
||||
}
|
||||
81
modules/file-explorer.js
Normal file
81
modules/file-explorer.js
Normal file
@ -0,0 +1,81 @@
|
||||
exports.setup = function(mstream, program){
|
||||
|
||||
const fs = require('fs'); // File System
|
||||
const fe = require('path');
|
||||
const slash = require('slash');
|
||||
|
||||
|
||||
|
||||
// parse directories
|
||||
mstream.post('/dirparser', function (req, res) {
|
||||
var directories = [];
|
||||
var filesArray = [];
|
||||
|
||||
// TODO: Make sure path is a sub-path of the user's music dir
|
||||
var path = fe.join(req.user.musicDir, req.body.dir);
|
||||
// Make sure it's a directory
|
||||
if(!fs.statSync( path).isDirectory()){
|
||||
res.status(500).json({ error: 'Not a directory' });
|
||||
return;
|
||||
}
|
||||
|
||||
// Will only show these files. Prevents people from snooping around
|
||||
// TODO: Move to global variable
|
||||
const masterFileTypesArray = ["mp3", "flac", "wav", "ogg", "aac", "m4a"];
|
||||
var fileTypesArray;
|
||||
if(req.body.filetypes){
|
||||
fileTypesArray = JSON.parse(req.body.filetypes);
|
||||
}else{
|
||||
fileTypesArray = masterFileTypesArray;
|
||||
}
|
||||
|
||||
|
||||
// get directory contents
|
||||
var files = fs.readdirSync( path);
|
||||
|
||||
// loop through files
|
||||
for (let i=0; i < files.length; i++) {
|
||||
|
||||
try{
|
||||
var stat = fs.statSync(fe.join(path, files[i]));
|
||||
}catch(error){
|
||||
// Bad file, ignore and continue
|
||||
// TODO: Log This
|
||||
continue;
|
||||
}
|
||||
|
||||
// Handle Directories
|
||||
if(stat.isDirectory()){
|
||||
directories.push({
|
||||
type:"directory",
|
||||
name:files[i]
|
||||
});
|
||||
}else{ // Handle Files
|
||||
var extension = getFileType(files[i]);
|
||||
if (fileTypesArray.indexOf(extension) > -1 && masterFileTypesArray.indexOf(extension) > -1) {
|
||||
filesArray.push({
|
||||
type:extension, // TODO: Should this be changed
|
||||
name:files[i]
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var returnPath = slash( fe.relative(req.user.musicDir, path) );
|
||||
if(returnPath.slice(-1) !== '/'){
|
||||
returnPath += '/';
|
||||
}
|
||||
|
||||
// Send back combined list of directories and mp3s
|
||||
res.send(
|
||||
JSON.stringify({ path:returnPath, contents:filesArray.concat(directories)})
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
|
||||
function getFileType(filename){
|
||||
return filename.split(".").pop();
|
||||
}
|
||||
|
||||
}
|
||||
206
modules/login.js
Normal file
206
modules/login.js
Normal file
@ -0,0 +1,206 @@
|
||||
exports.setup = function(mstream, program, express){
|
||||
// Use bcrypt for password storage
|
||||
const bcrypt = require('bcrypt');
|
||||
const jwt = require('jsonwebtoken'); // used to create, sign, and verify tokens
|
||||
const uuidV4 = require('uuid/v4');
|
||||
|
||||
|
||||
|
||||
|
||||
// TODO: Add New user functionality
|
||||
// Check for root user and password
|
||||
// Add credentials to user array
|
||||
|
||||
// TODO: Need a way to store and use already hashed passwords
|
||||
|
||||
|
||||
// TODO: password change function
|
||||
mstream.post('/change-password-request', function (req, res) {
|
||||
// Get email address from request
|
||||
// validate email against user array
|
||||
// Generate change password token
|
||||
// Invalidate all other change password tokens
|
||||
// Email the user the token
|
||||
|
||||
res.sendFile( 'COMING SOON!' );
|
||||
});
|
||||
|
||||
mstream.post('/change-password', function (req, res){
|
||||
// Check token
|
||||
// Get new password
|
||||
// Hash password and update user array
|
||||
|
||||
res.sendFile( 'COMING SOON!' );
|
||||
});
|
||||
|
||||
mstream.post('/sunset-user', function(req,res){
|
||||
// Removes all user info
|
||||
});
|
||||
|
||||
mstream.post('/add-user', function(req,res){
|
||||
// Add a user
|
||||
});
|
||||
|
||||
|
||||
// Create the user array
|
||||
var Users = program.users;
|
||||
var permissionsMap = {};
|
||||
|
||||
for (let username in Users) {
|
||||
// Setup user password
|
||||
generateSaltedPassword(username, Users[username]["password"]);
|
||||
|
||||
// If this is a guest user, continue
|
||||
if(Users[username].guestTo){
|
||||
continue;
|
||||
}
|
||||
|
||||
// If dir has not been added yet
|
||||
if ( !(Users[username].musicDir in permissionsMap) ){
|
||||
// Generate unique vPath if necessary
|
||||
// The best way is to store the vPath in the JSON file
|
||||
if(!Users[username].vPath){
|
||||
Users[username].vPath = uuidV4();
|
||||
}
|
||||
|
||||
// Add to permissionsMap
|
||||
permissionsMap[Users[username].musicDir] = Users[username].vPath;
|
||||
}else{
|
||||
Users[username].vPath = permissionsMap[Users[username].musicDir];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
function generateSaltedPassword(username, password){
|
||||
bcrypt.genSalt(10, function(err, salt) {
|
||||
bcrypt.hash(password, salt, function(err, hash) {
|
||||
// Store hash in your password DB.
|
||||
Users[username]['password'] = hash;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Failed Login Attempt
|
||||
mstream.get('/login-failed', function (req, res) {
|
||||
// Wait before sending the response
|
||||
setTimeout((function() {
|
||||
res.status(599).send(JSON.stringify({'Error':'Try Again'}))
|
||||
}), 800);
|
||||
});
|
||||
|
||||
mstream.get('/access-denied', function (req, res) {
|
||||
res.status(598).send(JSON.stringify({'Error':'Access Denied'}));
|
||||
});
|
||||
|
||||
mstream.get('/guest-access-denied', function (req, res) {
|
||||
res.status(597).send(JSON.stringify({'Error':'Access Denied'}));
|
||||
});
|
||||
|
||||
// route to authenticate a user (POST http://localhost:8080/api/authenticate)
|
||||
mstream.post('/login', function(req, res) {
|
||||
let username = req.body.username;
|
||||
let password = req.body.password;
|
||||
|
||||
// Check is user is in array
|
||||
if(typeof Users[username] === 'undefined') {
|
||||
// user does not exist
|
||||
return res.redirect('/login-failed');
|
||||
}
|
||||
|
||||
// Check is password is correct
|
||||
bcrypt.compare(password, Users[username]['password'], function(err, match) {
|
||||
if(match == false){
|
||||
// Password does not match
|
||||
return res.redirect('/login-failed');
|
||||
}
|
||||
|
||||
|
||||
var sendData = {
|
||||
username: username,
|
||||
}
|
||||
|
||||
var vPath;
|
||||
if(Users[username].guestTo){
|
||||
vPath = Users[Users[username].guestTo].vPath;
|
||||
}else{
|
||||
vPath = Users[username].vPath;
|
||||
}
|
||||
|
||||
// return the information including token as JSON
|
||||
var sendThis = {
|
||||
success: true,
|
||||
message: 'Welcome To mStream',
|
||||
vPath: vPath,
|
||||
token: jwt.sign(sendData, program.secret) // Make the token
|
||||
};
|
||||
|
||||
res.send(JSON.stringify(sendThis));
|
||||
});
|
||||
});
|
||||
|
||||
// Guest Users are not allowed to access these functions
|
||||
const forbiddenFunctions = ['/db/recursive-scan', '/saveplaylist', '/deleteplaylist'];
|
||||
|
||||
// Middleware that checks for token
|
||||
mstream.use(function(req, res, next) {
|
||||
// check header or url parameters or post parameters for token
|
||||
var token = req.body.token || req.query.token || req.headers['x-access-token'];
|
||||
if (!token) {
|
||||
return res.redirect('/access-denied');
|
||||
}
|
||||
|
||||
// verifies secret and checks exp
|
||||
jwt.verify(token, program.secret, function(err, decoded) {
|
||||
if (err) {
|
||||
return res.redirect('/access-denied');
|
||||
}
|
||||
|
||||
// Check if share token
|
||||
if(decoded.shareToken && decoded.shareToken === true){
|
||||
// We limit the endpoints to download and anythign in the allowedFiles array
|
||||
// TODO: There's gottab be a better way to habdle vpaths
|
||||
// TODO: Add vpath to allowedFiles when it's created ???
|
||||
// console.log(decodeURIComponent(req.path.substring(38)));
|
||||
if(req.path !== '/download' && decoded.allowedFiles.indexOf(decodeURIComponent(req.path.substring(38))) === -1){ // The substring is to cut out the vPath
|
||||
return res.redirect('/guest-access-denied');
|
||||
}
|
||||
req.allowedFiles = decoded.allowedFiles;
|
||||
next();
|
||||
return;
|
||||
}
|
||||
// User may access those files and no others
|
||||
|
||||
// Check for any hardcoded restrictions baked right into token
|
||||
if(decoded.restrictedFunctions && decoded.restrictedFunctions.indexOf(req.path) != -1){
|
||||
return res.redirect('/guest-access-denied');
|
||||
}
|
||||
|
||||
// TODO: Verify that users in token exist and vPath matches
|
||||
// TODO: Longterm goal - use vPath from request variable instead of having the user manually add it
|
||||
req.user = Users[decoded.username];
|
||||
req.user.username = decoded.username;
|
||||
|
||||
// Deny guest access
|
||||
if(req.user.guestTo && forbiddenFunctions.indexOf(req.path) != -1){
|
||||
return res.redirect('/guest-access-denied');
|
||||
}
|
||||
|
||||
|
||||
// Set user request data
|
||||
// TODO: Should we clone this in stead of referencing it ???
|
||||
if(req.user.guestTo){
|
||||
// Setup guest credentials based and normal user credentials
|
||||
req.user.username = req.user.guestTo;
|
||||
req.user.vPath = Users[req.user.guestTo].vPath;
|
||||
req.user.musicDir = Users[req.user.guestTo].musicDir;
|
||||
}
|
||||
next();
|
||||
});
|
||||
});
|
||||
|
||||
// Setup Music Dirs here so they are protected by middleware
|
||||
for (var key in permissionsMap) {
|
||||
mstream.use( '/' + permissionsMap[key] + '/' , express.static( key ));
|
||||
}
|
||||
}
|
||||
365
mstream.js
365
mstream.js
@ -10,11 +10,6 @@ const mstream = express();
|
||||
const fs = require('fs'); // File System
|
||||
const fe = require('path');
|
||||
const bodyParser = require('body-parser');
|
||||
const archiver = require('archiver'); // Zip Compression
|
||||
const os = require('os');
|
||||
const crypto = require('crypto');
|
||||
const slash = require('slash');
|
||||
const uuidV4 = require('uuid/v4');
|
||||
|
||||
|
||||
// Magic Middleware Things
|
||||
@ -40,8 +35,8 @@ console.log('Access mStream on your local network: http://' + require('internal-
|
||||
// console.log('Access mStream on your local network: http://' + add + ':' + program.port);
|
||||
// })
|
||||
|
||||
|
||||
// Handle Port Forwarding
|
||||
// TODO: Switch between uPNP and nat-pmp
|
||||
if(program.tunnel){
|
||||
const tunnel = require('./modules/auto-port-forwarding.js').setup(program.tunnel, program.port);
|
||||
}
|
||||
@ -66,9 +61,12 @@ try{
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// JukeBox
|
||||
const jukebox = require('./modules/jukebox.js');
|
||||
jukebox.setup2(mstream, server, program);
|
||||
// Serve Jukebox Page
|
||||
mstream.all('/remote', function (req, res) {
|
||||
res.sendFile( fe.join('public', 'remote.html'), { root: __dirname });
|
||||
});
|
||||
@ -76,7 +74,6 @@ mstream.all('/remote', function (req, res) {
|
||||
// Shared
|
||||
const sharedModule = require('./modules/shared.js');
|
||||
sharedModule.setupBeforeSecurity(mstream, program);
|
||||
|
||||
// Serve the shared webapp
|
||||
mstream.all('/shared/*', function (req, res) {
|
||||
res.sendFile( fe.join('public', 'shared.html'), { root: __dirname });
|
||||
@ -87,204 +84,8 @@ mstream.all('/shared/*', function (req, res) {
|
||||
|
||||
// Login functionality
|
||||
if(program.users){
|
||||
// Use bcrypt for password storage
|
||||
const bcrypt = require('bcrypt');
|
||||
const jwt = require('jsonwebtoken'); // used to create, sign, and verify tokens
|
||||
|
||||
|
||||
|
||||
|
||||
// TODO: Add New user functionality
|
||||
// Check for root user and password
|
||||
// Add credentials to user array
|
||||
|
||||
// TODO: Need a way to store and use already hashed passwords
|
||||
|
||||
|
||||
// TODO: password change function
|
||||
mstream.post('/change-password-request', function (req, res) {
|
||||
// Get email address from request
|
||||
// validate email against user array
|
||||
// Generate change password token
|
||||
// Invalidate all other change password tokens
|
||||
// Email the user the token
|
||||
|
||||
res.sendFile( 'COMING SOON!' );
|
||||
});
|
||||
|
||||
mstream.post('/change-password', function (req, res){
|
||||
// Check token
|
||||
// Get new password
|
||||
// Hash password and update user array
|
||||
|
||||
res.sendFile( 'COMING SOON!' );
|
||||
});
|
||||
|
||||
|
||||
// Create the user array
|
||||
var Users = program.users;
|
||||
var permissionsMap = {};
|
||||
|
||||
for (let username in Users) {
|
||||
// Setup user password
|
||||
generateSaltedPassword(username, Users[username]["password"]);
|
||||
|
||||
// If this is a guest user, continue
|
||||
if(Users[username].guestTo){
|
||||
continue;
|
||||
}
|
||||
|
||||
// If dir has not been added yet
|
||||
if ( !(Users[username].musicDir in permissionsMap) ){
|
||||
// Generate unique vPath if necessary
|
||||
// The best way is to store the vPath in the JSON file
|
||||
if(!Users[username].vPath){
|
||||
Users[username].vPath = uuidV4();
|
||||
}
|
||||
|
||||
// Add to permissionsMap
|
||||
permissionsMap[Users[username].musicDir] = Users[username].vPath;
|
||||
}else{
|
||||
Users[username].vPath = permissionsMap[Users[username].musicDir];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
function generateSaltedPassword(username, password){
|
||||
bcrypt.genSalt(10, function(err, salt) {
|
||||
bcrypt.hash(password, salt, function(err, hash) {
|
||||
// Store hash in your password DB.
|
||||
Users[username]['password'] = hash;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Failed Login Attempt
|
||||
mstream.get('/login-failed', function (req, res) {
|
||||
// Wait before sending the response
|
||||
setTimeout((function() {
|
||||
res.status(599).send(JSON.stringify({'Error':'Try Again'}))
|
||||
}), 800);
|
||||
});
|
||||
|
||||
mstream.get('/access-denied', function (req, res) {
|
||||
res.status(598).send(JSON.stringify({'Error':'Access Denied'}));
|
||||
});
|
||||
|
||||
mstream.get('/guest-access-denied', function (req, res) {
|
||||
res.status(597).send(JSON.stringify({'Error':'Access Denied'}));
|
||||
});
|
||||
|
||||
// route to authenticate a user (POST http://localhost:8080/api/authenticate)
|
||||
mstream.post('/login', function(req, res) {
|
||||
let username = req.body.username;
|
||||
let password = req.body.password;
|
||||
|
||||
// Check is user is in array
|
||||
if(typeof Users[username] === 'undefined') {
|
||||
// user does not exist
|
||||
return res.redirect('/login-failed');
|
||||
}
|
||||
|
||||
// Check is password is correct
|
||||
bcrypt.compare(password, Users[username]['password'], function(err, match) {
|
||||
if(match == false){
|
||||
// Password does not match
|
||||
return res.redirect('/login-failed');
|
||||
}
|
||||
|
||||
|
||||
var sendData = {
|
||||
username: username,
|
||||
}
|
||||
|
||||
var vPath;
|
||||
if(Users[username].guestTo){
|
||||
vPath = Users[Users[username].guestTo].vPath;
|
||||
}else{
|
||||
vPath = Users[username].vPath;
|
||||
}
|
||||
|
||||
// return the information including token as JSON
|
||||
var sendThis = {
|
||||
success: true,
|
||||
message: 'Welcome To mStream',
|
||||
vPath: vPath,
|
||||
token: jwt.sign(sendData, program.secret) // Make the token
|
||||
};
|
||||
|
||||
res.send(JSON.stringify(sendThis));
|
||||
});
|
||||
});
|
||||
|
||||
// Guest Users are not allowed to access these functions
|
||||
const forbiddenFunctions = ['/db/recursive-scan', '/saveplaylist', '/deleteplaylist'];
|
||||
|
||||
// Middleware that checks for token
|
||||
mstream.use(function(req, res, next) {
|
||||
// check header or url parameters or post parameters for token
|
||||
var token = req.body.token || req.query.token || req.headers['x-access-token'];
|
||||
if (!token) {
|
||||
return res.redirect('/access-denied');
|
||||
}
|
||||
|
||||
// verifies secret and checks exp
|
||||
jwt.verify(token, program.secret, function(err, decoded) {
|
||||
if (err) {
|
||||
return res.redirect('/access-denied');
|
||||
}
|
||||
|
||||
// Check if share token
|
||||
if(decoded.shareToken && decoded.shareToken === true){
|
||||
// We limit the endpoints to download and anythign in the allowedFiles array
|
||||
// TODO: There's gottab be a better way to habdle vpaths
|
||||
// TODO: Add vpath to allowedFiles when it's created ???
|
||||
// console.log(decodeURIComponent(req.path.substring(38)));
|
||||
if(req.path !== '/download' && decoded.allowedFiles.indexOf(decodeURIComponent(req.path.substring(38))) === -1){ // The substring is to cut out the vPath
|
||||
return res.redirect('/guest-access-denied');
|
||||
}
|
||||
req.allowedFiles = decoded.allowedFiles;
|
||||
next();
|
||||
return;
|
||||
}
|
||||
// User may access those files and no others
|
||||
|
||||
// Check for any hardcoded restrictions baked right into token
|
||||
if(decoded.restrictedFunctions && decoded.restrictedFunctions.indexOf(req.path) != -1){
|
||||
return res.redirect('/guest-access-denied');
|
||||
}
|
||||
|
||||
// TODO: Verify that users in token exist and vPath matches
|
||||
// TODO: Longterm goal - use vPath from request variable instead of having the user manually add it
|
||||
req.user = Users[decoded.username];
|
||||
req.user.username = decoded.username;
|
||||
|
||||
// Deny guest access
|
||||
if(req.user.guestTo && forbiddenFunctions.indexOf(req.path) != -1){
|
||||
return res.redirect('/guest-access-denied');
|
||||
}
|
||||
|
||||
|
||||
// Set user request data
|
||||
// TODO: Should we clone this in stead of referencing it ???
|
||||
if(req.user.guestTo){
|
||||
// Setup guest credentials based and normal user credentials
|
||||
req.user.username = req.user.guestTo;
|
||||
req.user.vPath = Users[req.user.guestTo].vPath;
|
||||
req.user.musicDir = Users[req.user.guestTo].musicDir;
|
||||
}
|
||||
next();
|
||||
});
|
||||
});
|
||||
|
||||
// Setup Music Dirs here so they are protected by middleware
|
||||
for (var key in permissionsMap) {
|
||||
mstream.use( '/' + permissionsMap[key] + '/' , express.static( key ));
|
||||
}
|
||||
|
||||
require('./modules/login.js').setup(mstream, program, express);
|
||||
}else{
|
||||
|
||||
// Dummy data
|
||||
mstream.use(function(req, res, next) {
|
||||
req.user = {
|
||||
@ -312,129 +113,21 @@ mstream.get('/ping', function(req, res){
|
||||
|
||||
|
||||
|
||||
// parse directories
|
||||
mstream.post('/dirparser', function (req, res) {
|
||||
var directories = [];
|
||||
var filesArray = [];
|
||||
|
||||
// TODO: Make sure path is a sub-path of the user's music dir
|
||||
var path = fe.join(req.user.musicDir, req.body.dir);
|
||||
// Make sure it's a directory
|
||||
if(!fs.statSync( path).isDirectory()){
|
||||
res.status(500).json({ error: 'Not a directory' });
|
||||
return;
|
||||
}
|
||||
|
||||
// Will only show these files. Prevents people from snooping around
|
||||
// TODO: Move to global vairable
|
||||
const masterFileTypesArray = ["mp3", "flac", "wav", "ogg", "aac", "m4a"];
|
||||
var fileTypesArray;
|
||||
if(req.body.filetypes){
|
||||
fileTypesArray = JSON.parse(req.body.filetypes);
|
||||
}else{
|
||||
fileTypesArray = masterFileTypesArray;
|
||||
}
|
||||
|
||||
|
||||
// get directory contents
|
||||
var files = fs.readdirSync( path);
|
||||
// Download Files Call
|
||||
require('./modules/download.js').setup(mstream, program);
|
||||
|
||||
// loop through files
|
||||
for (let i=0; i < files.length; i++) {
|
||||
// File Explorer API Call
|
||||
require('./modules/file-explorer.js').setup(mstream, program);
|
||||
|
||||
try{
|
||||
var stat = fs.statSync(fe.join(path, files[i]));
|
||||
}catch(error){
|
||||
// Bad file, ignore and continue
|
||||
// TODO: Log This
|
||||
continue;
|
||||
}
|
||||
// Load database plugin system
|
||||
require('./modules/db-management/database-master.js').setup(mstream, program);
|
||||
|
||||
// Handle Directories
|
||||
if(stat.isDirectory()){
|
||||
directories.push({
|
||||
type:"directory",
|
||||
name:files[i]
|
||||
});
|
||||
}else{ // Handle Files
|
||||
var extension = getFileType(files[i]);
|
||||
if (fileTypesArray.indexOf(extension) > -1 && masterFileTypesArray.indexOf(extension) > -1) {
|
||||
filesArray.push({
|
||||
type:extension, // TODO: Should this be changed
|
||||
name:files[i]
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
// Finish setting up the jukebox and shared
|
||||
jukebox.setup(mstream, server, program);
|
||||
sharedModule.setupAfterSecurity(mstream, program);
|
||||
|
||||
var returnPath = slash( fe.relative(req.user.musicDir, path) );
|
||||
if(returnPath.slice(-1) !== '/'){
|
||||
returnPath += '/';
|
||||
}
|
||||
|
||||
// Send back combined list of directories and mp3s
|
||||
res.send(
|
||||
JSON.stringify({ path:returnPath, contents:filesArray.concat(directories)})
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
|
||||
function getFileType(filename){
|
||||
return filename.split(".").pop();
|
||||
}
|
||||
|
||||
|
||||
// Download a zip file of music
|
||||
mstream.post('/download', function (req, res){
|
||||
var archive = archiver('zip');
|
||||
|
||||
archive.on('error', function(err) {
|
||||
console.log(err.message);
|
||||
res.status(500).send('{error: '+err.message+'}');
|
||||
});
|
||||
|
||||
archive.on('end', function() {
|
||||
// TODO: add logging
|
||||
});
|
||||
|
||||
//set the archive name
|
||||
// TODO: Rename this
|
||||
res.attachment('zipped-playlist.zip');
|
||||
|
||||
//streaming magic
|
||||
archive.pipe(res);
|
||||
|
||||
var fileArray;
|
||||
|
||||
|
||||
// Get the POSTed files
|
||||
if(req.allowedFiles){
|
||||
fileArray = allowedFiles;
|
||||
}else{
|
||||
fileArray = JSON.parse(req.body.fileArray);
|
||||
}
|
||||
|
||||
for(var i in fileArray) {
|
||||
// TODO: Confirm each item in posted data is a real file
|
||||
var fileString = fileArray[i];
|
||||
archive.file(fe.normalize( fileString), { name: fe.basename(fileString) });
|
||||
}
|
||||
|
||||
archive.finalize();
|
||||
});
|
||||
|
||||
|
||||
|
||||
// ============================================================================
|
||||
|
||||
// New Way
|
||||
// We need to pull this from the program var
|
||||
var dbSettings = program.database_plugin;
|
||||
const mstreamDB = require('./modules/db-management/database-master.js');
|
||||
mstreamDB.setup(mstream, program);
|
||||
|
||||
// ============================================================================
|
||||
|
||||
|
||||
// TODO: Add individual song
|
||||
@ -444,26 +137,9 @@ mstream.get('/db/add-songs', function(req, res){
|
||||
|
||||
// TODO: Get Album Art calls
|
||||
mstream.post( '/get-album-art', function(req, res){
|
||||
// Get filepath from post
|
||||
// Check if album art is in DB
|
||||
// Return If So
|
||||
// Pull album art from file stream
|
||||
// ??? Lookup album art via 3rd party ???
|
||||
|
||||
res.send('Coming Soon!');
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
jukebox.setup(mstream, server, program);
|
||||
sharedModule.setupAfterSecurity(mstream, program);
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
/////////////////// SPECIALITY HIGHER LEVEL COMMANDS /////////////////////
|
||||
|
||||
mstream.post( '/scrape-user-info', function(req, res){
|
||||
// The idea behind this is to hav a function that dumps a JSON of all relevant user info
|
||||
// UUIDs
|
||||
@ -477,21 +153,8 @@ mstream.post( '/scrape-user-info', function(req, res){
|
||||
});
|
||||
|
||||
|
||||
mstream.post('/sunset-user', function(req,res){
|
||||
// Removes all user info
|
||||
});
|
||||
|
||||
mstream.post('/add-user', function(req,res){
|
||||
// Add a user
|
||||
});
|
||||
|
||||
/////////////////// SPECIALITY HIGHER LEVEL COMMANDS ///////////////////
|
||||
|
||||
|
||||
// Start the server!
|
||||
// TODO: Check if port is in use befoe firing up server
|
||||
// const server = mstream.listen(program.port, function () {});
|
||||
|
||||
server.on('request', mstream);
|
||||
server.listen(program.port, function () { });
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user