1
0
mirror of https://github.com/hack-chat/main.git synced 2024-03-22 13:20:33 +08:00

135 lines
3.1 KiB
JavaScript
Raw Normal View History

2018-03-09 23:47:00 -08:00
/*
Description: Initial entry point, applies `channel` and `nick` to the calling socket
2018-03-09 23:47:00 -08:00
*/
const crypto = require('crypto');
const hash = (password) => {
let sha = crypto.createHash('sha256');
2018-03-09 23:47:00 -08:00
sha.update(password);
return sha.digest('base64').substr(0, 6);
};
2018-03-09 23:47:00 -08:00
const verifyNickname = (nick) => {
2018-03-09 23:47:00 -08:00
return /^[a-zA-Z0-9_]{1,24}$/.test(nick);
};
2018-03-09 23:47:00 -08:00
exports.run = async (core, server, socket, data) => {
if (server._police.frisk(socket.remoteAddress, 3)) {
server.reply({
cmd: 'warn',
text: 'You are joining channels too fast. Wait a moment and try again.'
}, socket);
return;
}
if (typeof socket.channel !== 'undefined') {
// Calling socket already in a channel
return;
}
if (typeof data.channel !== 'string' || typeof data.nick !== 'string') {
return;
}
let channel = data.channel.trim();
2018-03-09 23:47:00 -08:00
if (!channel) {
// Must join a non-blank channel
return;
}
// Process nickname
let nick = data.nick;
2018-03-09 23:47:00 -08:00
let nickArray = nick.split('#', 2);
nick = nickArray[0].trim();
if (!verifyNickname(nick)) {
server.reply({
cmd: 'warn',
text: 'Nickname must consist of up to 24 letters, numbers, and underscores'
}, socket);
return;
2018-03-09 23:47:00 -08:00
}
2018-04-28 22:29:38 -07:00
let userExists = server.findSockets({
channel: data.channel,
nick: (targetNick) => targetNick.toLowerCase() === nick.toLowerCase()
});
2018-03-09 23:47:00 -08:00
2018-04-28 22:29:38 -07:00
if (userExists.length > 0) {
// That nickname is already in that channel
server.reply({
cmd: 'warn',
text: 'Nickname taken'
}, socket);
return;
2018-03-09 23:47:00 -08:00
}
// TODO: Should we check for mod status first to prevent overwriting of admin status somehow? Meh, w/e, cba.
let uType = 'user';
let trip = null;
let password = nickArray[1];
if (nick.toLowerCase() == core.config.adminName.toLowerCase()) {
if (password != core.config.adminPass) {
2018-04-28 22:29:38 -07:00
server._police.frisk(socket.remoteAddress, 4);
2018-03-09 23:47:00 -08:00
server.reply({
cmd: 'warn',
text: 'Gtfo'
}, socket);
return;
} else {
uType = 'admin';
2018-04-28 22:29:38 -07:00
trip = 'Admin';
2018-03-09 23:47:00 -08:00
}
} else if (password) {
trip = hash(password + core.config.tripSalt);
}
// TODO: Disallow moderator impersonation
for (let mod of core.config.mods) {
2018-04-28 22:29:38 -07:00
if (trip === mod.trip) {
2018-03-09 23:47:00 -08:00
uType = 'mod';
2018-04-28 22:29:38 -07:00
}
2018-03-09 23:47:00 -08:00
}
2018-04-28 22:29:38 -07:00
// Reply with online user list
let newPeerList = server.findSockets({ channel: data.channel });
let joinAnnouncement = {
2018-03-09 23:47:00 -08:00
cmd: 'onlineAdd',
nick: nick,
trip: trip || 'null',
hash: server.getSocketHash(socket)
2018-04-28 22:29:38 -07:00
};
let nicks = [];
for (let i = 0, l = newPeerList.length; i < l; i++) {
server.reply(joinAnnouncement, newPeerList[i]);
nicks.push(newPeerList[i].nick);
}
2018-03-09 23:47:00 -08:00
socket.uType = uType;
socket.nick = nick;
socket.channel = channel;
if (trip !== null) socket.trip = trip;
2018-04-28 22:29:38 -07:00
nicks.push(socket.nick);
2018-03-09 23:47:00 -08:00
server.reply({
cmd: 'onlineSet',
nicks: nicks
}, socket);
core.managers.stats.increment('users-joined');
};
exports.requiredData = ['channel', 'nick'];
2018-05-13 16:03:22 +05:30
exports.info = {
name: 'join',
usage: 'join {channel} {nick}',
description: 'Place calling socket into target channel with target nick & broadcast event to channel'
};