Switch to 'm.sticker' message events. Allow whitelisting of wisget capabilities.

This commit is contained in:
Richard Lewis 2018-03-12 13:56:02 +00:00
parent 46f46ee294
commit b2d23b6999
6 changed files with 41 additions and 13 deletions

View file

@ -195,8 +195,8 @@ export default class WidgetMessaging extends MatrixPostMessageApi {
api: INBOUND_API_NAME, api: INBOUND_API_NAME,
version: WIDGET_API_VERSION, version: WIDGET_API_VERSION,
}); });
} else if (action === 'sticker_message') { } else if (action === 'm.sticker') {
dis.dispatch({action: 'sticker_message', data: event.data.widgetData, widgetId: event.data.widgetId}); dis.dispatch({action: 'm.sticker', data: event.data.widgetData, widgetId: event.data.widgetId});
} else if (action === 'integration_manager_open') { } else if (action === 'integration_manager_open') {
// Close the stickerpicker // Close the stickerpicker
dis.dispatch({action: 'stickerpicker_close'}); dis.dispatch({action: 'stickerpicker_close'});

View file

@ -69,7 +69,7 @@ const FilePanel = React.createClass({
"timeline": { "timeline": {
"contains_url": true, "contains_url": true,
"not_types": [ "not_types": [
"m.room.sticker", "m.sticker",
], ],
}, },
}, },

View file

@ -72,7 +72,9 @@ export default class AppTile extends React.Component {
error: null, error: null,
deleting: false, deleting: false,
widgetPageTitle: newProps.widgetPageTitle, widgetPageTitle: newProps.widgetPageTitle,
capabilities: [], allowedCapabilities: (this.props.whitelistCapabilities && this.props.whitelistCapabilities.length > 0) ?
this.props.whitelistCapabilities : [],
requestedCapabilities: [],
}; };
} }
@ -82,7 +84,7 @@ export default class AppTile extends React.Component {
* @return {Boolean} True if capability supported * @return {Boolean} True if capability supported
*/ */
_hasCapability(capability) { _hasCapability(capability) {
return this.state.capabilities.some((c) => {return c === capability;}); return this.state.allowedCapabilities.some((c) => {return c === capability;});
} }
/** /**
@ -341,10 +343,27 @@ export default class AppTile extends React.Component {
this.widgetMessaging = new WidgetMessaging(this.props.id, this.refs.appFrame.contentWindow); this.widgetMessaging = new WidgetMessaging(this.props.id, this.refs.appFrame.contentWindow);
this.widgetMessaging.startListening(); this.widgetMessaging.startListening();
this.widgetMessaging.addEndpoint(this.props.id, this.props.url); this.widgetMessaging.addEndpoint(this.props.id, this.props.url);
this.widgetMessaging.getCapabilities().then((capabilities) => { this.widgetMessaging.getCapabilities().then((requestedCapabilities) => {
console.log("Got widget capabilities", this.props.id, capabilities); console.log(`Widget ${this.props.id} requested capabilities:`, requestedCapabilities);
capabilities = capabilities || []; requestedCapabilities = requestedCapabilities || [];
this.setState({capabilities});
// Allow whitelisted capabilities
const requestedWhitelistCapabilies =
requestedCapabilities.filter(function(e) {
return this.indexOf(e)>=0;
}, this.props.whitelistCapabilities);
console.warn(`Widget ${this.props.id} allowing requested, whitelisted properties:`,
requestedWhitelistCapabilies);
// TODO -- Add UI to warn about and optionally allow requested capabilities
this.setState({
requestedCapabilities,
allowedCapabilities: this.state.allowedCapabilities.concat(requestedWhitelistCapabilies),
});
if (this.props.onCapabilityRequest) {
this.props.onCapabilityRequest(requestedCapabilities);
}
}).catch((err) => { }).catch((err) => {
console.log("Failed to get widget capabilities", this.widgetId, err); console.log("Failed to get widget capabilities", this.widgetId, err);
}); });
@ -354,8 +373,8 @@ export default class AppTile extends React.Component {
_onWidgetAction(payload) { _onWidgetAction(payload) {
if (payload.widgetId === this.props.id) { if (payload.widgetId === this.props.id) {
switch (payload.action) { switch (payload.action) {
case 'sticker_message': case 'm.sticker':
if (this._hasCapability('sticker_message')) { if (this._hasCapability('m.sticker')) {
dis.dispatch({action: 'post_sticker_message', data: payload.data}); dis.dispatch({action: 'post_sticker_message', data: payload.data});
} else { } else {
console.warn('Ignoring sticker message. Invalid capability'); console.warn('Ignoring sticker message. Invalid capability');
@ -626,6 +645,13 @@ AppTile.propTypes = {
handleMinimisePointerEvents: PropTypes.bool, handleMinimisePointerEvents: PropTypes.bool,
// Optionally hide the delete icon // Optionally hide the delete icon
showDelete: PropTypes.bool, showDelete: PropTypes.bool,
// Widget apabilities to allow by default (without user confirmation)
// NOTE -- Use with caution. This is intended to aid better integration / UX
// basic widget capabilities, e.g. injecting sticker message events.
whitelistCapabilities: PropTypes.array,
// Optional function to be called on widget capability request
// Called with an array of the requested capabilities
onCapabilityRequest: PropTypes.func,
}; };
AppTile.defaultProps = { AppTile.defaultProps = {
@ -636,4 +662,5 @@ AppTile.defaultProps = {
showMinimise: true, showMinimise: true,
showDelete: true, showDelete: true,
handleMinimisePointerEvents: false, handleMinimisePointerEvents: false,
whitelistCapabilities: [],
}; };

View file

@ -65,7 +65,7 @@ module.exports = React.createClass({
let BodyType = UnknownBody; let BodyType = UnknownBody;
if (msgtype && bodyTypes[msgtype]) { if (msgtype && bodyTypes[msgtype]) {
BodyType = bodyTypes[msgtype]; BodyType = bodyTypes[msgtype];
} else if (this.props.mxEvent.getType() === 'm.room.sticker') { } else if (this.props.mxEvent.getType() === 'm.sticker') {
BodyType = sdk.getComponent('messages.MStickerBody'); BodyType = sdk.getComponent('messages.MStickerBody');
} else if (content.url) { } else if (content.url) {
// Fallback to MFileBody if there's a content URL // Fallback to MFileBody if there's a content URL

View file

@ -36,7 +36,7 @@ const ObjectUtils = require('../../../ObjectUtils');
const eventTileTypes = { const eventTileTypes = {
'm.room.message': 'messages.MessageEvent', 'm.room.message': 'messages.MessageEvent',
'm.room.sticker': 'messages.MessageEvent', 'm.sticker': 'messages.MessageEvent',
'm.call.invite': 'messages.TextualEvent', 'm.call.invite': 'messages.TextualEvent',
'm.call.answer': 'messages.TextualEvent', 'm.call.answer': 'messages.TextualEvent',
'm.call.hangup': 'messages.TextualEvent', 'm.call.hangup': 'messages.TextualEvent',

View file

@ -159,6 +159,7 @@ export default class Stickerpicker extends React.Component {
showDelete={false} showDelete={false}
onMinimiseClick={this.onHideStickersClick} onMinimiseClick={this.onHideStickersClick}
handleMinimisePointerEvents={true} handleMinimisePointerEvents={true}
whitelistCapabilities={['m.sticker']}
/> />
</div> </div>
</div> </div>