mirror of
https://git.sr.ht/~emerson/reflectionircd
synced 2025-04-13 09:59:52 +00:00
add more IRC-side error checking
This commit is contained in:
parent
ddbdcc9981
commit
2e973a18db
3 changed files with 135 additions and 34 deletions
|
@ -3,6 +3,7 @@ import { MatrixUser } from "./MatrixUser.js";
|
|||
import { IRCUser } from "./IRCUser.js";
|
||||
import { Client } from "./Client.js";
|
||||
import numerics from "./numerics.js";
|
||||
import { IRCMessage } from "./Message.js";
|
||||
|
||||
export class Channel {
|
||||
public name: string
|
||||
|
@ -46,7 +47,9 @@ export class Channel {
|
|||
if (!newName || newName === this.name)
|
||||
return;
|
||||
const oldName = this.name;
|
||||
this.server.ircChannels.delete(oldName);
|
||||
this.name = newName;
|
||||
this.server.ircChannels.set(newName, this);
|
||||
this.ircUsers.forEach((user, username) => {
|
||||
user.getClients().forEach(client => {
|
||||
if (client.enabledCaps.has("draft/channel-rename")) {
|
||||
|
@ -136,7 +139,11 @@ export class Channel {
|
|||
]
|
||||
client.sendMessage(client.server.name, '352', userParams, passedTags);
|
||||
}
|
||||
client.sendMessage(client.server.name, '315', [this.name], passedTags);
|
||||
client.sendMessage(client.server.name, '315', [client.user.nick, this.name, "End of /WHO"], passedTags);
|
||||
}
|
||||
|
||||
handleModeChange(client: Client, message: IRCMessage) {
|
||||
|
||||
}
|
||||
|
||||
routeMatrixEvent(event: any) {
|
||||
|
|
144
src/Client.ts
144
src/Client.ts
|
@ -49,6 +49,56 @@ export class Client {
|
|||
});
|
||||
}
|
||||
|
||||
checkIfRegistered(passedTags: Map<string, string> = new Map()) {
|
||||
if (this.user === null)
|
||||
this.sendMessage(this.server.name, "451", [this.localNick, "You have not registered"], passedTags);
|
||||
|
||||
return this.user !== null;
|
||||
}
|
||||
|
||||
getMatrixUserFromNick(targetNick: string, passedTags: Map<string, string> = new Map()) {
|
||||
if (!this.user) return false;
|
||||
const targetMxid = this.server.nickToMxid.get(targetNick);
|
||||
if (!targetMxid) {
|
||||
this.sendMessage(this.server.name, "401", [this.user.nick, targetNick, "No such nick"], passedTags);
|
||||
return false;
|
||||
}
|
||||
const target = this.server.matrixUsers.get(targetMxid);
|
||||
if (!target) {
|
||||
this.sendMessage(this.server.name, "401", [this.user.nick, targetNick, "No such nick"], passedTags);
|
||||
return false;
|
||||
}
|
||||
return target;
|
||||
}
|
||||
|
||||
getChannel(channel: string, passedTags: Map<string, string> = new Map()) {
|
||||
if (!this.user) return false;
|
||||
const targetChannel = this.server.ircChannels.get(channel);
|
||||
if (!targetChannel) {
|
||||
this.sendMessage(this.server.name, "403", [this.user.nick, channel, "No such channel"], passedTags);
|
||||
return false;
|
||||
}
|
||||
return targetChannel;
|
||||
}
|
||||
|
||||
checkIfInChannel(channel: Channel, passedTags: Map<string, string> = new Map()) {
|
||||
if (!this.user) return false;
|
||||
if (!channel.ircUsers.has(this.user.nick)) {
|
||||
this.sendMessage(this.server.name, "442", [this.user.nick, "You're not on that channel"], passedTags);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
checkMinParams(message: IRCMessage, neededNumber: number) {
|
||||
if (!this.user) return false;
|
||||
if (message.params.length < neededNumber) {
|
||||
this.sendMessage(this.server.name, "461", [this.user.nick, message.command, "Not enough parameters"], message.tags);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
routeMessage(data: string) {
|
||||
const message = parseIRCMessage(data);
|
||||
switch (message.command.toUpperCase()) {
|
||||
|
@ -61,46 +111,79 @@ export class Client {
|
|||
break;
|
||||
}
|
||||
case 'INVITE': {
|
||||
const targetUser = this.server.getOrCreateMatrixUser(message.params[0])
|
||||
const targetChannel = this.server.ircChannels.get(message.params[1]);
|
||||
if (!this.checkIfRegistered(message.tags) || !this.checkMinParams(message, 2))
|
||||
return;
|
||||
const targetUser = this.getMatrixUserFromNick(message.params[0], message.tags);
|
||||
const targetChannel = this.getChannel(message.params[1], message.tags);
|
||||
if (!this.user || !targetUser || !targetChannel) return;
|
||||
if (!this.checkIfInChannel(targetChannel, message.tags)) return;
|
||||
if (targetChannel.matrixUsers.has(targetUser.nick)) {
|
||||
this.sendMessage(this.server.name, "443", [this.user.nick, targetUser.nick, "is already on channel"], message.tags);
|
||||
return;
|
||||
}
|
||||
const reason = (message.params.length === 3) ? message.params[2] : "";
|
||||
if (this.user && targetChannel && targetChannel.ircUsers.get(this.user.nick))
|
||||
this.user.inviteMatrixUser(this, targetChannel, targetUser, reason, message.tags);
|
||||
break;
|
||||
}
|
||||
case 'KICK': {
|
||||
const targetChannel = this.server.ircChannels.get(message.params[0]);
|
||||
const targetMxid = this.server.nickToMxid.get(message.params[1]);
|
||||
if (!targetMxid)
|
||||
if (!this.checkIfRegistered(message.tags) || !this.checkMinParams(message, 2))
|
||||
return;
|
||||
console.log(targetMxid);
|
||||
const targetChannel = this.getChannel(message.params[0], message.tags);
|
||||
const targetUser = this.getMatrixUserFromNick(message.params[1], message.tags);
|
||||
if (!this.user || !targetUser || !targetChannel) return;
|
||||
if (!this.checkIfInChannel(targetChannel, message.tags)) return;
|
||||
if (!targetChannel.matrixUsers.has(targetUser.nick)) {
|
||||
this.sendMessage(this.server.name, "441", [this.user.nick, targetUser.nick, targetChannel.name, "They aren't on that channel"], message.tags);
|
||||
return;
|
||||
}
|
||||
const reason = (message.params.length === 3) ? message.params[2] : "";
|
||||
if (this.user && targetChannel && targetChannel.ircUsers.get(this.user.nick))
|
||||
this.user.kickMatrixUser(this, targetChannel, targetMxid, reason, message.tags);
|
||||
this.user.kickMatrixUser(this, targetChannel, targetUser.mxid, reason, message.tags);
|
||||
break;
|
||||
}
|
||||
case 'MODE': {
|
||||
if (!this.checkIfRegistered(message.tags) || !this.checkMinParams(message, 1) || !this.user)
|
||||
return;
|
||||
const targetChannel = this.server.ircChannels.get(message.params[0]);
|
||||
if (this.user && targetChannel && targetChannel.ircUsers.get(this.user.nick))
|
||||
if (!targetChannel) {
|
||||
if (message.params[0] !== this.user.nick) {
|
||||
this.sendMessage(this.server.name, "502", [this.user.nick, "Can't view mode for other users"], message.tags);
|
||||
return;
|
||||
}
|
||||
this.sendMessage(this.server.name, "221", [this.user.nick, "+i"], message.tags);
|
||||
return;
|
||||
}
|
||||
if (!this.checkIfInChannel(targetChannel, message.tags)) return;
|
||||
if (message.params.length === 1)
|
||||
targetChannel.sendMode(this, message.tags);
|
||||
else
|
||||
targetChannel.handleModeChange(this, message);
|
||||
break;
|
||||
}
|
||||
case 'NAMES': {
|
||||
const targetChannel = this.server.ircChannels.get(message.params[0]);
|
||||
if (this.user && targetChannel && targetChannel.ircUsers.get(this.user.nick))
|
||||
if (!this.checkIfRegistered(message.tags) || !this.checkMinParams(message, 1))
|
||||
return;
|
||||
const targetChannel = this.getChannel(message.params[0], message.tags);
|
||||
if (!this.user || !targetChannel) return;
|
||||
if (!this.checkIfInChannel(targetChannel, message.tags)) return;
|
||||
targetChannel.sendNames(this, message.tags);
|
||||
break;
|
||||
}
|
||||
case 'NOTICE': {
|
||||
if (this.user) {
|
||||
if (!this.checkIfRegistered(message.tags) || !this.checkMinParams(message, 2))
|
||||
return;
|
||||
const targetChannel = this.getChannel(message.params[0], message.tags);
|
||||
if (!this.user || !targetChannel) return;
|
||||
if (!this.checkIfInChannel(targetChannel, message.tags)) return;
|
||||
this.user.sendMessageToMatrix(message, this);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'PART': {
|
||||
const targetChannel = this.server.ircChannels.get(message.params[0]);
|
||||
if (!this.checkIfRegistered(message.tags) || !this.checkMinParams(message, 1))
|
||||
return;
|
||||
const targetChannel = this.getChannel(message.params[0], message.tags);
|
||||
if (!this.user || !targetChannel) return;
|
||||
if (!this.checkIfInChannel(targetChannel, message.tags)) return;
|
||||
const reason = (message.params.length === 2) ? message.params[1] : "";
|
||||
if (this.user && targetChannel && targetChannel.ircUsers.get(this.user.nick))
|
||||
this.user.partMatrixRoom(this, targetChannel, reason, message.tags);
|
||||
break;
|
||||
}
|
||||
|
@ -109,21 +192,29 @@ export class Client {
|
|||
break;
|
||||
}
|
||||
case 'PRIVMSG': {
|
||||
if (this.user) {
|
||||
if (!this.checkIfRegistered(message.tags) || !this.checkMinParams(message, 2))
|
||||
return;
|
||||
const targetChannel = this.getChannel(message.params[0], message.tags);
|
||||
if (!this.user || !targetChannel) return;
|
||||
if (!this.checkIfInChannel(targetChannel, message.tags)) return;
|
||||
this.user.sendMessageToMatrix(message, this);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'TAGMSG': {
|
||||
if (this.user) {
|
||||
if (!this.checkIfRegistered(message.tags) || !this.checkMinParams(message, 1))
|
||||
return;
|
||||
const targetChannel = this.getChannel(message.params[0], message.tags);
|
||||
if (!this.user || !targetChannel) return;
|
||||
if (!this.checkIfInChannel(targetChannel, message.tags)) return;
|
||||
this.user.sendTagToMatrix(message, this);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'TOPIC': {
|
||||
const targetChannel = this.server.ircChannels.get(message.params[0]);
|
||||
if (!this.user || !targetChannel || !targetChannel.ircUsers.get(this.user.nick))
|
||||
break;
|
||||
if (!this.checkIfRegistered(message.tags) || !this.checkMinParams(message, 1))
|
||||
return;
|
||||
const targetChannel = this.getChannel(message.params[0], message.tags);
|
||||
if (!this.user || !targetChannel) return;
|
||||
if (!this.checkIfInChannel(targetChannel, message.tags)) return;
|
||||
if (message.params.length === 1) {
|
||||
targetChannel.sendTopic(this, message.tags);
|
||||
break;
|
||||
|
@ -133,8 +224,11 @@ export class Client {
|
|||
break;
|
||||
}
|
||||
case 'WHO': {
|
||||
const targetChannel = this.server.ircChannels.get(message.params[0]);
|
||||
if (this.user && targetChannel && targetChannel.ircUsers.get(this.user.nick))
|
||||
if (!this.checkIfRegistered(message.tags) || !this.checkMinParams(message, 1))
|
||||
return;
|
||||
const targetChannel = this.getChannel(message.params[0], message.tags);
|
||||
if (!this.user || !targetChannel) return;
|
||||
if (!this.checkIfInChannel(targetChannel, message.tags)) return;
|
||||
targetChannel.sendWho(this, message.tags);
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -36,7 +36,7 @@ const numerics = {
|
|||
return [nick, "End of MOTD"]
|
||||
},
|
||||
"433": (nick: string, otherNick: string) => {
|
||||
return [nick, otherNick, "You can't change nicks on IRC yet"]
|
||||
return [nick, otherNick, "Nickname is already in use"]
|
||||
},
|
||||
"900": (mask: string, nick: string) => {
|
||||
return [nick, mask, `You are now logged in as ${nick}`]
|
||||
|
|
Loading…
Add table
Reference in a new issue