Skip to content

Commit

Permalink
Simplify
Browse files Browse the repository at this point in the history
  • Loading branch information
ItsOnlyBinary committed Sep 5, 2023
1 parent bb168ef commit 1c75264
Show file tree
Hide file tree
Showing 5 changed files with 113 additions and 112 deletions.
6 changes: 3 additions & 3 deletions src/commands/handlers/registration.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,9 +84,9 @@ const handlers = {
handler.network.options.CHANMODES = option[1].split(',');
} else if (option[0] === 'CASEMAPPING') {
handler.network.options.CASEMAPPING = option[1];
// https://ircv3.net/specs/extensions/message-tags#rpl_isupport-tokens
} else if (option[0] === 'CLIENTTAGDENY' && handler.network.cap.isEnabled('message-tags')) {
handler.network.options.CLIENTTAGDENY = option[1].split(',');
} else if (option[0] === 'CLIENTTAGDENY') {
// https://ircv3.net/specs/extensions/message-tags#rpl_isupport-tokens
handler.network.options.CLIENTTAGDENY = option[1].split(',').filter((f) => !!f);
} else if (option[0] === 'NETWORK') {
handler.network.name = option[1];
} else if (option[0] === 'NAMESX' && !handler.network.cap.isEnabled('multi-prefix')) {
Expand Down
44 changes: 0 additions & 44 deletions src/messagetags.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@ module.exports.decodeValue = decodeValue;
module.exports.encodeValue = encodeValue;
module.exports.decode = decode;
module.exports.encode = encode;
module.exports.parseDenylist = parseDenylist;
module.exports.isBlocked = isBlocked;

const tokens_map = {
'\\\\': '\\',
Expand Down Expand Up @@ -70,45 +68,3 @@ function encode(tags, separator = ';') {

return parts.join(separator);
}

// Parses a raw CLIENTTAGDENY= denylist
// into a { allBlockedByDefault: boolean, explicitlyAccepted: string[], explicitlyDenied: string[] }
// structure.
function parseDenylist(raw) {
const denylist = {
allBlockedByDefault: false,
explicitlyAccepted: [],
explicitlyDenied: []
};
const parts = raw.split(',');

for (let idx = 0; idx < parts.length; idx++) {
const tag = parts[idx];
if (tag === '') {
continue;
}

if (tag === '*') {
denylist.allBlockedByDefault = true;
continue;
}

if (tag[0] === '-') {
denylist.explicitlyAccepted.push(tag.slice(1));
} else {
denylist.explicitlyDenied.push(tag);
}
}

return denylist;
}

// Takes a parsed denylist and returns whether tag is allowed
// according to current denial policies.
function isBlocked(denylist, tag) {
if (denylist.allBlockedByDefault) {
return !denylist.explicitlyAccepted.includes(tag);
} else {
return denylist.explicitlyDenied.includes(tag);
}
}
40 changes: 28 additions & 12 deletions src/networkinfo.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,17 @@ function NetworkInfo() {
{ symbol: '%', mode: 'h' },
{ symbol: '+', mode: 'v' }
],
CLIENTTAGDENY: []
};

// Network capabilities
this.cap = {
negotiating: false,
requested: [],
enabled: [],
available: new Map(),
isEnabled: function(cap_name) {
return this.enabled.indexOf(cap_name) > -1;
}
};

this.time_offsets = [];
Expand Down Expand Up @@ -70,6 +80,23 @@ function NetworkInfo() {
return this.options[support_name.toUpperCase()];
};

this.supportsTag = function supportsTag(tag_name) {
if (!this.cap.isEnabled('message-tags')) {
return false;
}

if (!this.options.CLIENTTAGDENY || this.options.CLIENTTAGDENY.length === 0) {
return true;
}

const allowAll = this.options.CLIENTTAGDENY[0] !== '*';
if (allowAll) {
return !this.options.CLIENTTAGDENY.some((tag) => tag === tag_name);
}

return this.options.CLIENTTAGDENY.some((tag) => tag === `-${tag_name}`);
};

this.isChannelName = function isChannelName(channel_name) {
if (typeof channel_name !== 'string' || channel_name === '') {
return false;
Expand Down Expand Up @@ -103,15 +130,4 @@ function NetworkInfo() {
target_group: target_group,
};
};

// Network capabilities
this.cap = {
negotiating: false,
requested: [],
enabled: [],
available: new Map(),
isEnabled: function(cap_name) {
return this.enabled.indexOf(cap_name) > -1;
}
};
}
43 changes: 0 additions & 43 deletions test/messagetags.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,49 +8,6 @@ const assert = chai.assert;
chai.use(require('chai-subset'));

describe('src/messagetags.js', function() {
describe('CLIENTTAGDENY= parsing', function() {
it('should parse CLIENTTAGDENY=', function() {
assert.deepEqual(MessageTags.parseDenylist(''), {
allBlockedByDefault: false,
explicitlyDenied: [],
explicitlyAccepted: []
});
});

it('should parse CLIENTTAGDENY=*,-a', function() {
assert.deepEqual(MessageTags.parseDenylist('*,-a'), {
allBlockedByDefault: true,
explicitlyAccepted: ['a'],
explicitlyDenied: []
});
});

it('should parse CLIENTTAGDENY=a,b', function() {
assert.deepEqual(MessageTags.parseDenylist('a,b'), {
allBlockedByDefault: false,
explicitlyAccepted: [],
explicitlyDenied: ['a', 'b']
});
});
});

describe('CLIENTTAGDENY= logic', function() {
it('should block all tags (`b`) with * and no exception', function() {
assert.isTrue(MessageTags.isBlocked(MessageTags.parseDenylist('*'), 'b'));
});

it('should not block all tags with * and exceptions (`c`, `a`)', function() {
assert.isFalse(MessageTags.isBlocked(MessageTags.parseDenylist('*,-c,-a'), 'a'));
assert.isFalse(MessageTags.isBlocked(MessageTags.parseDenylist('*,-c,-a'), 'c'));
assert.isTrue(MessageTags.isBlocked(MessageTags.parseDenylist('*,-c,-a'), 'b'));
});

it('should block a specific tag if no * is present', function() {
assert.isTrue(MessageTags.isBlocked(MessageTags.parseDenylist('a'), 'a'));
assert.isFalse(MessageTags.isBlocked(MessageTags.parseDenylist('a'), 'b'));
});
});

describe('value encoding', function() {
it('should decode characters to correct strings', function() {
const plain = "Some people use IRC; others don't \\o/ Note: Use IRC\r\n";
Expand Down
92 changes: 82 additions & 10 deletions test/networkinfo.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,28 @@ describe('src/networkinfo.js', function() {
const results = names.map(name => client.network.isChannelName(name));
assert.deepEqual(results, [false, false, false, false, false, false]);
});
});

describe('CLIENTTAGDENY Support', function() {
it('should parse CLIENTTAGDENY=a,b,c as a list', function() {
const client = newMockClient();
client.dispatch({
command: '005',
params: ['nick', 'CLIENTTAGDENY=a,b,c'],
tags: []
});
assert.deepEqual(client.network.options.CLIENTTAGDENY, ['a', 'b', 'c']);
});

it('should parse CLIENTTAGDENY=*,-a,-b as a list', function() {
const client = newMockClient();
client.dispatch({
command: '005',
params: ['nick', 'CLIENTTAGDENY=*,-a,-b'],
tags: []
});
assert.deepEqual(client.network.options.CLIENTTAGDENY, ['*', '-a', '-b']);
});

it('should parse CLIENTTAGDENY= as a list', function() {
const client = newMockClient();
Expand All @@ -61,27 +83,77 @@ describe('src/networkinfo.js', function() {
params: ['nick', 'CLIENTTAGDENY='],
tags: []
});
assert.isArray(client.network.options.CLIENTTAGDENY);
assert.isEmpty(client.network.options.CLIENTTAGDENY);
});

it('should parse CLIENTTAGDENY=*,-a,-b as a list', function() {
it('should be undefined when no CLIENTTAGDENY', function() {
const client = newMockClient();
client.dispatch({
command: '005',
params: ['nick', ''],
tags: []
});
assert.isUndefined(client.network.options.CLIENTTAGDENY);
});

it('should deny all when no message-tags CAP', function() {
const client = newMockClient();
client.dispatch({
command: '005',
params: ['nick', 'CLIENTTAGDENY=*,-a,-b'],
tags: []
});
assert.equal(client.network.options.CLIENTTAGDENY, ['*', '-a', '-b']);
assert.isFalse(client.network.supportsTag('a'));
assert.isFalse(client.network.supportsTag('b'));
});
});

it('should parse CLIENTTAGDENY=a,b,c as a list', function() {
const client = newMockClient();
client.dispatch({
command: '005',
params: ['nick', 'CLIENTTAGDENY=a,b,c'],
tags: []
it('should allow all when CLIENTTAGDENY=', function() {
const client = newMockClient();
client.network.cap.enabled.push('message-tags');
client.dispatch({
command: '005',
params: ['nick', 'CLIENTTAGDENY='],
tags: []
});
assert.isTrue(client.network.supportsTag('a'));
assert.isTrue(client.network.supportsTag('b'));
});

it('should deny all when CLIENTTAGDENY=*', function() {
const client = newMockClient();
client.network.cap.enabled.push('message-tags');
client.dispatch({
command: '005',
params: ['nick', 'CLIENTTAGDENY=*'],
tags: []
});
assert.isFalse(client.network.supportsTag('a'));
assert.isFalse(client.network.supportsTag('b'));
});

it('should allow a & deny b, c when CLIENTTAGDENY=*,-a', function() {
const client = newMockClient();
client.network.cap.enabled.push('message-tags');
client.dispatch({
command: '005',
params: ['nick', 'CLIENTTAGDENY=*,-a'],
tags: []
});
assert.isTrue(client.network.supportsTag('a'));
assert.isFalse(client.network.supportsTag('b'));
});

it('should allow a & deny b when CLIENTTAGDENY=b', function() {
const client = newMockClient();
client.network.cap.enabled.push('message-tags');
client.dispatch({
command: '005',
params: ['nick', 'CLIENTTAGDENY=b'],
tags: []
});
assert.isTrue(client.network.supportsTag('a'));
assert.isFalse(client.network.supportsTag('b'));
});
assert.equal(client.network.options.CLIENTTAGDENY, ['a', 'b', 'c']);
});
});

0 comments on commit 1c75264

Please sign in to comment.