make tags optional

This commit is contained in:
emerson 2022-01-24 16:36:25 -05:00
parent 614fe8eb1e
commit f8f082e4c8
2 changed files with 86 additions and 86 deletions

View file

@ -50,37 +50,37 @@ export class Client {
});
}
checkIfRegistered(passedTags: Map<string, string> = new Map()) {
checkIfRegistered() {
if (this.user === null)
this.sendMessage(this.server.name, "451", [this.localNick, "You have not registered"], passedTags);
this.sendMessage(this.server.name, "451", [this.localNick, "You have not registered"]);
return this.user !== null;
}
getMatrixUserFromNick(targetNick: string, passedTags: Map<string, string> = new Map()) {
getMatrixUserFromNick(targetNick: string) {
if (!this.user) return false;
const target = this.user.nickToMatrixUser.get(targetNick);
if (!target) {
this.sendMessage(this.server.name, "401", [this.user.nick, targetNick, "No such nick"], passedTags);
this.sendMessage(this.server.name, "401", [this.user.nick, targetNick, "No such nick"]);
return false;
}
return target;
}
getChannel(channel: string, passedTags: Map<string, string> = new Map()) {
getChannel(channel: string) {
if (!this.user) return false;
const targetChannel = this.user.channels.get(channel);
if (!targetChannel) {
this.sendMessage(this.server.name, "403", [this.user.nick, channel, "No such channel"], passedTags);
this.sendMessage(this.server.name, "403", [this.user.nick, channel, "No such channel"]);
return false;
}
return targetChannel;
}
checkIfInChannel(channel: Channel, passedTags: Map<string, string> = new Map()) {
checkIfInChannel(channel: Channel) {
if (!this.user) return false;
if (!this.user.channels.get(channel.name)) {
this.sendMessage(this.server.name, "442", [this.user.nick, "You're not on that channel"], passedTags);
this.sendMessage(this.server.name, "442", [this.user.nick, "You're not on that channel"]);
return false;
}
return true;
@ -89,7 +89,7 @@ export class Client {
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);
this.sendMessage(this.server.name, "461", [this.user.nick, message.command, "Not enough parameters"]);
return false;
}
return true;
@ -155,12 +155,12 @@ export class Client {
doAUTHENTICATE(message: IRCMessage) {
if (message.params[0] === "PLAIN") {
this.sendMessage("", "AUTHENTICATE", ["+"], message.tags);
this.sendMessage("", "AUTHENTICATE", ["+"]);
}
else {
const authArray = Buffer.from(message.params[0], 'base64').toString('utf-8').split('\0');
if (!authArray || authArray.length !== 3) {
this.sendMessage(this.server.name, '904', numerics['904']('*'), message.tags)
this.sendMessage(this.server.name, '904', numerics['904']('*'))
this.closeConnectionWithError('Invalid authentication')
}
const mxid = authArray[1];
@ -172,25 +172,25 @@ export class Client {
const thisIRCUser = this.server.getOrCreateIRCUser(mxid, accessToken, homeserver);
thisIRCUser.getVerification().then((response) => {
if (response.status === 401 || response.status === 403) {
this.sendMessage(this.server.name, '904', numerics['904']('*'), message.tags)
this.sendMessage(this.server.name, '904', numerics['904']('*'))
this.closeConnectionWithError('Invalid authentication')
} else if (response.status === 429) {
this.sendMessage(this.server.name, '904', numerics['904']('*'), message.tags)
this.sendMessage(this.server.name, '904', numerics['904']('*'))
this.closeConnectionWithError('rate limited, please try again later')
} else if (response.status !== 200) {
this.sendMessage(this.server.name, '904', numerics['904']('*'), message.tags)
this.sendMessage(this.server.name, '904', numerics['904']('*'))
this.closeConnectionWithError('verification failed, please check credentials')
}
this.deviceId = response.data.device_id
if (response.data.user_id !== mxid) {
this.sendMessage(this.server.name, '904', numerics['904']('*'), message.tags)
this.sendMessage(this.server.name, '904', numerics['904']('*'))
this.closeConnectionWithError('access token does not match mxid, please check credentials')
} else {
this.user = thisIRCUser;
this.sendMessage(this.server.name, '900', numerics['900'](this.user.getMask(), this.user.nick), new Map());
this.sendMessage(this.server.name, '903', numerics['903'](this.user.nick), new Map());
this.sendMessage(this.server.name, '900', numerics['900'](this.user.getMask(), this.user.nick));
this.sendMessage(this.server.name, '903', numerics['903'](this.user.nick));
if (this.user.isSynced()) {
this.user.addClient(this, message.tags);
this.user.addClient(this);
} else {
axios.get(`https://${this.user.homeserver}/_matrix/client/v3/sync?access_token=${accessToken}`).then(response => {
const data = response.data;
@ -215,8 +215,8 @@ export class Client {
if (this.user === null)
return;
this.user.nextBatch = data.next_batch;
this.sendMessage(this.server.name, 'NOTICE', [this.user.nick, 'You are now synced to the network!'], message.tags);
this.user.addClient(this, message.tags);
this.sendMessage(this.server.name, 'NOTICE', [this.user.nick, 'You are now synced to the network!']);
this.user.addClient(this);
}).catch(function (error) {
console.log(error);
})
@ -232,11 +232,11 @@ export class Client {
if (message.params.length === 2) {
this.capVersion = message.params[1];
}
this.sendMessage(this.server.name, "CAP", ["*", "LS", this.getCapString(this.capVersion)], message.tags);
this.sendMessage(this.server.name, "CAP", ["*", "LS", this.getCapString(this.capVersion)]);
break;
}
case 'LIST': {
this.sendMessage(this.server.name, "CAP", ["*", "LIST", this.getCapString(this.capVersion)], message.tags);
this.sendMessage(this.server.name, "CAP", ["*", "LIST", this.getCapString(this.capVersion)]);
break;
}
case 'REQ': {
@ -248,7 +248,7 @@ export class Client {
capsEnabled.push(cap);
}
});
this.sendMessage(this.server.name, "CAP", ["*", "ACK", capsEnabled.join(' ')], message.tags);
this.sendMessage(this.server.name, "CAP", ["*", "ACK", capsEnabled.join(' ')]);
break;
}
case 'END': {
@ -263,14 +263,14 @@ export class Client {
}
doINVITE(message: IRCMessage) {
if (!this.checkIfRegistered(message.tags) || !this.checkMinParams(message, 2))
if (!this.checkIfRegistered() || !this.checkMinParams(message, 2))
return;
const targetUser = this.getMatrixUserFromNick(message.params[0], message.tags);
const targetChannel = this.getChannel(message.params[1], message.tags);
const targetUser = this.getMatrixUserFromNick(message.params[0]);
const targetChannel = this.getChannel(message.params[1]);
if (!this.user || !targetUser || !targetChannel) return;
if (!this.checkIfInChannel(targetChannel, message.tags)) return;
if (!this.checkIfInChannel(targetChannel)) return;
if (targetChannel.matrixUsers.has(targetUser.nick)) {
this.sendMessage(this.server.name, "443", [this.user.nick, targetUser.nick, "is already on channel"], message.tags);
this.sendMessage(this.server.name, "443", [this.user.nick, targetUser.nick, "is already on channel"]);
return;
}
const reason = (message.params.length === 3) ? message.params[2] : "";
@ -291,14 +291,14 @@ export class Client {
}
doKICK(message: IRCMessage) {
if (!this.checkIfRegistered(message.tags) || !this.checkMinParams(message, 2))
if (!this.checkIfRegistered() || !this.checkMinParams(message, 2))
return;
const targetChannel = this.getChannel(message.params[0], message.tags);
const targetUser = this.getMatrixUserFromNick(message.params[1], message.tags);
const targetChannel = this.getChannel(message.params[0]);
const targetUser = this.getMatrixUserFromNick(message.params[1]);
if (!this.user || !targetUser || !targetChannel) return;
if (!this.checkIfInChannel(targetChannel, message.tags)) return;
if (!this.checkIfInChannel(targetChannel)) 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);
this.sendMessage(this.server.name, "441", [this.user.nick, targetUser.nick, targetChannel.name, "They aren't on that channel"]);
return;
}
const reason = (message.params.length === 3) ? message.params[2] : "";
@ -319,30 +319,30 @@ export class Client {
}
doMODE(message: IRCMessage) {
if (!this.checkIfRegistered(message.tags) || !this.checkMinParams(message, 1) || !this.user)
if (!this.checkIfRegistered() || !this.checkMinParams(message, 1) || !this.user)
return;
const targetChannel = this.user.channels.get(message.params[0]);
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);
this.sendMessage(this.server.name, "502", [this.user.nick, "Can't view mode for other users"]);
return;
}
this.sendMessage(this.server.name, "221", [this.user.nick, "+i"], message.tags);
this.sendMessage(this.server.name, "221", [this.user.nick, "+i"]);
return;
}
if (!this.checkIfInChannel(targetChannel, message.tags)) return;
if (!this.checkIfInChannel(targetChannel)) return;
if (message.params.length === 1) {
this.sendMessage(this.server.name, "324", [this.user.nick, targetChannel.name, `+n`], message.tags);
this.sendMessage(this.server.name, "324", [this.user.nick, targetChannel.name, `+n`]);
return;
}
}
doMSG(message: IRCMessage) {
if (!this.checkIfRegistered(message.tags) || !this.checkMinParams(message, 2))
if (!this.checkIfRegistered() || !this.checkMinParams(message, 2))
return;
const targetChannel = this.getChannel(message.params[0], message.tags);
const targetChannel = this.getChannel(message.params[0]);
if (!this.user || !targetChannel) return;
if (!this.checkIfInChannel(targetChannel, message.tags)) return;
if (!this.checkIfInChannel(targetChannel)) return;
let msgtype = 'm.text';
let msgbody = message.params[1];
if (message.command === 'NOTICE')
@ -378,7 +378,7 @@ export class Client {
});
}
sendNAMES(targetChannel: Channel, passedTags: Map<string, string> = new Map()) {
sendNAMES(targetChannel: Channel) {
if (!this.user) return;
let namesList: string[] = [];
for (const matrixUser of targetChannel.matrixUsers.values()) {
@ -392,38 +392,38 @@ export class Client {
}
else {
//@ts-ignore
this.sendMessage(this.server.name, "353", numerics["353"](this.user.nick, "=", targetChannel.name, singleNamesList), passedTags);
this.sendMessage(this.server.name, "353", numerics["353"](this.user.nick, "=", targetChannel.name, singleNamesList));
singleNamesList = [];
}
})
if (singleNamesList.length !== 0) {
this.sendMessage(this.server.name, "353", numerics["353"](this.user.nick, "=", targetChannel.name, singleNamesList), passedTags);
this.sendMessage(this.server.name, "353", numerics["353"](this.user.nick, "=", targetChannel.name, singleNamesList));
}
this.sendMessage(this.server.name, "366", numerics["366"](this.user.nick, targetChannel.name), passedTags);
this.sendMessage(this.server.name, "366", numerics["366"](this.user.nick, targetChannel.name));
}
doNAMES(message: IRCMessage) {
if (!this.checkIfRegistered(message.tags) || !this.checkMinParams(message, 1))
if (!this.checkIfRegistered() || !this.checkMinParams(message, 1))
return;
const targetChannel = this.getChannel(message.params[0], message.tags);
const targetChannel = this.getChannel(message.params[0]);
if (!this.user || !targetChannel) return;
if (!this.checkIfInChannel(targetChannel, message.tags)) return;
if (!this.checkIfInChannel(targetChannel)) return;
this.sendNAMES(targetChannel);
}
doPART(message: IRCMessage) {
if (!this.checkIfRegistered(message.tags) || !this.checkMinParams(message, 1))
if (!this.checkIfRegistered() || !this.checkMinParams(message, 1))
return;
const targetChannel = this.getChannel(message.params[0], message.tags);
const targetChannel = this.getChannel(message.params[0]);
if (!this.user || !targetChannel) return;
if (!this.checkIfInChannel(targetChannel, message.tags)) return;
if (!this.checkIfInChannel(targetChannel)) return;
const reason = (message.params.length === 2) ? message.params[1] : "";
axios.post(`https://${this.user.homeserver}/_matrix/client/v3/rooms/${targetChannel.roomId}/leave?access_token=${this.user.accessToken}`, {"reason": reason}).then(response => {
if (response.status === 200) {
//@ts-ignore
this.user.getClients().forEach(c => {
//@ts-ignore
c.sendMessage(this.user.getMask(), "PART", [targetChannel.name, reason], message.tags);
c.sendMessage(this.user.getMask(), "PART", [targetChannel.name, reason]);
})
//@ts-ignore
this.user.channels.delete(targetChannel.name);
@ -432,7 +432,7 @@ export class Client {
}
else {
//@ts-ignore
this.sendMessage(this.server.name, "NOTICE", [this.user.nick, JSON.stringify(response.data)], message.tags);
this.sendMessage(this.server.name, "NOTICE", [this.user.nick, JSON.stringify(response.data)]);
}
}).catch(function (error) {
if (error.response) {
@ -447,11 +447,11 @@ export class Client {
}
doTAGMSG(message: IRCMessage) {
if (!this.checkIfRegistered(message.tags) || !this.checkMinParams(message, 1))
if (!this.checkIfRegistered() || !this.checkMinParams(message, 1))
return;
const targetChannel = this.getChannel(message.params[0], message.tags);
const targetChannel = this.getChannel(message.params[0]);
if (!this.user || !targetChannel) return;
if (!this.checkIfInChannel(targetChannel, message.tags)) return;
if (!this.checkIfInChannel(targetChannel)) return;
if (message.tags.has("+draft/react") && message.tags.has("+draft/reply")) {
const content = {
"m.relates_to": {
@ -475,27 +475,27 @@ export class Client {
}
}
sendTOPIC(targetChannel: Channel, passedTags: Map<string, string> = new Map()) {
sendTOPIC(targetChannel: Channel) {
if (!this.user) return;
const topicText = targetChannel.topic.get('text') || '';
const topicSetter = targetChannel.topic.get('setter') || 'matrix';
const topicTimestamp = targetChannel.topic.get('timestamp') || '0';
if (topicText === '') {
this.sendMessage(this.server.name, '331', [this.user.nick, targetChannel.name, 'No topic is set'], passedTags);
this.sendMessage(this.server.name, '331', [this.user.nick, targetChannel.name, 'No topic is set']);
return;
}
this.sendMessage(this.server.name, '332', [this.user.nick, targetChannel.name, topicText], passedTags);
this.sendMessage(this.server.name, '333', [this.user.nick, targetChannel.name, topicSetter, topicTimestamp], passedTags);
this.sendMessage(this.server.name, '332', [this.user.nick, targetChannel.name, topicText]);
this.sendMessage(this.server.name, '333', [this.user.nick, targetChannel.name, topicSetter, topicTimestamp]);
}
doTOPIC(message: IRCMessage) {
if (!this.checkIfRegistered(message.tags) || !this.checkMinParams(message, 1))
if (!this.checkIfRegistered() || !this.checkMinParams(message, 1))
return;
const targetChannel = this.getChannel(message.params[0], message.tags);
const targetChannel = this.getChannel(message.params[0]);
if (!this.user || !targetChannel) return;
if (!this.checkIfInChannel(targetChannel, message.tags)) return;
if (!this.checkIfInChannel(targetChannel)) return;
if (message.params.length === 1) {
this.sendTOPIC(targetChannel, message.tags);
this.sendTOPIC(targetChannel);
return;
}
const topic = message.params[1];
@ -512,11 +512,11 @@ export class Client {
}
doWHO(message: IRCMessage) {
if (!this.checkIfRegistered(message.tags) || !this.checkMinParams(message, 1))
if (!this.checkIfRegistered() || !this.checkMinParams(message, 1))
return;
const targetChannel = this.getChannel(message.params[0], message.tags);
const targetChannel = this.getChannel(message.params[0]);
if (!this.user || !targetChannel) return;
if (!this.checkIfInChannel(targetChannel, message.tags)) return;
if (!this.checkIfInChannel(targetChannel)) return;
for (const matrixUser of targetChannel.matrixUsers.values()) {
const opStatus = targetChannel.getNickPowerLevelMapping(matrixUser.nick);
const userParams = [
@ -529,9 +529,9 @@ export class Client {
`H${opStatus}`,
`0 ${matrixUser.realname}`
]
this.sendMessage(this.server.name, '352', userParams, message.tags);
this.sendMessage(this.server.name, '352', userParams);
}
this.sendMessage(this.server.name, '315', [this.user.nick, targetChannel.name, "End of /WHO"], message.tags);
this.sendMessage(this.server.name, '315', [this.user.nick, targetChannel.name, "End of /WHO"]);
}
doRegistration(message: IRCMessage) {
@ -539,10 +539,10 @@ export class Client {
this.closeConnectionWithError("You must use SASL to connect to this server");
return;
}
this.sendMessage(this.server.name, '001', numerics['001'](this.user.nick, this.server.name), message.tags);
this.sendMessage(this.server.name, '002', numerics['002'](this.user.nick, this.server.name, '0.0.1'), message.tags);
this.sendMessage(this.server.name, '003', numerics['003'](this.user.nick, 'yesterday'), message.tags);
this.sendMessage(this.server.name, '004', numerics['004'](this.user.nick, this.server.name, '0.0.1', 'i', 'Lhionpsv'), message.tags);
this.sendMessage(this.server.name, '001', numerics['001'](this.user.nick, this.server.name));
this.sendMessage(this.server.name, '002', numerics['002'](this.user.nick, this.server.name, '0.0.1'));
this.sendMessage(this.server.name, '003', numerics['003'](this.user.nick, 'yesterday'));
this.sendMessage(this.server.name, '004', numerics['004'](this.user.nick, this.server.name, '0.0.1', 'i', 'Lhionpsv'));
const iSupportArray = [
'CASEMAPPING=ascii',
'CHANMODES=,,,Linps',
@ -553,18 +553,18 @@ export class Client {
if (this.enabledCaps.has('draft/chathistory')) {
iSupportArray.push('CHATHISTORY=50');
}
this.sendMessage(this.server.name, '005', numerics['005'](this.user.nick, iSupportArray), message.tags);
this.sendMessage(this.server.name, '005', numerics['005'](this.user.nick, iSupportArray));
this.sendMessage(this.server.name, '375', numerics['375'](this.user.nick), message.tags);
this.sendMessage(this.server.name, '372', numerics['372'](this.user.nick, "It's an MOTD"), message.tags);
this.sendMessage(this.server.name, '376', numerics['376'](this.user.nick), message.tags);
this.sendMessage(this.server.name, '375', numerics['375'](this.user.nick));
this.sendMessage(this.server.name, '372', numerics['372'](this.user.nick, "It's an MOTD"));
this.sendMessage(this.server.name, '376', numerics['376'](this.user.nick));
this.sendMessage(this.user.nick, 'MODE', [this.user.nick, '+i'], message.tags);
this.sendMessage(this.user.nick, 'MODE', [this.user.nick, '+i']);
if (!this.user.isSynced())
this.sendMessage(this.server.name, 'NOTICE', [this.user.nick, 'Please wait for initial sync, this may take a while if you are in many large channels'], message.tags);
this.sendMessage(this.server.name, 'NOTICE', [this.user.nick, 'Please wait for initial sync, this may take a while if you are in many large channels']);
}
sendMessage(prefix: string, command: string, params: string[], tags: Map<string, string>) {
sendMessage(prefix: string, command: string, params: string[], tags: Map<string, string> = new Map()) {
const capTagMapping = new Map([
['account', 'account-tag'],
['label', 'labeled-response'],

View file

@ -95,21 +95,21 @@ export class IRCUser {
return this.clients;
}
joinNewIRCClient(client: Client, targetChannel: Channel, passedTags: Map<string, string>) {
joinNewIRCClient(client: Client, targetChannel: Channel) {
if (client.enabledCaps.has('extended-join')) {
client.sendMessage(this.getMask(), "JOIN", [targetChannel.name, this.accountName, this.mxid], new Map([['account', this.realname]]));
} else {
client.sendMessage(this.getMask(), "JOIN", [targetChannel.name], new Map([['account', this.realname]]));
}
client.sendNAMES(targetChannel, passedTags);
client.sendTOPIC(targetChannel, passedTags);
client.sendNAMES(targetChannel);
client.sendTOPIC(targetChannel);
}
addClient(client: Client, passedTags: Map<string, string>) {
addClient(client: Client) {
this.clients.add(client);
if (this.nextBatch !== "") {
for (const channel of this.channels.values()) {
this.joinNewIRCClient(client, channel, passedTags);
this.joinNewIRCClient(client, channel);
}
}
}
@ -236,7 +236,7 @@ export class IRCUser {
}
else {
client.sendMessage(this.server.name, "PART", [oldName, "Renaming channel"], new Map());
this.joinNewIRCClient(client, targetChannel, new Map());
this.joinNewIRCClient(client, targetChannel);
}
})
}