mirror of
https://github.com/hack-chat/main.git
synced 2024-03-22 13:20:33 +08:00
dev sync
This commit is contained in:
parent
76b30c8553
commit
b4553511f0
5
server/package-lock.json
generated
5
server/package-lock.json
generated
|
@ -18,6 +18,11 @@
|
|||
"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",
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
"author": "Marzavec",
|
||||
"license": "WTFPL",
|
||||
"dependencies": {
|
||||
"ascii-captcha": "0.0.3",
|
||||
"chalk": "^3.0.0",
|
||||
"common-tags": "^1.8.0",
|
||||
"dateformat": "^3.0.3",
|
||||
|
|
|
@ -2,14 +2,19 @@
|
|||
Description: Adds the target trip to the mod list then elevates the uType
|
||||
*/
|
||||
|
||||
import * as UAC from '../utility/UAC/_info';
|
||||
import {
|
||||
isAdmin,
|
||||
isModerator,
|
||||
levels,
|
||||
getUserDetails,
|
||||
} from '../utility/_UAC';
|
||||
|
||||
// module main
|
||||
export async function run({
|
||||
core, server, socket, payload,
|
||||
}) {
|
||||
// increase rate limit chance and ignore if not admin
|
||||
if (!UAC.isAdmin(socket.level)) {
|
||||
if (!isAdmin(socket.level)) {
|
||||
return server.police.frisk(socket.address, 20);
|
||||
}
|
||||
|
||||
|
@ -19,10 +24,20 @@ export async function run({
|
|||
// find targets current connections
|
||||
const newMod = server.findSockets({ trip: payload.trip });
|
||||
if (newMod.length !== 0) {
|
||||
// build update notice with new privileges
|
||||
const updateNotice = {
|
||||
...getUserDetails(newMod[0]),
|
||||
...{
|
||||
cmd: 'updateUser',
|
||||
uType: 'mod', // @todo use legacyLevelToLabel from _LegacyFunctions.js
|
||||
level: levels.moderator,
|
||||
},
|
||||
};
|
||||
|
||||
for (let i = 0, l = newMod.length; i < l; i += 1) {
|
||||
// upgrade privilages
|
||||
newMod[i].uType = 'mod';
|
||||
newMod[i].level = UAC.levels.moderator;
|
||||
newMod[i].uType = 'mod'; // @todo use legacyLevelToLabel from _LegacyFunctions.js
|
||||
newMod[i].level = levels.moderator;
|
||||
|
||||
// inform new mod
|
||||
server.send({
|
||||
|
@ -30,6 +45,14 @@ export async function run({
|
|||
text: 'You are now a mod.',
|
||||
channel: newMod[i].channel, // @todo Multichannel
|
||||
}, newMod[i]);
|
||||
|
||||
// notify channel
|
||||
server.broadcast({
|
||||
...updateNotice,
|
||||
...{
|
||||
channel: newMod[i].channel,
|
||||
},
|
||||
}, { channel: newMod[i].channel });
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -45,7 +68,7 @@ export async function run({
|
|||
cmd: 'info',
|
||||
text: `Added mod: ${payload.trip}`,
|
||||
channel: false, // @todo Multichannel, false for global info
|
||||
}, { level: UAC.isModerator });
|
||||
}, { level: isModerator });
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -6,12 +6,14 @@
|
|||
Description: Outputs all current channels and their user nicks
|
||||
*/
|
||||
|
||||
import * as UAC from '../utility/UAC/_info';
|
||||
import {
|
||||
isAdmin,
|
||||
} from '../utility/_UAC';
|
||||
|
||||
// module main
|
||||
export async function run({ server, socket }) {
|
||||
// increase rate limit chance and ignore if not admin
|
||||
if (!UAC.isAdmin(socket.level)) {
|
||||
if (!isAdmin(socket.level)) {
|
||||
return server.police.frisk(socket.address, 20);
|
||||
}
|
||||
|
||||
|
|
|
@ -2,14 +2,17 @@
|
|||
Description: Clears and resets the command modules, outputting any errors
|
||||
*/
|
||||
|
||||
import * as UAC from '../utility/UAC/_info';
|
||||
import {
|
||||
isAdmin,
|
||||
isModerator,
|
||||
} from '../utility/_UAC';
|
||||
|
||||
// module main
|
||||
export async function run({
|
||||
core, server, socket, payload,
|
||||
}) {
|
||||
// increase rate limit chance and ignore if not admin
|
||||
if (!UAC.isAdmin(socket.level)) {
|
||||
if (!isAdmin(socket.level)) {
|
||||
return server.police.frisk(socket.address, 20);
|
||||
}
|
||||
|
||||
|
@ -37,7 +40,7 @@ export async function run({
|
|||
cmd: 'info',
|
||||
text: loadResult,
|
||||
channel: false, // @todo Multichannel, false for global
|
||||
}, { level: UAC.isModerator });
|
||||
}, { level: isModerator });
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -2,14 +2,18 @@
|
|||
Description: Removes target trip from the config as a mod and downgrades the socket type
|
||||
*/
|
||||
|
||||
import * as UAC from '../utility/UAC/_info';
|
||||
import {
|
||||
isAdmin,
|
||||
isModerator,
|
||||
levels,
|
||||
} from '../utility/_UAC';
|
||||
|
||||
// module main
|
||||
export async function run({
|
||||
core, server, socket, payload,
|
||||
}) {
|
||||
// increase rate limit chance and ignore if not admin
|
||||
if (!UAC.isAdmin(socket.level)) {
|
||||
if (!isAdmin(socket.level)) {
|
||||
return server.police.frisk(socket.address, 20);
|
||||
}
|
||||
|
||||
|
@ -23,7 +27,7 @@ export async function run({
|
|||
for (let i = 0, l = targetMod.length; i < l; i += 1) {
|
||||
// downgrade privilages
|
||||
targetMod[i].uType = 'user';
|
||||
targetMod[i].level = UAC.levels.default;
|
||||
targetMod[i].level = levels.default;
|
||||
|
||||
// inform ex-mod
|
||||
server.send({
|
||||
|
@ -48,7 +52,7 @@ export async function run({
|
|||
cmd: 'info',
|
||||
text: `Removed mod: ${payload.trip}`,
|
||||
channel: false, // @todo Multichannel, false for global
|
||||
}, { level: UAC.isModerator });
|
||||
}, { level: isModerator });
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -2,12 +2,15 @@
|
|||
Description: Writes the current config to disk
|
||||
*/
|
||||
|
||||
import * as UAC from '../utility/UAC/_info';
|
||||
import {
|
||||
isAdmin,
|
||||
isModerator,
|
||||
} from '../utility/_UAC';
|
||||
|
||||
// module main
|
||||
export async function run({ core, server, socket }) {
|
||||
// increase rate limit chance and ignore if not admin
|
||||
if (!UAC.isAdmin(socket.level)) {
|
||||
if (!isAdmin(socket.level)) {
|
||||
return server.police.frisk(socket.address, 20);
|
||||
}
|
||||
|
||||
|
@ -25,7 +28,7 @@ export async function run({ core, server, socket }) {
|
|||
cmd: 'info',
|
||||
text: 'Config saved!',
|
||||
channel: false, // @todo Multichannel
|
||||
}, { level: UAC.isModerator });
|
||||
}, { level: isModerator });
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -2,12 +2,14 @@
|
|||
Description: Emmits a server-wide message as `info`
|
||||
*/
|
||||
|
||||
import * as UAC from '../utility/UAC/_info';
|
||||
import {
|
||||
isAdmin,
|
||||
} from '../utility/_UAC';
|
||||
|
||||
// module main
|
||||
export async function run({ server, socket, payload }) {
|
||||
// increase rate limit chance and ignore if not admin
|
||||
if (!UAC.isAdmin(socket.level)) {
|
||||
if (!isAdmin(socket.level)) {
|
||||
return server.police.frisk(socket.address, 20);
|
||||
}
|
||||
|
||||
|
|
111
server/src/commands/core/changecolor.js
Normal file
111
server/src/commands/core/changecolor.js
Normal file
|
@ -0,0 +1,111 @@
|
|||
/*
|
||||
Description: Allows calling client to change their nickname color
|
||||
*/
|
||||
|
||||
// module support functions
|
||||
const verifyColor = (color) => /(^[0-9A-F]{6}$)|(^[0-9A-F]{3}$)/i.test(color);
|
||||
|
||||
// module main
|
||||
export async function run({
|
||||
core, server, socket, payload,
|
||||
}) {
|
||||
const channel = socket.channel;
|
||||
|
||||
if (server.police.frisk(socket.address, 6)) {
|
||||
return server.reply({
|
||||
cmd: 'warn', // @todo Add numeric error code as `id`
|
||||
text: 'You are changing colors too fast. Wait a moment before trying again.',
|
||||
channel, // @todo Multichannel
|
||||
}, socket);
|
||||
}
|
||||
|
||||
// verify user data is string
|
||||
if (typeof payload.color !== 'string') {
|
||||
return true;
|
||||
}
|
||||
|
||||
// make sure requested nickname meets standards
|
||||
const newColor = payload.color.trim().toUpperCase().replace(/#/g, '');
|
||||
if (newColor !== 'RESET' && !verifyColor(newColor)) {
|
||||
return server.reply({
|
||||
cmd: 'warn',
|
||||
text: 'Invalid color! Color must be in hex value',
|
||||
channel, // @todo Multichannel
|
||||
}, socket);
|
||||
}
|
||||
|
||||
if (newColor === 'RESET') {
|
||||
socket.color = false;
|
||||
} else {
|
||||
socket.color = newColor;
|
||||
}
|
||||
|
||||
// build update notice with new color
|
||||
const updateNotice = {
|
||||
...getUserDetails(socket),
|
||||
...{
|
||||
cmd: 'updateUser',
|
||||
channel: socket.channel, // @todo Multichannel
|
||||
}
|
||||
};
|
||||
|
||||
// notify channel that the user has changed their name
|
||||
// @todo this should be sent to every channel the user is in (multichannel)
|
||||
server.broadcast(updateNotice, { channel: socket.channel });
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// module hook functions
|
||||
export function initHooks(server) {
|
||||
server.registerHook('in', 'chat', this.colorCheck.bind(this), 29);
|
||||
}
|
||||
|
||||
// hooks chat commands checking for /color
|
||||
export function colorCheck({
|
||||
core, server, socket, payload,
|
||||
}) {
|
||||
if (typeof payload.text !== 'string') {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (payload.text.startsWith('/color ')) {
|
||||
const input = payload.text.split(' ');
|
||||
|
||||
// If there is no color target parameter
|
||||
if (input[1] === undefined) {
|
||||
server.reply({
|
||||
cmd: 'warn',
|
||||
text: 'Refer to `/help changecolor` for instructions on how to use this command.',
|
||||
channel: socket.channel, // @todo Multichannel
|
||||
}, socket);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
this.run({
|
||||
core,
|
||||
server,
|
||||
socket,
|
||||
payload: {
|
||||
cmd: 'changecolor',
|
||||
color: input[1],
|
||||
},
|
||||
});
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return payload;
|
||||
}
|
||||
|
||||
// module meta
|
||||
export const requiredData = ['color'];
|
||||
export const info = {
|
||||
name: 'changecolor',
|
||||
description: 'This will change your nickname color',
|
||||
usage: `
|
||||
API: { cmd: 'changecolor', color: '<new color as hex>' }
|
||||
Text: /color <new color as hex>
|
||||
Removal: /color reset`,
|
||||
};
|
|
@ -4,17 +4,22 @@
|
|||
Description: Allows calling client to change their current nickname
|
||||
*/
|
||||
|
||||
import * as UAC from '../utility/UAC/_info';
|
||||
import {
|
||||
verifyNickname,
|
||||
getUserDetails,
|
||||
} from '../utility/_UAC';
|
||||
|
||||
// module main
|
||||
export async function run({
|
||||
core, server, socket, payload,
|
||||
}) {
|
||||
const channel = socket.channel;
|
||||
|
||||
if (server.police.frisk(socket.address, 6)) {
|
||||
return server.reply({
|
||||
cmd: 'warn', // @todo Add numeric error code as `id`
|
||||
text: 'You are changing nicknames too fast. Wait a moment before trying again.',
|
||||
channel: socket.channel, // @todo Multichannel
|
||||
channel, // @todo Multichannel
|
||||
}, socket);
|
||||
}
|
||||
|
||||
|
@ -27,11 +32,11 @@ export async function run({
|
|||
|
||||
// make sure requested nickname meets standards
|
||||
const newNick = payload.nick.trim();
|
||||
if (!UAC.verifyNickname(newNick)) {
|
||||
if (!verifyNickname(newNick)) {
|
||||
return server.reply({
|
||||
cmd: 'warn', // @todo Add numeric error code as `id`
|
||||
text: 'Nickname must consist of up to 24 letters, numbers, and underscores',
|
||||
channel: socket.channel, // @todo Multichannel
|
||||
channel, // @todo Multichannel
|
||||
}, socket);
|
||||
}
|
||||
|
||||
|
@ -43,7 +48,7 @@ export async function run({
|
|||
return server.reply({
|
||||
cmd: 'warn', // @todo Add numeric error code as `id`
|
||||
text: 'You are not the admin, liar!',
|
||||
channel: socket.channel, // @todo Multichannel
|
||||
channel, // @todo Multichannel
|
||||
}, socket);
|
||||
}
|
||||
|
||||
|
@ -51,13 +56,13 @@ export async function run({
|
|||
return server.reply({
|
||||
cmd: 'warn', // @todo Add numeric error code as `id`
|
||||
text: 'You already have that name',
|
||||
channel: socket.channel, // @todo Multichannel
|
||||
channel, // @todo Multichannel
|
||||
}, socket);
|
||||
}
|
||||
|
||||
// find any sockets that have the same nickname
|
||||
const userExists = server.findSockets({
|
||||
channel: socket.channel,
|
||||
channel,
|
||||
nick: (targetNick) => targetNick.toLowerCase() === newNick.toLowerCase()
|
||||
// Allow them to rename themselves to a different case
|
||||
&& targetNick != previousNick,
|
||||
|
@ -69,37 +74,57 @@ export async function run({
|
|||
return server.reply({
|
||||
cmd: 'warn', // @todo Add numeric error code as `id`
|
||||
text: 'Nickname taken',
|
||||
channel: socket.channel, // @todo Multichannel
|
||||
channel, // @todo Multichannel
|
||||
}, socket);
|
||||
}
|
||||
|
||||
// build join and leave notices
|
||||
// @todo this is a legacy client holdover, name changes in the future will
|
||||
// have thieir own event
|
||||
// build update notice with new nickname
|
||||
const updateNotice = {
|
||||
...getUserDetails(socket),
|
||||
...{
|
||||
cmd: 'updateUser',
|
||||
nick: newNick,
|
||||
channel, // @todo Multichannel
|
||||
}
|
||||
};
|
||||
|
||||
// build join and leave notices for legacy clients
|
||||
const leaveNotice = {
|
||||
cmd: 'onlineRemove',
|
||||
userid: socket.userid,
|
||||
nick: socket.nick,
|
||||
channel: socket.channel, // @todo Multichannel
|
||||
channel, // @todo Multichannel
|
||||
};
|
||||
|
||||
const joinNotice = {
|
||||
cmd: 'onlineAdd',
|
||||
nick: newNick,
|
||||
trip: socket.trip || 'null',
|
||||
hash: socket.hash,
|
||||
channel: socket.channel, // @todo Multichannel
|
||||
...getUserDetails(socket),
|
||||
...{
|
||||
cmd: 'onlineAdd',
|
||||
nick: newNick,
|
||||
channel, // @todo Multichannel
|
||||
},
|
||||
};
|
||||
|
||||
// broadcast remove event and join event with new name, this is to support legacy clients and bots
|
||||
server.broadcast(leaveNotice, { channel: socket.channel });
|
||||
server.broadcast(joinNotice, { channel: socket.channel });
|
||||
// gather channel peers
|
||||
const peerList = server.findSockets({ channel });
|
||||
for (let i = 0, l = peerList.length; i < l; i += 1) {
|
||||
if (peerList[i].hcProtocol === 1) {
|
||||
// send join/leave to legacy clients
|
||||
server.send(leaveNotice, peerList[i]);
|
||||
server.send(joinNotice, peerList[i]);
|
||||
} else {
|
||||
// send update info
|
||||
// @todo this should be sent to every channel the client is in
|
||||
server.send(updateNotice, peerList[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// notify channel that the user has changed their name
|
||||
server.broadcast({
|
||||
cmd: 'info',
|
||||
text: `${socket.nick} is now ${newNick}`,
|
||||
channel: socket.channel, // @todo Multichannel
|
||||
}, { channel: socket.channel });
|
||||
channel, // @todo Multichannel
|
||||
}, { channel });
|
||||
|
||||
// commit change to nickname
|
||||
socket.nick = newNick; // eslint-disable-line no-param-reassign
|
||||
|
|
|
@ -2,7 +2,10 @@
|
|||
Description: Rebroadcasts any `text` to all clients in a `channel`
|
||||
*/
|
||||
|
||||
import * as UAC from '../utility/UAC/_info';
|
||||
import {
|
||||
isAdmin,
|
||||
isModerator,
|
||||
} from '../utility/_UAC';
|
||||
|
||||
// module support functions
|
||||
const parseText = (text) => {
|
||||
|
@ -54,9 +57,9 @@ export async function run({
|
|||
level: socket.level,
|
||||
};
|
||||
|
||||
if (UAC.isAdmin(socket.level)) {
|
||||
if (isAdmin(socket.level)) {
|
||||
outgoingPayload.admin = true;
|
||||
} else if (UAC.isModerator(socket.level)) {
|
||||
} else if (isModerator(socket.level)) {
|
||||
outgoingPayload.mod = true;
|
||||
}
|
||||
|
||||
|
@ -64,6 +67,10 @@ export async function run({
|
|||
outgoingPayload.trip = socket.trip; /* @legacy */
|
||||
}
|
||||
|
||||
if (socket.color) {
|
||||
outgoingPayload.color = socket.color;
|
||||
}
|
||||
|
||||
// broadcast to channel peers
|
||||
server.broadcast(outgoingPayload, { channel: socket.channel });
|
||||
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
Description: Adds requested channel into the calling clients "subscribed channels"
|
||||
*/
|
||||
|
||||
// import * as UAC from '../utility/UAC/_info';
|
||||
import {
|
||||
canJoinChannel,
|
||||
} from '../utility/_Channels';
|
||||
|
@ -18,6 +17,7 @@ import {
|
|||
import {
|
||||
verifyNickname,
|
||||
getUserPerms,
|
||||
getUserDetails,
|
||||
} from '../utility/_UAC';
|
||||
|
||||
// module main
|
||||
|
@ -76,6 +76,7 @@ export async function run({
|
|||
|
||||
// get trip and level
|
||||
const { trip, level } = getUserPerms(pass, core.config, channel);
|
||||
|
||||
// store the user values
|
||||
const userInfo = {
|
||||
nick,
|
||||
|
@ -84,6 +85,8 @@ export async function run({
|
|||
hash: socket.hash,
|
||||
level,
|
||||
userid: socket.userid,
|
||||
isBot: socket.isBot,
|
||||
color: socket.color,
|
||||
channel,
|
||||
};
|
||||
|
||||
|
@ -119,18 +122,14 @@ export async function run({
|
|||
// send join announcement and prep online set reply
|
||||
for (let i = 0, l = newPeerList.length; i < l; i += 1) {
|
||||
server.reply(joinAnnouncement, newPeerList[i]);
|
||||
|
||||
nicks.push(newPeerList[i].nick); /* @legacy */
|
||||
|
||||
users.push({
|
||||
nick: newPeerList[i].nick,
|
||||
trip: newPeerList[i].trip,
|
||||
uType: newPeerList[i].uType, /* @legacy */
|
||||
hash: newPeerList[i].hash,
|
||||
level: newPeerList[i].level,
|
||||
userid: newPeerList[i].userid,
|
||||
channel,
|
||||
isme: false,
|
||||
isBot: newPeerList[i].isBot,
|
||||
...{
|
||||
channel,
|
||||
isme: false,
|
||||
},
|
||||
...getUserDetails(newPeerList[i]),
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -2,6 +2,11 @@
|
|||
Description: Changes the current channel of the calling socket
|
||||
@deprecated This module will be removed or replaced
|
||||
*/
|
||||
import {
|
||||
verifyNickname,
|
||||
getUserPerms,
|
||||
getUserDetails,
|
||||
} from '../utility/_UAC';
|
||||
|
||||
// module main
|
||||
export async function run({ server, socket, payload }) {
|
||||
|
@ -27,7 +32,7 @@ export async function run({ server, socket, payload }) {
|
|||
}, socket);
|
||||
}
|
||||
|
||||
if (payload.channel === socket.channel) {
|
||||
if (payload.channel === socket.channel) { // @todo Multichannel update
|
||||
// they are trying to rejoin the channel
|
||||
return true;
|
||||
}
|
||||
|
@ -52,41 +57,61 @@ export async function run({ server, socket, payload }) {
|
|||
server.reply({
|
||||
cmd: 'onlineRemove',
|
||||
nick: peerList[i].nick,
|
||||
userid: peerList[i].userid,
|
||||
channel: socket.channel, // @todo Multichannel
|
||||
}, socket);
|
||||
|
||||
if (socket.nick !== peerList[i].nick) {
|
||||
if (socket.userid !== peerList[i].userid) {
|
||||
server.reply({
|
||||
cmd: 'onlineRemove',
|
||||
nick: socket.nick,
|
||||
userid: socket.userid,
|
||||
channel: socket.channel, // @todo Multichannel
|
||||
}, peerList[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// @todo import function from join module
|
||||
// broadcast join notice to new peers
|
||||
const newPeerList = server.findSockets({ channel: payload.channel });
|
||||
const moveAnnouncement = {
|
||||
cmd: 'onlineAdd',
|
||||
nick: socket.nick,
|
||||
trip: socket.trip || 'null',
|
||||
hash: socket.hash,
|
||||
...{
|
||||
cmd: 'onlineAdd',
|
||||
channel: payload.channel, // @todo Multichannel
|
||||
},
|
||||
...getUserDetails(socket),
|
||||
};
|
||||
|
||||
const nicks = [];
|
||||
const users = [];
|
||||
|
||||
for (let i = 0, l = newPeerList.length; i < l; i += 1) {
|
||||
server.reply(moveAnnouncement, newPeerList[i]);
|
||||
nicks.push(newPeerList[i].nick);
|
||||
|
||||
nicks.push(newPeerList[i].nick); /* @legacy */
|
||||
users.push({
|
||||
...{
|
||||
channel: payload.channel,
|
||||
isme: false,
|
||||
},
|
||||
...getUserDetails(newPeerList[i]),
|
||||
});
|
||||
}
|
||||
|
||||
nicks.push(socket.nick);
|
||||
nicks.push(socket.nick); /* @legacy */
|
||||
users.push({
|
||||
...{
|
||||
channel: payload.channel,
|
||||
isme: true,
|
||||
},
|
||||
...getUserDetails(socket)
|
||||
});
|
||||
|
||||
// reply with new user list
|
||||
server.reply({
|
||||
cmd: 'onlineSet',
|
||||
nicks,
|
||||
users,
|
||||
channel: socket.channel, // @todo Multichannel (!)
|
||||
}, socket);
|
||||
|
||||
|
|
|
@ -55,6 +55,7 @@ export async function run({ server, socket, payload }) {
|
|||
socket.userid = Math.floor(Math.random() * 9999999999999);
|
||||
socket.hash = server.getSocketHash(socket);
|
||||
socket.isBot = payload.isBot || false;
|
||||
socket.color = false;
|
||||
|
||||
// dispatch info
|
||||
server.reply({
|
||||
|
|
|
@ -90,6 +90,8 @@ export async function run({ server, socket, payload }) {
|
|||
server.reply(outgoingPayload, socket);
|
||||
}
|
||||
|
||||
targetUser.whisperReply = socket.nick;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -161,6 +163,7 @@ export function whisperCheck({
|
|||
payload: {
|
||||
cmd: 'whisper',
|
||||
nick: socket.whisperReply,
|
||||
channel: socket.channel, // @todo Multichannel
|
||||
text: whisperText,
|
||||
},
|
||||
});
|
||||
|
|
|
@ -3,7 +3,11 @@
|
|||
Description: Adds the target socket's ip to the ratelimiter
|
||||
*/
|
||||
|
||||
import * as UAC from '../utility/UAC/_info';
|
||||
import {
|
||||
isModerator,
|
||||
getUserDetails,
|
||||
levels,
|
||||
} from '../utility/_UAC';
|
||||
import {
|
||||
Errors,
|
||||
} from '../utility/_Constants';
|
||||
|
@ -16,7 +20,7 @@ export async function run({
|
|||
core, server, socket, payload,
|
||||
}) {
|
||||
// increase rate limit chance and ignore if not admin or mod
|
||||
if (!UAC.isModerator(socket.level)) {
|
||||
if (!isModerator(socket.level)) {
|
||||
return server.police.frisk(socket.address, 10);
|
||||
}
|
||||
|
||||
|
@ -62,9 +66,9 @@ export async function run({
|
|||
server.broadcast({
|
||||
cmd: 'info',
|
||||
text: `Banned ${targetNick}`,
|
||||
user: UAC.getUserDetails(targetUser),
|
||||
user: getUserDetails(targetUser),
|
||||
channel: socket.channel, // @todo Multichannel
|
||||
}, { channel: socket.channel, level: (level) => level < UAC.levels.moderator });
|
||||
}, { channel: socket.channel, level: (level) => level < levels.moderator });
|
||||
|
||||
// notify mods
|
||||
server.broadcast({
|
||||
|
@ -72,9 +76,9 @@ export async function run({
|
|||
text: `${socket.nick}#${socket.trip} banned ${targetNick} in ${payload.channel}, userhash: ${targetUser.hash}`,
|
||||
channel: socket.channel, // @todo Multichannel
|
||||
inChannel: payload.channel,
|
||||
user: UAC.getUserDetails(targetUser),
|
||||
banner: UAC.getUserDetails(socket),
|
||||
}, { level: UAC.isModerator });
|
||||
user: getUserDetails(targetUser),
|
||||
banner: getUserDetails(socket),
|
||||
}, { level: isModerator });
|
||||
|
||||
// force connection closed
|
||||
targetUser.terminate();
|
||||
|
|
|
@ -6,7 +6,9 @@
|
|||
* Author: simple
|
||||
*/
|
||||
|
||||
import * as UAC from '../utility/UAC/_info';
|
||||
import {
|
||||
isModerator,
|
||||
} from '../utility/_UAC';
|
||||
import {
|
||||
Errors,
|
||||
} from '../utility/_Constants';
|
||||
|
@ -26,7 +28,7 @@ export async function run({
|
|||
core, server, socket, payload,
|
||||
}) {
|
||||
// increase rate limit chance and ignore if not admin or mod
|
||||
if (!UAC.isModerator(socket.level)) {
|
||||
if (!isModerator(socket.level)) {
|
||||
return server.police.frisk(socket.address, 10);
|
||||
}
|
||||
|
||||
|
@ -77,7 +79,7 @@ export async function run({
|
|||
cmd: 'info',
|
||||
text: `${socket.nick}#${socket.trip} muzzled ${targetUser.nick} in ${payload.channel}, userhash: ${targetUser.hash}`,
|
||||
channel: false, // @todo Multichannel, false for global
|
||||
}, { level: UAC.isModerator });
|
||||
}, { level: isModerator });
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -4,7 +4,11 @@
|
|||
Description: Forces a change on the target(s) socket's channel, then broadcasts event
|
||||
*/
|
||||
|
||||
import * as UAC from '../utility/UAC/_info';
|
||||
import {
|
||||
isModerator,
|
||||
levels,
|
||||
getUserDetails,
|
||||
} from '../utility/_UAC';
|
||||
import {
|
||||
Errors,
|
||||
} from '../utility/_Constants';
|
||||
|
@ -17,7 +21,7 @@ export async function run({
|
|||
core, server, socket, payload,
|
||||
}) {
|
||||
// increase rate limit chance and ignore if not admin or mod
|
||||
if (!UAC.isModerator(socket.level)) {
|
||||
if (!isModerator(socket.level)) {
|
||||
return server.police.frisk(socket.address, 10);
|
||||
}
|
||||
|
||||
|
@ -76,17 +80,15 @@ export async function run({
|
|||
|
||||
// Announce the kicked clients arrival in destChannel and that they were kicked
|
||||
// Before they arrive, so they don't see they got moved
|
||||
for (let i = 0; i < kicked.length; i += 1) {
|
||||
server.broadcast({
|
||||
const moveAnnouncement = {
|
||||
...getUserDetails(socket),
|
||||
...{
|
||||
cmd: 'onlineAdd',
|
||||
nick: kicked[i].nick,
|
||||
trip: kicked[i].trip || 'null',
|
||||
uType: 'user',
|
||||
hash: kicked[i].hash,
|
||||
level: UAC.levels.default,
|
||||
userid: kicked[i].userid,
|
||||
channel: destChannel,
|
||||
}, { channel: destChannel });
|
||||
channel: destChannel, // @todo Multichannel
|
||||
},
|
||||
};
|
||||
for (let i = 0; i < kicked.length; i += 1) {
|
||||
server.broadcast(moveAnnouncement, { channel: destChannel });
|
||||
}
|
||||
|
||||
// Move all kicked clients to the new channel
|
||||
|
@ -98,7 +100,7 @@ export async function run({
|
|||
cmd: 'info',
|
||||
text: `${kicked[i].nick} was banished to ?${destChannel}`,
|
||||
channel: socket.channel, // @todo Multichannel
|
||||
}, { channel: socket.channel, level: UAC.isModerator });
|
||||
}, { channel: socket.channel, level: isModerator });
|
||||
|
||||
console.log(`${socket.nick} [${socket.trip}] kicked ${kicked[i].nick} in ${socket.channel} to ${destChannel} `);
|
||||
}
|
||||
|
@ -118,7 +120,7 @@ export async function run({
|
|||
cmd: 'info',
|
||||
text: `Kicked ${kicked.map((k) => k.nick).join(', ')}`,
|
||||
channel: socket.channel, // @todo Multichannel
|
||||
}, { channel: socket.channel, level: (level) => level < UAC.levels.moderator });
|
||||
}, { channel: socket.channel, level: (level) => level < levels.moderator });
|
||||
|
||||
// stats are fun
|
||||
core.stats.increment('users-kicked', kicked.length);
|
||||
|
|
|
@ -3,12 +3,15 @@
|
|||
@deprecated This module will be removed or replaced
|
||||
*/
|
||||
|
||||
import * as UAC from '../utility/UAC/_info';
|
||||
import {
|
||||
isModerator,
|
||||
getUserDetails,
|
||||
} from '../utility/_UAC';
|
||||
|
||||
// module main
|
||||
export async function run({ server, socket, payload }) {
|
||||
// increase rate limit chance and ignore if not admin or mod
|
||||
if (!UAC.isModerator(socket.level)) {
|
||||
if (!isModerator(socket.level)) {
|
||||
return server.police.frisk(socket.address, 10);
|
||||
}
|
||||
|
||||
|
@ -59,6 +62,7 @@ export async function run({ server, socket, payload }) {
|
|||
for (let i = 0, l = peerList.length; i < l; i += 1) {
|
||||
server.reply({
|
||||
cmd: 'onlineRemove',
|
||||
userid: peerList[i].userid,
|
||||
nick: peerList[i].nick,
|
||||
channel: socket.channel, // @todo Multichannel
|
||||
}, badClient);
|
||||
|
@ -66,6 +70,7 @@ export async function run({ server, socket, payload }) {
|
|||
if (badClient.nick !== peerList[i].nick) {
|
||||
server.reply({
|
||||
cmd: 'onlineRemove',
|
||||
userid: badClient.userid,
|
||||
nick: badClient.nick,
|
||||
channel: socket.channel, // @todo Multichannel
|
||||
}, peerList[i]);
|
||||
|
@ -73,27 +78,43 @@ export async function run({ server, socket, payload }) {
|
|||
}
|
||||
}
|
||||
|
||||
// @todo import from join module
|
||||
|
||||
const newPeerList = server.findSockets({ channel: payload.channel });
|
||||
const moveAnnouncement = {
|
||||
cmd: 'onlineAdd',
|
||||
nick: badClient.nick,
|
||||
trip: badClient.trip || 'null',
|
||||
hash: server.getSocketHash(badClient),
|
||||
...getUserDetails(badClient),
|
||||
...{
|
||||
cmd: 'onlineAdd',
|
||||
channel: payload.channel, // @todo Multichannel
|
||||
},
|
||||
};
|
||||
const nicks = [];
|
||||
|
||||
const users = [];
|
||||
for (let i = 0, l = newPeerList.length; i < l; i += 1) {
|
||||
server.reply(moveAnnouncement, newPeerList[i]);
|
||||
nicks.push(newPeerList[i].nick);
|
||||
|
||||
nicks.push(newPeerList[i].nick); /* @legacy */
|
||||
users.push({
|
||||
...{
|
||||
channel,
|
||||
isme: false,
|
||||
},
|
||||
...getUserDetails(newPeerList[i]),
|
||||
});
|
||||
}
|
||||
|
||||
nicks.push(badClient.nick);
|
||||
nicks.push(badClient.nick); /* @legacy */
|
||||
users.push({
|
||||
...{
|
||||
isme: true,
|
||||
},
|
||||
...getUserDetails(badClient),
|
||||
});
|
||||
|
||||
server.reply({
|
||||
cmd: 'onlineSet',
|
||||
nicks,
|
||||
channel: socket.channel, // @todo Multichannel (!)
|
||||
nicks, /* @legacy */
|
||||
users,
|
||||
channel, // @todo Multichannel (?)
|
||||
}, badClient);
|
||||
|
||||
badClient.channel = payload.channel;
|
||||
|
@ -101,7 +122,7 @@ export async function run({ server, socket, payload }) {
|
|||
server.broadcast({
|
||||
cmd: 'info',
|
||||
text: `${badClient.nick} was moved into ?${payload.channel}`,
|
||||
channel: socket.channel, // @todo Multichannel
|
||||
channel: payload.channel, // @todo Multichannel
|
||||
}, { channel: payload.channel });
|
||||
|
||||
return true;
|
||||
|
|
|
@ -5,7 +5,9 @@
|
|||
* Author: simple
|
||||
*/
|
||||
|
||||
import * as UAC from '../utility/UAC/_info';
|
||||
import {
|
||||
isModerator,
|
||||
} from '../utility/_UAC';
|
||||
|
||||
// module constructor
|
||||
export function init(core) {
|
||||
|
@ -19,7 +21,7 @@ export async function run({
|
|||
core, server, socket, payload,
|
||||
}) {
|
||||
// increase rate limit chance and ignore if not admin or mod
|
||||
if (!UAC.isModerator(socket.level)) {
|
||||
if (!isModerator(socket.level)) {
|
||||
return server.police.frisk(socket.address, 10);
|
||||
}
|
||||
|
||||
|
@ -40,7 +42,7 @@ export async function run({
|
|||
cmd: 'info',
|
||||
text: `${socket.nick} unmuzzled all users`,
|
||||
channel: false, // @todo Multichannel, false for global
|
||||
}, { level: UAC.isModerator });
|
||||
}, { level: isModerator });
|
||||
}
|
||||
} else if (payload.hash === '*') {
|
||||
core.muzzledHashes = {};
|
||||
|
@ -49,7 +51,7 @@ export async function run({
|
|||
cmd: 'info',
|
||||
text: `${socket.nick} unmuzzled all users`,
|
||||
channel: false, // @todo Multichannel, false for global
|
||||
}, { level: UAC.isModerator });
|
||||
}, { level: isModerator });
|
||||
}
|
||||
|
||||
// find target & remove mute status
|
||||
|
@ -67,7 +69,7 @@ export async function run({
|
|||
cmd: 'info',
|
||||
text: `${socket.nick}#${socket.trip} unmuzzled : ${target}`,
|
||||
channel: false, // @todo Multichannel, false for global
|
||||
}, { level: UAC.isModerator });
|
||||
}, { level: isModerator });
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -4,14 +4,16 @@
|
|||
Description: Removes a target ip from the ratelimiter
|
||||
*/
|
||||
|
||||
import * as UAC from '../utility/UAC/_info';
|
||||
import {
|
||||
isModerator,
|
||||
} from '../utility/_UAC';
|
||||
|
||||
// module main
|
||||
export async function run({
|
||||
core, server, socket, payload,
|
||||
}) {
|
||||
// increase rate limit chance and ignore if not admin or mod
|
||||
if (!UAC.isModerator(socket.level)) {
|
||||
if (!isModerator(socket.level)) {
|
||||
return server.police.frisk(socket.address, 10);
|
||||
}
|
||||
|
||||
|
@ -56,7 +58,7 @@ export async function run({
|
|||
cmd: 'info',
|
||||
text: `${socket.nick}#${socket.trip} unbanned: ${target}`,
|
||||
channel: false, // @todo Multichannel, false for global
|
||||
}, { level: UAC.isModerator });
|
||||
}, { level: isModerator });
|
||||
|
||||
// stats are fun
|
||||
core.stats.decrement('users-banned');
|
||||
|
|
|
@ -4,12 +4,14 @@
|
|||
Description: Clears all bans and ratelimits
|
||||
*/
|
||||
|
||||
import * as UAC from '../utility/UAC/_info';
|
||||
import {
|
||||
isModerator,
|
||||
} from '../utility/_UAC';
|
||||
|
||||
// module main
|
||||
export async function run({ core, server, socket }) {
|
||||
// increase rate limit chance and ignore if not admin or mod
|
||||
if (!UAC.isModerator(socket.level)) {
|
||||
if (!isModerator(socket.level)) {
|
||||
return server.police.frisk(socket.address, 10);
|
||||
}
|
||||
|
||||
|
@ -32,7 +34,7 @@ export async function run({ core, server, socket }) {
|
|||
cmd: 'info',
|
||||
text: `${socket.nick}#${socket.trip} unbanned all ip addresses`,
|
||||
channel: false, // @todo Multichannel, false for global
|
||||
}, { level: UAC.isModerator });
|
||||
}, { level: isModerator });
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -1,119 +0,0 @@
|
|||
// NOTE: this has been moved into /utility/ as _UAC.js
|
||||
/**
|
||||
* User Account Control information containing level constants
|
||||
* and simple helper functions related to users
|
||||
* @property {Object} levels - Defines labels for default permission ranges
|
||||
* @author MinusGix ( https://github.com/MinusGix )
|
||||
* @version v1.0.0
|
||||
* @license WTFPL ( http://www.wtfpl.net/txt/copying/ )
|
||||
*/
|
||||
|
||||
/**
|
||||
* Object defining labels for default permission ranges
|
||||
* @typedef {Object} levels
|
||||
* @property {number} admin Global administrator range
|
||||
* @property {number} moderator Global moderator range
|
||||
* @property {number} channelOwner Local administrator range
|
||||
* @property {number} channelModerator Local moderator range
|
||||
* @property {number} channelTrusted Local (non-public) channel trusted
|
||||
* @property {number} trustedUser Public channel trusted
|
||||
* @property {number} default Default user level
|
||||
*/
|
||||
export const levels = {
|
||||
admin: 9999999,
|
||||
moderator: 999999,
|
||||
|
||||
channelOwner: 99999,
|
||||
channelModerator: 9999,
|
||||
channelTrusted: 8999,
|
||||
|
||||
trustedUser: 500,
|
||||
default: 100,
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns true if target level is equal or greater than the global admin level
|
||||
* @public
|
||||
* @param {number} level Level to verify
|
||||
* @return {boolean}
|
||||
*/
|
||||
export function isAdmin(level) {
|
||||
return level >= levels.admin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if target level is equal or greater than the global moderator level
|
||||
* @public
|
||||
* @param {number} level Level to verify
|
||||
* @return {boolean}
|
||||
*/
|
||||
export function isModerator(level) {
|
||||
return level >= levels.moderator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if target level is equal or greater than the channel owner level
|
||||
* @public
|
||||
* @param {number} level Level to verify
|
||||
* @return {boolean}
|
||||
*/
|
||||
export function isChannelOwner(level) {
|
||||
return level >= levels.channelOwner;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if target level is equal or greater than the channel moderator level
|
||||
* @public
|
||||
* @param {number} level Level to verify
|
||||
* @return {boolean}
|
||||
*/
|
||||
export function isChannelModerator(level) {
|
||||
return level >= levels.channelModerator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if target level is equal or greater than the channel trust level
|
||||
* @public
|
||||
* @param {number} level Level to verify
|
||||
* @return {boolean}
|
||||
*/
|
||||
export function isChannelTrusted(level) {
|
||||
return level >= levels.channelTrusted;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if target level is equal or greater than a trusted user
|
||||
* @public
|
||||
* @param {number} level Level to verify
|
||||
* @return {boolean}
|
||||
*/
|
||||
export function isTrustedUser(level) {
|
||||
return level >= levels.trustedUser;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an object containing public information about the socket
|
||||
* @public
|
||||
* @param {WebSocket} socket Target client
|
||||
* @return {Object}
|
||||
*/
|
||||
export function getUserDetails(socket) {
|
||||
return {
|
||||
uType: socket.uType,
|
||||
nick: socket.nick,
|
||||
trip: socket.trip || 'null',
|
||||
hash: socket.hash,
|
||||
level: socket.level,
|
||||
userid: socket.userid,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the nickname is valid
|
||||
* @public
|
||||
* @param {string} nick Nickname to verify
|
||||
* @return {boolean}
|
||||
*/
|
||||
export function verifyNickname(nick) {
|
||||
return /^[a-zA-Z0-9_]{1,24}$/.test(nick);
|
||||
}
|
|
@ -22,6 +22,7 @@ export function upgradeLegacyJoin(server, socket, payload) {
|
|||
// these would have been applied in the `session` module, apply it now
|
||||
socket.hash = server.getSocketHash(socket);
|
||||
socket.isBot = false;
|
||||
socket.color = false;
|
||||
|
||||
// pull the password from the nick
|
||||
const nickArray = payload.nick.split('#', 2);
|
||||
|
|
|
@ -104,12 +104,14 @@ export function isTrustedUser(level) {
|
|||
*/
|
||||
export function getUserDetails(socket) {
|
||||
return {
|
||||
uType: socket.uType,
|
||||
nick: socket.nick,
|
||||
trip: socket.trip || 'null',
|
||||
trip: socket.trip || '',
|
||||
uType: socket.uType,
|
||||
hash: socket.hash,
|
||||
level: socket.level,
|
||||
userid: socket.userid,
|
||||
isBot: socket.isBot,
|
||||
color: socket.color,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -154,13 +156,12 @@ export function getUserPerms(pass, config, channel) {
|
|||
};
|
||||
}
|
||||
|
||||
let level = levels.default;
|
||||
|
||||
// check if user is global mod
|
||||
config.mods.forEach((mod) => { // eslint-disable-line consistent-return
|
||||
if (trip === mod.trip) {
|
||||
return {
|
||||
trip,
|
||||
level: levels.moderator,
|
||||
};
|
||||
level = levels.moderator;
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -181,6 +182,6 @@ export function getUserPerms(pass, config, channel) {
|
|||
|
||||
return {
|
||||
trip,
|
||||
level: levels.default,
|
||||
level,
|
||||
};
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user