Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
197abf8
Initial progress
cpitman Oct 18, 2016
76c02b8
Direct messaging complete
cpitman Oct 18, 2016
f6c433b
Handle net-splits
cpitman Oct 18, 2016
123f4e4
Cleaned up logging
cpitman Oct 18, 2016
1e0045b
more cleanup, better log messages
cpitman Oct 18, 2016
39278a1
Added support for IRC users to create rooms and invite RC users
cpitman Oct 20, 2016
33bc058
Keep rooms in sync
cpitman Oct 20, 2016
72b4b83
IRC user can kick RC user
cpitman Oct 20, 2016
45d12fa
Working on transcription of coffescript to ecmascript code and fittin…
lindoelio Dec 20, 2017
702969c
Working on transcription of coffescript to ecmascript code and fittin…
lindoelio Dec 22, 2017
67d4552
Merge branch 'develop' of https://github.com/RocketChat/Rocket.Chat i…
lindoelio Dec 22, 2017
6fc0d2a
Adds settings section for config the IRC Server bridge.
lindoelio Dec 22, 2017
2305680
Merge branch 'develop' of https://github.com/RocketChat/Rocket.Chat i…
lindoelio Dec 30, 2017
f809fcd
Merge branch 'develop' of https://github.com/RocketChat/Rocket.Chat i…
lindoelio Jan 15, 2018
f997ad2
Working handles for direct messages
lindoelio Jan 29, 2018
c219d46
Working handles for direct messages
lindoelio Jan 30, 2018
b2c55c4
Solving merge conflicts with develop branch
lindoelio Jan 30, 2018
cfb649f
Working handles for direct messages
lindoelio Jan 31, 2018
a99c571
Working handles for direct messages
lindoelio Feb 5, 2018
0949401
Solving merge conflicts with develop branch
lindoelio Feb 5, 2018
330557c
Working handles for direct messages
lindoelio Feb 6, 2018
3e4b453
Working on RC server connection to a local IRC Network
lindoelio Feb 9, 2018
7176f78
Merge branch 'develop' of https://github.com/RocketChat/Rocket.Chat i…
lindoelio Feb 9, 2018
b99a5d3
first version, using a RFC2813 implementation
alansikora Mar 12, 2018
a91ca4a
Merge branch 'develop' into irc-server-federation-rfc2813
Hudell May 14, 2018
a1766e9
Fixing lint errors
Hudell May 15, 2018
e582856
Fixed partial username
Hudell May 15, 2018
cbd5418
Fixed problems with scope
Hudell May 15, 2018
77dae32
removed parser name
Hudell May 15, 2018
9df74b4
Merge branch 'develop' into irc-server-federation-rfc2813
Hudell May 15, 2018
99edf0f
Merge branch 'develop' into irc-server-federation-rfc2813
Hudell May 15, 2018
3159729
Merge branch 'develop' into irc-server-federation-rfc2813
Hudell May 16, 2018
0678020
Added a button to reset the IRC connection
Hudell May 21, 2018
73cbd78
Adjusted messages
Hudell May 21, 2018
2e15b4e
Merge branch 'irc-server-federation-rfc2813' of github.com:RocketChat…
Hudell May 21, 2018
37924da
Merge branch 'develop' into irc-server-federation-rfc2813
Hudell May 21, 2018
79415ac
Fixed IRC federation for new users
pierre-lehnen-rc May 25, 2018
944f8cc
Merge branch 'develop' into irc-server-federation-rfc2813
pierre-lehnen-rc May 25, 2018
3479de9
Ignore eslint about control character on regex
pierre-lehnen-rc May 25, 2018
0ab003d
Adjusted settings strings
pierre-lehnen-rc May 25, 2018
5b9e862
Merge branch 'develop' into irc-server-federation-rfc2813
pierre-lehnen-rc May 28, 2018
db8dcd8
Merge branch 'develop' into irc-server-federation-rfc2813
Hudell Jun 6, 2018
2ca5a50
Merge branch 'develop' into irc-server-federation-rfc2813
engelgabriel Jun 7, 2018
81a609d
Merge branch 'develop' into irc-server-federation-rfc2813
Hudell Jun 7, 2018
fcb10d6
Merge branch 'develop' into irc-server-federation-rfc2813
Hudell Jun 8, 2018
73a5941
Merge branch 'develop' into irc-server-federation-rfc2813
Hudell Jun 8, 2018
9618437
Merge branch 'develop' into irc-server-federation-rfc2813
Hudell Jun 20, 2018
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .meteor/versions
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ rocketchat:importer-slack@0.0.1
rocketchat:importer-slack-users@1.0.0
rocketchat:integrations@0.0.1
rocketchat:internal-hubot@0.0.1
rocketchat:irc@0.0.2
rocketchat:irc@0.0.1
rocketchat:issuelinks@0.0.1
rocketchat:katex@0.0.1
rocketchat:lazy-load@0.0.1
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@
"poplib": "^0.1.7",
"prom-client": "^11.0.0",
"querystring": "^0.2.0",
"queue-fifo": "^0.2.4",
"redis": "^2.8.0",
"semver": "^5.5.0",
"sharp": "^0.20.3",
Expand Down
6 changes: 6 additions & 0 deletions packages/rocketchat-i18n/i18n/en.i18n.json
Original file line number Diff line number Diff line change
Expand Up @@ -538,6 +538,8 @@
"Condensed": "Condensed",
"Computer": "Computer",
"Confirm_password": "Confirm your password",
"Connection_Closed" : "Connection closed",
"Connection_Reset" : "Connection reset",
"Consulting": "Consulting",
"Consumer_Goods": "Consumer Goods",
"Contains_Security_Fixes": "Contains Security Fixes",
Expand Down Expand Up @@ -1391,6 +1393,9 @@
"IRC_Channel_Users_End": "End of output of the NAMES command.",
"IRC_Description": "Internet Relay Chat (IRC) is a text-based group communication tool. Users join uniquely named channels, or rooms, for open discussion. IRC also supports private messages between individual users and file sharing capabilities. This package integrates these layers of functionality with Rocket.Chat.",
"IRC_Enabled": "Attempt to integrate IRC support. Changing this value requires restarting Rocket.Chat.",
"IRC_Enabled_Alert": "IRC Support is a work in progress. Use on a production system is not recommended at this time.",
"IRC_Federation": "IRC Federation",
"IRC_Federation_Disabled": "IRC Federation is disabled.",
"IRC_Hostname": "The IRC host server to connect to.",
"IRC_Login_Fail": "Output upon a failed connection to the IRC server.",
"IRC_Login_Success": "Output upon a successful connection to the IRC server.",
Expand Down Expand Up @@ -2057,6 +2062,7 @@
"Reset": "Reset",
"Reset_password": "Reset password",
"Reset_section_settings": "Reset Section Settings",
"Reset_Connection" : "Reset Connection",
"Restart": "Restart",
"Restart_the_server": "Restart the server",
"Retail": "Retail",
Expand Down
1 change: 1 addition & 0 deletions packages/rocketchat-irc/.npm/package/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
node_modules
7 changes: 7 additions & 0 deletions packages/rocketchat-irc/.npm/package/README
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
This directory and the files immediately inside it are automatically generated
when you change this package's NPM dependencies. Commit the files in this
directory (npm-shrinkwrap.json, .gitignore, and this README) to source control
so that others run the same versions of sub-dependencies.

You should NOT check in the node_modules directory that Meteor automatically
creates; if you are using git, the .gitignore file tells git to ignore it.
20 changes: 20 additions & 0 deletions packages/rocketchat-irc/.npm/package/npm-shrinkwrap.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 9 additions & 7 deletions packages/rocketchat-irc/package.js
Original file line number Diff line number Diff line change
@@ -1,20 +1,22 @@
Package.describe({
name: 'rocketchat:irc',
version: '0.0.2',
summary: 'RocketChat libraries',
version: '0.0.1',
summary: 'RocketChat support for federating with IRC servers as a leaf node',
git: ''
});

Package.onUse(function(api) {
api.use([
'ecmascript',
'underscore',
'rocketchat:lib'
]);

api.addFiles([
'server/settings.js',
'server/server.js'
], 'server');
api.addFiles('server/irc.js', 'server');
api.addFiles('server/methods/resetIrcConnection.js', 'server');
api.addFiles('server/irc-settings.js', 'server');
});

api.export(['Irc'], ['server']);
Npm.depends({
'queue-fifo': '0.2.4'
});
138 changes: 138 additions & 0 deletions packages/rocketchat-irc/server/irc-bridge/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
import Queue from 'queue-fifo';
import * as servers from '../servers';
import * as peerCommandHandlers from './peerHandlers';
import * as localCommandHandlers from './localHandlers';

class Bridge {
constructor(config) {
// General
this.config = config;

// Workaround for Rocket.Chat callbacks being called multiple times
this.loggedInUsers = [];

// Server
const Server = servers[this.config.server.protocol];

this.server = new Server(this.config);

this.setupPeerHandlers();
this.setupLocalHandlers();

// Command queue
this.queue = new Queue();
this.queueTimeout = 5;
}

init() {
this.loggedInUsers = [];
this.server.register();

this.server.on('registered', () => {
this.logQueue('Starting...');

this.runQueue();
});
}

stop() {
this.server.disconnect();
}

/**
* Log helper
*/
log(message) {
console.log(`[irc][bridge] ${ message }`);
}

logQueue(message) {
console.log(`[irc][bridge][queue] ${ message }`);
}

/**
*
*
* Queue
*
*
*/
onMessageReceived(from, command, ...parameters) {
this.queue.enqueue({ from, command, parameters });
}

async runQueue() {
// If it is empty, skip and keep the queue going
if (this.queue.isEmpty()) {
return setTimeout(this.runQueue.bind(this), this.queueTimeout);
}

// Get the command
const item = this.queue.dequeue();

this.logQueue(`Processing "${ item.command }" command from "${ item.from }"`);

// Handle the command accordingly
switch (item.from) {
case 'local':
if (!localCommandHandlers[item.command]) {
throw new Error(`Could not find handler for local:${ item.command }`);
}

await localCommandHandlers[item.command].apply(this, item.parameters);
break;
case 'peer':
if (!peerCommandHandlers[item.command]) {
throw new Error(`Could not find handler for peer:${ item.command }`);
}

await peerCommandHandlers[item.command].apply(this, item.parameters);
break;
}

// Keep the queue going
setTimeout(this.runQueue.bind(this), this.queueTimeout);
}

/**
*
*
* Peer
*
*
*/
setupPeerHandlers() {
this.server.on('peerCommand', (cmd) => {
this.onMessageReceived('peer', cmd.identifier, cmd.args);
});
}

/**
*
*
* Local
*
*
*/
setupLocalHandlers() {
// Auth
RocketChat.callbacks.add('afterValidateLogin', this.onMessageReceived.bind(this, 'local', 'onLogin'), RocketChat.callbacks.priority.LOW, 'irc-on-login');
RocketChat.callbacks.add('afterCreateUser', this.onMessageReceived.bind(this, 'local', 'onCreateUser'), RocketChat.callbacks.priority.LOW, 'irc-on-create-user');
// Joining rooms or channels
RocketChat.callbacks.add('afterCreateChannel', this.onMessageReceived.bind(this, 'local', 'onCreateRoom'), RocketChat.callbacks.priority.LOW, 'irc-on-create-channel');
RocketChat.callbacks.add('afterCreateRoom', this.onMessageReceived.bind(this, 'local', 'onCreateRoom'), RocketChat.callbacks.priority.LOW, 'irc-on-create-room');
RocketChat.callbacks.add('afterJoinRoom', this.onMessageReceived.bind(this, 'local', 'onJoinRoom'), RocketChat.callbacks.priority.LOW, 'irc-on-join-room');
// Leaving rooms or channels
RocketChat.callbacks.add('afterLeaveRoom', this.onMessageReceived.bind(this, 'local', 'onLeaveRoom'), RocketChat.callbacks.priority.LOW, 'irc-on-leave-room');
// Chatting
RocketChat.callbacks.add('afterSaveMessage', this.onMessageReceived.bind(this, 'local', 'onSaveMessage'), RocketChat.callbacks.priority.LOW, 'irc-on-save-message');
// Leaving
RocketChat.callbacks.add('afterLogoutCleanUp', this.onMessageReceived.bind(this, 'local', 'onLogout'), RocketChat.callbacks.priority.LOW, 'irc-on-logout');
}

sendCommand(command, parameters) {
this.server.emit('onReceiveFromLocal', command, parameters);
}
}

export default Bridge;
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import onCreateRoom from './onCreateRoom';
import onJoinRoom from './onJoinRoom';
import onLeaveRoom from './onLeaveRoom';
import onLogin from './onLogin';
import onLogout from './onLogout';
import onSaveMessage from './onSaveMessage';
import onCreateUser from './onCreateUser';

export { onCreateRoom, onJoinRoom, onLeaveRoom, onLogin, onLogout, onSaveMessage, onCreateUser };
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
export default function handleOnCreateRoom(user, room) {
if (!room.usernames) {
return this.log(`Room ${ room.name } does not have a valid list of usernames`);
}

for (const username of room.usernames) {
const user = RocketChat.models.Users.findOne({ username });

if (user.profile.irc.fromIRC) {
this.sendCommand('joinChannel', { room, user });
} else {
this.sendCommand('joinedChannel', { room, user });
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
export default function handleOnCreateUser(newUser) {
if (!newUser) {
return this.log('Invalid handleOnCreateUser call');
}
if (!newUser.username) {
return this.log('Invalid handleOnCreateUser call (Missing username)');
}
if (this.loggedInUsers.indexOf(newUser._id) !== -1) {
return this.log('Duplicate handleOnCreateUser call');
}

this.loggedInUsers.push(newUser._id);

Meteor.users.update({ _id: newUser._id }, {
$set: {
'profile.irc.fromIRC': false,
'profile.irc.username': `${ newUser.username }-rkt`,
'profile.irc.nick': `${ newUser.username }-rkt`,
'profile.irc.hostname': 'rocket.chat'
}
});

const user = RocketChat.models.Users.findOne({
_id: newUser._id
});

this.sendCommand('registerUser', user);

const rooms = RocketChat.models.Rooms.findWithUsername(user.username).fetch();

rooms.forEach(room => this.sendCommand('joinedChannel', { room, user }));
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export default function handleOnJoinRoom(user, room) {
this.sendCommand('joinedChannel', { room, user });
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export default function handleOnLeaveRoom(user, room) {
this.sendCommand('leftChannel', { room, user });
}
32 changes: 32 additions & 0 deletions packages/rocketchat-irc/server/irc-bridge/localHandlers/onLogin.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
export default function handleOnLogin(login) {
if (login.user === null) {
return this.log('Invalid handleOnLogin call');
}
if (!login.user.username) {
return this.log('Invalid handleOnLogin call (Missing username)');
}
if (this.loggedInUsers.indexOf(login.user._id) !== -1) {
return this.log('Duplicate handleOnLogin call');
}

this.loggedInUsers.push(login.user._id);

Meteor.users.update({ _id: login.user._id }, {
$set: {
'profile.irc.fromIRC': false,
'profile.irc.username': `${ login.user.username }-rkt`,
'profile.irc.nick': `${ login.user.username }-rkt`,
'profile.irc.hostname': 'rocket.chat'
}
});

const user = RocketChat.models.Users.findOne({
_id: login.user._id
});

this.sendCommand('registerUser', user);

const rooms = RocketChat.models.Rooms.findWithUsername(user.username).fetch();

rooms.forEach(room => this.sendCommand('joinedChannel', { room, user }));
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import _ from 'underscore';

export default function handleOnLogout(user) {
this.loggedInUsers = _.without(this.loggedInUsers, user._id);

this.sendCommand('disconnected', { user });
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
export default function handleOnSaveMessage(message, to) {
let toIdentification = '';
// Direct message
if (to.t === 'd') {
const subscriptions = RocketChat.models.Subscriptions.findByRoomId(to._id);
subscriptions.forEach((subscription) => {
if (subscription.u.username !== to.username) {
const userData = RocketChat.models.Users.findOne({ username: subscription.u.username });
if (userData) {
if (userData.profile && userData.profile.irc && userData.profile.irc.nick) {
toIdentification = userData.profile.irc.nick;
} else {
toIdentification = userData.username;
}
} else {
toIdentification = subscription.u.username;
}
}
});

if (!toIdentification) {
console.error('[irc][server] Target user not found');
return;
}
} else {
toIdentification = `#${ to.name }`;
}

const user = RocketChat.models.Users.findOne({ _id: message.u._id });

this.sendCommand('sentMessage', { to: toIdentification, user, message: message.msg });
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
export default function handleQUIT(args) {
const user = RocketChat.models.Users.findOne({
'profile.irc.nick': args.nick
});

Meteor.users.update({ _id: user._id }, {
$set: {
status: 'offline'
}
});

RocketChat.models.Rooms.removeUsernameFromAll(user.username);
}
Loading