Compare commits

..

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

14 changed files with 34 additions and 81 deletions

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://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> <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.1-Alpha 0.4-INDEV
========= =========
Canopy - /ˈkæ.nə.pi/: Canopy - /ˈkæ.nə.pi/:

View file

@ -1,7 +1,6 @@
{ {
"name": "canopy-of-alpha", "name": "canopy-of-indev",
"version": "0.1", "version": "0.4",
"canopyDisplayVersion": "0.1-Alpha",
"license": "AGPL-3.0-only", "license": "AGPL-3.0-only",
"dependencies": { "dependencies": {
"@braintree/sanitize-url": "^7.1.1", "@braintree/sanitize-url": "^7.1.1",

View file

@ -16,7 +16,6 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.*/
//Config //Config
const config = require('../../config.json'); const config = require('../../config.json');
const package = require('../../package.json');
//Local Imports //Local Imports
const csrfUtils = require('../utils/csrfUtils'); const csrfUtils = require('../utils/csrfUtils');
@ -24,5 +23,5 @@ const csrfUtils = require('../utils/csrfUtils');
//register page functions //register page functions
module.exports.get = async function(req, res){ module.exports.get = async function(req, res){
//Render page //Render page
return res.render('about', {aboutText: config.aboutText, instance: config.instanceName, 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

@ -33,14 +33,17 @@ module.exports.post = async function(req, res){
const data = matchedData(req); const data = matchedData(req);
//make sure we're not bullshitting ourselves here. //make sure we're not bullshitting ourselves here.
if(user == null || user.user == null){ if(user == null){
return errorHandler(res, 'You must be logged in to delete your account!', 'unauthorized'); res.status(400);
return res.send('Invalid Session! Cannot delete account while logged out!');
} }
const userDB = await userModel.findOne({user: user.user}); const userDB = await userModel.findOne(user);
if(!userDB){ if(!userDB){
return errorHandler(res, 'User not found!', 'unauthorized'); res.status(400);
return res.send('Invalid User! Account must exist in order to delete!');
} }
await userDB.nuke(data.pass); await userDB.nuke(data.pass);

View file

@ -46,13 +46,7 @@ module.exports.post = async function(req, res){
const {field, change} = data; const {field, change} = data;
const {user} = req.session; const {user} = req.session;
//If the user is null const userDB = await userModel.findOne(user);
if(user == null || user.user == null){
//BEFORE YOU BREAK MY HEART!!!
return errorHandler(res, 'You must be logged in to preform this action!', 'unauthorized');
}
const userDB = await userModel.findOne({user: user.user});
const update = {}; const update = {};
@ -92,7 +86,8 @@ module.exports.post = async function(req, res){
res.status(200); res.status(200);
return res.send(update); return res.send(update);
}else{ }else{
return errorHandler(res, 'User not found!', 'unauthorized'); res.status(400);
return res.send({errors: [{msg:"User not found!"}]});
} }
}else{ }else{
res.status(400); res.status(400);

View file

@ -51,11 +51,8 @@ const emoteSchema = new mongoose.Schema({
* Post-Save function, ensures all new emotes are broadcastes to actively connected clients * Post-Save function, ensures all new emotes are broadcastes to actively connected clients
*/ */
emoteSchema.post('save', async function (next){ emoteSchema.post('save', async function (next){
//Ensure the channel manager is actually up //broadcast updated emotes
if(server.channelManager != null){ server.channelManager.broadcastSiteEmotes();
//broadcast updated emotes
server.channelManager.broadcastSiteEmotes();
}
}); });
/** /**

View file

@ -36,20 +36,15 @@ const tokeCommandSchema = new mongoose.Schema({
* Pre-Save middleware, ensures tokebot receives all new toke commands * Pre-Save middleware, ensures tokebot receives all new toke commands
*/ */
tokeCommandSchema.pre('save', async function (next){ tokeCommandSchema.pre('save', async function (next){
//if the channel manager, chat handler, and chat post-processor are all loaded up... //if the command was changed
if(this.isModified("command")){ if(this.isModified("command")){
if(server.channelManager != null && //Get server tokebot object
server.channelManager.chatHandler != null && const tokebot = server.channelManager.chatHandler.chatPreprocessor.tokebot;
server.channelManager.chatHandler.chatPreprocessor != null){
//Get server tokebot object //If tokebot is up and running
const tokebot = server.channelManager.chatHandler.chatPreprocessor.tokebot; if(tokebot != null && tokebot.tokeCommands != null){
//Pop the command on to the end
//If tokebot is up and running tokebot.tokeCommands.push(this.command);
if(tokebot != null && tokebot.tokeCommands != null){
//Pop the command on to the end
tokebot.tokeCommands.push(this.command);
}
} }
} }

View file

@ -217,22 +217,13 @@ migrationSchema.statics.ingestLegacyUser = async function(rawProfile){
return; return;
} }
//Pull rank, dropping over-ranked users down to current enum length
let rank = Math.min(Math.max(0, profileArray[3]), permissionModel.rankEnum.length - 1);
//If this user was a mod on the old site
if(rank == 2){
//Set them up as a mod here
rank = permissionModel.rankEnum.length - 2;
}
//Create migration profile object from scraped info //Create migration profile object from scraped info
const migrationProfile = new this({ const migrationProfile = new this({
user: profileArray[1], user: profileArray[1],
pass: profileArray[2], pass: profileArray[2],
//Clamp rank to 0 and the max setting allowed by the rank enum //Clamp rank to 0 and the max setting allowed by the rank enum
rank, rank: Math.min(Math.max(0, profileArray[3]), permissionModel.rankEnum.length - 1),
email: validator.normalizeEmail(profileArray[4]), email: validator.normalizeEmail(profileArray[4]),
date: profileArray[7], date: profileArray[7],
}) })

View file

@ -75,7 +75,6 @@ const apiRouter = require('./routers/apiRouter');
//Define Config variables //Define Config variables
const config = require('../config.json'); const config = require('../config.json');
const package = require('../package.json');
const port = config.port; const port = config.port;
const dbUrl = `mongodb://${config.db.user}:${config.db.pass}@${config.db.address}:${config.db.port}/${config.db.database}`; const dbUrl = `mongodb://${config.db.user}:${config.db.pass}@${config.db.address}:${config.db.port}/${config.db.database}`;
@ -209,7 +208,7 @@ Might be better if she kicked off everything at once, and ran a while loop to ch
This runs once at server startup, and most startups will run fairly quickly so... Not worth it?*/ This runs once at server startup, and most startups will run fairly quickly so... Not worth it?*/
async function asyncKickStart(){ async function asyncKickStart(){
//Lettum fuckin' know wassup //Lettum fuckin' know wassup
console.log(`${config.instanceName}(Powered by Canopy ${package.canopyDisplayVersion}) is booting up!`); console.log(`${config.instanceName}(Powered by Canopy) is booting up!`);
//Run legacy migration //Run legacy migration
await migrationModel.ingestLegacyDump(); await migrationModel.ingestLegacyDump();

View file

@ -40,8 +40,6 @@ along with this program. If not, see <https://www.gnu.org/licenses/>. %>
it was decided that the original cytube fork, fore.st, had been run past it's prime. In summer/fall 2024, work began on a it was decided that the original cytube fork, fore.st, had been run past it's prime. In summer/fall 2024, work began on a
replacement. The resulting software became <a href="https://git.ourfore.st/rainbownapkin/canopy">Canopy</a>, which was replacement. The resulting software became <a href="https://git.ourfore.st/rainbownapkin/canopy">Canopy</a>, which was
first used to run the ourfore.st instance in late 2025.</p> first used to run the ourfore.st instance in late 2025.</p>
<br>
<h2>Canopy Ver: <%= version %></h2>
</div> </div>
</div> </div>
</body> </body>

View file

@ -337,16 +337,13 @@ function onYouTubeIframeAPIReady(){
//Set embed api to true //Set embed api to true
client.ytEmbedAPILoaded = true; client.ytEmbedAPILoaded = true;
//If the player is ready and has a mediaHandler loaded //Get currently playing item
if(client.player != null && client.player.mediaHandler != null){ const nowPlaying = client.player.mediaHandler.nowPlaying;
//Get currently playing item
const nowPlaying = client.player.mediaHandler.nowPlaying;
//If we're playing a youtube video and the official embeds are enabled //If we're playing a youtube video and the official embeds are enabled
if(nowPlaying.type == 'yt' && localStorage.getItem('ytPlayerType') == "embed"){ if(nowPlaying.type == 'yt' && localStorage.getItem('ytPlayerType') == "embed"){
//Restart the video now that the embed api has loaded //Restart the video now that the embed api has loaded
client.player.start({media: nowPlaying}); client.player.start({media: nowPlaying});
}
} }
} }

View file

@ -907,10 +907,6 @@ class hlsLiveStreamHandler extends hlsBase{
return; return;
} }
//Resize chat box to video aspect, since this is the only event thats reliably called on ratio change
//Re-enforcing UX rules a little more often shouldnt cause too many issues anywho.
this.client.chatBox.resizeAspect();
//Calculate distance to end of stream //Calculate distance to end of stream
const difference = this.video.duration - this.video.currentTime; const difference = this.video.duration - this.video.currentTime;

View file

@ -24,7 +24,7 @@ class pmPanel extends panelObj{
* @param {channel} client - Parent client Management Object * @param {channel} client - Parent client Management Object
* @param {Document} panelDocument - Panel Document * @param {Document} panelDocument - Panel Document
*/ */
constructor(client, panelDocument, startSesh){ constructor(client, panelDocument){
super(client, "Private Messaging", "/panel/pm", panelDocument); super(client, "Private Messaging", "/panel/pm", panelDocument);
/** /**
@ -71,17 +71,7 @@ class pmPanel extends panelObj{
//Tell PMHandler to start tracking this panel //Tell PMHandler to start tracking this panel
this.client.pmHandler.panelList.set(this.uuid, null); this.client.pmHandler.panelList.set(this.uuid, null);
//Define network related listeners
this.defineListeners(); this.defineListeners();
//If a start sesh was provided
if(startSesh != null && startSesh != ""){
//Send message out to server
this.client.pmSocket.emit("pm", {
recipients: startSesh.split(" "),
msg: ""
});
}
} }
closer(){ closer(){
@ -136,6 +126,7 @@ class pmPanel extends panelObj{
this.seshSendButton.addEventListener("click", this.send.bind(this)); this.seshSendButton.addEventListener("click", this.send.bind(this));
this.seshBuffer.addEventListener('scroll', this.scrollHandler.bind(this)); this.seshBuffer.addEventListener('scroll', this.scrollHandler.bind(this));
this.ownerDoc.defaultView.addEventListener('resize', this.handleAutoScroll.bind(this)); this.ownerDoc.defaultView.addEventListener('resize', this.handleAutoScroll.bind(this));
} }
startSesh(event){ startSesh(event){
@ -189,12 +180,6 @@ class pmPanel extends panelObj{
* Render out current sesh array to sesh list UI * Render out current sesh array to sesh list UI
*/ */
renderSeshList(){ renderSeshList(){
//If we don't have a sesh list
if(this.seshList == null){
//Fuck off, you're not even done building the object yet.
return;
}
//Clear out the sesh list //Clear out the sesh list
this.seshList.innerHTML = ""; this.seshList.innerHTML = "";

View file

@ -173,8 +173,7 @@ class userList{
function renderContextMenu(event){ function renderContextMenu(event){
//Setup menu map //Setup menu map
let menuMap = new Map([ let menuMap = new Map([
["Profile", ()=>{this.client.cPanel.setActivePanel(new panelObj(this.client, user.user, `/panel/profile?user=${user.user}`))}], ["Profile", ()=>{this.client.cPanel.setActivePanel(new panelObj(this.client, `${user.user}`, `/panel/profile?user=${user.user}`))}],
["PM", ()=>{this.client.cPanel.setActivePanel(new pmPanel(client, undefined, user.user))}],
["Mention", ()=>{this.client.chatBox.catChat(`${user.user} `)}], ["Mention", ()=>{this.client.chatBox.catChat(`${user.user} `)}],
["Toke With", ()=>{this.client.chatBox.tokeWith(user.user)}], ["Toke With", ()=>{this.client.chatBox.tokeWith(user.user)}],
]); ]);