Compare commits

..

No commits in common. "main" and "0.4-indev-hotfix-2" have entirely different histories.

263 changed files with 811 additions and 1818 deletions

3
.gitignore vendored
View file

@ -9,5 +9,4 @@ chatexamples.txt
server.cert
server.key
www/nonfree/*
migration/*
www/hrt.zip
migration/*

View file

@ -1,4 +1,4 @@
All Original Canopy Code is Covered under the Gnu Affero General Public License v3 - 2024 - 2026 Rainbownapkin
All Original Canopy Code is Covered under the Gnu Affero General Public License v3 - 2024 - 2025 Rainbownapkin
GNU AFFERO GENERAL PUBLIC LICENSE
Version 3, 19 November 2007

View file

@ -9,7 +9,7 @@ Canopy
<a href="https://git.ourfore.st/rainbownapkin/canopy/issues" target="_blank"><img src="https://git.ourfore.st/rainbownapkin/canopy/badges/issues/closed.svg"></a>
<a href="https://www.gnu.org/licenses/agpl-3.0.en.html" target="_blank"><img src="https://img.shields.io/badge/License-AGPL_v3-663366.svg"></a>
0.2-Alpha (Durban Poison)
0.4-INDEV Hotfix 2
=========
Canopy - /ˈkæ.nə.pi/:

View file

@ -34,10 +34,5 @@
"address": "toke@42069.weed",
"pass": "CHANGE_ME"
},
"links":{
"About": "/about",
"Code": "https://git.ourfore.st/rainbownapkin/canopy",
"HRT": "/hrt"
},
"aboutText":"<a href=\"https://ourfore.st/\">ourfore.st</a> is the one and only original canopy instance. Setup, ran, and administered by rainbownapkin herself. This site exists to provide a featureful, preformant, and comfy replacement for the TTN community."
}

View file

@ -65,12 +65,6 @@
"address": "toke@42069.weed",
"pass": "CHANGE_ME"
},
//Provides customizable links for navbar
"links":{
"About": "/about",
"Code": "https://git.ourfore.st/rainbownapkin/canopy",
"HRT": "/hrt"
},
//Fills the 'about ${instanceName}' section on the /about page, lets users know about your specific instance
"aboutText":"<a href=\"https://ourfore.st/\">ourfore.st</a> is the one and only original canopy instance. Setup, ran, and administered by rainbownapkin herself. This site exists to provide a featureful, preformant, and comfy replacement for the TTN community."
}

View file

@ -1,9 +0,0 @@
We're a pretty small and informal community, so I think I can make this small and informal:
- Registration on git.ourfore.st is locked for anti-bot reasons. Bug bowie if you want access.
- Start a new branch either here or on another gitforge (preferably https://codeburg.org), and submit a PR
- Don't feel the need to limit yourself to already open issues, those are simply my current goals. Feel free to fuck around and make cool shit.
- No stolen and/or LLM-Generated code
- Thank you and much love for peeking at, using, and maybe even contributing to Canopy! <3
-Bowie

View file

@ -1,14 +1,13 @@
{
"name": "canopy-of-alpha",
"version": "0.2.0",
"canopyDisplayVersion": "0.2-Alpha (Durban Poison)",
"name": "canopy-of-indev",
"version": "0.4.2",
"license": "AGPL-3.0-only",
"dependencies": {
"@braintree/sanitize-url": "^7.1.1",
"altcha": "^2.3.0",
"altcha": "^1.0.7",
"altcha-lib": "^1.2.0",
"argon2": "^0.44.0",
"bcrypt": "^6.0.0",
"bcrypt": "^5.1.1",
"bootstrap-icons": "^1.11.3",
"connect-mongo": "^5.1.0",
"cookie-parser": "^1.4.7",
@ -20,8 +19,8 @@
"hls.js": "^1.6.2",
"mongoose": "^8.4.3",
"node-cron": "^3.0.3",
"nodemailer": "^8.0.7",
"socket.io": "^4.2.0",
"nodemailer": "^7.0.9",
"socket.io": "^4.8.1",
"youtube-dl-exec": "^3.0.20"
},
"scripts": {

View file

@ -1,5 +1,5 @@
/*Canopy - The next generation of stoner streaming software
Copyright (C) 2024-2026 Rainbownapkin and the TTN Community
Copyright (C) 2024-2025 Rainbownapkin and the TTN Community
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as

View file

@ -1,5 +1,5 @@
/*Canopy - The next generation of stoner streaming software
Copyright (C) 2024-2026 Rainbownapkin and the TTN Community
Copyright (C) 2024-2025 Rainbownapkin and the TTN Community
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
@ -46,11 +46,6 @@ class activeChannel{
* List of channel-wide toke commands
*/
this.tokeCommands = chanDB.tokeCommands;
/**
* Internal Database Identifier for the channel
*/
this._id = chanDB._id;
/**
* List of connected users

View file

@ -1,5 +1,5 @@
/*Canopy - The next generation of stoner streaming software
Copyright (C) 2024-2026 Rainbownapkin and the TTN Community
Copyright (C) 2024-2025 Rainbownapkin and the TTN Community
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as

View file

@ -1,5 +1,5 @@
/*Canopy - The next generation of stoner streaming software
Copyright (C) 2024-2026 Rainbownapkin and the TTN Community
Copyright (C) 2024-2025 Rainbownapkin and the TTN Community
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as

View file

@ -1,5 +1,5 @@
/*Canopy - The next generation of stoner streaming software
Copyright (C) 2024-2026 Rainbownapkin and the TTN Community
Copyright (C) 2024-2025 Rainbownapkin and the TTN Community
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as

View file

@ -1,5 +1,5 @@
/*Canopy - The next generation of stoner streaming software
Copyright (C) 2024-2026 Rainbownapkin and the TTN Community
Copyright (C) 2024-2025 Rainbownapkin and the TTN Community
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
@ -212,12 +212,6 @@ class chatHandler{
* @param {chat} chat - Chat Object representing the message to broadcast to the given channel
*/
relayChatObject(chan, chat){
//If we have an empty chat
if(chat.msg.length <= 0){
//Drop it
return;
}
//Send out chat
this.server.io.in(chan).emit("chatMessage", chat);

View file

@ -1,5 +1,5 @@
/*Canopy - The next generation of stoner streaming software
Copyright (C) 2024-2026 Rainbownapkin and the TTN Community
Copyright (C) 2024-2025 Rainbownapkin and the TTN Community
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as

View file

@ -1,5 +1,5 @@
/*Canopy - The next generation of stoner streaming software
Copyright (C) 2024-2026 Rainbownapkin and the TTN Community
Copyright (C) 2024-2025 Rainbownapkin and the TTN Community
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
@ -54,11 +54,6 @@ class connectedUser{
*/
this.highLevel = userDB.highLevel;
/**
* Internal Database Identifier for the user
*/
this._id = userDB._id;
//Check to make sure users flair entry from DB is good
if(userDB.flair != null){
//Set flair from DB

View file

@ -1,135 +0,0 @@
/*Canopy - The next generation of stoner streaming software
Copyright (C) 2024-2026 Rainbownapkin and the TTN Community
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.*/
//Local Imports
const media = require('./media');
const queuedMedia = require('./queuedMedia');
/**
* Class extending media which represents a queued piece of media
* @extends media
*/
class archivedMedia extends queuedMedia{
/**
* Creates a new queued media object
* @param {String} channel - Channel where object was queued
*/
constructor(title, fileName, url, id, type, duration, rawLink, startTime, startTimeStamp = 0, earlyEnd, uuid, channel){
//Call derived constructor
super(title, fileName, url, id, type, duration, rawLink, startTime, startTimeStamp, earlyEnd, uuid);
/**
* Channel media was queued
*/
this.channel = channel;
/**
* Media status type
*/
this.status = 'archived';
}
//statics
/**
* Creates a archivedMedia object from a media object
* @param {String} channel - Channel where object was queued
* @returns {archivedMedia} queuedMedia object created from given media object
*/
static fromMedia(media, startTime, startTimeStamp, channel){
//Create and return queuedMedia object from given media object and arguments
return new this(
media.title,
media.fileName,
media.url,
media.id,
media.type,
media.duration,
media.rawLink,
startTime,
startTimeStamp,
null,
null,
channel);
}
/**
* Creates a archivedMedia object from a queuedMedia object
* @param {String} channel - Channel where object was queued
* @returns {archivedMedia} queuedMedia object created from given media object
*/
static fromQueuedMedia(media, channel){
//Create and return queuedMedia object from given media object and arguments
return new this(
media.title,
media.fileName,
media.url,
media.id,
media.type,
media.duration,
media.rawLink,
media.startTime,
media.startTimeStamp,
media.earlyEnd,
media.uuid,
channel);
}
/**
* Converts array of media objects into array of archivedMedia objects
* @param {String} channel - Channel where object was queued
* @returns Array of converted queued media objects
*/
static fromMediaArray(mediaList, start, channel){
//Queued Media List
const archivedMediaList = [];
//Start Time Offset
let startOffset = 0;
for(let media of mediaList){
//Convert mediaObj to queuedMedia and push to the back of the list
archivedMediaList.push(this.fromMedia(media, start + startOffset, 0, channel));
//Set start offset to end of the current item
startOffset += (media.duration * 1000) + 5;
}
return archivedMediaList;
}
//methods
/**
* Generates a unique clone of a given media object
* @returns unique clone of media object
*/
clone(){
return new archivedMedia(
this.title,
this.fileName,
this.url,
this.id,
this.type,
this.duration,
this.rawLink,
this.startTime,
this.startTimeStamp,
this.earlyEnd,
null,
this.channel
);
}
}
module.exports = archivedMedia;

View file

@ -1,5 +1,5 @@
/*Canopy - The next generation of stoner streaming software
Copyright (C) 2024-2026 Rainbownapkin and the TTN Community
Copyright (C) 2024-2025 Rainbownapkin and the TTN Community
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as

File diff suppressed because it is too large Load diff

View file

@ -1,5 +1,5 @@
/*Canopy - The next generation of stoner streaming software
Copyright (C) 2024-2026 Rainbownapkin and the TTN Community
Copyright (C) 2024-2025 Rainbownapkin and the TTN Community
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
@ -16,18 +16,14 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.*/
//NPM imports
const validator = require('validator');
const mongoose = require('mongoose');
const { BSON } = require('mongodb');
//Local imports
const config = require('../../../../config.json');
const queuedMedia = require('./queuedMedia');
const archivedMedia = require('./archivedMedia');
const yanker = require('../../../utils/media/yanker');
const loggerUtils = require('../../../utils/loggerUtils');
const channelModel = require('../../../schemas/channel/channelSchema');
const permissionModel = require('../../../schemas/permissionSchema');
const archivedMediaModel = require('../../../schemas/channel/media/archivedMediaSchema');
/**
* Object represneting a single channel's media queue
@ -357,12 +353,6 @@ class queue{
throw loggerUtils.exceptionSmith(`Unable to find channel document ${this.channel.name} while queue item!`, "queue");
}
//If the user doesn't have permission to be doing this shit
if(!((!this.locked && await chanDB.permCheck(socket.user, 'scheduleMedia')) || await chanDB.permCheck(socket.user, 'scheduleAdmin'))){
//Fuggettabouttit!
return;
}
//If something is playing
if(this.nowPlaying != null){
//Capture currently playing object
@ -409,7 +399,7 @@ class queue{
);
//Validate mode input, and default to overwrite
this.liveMode = (data != null && data.mode == "pushback") ? "pushback" : "overwrite";
this.liveMode = (data.mode == "pushback") ? "pushback" : "overwrite";
//Throw stream lock
this.streamLock = true;
@ -432,8 +422,6 @@ class queue{
if(data != null && data.full){
//Pull the channel DB doc
const chanDB = await channelModel.findOne({name:this.channel.name});
//Pull archived media by channel name
const archived = await this.getArchive();
//Cook and emit a new object from all of the data
socket.emit("dumpQueue", {
@ -444,7 +432,7 @@ class queue{
DB: {
schedule: chanDB.media.scheduled,
nowPlaying: chanDB.media.nowPlaying,
archived,
archived: chanDB.media.archived,
}
});
@ -779,14 +767,31 @@ class queue{
//Get requested media
const media = this.getItemByUUID(uuid);
//If we couldn't find anything in the current channel schedule
//If we got a bad request
if(media == null){
try{
//Attempt to delete matching item from archived media
const deletedArchive = await archivedMediaModel.deleteOne({channel: this.channel._id, uuid: new BSON.UUID(uuid)});
//If we wheren't handed a channel
if(chanDB == null){
//DO everything ourselves since we don't have a fance end() function to do it
chanDB = await channelModel.findOne({name:this.channel.name});
}
//if nothing got deleted
if(deletedArchive == null || deletedArchive.deletedCount == 0){
//If we couldn't find the channel
if(chanDB == null){
//FUCK
throw loggerUtils.exceptionSmith(`Unable to find channel document ${this.channel.name} while queue item!`, "queue");
}
//Keep a copy of the archive that hasn't been changed
const preArchive = chanDB.media.archived;
//Filter out the requested item from the archive
chanDB.media.archived = chanDB.media.archived.filter((record)=>{
return record.uuid.toString() != uuid;
})
//If nothing changed in the archive
if(preArchive.length == chanDB.media.archived.length){
//If an originating socket was provided for this request
if(socket != null){
//Yell at the user for being an asshole
@ -797,7 +802,13 @@ class queue{
//If broadcasting is enabled
if(!noBroadcast){
//Broadcast changes
this.broadcastQueue();
this.broadcastQueue(chanDB);
}
//If saving is disabled
if(!noScheduling){
//Save changes to the DB
await chanDB.save();
}
}
}catch(err){
@ -1134,7 +1145,7 @@ class queue{
//If nowPlaying isn't null and isn't what we're about to throw on
if(chanDB.media.nowPlaying != null && chanDB.media.nowPlaying.uuid.toString() != mediaObj.uuid){
//Archive whats already in there since we're about to clobber the fuck out of it
this.archiveMedia(chanDB.media.nowPlaying);
chanDB.media.archived.push(chanDB.media.nowPlaying);
}
//Set the now playing queued media document
@ -1273,7 +1284,7 @@ class queue{
//If archiving is enabled
if(!noArchive){
//Add the item to the channel archive
await this.archiveMedia(wasPlaying);
chanDB.media.archived.push(wasPlaying);
}
//broadcast queue using unsaved archive, run this before chanDB.save() for better responsiveness
@ -1372,7 +1383,7 @@ class queue{
let finished = false;
//Throw the livestream into the archive
this.archiveMedia(wasPlaying);
chanDB.media.archived.push(wasPlaying);
//Save the DB
await chanDB.save();
@ -1457,7 +1468,7 @@ class queue{
}
//Throw the livestream into the archive
this.archiveMedia(wasPlaying);
chanDB.media.archived.push(wasPlaying);
//Set the current place to schedule items at 5ms after the end of the live stream
let curPlace = wasPlaying.getEndTime() + 5;
@ -1726,28 +1737,30 @@ class queue{
//Create an empty array to hold our schedule
let schedule = [];
//Get todays epoch
const yesterday = new Date();
//Make it yesterdays
yesterday.setDate(yesterday.getDate() - 1);
//Get archive since yesterday
const archive = await this.getArchive(yesterday);
//Get yestedays epoch
const yesterday = new Date().setDate(new Date().getDate() - 1);
//Iterate through the channel archive backwards to save time
for(let mediaIndex = archive.length - 1; mediaIndex >= 0; mediaIndex--){
for(let mediaIndex = chanDB.media.archived.length - 1; mediaIndex >= 0; mediaIndex--){
//Grab the current media record
let media = archive[mediaIndex].rehydrate();
let media = chanDB.media.archived[mediaIndex].rehydrate();
//If we're sending out the live remainder during a live stream
if(this.liveRemainder != null && media.uuid.toString() == this.liveRemainder.uuid.toString()){
//Throw out the early end before sending it off, so it looks like it hasn't been cut off yet (smoke n mirrors :P)
media.earlyEnd = null;
//If the media started within the last 24 hours
if(media.startTime > yesterday){
//If we're sending out the live remainder during a live stream
if(this.liveRemainder != null && media.uuid.toString() == this.liveRemainder.uuid.toString()){
//Throw out the early end before sending it off, so it looks like it hasn't been cut off yet (smoke n mirrors :P)
media.earlyEnd = null;
}
//Add it to the temporary schedule array as if it where part of the actual schedule map
schedule.unshift([media.startTime, media]);
//Otherwise if it's older
}else{
//Then we should be done as archived items are added as they are played/end.
//No newer items should be beyond this point!
break;
}
//Add it to the temporary schedule array as if it where part of the actual schedule map
schedule.unshift([media.startTime, media]);
}
//Concatonate the actual schedule to the items we pulled out of the archive return it
@ -1797,7 +1810,7 @@ class queue{
chanDB.media.nowPlaying = null;
//Archive the bitch
this.archiveMedia(wasPlaying);
chanDB.media.archived.push(wasPlaying);
}
}
@ -1827,36 +1840,36 @@ class queue{
//If it's been ended
}else{
//Archive ended media
this.archiveMedia(record);
chanDB.media.archived.push(record);
}
}
}
//If we have a remainder from a livestream
if(chanDB.media.liveRemainder){
let archive = await this.getArchive();
//Iterate backwards through the archive to pull the newest first, since that's probably where this fucker is
for(let archiveIndex = (chanDB.media.archived.length - 1); archiveIndex > 0; archiveIndex--){
//Grab the current media object
const archivedMedia = chanDB.media.archived[archiveIndex];
//Iterate backwards through channel archive
for(let archiveIndex = (archive.length - 1); archiveIndex > 0; archiveIndex--){
//If the current object matches our remainder UUID
if((archive[archiveIndex].uuid.toString() == chanDB.media.liveRemainder.toString())){
if((archivedMedia.uuid.toString() == chanDB.media.liveRemainder.toString())){
//Null out any early end
archive[archiveIndex].earlyEnd = null;
archivedMedia.earlyEnd = null;
//Re-hydrate the item
const archivedMediaObject = archive[archiveIndex].rehydrate();
const archivedMediaObject = archivedMedia.rehydrate();
//if we still have a video to finish
if(archivedMediaObject.getEndTime() > now){
//Convert the fucker back to queuedMedia and save as now playing
chanDB.media.nowPlaying = queuedMedia.fromArchivedMedia(archivedMediaObject);
//Set the fucker as now playing
chanDB.media.nowPlaying = archivedMediaObject;
//Schedule the fucker in RAM, w/ the start function also running in RAM-Only mode
this.scheduleMedia([archivedMediaObject], null, chanDB, true, true, true);
//Splice the fucker out of the archive
await archivedMediaModel.deleteOne({channel: this.channel._id, uuid: new BSON.UUID(chanDB.media.liveRemainder)});
chanDB.media.archived.splice(archiveIndex, 1);
}
//Break out of the loop
@ -1879,36 +1892,6 @@ class queue{
loggerUtils.localExceptionHandler(err);
}
}
/**
* Commits a queuedMedia object to the media archives
* @param {queuedMedia} media - Media object to be archived
*/
async archiveMedia(media){
//Convert queuedMedia object to archivedMedia object
let archived = archivedMedia.fromQueuedMedia(media, this.channel._id);
//Save archivedMedia object to site-wide media archive (gross but performant)
let archivedDoc = await archivedMediaModel.create(archived);
}
/**
* Get Channel Archive
*/
async getArchive(startDate){
//If we provided a start date
if(startDate != null){
//Return archived media after start date
return await archivedMediaModel.find({
channel:this.channel._id,
//Prevent mongoose from attempting to sanatize and invalidate our query object, plus I think we can trust an epoch that came from server-side :)
startTime: mongoose.trusted({$gt: startDate.getTime()})
});
//Otherwise
}else{
//return all archived media
return await archivedMediaModel.find({channel:this.channel._id});
}
}
}
module.exports = queue;

View file

@ -1,5 +1,5 @@
/*Canopy - The next generation of stoner streaming software
Copyright (C) 2024-2026 Rainbownapkin and the TTN Community
Copyright (C) 2024-2025 Rainbownapkin and the TTN Community
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
@ -21,7 +21,7 @@ const loggerUtils = require("../../../utils/loggerUtils");
const channelModel = require("../../../schemas/channel/channelSchema");
/**
* Class containg per-channel server-side queue broadcasting logic
* Class containg global server-side private message relay logic
*
* Exists to make broadcasting channel queues to groups of authenticated users with the 'read-queue' perm as painless as possible,
* reducing DB call/perm checks to just connection time, and not requireing any out-of-library user iteration at broadcast time.

View file

@ -1,5 +1,5 @@
/*Canopy - The next generation of stoner streaming software
Copyright (C) 2024-2026 Rainbownapkin and the TTN Community
Copyright (C) 2024-2025 Rainbownapkin and the TTN Community
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
@ -88,27 +88,6 @@ class queuedMedia extends media{
startTimeStamp);
}
/**
* Creates a queuedMedia object from an archivedMedia object
* @param {String} channel - Channel where object was queued
* @returns {archivedMedia} queuedMedia object created from given media object
*/
static fromArchivedMedia(media){
//Create and return queuedMedia object from given media object and arguments
return new this(
media.title,
media.fileName,
media.url,
media.id,
media.type,
media.duration,
media.rawLink,
media.startTime,
media.startTimeStamp,
media.earlyEnd,
media.uuid);
}
/**
* Converts array of media objects into array of queuedMedia objects
* @param {Array} mediaList - Array of media objects to queue

View file

@ -1,5 +1,5 @@
/*Canopy - The next generation of stoner streaming software
Copyright (C) 2024-2026 Rainbownapkin and the TTN Community
Copyright (C) 2024-2025 Rainbownapkin and the TTN Community
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
@ -148,15 +148,6 @@ class tokebot{
//Add the toking user to the tokers map
this.tokers.set(commandObj.socket.user.user, commandObj.argumentArray[0].toLowerCase());
if(this.tokeCounter <= 3){
//Drop the toke timer
clearTimeout(this.tokeTimer);
//Roll the toke counter back to 3
this.tokeCounter = 3;
//Re-start the toke timer
this.tokeTimer = setTimeout(this.countdown.bind(this), 1000);
}
//If the user is already in the toke
}else{
//Tell them to fuck off
@ -219,7 +210,7 @@ class tokebot{
//Decrement toke time
this.tokeCounter--;
//try again in another second
this.tokeTimer = setTimeout(this.countdown.bind(this), 1000);
this.tokeTimer = setTimeout(this.countdown.bind(this), 1000)
}
/**

View file

@ -1,5 +1,5 @@
/*Canopy - The next generation of stoner streaming software
Copyright (C) 2024-2026 Rainbownapkin and the TTN Community
Copyright (C) 2024-2025 Rainbownapkin and the TTN Community
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as

View file

@ -1,5 +1,5 @@
/*Canopy - The next generation of stoner streaming software
Copyright (C) 2024-2026 Rainbownapkin and the TTN Community
Copyright (C) 2024-2025 Rainbownapkin and the TTN Community
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
@ -57,7 +57,7 @@ class chatPreprocessor{
//If we don't pass sanatization/validation turn this car around
if(!this.sanatizeCommand(commandObj)){
return false;
return;
}
//split the command

View file

@ -1,5 +1,5 @@
/*Canopy - The next generation of stoner streaming software
Copyright (C) 2024-2026 Rainbownapkin and the TTN Community
Copyright (C) 2024-2025 Rainbownapkin and the TTN Community
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as

View file

@ -1,5 +1,5 @@
/*Canopy - The next generation of stoner streaming software
Copyright (C) 2024-2026 Rainbownapkin and the TTN Community
Copyright (C) 2024-2025 Rainbownapkin and the TTN Community
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as

View file

@ -1,5 +1,5 @@
/*Canopy - The next generation of stoner streaming software
Copyright (C) 2024-2026 Rainbownapkin and the TTN Community
Copyright (C) 2024-2025 Rainbownapkin and the TTN Community
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
@ -26,5 +26,5 @@ module.exports = async function(req, res){
res.status(404);
//Render page
return res.render('404', {instance: config.instanceName, links: config.links, user: req.session.user, csrfToken: csrfUtils.generateToken(req)});
return res.render('404', {instance: config.instanceName, user: req.session.user, csrfToken: csrfUtils.generateToken(req)});
}

View file

@ -1,5 +1,5 @@
/*Canopy - The next generation of stoner streaming software
Copyright (C) 2024-2026 Rainbownapkin and the TTN Community
Copyright (C) 2024-2025 Rainbownapkin and the TTN Community
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
@ -16,7 +16,6 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.*/
//Config
const config = require('../../config.json');
const package = require('../../package.json');
//Local Imports
const csrfUtils = require('../utils/csrfUtils');
@ -24,5 +23,5 @@ const csrfUtils = require('../utils/csrfUtils');
//register page functions
module.exports.get = async function(req, res){
//Render page
return res.render('about', {aboutText: config.aboutText, instance: config.instanceName, links: config.links, user: req.session.user, version: package.canopyDisplayVersion, csrfToken: csrfUtils.generateToken(req)});
return res.render('about', {aboutText: config.aboutText, instance: config.instanceName, user: req.session.user, csrfToken: csrfUtils.generateToken(req)});
}

View file

@ -1,5 +1,5 @@
/*Canopy - The next generation of stoner streaming software
Copyright (C) 2024-2026 Rainbownapkin and the TTN Community
Copyright (C) 2024-2025 Rainbownapkin and the TTN Community
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
@ -42,7 +42,7 @@ module.exports.get = async function(req, res){
//Render out the page
return res.render('adminPanel', {
instance: config.instanceName, links: config.links,
instance: config.instanceName,
user: req.session.user,
rankEnum: permissionModel.rankEnum,
chanGuide: chanGuide,

View file

@ -1,5 +1,5 @@
/*Canopy - The next generation of stoner streaming software
Copyright (C) 2024-2026 Rainbownapkin and the TTN Community
Copyright (C) 2024-2025 Rainbownapkin and the TTN Community
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as

View file

@ -1,6 +1,6 @@
/*Canopy - The next generation of stoner streaming software
Copyright (C) 2024-2026 Rainbownapkin and the TTN Community
Copyright (C) 2024-2025 Rainbownapkin and the TTN Community
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
@ -60,7 +60,7 @@ module.exports.post = async function(req, res){
//Look through DB and migration cache for existing email
const existingDB = await userModel.findOne({email: new RegExp(`^${email}$`, 'i')});
const existingDB = await userModel.findOne({email: new RegExp(email, 'i')});
const needsMigration = userModel.migrationCache.emails.includes(email.toLowerCase());
//If the email is in use

View file

@ -1,5 +1,5 @@
/*Canopy - The next generation of stoner streaming software
Copyright (C) 2024-2026 Rainbownapkin and the TTN Community
Copyright (C) 2024-2025 Rainbownapkin and the TTN Community
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
@ -90,7 +90,7 @@ module.exports.post = async function(req, res){
const {user, pass} = matchedData(req);
//Look for the username in the migration DB
const migrationDB = await migrationModel.findOne({user: new RegExp(`^${user}$`, 'i')});
const migrationDB = await migrationModel.findOne({user});
//If we found a migration profile
if(migrationDB != null){

View file

@ -1,5 +1,5 @@
/*Canopy - The next generation of stoner streaming software
Copyright (C) 2024-2026 Rainbownapkin and the TTN Community
Copyright (C) 2024-2025 Rainbownapkin and the TTN Community
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as

View file

@ -1,5 +1,5 @@
/*Canopy - The next generation of stoner streaming software
Copyright (C) 2024-2026 Rainbownapkin and the TTN Community
Copyright (C) 2024-2025 Rainbownapkin and the TTN Community
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as

View file

@ -1,5 +1,5 @@
/*Canopy - The next generation of stoner streaming software
Copyright (C) 2024-2026 Rainbownapkin and the TTN Community
Copyright (C) 2024-2025 Rainbownapkin and the TTN Community
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as

View file

@ -1,5 +1,5 @@
/*Canopy - The next generation of stoner streaming software
Copyright (C) 2024-2026 Rainbownapkin and the TTN Community
Copyright (C) 2024-2025 Rainbownapkin and the TTN Community
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as

View file

@ -1,5 +1,5 @@
/*Canopy - The next generation of stoner streaming software
Copyright (C) 2024-2026 Rainbownapkin and the TTN Community
Copyright (C) 2024-2025 Rainbownapkin and the TTN Community
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as

View file

@ -1,5 +1,5 @@
/*Canopy - The next generation of stoner streaming software
Copyright (C) 2024-2026 Rainbownapkin and the TTN Community
Copyright (C) 2024-2025 Rainbownapkin and the TTN Community
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as

View file

@ -1,5 +1,5 @@
/*Canopy - The next generation of stoner streaming software
Copyright (C) 2024-2026 Rainbownapkin and the TTN Community
Copyright (C) 2024-2025 Rainbownapkin and the TTN Community
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as

View file

@ -1,5 +1,5 @@
/*Canopy - The next generation of stoner streaming software
Copyright (C) 2024-2026 Rainbownapkin and the TTN Community
Copyright (C) 2024-2025 Rainbownapkin and the TTN Community
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as

View file

@ -1,5 +1,5 @@
/*Canopy - The next generation of stoner streaming software
Copyright (C) 2024-2026 Rainbownapkin and the TTN Community
Copyright (C) 2024-2025 Rainbownapkin and the TTN Community
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as

View file

@ -1,5 +1,5 @@
/*Canopy - The next generation of stoner streaming software
Copyright (C) 2024-2026 Rainbownapkin and the TTN Community
Copyright (C) 2024-2025 Rainbownapkin and the TTN Community
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as

View file

@ -1,5 +1,5 @@
/*Canopy - The next generation of stoner streaming software
Copyright (C) 2024-2026 Rainbownapkin and the TTN Community
Copyright (C) 2024-2025 Rainbownapkin and the TTN Community
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as

View file

@ -1,5 +1,5 @@
/*Canopy - The next generation of stoner streaming software
Copyright (C) 2024-2026 Rainbownapkin and the TTN Community
Copyright (C) 2024-2025 Rainbownapkin and the TTN Community
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as

View file

@ -1,5 +1,5 @@
/*Canopy - The next generation of stoner streaming software
Copyright (C) 2024-2026 Rainbownapkin and the TTN Community
Copyright (C) 2024-2025 Rainbownapkin and the TTN Community
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as

View file

@ -1,5 +1,5 @@
/*Canopy - The next generation of stoner streaming software
Copyright (C) 2024-2026 Rainbownapkin and the TTN Community
Copyright (C) 2024-2025 Rainbownapkin and the TTN Community
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as

View file

@ -1,5 +1,5 @@
/*Canopy - The next generation of stoner streaming software
Copyright (C) 2024-2026 Rainbownapkin and the TTN Community
Copyright (C) 2024-2025 Rainbownapkin and the TTN Community
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as

View file

@ -1,5 +1,5 @@
/*Canopy - The next generation of stoner streaming software
Copyright (C) 2024-2026 Rainbownapkin and the TTN Community
Copyright (C) 2024-2025 Rainbownapkin and the TTN Community
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as

View file

@ -1,5 +1,5 @@
/*Canopy - The next generation of stoner streaming software
Copyright (C) 2024-2026 Rainbownapkin and the TTN Community
Copyright (C) 2024-2025 Rainbownapkin and the TTN Community
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as

View file

@ -1,5 +1,5 @@
/*Canopy - The next generation of stoner streaming software
Copyright (C) 2024-2026 Rainbownapkin and the TTN Community
Copyright (C) 2024-2025 Rainbownapkin and the TTN Community
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as

View file

@ -1,5 +1,5 @@
/*Canopy - The next generation of stoner streaming software
Copyright (C) 2024-2026 Rainbownapkin and the TTN Community
Copyright (C) 2024-2025 Rainbownapkin and the TTN Community
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as

View file

@ -1,5 +1,5 @@
/*Canopy - The next generation of stoner streaming software
Copyright (C) 2024-2026 Rainbownapkin and the TTN Community
Copyright (C) 2024-2025 Rainbownapkin and the TTN Community
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as

View file

@ -1,5 +1,5 @@
/*Canopy - The next generation of stoner streaming software
Copyright (C) 2024-2026 Rainbownapkin and the TTN Community
Copyright (C) 2024-2025 Rainbownapkin and the TTN Community
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as

View file

@ -1,5 +1,5 @@
/*Canopy - The next generation of stoner streaming software
Copyright (C) 2024-2026 Rainbownapkin and the TTN Community
Copyright (C) 2024-2025 Rainbownapkin and the TTN Community
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as

View file

@ -1,5 +1,5 @@
/*Canopy - The next generation of stoner streaming software
Copyright (C) 2024-2026 Rainbownapkin and the TTN Community
Copyright (C) 2024-2025 Rainbownapkin and the TTN Community
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as

View file

@ -1,5 +1,5 @@
/*Canopy - The next generation of stoner streaming software
Copyright (C) 2024-2026 Rainbownapkin and the TTN Community
Copyright (C) 2024-2025 Rainbownapkin and the TTN Community
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as

View file

@ -1,5 +1,5 @@
/*Canopy - The next generation of stoner streaming software
Copyright (C) 2024-2026 Rainbownapkin and the TTN Community
Copyright (C) 2024-2025 Rainbownapkin and the TTN Community
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as

View file

@ -1,5 +1,5 @@
/*Canopy - The next generation of stoner streaming software
Copyright (C) 2024-2026 Rainbownapkin and the TTN Community
Copyright (C) 2024-2025 Rainbownapkin and the TTN Community
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as

View file

@ -1,5 +1,5 @@
/*Canopy - The next generation of stoner streaming software
Copyright (C) 2024-2026 Rainbownapkin and the TTN Community
Copyright (C) 2024-2025 Rainbownapkin and the TTN Community
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as

View file

@ -1,5 +1,5 @@
/*Canopy - The next generation of stoner streaming software
Copyright (C) 2024-2026 Rainbownapkin and the TTN Community
Copyright (C) 2024-2025 Rainbownapkin and the TTN Community
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
@ -22,5 +22,5 @@ const csrfUtils = require('../utils/csrfUtils');
//channel functions
module.exports.get = function(req, res){
res.render('channel', {instance: config.instanceName, links: config.links, user: req.session.user, csrfToken: csrfUtils.generateToken(req)});
res.render('channel', {instance: config.instanceName, user: req.session.user, csrfToken: csrfUtils.generateToken(req)});
}

View file

@ -1,5 +1,5 @@
/*Canopy - The next generation of stoner streaming software
Copyright (C) 2024-2026 Rainbownapkin and the TTN Community
Copyright (C) 2024-2025 Rainbownapkin and the TTN Community
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
@ -42,7 +42,7 @@ module.exports.get = async function(req, res){
throw loggerUtils.exceptionSmith("Channel not found.", "queue");
}
return res.render('channelSettings', {instance: config.instanceName, links: config.links, user: req.session.user, channel: chanDB, reqRank, rankEnum: permissionModel.rankEnum, csrfToken: csrfUtils.generateToken(req), unescape: validator.unescape});
return res.render('channelSettings', {instance: config.instanceName, user: req.session.user, channel: chanDB, reqRank, rankEnum: permissionModel.rankEnum, csrfToken: csrfUtils.generateToken(req), unescape: validator.unescape});
}catch(err){
return exceptionHandler(res, err);
}

View file

@ -1,5 +1,5 @@
/*Canopy - The next generation of stoner streaming software
Copyright (C) 2024-2026 Rainbownapkin and the TTN Community
Copyright (C) 2024-2025 Rainbownapkin and the TTN Community
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
@ -40,18 +40,18 @@ module.exports.get = async function(req, res){
//If we have an invalid request
if(requestDB == null){
return res.render('emailChange', {instance: config.instanceName, links: config.links, user: req.session.user, csrfToken: csrfUtils.generateToken(req), valid: false});
return res.render('emailChange', {instance: config.instanceName, user: req.session.user, csrfToken: csrfUtils.generateToken(req), valid: false});
}
//Speak of our success (don't wait for the emails to be sent)
res.render('emailChange', {instance: config.instanceName, links: config.links, user: req.session.user, csrfToken: csrfUtils.generateToken(req), valid: true});
res.render('emailChange', {instance: config.instanceName, user: req.session.user, csrfToken: csrfUtils.generateToken(req), valid: true});
//Consume the request
await requestDB.consume();
}else{
return res.render('emailChange', {instance: config.instanceName, links: config.links, user: req.session.user, csrfToken: csrfUtils.generateToken(req), valid: false});
return res.render('emailChange', {instance: config.instanceName, user: req.session.user, csrfToken: csrfUtils.generateToken(req), valid: false});
}
}catch(err){
return res.render('emailChange', {instance: config.instanceName, links: config.links, user: req.session.user, csrfToken: csrfUtils.generateToken(req), valid: false});
return res.render('emailChange', {instance: config.instanceName, user: req.session.user, csrfToken: csrfUtils.generateToken(req), valid: false});
}
}

View file

@ -1,28 +0,0 @@
/*Canopy - The next generation of stoner streaming software
Copyright (C) 2024-2026 Rainbownapkin and the TTN Community
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.*/
//Config
const config = require('../../config.json');
const package = require('../../package.json');
//Local Imports
const csrfUtils = require('../utils/csrfUtils');
//register page functions
module.exports.get = async function(req, res){
//Render page
return res.render('hrt', {instance: config.instanceName, links: config.links, user: req.session.user, csrfToken: csrfUtils.generateToken(req)});
}

View file

@ -1,5 +1,5 @@
/*Canopy - The next generation of stoner streaming software
Copyright (C) 2024-2026 Rainbownapkin and the TTN Community
Copyright (C) 2024-2025 Rainbownapkin and the TTN Community
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
@ -29,7 +29,7 @@ const {exceptionHandler, errorHandler} = require('../utils/loggerUtils');
module.exports.get = async function(req, res){
try{
const chanGuide = await channelModel.getChannelList();
return res.render('index', {instance: config.instanceName, links: config.links, user: req.session.user, chanGuide: chanGuide, csrfToken: csrfUtils.generateToken(req), unescape: validator.unescape});
return res.render('index', {instance: config.instanceName, user: req.session.user, chanGuide: chanGuide, csrfToken: csrfUtils.generateToken(req), unescape: validator.unescape});
}catch(err){
return exceptionHandler(res, err);
}

View file

@ -1,5 +1,5 @@
/*Canopy - The next generation of stoner streaming software
Copyright (C) 2024-2026 Rainbownapkin and the TTN Community
Copyright (C) 2024-2025 Rainbownapkin and the TTN Community
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
@ -45,7 +45,7 @@ module.exports.get = async function(req, res){
//if we have previous attempts for this user
if(attempts != null){
if(attempts.count > sessionUtils.maxAttempts){
return res.render('lockedAccount', {instance: config.instanceName, links: config.links, user: req.session.user, csrfToken: csrfUtils.generateToken(req)});
return res.render('lockedAccount', {instance: config.instanceName, user: req.session.user, csrfToken: csrfUtils.generateToken(req)});
}
//If the users login's are being throttled
@ -56,16 +56,16 @@ module.exports.get = async function(req, res){
const challenge = await altchaUtils.genCaptcha(difficulty, user);
//Render page
return res.render('login', {instance: config.instanceName, links: config.links, user: req.session.user, challenge, csrfToken: csrfUtils.generateToken(req)});
return res.render('login', {instance: config.instanceName, user: req.session.user, challenge, csrfToken: csrfUtils.generateToken(req)});
}
//otherwise
}else{
//Render generic page
return res.render('login', {instance: config.instanceName, links: config.links, user: req.session.user, challenge: null, csrfToken: csrfUtils.generateToken(req)});
return res.render('login', {instance: config.instanceName, user: req.session.user, challenge: null, csrfToken: csrfUtils.generateToken(req)});
}
//if we received invalid input
}else{
//Render pretend nothing happened, send out a generic page
return res.render('login', {instance: config.instanceName, links: config.links, user: req.session.user, challenge: null, csrfToken: csrfUtils.generateToken(req)});
return res.render('login', {instance: config.instanceName, user: req.session.user, challenge: null, csrfToken: csrfUtils.generateToken(req)});
}
}

View file

@ -1,5 +1,5 @@
/*Canopy - The next generation of stoner streaming software
Copyright (C) 2024-2026 Rainbownapkin and the TTN Community
Copyright (C) 2024-2025 Rainbownapkin and the TTN Community
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
@ -27,5 +27,5 @@ module.exports.get = async function(req, res){
const challenge = await altchaUtils.genCaptcha();
//Render page
return res.render('migrate', {instance: config.instanceName, links: config.links, user: req.session.user, challenge, csrfToken: csrfUtils.generateToken(req)});
return res.render('migrate', {instance: config.instanceName, user: req.session.user, challenge, csrfToken: csrfUtils.generateToken(req)});
}

View file

@ -1,5 +1,5 @@
/*Canopy - The next generation of stoner streaming software
Copyright (C) 2024-2026 Rainbownapkin and the TTN Community
Copyright (C) 2024-2025 Rainbownapkin and the TTN Community
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
@ -27,5 +27,5 @@ module.exports.get = async function(req, res){
const challenge = await altchaUtils.genCaptcha();
//render the page
return res.render('newChannel', {instance: config.instanceName, links: config.links, user: req.session.user, challenge, csrfToken: csrfUtils.generateToken(req)});
return res.render('newChannel', {instance: config.instanceName, user: req.session.user, challenge, csrfToken: csrfUtils.generateToken(req)});
}

View file

@ -1,5 +1,5 @@
/*Canopy - The next generation of stoner streaming software
Copyright (C) 2024-2026 Rainbownapkin and the TTN Community
Copyright (C) 2024-2025 Rainbownapkin and the TTN Community
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as

View file

@ -1,5 +1,5 @@
/*Canopy - The next generation of stoner streaming software
Copyright (C) 2024-2026 Rainbownapkin and the TTN Community
Copyright (C) 2024-2025 Rainbownapkin and the TTN Community
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as

View file

@ -1,5 +1,5 @@
/*Canopy - The next generation of stoner streaming software
Copyright (C) 2024-2026 Rainbownapkin and the TTN Community
Copyright (C) 2024-2025 Rainbownapkin and the TTN Community
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as

View file

@ -1,5 +1,5 @@
/*Canopy - The next generation of stoner streaming software
Copyright (C) 2024-2026 Rainbownapkin and the TTN Community
Copyright (C) 2024-2025 Rainbownapkin and the TTN Community
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
@ -19,5 +19,5 @@ const config = require('../../../config.json');
//popout panel container functions
module.exports.get = async function(req, res){
res.render('popoutContainer', {instance: config.instanceName, links: config.links});
res.render('popoutContainer', {instance: config.instanceName});
}

View file

@ -1,5 +1,5 @@
/*Canopy - The next generation of stoner streaming software
Copyright (C) 2024-2026 Rainbownapkin and the TTN Community
Copyright (C) 2024-2025 Rainbownapkin and the TTN Community
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as

View file

@ -1,5 +1,5 @@
/*Canopy - The next generation of stoner streaming software
Copyright (C) 2024-2026 Rainbownapkin and the TTN Community
Copyright (C) 2024-2025 Rainbownapkin and the TTN Community
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as

View file

@ -1,5 +1,5 @@
/*Canopy - The next generation of stoner streaming software
Copyright (C) 2024-2026 Rainbownapkin and the TTN Community
Copyright (C) 2024-2025 Rainbownapkin and the TTN Community
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as

View file

@ -1,5 +1,5 @@
/*Canopy - The next generation of stoner streaming software
Copyright (C) 2024-2026 Rainbownapkin and the TTN Community
Copyright (C) 2024-2025 Rainbownapkin and the TTN Community
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
@ -47,11 +47,11 @@ module.exports.get = async function(req, res){
*/
//Render page
return res.render('passwordReset', {instance: config.instanceName, links: config.links, user: req.session.user, challenge, token, csrfToken: csrfUtils.generateToken(req)});
return res.render('passwordReset', {instance: config.instanceName, user: req.session.user, challenge, token, csrfToken: csrfUtils.generateToken(req)});
//If we didn't get a valid token
}else{
//otherwise render generic page
return res.render('passwordReset', {instance: config.instanceName, links: config.links, user: req.session.user, challenge, token: null, csrfToken: csrfUtils.generateToken(req)});
return res.render('passwordReset', {instance: config.instanceName, user: req.session.user, challenge, token: null, csrfToken: csrfUtils.generateToken(req)});
}
}catch(err){
return exceptionHandler(res, err);

View file

@ -1,5 +1,5 @@
/*Canopy - The next generation of stoner streaming software
Copyright (C) 2024-2026 Rainbownapkin and the TTN Community
Copyright (C) 2024-2025 Rainbownapkin and the TTN Community
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
@ -42,7 +42,7 @@ module.exports.get = async function(req, res){
const presence = await presenceUtils.getPresence(profile.user);
res.render('profile', {
instance: config.instanceName, links: config.links,
instance: config.instanceName,
user: req.session.user,
profile,
selfProfile,
@ -52,7 +52,7 @@ module.exports.get = async function(req, res){
});
}else{
res.render('profile', {
instance: config.instanceName, links: config.links,
instance: config.instanceName,
user: req.session.user,
profile: null,
selfProfile: false,

View file

@ -1,5 +1,5 @@
/*Canopy - The next generation of stoner streaming software
Copyright (C) 2024-2026 Rainbownapkin and the TTN Community
Copyright (C) 2024-2025 Rainbownapkin and the TTN Community
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
@ -27,5 +27,5 @@ module.exports.get = async function(req, res){
const challenge = await altchaUtils.genCaptcha();
//Render page
return res.render('register', {instance: config.instanceName, links: config.links, user: req.session.user, challenge, csrfToken: csrfUtils.generateToken(req)});
return res.render('register', {instance: config.instanceName, user: req.session.user, challenge, csrfToken: csrfUtils.generateToken(req)});
}

View file

@ -1,5 +1,5 @@
/*Canopy - The next generation of stoner streaming software
Copyright (C) 2024-2026 Rainbownapkin and the TTN Community
Copyright (C) 2024-2025 Rainbownapkin and the TTN Community
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as

View file

@ -1,5 +1,5 @@
/*Canopy - The next generation of stoner streaming software
Copyright (C) 2024-2026 Rainbownapkin and the TTN Community
Copyright (C) 2024-2025 Rainbownapkin and the TTN Community
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as

View file

@ -1,5 +1,5 @@
/*Canopy - The next generation of stoner streaming software
Copyright (C) 2024-2026 Rainbownapkin and the TTN Community
Copyright (C) 2024-2025 Rainbownapkin and the TTN Community
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as

View file

@ -1,5 +1,5 @@
/*Canopy - The next generation of stoner streaming software
Copyright (C) 2024-2026 Rainbownapkin and the TTN Community
Copyright (C) 2024-2025 Rainbownapkin and the TTN Community
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as

View file

@ -1,5 +1,5 @@
/*Canopy - The next generation of stoner streaming software
Copyright (C) 2024-2026 Rainbownapkin and the TTN Community
Copyright (C) 2024-2025 Rainbownapkin and the TTN Community
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as

View file

@ -1,5 +1,5 @@
/*Canopy - The next generation of stoner streaming software
Copyright (C) 2024-2026 Rainbownapkin and the TTN Community
Copyright (C) 2024-2025 Rainbownapkin and the TTN Community
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as

View file

@ -1,5 +1,5 @@
/*Canopy - The next generation of stoner streaming software
Copyright (C) 2024-2026 Rainbownapkin and the TTN Community
Copyright (C) 2024-2025 Rainbownapkin and the TTN Community
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as

View file

@ -1,5 +1,5 @@
/*Canopy - The next generation of stoner streaming software
Copyright (C) 2024-2026 Rainbownapkin and the TTN Community
Copyright (C) 2024-2025 Rainbownapkin and the TTN Community
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as

View file

@ -1,5 +1,5 @@
/*Canopy - The next generation of stoner streaming software
Copyright (C) 2024-2026 Rainbownapkin and the TTN Community
Copyright (C) 2024-2025 Rainbownapkin and the TTN Community
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as

View file

@ -1,5 +1,5 @@
/*Canopy - The next generation of stoner streaming software
Copyright (C) 2024-2026 Rainbownapkin and the TTN Community
Copyright (C) 2024-2025 Rainbownapkin and the TTN Community
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as

View file

@ -1,34 +0,0 @@
/*Canopy - The next generation of stoner streaming software
Copyright (C) 2024-2026 Rainbownapkin and the TTN Community
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.*/
//npm imports
const { Router } = require('express');
//local imports
const hrtController = require("../controllers/hrtController");
const presenceUtils = require("../utils/presenceUtils");
//globals
const router = Router();
//Use presence middleware
router.use(presenceUtils.presenceMiddleware);
//routing functions
router.get('/', hrtController.get);
module.exports = router;

View file

@ -1,5 +1,5 @@
/*Canopy - The next generation of stoner streaming software
Copyright (C) 2024-2026 Rainbownapkin and the TTN Community
Copyright (C) 2024-2025 Rainbownapkin and the TTN Community
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as

View file

@ -1,5 +1,5 @@
/*Canopy - The next generation of stoner streaming software
Copyright (C) 2024-2026 Rainbownapkin and the TTN Community
Copyright (C) 2024-2025 Rainbownapkin and the TTN Community
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as

View file

@ -1,5 +1,5 @@
/*Canopy - The next generation of stoner streaming software
Copyright (C) 2024-2026 Rainbownapkin and the TTN Community
Copyright (C) 2024-2025 Rainbownapkin and the TTN Community
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as

View file

@ -1,5 +1,5 @@
/*Canopy - The next generation of stoner streaming software
Copyright (C) 2024-2026 Rainbownapkin and the TTN Community
Copyright (C) 2024-2025 Rainbownapkin and the TTN Community
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as

View file

@ -1,5 +1,5 @@
/*Canopy - The next generation of stoner streaming software
Copyright (C) 2024-2026 Rainbownapkin and the TTN Community
Copyright (C) 2024-2025 Rainbownapkin and the TTN Community
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as

View file

@ -1,5 +1,5 @@
/*Canopy - The next generation of stoner streaming software
Copyright (C) 2024-2026 Rainbownapkin and the TTN Community
Copyright (C) 2024-2025 Rainbownapkin and the TTN Community
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as

View file

@ -1,5 +1,5 @@
/*Canopy - The next generation of stoner streaming software
Copyright (C) 2024-2026 Rainbownapkin and the TTN Community
Copyright (C) 2024-2025 Rainbownapkin and the TTN Community
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as

View file

@ -1,5 +1,5 @@
/*Canopy - The next generation of stoner streaming software
Copyright (C) 2024-2026 Rainbownapkin and the TTN Community
Copyright (C) 2024-2025 Rainbownapkin and the TTN Community
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as

View file

@ -1,5 +1,5 @@
/*Canopy - The next generation of stoner streaming software
Copyright (C) 2024-2026 Rainbownapkin and the TTN Community
Copyright (C) 2024-2025 Rainbownapkin and the TTN Community
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as

View file

@ -1,5 +1,5 @@
/*Canopy - The next generation of stoner streaming software
Copyright (C) 2024-2026 Rainbownapkin and the TTN Community
Copyright (C) 2024-2025 Rainbownapkin and the TTN Community
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as

View file

@ -1,5 +1,5 @@
/*Canopy - The next generation of stoner streaming software
Copyright (C) 2024-2026 Rainbownapkin and the TTN Community
Copyright (C) 2024-2025 Rainbownapkin and the TTN Community
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as

View file

@ -1,5 +1,5 @@
/*Canopy - The next generation of stoner streaming software
Copyright (C) 2024-2026 Rainbownapkin and the TTN Community
Copyright (C) 2024-2025 Rainbownapkin and the TTN Community
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
@ -30,7 +30,7 @@ const emoteModel = require('../emoteSchema');
const channelPermissionSchema = require('./channelPermissionSchema');
const channelBanSchema = require('./channelBanSchema');
const queuedMediaSchema = require('./media/queuedMediaSchema');
const {playlistSchema} = require('./media/playlist/playlistSchema');
const playlistSchema = require('./media/playlistSchema');
const chatSchema = require('./chatSchema');
//Utils
const { exceptionHandler, errorHandler } = require('../../utils/loggerUtils');
@ -666,6 +666,77 @@ channelSchema.methods.getEmotes = function(){
return emoteList;
}
/**
* Generates Network-Friendly Browser-Digestable list of channel playlists
* @returns {Array} Network-Friendly Browser-Digestable list of channel playlists
*/
channelSchema.methods.getPlaylists = function(){
//Create an empty array to hold our emote list
const playlists = [];
//For each channel emote
for(let playlist of this.media.playlists){
//Push an object with select information from the emote to the emote list
playlists.push(playlist.dehydrate());
}
//return the emote list
return playlists;
}
/**
* Crawls through channel playlists, running a given callback function against each one
* @param {Function} cb - Callback function to run against channel playlists
*/
channelSchema.methods.playlistCrawl = function(cb){
for(let listIndex in this.media.playlists){
//Grab the associated playlist
playlist = this.media.playlists[listIndex];
//Call the callback with the playlist and list index as arguments
cb(playlist, listIndex);
}
}
/**
* Finds channel playlist by playlist name
* @param {String} name - name of given playlist to find
* @returns {Mongoose.Document} - Sub-Document representing a single playlist
*/
channelSchema.methods.getPlaylistByName = function(name){
//Create null value to hold our found playlist
let foundPlaylist = null;
//Crawl through active playlists
this.playlistCrawl((playlist, listIndex) => {
//If we found a match based on name
if(playlist.name == name){
//Keep it
foundPlaylist = playlist;
//Pass down the list index
foundPlaylist.listIndex = listIndex;
}
});
//return the given playlist
return foundPlaylist;
}
/**
* Deletes channel playlist by playlist name
* @param {String} name - name of given playlist to Delete
*/
channelSchema.methods.deletePlaylistByName = async function(name){
//Find the playlist
let playlist = this.getPlaylistByName(name);
//splice out the given playlist
this.media.playlists.splice(playlist.listIndex, 1);
//save the channel document
await this.save();
}
/**
* Generates Network-Friendly Browser-Digestable list of Channel-Wide user bans
* @returns {Array} Network-Friendly Browser-Digestable list of Channel-Wide user bans

Some files were not shown because too many files have changed in this diff Show more