@@ -32,7 +32,7 @@ import {
3232 Widget ,
3333 WidgetApiToWidgetAction ,
3434 WidgetApiFromWidgetAction ,
35- IModalWidgetOpenRequest ,
35+ IModalWidgetOpenRequest , IWidgetApiErrorResponseData ,
3636} from "matrix-widget-api" ;
3737import { StopGapWidgetDriver } from "./StopGapWidgetDriver" ;
3838import { EventEmitter } from "events" ;
@@ -47,13 +47,14 @@ import { WidgetType } from "../../widgets/WidgetType";
4747import ActiveWidgetStore from "../ActiveWidgetStore" ;
4848import { objectShallowClone } from "../../utils/objects" ;
4949import defaultDispatcher from "../../dispatcher/dispatcher" ;
50- import { ElementWidgetActions } from "./ElementWidgetActions" ;
50+ import { ElementWidgetActions , IViewRoomApiRequest } from "./ElementWidgetActions" ;
5151import Modal from "../../Modal" ;
5252import WidgetOpenIDPermissionsDialog from "../../components/views/dialogs/WidgetOpenIDPermissionsDialog" ;
5353import { ModalWidgetStore } from "../ModalWidgetStore" ;
5454import ThemeWatcher from "../../settings/watchers/ThemeWatcher" ;
5555import { getCustomTheme } from "../../theme" ;
5656import CountlyAnalytics from "../../CountlyAnalytics" ;
57+ import { ElementWidgetCapabilities } from "./ElementWidgetCapabilities" ;
5758
5859// TODO: Destroy all of this code
5960
@@ -286,7 +287,8 @@ export class StopGapWidget extends EventEmitter {
286287
287288 public start ( iframe : HTMLIFrameElement ) {
288289 if ( this . started ) return ;
289- const driver = new StopGapWidgetDriver ( this . appTileProps . whitelistCapabilities || [ ] ) ;
290+ const allowedCapabilities = this . appTileProps . whitelistCapabilities || [ ] ;
291+ const driver = new StopGapWidgetDriver ( allowedCapabilities , this . mockWidget . type ) ;
290292 this . messaging = new ClientWidgetApi ( this . mockWidget , iframe , driver ) ;
291293 this . messaging . on ( "preparing" , ( ) => this . emit ( "preparing" ) ) ;
292294 this . messaging . on ( "ready" , ( ) => this . emit ( "ready" ) ) ;
@@ -298,6 +300,35 @@ export class StopGapWidget extends EventEmitter {
298300 ActiveWidgetStore . setRoomId ( this . mockWidget . id , this . appTileProps . room . roomId ) ;
299301 }
300302
303+ // Always attach a handler for ViewRoom, but permission check it internally
304+ this . messaging . on ( `action:${ ElementWidgetActions . ViewRoom } ` , ( ev : CustomEvent < IViewRoomApiRequest > ) => {
305+ ev . preventDefault ( ) ; // stop the widget API from auto-rejecting this
306+
307+ // Check up front if this is even a valid request
308+ const targetRoomId = ( ev . detail . data || { } ) . room_id ;
309+ if ( ! targetRoomId ) {
310+ return this . messaging . transport . reply ( ev . detail , < IWidgetApiErrorResponseData > {
311+ error : { message : "Invalid room ID." } ,
312+ } ) ;
313+ }
314+
315+ // Check the widget's permission
316+ if ( ! this . messaging . hasCapability ( ElementWidgetCapabilities . CanChangeViewedRoom ) ) {
317+ return this . messaging . transport . reply ( ev . detail , < IWidgetApiErrorResponseData > {
318+ error : { message : "This widget does not have permission for this action (denied)." } ,
319+ } ) ;
320+ }
321+
322+ // at this point we can change rooms, so do that
323+ defaultDispatcher . dispatch ( {
324+ action : 'view_room' ,
325+ room_id : targetRoomId ,
326+ } ) ;
327+
328+ // acknowledge so the widget doesn't freak out
329+ this . messaging . transport . reply ( ev . detail , < IWidgetApiRequestEmptyData > { } ) ;
330+ } ) ;
331+
301332 if ( WidgetType . JITSI . matches ( this . mockWidget . type ) ) {
302333 this . messaging . on ( "action:set_always_on_screen" ,
303334 ( ev : CustomEvent < IStickyActionRequest > ) => {
0 commit comments