Compare commits
No commits in common. "main" and "0.4-indev-hotfix-1" have entirely different histories.
main
...
0.4-indev-
|
|
@ -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 Hotfix 1
|
||||||
=========
|
=========
|
||||||
|
|
||||||
Canopy - /ˈkæ.nə.pi/:
|
Canopy - /ˈkæ.nə.pi/:
|
||||||
|
|
|
||||||
|
|
@ -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",
|
||||||
|
|
|
||||||
|
|
@ -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)});
|
||||||
}
|
}
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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],
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -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();
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
|
|
|
||||||
|
|
@ -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});
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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 = "";
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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)}],
|
||||||
]);
|
]);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue