mirror of https://github.com/vector-im/riot-web
Register and de-register widget postMessage endpoints.
parent
2cfbbb000e
commit
be603fecb0
|
@ -14,20 +14,22 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
let listenerCount = 0;
|
||||||
|
let messageEndpoints = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle widget postMessage events
|
* Handle widget postMessage events
|
||||||
* @param {Event} event Event to handle
|
* @param {Event} event Event to handle
|
||||||
* @return {undefined}
|
* @return {undefined}
|
||||||
*/
|
*/
|
||||||
function onMessage(event) {
|
function onMessage(event) {
|
||||||
console.warn("Checking for widget event", event);
|
|
||||||
if (!event.origin) { // Handle chrome
|
if (!event.origin) { // Handle chrome
|
||||||
event.origin = event.originalEvent.origin;
|
event.origin = event.originalEvent.origin;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Event origin is empty string if undefined
|
// Event origin is empty string if undefined
|
||||||
if (event.origin.length === 0 || !event.data.widgetData) {
|
if (event.origin.length === 0 || trustedEndpoint(event.origin) || !event.data.widgetData) {
|
||||||
// TODO / FIXME -- check for valid origin URLs!!
|
console.warn("Ignoring postMessage", event);
|
||||||
return; // don't log this - debugging APIs like to spam postMessage which floods the log otherwise
|
return; // don't log this - debugging APIs like to spam postMessage which floods the log otherwise
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,11 +37,49 @@ function onMessage(event) {
|
||||||
alert(event.data.widgetData);
|
alert(event.data.widgetData);
|
||||||
}
|
}
|
||||||
|
|
||||||
let listenerCount = 0;
|
/**
|
||||||
|
* Check if message origin is registered as trusted
|
||||||
|
* @param {string} origin PostMessage origin to check
|
||||||
|
* @return {boolean} True if trusted
|
||||||
|
*/
|
||||||
|
function trustedEndpoint(origin) {
|
||||||
|
if (origin) {
|
||||||
|
if (messageEndpoints.filter(function(endpoint) {
|
||||||
|
if (endpoint.endpointUrl == origin) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}).length > 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents mapping of widget instance to URLs for trusted postMessage communication.
|
||||||
|
*/
|
||||||
|
class WidgetMessageEndpoint {
|
||||||
|
/**
|
||||||
|
* Mapping of widget instance to URL for trusted postMessage communication.
|
||||||
|
* @param {string} widgetId Unique widget identifier
|
||||||
|
* @param {string} endpointUrl Widget wurl origin.
|
||||||
|
*/
|
||||||
|
constructor(widgetId, endpointUrl) {
|
||||||
|
if (!widgetId) {
|
||||||
|
throw new Error("No widgetId specified in widgetMessageEndpoint constructor");
|
||||||
|
}
|
||||||
|
if (!endpointUrl) {
|
||||||
|
throw new Error("No endpoint specified in widgetMessageEndpoint constructor");
|
||||||
|
}
|
||||||
|
this.widgetId = widgetId;
|
||||||
|
this.endpointUrl = endpointUrl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
/**
|
/**
|
||||||
* Register widget message event listeners
|
* Register widget message event listeners
|
||||||
* @return {undefined}
|
|
||||||
*/
|
*/
|
||||||
startListening() {
|
startListening() {
|
||||||
if (listenerCount === 0) {
|
if (listenerCount === 0) {
|
||||||
|
@ -48,6 +88,9 @@ module.exports = {
|
||||||
listenerCount += 1;
|
listenerCount += 1;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* De-register widget message event listeners
|
||||||
|
*/
|
||||||
stopListening() {
|
stopListening() {
|
||||||
listenerCount -= 1;
|
listenerCount -= 1;
|
||||||
if (listenerCount === 0) {
|
if (listenerCount === 0) {
|
||||||
|
@ -62,4 +105,39 @@ module.exports = {
|
||||||
console.error(e);
|
console.error(e);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register a widget endpoint for trusted postMessage communication
|
||||||
|
* @param {string} widgetId Unique widget identifier
|
||||||
|
* @param {string} endpointUrl Widget wurl origin (protocol + (optional port) + host)
|
||||||
|
*/
|
||||||
|
addEndpoint(widgetId, endpointUrl) {
|
||||||
|
const endpoint = new WidgetMessageEndpoint(widgetId, endpointUrl);
|
||||||
|
if (messageEndpoints && messageEndpoints.length > 0) {
|
||||||
|
if (messageEndpoints.filter(function(ep) {
|
||||||
|
return (ep.widgetId == widgetId && ep.endpointUrl == endpointUrl);
|
||||||
|
}).length > 0) {
|
||||||
|
// Message endpoint already registered
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
messageEndpoints.push(endpoint);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* De-register a widget endpoint from trusted communication sources
|
||||||
|
* @param {string} widgetId Unique widget identifier
|
||||||
|
* @param {string} endpointUrl Widget wurl origin (protocol + (optional port) + host)
|
||||||
|
* @return {boolean} True if endpoint was successfully removed
|
||||||
|
*/
|
||||||
|
removeOrigin(widgetId, endpointUrl) {
|
||||||
|
if (messageEndpoints && messageEndpoints.length > 0) {
|
||||||
|
const length = messageEndpoints.length;
|
||||||
|
messageEndpoints = messageEndpoints.filter(function(endpoint) {
|
||||||
|
return (endpoint.widgetId != widgetId || endpoint.endpointUrl != endpointUrl);
|
||||||
|
});
|
||||||
|
return (length > messageEndpoints.length);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue