One shortcut to ring them all

Idea of the feature was to be able to define one keyboard shortcut in Electron application to handle all basic actions that can be done for managing calls in XiVO.

Basically, with one keypress we wanted to be able to:

  • Answer if phone is ringing
  • Hangup if phone is in call
  • Call if phone is available and clipboard contains phone number

So what is the problem ?

Indeed, defining a global shortcut is easy stuff in Electron, however as you may know, we already developed a Web-app that takes care of all this call business which is already wrapped in a desktop application as shown in following screenshot.

Desktop Assistant

Basically we wanted to avoid as much as possible side effect (and therefore coupling) between the Electron application and the existing Web-app.

So we started to think to a one way workflow to send the command from Electron to our Angular Web-app…

Technical solution

Message Workflow

How was it implemented ?

Electron

When combination of key is pressed from the keyboard, interceptor is defined in application.js

1
2
3
4
5
function setGlobalShortcut(browserWindow, keyCombination) {
globalShortcut.register(keyCombination, () => {
forwardMessage(browserWindow, clipboard.readText('selection'),phoneEvent)
});
}

Afterwards message is forwarded to Web-app thanks to HTML5 Messaging API

1
2
3
4
5
6
7
8
9
function forwardMessage(browserWindow, msg, type) {
try{
if (msg) browserWindow.webContents.
executeJavaScript('window.postMessage('+ JSON.stringify(new Message(type, msg)) +', "/")')
}
catch (exception){
console.log (exception);
}
}

Web application

In Web-app, then we just register DOM event listener to handle what we received

1
2
3
4
5
var _registerEventListener = function() {
angular.element($window).on('message', function (event) {
_handleEvent(event);
});
};

Security concerns

As described in previous diagram, we use postMessage() API (an HTML5 extension that originally permits string message-passing between frames).
postMessage is considered secure as long as the origin and source of an arriving message is checked. Acting on a message without verifying its source opens a vector for cross-site scripting attacks. that’s why in ExternalEvent.factory.js following checks are made:

  • Is message origin corresponds to application origin ?
  • Is message sent without using wildcards in the origin ?
  • Is message source corresponds to target source ?
  • Is message data not containing chars forbidden in SIP extension ?

(following checks are inspired from W3C recommendations)

Another risk, is to avoid key-repeated action (typically by keeping pressed the shortcut). This potential flaw is handled thanks to Debounce.factory.js that will prevent to forward the same event until a predefined timeout has been reached (500ms per default).

Share