aboutsummaryrefslogtreecommitdiffstats
path: root/server
diff options
context:
space:
mode:
authormarzavec <admin@marzavec.com>2020-03-12 19:28:20 +0100
committermarzavec <admin@marzavec.com>2020-03-12 19:28:20 +0100
commit2b6e771383f4c6f392b32ce26e4d759b56791132 (patch)
treeb8c1cefecbd7f5816a3fb5ddc4bdb6bdfe463ba2 /server
parentMerge pull request #96 from MinusGix/fixKickHash (diff)
downloadhackchat-2b6e771383f4c6f392b32ce26e4d759b56791132.tar.gz
hackchat-2b6e771383f4c6f392b32ce26e4d759b56791132.zip
Protocol Updates and Bug Fixes
Diffstat (limited to 'server')
-rw-r--r--server/package-lock.json39
-rw-r--r--server/package.json6
-rw-r--r--server/src/commands/admin/reload.js2
-rw-r--r--server/src/commands/admin/saveconfig.js2
-rw-r--r--server/src/commands/core/emote.js8
-rw-r--r--server/src/commands/core/join.js61
-rw-r--r--server/src/commands/core/move.js45
-rw-r--r--server/src/commands/core/ping.js4
-rw-r--r--server/src/commands/core/session.js13
-rw-r--r--server/src/commands/core/whisper.js3
-rw-r--r--server/src/commands/mod/dumb.js34
-rw-r--r--server/src/commands/mod/moveuser.js1
-rw-r--r--server/src/commands/mod/speak.js18
-rw-r--r--server/src/commands/mod/unban.js4
-rw-r--r--server/src/commands/mod/unbanall.js2
15 files changed, 187 insertions, 55 deletions
diff --git a/server/package-lock.json b/server/package-lock.json
index 6957232..6a1b8c3 100644
--- a/server/package-lock.json
+++ b/server/package-lock.json
@@ -10,24 +10,24 @@
"integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ=="
},
"ansi-styles": {
- "version": "4.2.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.0.tgz",
- "integrity": "sha512-7kFQgnEaMdRtwf6uSfUnVr9gSGC7faurn+J/Mv90/W+iTtN0405/nLdopfMWwchyxhbGYl6TC4Sccn9TUkGAgg==",
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
+ "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
"requires": {
"@types/color-name": "^1.1.1",
"color-convert": "^2.0.1"
}
},
+ "ascii-captcha": {
+ "version": "0.0.3",
+ "resolved": "https://registry.npmjs.org/ascii-captcha/-/ascii-captcha-0.0.3.tgz",
+ "integrity": "sha1-NAtO1oVYOHEHsJVzBC/kc4v0mPk="
+ },
"async": {
"version": "0.9.2",
"resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz",
"integrity": "sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0="
},
- "async-limiter": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz",
- "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ=="
- },
"balanced-match": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
@@ -95,13 +95,12 @@
"integrity": "sha1-hLdFiW80xoTpjyzg5Cq69Du6AX0="
},
"didyoumean2": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/didyoumean2/-/didyoumean2-3.1.2.tgz",
- "integrity": "sha512-5j2ZwqqXoNIUxgNWcwsqOXECB+2br7pXCBf7E3bymh9pHINvcL8knXkP67iMK/CNGZk/tf40ixCfjFV4osdFBA==",
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/didyoumean2/-/didyoumean2-4.0.0.tgz",
+ "integrity": "sha512-7+OMIHqPDJ4uxeExQx8cSk26oD3KUloAQzi2R+3rmTU4IHvSDDmWZTQ6bmC4+MTw61DkYoh5ARxwS9MRoz0t2A==",
"requires": {
"leven": "^3.1.0",
- "lodash.deburr": "^4.1.0",
- "ramda": "^0.26.1"
+ "lodash.deburr": "^4.1.0"
}
},
"esm": {
@@ -256,11 +255,6 @@
"winston": "2.1.x"
}
},
- "ramda": {
- "version": "0.26.1",
- "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.26.1.tgz",
- "integrity": "sha512-hLWjpy7EnsDBb0p+Z3B7rPi3GDeRG5ZtiI33kJhTt+ORCd38AbAIjB/9zRIUoeTbE/AVX5ZkU7m6bznsvrf8eQ=="
- },
"read": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/read/-/read-1.0.7.tgz",
@@ -355,12 +349,9 @@
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
},
"ws": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/ws/-/ws-7.2.0.tgz",
- "integrity": "sha512-+SqNqFbwTm/0DC18KYzIsMTnEWpLwJsiasW/O17la4iDRRIO9uaHbvKiAS3AHgTiuuWerK/brj4O6MYZkei9xg==",
- "requires": {
- "async-limiter": "^1.0.0"
- }
+ "version": "7.2.3",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-7.2.3.tgz",
+ "integrity": "sha512-HTDl9G9hbkNDk98naoR/cHDws7+EyYMOdL1BmjsZXRUjf7d+MficC4B7HLUPlSiho0vg+CWKrGIt/VJBd1xunQ=="
}
}
}
diff --git a/server/package.json b/server/package.json
index 311a591..f6a9a90 100644
--- a/server/package.json
+++ b/server/package.json
@@ -1,6 +1,6 @@
{
"name": "hack.chat-v2",
- "version": "2.1.9",
+ "version": "2.1.93",
"description": "a minimal distraction free chat application",
"main": "main.js",
"repository": {
@@ -21,11 +21,11 @@
"chalk": "^3.0.0",
"common-tags": "^1.8.0",
"dateformat": "^3.0.3",
- "didyoumean2": "^3.1.2",
+ "didyoumean2": "^4.0.0",
"esm": "^3.2.25",
"fs-extra": "^8.1.0",
"prompt": "^1.0.0",
"readdir-recursive": "0.0.4",
- "ws": "^7.2.0"
+ "ws": "^7.2.3"
}
}
diff --git a/server/src/commands/admin/reload.js b/server/src/commands/admin/reload.js
index f74624e..a1d22ac 100644
--- a/server/src/commands/admin/reload.js
+++ b/server/src/commands/admin/reload.js
@@ -31,7 +31,7 @@ export async function run(core, server, socket, data) {
}
// send results to moderators (which the user using this command is higher than)
- server.reply({
+ server.broadcast({
cmd: 'info',
text: loadResult,
}, { level: UAC.isModerator });
diff --git a/server/src/commands/admin/saveconfig.js b/server/src/commands/admin/saveconfig.js
index b9411af..260ff14 100644
--- a/server/src/commands/admin/saveconfig.js
+++ b/server/src/commands/admin/saveconfig.js
@@ -20,7 +20,7 @@ export async function run(core, server, socket) {
}
// return success message to moderators and admins
- server.reply({
+ server.broadcast({
cmd: 'info',
text: 'Config saved!',
}, { level: UAC.isModerator });
diff --git a/server/src/commands/core/emote.js b/server/src/commands/core/emote.js
index 19a5fbe..21d14d1 100644
--- a/server/src/commands/core/emote.js
+++ b/server/src/commands/core/emote.js
@@ -22,7 +22,7 @@ const parseText = (text) => {
// module main
export async function run(core, server, socket, payload) {
// check user input
- const text = parseText(payload.text);
+ let text = parseText(payload.text);
if (!text) {
// lets not send objects or empty text, yea?
@@ -38,11 +38,15 @@ export async function run(core, server, socket, payload) {
}, socket);
}
+ if (!text.startsWith("'")) {
+ text = ` ${text}`;
+ }
+
const newPayload = {
cmd: 'info',
type: 'emote',
nick: socket.nick,
- text: `@${socket.nick} ${text}`,
+ text: `@${socket.nick}${text}`,
};
if (socket.trip) {
newPayload.trip = socket.trip;
diff --git a/server/src/commands/core/join.js b/server/src/commands/core/join.js
index ddbdf6d..b17e1fc 100644
--- a/server/src/commands/core/join.js
+++ b/server/src/commands/core/join.js
@@ -18,7 +18,7 @@ const hash = (password) => {
export function parseNickname(core, data) {
const userInfo = {
nick: '',
- uType: 'user',
+ uType: 'user', /* @legacy */
trip: null,
level: UAC.levels.default,
};
@@ -41,7 +41,7 @@ export function parseNickname(core, data) {
}
if (hash(password + core.config.tripSalt) === core.config.adminTrip) {
- userInfo.uType = 'admin';
+ userInfo.uType = 'admin'; /* @legacy */
userInfo.trip = 'Admin';
userInfo.level = UAC.levels.admin;
} else if (userInfo.nick.toLowerCase() === core.config.adminName.toLowerCase()) {
@@ -55,7 +55,7 @@ export function parseNickname(core, data) {
// for (const mod of core.config.mods) {
core.config.mods.forEach((mod) => {
if (userInfo.trip === mod.trip) {
- userInfo.uType = 'mod';
+ userInfo.uType = 'mod'; /* @legacy */
userInfo.level = UAC.levels.moderator;
}
});
@@ -111,40 +111,73 @@ export async function run(core, server, socket, data) {
}, socket);
}
- userInfo.userHash = server.getSocketHash(socket);
+ userInfo.hash = server.getSocketHash(socket);
+ // assign "unique" socket ID
+ if (typeof socket.userid === 'undefined') {
+ userInfo.userid = Math.floor(Math.random() * 9999999999999);
+ }
+
+ // TODO: place this within it's own function allowing import
// prepare to notify channel peers
const newPeerList = server.findSockets({ channel: data.channel });
- const nicks = [];
+ const nicks = []; /* @legacy */
+ const users = [];
const joinAnnouncement = {
cmd: 'onlineAdd',
nick: userInfo.nick,
trip: userInfo.trip || 'null',
- hash: userInfo.userHash,
+ utype: userInfo.uType, /* @legacy */
+ hash: userInfo.hash,
level: userInfo.level,
+ userid: userInfo.userid,
+ channel: data.channel,
};
// send join announcement and prep online set
for (let i = 0, l = newPeerList.length; i < l; i += 1) {
server.reply(joinAnnouncement, newPeerList[i]);
- nicks.push(newPeerList[i].nick);
+ nicks.push(newPeerList[i].nick); /* @legacy */
+
+ users.push({
+ nick: newPeerList[i].nick,
+ trip: newPeerList[i].trip,
+ utype: newPeerList[i].uType, /* @legacy */
+ hash: newPeerList[i].userHash,
+ level: newPeerList[i].level,
+ userid: newPeerList[i].userid,
+ channel: data.channel,
+ isme: false,
+ });
}
// store user info
- socket.uType = userInfo.uType;
+ socket.uType = userInfo.uType; /* @legacy */
socket.nick = userInfo.nick;
- socket.channel = data.channel;
- socket.hash = userInfo.userHash;
+ socket.trip = userInfo.trip;
+ socket.channel = data.channel; /* @legacy */
+ socket.hash = userInfo.hash;
socket.level = userInfo.level;
- if (userInfo.trip !== null) socket.trip = userInfo.trip;
-
- nicks.push(socket.nick);
+ socket.userid = userInfo.userid;
+
+ nicks.push(socket.nick); /* @legacy */
+ users.push({
+ nick: socket.nick,
+ trip: socket.trip,
+ utype: socket.uType,
+ hash: socket.userHash,
+ level: socket.level,
+ userid: socket.userid,
+ channel: data.channel,
+ isme: true,
+ });
// reply with channel peer list
server.reply({
cmd: 'onlineSet',
- nicks,
+ nicks, /* @legacy */
+ users,
}, socket);
// stats are fun
diff --git a/server/src/commands/core/move.js b/server/src/commands/core/move.js
index 7eda88c..fdafab4 100644
--- a/server/src/commands/core/move.js
+++ b/server/src/commands/core/move.js
@@ -17,6 +17,13 @@ export async function run(core, server, socket, data) {
return true;
}
+ if (data.channel === '') {
+ return server.reply({
+ cmd: 'warn',
+ text: 'Cannot move to an empty channel.',
+ }, socket);
+ }
+
if (data.channel === socket.channel) {
// they are trying to rejoin the channel
return true;
@@ -53,6 +60,7 @@ export async function run(core, server, socket, data) {
}
}
+ // TODO: import function from join module
// broadcast join notice to new peers
const newPeerList = server.findSockets({ channel: data.channel });
const moveAnnouncement = {
@@ -82,10 +90,45 @@ export async function run(core, server, socket, data) {
return true;
}
+// module hook functions
+export function initHooks(server) {
+ server.registerHook('in', 'chat', this.moveCheck.bind(this), 29);
+}
+
+export function moveCheck(core, server, socket, payload) {
+ if (typeof payload.text !== 'string') {
+ return false;
+ }
+
+ if (payload.text.startsWith('/move ')) {
+ const input = payload.text.split(' ');
+
+ // If there is no channel target parameter
+ if (input[1] === undefined) {
+ server.reply({
+ cmd: 'warn',
+ text: 'Refer to `/help move` for instructions on how to use this command.',
+ }, socket);
+
+ return false;
+ }
+
+ this.run(core, server, socket, {
+ cmd: 'move',
+ channel: input[1],
+ });
+
+ return false;
+ }
+
+ return payload;
+}
+
export const requiredData = ['channel'];
export const info = {
name: 'move',
description: 'This will change your current channel to the new one provided',
usage: `
- API: { cmd: 'move', channel: '<target channel>' }`,
+ API: { cmd: 'move', channel: '<target channel>' }
+ Text: /move <new channel>`,
};
diff --git a/server/src/commands/core/ping.js b/server/src/commands/core/ping.js
index 7d8623d..6266f4c 100644
--- a/server/src/commands/core/ping.js
+++ b/server/src/commands/core/ping.js
@@ -3,9 +3,7 @@
*/
// module main
-export async function run() {
-
-}
+export async function run() { }
export const info = {
name: 'ping',
diff --git a/server/src/commands/core/session.js b/server/src/commands/core/session.js
new file mode 100644
index 0000000..677e9a4
--- /dev/null
+++ b/server/src/commands/core/session.js
@@ -0,0 +1,13 @@
+/*
+ Description: Create a new socket session or restore previous session
+*/
+
+// module main
+export async function run() { }
+
+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>' }`
+};
diff --git a/server/src/commands/core/whisper.js b/server/src/commands/core/whisper.js
index 0c2e2d3..4424cd2 100644
--- a/server/src/commands/core/whisper.js
+++ b/server/src/commands/core/whisper.js
@@ -88,7 +88,7 @@ export function whisperCheck(core, server, socket, payload) {
return false;
}
- if (payload.text.startsWith('/whisper')) {
+ if (payload.text.startsWith('/whisper') || payload.text.startsWith('/w ')) {
const input = payload.text.split(' ');
// If there is no nickname target parameter
@@ -147,5 +147,6 @@ export const info = {
usage: `
API: { cmd: 'whisper', nick: '<target name>', text: '<text to whisper>' }
Text: /whisper <target name> <text to whisper>
+ Text: /w <target name> <text to whisper>
Alt Text: /r <text to whisper, this will auto reply to the last person who whispered to you>`,
};
diff --git a/server/src/commands/mod/dumb.js b/server/src/commands/mod/dumb.js
index 51fc745..ba2886d 100644
--- a/server/src/commands/mod/dumb.js
+++ b/server/src/commands/mod/dumb.js
@@ -66,9 +66,9 @@ export async function run(core, server, socket, data) {
// module hook functions
export function initHooks(server) {
- server.registerHook('in', 'chat', this.chatCheck.bind(this), 25);
- server.registerHook('in', 'invite', this.inviteCheck.bind(this), 25);
- // TODO: add whisper hook, need hook priorities todo finished first
+ server.registerHook('in', 'chat', this.chatCheck.bind(this), 10);
+ server.registerHook('in', 'invite', this.inviteCheck.bind(this), 10);
+ server.registerHook('in', 'whisper', this.whisperCheck.bind(this), 10);
}
// hook incoming chat commands, shadow-prevent chat if they are muzzled
@@ -140,6 +140,34 @@ export function inviteCheck(core, server, socket, payload) {
return payload;
}
+// shadow-prevent all whispers from muzzled users
+export function whisperCheck(core, server, socket, payload) {
+ if (typeof payload.nick !== 'string') {
+ return false;
+ }
+
+ if (typeof payload.text !== 'string') {
+ return false;
+ }
+
+ if (core.muzzledHashes[socket.hash]) {
+ const targetNick = payload.nick;
+
+ server.reply({
+ cmd: 'info',
+ type: 'whisper',
+ 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
+ server.police.frisk(socket.address, 9);
+
+ return false;
+ }
+
+ return payload;
+}
+
export const requiredData = ['nick'];
export const info = {
name: 'dumb',
diff --git a/server/src/commands/mod/moveuser.js b/server/src/commands/mod/moveuser.js
index 4b5d52c..b86edb4 100644
--- a/server/src/commands/mod/moveuser.js
+++ b/server/src/commands/mod/moveuser.js
@@ -68,6 +68,7 @@ export async function run(core, server, socket, data) {
}
}
+ // TODO: import from join module
const newPeerList = server.findSockets({ channel: data.channel });
const moveAnnouncement = {
cmd: 'onlineAdd',
diff --git a/server/src/commands/mod/speak.js b/server/src/commands/mod/speak.js
index f184ef5..e5ff8e2 100644
--- a/server/src/commands/mod/speak.js
+++ b/server/src/commands/mod/speak.js
@@ -27,6 +27,24 @@ export async function run(core, server, socket, data) {
}, socket);
}
+ if (typeof data.ip === 'string') {
+ if (data.ip === '*') {
+ core.muzzledHashes = {};
+
+ return server.broadcast({
+ cmd: 'info',
+ text: `${socket.nick} unmuzzled all users`,
+ }, { level: UAC.isModerator });
+ }
+ } else if (data.hash === '*') {
+ core.muzzledHashes = {};
+
+ return server.broadcast({
+ cmd: 'info',
+ text: `${socket.nick} unmuzzled all users`,
+ }, { level: UAC.isModerator });
+ }
+
// find target & remove mute status
let target;
if (typeof data.ip === 'string') {
diff --git a/server/src/commands/mod/unban.js b/server/src/commands/mod/unban.js
index 9f50e92..3b72fdc 100644
--- a/server/src/commands/mod/unban.js
+++ b/server/src/commands/mod/unban.js
@@ -20,8 +20,8 @@ export async function run(core, server, socket, data) {
}
// find target
- let mode; let
- target;
+ let mode;
+ let target;
if (typeof data.ip === 'string') {
mode = 'ip';
target = data.ip;
diff --git a/server/src/commands/mod/unbanall.js b/server/src/commands/mod/unbanall.js
index a5de3c8..9d417aa 100644
--- a/server/src/commands/mod/unbanall.js
+++ b/server/src/commands/mod/unbanall.js
@@ -14,6 +14,8 @@ export async function run(core, server, socket) {
// remove arrest records
server.police.clear();
+ core.stats.set('users-banned', 0);
+
console.log(`${socket.nick} [${socket.trip}] unbanned all`);
// reply with success