From 999fae91b7e9f60a842f306a69a7d985164889e3 Mon Sep 17 00:00:00 2001 From: rainbow napkin Date: Sat, 7 Nov 2026 11:17:38 -0500 Subject: [PATCH] Created !ignore command to add users to blocklist, and supporting methods to get and set blocks (and their alts) from DB --- src/app/channel/commandProcessor.js | 23 +++++++ src/schemas/user/userSchema.js | 93 +++++++++++++++++++++++++++++ 2 files changed, 116 insertions(+) diff --git a/src/app/channel/commandProcessor.js b/src/app/channel/commandProcessor.js index 0a157a3..2f6af14 100644 --- a/src/app/channel/commandProcessor.js +++ b/src/app/channel/commandProcessor.js @@ -17,6 +17,7 @@ along with this program. If not, see .*/ //Local Imports const permissionModel = require('../../schemas/permissionSchema'); const channelModel = require('../../schemas/channel/channelSchema'); +const {userModel} = require('../../schemas/user/userSchema'); /** * Class representing global server-side chat/command processing logic @@ -113,6 +114,28 @@ class commandProcessor{ return true } + async ignore(commandObj){ + //If we wherent given a user to ignore + if(commandObj.argumentArray[1] == null){ + //Silently return + return; + } + + //Attempt to find user DB doc object + const userDB = await userModel.findOne({user: commandObj.socket.user.user}); + + //Prevent missing users + if(userDB == null){ + throw loggerUtils.exceptionSmith("Called from invalid user", "validation"); + } + + //ignore user + await userDB.ignoreByUser(commandObj.argumentArray[1]); + + //disable send flag + return false; + } + /** * Command Processor method to handle the '!announce' command * @param {Object} commandObj - Object representing a single given command/chat request diff --git a/src/schemas/user/userSchema.js b/src/schemas/user/userSchema.js index f013a07..b8136dd 100644 --- a/src/schemas/user/userSchema.js +++ b/src/schemas/user/userSchema.js @@ -153,6 +153,10 @@ const userSchema = new mongoose.Schema({ type: mongoose.SchemaTypes.ObjectID, ref: "user" }], + ignored:[{ + type: mongoose.SchemaTypes.ObjectID, + ref: "user", + }], playlists: [playlistSchema] }); @@ -662,6 +666,95 @@ userSchema.methods.deleteEmote = async function(name){ } } +/** + * Ignores a given user by their username + * @param {Mongoose.Document} userDB - DB Document of user to ignore + */ +userSchema.methods.ignoreByUser = async function(user){ + //Pull user doc from DB + const userDB = await this.constructor.findOne({user}); + //Do a ignorem user by username + await this.ignoreByUserDoc(userDB); +} + +/** + * Ignores a given user by their DB Document + * @param {Mongoose.Document} userDB - DB Document of user to ignore + */ +userSchema.methods.ignoreByUserDoc = async function(userDB){ + //Prevent missing users + if(userDB == null){ + throw loggerUtils.exceptionSmith("User not found", "validation"); + } + + if(this.ignored.includes(userDB._id)){ + throw loggerUtils.exceptionSmith("User already ignored", "validation"); + } + + //Push user into ignored array + this.ignored.push(userDB._id); + + //Save the DB document + await this.save(); + + console.log(await this.getIgnoredUsers()); +} + +userSchema.methods.getIgnoredUsers = async function(fetchAlts = true){ + //Not me commiting ancient fucking sin + const _this = this; + + //Populate all ignored users + await this.populate('ignored'); + + //If we're fetching alts + if(fetchAlts){ + //Populate ignored users alts + await this.populate('ignored.alts'); + } + + //Create return object to hold list of DB ids and public user IDs/names + //Code using this method typically only need either/or, so seperating them from da get-go was the easiest option. + const ignored = { + _id: [], + user: [] + } + + //Iterate through all ignored users + for(const ignoredUser of this.ignored){ + //Push user to ignored list + pushToList(ignoredUser); + + //If we're fetching alts + if(fetchAlts){ + //Iterate through ignored users alts + for(const ignoredAlt of ignoredUser.alts){ + //Push alt to ignored list + pushToList(ignoredAlt); + } + } + } + + //Return list of ignored users + return ignored; + + function pushToList(ignoredUser){ + //If we haven't already added this user, and it isn't us + //ignoring our own alts seem silly at first, but remember 1 IP =/= one user. + //VPNs, CGNAT, and even household disagreements all happen in da real world. + if(!ignored._id.includes(ignoredUser._id) && !ignoredUser._id.equals(_this._id)){ + //Push DB _id into list for server-side use + ignored._id.push(ignoredUser._id); + //Push ignored username/outward id combo for client usage + ignored.user.push({ + user: ignoredUser.user, + id: ignoredUser.id + }); + } + } + +} + /** * Salts, Hashes and Tattoo's IP address to user document in a privacy respecting manner * @param {String} ip - Plaintext IP Address to Salt, Hash and Tattoo