index.js
function(options, params) {

            // create connection to qrs
            var qrsApi = qrs(options);

            var ip = params.ip;
            var vp = params.vp;
            
            // Returned object
            var task = new Task();

            // Promise chain
            // TODO: Convert this to a rx based logic
            var vpConfig = promise().then(function() {

                // Get proxy configuration
                return qrsApi.proxyservice.local.get();

            }).then(function(settings) {

                // Get virtual proxy configuration

                var vpsettings = undef.child(settings, 'settings.virtualProxies', []).filter(function(elem, index) {
                    if (undef.is(vp)) return true;
                    else if (parseInt(vp) === vp) return index == vp;
                    else return elem.prefix == vp;
                });

                return promise.all(vpsettings.map(function(vp) {
                    return qrsApi.virtualproxyconfig.id(vp.id).get();
                }));

            }).then(function(vpSettings) {

                return promise.all(vpSettings.map(function(settings) {

                    // If IP not already in whitelist

                    if (settings.websocketCrossOriginWhiteList.indexOf(ip) == -1) {

                        // Add it and push new config
                        // The mechanism with dates below makes sure that there is no desync between
                        // the client and the Qlik Sense server

                        settings.websocketCrossOriginWhiteList.push(ip);

                        var currDate = new Date();
                        var oldDate = new Date(settings.modifiedDate);
                        var newDate;

                        if (currDate > oldDate) {
                            newDate = currDate;
                        } else {
                            newDate = oldDate;
                            newDate.setSeconds(newDate.getSeconds() + 1);
                        }

                        settings.modifiedDate = newDate.toISOString();

                        return qrsApi.virtualproxyconfig.id(settings.id).put(settings);

                    } else {

                        // Else just return the VP config

                        return settings;
                    }
                }));

            });
            
            // Convert the promise chain to an observable and register our task object
            Rx.Observable.from(vpConfig).subscribe(task);
            
            if (returnObservable) {
                return task;
            } else {
                return task.toPromise(extPromise);
            }

        }
function(options, params) {

            // create connection to qrs
            var qrsApi = qrs(options);

            var ip = params.ip;
            var vp = params.vp;
            
            // Returned object
            var task = new Task();

            // Promise chain
            // TODO: Convert this to a rx based logic
            var vpConfig = promise().then(function() {

                // Get proxy configuration
                return qrsApi.proxyservice.local.get();

            }).then(function(settings) {

                // Get virtual proxy configuration

                var vpsettings = undef.child(settings, 'settings.virtualProxies', []).filter(function(elem, index) {
                    if (undef.is(vp)) return true;
                    else if (parseInt(vp) === vp) return index == vp;
                    else return elem.prefix == vp;
                });

                return promise.all(vpsettings.map(function(vp) {
                    return qrsApi.virtualproxyconfig.id(vp.id).get();
                }));

            }).then(function(vpSettings) {

                return promise.all(vpSettings.map(function(settings) {

                    // If IP not already in whitelist

                    if (settings.websocketCrossOriginWhiteList.indexOf(ip) == -1) {

                        // Add it and push new config
                        // The mechanism with dates below makes sure that there is no desync between
                        // the client and the Qlik Sense server

                        settings.websocketCrossOriginWhiteList.push(ip);

                        var currDate = new Date();
                        var oldDate = new Date(settings.modifiedDate);
                        var newDate;

                        if (currDate > oldDate) {
                            newDate = currDate;
                        } else {
                            newDate = oldDate;
                            newDate.setSeconds(newDate.getSeconds() + 1);
                        }

                        settings.modifiedDate = newDate.toISOString();

                        return qrsApi.virtualproxyconfig.id(settings.id).put(settings);

                    } else {

                        // Else just return the VP config

                        return settings;
                    }
                }));

            });
            
            // Convert the promise chain to an observable and register our task object
            Rx.Observable.from(vpConfig).subscribe(task);
            
            if (returnObservable) {
                return task;
            } else {
                return task.toPromise(extPromise);
            }

        }
Adds the given ip address to the websocket whitelist of the given virtual proxy.
Be careful: this restarts the proxy. The restart can take 1-2 seconds. All subsequent API
calls within this restart will fail miserably with various random & useless error messages.

@example
```javascript
readFile('./client.pfx').then(function(certif) {

return utils.Qlik.addToWhiteList({
restUri: 'https://10.76.224.72:4242',
pfx: certif,
passPhrase: '',
UserId: 'qlikservice',
UserDirectory: '2008R2-0',
params: {
ip: '10.76.224.72'
}
});

}).then(function(ret) {
console.log(ret);
}, function(ret) {
console.log(ret);
});
```

@memberOf Qlik

@param {options}             options         Qlik Sense connection options
@param {string}              params          parameters to add to the whitelist
@param {string}              params.ip       the ip to add
@param {string|int}          [params.vp]     the prefix or id of the virtual proxy to update. If null or false, this function will update all vps
@returns {Promise.<Object>}                  a promise resolving to the virtual proxy configuration when successfull