mirror of
https://github.com/hack-chat/main.git
synced 2024-03-22 13:20:33 +08:00
normalized
This commit is contained in:
parent
6266b1432d
commit
72324050f5
14
.editorconfig
Normal file
14
.editorconfig
Normal file
|
@ -0,0 +1,14 @@
|
|||
# editorconfig.org
|
||||
|
||||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
end_of_line = lf
|
||||
insert_final_newline = true
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
[*.md]
|
||||
trim_trailing_whitespace = false
|
15
.eslintrc.js
Normal file
15
.eslintrc.js
Normal file
|
@ -0,0 +1,15 @@
|
|||
module.exports = {
|
||||
env: {
|
||||
browser: true,
|
||||
commonjs: true,
|
||||
es2021: true,
|
||||
},
|
||||
extends: [
|
||||
'airbnb-base',
|
||||
],
|
||||
parserOptions: {
|
||||
ecmaVersion: 12,
|
||||
},
|
||||
rules: {
|
||||
},
|
||||
};
|
107
.gitattributes
vendored
Normal file
107
.gitattributes
vendored
Normal file
|
@ -0,0 +1,107 @@
|
|||
# From https://github.com/Danimoth/gitattributes/blob/master/Web.gitattributes
|
||||
|
||||
# Handle line endings automatically for files detected as text
|
||||
# and leave all files detected as binary untouched.
|
||||
* text=auto
|
||||
|
||||
#
|
||||
# The above will handle all files NOT found below
|
||||
#
|
||||
|
||||
#
|
||||
## These files are text and should be normalized (Convert crlf => lf)
|
||||
#
|
||||
|
||||
# source code
|
||||
*.php text
|
||||
*.css text
|
||||
*.sass text
|
||||
*.scss text
|
||||
*.less text
|
||||
*.styl text
|
||||
*.js text eol=lf
|
||||
*.coffee text
|
||||
*.json text
|
||||
*.htm text
|
||||
*.html text
|
||||
*.xml text
|
||||
*.svg text
|
||||
*.txt text
|
||||
*.ini text
|
||||
*.inc text
|
||||
*.pl text
|
||||
*.rb text
|
||||
*.py text
|
||||
*.scm text
|
||||
*.sql text
|
||||
*.sh text
|
||||
*.bat text
|
||||
|
||||
# templates
|
||||
*.ejs text
|
||||
*.hbt text
|
||||
*.jade text
|
||||
*.haml text
|
||||
*.hbs text
|
||||
*.dot text
|
||||
*.tmpl text
|
||||
*.phtml text
|
||||
|
||||
# server config
|
||||
.htaccess text
|
||||
.nginx.conf text
|
||||
|
||||
# git config
|
||||
.gitattributes text
|
||||
.gitignore text
|
||||
.gitconfig text
|
||||
|
||||
# code analysis config
|
||||
.jshintrc text
|
||||
.jscsrc text
|
||||
.jshintignore text
|
||||
.csslintrc text
|
||||
|
||||
# misc config
|
||||
*.yaml text
|
||||
*.yml text
|
||||
.editorconfig text
|
||||
|
||||
# build config
|
||||
*.npmignore text
|
||||
*.bowerrc text
|
||||
|
||||
# Heroku
|
||||
Procfile text
|
||||
.slugignore text
|
||||
|
||||
# Documentation
|
||||
*.md text
|
||||
LICENSE text
|
||||
AUTHORS text
|
||||
|
||||
|
||||
#
|
||||
## These files are binary and should be left untouched
|
||||
#
|
||||
|
||||
# (binary is a macro for -text -diff)
|
||||
*.png binary
|
||||
*.jpg binary
|
||||
*.jpeg binary
|
||||
*.gif binary
|
||||
*.ico binary
|
||||
*.mov binary
|
||||
*.mp4 binary
|
||||
*.mp3 binary
|
||||
*.flv binary
|
||||
*.fla binary
|
||||
*.swf binary
|
||||
*.gz binary
|
||||
*.zip binary
|
||||
*.7z binary
|
||||
*.ttf binary
|
||||
*.eot binary
|
||||
*.woff binary
|
||||
*.pyc binary
|
||||
*.pdf binary
|
1407
package-lock.json
generated
1407
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
12
package.json
12
package.json
|
@ -18,14 +18,20 @@
|
|||
"clear": "pm2 flush",
|
||||
"status": "pm2 list",
|
||||
"refresh": "pm2 flush && pm2 stop pm2.config.js && pm2 delete pm2.config.js",
|
||||
"postinstall": "cd ./server && npm install && npm run config"
|
||||
"postinstall": "cd ./server && npm install && npm run config",
|
||||
"lint": "eslint --ignore-path .gitignore -- ./server ",
|
||||
"lint:fix": "eslint --ignore-path .gitignore --fix -- ./server "
|
||||
},
|
||||
"author": "Marzavec",
|
||||
"license": "WTFPL",
|
||||
"dependencies": {
|
||||
"esm": "^3.2.25",
|
||||
"http-server": "^0.12.3",
|
||||
"pm2": "^4.4.1",
|
||||
"react-icons": "^3.11.0"
|
||||
"pm2": "^4.4.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"eslint": "^7.9.0",
|
||||
"eslint-config-airbnb-base": "^14.2.0",
|
||||
"eslint-plugin-import": "^2.22.0"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
*/
|
||||
|
||||
// import and initialize the core application
|
||||
import { CoreApp } from './src/serverLib/CoreApp';
|
||||
import CoreApp from './src/serverLib/CoreApp';
|
||||
|
||||
const coreApp = new CoreApp();
|
||||
coreApp.init();
|
||||
|
|
|
@ -5,17 +5,19 @@
|
|||
import * as UAC from '../utility/UAC/_info';
|
||||
|
||||
// module main
|
||||
export async function run(core, server, socket, data) {
|
||||
export async function run({
|
||||
core, server, socket, payload,
|
||||
}) {
|
||||
// increase rate limit chance and ignore if not admin
|
||||
if (!UAC.isAdmin(socket.level)) {
|
||||
return server.police.frisk(socket.address, 20);
|
||||
}
|
||||
|
||||
// add new trip to config
|
||||
core.config.mods.push({ trip: data.trip });
|
||||
core.config.mods.push({ trip: payload.trip });
|
||||
|
||||
// find targets current connections
|
||||
const newMod = server.findSockets({ trip: data.trip });
|
||||
const newMod = server.findSockets({ trip: payload.trip });
|
||||
if (newMod.length !== 0) {
|
||||
for (let i = 0, l = newMod.length; i < l; i += 1) {
|
||||
// upgrade privilages
|
||||
|
@ -33,13 +35,13 @@ export async function run(core, server, socket, data) {
|
|||
// return success message
|
||||
server.reply({
|
||||
cmd: 'info',
|
||||
text: `Added mod trip: ${data.trip}, remember to run 'saveconfig' to make it permanent`,
|
||||
text: `Added mod trip: ${payload.trip}, remember to run 'saveconfig' to make it permanent`,
|
||||
}, socket);
|
||||
|
||||
// notify all mods
|
||||
server.broadcast({
|
||||
cmd: 'info',
|
||||
text: `Added mod: ${data.trip}`,
|
||||
text: `Added mod: ${payload.trip}`,
|
||||
}, { level: UAC.isModerator });
|
||||
|
||||
return true;
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
/* eslint no-unused-vars: 0 */
|
||||
/* eslint no-restricted-syntax: 0 */
|
||||
/* eslint guard-for-in: 0 */
|
||||
|
||||
/*
|
||||
Description: Outputs all current channels and their user nicks
|
||||
*/
|
||||
|
@ -5,7 +9,7 @@
|
|||
import * as UAC from '../utility/UAC/_info';
|
||||
|
||||
// module main
|
||||
export async function run(core, server, socket) {
|
||||
export async function run({ server, socket }) {
|
||||
// increase rate limit chance and ignore if not admin
|
||||
if (!UAC.isAdmin(socket.level)) {
|
||||
return server.police.frisk(socket.address, 20);
|
||||
|
|
|
@ -5,7 +5,9 @@
|
|||
import * as UAC from '../utility/UAC/_info';
|
||||
|
||||
// module main
|
||||
export async function run(core, server, socket, data) {
|
||||
export async function run({
|
||||
core, server, socket, payload,
|
||||
}) {
|
||||
// increase rate limit chance and ignore if not admin
|
||||
if (!UAC.isAdmin(socket.level)) {
|
||||
return server.police.frisk(socket.address, 20);
|
||||
|
@ -26,8 +28,8 @@ export async function run(core, server, socket, data) {
|
|||
${loadResult}`;
|
||||
}
|
||||
|
||||
if (typeof data.reason !== 'undefined') {
|
||||
loadResult += `\nReason: ${data.reason}`;
|
||||
if (typeof payload.reason !== 'undefined') {
|
||||
loadResult += `\nReason: ${payload.reason}`;
|
||||
}
|
||||
|
||||
// send results to moderators (which the user using this command is higher than)
|
||||
|
|
|
@ -5,17 +5,20 @@
|
|||
import * as UAC from '../utility/UAC/_info';
|
||||
|
||||
// module main
|
||||
export async function run(core, server, socket, data) {
|
||||
export async function run({
|
||||
core, server, socket, payload,
|
||||
}) {
|
||||
// increase rate limit chance and ignore if not admin
|
||||
if (!UAC.isAdmin(socket.level)) {
|
||||
return server.police.frisk(socket.address, 20);
|
||||
}
|
||||
|
||||
// remove trip from config
|
||||
core.config.mods = core.config.mods.filter((mod) => mod.trip !== data.trip);
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
core.config.mods = core.config.mods.filter((mod) => mod.trip !== payload.trip);
|
||||
|
||||
// find targets current connections
|
||||
const targetMod = server.findSockets({ trip: data.trip });
|
||||
const targetMod = server.findSockets({ trip: payload.trip });
|
||||
if (targetMod.length !== 0) {
|
||||
for (let i = 0, l = targetMod.length; i < l; i += 1) {
|
||||
// downgrade privilages
|
||||
|
@ -34,14 +37,14 @@ export async function run(core, server, socket, data) {
|
|||
server.reply({
|
||||
cmd: 'info',
|
||||
text: `Removed mod trip: ${
|
||||
data.trip
|
||||
payload.trip
|
||||
}, remember to run 'saveconfig' to make it permanent`,
|
||||
}, socket);
|
||||
|
||||
// notify all mods
|
||||
server.broadcast({
|
||||
cmd: 'info',
|
||||
text: `Removed mod: ${data.trip}`,
|
||||
text: `Removed mod: ${payload.trip}`,
|
||||
}, { level: UAC.isModerator });
|
||||
|
||||
return true;
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
import * as UAC from '../utility/UAC/_info';
|
||||
|
||||
// module main
|
||||
export async function run(core, server, socket) {
|
||||
export async function run({ core, server, socket }) {
|
||||
// increase rate limit chance and ignore if not admin
|
||||
if (!UAC.isAdmin(socket.level)) {
|
||||
return server.police.frisk(socket.address, 20);
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
import * as UAC from '../utility/UAC/_info';
|
||||
|
||||
// module main
|
||||
export async function run(core, server, socket, data) {
|
||||
export async function run({ server, socket, payload }) {
|
||||
// increase rate limit chance and ignore if not admin
|
||||
if (!UAC.isAdmin(socket.level)) {
|
||||
return server.police.frisk(socket.address, 20);
|
||||
|
@ -14,7 +14,7 @@ export async function run(core, server, socket, data) {
|
|||
// send text to all channels
|
||||
server.broadcast({
|
||||
cmd: 'info',
|
||||
text: `Server Notice: ${data.text}`,
|
||||
text: `Server Notice: ${payload.text}`,
|
||||
}, {});
|
||||
|
||||
return true;
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
/* eslint eqeqeq: 0 */
|
||||
|
||||
/*
|
||||
Description: Allows calling client to change their current nickname
|
||||
*/
|
||||
|
@ -5,7 +7,9 @@
|
|||
import * as UAC from '../utility/UAC/_info';
|
||||
|
||||
// module main
|
||||
export async function run(core, server, socket, data) {
|
||||
export async function run({
|
||||
core, server, socket, payload,
|
||||
}) {
|
||||
if (server.police.frisk(socket.address, 6)) {
|
||||
return server.reply({
|
||||
cmd: 'warn', // @todo Remove english and change to numeric id
|
||||
|
@ -14,14 +18,14 @@ export async function run(core, server, socket, data) {
|
|||
}
|
||||
|
||||
// verify user data is string
|
||||
if (typeof data.nick !== 'string') {
|
||||
if (typeof payload.nick !== 'string') {
|
||||
return true;
|
||||
}
|
||||
|
||||
const previousNick = socket.nick;
|
||||
|
||||
// make sure requested nickname meets standards
|
||||
const newNick = data.nick.trim();
|
||||
const newNick = payload.nick.trim();
|
||||
if (!UAC.verifyNickname(newNick)) {
|
||||
return server.reply({
|
||||
cmd: 'warn', // @todo Remove english and change to numeric id
|
||||
|
@ -30,7 +34,7 @@ export async function run(core, server, socket, data) {
|
|||
}
|
||||
|
||||
// prevent admin impersonation
|
||||
// TODO: prevent mod impersonation
|
||||
// @todo prevent mod impersonation
|
||||
if (newNick.toLowerCase() === core.config.adminName.toLowerCase()) {
|
||||
server.police.frisk(socket.address, 4);
|
||||
|
||||
|
@ -50,9 +54,9 @@ export async function run(core, server, socket, data) {
|
|||
// find any sockets that have the same nickname
|
||||
const userExists = server.findSockets({
|
||||
channel: socket.channel,
|
||||
nick: (targetNick) => targetNick.toLowerCase() === newNick.toLowerCase() &&
|
||||
nick: (targetNick) => targetNick.toLowerCase() === newNick.toLowerCase()
|
||||
// Allow them to rename themselves to a different case
|
||||
targetNick != previousNick,
|
||||
&& targetNick != previousNick,
|
||||
});
|
||||
|
||||
// return error if found
|
||||
|
@ -65,7 +69,7 @@ export async function run(core, server, socket, data) {
|
|||
}
|
||||
|
||||
// build join and leave notices
|
||||
// TODO: this is a legacy client holdover, name changes in the future will
|
||||
// @todo this is a legacy client holdover, name changes in the future will
|
||||
// have thieir own event
|
||||
const leaveNotice = {
|
||||
cmd: 'onlineRemove',
|
||||
|
@ -90,7 +94,7 @@ export async function run(core, server, socket, data) {
|
|||
}, { channel: socket.channel });
|
||||
|
||||
// commit change to nickname
|
||||
socket.nick = newNick;
|
||||
socket.nick = newNick; // eslint-disable-line no-param-reassign
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -101,7 +105,9 @@ export function initHooks(server) {
|
|||
}
|
||||
|
||||
// hooks chat commands checking for /nick
|
||||
export function nickCheck(core, server, socket, payload) {
|
||||
export function nickCheck({
|
||||
core, server, socket, payload,
|
||||
}) {
|
||||
if (typeof payload.text !== 'string') {
|
||||
return false;
|
||||
}
|
||||
|
@ -121,9 +127,14 @@ export function nickCheck(core, server, socket, payload) {
|
|||
|
||||
const newNick = input[1].replace(/@/g, '');
|
||||
|
||||
this.run(core, server, socket, {
|
||||
cmd: 'changenick',
|
||||
nick: newNick,
|
||||
this.run({
|
||||
core,
|
||||
server,
|
||||
socket,
|
||||
payload: {
|
||||
cmd: 'changenick',
|
||||
nick: newNick,
|
||||
},
|
||||
});
|
||||
|
||||
return false;
|
||||
|
|
|
@ -22,9 +22,11 @@ const parseText = (text) => {
|
|||
};
|
||||
|
||||
// module main
|
||||
export async function run(core, server, socket, data) {
|
||||
export async function run({
|
||||
core, server, socket, payload,
|
||||
}) {
|
||||
// check user input
|
||||
const text = parseText(data.text);
|
||||
const text = parseText(payload.text);
|
||||
|
||||
if (!text) {
|
||||
// lets not send objects or empty text, yea?
|
||||
|
@ -41,7 +43,7 @@ export async function run(core, server, socket, data) {
|
|||
}
|
||||
|
||||
// build chat payload
|
||||
const payload = {
|
||||
const outgoingPayload = {
|
||||
cmd: 'chat',
|
||||
nick: socket.nick, /* @legacy */
|
||||
userid: socket.userid,
|
||||
|
@ -51,17 +53,17 @@ export async function run(core, server, socket, data) {
|
|||
};
|
||||
|
||||
if (UAC.isAdmin(socket.level)) {
|
||||
payload.admin = true;
|
||||
outgoingPayload.admin = true;
|
||||
} else if (UAC.isModerator(socket.level)) {
|
||||
payload.mod = true;
|
||||
outgoingPayload.mod = true;
|
||||
}
|
||||
|
||||
if (socket.trip) {
|
||||
payload.trip = socket.trip; /* @legacy */
|
||||
outgoingPayload.trip = socket.trip; /* @legacy */
|
||||
}
|
||||
|
||||
// broadcast to channel peers
|
||||
server.broadcast(payload, { channel: socket.channel });
|
||||
server.broadcast(outgoingPayload, { channel: socket.channel });
|
||||
|
||||
// stats are fun
|
||||
core.stats.increment('messages-sent');
|
||||
|
@ -76,7 +78,7 @@ export function initHooks(server) {
|
|||
}
|
||||
|
||||
// checks for miscellaneous '/' based commands
|
||||
export function commandCheckIn(core, server, socket, payload) {
|
||||
export function commandCheckIn({ server, socket, payload }) {
|
||||
if (typeof payload.text !== 'string') {
|
||||
return false;
|
||||
}
|
||||
|
@ -93,7 +95,7 @@ export function commandCheckIn(core, server, socket, payload) {
|
|||
return payload;
|
||||
}
|
||||
|
||||
export function finalCmdCheck(core, server, socket, payload) {
|
||||
export function finalCmdCheck({ server, socket, payload }) {
|
||||
if (typeof payload.text !== 'string') {
|
||||
return false;
|
||||
}
|
||||
|
@ -103,7 +105,7 @@ export function finalCmdCheck(core, server, socket, payload) {
|
|||
}
|
||||
|
||||
if (payload.text.startsWith('//')) {
|
||||
payload.text = payload.text.substr(1);
|
||||
payload.text = payload.text.substr(1); // eslint-disable-line no-param-reassign
|
||||
|
||||
return payload;
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ const parseText = (text) => {
|
|||
};
|
||||
|
||||
// module main
|
||||
export async function run(core, server, socket, payload) {
|
||||
export async function run({ server, socket, payload }) {
|
||||
// check user input
|
||||
let text = parseText(payload.text);
|
||||
|
||||
|
@ -65,7 +65,9 @@ export function initHooks(server) {
|
|||
}
|
||||
|
||||
// hooks chat commands checking for /me
|
||||
export function emoteCheck(core, server, socket, payload) {
|
||||
export function emoteCheck({
|
||||
core, server, socket, payload,
|
||||
}) {
|
||||
if (typeof payload.text !== 'string') {
|
||||
return false;
|
||||
}
|
||||
|
@ -86,9 +88,14 @@ export function emoteCheck(core, server, socket, payload) {
|
|||
input.splice(0, 1);
|
||||
const actionText = input.join(' ');
|
||||
|
||||
this.run(core, server, socket, {
|
||||
cmd: 'emote',
|
||||
text: actionText,
|
||||
this.run({
|
||||
core,
|
||||
server,
|
||||
socket,
|
||||
payload: {
|
||||
cmd: 'emote',
|
||||
text: actionText,
|
||||
},
|
||||
});
|
||||
|
||||
return false;
|
||||
|
|
|
@ -3,7 +3,9 @@
|
|||
*/
|
||||
|
||||
// module main
|
||||
export async function run(core, server, socket, payload) {
|
||||
export async function run({
|
||||
core, server, socket, payload,
|
||||
}) {
|
||||
// check for spam
|
||||
if (server.police.frisk(socket.address, 2)) {
|
||||
return server.reply({
|
||||
|
@ -24,7 +26,9 @@ export async function run(core, server, socket, payload) {
|
|||
const categories = core.commands.categoriesList.sort();
|
||||
for (let i = 0, j = categories.length; i < j; i += 1) {
|
||||
reply += `|${categories[i].replace('../src/commands/', '').replace(/^\w/, (c) => c.toUpperCase())}:|`;
|
||||
const catCommands = core.commands.all(categories[i]).sort((a, b) => a.info.name.localeCompare(b.info.name));
|
||||
const catCommands = core.commands.all(categories[i]).sort(
|
||||
(a, b) => a.info.name.localeCompare(b.info.name),
|
||||
);
|
||||
reply += `${catCommands.map((c) => `${c.info.name}`).join(', ')}|\n`;
|
||||
}
|
||||
|
||||
|
@ -40,6 +44,7 @@ export async function run(core, server, socket, payload) {
|
|||
reply += `|**Aliases:**|${typeof command.info.aliases !== 'undefined' ? command.info.aliases.join(', ') : 'None'}|\n`;
|
||||
reply += `|**Category:**|${command.info.category.replace('../src/commands/', '').replace(/^\w/, (c) => c.toUpperCase())}|\n`;
|
||||
reply += `|**Required Parameters:**|${command.requiredData || 'None'}|\n`;
|
||||
// eslint-disable-next-line no-useless-escape
|
||||
reply += `|**Description:**|${command.info.description || '¯\_(ツ)_/¯'}|\n\n`;
|
||||
reply += `**Usage:** ${command.info.usage || command.info.name}`;
|
||||
}
|
||||
|
@ -60,7 +65,9 @@ export function initHooks(server) {
|
|||
}
|
||||
|
||||
// hooks chat commands checking for /whisper
|
||||
export function helpCheck(core, server, socket, payload) {
|
||||
export function helpCheck({
|
||||
core, server, socket, payload,
|
||||
}) {
|
||||
if (typeof payload.text !== 'string') {
|
||||
return false;
|
||||
}
|
||||
|
@ -68,9 +75,14 @@ export function helpCheck(core, server, socket, payload) {
|
|||
if (payload.text.startsWith('/help')) {
|
||||
const input = payload.text.substr(1).split(' ', 2);
|
||||
|
||||
this.run(core, server, socket, {
|
||||
cmd: input[0],
|
||||
command: input[1],
|
||||
this.run({
|
||||
core,
|
||||
server,
|
||||
socket,
|
||||
payload: {
|
||||
cmd: input[0],
|
||||
command: input[1],
|
||||
},
|
||||
});
|
||||
|
||||
return false;
|
||||
|
|
|
@ -8,16 +8,17 @@
|
|||
* @param {any} channel
|
||||
* @return {string}
|
||||
*/
|
||||
export function getChannel (channel=undefined) {
|
||||
export function getChannel(channel = undefined) {
|
||||
if (typeof channel === 'string') {
|
||||
return channel;
|
||||
} else {
|
||||
return Math.random().toString(36).substr(2, 8);
|
||||
}
|
||||
return Math.random().toString(36).substr(2, 8);
|
||||
}
|
||||
|
||||
// module main
|
||||
export async function run(core, server, socket, data) {
|
||||
export async function run({
|
||||
core, server, socket, payload,
|
||||
}) {
|
||||
// check for spam
|
||||
if (server.police.frisk(socket.address, 2)) {
|
||||
return server.reply({
|
||||
|
@ -27,18 +28,18 @@ export async function run(core, server, socket, data) {
|
|||
}
|
||||
|
||||
// verify user input
|
||||
if (typeof data.userid !== 'number' || typeof data.channel !== 'string') {
|
||||
if (typeof payload.userid !== 'number' || typeof payload.channel !== 'string') {
|
||||
return true;
|
||||
}
|
||||
|
||||
// why would you invite yourself?
|
||||
if (data.userid === socket.userid) {
|
||||
if (payload.userid === socket.userid) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// @todo Verify this socket is part of data.channel - multichannel patch
|
||||
// @todo Verify this socket is part of payload.channel - multichannel patch
|
||||
// find target user
|
||||
let targetClient = server.findSockets({ channel: data.channel, userid: data.userid });
|
||||
let targetClient = server.findSockets({ channel: payload.channel, userid: payload.userid });
|
||||
|
||||
if (targetClient.length === 0) {
|
||||
return server.reply({
|
||||
|
@ -50,22 +51,22 @@ export async function run(core, server, socket, data) {
|
|||
[targetClient] = targetClient;
|
||||
|
||||
// generate common channel
|
||||
const channel = getChannel(data.to);
|
||||
const channel = getChannel(payload.to);
|
||||
|
||||
// build invite
|
||||
const payload = {
|
||||
const outgoingPayload = {
|
||||
cmd: 'invite',
|
||||
channel: socket.channel,
|
||||
from: socket.userid,
|
||||
to: data.userid,
|
||||
to: payload.userid,
|
||||
inviteChannel: channel,
|
||||
};
|
||||
|
||||
// send invite notice to target client
|
||||
server.reply(payload, targetClient);
|
||||
server.reply(outgoingPayload, targetClient);
|
||||
|
||||
// send invite notice to this client
|
||||
server.reply(payload, socket);
|
||||
server.reply(outgoingPayload, socket);
|
||||
|
||||
// stats are fun
|
||||
core.stats.increment('invites-sent');
|
||||
|
@ -73,7 +74,7 @@ export async function run(core, server, socket, data) {
|
|||
return true;
|
||||
}
|
||||
|
||||
export const requiredData = [];//['nick'];
|
||||
export const requiredData = []; // ['nick'];
|
||||
export const info = {
|
||||
name: 'invite',
|
||||
description: 'Sends an invite to the target client with the provided channel, or a random channel.',
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
/* eslint no-param-reassign: 0 */
|
||||
|
||||
/*
|
||||
Description: Initial entry point, applies `channel` and `nick` to the calling socket
|
||||
*/
|
||||
|
@ -29,7 +31,7 @@ export function parseNickname(core, data) {
|
|||
return 'Nickname must consist of up to 24 letters, numbers, and underscores';
|
||||
}
|
||||
|
||||
let password = data.pass || false;
|
||||
const password = data.pass || false;
|
||||
|
||||
if (hash(password + core.config.tripSalt) === core.config.adminTrip) {
|
||||
userInfo.uType = 'admin'; /* @legacy */
|
||||
|
@ -43,7 +45,7 @@ export function parseNickname(core, data) {
|
|||
userInfo.trip = hash(password + core.config.tripSalt);
|
||||
}
|
||||
|
||||
// TODO: disallow moderator impersonation
|
||||
// @todo disallow moderator impersonation
|
||||
// for (const mod of core.config.mods) {
|
||||
core.config.mods.forEach((mod) => {
|
||||
if (userInfo.trip === mod.trip) {
|
||||
|
@ -56,7 +58,9 @@ export function parseNickname(core, data) {
|
|||
}
|
||||
|
||||
// module main
|
||||
export async function run(core, server, socket, data) {
|
||||
export async function run({
|
||||
core, server, socket, payload,
|
||||
}) {
|
||||
// check for spam
|
||||
if (server.police.frisk(socket.address, 3)) {
|
||||
return server.reply({
|
||||
|
@ -75,17 +79,17 @@ export async function run(core, server, socket, data) {
|
|||
}
|
||||
|
||||
// check user input
|
||||
if (typeof data.channel !== 'string' || typeof data.nick !== 'string') {
|
||||
if (typeof payload.channel !== 'string' || typeof payload.nick !== 'string') {
|
||||
return true;
|
||||
}
|
||||
|
||||
const channel = data.channel.trim();
|
||||
const channel = payload.channel.trim();
|
||||
if (!channel) {
|
||||
// must join a non-blank channel
|
||||
return true;
|
||||
}
|
||||
|
||||
const userInfo = this.parseNickname(core, data);
|
||||
const userInfo = this.parseNickname(core, payload);
|
||||
if (typeof userInfo === 'string') {
|
||||
return server.reply({
|
||||
cmd: 'warn', // @todo Remove english and change to numeric id
|
||||
|
@ -95,7 +99,7 @@ export async function run(core, server, socket, data) {
|
|||
|
||||
// check if the nickname already exists in the channel
|
||||
const userExists = server.findSockets({
|
||||
channel: data.channel,
|
||||
channel: payload.channel,
|
||||
nick: (targetNick) => targetNick.toLowerCase() === userInfo.nick.toLowerCase(),
|
||||
});
|
||||
|
||||
|
@ -108,13 +112,13 @@ export async function run(core, server, socket, data) {
|
|||
}
|
||||
|
||||
// populate final userinfo fields
|
||||
// @TODO: this could be move into parseNickname, changing the function name to match
|
||||
// @todo this could be move into parseNickname, changing the function name to match
|
||||
userInfo.hash = server.getSocketHash(socket);
|
||||
userInfo.userid = socket.userid;
|
||||
|
||||
// @TODO: place this within it's own function allowing import
|
||||
// @todo place this within it's own function allowing import
|
||||
// prepare to notify channel peers
|
||||
const newPeerList = server.findSockets({ channel: data.channel });
|
||||
const newPeerList = server.findSockets({ channel: payload.channel });
|
||||
const nicks = []; /* @legacy */
|
||||
const users = [];
|
||||
|
||||
|
@ -126,7 +130,7 @@ export async function run(core, server, socket, data) {
|
|||
hash: userInfo.hash,
|
||||
level: userInfo.level,
|
||||
userid: userInfo.userid,
|
||||
channel: data.channel,
|
||||
channel: payload.channel,
|
||||
};
|
||||
|
||||
// send join announcement and prep online set
|
||||
|
@ -141,7 +145,7 @@ export async function run(core, server, socket, data) {
|
|||
hash: newPeerList[i].hash,
|
||||
level: newPeerList[i].level,
|
||||
userid: newPeerList[i].userid,
|
||||
channel: data.channel,
|
||||
channel: payload.channel,
|
||||
isme: false,
|
||||
});
|
||||
}
|
||||
|
@ -150,7 +154,7 @@ export async function run(core, server, socket, data) {
|
|||
socket.uType = userInfo.uType; /* @legacy */
|
||||
socket.nick = userInfo.nick;
|
||||
socket.trip = userInfo.trip;
|
||||
socket.channel = data.channel; /* @legacy */
|
||||
socket.channel = payload.channel; /* @legacy */
|
||||
socket.hash = userInfo.hash;
|
||||
socket.level = userInfo.level;
|
||||
|
||||
|
@ -162,7 +166,7 @@ export async function run(core, server, socket, data) {
|
|||
hash: socket.hash,
|
||||
level: socket.level,
|
||||
userid: socket.userid,
|
||||
channel: data.channel,
|
||||
channel: payload.channel,
|
||||
isme: true,
|
||||
});
|
||||
|
||||
|
@ -179,7 +183,7 @@ export async function run(core, server, socket, data) {
|
|||
return true;
|
||||
}
|
||||
|
||||
export const requiredData = ['channel', 'nick'];
|
||||
export const requiredData = []; // ['channel', 'nick'];
|
||||
export const info = {
|
||||
name: 'join',
|
||||
description: 'Place calling socket into target channel with target nick & broadcast event to channel',
|
||||
|
|
|
@ -21,7 +21,7 @@ const formatTime = (time) => {
|
|||
};
|
||||
|
||||
// module main
|
||||
export async function run(core, server, socket) {
|
||||
export async function run({ core, server, socket }) {
|
||||
// gather connection and channel count
|
||||
let ips = {};
|
||||
let channels = {};
|
||||
|
@ -63,14 +63,21 @@ export function initHooks(server) {
|
|||
}
|
||||
|
||||
// hooks chat commands checking for /stats
|
||||
export function statsCheck(core, server, socket, payload) {
|
||||
export function statsCheck({
|
||||
core, server, socket, payload,
|
||||
}) {
|
||||
if (typeof payload.text !== 'string') {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (payload.text.startsWith('/stats')) {
|
||||
this.run(core, server, socket, {
|
||||
cmd: 'morestats',
|
||||
this.run({
|
||||
core,
|
||||
server,
|
||||
socket,
|
||||
payload: {
|
||||
cmd: 'morestats',
|
||||
},
|
||||
});
|
||||
|
||||
return false;
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
/*
|
||||
Description: Changes the current channel of the calling socket
|
||||
@deprecated This module will be removed or replaced
|
||||
*/
|
||||
|
||||
// module main
|
||||
export async function run(core, server, socket, data) {
|
||||
export async function run({ server, socket, payload }) {
|
||||
// check for spam
|
||||
if (server.police.frisk(socket.address, 6)) {
|
||||
return server.reply({
|
||||
|
@ -13,18 +14,18 @@ export async function run(core, server, socket, data) {
|
|||
}
|
||||
|
||||
// check user input
|
||||
if (typeof data.channel !== 'string') {
|
||||
if (typeof payload.channel !== 'string') {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (data.channel === '') {
|
||||
if (payload.channel === '') {
|
||||
return server.reply({
|
||||
cmd: 'warn', // @todo Remove english and change to numeric id
|
||||
text: 'Cannot move to an empty channel.',
|
||||
}, socket);
|
||||
}
|
||||
|
||||
if (data.channel === socket.channel) {
|
||||
if (payload.channel === socket.channel) {
|
||||
// they are trying to rejoin the channel
|
||||
return true;
|
||||
}
|
||||
|
@ -32,7 +33,7 @@ export async function run(core, server, socket, data) {
|
|||
// check that the nickname isn't already in target channel
|
||||
const currentNick = socket.nick.toLowerCase();
|
||||
const userExists = server.findSockets({
|
||||
channel: data.channel,
|
||||
channel: payload.channel,
|
||||
nick: (targetNick) => targetNick.toLowerCase() === currentNick,
|
||||
});
|
||||
|
||||
|
@ -60,9 +61,9 @@ export async function run(core, server, socket, data) {
|
|||
}
|
||||
}
|
||||
|
||||
// TODO: import function from join module
|
||||
// @todo import function from join module
|
||||
// broadcast join notice to new peers
|
||||
const newPeerList = server.findSockets({ channel: data.channel });
|
||||
const newPeerList = server.findSockets({ channel: payload.channel });
|
||||
const moveAnnouncement = {
|
||||
cmd: 'onlineAdd',
|
||||
nick: socket.nick,
|
||||
|
@ -85,7 +86,7 @@ export async function run(core, server, socket, data) {
|
|||
}, socket);
|
||||
|
||||
// commit change
|
||||
socket.channel = data.channel;
|
||||
socket.channel = payload.channel; // eslint-disable-line no-param-reassign
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -95,7 +96,9 @@ export function initHooks(server) {
|
|||
server.registerHook('in', 'chat', this.moveCheck.bind(this), 29);
|
||||
}
|
||||
|
||||
export function moveCheck(core, server, socket, payload) {
|
||||
export function moveCheck({
|
||||
core, server, socket, payload,
|
||||
}) {
|
||||
if (typeof payload.text !== 'string') {
|
||||
return false;
|
||||
}
|
||||
|
@ -113,9 +116,14 @@ export function moveCheck(core, server, socket, payload) {
|
|||
return false;
|
||||
}
|
||||
|
||||
this.run(core, server, socket, {
|
||||
cmd: 'move',
|
||||
channel: input[1],
|
||||
this.run({
|
||||
core,
|
||||
server,
|
||||
socket,
|
||||
payload: {
|
||||
cmd: 'move',
|
||||
channel: input[1],
|
||||
},
|
||||
});
|
||||
|
||||
return false;
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* eslint no-empty-function: 0 */
|
||||
/*
|
||||
Description: This module is only in place to supress error notices legacy sources may get
|
||||
*/
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
/* eslint no-param-reassign: 0 */
|
||||
|
||||
/*
|
||||
Description: Create a new socket session or restore previous session
|
||||
*/
|
||||
|
@ -5,19 +7,19 @@
|
|||
// module support functions
|
||||
const createSessionID = () => {
|
||||
let sessionID = '';
|
||||
for( let i = 0, j = 32; i < j; i++) {
|
||||
for (let i = 0, j = 32; i < j; i += 1) {
|
||||
sessionID += Math.random().toString(36).substr(2, 9);
|
||||
}
|
||||
return sessionID;
|
||||
}
|
||||
};
|
||||
|
||||
// module main
|
||||
export async function run(core, server, socket) {
|
||||
export async function run({ server, socket }) {
|
||||
// gather connection and channel count
|
||||
let ips = {};
|
||||
let channels = {};
|
||||
// todo: use public channel flag
|
||||
let publicChanCounts = {
|
||||
// @todo use public channel flag
|
||||
const publicChanCounts = {
|
||||
lounge: 0,
|
||||
meta: 0,
|
||||
math: 0,
|
||||
|
@ -30,13 +32,13 @@ export async function run(core, server, socket) {
|
|||
chinese: 0,
|
||||
};
|
||||
|
||||
// todo: code resuage between here and `morestats`, export function
|
||||
// todo code resuage between here and `morestats`, export function
|
||||
server.clients.forEach((client) => {
|
||||
if (client.channel) {
|
||||
channels[client.channel] = true;
|
||||
ips[client.address] = true;
|
||||
if (typeof publicChanCounts[client.channel] !== 'undefined') {
|
||||
publicChanCounts[client.channel]++;
|
||||
publicChanCounts[client.channel] += 1;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -47,7 +49,7 @@ export async function run(core, server, socket) {
|
|||
ips = null;
|
||||
channels = null;
|
||||
|
||||
// @todo: restore session
|
||||
// @todo restore session
|
||||
socket.sessionID = createSessionID();
|
||||
socket.hcProtocol = 2;
|
||||
socket.userid = Math.floor(Math.random() * 9999999999999);
|
||||
|
@ -67,5 +69,5 @@ export const info = {
|
|||
name: 'session',
|
||||
description: 'Restore previous state by session id or return new session id (currently unavailable)',
|
||||
usage: `
|
||||
API: { cmd: 'session', id: '<previous session>' }`
|
||||
API: { cmd: 'session', id: '<previous session>' }`,
|
||||
};
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
*/
|
||||
|
||||
// module main
|
||||
export async function run(core, server, socket) {
|
||||
export async function run({ core, server, socket }) {
|
||||
// gather connection and channel count
|
||||
let ips = {};
|
||||
let channels = {};
|
||||
|
|
|
@ -25,7 +25,7 @@ const parseText = (text) => {
|
|||
};
|
||||
|
||||
// module main
|
||||
export async function run(core, server, socket, payload) {
|
||||
export async function run({ server, socket, payload }) {
|
||||
// check user input
|
||||
const text = parseText(payload.text);
|
||||
|
||||
|
@ -85,7 +85,9 @@ export function initHooks(server) {
|
|||
}
|
||||
|
||||
// hooks chat commands checking for /whisper
|
||||
export function whisperCheck(core, server, socket, payload) {
|
||||
export function whisperCheck({
|
||||
core, server, socket, payload,
|
||||
}) {
|
||||
if (typeof payload.text !== 'string') {
|
||||
return false;
|
||||
}
|
||||
|
@ -107,10 +109,15 @@ export function whisperCheck(core, server, socket, payload) {
|
|||
input.splice(0, 2);
|
||||
const whisperText = input.join(' ');
|
||||
|
||||
this.run(core, server, socket, {
|
||||
cmd: 'whisper',
|
||||
nick: target,
|
||||
text: whisperText,
|
||||
this.run({
|
||||
core,
|
||||
server,
|
||||
socket,
|
||||
payload: {
|
||||
cmd: 'whisper',
|
||||
nick: target,
|
||||
text: whisperText,
|
||||
},
|
||||
});
|
||||
|
||||
return false;
|
||||
|
@ -130,10 +137,15 @@ export function whisperCheck(core, server, socket, payload) {
|
|||
input.splice(0, 1);
|
||||
const whisperText = input.join(' ');
|
||||
|
||||
this.run(core, server, socket, {
|
||||
cmd: 'whisper',
|
||||
nick: socket.whisperReply,
|
||||
text: whisperText,
|
||||
this.run({
|
||||
core,
|
||||
server,
|
||||
socket,
|
||||
payload: {
|
||||
cmd: 'whisper',
|
||||
nick: socket.whisperReply,
|
||||
text: whisperText,
|
||||
},
|
||||
});
|
||||
|
||||
return false;
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
*/
|
||||
|
||||
// module main
|
||||
export async function run(core, server, socket, data) {
|
||||
if (data.cmdKey !== server.cmdKey) {
|
||||
export async function run({ server, socket, payload }) {
|
||||
if (payload.cmdKey !== server.cmdKey) {
|
||||
// internal command attempt by client, increase rate limit chance and ignore
|
||||
return server.police.frisk(socket.address, 20);
|
||||
}
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
/* eslint no-param-reassign: 0 */
|
||||
|
||||
/*
|
||||
Description: This module adjusts outgoing data, making it compatible with legacy clients
|
||||
Dear god this module is horrifying
|
||||
|
@ -6,7 +8,7 @@
|
|||
// import * as UAC from '../utility/UAC/_info';
|
||||
|
||||
// module main
|
||||
export async function run(core, server, socket, data) {
|
||||
export async function run({ server, socket }) {
|
||||
return server.police.frisk(socket.address, 20);
|
||||
}
|
||||
|
||||
|
@ -21,14 +23,14 @@ export function initHooks(server) {
|
|||
}
|
||||
|
||||
// hook incoming join events, if session was not invoked, default proto to 1
|
||||
export function joinCheck(core, server, socket, payload) {
|
||||
export function joinCheck({ socket, payload }) {
|
||||
if (typeof socket.hcProtocol === 'undefined') {
|
||||
socket.hcProtocol = 1;
|
||||
|
||||
const nickArray = payload.nick.split('#', 2);
|
||||
payload.nick = nickArray[0].trim();
|
||||
if (nickArray[1] && typeof payload.pass === 'undefined') {
|
||||
payload.pass = nickArray[1];
|
||||
payload.pass = nickArray[1]; // eslint-disable-line prefer-destructuring
|
||||
}
|
||||
|
||||
// dunno how this happened on the legacy version
|
||||
|
@ -45,30 +47,30 @@ export function joinCheck(core, server, socket, payload) {
|
|||
}
|
||||
|
||||
// if legacy client sent an invite, downgrade request
|
||||
export function inviteInCheck(core, server, socket, payload) {
|
||||
export function inviteInCheck({ server, socket, payload }) {
|
||||
if (socket.hcProtocol === 1) {
|
||||
let targetClient = server.findSockets({ channel: socket.channel, nick: data.nick });
|
||||
let targetClient = server.findSockets({ channel: socket.channel, nick: payload.nick });
|
||||
|
||||
if (targetClient.length === 0) {
|
||||
server.reply({
|
||||
cmd: 'warn',
|
||||
text: 'Could not find user in that channel',
|
||||
}, socket);
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
[targetClient] = targetClient;
|
||||
|
||||
|
||||
payload.userid = targetClient.userid;
|
||||
payload.channel = socket.channel;
|
||||
}
|
||||
|
||||
|
||||
return payload;
|
||||
}
|
||||
|
||||
//
|
||||
export function inviteOutCheck(core, server, socket, payload) {
|
||||
//
|
||||
export function inviteOutCheck({ server, socket, payload }) {
|
||||
if (socket.hcProtocol === 1) {
|
||||
payload.cmd = 'info';
|
||||
if (socket.userid === payload.from) {
|
||||
|
@ -89,59 +91,59 @@ export function inviteOutCheck(core, server, socket, payload) {
|
|||
return payload;
|
||||
}
|
||||
|
||||
export function banCheck(core, server, socket, payload) {
|
||||
export function banCheck({ server, socket, payload }) {
|
||||
if (socket.hcProtocol === 1) {
|
||||
let targetClient = server.findSockets({ channel: socket.channel, nick: data.nick });
|
||||
let targetClient = server.findSockets({ channel: socket.channel, nick: payload.nick });
|
||||
|
||||
if (targetClient.length === 0) {
|
||||
server.reply({
|
||||
cmd: 'warn',
|
||||
text: 'Could not find user in that channel',
|
||||
}, socket);
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
[targetClient] = targetClient;
|
||||
|
||||
|
||||
payload.userid = targetClient.userid;
|
||||
payload.channel = socket.channel;
|
||||
}
|
||||
|
||||
|
||||
return payload;
|
||||
}
|
||||
|
||||
export function dumbCheck(core, server, socket, payload) {
|
||||
export function dumbCheck({ server, socket, payload }) {
|
||||
if (socket.hcProtocol === 1) {
|
||||
let targetClient = server.findSockets({ channel: socket.channel, nick: data.nick });
|
||||
let targetClient = server.findSockets({ channel: socket.channel, nick: payload.nick });
|
||||
|
||||
if (targetClient.length === 0) {
|
||||
server.reply({
|
||||
cmd: 'warn',
|
||||
text: 'Could not find user in that channel',
|
||||
}, socket);
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
[targetClient] = targetClient;
|
||||
|
||||
|
||||
payload.userid = targetClient.userid;
|
||||
payload.channel = socket.channel;
|
||||
}
|
||||
|
||||
|
||||
return payload;
|
||||
}
|
||||
|
||||
export function kickCheck(core, server, socket, payload) {
|
||||
export function kickCheck({ server, socket, payload }) {
|
||||
if (socket.hcProtocol === 1) {
|
||||
if (typeof payload.nick !== 'number') {
|
||||
if (typeof payload.nick !== 'object' && !Array.isArray(data.nick)) {
|
||||
if (typeof payload.nick !== 'object' && !Array.isArray(payload.nick)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
let targetClient = server.findSockets({ channel: socket.channel, nick: data.nick });
|
||||
const targetClient = server.findSockets({ channel: socket.channel, nick: payload.nick });
|
||||
|
||||
if (targetClient.length === 0) {
|
||||
return false;
|
||||
|
@ -151,10 +153,10 @@ export function kickCheck(core, server, socket, payload) {
|
|||
for (let i = 0, j = targetClient.length; i < j; i += 1) {
|
||||
payload.userid.push(targetClient[i].userid);
|
||||
}
|
||||
|
||||
|
||||
payload.channel = socket.channel;
|
||||
}
|
||||
|
||||
|
||||
return payload;
|
||||
}
|
||||
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
*/
|
||||
|
||||
// module main
|
||||
export async function run(core, server, socket, data) {
|
||||
if (data.cmdKey !== server.cmdKey) {
|
||||
export async function run({ server, socket, payload }) {
|
||||
if (payload.cmdKey !== server.cmdKey) {
|
||||
// internal command attempt by client, increase rate limit chance and ignore
|
||||
return server.police.frisk(socket.address, 20);
|
||||
}
|
||||
|
@ -12,7 +12,7 @@ export async function run(core, server, socket, data) {
|
|||
// send warning to target socket
|
||||
server.reply({
|
||||
cmd: 'warn', // @todo Remove english and change to numeric id
|
||||
text: data.text
|
||||
text: payload.text,
|
||||
}, socket);
|
||||
|
||||
return true;
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* eslint no-console: 0 */
|
||||
/*
|
||||
Description: Adds the target socket's ip to the ratelimiter
|
||||
*/
|
||||
|
@ -5,19 +6,21 @@
|
|||
import * as UAC from '../utility/UAC/_info';
|
||||
|
||||
// module main
|
||||
export async function run(core, server, socket, data) {
|
||||
export async function run({
|
||||
core, server, socket, payload,
|
||||
}) {
|
||||
// increase rate limit chance and ignore if not admin or mod
|
||||
if (!UAC.isModerator(socket.level)) {
|
||||
return server.police.frisk(socket.address, 10);
|
||||
}
|
||||
|
||||
// check user input
|
||||
if (typeof data.userid !== 'number') {
|
||||
if (typeof payload.userid !== 'number') {
|
||||
return true;
|
||||
}
|
||||
|
||||
// find target user
|
||||
let badClient = server.findSockets({ channel: socket.channel, userid: data.userid });
|
||||
let badClient = server.findSockets({ channel: socket.channel, userid: payload.userid });
|
||||
|
||||
if (badClient.length === 0) {
|
||||
return server.reply({
|
||||
|
@ -52,8 +55,8 @@ export async function run(core, server, socket, data) {
|
|||
// notify mods
|
||||
server.broadcast({
|
||||
cmd: 'info',
|
||||
text: `${socket.nick}#${socket.trip} banned ${targetNick} in ${data.channel}, userhash: ${badClient.hash}`,
|
||||
channel: data.channel,
|
||||
text: `${socket.nick}#${socket.trip} banned ${targetNick} in ${payload.channel}, userhash: ${badClient.hash}`,
|
||||
channel: payload.channel,
|
||||
user: UAC.getUserDetails(badClient),
|
||||
banner: UAC.getUserDetails(socket),
|
||||
}, { level: UAC.isModerator });
|
||||
|
@ -67,7 +70,7 @@ export async function run(core, server, socket, data) {
|
|||
return true;
|
||||
}
|
||||
|
||||
//export const requiredData = ['nick'];
|
||||
// export const requiredData = ['nick'];
|
||||
export const info = {
|
||||
name: 'ban',
|
||||
description: 'Disconnects the target nickname in the same channel as calling socket & adds to ratelimiter',
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
/* eslint no-param-reassign: 0 */
|
||||
/* eslint no-multi-assign: 0 */
|
||||
|
||||
/*
|
||||
* Description: Make a user (spammer) dumb (mute)
|
||||
* Author: simple
|
||||
|
@ -13,19 +16,21 @@ export function init(core) {
|
|||
}
|
||||
|
||||
// module main
|
||||
export async function run(core, server, socket, data) {
|
||||
export async function run({
|
||||
core, server, socket, payload,
|
||||
}) {
|
||||
// increase rate limit chance and ignore if not admin or mod
|
||||
if (!UAC.isModerator(socket.level)) {
|
||||
return server.police.frisk(socket.address, 10);
|
||||
}
|
||||
|
||||
// check user input
|
||||
if (typeof data.userid !== 'number') {
|
||||
if (typeof payload.userid !== 'number') {
|
||||
return true;
|
||||
}
|
||||
|
||||
// find target user
|
||||
let badClient = server.findSockets({ channel: data.channel, userid: data.userid });
|
||||
let badClient = server.findSockets({ channel: payload.channel, userid: payload.userid });
|
||||
|
||||
if (badClient.length === 0) {
|
||||
return server.reply({
|
||||
|
@ -50,14 +55,14 @@ export async function run(core, server, socket, data) {
|
|||
};
|
||||
|
||||
// store allies if needed
|
||||
if (data.allies && Array.isArray(data.allies)) {
|
||||
record.allies = data.allies;
|
||||
if (payload.allies && Array.isArray(payload.allies)) {
|
||||
record.allies = payload.allies;
|
||||
}
|
||||
|
||||
// notify mods
|
||||
server.broadcast({
|
||||
cmd: 'info',
|
||||
text: `${socket.nick}#${socket.trip} muzzled ${badClient.nick} in ${data.channel}, userhash: ${badClient.hash}`,
|
||||
text: `${socket.nick}#${socket.trip} muzzled ${badClient.nick} in ${payload.channel}, userhash: ${badClient.hash}`,
|
||||
}, { level: UAC.isModerator });
|
||||
|
||||
return true;
|
||||
|
@ -71,7 +76,9 @@ export function initHooks(server) {
|
|||
}
|
||||
|
||||
// hook incoming chat commands, shadow-prevent chat if they are muzzled
|
||||
export function chatCheck(core, server, socket, payload) {
|
||||
export function chatCheck({
|
||||
core, server, socket, payload,
|
||||
}) {
|
||||
if (typeof payload.text !== 'string') {
|
||||
return false;
|
||||
}
|
||||
|
@ -116,10 +123,10 @@ export function chatCheck(core, server, socket, payload) {
|
|||
}
|
||||
|
||||
// shadow-prevent all invites from muzzled users
|
||||
export function inviteCheck(core, server, socket, payload) {
|
||||
export function inviteCheck({ core, socket, payload }) {
|
||||
if (core.muzzledHashes[socket.hash]) {
|
||||
// @todo convert to protocol 2
|
||||
/*const nickValid = Invite.checkNickname(payload.nick);
|
||||
/* const nickValid = Invite.checkNickname(payload.nick);
|
||||
if (nickValid !== null) {
|
||||
server.reply({
|
||||
cmd: 'warn', // @todo Remove english and change to numeric id
|
||||
|
@ -132,7 +139,7 @@ export function inviteCheck(core, server, socket, payload) {
|
|||
const channel = Invite.getChannel();
|
||||
|
||||
// send fake reply
|
||||
server.reply(Invite.createSuccessPayload(payload.nick, channel), socket);*/
|
||||
server.reply(Invite.createSuccessPayload(payload.nick, channel), socket); */
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -141,7 +148,9 @@ export function inviteCheck(core, server, socket, payload) {
|
|||
}
|
||||
|
||||
// shadow-prevent all whispers from muzzled users
|
||||
export function whisperCheck(core, server, socket, payload) {
|
||||
export function whisperCheck({
|
||||
core, server, socket, payload,
|
||||
}) {
|
||||
if (typeof payload.nick !== 'string') {
|
||||
return false;
|
||||
}
|
||||
|
@ -159,7 +168,8 @@ export function whisperCheck(core, server, socket, payload) {
|
|||
text: `You whispered to @${targetNick}: ${payload.text}`,
|
||||
}, socket);
|
||||
|
||||
// blanket "spam" protection, may expose the ratelimiting lines from `chat` and use that, TODO: one day #lazydev
|
||||
// blanket "spam" protection, may expose the ratelimiting lines from
|
||||
// `chat` and use that, @todo one day #lazydev
|
||||
server.police.frisk(socket.address, 9);
|
||||
|
||||
return false;
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
/* eslint no-console: 0 */
|
||||
|
||||
/*
|
||||
Description: Forces a change on the target(s) socket's channel, then broadcasts event
|
||||
*/
|
||||
|
@ -5,29 +7,31 @@
|
|||
import * as UAC from '../utility/UAC/_info';
|
||||
|
||||
// module main
|
||||
export async function run(core, server, socket, data) {
|
||||
export async function run({
|
||||
core, server, socket, payload,
|
||||
}) {
|
||||
// increase rate limit chance and ignore if not admin or mod
|
||||
if (!UAC.isModerator(socket.level)) {
|
||||
return server.police.frisk(socket.address, 10);
|
||||
}
|
||||
|
||||
// check user input
|
||||
if (typeof data.userid !== 'number') {
|
||||
if (typeof payload.userid !== 'number') {
|
||||
// @todo create multi-ban ui
|
||||
if (typeof data.userid !== 'object' && !Array.isArray(data.userid)) {
|
||||
if (typeof payload.userid !== 'object' && !Array.isArray(payload.userid)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
let destChannel;
|
||||
if (typeof data.to === 'string' && !!data.to.trim()) {
|
||||
destChannel = data.to;
|
||||
if (typeof payload.to === 'string' && !!payload.to.trim()) {
|
||||
destChannel = payload.to;
|
||||
} else {
|
||||
destChannel = Math.random().toString(36).substr(2, 8);
|
||||
}
|
||||
|
||||
// find target user(s)
|
||||
const badClients = server.findSockets({ channel: data.channel, userid: data.userid });
|
||||
const badClients = server.findSockets({ channel: payload.channel, userid: payload.userid });
|
||||
|
||||
if (badClients.length === 0) {
|
||||
return server.reply({
|
||||
|
@ -76,7 +80,6 @@ export async function run(core, server, socket, data) {
|
|||
console.log(`${socket.nick} [${socket.trip}] kicked ${kicked[i].nick} in ${socket.channel} to ${destChannel} `);
|
||||
}
|
||||
|
||||
|
||||
// broadcast client leave event
|
||||
for (let i = 0, j = kicked.length; i < j; i += 1) {
|
||||
server.broadcast({
|
||||
|
|
|
@ -5,23 +5,23 @@
|
|||
import * as UAC from '../utility/UAC/_info';
|
||||
|
||||
// module main
|
||||
export async function run(core, server, socket, data) {
|
||||
export async function run({ server, socket, payload }) {
|
||||
// increase rate limit chance and ignore if not admin or mod
|
||||
if (!UAC.isModerator(socket.level)) {
|
||||
return server.police.frisk(socket.address, 10);
|
||||
}
|
||||
|
||||
// check user input
|
||||
if (typeof data.nick !== 'string' || typeof data.channel !== 'string') {
|
||||
if (typeof payload.nick !== 'string' || typeof payload.channel !== 'string') {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (data.channel === socket.channel) {
|
||||
if (payload.channel === socket.channel) {
|
||||
// moving them into the same channel? y u do this?
|
||||
return true;
|
||||
}
|
||||
|
||||
const badClients = server.findSockets({ channel: socket.channel, nick: data.nick });
|
||||
const badClients = server.findSockets({ channel: socket.channel, nick: payload.nick });
|
||||
|
||||
if (badClients.length === 0) {
|
||||
return server.reply({
|
||||
|
@ -41,7 +41,7 @@ export async function run(core, server, socket, data) {
|
|||
|
||||
const currentNick = badClient.nick.toLowerCase();
|
||||
const userExists = server.findSockets({
|
||||
channel: data.channel,
|
||||
channel: payload.channel,
|
||||
nick: (targetNick) => targetNick.toLowerCase() === currentNick,
|
||||
});
|
||||
|
||||
|
@ -68,8 +68,8 @@ export async function run(core, server, socket, data) {
|
|||
}
|
||||
}
|
||||
|
||||
// TODO: import from join module
|
||||
const newPeerList = server.findSockets({ channel: data.channel });
|
||||
// @todo import from join module
|
||||
const newPeerList = server.findSockets({ channel: payload.channel });
|
||||
const moveAnnouncement = {
|
||||
cmd: 'onlineAdd',
|
||||
nick: badClient.nick,
|
||||
|
@ -90,12 +90,12 @@ export async function run(core, server, socket, data) {
|
|||
nicks,
|
||||
}, badClient);
|
||||
|
||||
badClient.channel = data.channel;
|
||||
badClient.channel = payload.channel;
|
||||
|
||||
server.broadcast({
|
||||
cmd: 'info',
|
||||
text: `${badClient.nick} was moved into ?${data.channel}`,
|
||||
}, { channel: data.channel });
|
||||
text: `${badClient.nick} was moved into ?${payload.channel}`,
|
||||
}, { channel: payload.channel });
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
/* eslint no-param-reassign: 0 */
|
||||
|
||||
/*
|
||||
* Description: Pardon a dumb user to be able to speak again
|
||||
* Author: simple
|
||||
|
@ -13,22 +15,24 @@ export function init(core) {
|
|||
}
|
||||
|
||||
// module main
|
||||
export async function run(core, server, socket, data) {
|
||||
export async function run({
|
||||
core, server, socket, payload,
|
||||
}) {
|
||||
// increase rate limit chance and ignore if not admin or mod
|
||||
if (!UAC.isModerator(socket.level)) {
|
||||
return server.police.frisk(socket.address, 10);
|
||||
}
|
||||
|
||||
// check user input
|
||||
if (typeof data.ip !== 'string' && typeof data.hash !== 'string') {
|
||||
if (typeof payload.ip !== 'string' && typeof payload.hash !== 'string') {
|
||||
return server.reply({
|
||||
cmd: 'warn', // @todo Remove english and change to numeric id
|
||||
text: "hash:'targethash' or ip:'1.2.3.4' is required",
|
||||
}, socket);
|
||||
}
|
||||
|
||||
if (typeof data.ip === 'string') {
|
||||
if (data.ip === '*') {
|
||||
if (typeof payload.ip === 'string') {
|
||||
if (payload.ip === '*') {
|
||||
core.muzzledHashes = {};
|
||||
|
||||
return server.broadcast({
|
||||
|
@ -36,7 +40,7 @@ export async function run(core, server, socket, data) {
|
|||
text: `${socket.nick} unmuzzled all users`,
|
||||
}, { level: UAC.isModerator });
|
||||
}
|
||||
} else if (data.hash === '*') {
|
||||
} else if (payload.hash === '*') {
|
||||
core.muzzledHashes = {};
|
||||
|
||||
return server.broadcast({
|
||||
|
@ -47,10 +51,10 @@ export async function run(core, server, socket, data) {
|
|||
|
||||
// find target & remove mute status
|
||||
let target;
|
||||
if (typeof data.ip === 'string') {
|
||||
target = server.getSocketHash(data.ip);
|
||||
if (typeof payload.ip === 'string') {
|
||||
target = server.getSocketHash(payload.ip);
|
||||
} else {
|
||||
target = data.hash;
|
||||
target = payload.hash;
|
||||
}
|
||||
|
||||
delete core.muzzledHashes[target];
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
/* eslint no-console: 0 */
|
||||
|
||||
/*
|
||||
Description: Removes a target ip from the ratelimiter
|
||||
*/
|
||||
|
@ -5,14 +7,16 @@
|
|||
import * as UAC from '../utility/UAC/_info';
|
||||
|
||||
// module main
|
||||
export async function run(core, server, socket, data) {
|
||||
export async function run({
|
||||
core, server, socket, payload,
|
||||
}) {
|
||||
// increase rate limit chance and ignore if not admin or mod
|
||||
if (!UAC.isModerator(socket.level)) {
|
||||
return server.police.frisk(socket.address, 10);
|
||||
}
|
||||
|
||||
// check user input
|
||||
if (typeof data.ip !== 'string' && typeof data.hash !== 'string') {
|
||||
if (typeof payload.ip !== 'string' && typeof payload.hash !== 'string') {
|
||||
return server.reply({
|
||||
cmd: 'warn', // @todo Remove english and change to numeric id
|
||||
text: "hash:'targethash' or ip:'1.2.3.4' is required",
|
||||
|
@ -22,12 +26,12 @@ export async function run(core, server, socket, data) {
|
|||
// find target
|
||||
let mode;
|
||||
let target;
|
||||
if (typeof data.ip === 'string') {
|
||||
if (typeof payload.ip === 'string') {
|
||||
mode = 'ip';
|
||||
target = data.ip;
|
||||
target = payload.ip;
|
||||
} else {
|
||||
mode = 'hash';
|
||||
target = data.hash;
|
||||
target = payload.hash;
|
||||
}
|
||||
|
||||
// remove arrest record
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
/* eslint no-console: 0 */
|
||||
|
||||
/*
|
||||
Description: Clears all bans and ratelimits
|
||||
*/
|
||||
|
@ -5,7 +7,7 @@
|
|||
import * as UAC from '../utility/UAC/_info';
|
||||
|
||||
// module main
|
||||
export async function run(core, server, socket) {
|
||||
export async function run({ core, server, socket }) {
|
||||
// increase rate limit chance and ignore if not admin or mod
|
||||
if (!UAC.isModerator(socket.level)) {
|
||||
return server.police.frisk(socket.address, 10);
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
/* eslint no-bitwise: 0 */
|
||||
/* eslint global-require: 0 */
|
||||
/* eslint class-methods-use-this: 0 */
|
||||
/* eslint no-param-reassign: 0 */
|
||||
/* eslint no-console: 0 */
|
||||
|
||||
import {
|
||||
start as _start,
|
||||
get,
|
||||
|
@ -8,6 +14,7 @@ import {
|
|||
* @author Marzavec ( https://github.com/marzavec )
|
||||
* @version v2.0.0
|
||||
* @license WTFPL ( http://www.wtfpl.net/txt/copying/ )
|
||||
* @todo Convert to use the `enquirer` package instead
|
||||
*/
|
||||
class SetupWizard {
|
||||
/**
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
/* eslint no-console: 0 */
|
||||
|
||||
/**
|
||||
* This script will be run before the package starts asking for the config data,
|
||||
* used to output a simple guide for the coming questions, or to spam some sexy
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
/* eslint no-console: 0 */
|
||||
|
||||
/**
|
||||
* This script will be run once all questions have finished and no errors have
|
||||
* occured. You can congratulate the user on their fine choice in software usage
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
/* eslint no-undef: 0 */
|
||||
/* eslint global-require: 0 */
|
||||
|
||||
/**
|
||||
* This object contains Prompt ( https://www.npmjs.com/package/prompt ) style
|
||||
* questions that the SetupWizard will require an answer to. Questions are asked
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
/* eslint no-console: 0 */
|
||||
|
||||
import {
|
||||
basename,
|
||||
join,
|
||||
|
@ -98,6 +100,7 @@ class CommandManager {
|
|||
.replace(new RegExp(sep.replace('\\', '\\\\'), 'g'), '/');
|
||||
}
|
||||
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
command.info.category = category;
|
||||
|
||||
if (this.categories.indexOf(category) === -1) {
|
||||
|
@ -126,6 +129,7 @@ class CommandManager {
|
|||
* @private
|
||||
* @return {String} Module errors or null if none
|
||||
*/
|
||||
// eslint-disable-next-line class-methods-use-this
|
||||
validateCommand(object) {
|
||||
if (typeof object !== 'object') { return 'command setup is invalid'; }
|
||||
if (typeof object.run !== 'function') { return 'run function is missing'; }
|
||||
|
@ -253,11 +257,11 @@ class CommandManager {
|
|||
* @private
|
||||
* @return {*} Arbitrary module return data
|
||||
*/
|
||||
async execute(command, server, socket, data) {
|
||||
async execute(command, server, socket, payload) {
|
||||
if (typeof command.requiredData !== 'undefined') {
|
||||
const missing = [];
|
||||
for (let i = 0, len = command.requiredData.length; i < len; i += 1) {
|
||||
if (typeof data[command.requiredData[i]] === 'undefined') { missing.push(command.requiredData[i]); }
|
||||
if (typeof payload[command.requiredData[i]] === 'undefined') { missing.push(command.requiredData[i]); }
|
||||
}
|
||||
|
||||
if (missing.length > 0) {
|
||||
|
@ -278,7 +282,12 @@ class CommandManager {
|
|||
}
|
||||
|
||||
try {
|
||||
return await command.run(this.core, server, socket, data);
|
||||
return await command.run({
|
||||
core: this.core,
|
||||
server,
|
||||
socket,
|
||||
payload,
|
||||
});
|
||||
} catch (err) {
|
||||
const errText = `Failed to execute '${command.info.name}': `;
|
||||
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
/* eslint no-console: 0 */
|
||||
|
||||
import dateFormat from 'dateformat';
|
||||
import {
|
||||
existsSync,
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
/* eslint no-console: 0 */
|
||||
|
||||
import { join } from 'path';
|
||||
import {
|
||||
CommandManager,
|
||||
|
@ -90,4 +92,4 @@ class CoreApp {
|
|||
}
|
||||
}
|
||||
|
||||
export { CoreApp };
|
||||
export { CoreApp as default };
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
/* eslint global-require: 0 */
|
||||
/* eslint no-console: 0 */
|
||||
|
||||
import {
|
||||
resolve,
|
||||
basename as _basename,
|
||||
|
@ -57,7 +60,7 @@ class ImportsManager {
|
|||
|
||||
let imported;
|
||||
try {
|
||||
imported = require(file);
|
||||
imported = require(file); // eslint-disable-line import/no-dynamic-require
|
||||
|
||||
if (!this.imports[dirName]) {
|
||||
this.imports[dirName] = {};
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
/* eslint no-bitwise: 0 */
|
||||
/* eslint no-console: 0 */
|
||||
|
||||
import {
|
||||
Server as WsServer,
|
||||
OPEN as SocketReady,
|
||||
|
@ -189,10 +192,6 @@ class MainServer extends WsServer {
|
|||
* Issue #1: hard coded `cmd` check
|
||||
* Issue #2: hard coded `cmd` value checks
|
||||
*/
|
||||
if (typeof payload.cmd === 'undefined') {
|
||||
return;
|
||||
}
|
||||
|
||||
if (typeof payload.cmd !== 'string') {
|
||||
return;
|
||||
}
|
||||
|
@ -509,7 +508,12 @@ class MainServer extends WsServer {
|
|||
|
||||
for (let i = 0, j = hooks.length; i < j; i += 1) {
|
||||
try {
|
||||
newPayload = hooks[i].run(this.core, this, socket, newPayload);
|
||||
newPayload = hooks[i].run({
|
||||
core: this.core,
|
||||
server: this,
|
||||
socket,
|
||||
payload: newPayload,
|
||||
});
|
||||
} catch (err) {
|
||||
const errText = `Hook failure, '${type}', '${command}': `;
|
||||
if (this.core.config.logErrDetailed === true) {
|
||||
|
|
|
@ -77,6 +77,7 @@ class RateLimiter {
|
|||
return true;
|
||||
}
|
||||
|
||||
// eslint-disable-next-line no-restricted-properties
|
||||
record.score *= Math.pow(2, -(Date.now() - record.time) / this.halflife);
|
||||
record.score += deltaScore;
|
||||
record.time = Date.now();
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
/* eslint global-require: 0 */
|
||||
|
||||
export const CommandManager = require('./CommandManager').default;
|
||||
export const ConfigManager = require('./ConfigManager').default;
|
||||
export const ImportsManager = require('./ImportsManager').default;
|
||||
|
|
Loading…
Reference in New Issue
Block a user