Finished up with chat prompt autocomplete.

This commit is contained in:
rainbow napkin 2025-01-05 00:05:19 -05:00
parent acbe0400c4
commit 9df7f52e9e
7 changed files with 197 additions and 100 deletions

View file

@ -41,6 +41,8 @@ module.exports = class{
await this.sendSiteEmotes();
await this.sendChanEmotes(chanDB);
await this.sendPersonalEmotes(userDB);
//Send out used tokes
await this.sendUsedTokes(userDB);
//Tattoo hashed IP address to user account for seven days
@ -64,7 +66,12 @@ module.exports = class{
//at the end of the day there has to be some penance for decent multi-session handling on-top of a library that doesn't do it.
//Having to crawl through these sockets is that. Because the other ways seem more gross somehow.
emit(eventName, args){
this.socketCrawl((socket)=>{socket.emit(eventName, args)});
this.socketCrawl((socket)=>{
//Ensure our socket is initialized
if(socket != null){
socket.emit(eventName, args);
}
});
}
//generic disconnect function, defaults to kick
@ -73,11 +80,33 @@ module.exports = class{
this.socketCrawl((socket)=>{socket.disconnect()});
}
async sendClientMetadata(){
//This is the big first push upon connection
//It should only fire once, so things that only need to be sent once can be slapped into here
async sendClientMetadata(userDB, chanDB){
//Get flairList from DB and setup flairList array
const flairListDB = await flairModel.find({});
var flairList = [];
//if we wherent handed a user document
if(userDB == null){
//Pull it based on user name
userDB = await userModel.findOne({user: this.user});
}
//if we wherent handed a channel document
if(chanDB == null){
//Pull it based on channel name
chanDB = await channelModel.findOne({name: this.channel.name});
}
//If our perm map is un-initiated
//can't set this in constructor easily since it's asyncornous
//need to wait for it to complete before sending this off, but shouldnt re-do the wait for later connections
if(this.permMap == null){
//Grab perm map
this.permMap = await chanDB.getPermMapByUserDoc(userDB);
}
//Setup our userObj
const userObj = {
id: this.id,
@ -85,7 +114,11 @@ module.exports = class{
rank: this.rank,
chanRank: this.chanRank,
highLevel: this.highLevel,
flair: this.flair
permMap: {
site: Array.from(this.permMap.site),
chan: Array.from(this.permMap.chan),
},
flair: this.flair,
}
//For each flair listed in the Database

View file

@ -447,6 +447,17 @@ channelSchema.methods.getChannelRank = async function(user){
return await this.getChannelRankByUserDoc(userDB);
}
channelSchema.methods.permCheck = async function (user, perm){
//Set userDB to null if we wheren't passed a real user
if(user != null){
var userDB = await userModel.findOne({user: user.user});
}else{
var userDB = null;
}
return await this.permCheckByUserDoc(userDB, perm)
}
channelSchema.methods.permCheckByUserDoc = async function(userDB, perm){
//Get site-wide rank as number, default to anon for anonymous users
const rank = userDB ? permissionModel.rankToNum(userDB.rank) : permissionModel.rankToNum("anon");
@ -464,15 +475,25 @@ channelSchema.methods.permCheckByUserDoc = async function(userDB, perm){
return (permCheck || overrideCheck);
}
channelSchema.methods.permCheck = async function (user, perm){
//Set userDB to null if we wheren't passed a real user
if(user != null){
var userDB = await userModel.findOne({user: user.user});
}else{
var userDB = null;
}
channelSchema.methods.getPermMapByUserDoc = async function(userDB){
//Grap site-wide permissions
const sitePerms = await permissionModel.getPerms();
const siteMap = sitePerms.getPermMapByUserDoc(userDB);
//Pull chan permissions keys
let permTree = channelPermissionSchema.tree;
let permMap = new Map();
return await this.permCheckByUserDoc(userDB, perm)
//For each object in the temporary permissions object
for(let perm of Object.keys(permTree)){
//Check the current permission
permMap.set(perm, await this.permCheckByUserDoc(userDB, perm));
}
//return perm map
return {
site: siteMap.site,
chan: permMap
};
}
channelSchema.methods.checkBanByUserDoc = async function(userDB){

View file

@ -139,26 +139,8 @@ permissionSchema.statics.permCheck = async function(user, perm){
permissionSchema.statics.permCheckByUserDoc = async function(user, perm){
//Get permission list
const perms = await this.getPerms();
//Set user to anon rank if no rank was found for the given user
if(user == null || user.rank == null){
user ={
rank: "anon"
};
}
//Check if this permission exists
if(perms[perm] != null){
//if so get required rank as a number
requiredRank = this.rankToNum(perms[perm])
//if so get user rank as a number
userRank = user ? this.rankToNum(user.rank) : 0;
//return whether or not the user is equal to or higher than the required rank for this permission
return (userRank >= requiredRank);
}else{
//if not scream and shout
throw new Error(`Permission check '${perm}' not found!`);
}
//Call the perm check method
return perms.permCheckByUserDoc(user, perm);
}
permissionSchema.statics.overrideCheck = async function(user, perm){
@ -175,27 +157,9 @@ permissionSchema.statics.overrideCheck = async function(user, perm){
permissionSchema.statics.overrideCheckByUserDoc = async function(user, perm){
//Get permission list
const perms = (await this.getPerms()).channelOverrides;
//Set user to anon rank if no rank was found for the given user
if(user == null || user.rank == null){
user ={
rank: "anon"
};
}
//Check if this permission exists
if(perms[perm] != null){
//if so get required rank as a number
requiredRank = this.rankToNum(perms[perm])
//if so get user rank as a number
userRank = user ? this.rankToNum(user.rank) : 0;
//return whether or not the user is equal to or higher than the required rank for this permission
return (userRank >= requiredRank);
}else{
//if not scream and shout
throw new Error(`Permission check '${perm}' not found!`);
}
const perms = await this.getPerms();
//Call the perm check method
return perms.overrideCheckByUserDoc(user, perm);
}
//Middleware for rank checks
@ -211,4 +175,76 @@ permissionSchema.statics.reqPermCheck = function(perm){
}
}
//methods
//these are good to have even for single-doc collections since we can loop through them without finding them in the database each time
permissionSchema.methods.permCheckByUserDoc = function(userDB, perm){
//Set user to anon rank if no rank was found for the given user
if(userDB == null || userDB.rank == null){
userDB ={
rank: "anon"
};
}
//Check if this permission exists
if(this[perm] != null){
//if so get required rank as a number
requiredRank = this.model().rankToNum(this[perm])
//if so get user rank as a number
userRank = userDB ? this.model().rankToNum(userDB.rank) : 0;
//return whether or not the user is equal to or higher than the required rank for this permission
return (userRank >= requiredRank);
}else{
//if not scream and shout
throw new Error(`Permission check '${perm}' not found!`);
}
}
permissionSchema.methods.overrideCheckByUserDoc = function(userDB, perm){
//Set user to anon rank if no rank was found for the given user
if(userDB == null || userDB.rank == null){
userDB ={
rank: "anon"
};
}
//Check if this permission exists
if(this.channelOverrides[perm] != null){
//if so get required rank as a number
requiredRank = this.model().rankToNum(this.channelOverrides[perm])
//if so get user rank as a number
userRank = userDB ? this.model().rankToNum(userDB.rank) : 0;
//return whether or not the user is equal to or higher than the required rank for this permission
return (userRank >= requiredRank);
}else{
//if not scream and shout
throw new Error(`Permission check '${perm}' not found!`);
}
}
permissionSchema.methods.getPermMapByUserDoc = function(userDB){
//Pull permissions keys
let permTree = this.schema.tree;
let overrideTree = channelPermissionSchema.tree;
let permMap = new Map();
let overrideMap = new Map();
//For each object in the temporary permissions object
for(let perm of Object.keys(permTree)){
//Check the current permission
permMap.set(perm, this.permCheckByUserDoc(userDB, perm));
}
//For each object in the temporary permissions object
for(let perm of Object.keys(overrideTree)){
//Check the current permission
overrideMap.set(perm, this.overrideCheckByUserDoc(userDB, perm));
}
//return the auto-generated schema
return {
site: permMap,
channelOverrides: overrideMap
}
}
module.exports = mongoose.model("permissions", permissionSchema);

View file

@ -30,18 +30,18 @@ module.exports.isRank = function(value){
//Internal functions for loading validator schema through the database so we only have to maintain permissions in one place
function loadPermValidatorSchema(){
//Pull permissions keys
var tempPerms = permissionModel.schema.tree;
var permTree = permissionModel.schema.tree;
//Create empty object for schema
var schema = {};
//Scrape out gunk
delete tempPerms.id;
delete tempPerms._id;
delete tempPerms.__v;
delete tempPerms.channelOverrides;
delete permTree.id;
delete permTree._id;
delete permTree.__v;
delete permTree.channelOverrides;
//For each object in the temporary permissions object
Object.keys(tempPerms).forEach((key) => {
for(let key of Object.keys(permTree)){
//Create an entry in the validation schema for the current permission
schema[`permissionsMap.${key}`] = {
optional: true,
@ -49,7 +49,7 @@ function loadPermValidatorSchema(){
options: module.exports.isRank
}
}
});
}
//return the auto-generated schema
return schema;
@ -57,17 +57,17 @@ function loadPermValidatorSchema(){
function loadChanPermValidatorSchema(){
//Pull permissions keys
var tempPerms = channelPermissionSchema.tree;
var permTree = channelPermissionSchema.tree;
//Create empty object for schema
var schema = {};
//Scrape out gunk
delete tempPerms.id;
delete tempPerms._id;
delete tempPerms.__v;
delete permTree.id;
delete permTree._id;
delete permTree.__v;
//For each object in the temporary permissions object
Object.keys(tempPerms).forEach((key) => {
for(let key of Object.keys(permTree)){
//Create an entry in the validation schema for the current permission
schema[`channelPermissionsMap.${key}`] = {
optional: true,
@ -75,7 +75,7 @@ function loadChanPermValidatorSchema(){
options: module.exports.isRank
}
}
});
}
//return the schema
return schema;