2017-08-29 00:08:08 +02:00
|
|
|
|
function U2f(webVaultUrl, successCallback, errorCallback, infoCallback) {
|
2017-06-26 21:37:15 +02:00
|
|
|
|
this.success = successCallback;
|
|
|
|
|
this.error = errorCallback;
|
|
|
|
|
this.info = infoCallback;
|
|
|
|
|
this.iframe = null;
|
2017-06-27 14:15:29 +02:00
|
|
|
|
this.connectorLink = document.createElement('a');
|
2017-08-29 00:08:08 +02:00
|
|
|
|
this.webVaultUrl = webVaultUrl && webVaultUrl !== '' ? webVaultUrl : 'https://vault.bitwarden.com';
|
2017-07-14 21:34:05 +02:00
|
|
|
|
}
|
2017-06-26 21:37:15 +02:00
|
|
|
|
|
2017-07-26 06:20:30 +02:00
|
|
|
|
(function () {
|
|
|
|
|
var thisU2f = null;
|
2017-06-26 21:37:15 +02:00
|
|
|
|
|
2017-07-26 06:20:30 +02:00
|
|
|
|
U2f.prototype.init = function (data) {
|
|
|
|
|
var self = thisU2f = this;
|
2017-06-26 21:37:15 +02:00
|
|
|
|
|
2017-08-29 00:08:08 +02:00
|
|
|
|
self.connectorLink.href = self.webVaultUrl + '/u2f-connector.html' +
|
2017-07-26 06:20:30 +02:00
|
|
|
|
'?data=' + this.base64Encode(JSON.stringify(data)) +
|
|
|
|
|
'&parent=' + encodeURIComponent(document.location.href) +
|
|
|
|
|
'&v=1';
|
2017-06-27 14:15:29 +02:00
|
|
|
|
|
2017-07-26 06:20:30 +02:00
|
|
|
|
self.iframe = document.getElementById('u2f_iframe');
|
|
|
|
|
self.iframe.src = self.connectorLink.href;
|
|
|
|
|
|
|
|
|
|
window.addEventListener('message', parseMessage, false);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
U2f.prototype.validMessage = function (event) {
|
|
|
|
|
if (!event.origin || event.origin === '' || event.origin !== this.connectorLink.origin) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return event.data.indexOf('success|') === 0 || event.data.indexOf('error|') === 0 || event.data.indexOf('info|') === 0;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
U2f.prototype.stop = function () {
|
|
|
|
|
this.sendMessage('stop');
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
U2f.prototype.start = function () {
|
|
|
|
|
this.sendMessage('start');
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
U2f.prototype.sendMessage = function (message) {
|
|
|
|
|
var self = this;
|
|
|
|
|
if (!self.iframe || !self.iframe.src || !self.iframe.contentWindow) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
self.iframe.contentWindow.postMessage(message, self.iframe.src);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
U2f.prototype.base64Encode = function (str) {
|
|
|
|
|
return btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, function (match, p1) {
|
|
|
|
|
return String.fromCharCode('0x' + p1);
|
|
|
|
|
}));
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
U2f.prototype.cleanup = function () {
|
|
|
|
|
window.removeEventListener('message', parseMessage, false);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
function parseMessage(event) {
|
|
|
|
|
if (!thisU2f) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!thisU2f.validMessage(event)) {
|
|
|
|
|
thisU2f.error('Invalid message.');
|
2017-06-26 21:37:15 +02:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var parts = event.data.split('|');
|
2017-07-26 06:20:30 +02:00
|
|
|
|
if (parts[0] === 'success' && thisU2f.success) {
|
|
|
|
|
thisU2f.success(parts[1]);
|
2017-06-26 21:37:15 +02:00
|
|
|
|
}
|
2017-07-26 06:20:30 +02:00
|
|
|
|
else if (parts[0] === 'error' && thisU2f.error) {
|
|
|
|
|
thisU2f.error(parts[1]);
|
2017-06-26 21:37:15 +02:00
|
|
|
|
}
|
|
|
|
|
else if (parts[0] === 'info') {
|
2017-07-26 06:20:30 +02:00
|
|
|
|
if (thisU2f.info) {
|
|
|
|
|
thisU2f.info(parts[1]);
|
2017-06-26 21:37:15 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
2017-07-26 20:05:02 +02:00
|
|
|
|
}
|
2017-07-26 06:20:30 +02:00
|
|
|
|
})();
|