Skip to content

Instantly share code, notes, and snippets.

@lmarkus
Created May 27, 2016 08:30
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save lmarkus/0315d6b7d6fa00ba1afd1d65667cf5b2 to your computer and use it in GitHub Desktop.
Save lmarkus/0315d6b7d6fa00ba1afd1d65667cf5b2 to your computer and use it in GitHub Desktop.
PGP over Slack using Greasemonkey
// ==UserScript==
// @name SlackPGP
// @namespace slack
// @description slackPGP
// @include https://*.slack.com/messages/*
// @version 1
// @grant none
// ==/UserScript==
//Evil globals
var publicKey = "0xDEADBEEF";
var privateKey = "";
var peerPublicKey;
var iStartedPGP;
var lastSent;
var myPeerId;
//Monkey patch Slack's message submit.
var submit = TS.view.submit;
function sendPublicKey() {
$('#message-input').val('handshake:' + publicKey);
submit();
}
/**
* Detect the other persons ID
* I can grab this from data hiding in the direct message channel title
*/
function getPeerId() {
myPeerId = myPeerId || $('#channel_header_info').find('span.presence').data('member-presence');
return myPeerId;
console.log('Peer: ' + myPeerId);
}
/**
Who sent this message? Me or my peer?
*/
function isFromPeer(senderId) {
return getPeerId() === senderId;
}
/**
* Drop in your favorite PGP library here....
*/
function encrypt(message, callback) {
setTimeout(function () {
console.log('encrypting with ', peerPublicKey);
return callback('%' + message + '%');
}, 0)
}
function decrypt(message, callback) {
setTimeout(function () {
console.log('dec using ', privateKey);
return callback(message.replace(/%/g, ''));
}, 0)
}
//Detect new message received. There's probably an event to hook into, but I'm lazy :)
$('#msgs_div').on('DOMNodeInserted', function (e) {
var target = $(e.target);
if (target.is('ts-message:not(.bot_message):not(.unprocessed)')) {//Ignore non-useful slack messages
console.log('message received!');
var container = target.find('.message_body');
var text = container.html();
var senderId = target.find('.message_sender').data('member-id');
console.log(senderId + ':', text);
if (isFromPeer(senderId)) {
// Check to see if we're establishing the handshake
if (text.match('^handshake:')) {
peerPublicKey = text.split(':')[1];
console.log('Received Key from peer');
if (!iStartedPGP) { //If I didn't start, then send them my public key.
sendPublicKey();
}
console.log('Handshake complete');
return;
}
// Otherwise decrypt the received text, and replace inline
decrypt(text, function (plainText) {
container.html(plainText);
});
}
else {
//Replace my encrypted text with plain, just on this client
container.html(lastSent)
}
}
});
/**
* Monkey Patch outgoing messages to make sure they're encrypted
*/
TS.view.submit = function () {
var message = lastSent = $('#message-input').val();
// Special case to begin an encrypted session.
if (message === 'pgp') {
iStartedPGP = true;
return sendPublicKey();
}
encrypt(message, function (encMessage) {
$('#message-input').val(encMessage);
submit();
})
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment