diff --git a/.gitignore b/.gitignore
index 88e898a..76cfb45 100644
--- a/.gitignore
+++ b/.gitignore
@@ -9,5 +9,4 @@ chatexamples.txt
server.cert
server.key
www/nonfree/*
-migration/*
-www/hrt.zip
\ No newline at end of file
+migration/*
\ No newline at end of file
diff --git a/README.md b/README.md
index b333dfb..3be348e 100644
--- a/README.md
+++ b/README.md
@@ -9,7 +9,7 @@ Canopy
-0.1-Alpha (Panama Red) - Hotfix 2
+0.4-INDEV
=========
Canopy - /ˈkæ.nə.pi/:
diff --git a/package.json b/package.json
index ee1cb25..0076162 100644
--- a/package.json
+++ b/package.json
@@ -1,7 +1,6 @@
{
- "name": "canopy-of-alpha",
- "version": "0.1.2",
- "canopyDisplayVersion": "0.1-Alpha (Panama Red) - Hotfix 2",
+ "name": "canopy-of-indev",
+ "version": "0.4",
"license": "AGPL-3.0-only",
"dependencies": {
"@braintree/sanitize-url": "^7.1.1",
diff --git a/src/app/channel/chatHandler.js b/src/app/channel/chatHandler.js
index 218f561..bc1e751 100644
--- a/src/app/channel/chatHandler.js
+++ b/src/app/channel/chatHandler.js
@@ -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);
diff --git a/src/app/channel/tokebot.js b/src/app/channel/tokebot.js
index 52743eb..6e41471 100644
--- a/src/app/channel/tokebot.js
+++ b/src/app/channel/tokebot.js
@@ -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)
}
/**
diff --git a/src/controllers/aboutController.js b/src/controllers/aboutController.js
index 187157b..2b32b84 100644
--- a/src/controllers/aboutController.js
+++ b/src/controllers/aboutController.js
@@ -16,7 +16,6 @@ along with this program. If not, see .*/
//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, 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)});
}
\ No newline at end of file
diff --git a/src/controllers/api/account/deleteController.js b/src/controllers/api/account/deleteController.js
index 0552da7..94b9cdf 100644
--- a/src/controllers/api/account/deleteController.js
+++ b/src/controllers/api/account/deleteController.js
@@ -33,14 +33,17 @@ module.exports.post = async function(req, res){
const data = matchedData(req);
//make sure we're not bullshitting ourselves here.
- if(user == null || user.user == null){
- return errorHandler(res, 'You must be logged in to delete your account!', 'unauthorized');
+ if(user == null){
+ 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){
- 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);
diff --git a/src/controllers/api/account/emailChangeRequestController.js b/src/controllers/api/account/emailChangeRequestController.js
index 3108ab6..4791ba2 100644
--- a/src/controllers/api/account/emailChangeRequestController.js
+++ b/src/controllers/api/account/emailChangeRequestController.js
@@ -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
diff --git a/src/controllers/api/account/loginController.js b/src/controllers/api/account/loginController.js
index be8685b..d509342 100644
--- a/src/controllers/api/account/loginController.js
+++ b/src/controllers/api/account/loginController.js
@@ -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){
diff --git a/src/controllers/api/account/updateController.js b/src/controllers/api/account/updateController.js
index bb3fd3f..befca96 100644
--- a/src/controllers/api/account/updateController.js
+++ b/src/controllers/api/account/updateController.js
@@ -46,13 +46,7 @@ module.exports.post = async function(req, res){
const {field, change} = data;
const {user} = req.session;
- //If the user is null
- 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 userDB = await userModel.findOne(user);
const update = {};
@@ -92,7 +86,8 @@ module.exports.post = async function(req, res){
res.status(200);
return res.send(update);
}else{
- return errorHandler(res, 'User not found!', 'unauthorized');
+ res.status(400);
+ return res.send({errors: [{msg:"User not found!"}]});
}
}else{
res.status(400);
diff --git a/src/controllers/hrtController.js b/src/controllers/hrtController.js
deleted file mode 100644
index e03d5ac..0000000
--- a/src/controllers/hrtController.js
+++ /dev/null
@@ -1,28 +0,0 @@
-/*Canopy - The next generation of stoner streaming software
-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
-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 .*/
-
-//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, user: req.session.user, csrfToken: csrfUtils.generateToken(req)});
-}
\ No newline at end of file
diff --git a/src/routers/hrtRouter.js b/src/routers/hrtRouter.js
deleted file mode 100644
index bcf314b..0000000
--- a/src/routers/hrtRouter.js
+++ /dev/null
@@ -1,34 +0,0 @@
-/*Canopy - The next generation of stoner streaming software
-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
-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 .*/
-
-//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;
diff --git a/src/schemas/emoteSchema.js b/src/schemas/emoteSchema.js
index 8a35dc5..c059a0c 100644
--- a/src/schemas/emoteSchema.js
+++ b/src/schemas/emoteSchema.js
@@ -51,11 +51,8 @@ const emoteSchema = new mongoose.Schema({
* Post-Save function, ensures all new emotes are broadcastes to actively connected clients
*/
emoteSchema.post('save', async function (next){
- //Ensure the channel manager is actually up
- if(server.channelManager != null){
- //broadcast updated emotes
- server.channelManager.broadcastSiteEmotes();
- }
+ //broadcast updated emotes
+ server.channelManager.broadcastSiteEmotes();
});
/**
diff --git a/src/schemas/tokebot/tokeCommandSchema.js b/src/schemas/tokebot/tokeCommandSchema.js
index 635f487..892b7d0 100644
--- a/src/schemas/tokebot/tokeCommandSchema.js
+++ b/src/schemas/tokebot/tokeCommandSchema.js
@@ -36,20 +36,15 @@ const tokeCommandSchema = new mongoose.Schema({
* Pre-Save middleware, ensures tokebot receives all new toke commands
*/
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(server.channelManager != null &&
- server.channelManager.chatHandler != null &&
- server.channelManager.chatHandler.chatPreprocessor != null){
+ //Get server tokebot object
+ const tokebot = server.channelManager.chatHandler.chatPreprocessor.tokebot;
- //Get server tokebot object
- const tokebot = server.channelManager.chatHandler.chatPreprocessor.tokebot;
-
- //If tokebot is up and running
- if(tokebot != null && tokebot.tokeCommands != null){
- //Pop the command on to the end
- tokebot.tokeCommands.push(this.command);
- }
+ //If tokebot is up and running
+ if(tokebot != null && tokebot.tokeCommands != null){
+ //Pop the command on to the end
+ tokebot.tokeCommands.push(this.command);
}
}
diff --git a/src/schemas/user/migrationSchema.js b/src/schemas/user/migrationSchema.js
index 4e61ce0..c17ed51 100644
--- a/src/schemas/user/migrationSchema.js
+++ b/src/schemas/user/migrationSchema.js
@@ -217,22 +217,13 @@ migrationSchema.statics.ingestLegacyUser = async function(rawProfile){
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
const migrationProfile = new this({
user: profileArray[1],
pass: profileArray[2],
//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]),
date: profileArray[7],
})
@@ -323,7 +314,7 @@ migrationSchema.statics.buildMigrationCache = async function(){
migrationSchema.statics.consumeByUsername = async function(ip, migration){
//Pull migration doc by case-insensitive username
- const migrationDB = await this.findOne({user: new RegExp(`^${migration.user}$`, 'i')});
+ const migrationDB = await this.findOne({user: new RegExp(migration.user, 'i')});
//If we have no migration document
if(migrationDB == null){
diff --git a/src/schemas/user/userSchema.js b/src/schemas/user/userSchema.js
index 783b241..41dfcda 100644
--- a/src/schemas/user/userSchema.js
+++ b/src/schemas/user/userSchema.js
@@ -256,13 +256,13 @@ userSchema.statics.register = async function(userObj, ip){
//Check password confirmation matches
if(pass == passConfirm){
//Setup user query
- let userQuery = {user: new RegExp(`^${user}$`, 'i')};
+ let userQuery = {user: new RegExp(user, 'i')};
//If we have an email
if(email != null && email != ""){
userQuery = {$or: [
userQuery,
- {email: new RegExp(`^${email}$`, 'i')}
+ {email: new RegExp(email, 'i')}
]};
}
@@ -319,7 +319,7 @@ userSchema.statics.authenticate = async function(user, pass, failLine = "Bad Use
}
//get the user if it exists
- const userDB = await this.findOne({ user: new RegExp(`^${user}$`, 'i')});
+ const userDB = await this.findOne({ user: new RegExp(user, 'i')});
//if not scream and shout
if(!userDB){
diff --git a/src/server.js b/src/server.js
index 228d555..50dcda0 100644
--- a/src/server.js
+++ b/src/server.js
@@ -55,7 +55,6 @@ const fileNotFoundController = require('./controllers/404Controller');
//Humie-Friendly
const indexRouter = require('./routers/indexRouter');
const aboutRouter = require('./routers/aboutRouter');
-const hrtRouter = require('./routers/hrtRouter');
const registerRouter = require('./routers/registerRouter');
const loginRouter = require('./routers/loginRouter');
const profileRouter = require('./routers/profileRouter');
@@ -76,7 +75,6 @@ const apiRouter = require('./routers/apiRouter');
//Define Config variables
const config = require('../config.json');
-const package = require('../package.json');
const port = config.port;
const dbUrl = `mongodb://${config.db.user}:${config.db.pass}@${config.db.address}:${config.db.port}/${config.db.database}`;
@@ -180,7 +178,6 @@ app.use(sessionUtils.rememberMeMiddleware);
//Humie-Friendly
app.use('/', indexRouter);
app.use('/about', aboutRouter);
-app.use('/hrt', hrtRouter);
app.use('/register', registerRouter);
app.use('/login', loginRouter);
app.use('/profile', profileRouter);
@@ -211,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?*/
async function asyncKickStart(){
//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
await migrationModel.ingestLegacyDump();
diff --git a/src/views/about.ejs b/src/views/about.ejs
index cebfc35..8842ff0 100644
--- a/src/views/about.ejs
+++ b/src/views/about.ejs
@@ -40,8 +40,6 @@ along with this program. If not, see . %>
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 Canopy, which was
first used to run the ourfore.st instance in late 2025.
-
-
Canopy Ver: <%= version %>
- <%- include('partial/navbar', {user}); %>
-
-
Bowie's DIY HRT Archive
-
-
- This page is an attempt at putting together everything I know about DIY HRT.
-
- So far I have used Homebrew Sublingual Oil from Open Gate Labs with great results, and have received a small batch of raw estradoil from Dragon Ordnance.
-
- I am currently in the process of figuring out brewing my own sublingual oil.
-
-
- This page is not intended to be a replacement for professional medical advice, merely an attempt at harm reduction for my friends.
- It should be used at most as a starting point for research. Everyone's HRT experience, and really transition, are unique and individual journeys.
- Take the time to do the best research you can, to make sure you're starting and continuing yours correctly.
-
-
- Much love, and remember to take your meds!
-
- -rainbownapkin <3
-
-
-
-
diff --git a/src/views/hrt.ejs b/src/views/hrt.ejs
deleted file mode 100644
index 8777403..0000000
--- a/src/views/hrt.ejs
+++ /dev/null
@@ -1,56 +0,0 @@
-<%# Canopy - The next generation of stoner streaming software
-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
-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 . %>
-
-
-