|
|
@ -24,6 +24,17 @@ async function checkUserPermissions(sender) {
|
|
|
|
return false;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
async function loginUser(matrixUser, remoteUser, oauthToken) {
|
|
|
|
|
|
|
|
remoteUser.set('password', oauthToken);
|
|
|
|
|
|
|
|
await bridge.getUserStore().linkUsers(matrixUser, remoteUser)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
async function logoutUser(matrixId) {
|
|
|
|
|
|
|
|
const links = await bridge.getUserStore().getRemoteLinks(matrixId);
|
|
|
|
|
|
|
|
links.forEach(async remoteId => {
|
|
|
|
|
|
|
|
await bridge.getUserStore().unlinkUserIds(matrixId, remoteId);
|
|
|
|
|
|
|
|
console.log('Removed credentials of', remoteId, 'by', matrixId);
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
}
|
|
|
|
async function bridgeRoom(sender, matrixRoom, remoteRoom) {
|
|
|
|
async function bridgeRoom(sender, matrixRoom, remoteRoom) {
|
|
|
|
await bridge.getRoomStore().linkRooms(matrixRoom, remoteRoom);
|
|
|
|
await bridge.getRoomStore().linkRooms(matrixRoom, remoteRoom);
|
|
|
|
console.log('Linked rooms', matrixRoom.roomId, 'and', remoteRoom.roomId, 'by', sender);
|
|
|
|
console.log('Linked rooms', matrixRoom.roomId, 'and', remoteRoom.roomId, 'by', sender);
|
|
|
@ -35,47 +46,63 @@ async function unbridgeRoom(sender, roomId) {
|
|
|
|
async function matrixEventHandler(request, context) {
|
|
|
|
async function matrixEventHandler(request, context) {
|
|
|
|
const event = request.getData();
|
|
|
|
const event = request.getData();
|
|
|
|
|
|
|
|
|
|
|
|
if(event.type === 'm.room.message') {
|
|
|
|
if(!await checkUserPermissions(event.sender)) {
|
|
|
|
const message = event.content.body;
|
|
|
|
// no permissions; don't bridge
|
|
|
|
|
|
|
|
|
|
|
|
const remoteUsers = await bridge.getUserStore().getRemoteUsersFromMatrixId(event.sender);
|
|
|
|
|
|
|
|
// use the first user, multipe user mappings are unsupported
|
|
|
|
|
|
|
|
const remoteUser = remoteUsers[0];
|
|
|
|
|
|
|
|
if(!remoteUser) {
|
|
|
|
|
|
|
|
// ignore messages from users without tmi credentials
|
|
|
|
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if(event.type === 'm.room.message') {
|
|
|
|
|
|
|
|
const message = event.content.body;
|
|
|
|
|
|
|
|
|
|
|
|
// handle bot commands and return directly afterwards
|
|
|
|
// handle bot commands and return directly afterwards
|
|
|
|
const command = message.match(/^!tmi (?<subcommand>\w*)( (?<args>.*))?$/);
|
|
|
|
const command = message.match(/^!tmi (?<subcommand>\w*)( (?<args>.*))?$/);
|
|
|
|
if(command) {
|
|
|
|
if(command) {
|
|
|
|
|
|
|
|
switch (command.groups.subcommand) {
|
|
|
|
|
|
|
|
case 'login':
|
|
|
|
|
|
|
|
const args = command.groups.args.split(' ');
|
|
|
|
|
|
|
|
const tmiUser = args[0];
|
|
|
|
|
|
|
|
const oauthToken = args[1];
|
|
|
|
|
|
|
|
await loginUser(new mx.MatrixUser(event.sender), new mx.RemoteUser(tmiUser), oauthToken);
|
|
|
|
|
|
|
|
bridge.getIntent().sendText(event.room_id, 'Saved oauth token of '+event.sender+' - please redact your login message to protect the token');
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
case 'logout':
|
|
|
|
|
|
|
|
await logoutUser(event.sender);
|
|
|
|
|
|
|
|
bridge.getIntent().sendText(event.room_id, 'Removed oauth token of '+event.sender);
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
case 'bridge':
|
|
|
|
if(!await checkAdminPermissions(event.sender)) {
|
|
|
|
if(!await checkAdminPermissions(event.sender)) {
|
|
|
|
bridge.getIntent().sendText(event.room_id, event.sender+' is not permitted as admin of this bridge');
|
|
|
|
bridge.getIntent().sendText(event.room_id, event.sender+' is not permitted as admin of this bridge');
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
switch (command.groups.subcommand) {
|
|
|
|
|
|
|
|
case 'bridge':
|
|
|
|
|
|
|
|
let channel = command.groups.args.toLowerCase();
|
|
|
|
let channel = command.groups.args.toLowerCase();
|
|
|
|
if(!channel.match(/^#/)) {
|
|
|
|
if(!channel.match(/^#/)) {
|
|
|
|
channel = '#'+channel
|
|
|
|
channel = '#'+channel
|
|
|
|
}
|
|
|
|
}
|
|
|
|
bridgeRoom(event.sender, new mx.MatrixRoom(event.room_id), new mx.RemoteRoom(channel));
|
|
|
|
bridgeRoom(event.sender, new mx.MatrixRoom(event.room_id), new mx.RemoteRoom(channel));
|
|
|
|
bridge.getIntent().sendText(event.room_id, 'This room is now bridged to '+channel);
|
|
|
|
bridge.getIntent().sendText(event.room_id, 'This room is now bridged to '+channel);
|
|
|
|
break;
|
|
|
|
return;
|
|
|
|
case 'unbridge':
|
|
|
|
case 'unbridge':
|
|
|
|
unbridgeRoom(event.sender, event.room_id);
|
|
|
|
if(!await checkAdminPermissions(event.sender)) {
|
|
|
|
bridge.getIntent().sendText(event.room_id, 'Removed all bridges from this room');
|
|
|
|
bridge.getIntent().sendText(event.room_id, event.sender+' is not permitted as admin of this bridge');
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
|
|
|
bridge.getIntent().sendText(event.room_id, 'available commands: bridge, unbridge');
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if(!await checkUserPermissions(event.sender)) {
|
|
|
|
unbridgeRoom(event.sender, event.room_id);
|
|
|
|
// no permissions; don't bridge
|
|
|
|
bridge.getIntent().sendText(event.room_id, 'Removed all bridges from this room');
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
|
|
|
bridge.getIntent().sendText(event.room_id, 'available commands: login, logout, bridge, unbridge');
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const remoteUsers = await bridge.getUserStore().getRemoteUsersFromMatrixId(event.sender);
|
|
|
|
|
|
|
|
// use the first user, multipe user mappings are unsupported
|
|
|
|
|
|
|
|
const remoteUser = remoteUsers[0];
|
|
|
|
|
|
|
|
if(!remoteUser) {
|
|
|
|
|
|
|
|
// ignore messages from users without tmi credentials
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|