Fixed perms for schedule/channel playlists

This commit is contained in:
rainbow napkin 2025-04-04 20:38:40 -04:00
parent 8c990c14e6
commit e61d9deb52
3 changed files with 197 additions and 169 deletions

View file

@ -66,49 +66,50 @@ module.exports = class{
chanDB = await channelModel.findOne({name: this.channel.name}); chanDB = await channelModel.findOne({name: this.channel.name});
} }
if(await chanDB.permCheck(socket.user, 'editChannelPlaylists')){
//If the title is too long //If the title is too long
if(!validator.isLength(data.playlist, {max:30})){ if(!validator.isLength(data.playlist, {max:30})){
//Bitch, moan, complain... //Bitch, moan, complain...
loggerUtils.socketErrorHandler(socket, "Playlist name too long!", "validation"); loggerUtils.socketErrorHandler(socket, "Playlist name too long!", "validation");
//and ignore it! //and ignore it!
return; return;
}
//Escape/trim the playlist name
const name = validator.escape(validator.trim(data.playlist));
//If the channel already exists
if(chanDB.getPlaylistByName(name) != null){
//Bitch, moan, complain...
loggerUtils.socketErrorHandler(socket, `Playlist named '${name}' already exists!`, "validation");
//and ignore it!
return;
}
//Create empty array to hold titles
const safeTitles = [];
//For each default title passed by the data
for(let title of data.defaultTitles){
//If the title isn't too long
if(validator.isLength(title, {min:1, max:30})){
//Add it to the safe title list
safeTitles.push(validator.escape(validator.trim(title)))
} }
//Escape/trim the playlist name
const name = validator.escape(validator.trim(data.playlist));
//If the channel already exists
if(chanDB.getPlaylistByName(name) != null){
//Bitch, moan, complain...
loggerUtils.socketErrorHandler(socket, `Playlist named '${name}' already exists!`, "validation");
//and ignore it!
return;
}
//Create empty array to hold titles
const safeTitles = [];
//For each default title passed by the data
for(let title of data.defaultTitles){
//If the title isn't too long
if(validator.isLength(title, {min:1, max:30})){
//Add it to the safe title list
safeTitles.push(validator.escape(validator.trim(title)))
}
}
//Add playlist to the channel doc
chanDB.media.playlists.push({
name,
defaultTitles: safeTitles
});
//Save the channel doc
await chanDB.save();
//Return playlists from channel doc
socket.emit('chanPlaylists', chanDB.getPlaylists());
} }
//Add playlist to the channel doc
chanDB.media.playlists.push({
name,
defaultTitles: safeTitles
});
//Save the channel doc
await chanDB.save();
//Return playlists from channel doc
socket.emit('chanPlaylists', chanDB.getPlaylists());
}catch(err){ }catch(err){
return loggerUtils.socketExceptionHandler(socket, err); return loggerUtils.socketExceptionHandler(socket, err);
} }
@ -122,11 +123,13 @@ module.exports = class{
chanDB = await channelModel.findOne({name: this.channel.name}); chanDB = await channelModel.findOne({name: this.channel.name});
} }
//Delete playlist name if(await chanDB.permCheck(socket.user, 'editChannelPlaylists')){
await chanDB.deletePlaylistByName(data.playlist); //Delete playlist name
await chanDB.deletePlaylistByName(data.playlist);
//Return playlists from channel doc //Return playlists from channel doc
socket.emit('chanPlaylists', chanDB.getPlaylists()); socket.emit('chanPlaylists', chanDB.getPlaylists());
}
}catch(err){ }catch(err){
return loggerUtils.socketExceptionHandler(socket, err); return loggerUtils.socketExceptionHandler(socket, err);
} }
@ -140,38 +143,40 @@ module.exports = class{
chanDB = await channelModel.findOne({name: this.channel.name}); chanDB = await channelModel.findOne({name: this.channel.name});
} }
let url = data.url if(await chanDB.permCheck(socket.user, 'editChannelPlaylists')){
let url = data.url
//If we where given a bad URL //If we where given a bad URL
if(!validator.isURL(url)){
//Attempt to fix the situation by encoding it
url = encodeURI(url);
//If it's still bad
if(!validator.isURL(url)){ if(!validator.isURL(url)){
//Attempt to fix the situation by encoding it
url = encodeURI(url);
//If it's still bad
if(!validator.isURL(url)){
//Bitch, moan, complain...
loggerUtils.socketErrorHandler(socket, "Bad URL!", "validation");
//and ignore it!
return;
}
}
//Pull media metadata
let mediaList = await yanker.yankMedia(url);
//If we didn't get any media
if(mediaList.length == 0 || mediaList == null){
//Bitch, moan, complain... //Bitch, moan, complain...
loggerUtils.socketErrorHandler(socket, "Bad URL!", "validation"); loggerUtils.socketErrorHandler(socket, "No media found!", "queue");
//and ignore it! //and ignore it!
return; return;
} }
//Add media object to the given playlist
await chanDB.addToPlaylist(data.playlist, mediaList[0]);
//Return playlists from channel doc
socket.emit('chanPlaylists', chanDB.getPlaylists());
} }
//Pull media metadata
let mediaList = await yanker.yankMedia(url);
//If we didn't get any media
if(mediaList.length == 0 || mediaList == null){
//Bitch, moan, complain...
loggerUtils.socketErrorHandler(socket, "No media found!", "queue");
//and ignore it!
return;
}
//Add media object to the given playlist
await chanDB.addToPlaylist(data.playlist, mediaList[0]);
//Return playlists from channel doc
socket.emit('chanPlaylists', chanDB.getPlaylists());
}catch(err){ }catch(err){
return loggerUtils.socketExceptionHandler(socket, err); return loggerUtils.socketExceptionHandler(socket, err);
} }
@ -185,29 +190,32 @@ module.exports = class{
chanDB = await channelModel.findOne({name: this.channel.name}); chanDB = await channelModel.findOne({name: this.channel.name});
} }
//Pull a valid start time from input, or make one up if we can't //Permcheck to make sure the user can fuck w/ the queue
let start = this.channel.queue.getStart(data.start); if((!this.channel.queue.locked && await chanDB.permCheck(socket.user, 'scheduleMedia')) || await chanDB.permCheck(socket.user, 'scheduleAdmin')){
//Pull a valid start time from input, or make one up if we can't
let start = this.channel.queue.getStart(data.start);
//Grab playlist from the DB //Grab playlist from the DB
let playlist = chanDB.getPlaylistByName(data.playlist); let playlist = chanDB.getPlaylistByName(data.playlist);
//Create an empty array to hold our media list //Create an empty array to hold our media list
const mediaList = []; const mediaList = [];
//Iterate through playlist media //Iterate through playlist media
for(let item of playlist.media){ for(let item of playlist.media){
//Rehydrate a full phat media object from the flat DB entry //Rehydrate a full phat media object from the flat DB entry
let mediaObj = item.rehydrate(); let mediaObj = item.rehydrate();
//Set media title from default titles //Set media title from default titles
mediaObj.title = playlist.defaultTitles[Math.floor(Math.random() * playlist.defaultTitles.length)]; mediaObj.title = playlist.defaultTitles[Math.floor(Math.random() * playlist.defaultTitles.length)];
//Push rehydrated item on to the mediaList //Push rehydrated item on to the mediaList
mediaList.push(mediaObj); mediaList.push(mediaObj);
}
//Convert array of standard media objects to queued media objects, and push to schedule
this.channel.queue.scheduleMedia(queuedMedia.fromMediaArray(mediaList, start), socket, chanDB);
} }
//Convert array of standard media objects to queued media objects, and push to schedule
this.channel.queue.scheduleMedia(queuedMedia.fromMediaArray(mediaList, start), socket, chanDB);
}catch(err){ }catch(err){
return loggerUtils.socketExceptionHandler(socket, err); return loggerUtils.socketExceptionHandler(socket, err);
} }
@ -221,36 +229,38 @@ module.exports = class{
chanDB = await channelModel.findOne({name: this.channel.name}); chanDB = await channelModel.findOne({name: this.channel.name});
} }
//If the title is too long if(await chanDB.permCheck(socket.user, 'editChannelPlaylists')){
if(!validator.isLength(data.name, {max:30})){ //If the title is too long
//Bitch, moan, complain... if(!validator.isLength(data.name, {max:30})){
loggerUtils.socketErrorHandler(socket, "Playlist name too long!", "validation"); //Bitch, moan, complain...
//and ignore it! loggerUtils.socketErrorHandler(socket, "Playlist name too long!", "validation");
return; //and ignore it!
return;
}
//Escape/trim the playlist name
const name = validator.escape(validator.trim(data.name));
//If the channel already exists
if(chanDB.getPlaylistByName(name) != null){
//Bitch, moan, complain...
loggerUtils.socketErrorHandler(socket, `Playlist named '${name}' already exists!`, "validation");
//and ignore it!
return;
}
//Find playlist
let playlist = chanDB.getPlaylistByName(data.playlist);
//Change playlist name
chanDB.media.playlists[playlist.listIndex].name = name;
//Save channel document
await chanDB.save();
//Return playlists from channel doc
socket.emit('chanPlaylists', chanDB.getPlaylists());
} }
//Escape/trim the playlist name
const name = validator.escape(validator.trim(data.name));
//If the channel already exists
if(chanDB.getPlaylistByName(name) != null){
//Bitch, moan, complain...
loggerUtils.socketErrorHandler(socket, `Playlist named '${name}' already exists!`, "validation");
//and ignore it!
return;
}
//Find playlist
let playlist = chanDB.getPlaylistByName(data.playlist);
//Change playlist name
chanDB.media.playlists[playlist.listIndex].name = name;
//Save channel document
await chanDB.save();
//Return playlists from channel doc
socket.emit('chanPlaylists', chanDB.getPlaylists());
}catch(err){ }catch(err){
return loggerUtils.socketExceptionHandler(socket, err); return loggerUtils.socketExceptionHandler(socket, err);
} }
@ -264,29 +274,31 @@ module.exports = class{
chanDB = await channelModel.findOne({name: this.channel.name}); chanDB = await channelModel.findOne({name: this.channel.name});
} }
//Find playlist if(await chanDB.permCheck(socket.user, 'editChannelPlaylists')){
let playlist = chanDB.getPlaylistByName(data.playlist); //Find playlist
let playlist = chanDB.getPlaylistByName(data.playlist);
//Create empty array to hold titles //Create empty array to hold titles
const safeTitles = []; const safeTitles = [];
//For each default title passed by the data //For each default title passed by the data
for(let title of data.defaultTitles){ for(let title of data.defaultTitles){
//If the title isn't too long or too short //If the title isn't too long or too short
if(validator.isLength(title, {min: 1, max:30})){ if(validator.isLength(title, {min: 1, max:30})){
//Add it to the safe title list //Add it to the safe title list
safeTitles.push(validator.escape(validator.trim(title))) safeTitles.push(validator.escape(validator.trim(title)))
}
} }
//Change playlist name
chanDB.media.playlists[playlist.listIndex].defaultTitles = safeTitles;
//Save channel document
await chanDB.save();
//Return playlists from channel doc
socket.emit('chanPlaylists', chanDB.getPlaylists());
} }
//Change playlist name
chanDB.media.playlists[playlist.listIndex].defaultTitles = safeTitles;
//Save channel document
await chanDB.save();
//Return playlists from channel doc
socket.emit('chanPlaylists', chanDB.getPlaylists());
}catch(err){ }catch(err){
return loggerUtils.socketExceptionHandler(socket, err); return loggerUtils.socketExceptionHandler(socket, err);
} }
@ -300,19 +312,21 @@ module.exports = class{
chanDB = await channelModel.findOne({name: this.channel.name}); chanDB = await channelModel.findOne({name: this.channel.name});
} }
//If we don't have a valid UUID if(await chanDB.permCheck(socket.user, 'editChannelPlaylists')){
if(!validator.isUUID(data.uuid)){ //If we don't have a valid UUID
//Bitch, moan, complain... if(!validator.isUUID(data.uuid)){
loggerUtils.socketErrorHandler(socket, `'${data.uuid}' is not a valid UUID!`, "validation"); //Bitch, moan, complain...
//and ignore it! loggerUtils.socketErrorHandler(socket, `'${data.uuid}' is not a valid UUID!`, "validation");
return; //and ignore it!
return;
}
//Delete media from channel playlist
chanDB.deletePlaylistMediaByUUID(data.playlist, data.uuid);
//Return playlists from channel doc
socket.emit('chanPlaylists', chanDB.getPlaylists());
} }
//Delete media from channel playlist
chanDB.deletePlaylistMediaByUUID(data.playlist, data.uuid);
//Return playlists from channel doc
socket.emit('chanPlaylists', chanDB.getPlaylists());
}catch(err){ }catch(err){
return loggerUtils.socketExceptionHandler(socket, err); return loggerUtils.socketExceptionHandler(socket, err);
} }

View file

@ -54,7 +54,7 @@ module.exports = class{
defineListeners(socket){ defineListeners(socket){
socket.on("queue", (data) => {this.queueURL(socket, data)}); socket.on("queue", (data) => {this.queueURL(socket, data)});
socket.on("stop", (data) => {this.stopMedia(socket)}); socket.on("stop", (data) => {this.stopMedia(socket)}); //needs perms
socket.on("delete", (data) => {this.deleteMedia(socket, data)}); socket.on("delete", (data) => {this.deleteMedia(socket, data)});
socket.on("clear", (data) => {this.deleteRange(socket, data)}); socket.on("clear", (data) => {this.deleteRange(socket, data)});
socket.on("move", (data) => {this.moveMedia(socket, data)}); socket.on("move", (data) => {this.moveMedia(socket, data)});
@ -121,27 +121,35 @@ module.exports = class{
} }
} }
stopMedia(socket){ async stopMedia(socket){
//If we're not currently playing anything //Get the current channel from the database
if(this.nowPlaying == null){ const chanDB = await channelModel.findOne({name: socket.chan});
//If an originating socket was provided for this request
if(socket != null){ console.log(!this.locked && await chanDB.permCheck(socket.user, 'scheduleMedia')) || await chanDB.permCheck(socket.user, 'scheduleAdmin');
//Yell at the user for being an asshole //Permcheck to make sure the user can fuck w/ the queue
loggerUtils.socketErrorHandler(socket, "No media playing!", "queue"); if((!this.locked && await chanDB.permCheck(socket.user, 'scheduleMedia')) || await chanDB.permCheck(socket.user, 'scheduleAdmin')){
//If we're not currently playing anything
if(this.nowPlaying == null){
//If an originating socket was provided for this request
if(socket != null){
//Yell at the user for being an asshole
loggerUtils.socketErrorHandler(socket, "No media playing!", "queue");
}
//Ignore it
return false;
} }
//Ignore it //Stop playing
return false; const stoppedMedia = this.nowPlaying;
//Get difference between current time and start time and set as early end
stoppedMedia.earlyEnd = (new Date().getTime() - stoppedMedia.startTime) / 1000;
//End the media
this.end();
} }
//Stop playing
const stoppedMedia = this.nowPlaying;
//Get difference between current time and start time and set as early end
stoppedMedia.earlyEnd = (new Date().getTime() - stoppedMedia.startTime) / 1000;
//End the media
this.end();
} }
async deleteMedia(socket, data){ async deleteMedia(socket, data){

View file

@ -100,6 +100,12 @@ const channelPermissionSchema = new mongoose.Schema({
default: "admin", default: "admin",
required: true required: true
}, },
editChannelPlaylists:{
type: mongoose.SchemaTypes.String,
enum: rankEnum,
default: "admin",
required: true
},
deleteChannel: { deleteChannel: {
type: mongoose.SchemaTypes.String, type: mongoose.SchemaTypes.String,
enum: rankEnum, enum: rankEnum,