From d1178b1a01dd137ca303573814ca3c97bd2a056b Mon Sep 17 00:00:00 2001 From: jonny Date: Wed, 23 Jun 2021 20:19:38 +0200 Subject: [PATCH 1/5] immutableData was never assigned --- front/src/Api/iframe/room.ts | 99 ++++++++++++++++++------------------ 1 file changed, 49 insertions(+), 50 deletions(-) diff --git a/front/src/Api/iframe/room.ts b/front/src/Api/iframe/room.ts index aed4d983..817141f4 100644 --- a/front/src/Api/iframe/room.ts +++ b/front/src/Api/iframe/room.ts @@ -1,53 +1,51 @@ import { Subject } from "rxjs"; -import { EnterLeaveEvent, isEnterLeaveEvent } from '../Events/EnterLeaveEvent'; -import {IframeApiContribution, sendToWorkadventure} from './IframeApiContribution'; + +import { isDataLayerEvent } from "../Events/DataLayerEvent"; +import { EnterLeaveEvent, isEnterLeaveEvent } from "../Events/EnterLeaveEvent"; +import { isGameStateEvent } from "../Events/GameStateEvent"; + +import { IframeApiContribution, sendToWorkadventure } from "./IframeApiContribution"; import { apiCallback } from "./registeredCallbacks"; -import type {LayerEvent} from "../Events/LayerEvent"; -import type {SetPropertyEvent} from "../Events/setPropertyEvent"; -import type {GameStateEvent} from "../Events/GameStateEvent"; -import type {ITiledMap} from "../../Phaser/Map/ITiledMap"; -import type {DataLayerEvent} from "../Events/DataLayerEvent"; -import {isGameStateEvent} from "../Events/GameStateEvent"; -import {isDataLayerEvent} from "../Events/DataLayerEvent"; + +import type { ITiledMap } from "../../Phaser/Map/ITiledMap"; +import type { DataLayerEvent } from "../Events/DataLayerEvent"; +import type { GameStateEvent } from "../Events/GameStateEvent"; const enterStreams: Map> = new Map>(); const leaveStreams: Map> = new Map>(); const dataLayerResolver = new Subject(); const stateResolvers = new Subject(); -let immutableData: GameStateEvent; +let immutableDataPromise: Promise | undefined = undefined; interface Room { - id: string, - mapUrl: string, - map: ITiledMap, - startLayer: string | null + id: string; + mapUrl: string; + map: ITiledMap; + startLayer: string | null; } interface User { - id: string | undefined, - nickName: string | null, - tags: string[] + id: string | undefined; + nickName: string | null; + tags: string[]; } - function getGameState(): Promise { - if (immutableData) { - return Promise.resolve(immutableData); - } - else { - return new Promise((resolver, thrower) => { + if (immutableDataPromise === undefined) { + immutableDataPromise = new Promise((resolver, thrower) => { stateResolvers.subscribe(resolver); - sendToWorkadventure({type: "getState", data: null}); - }) + sendToWorkadventure({ type: "getState", data: null }); + }); } + return immutableDataPromise; } function getDataLayer(): Promise { return new Promise((resolver, thrower) => { dataLayerResolver.subscribe(resolver); - sendToWorkadventure({type: "getDataLayer", data: null}) - }) + sendToWorkadventure({ type: "getDataLayer", data: null }); + }); } class WorkadventureRoomCommands extends IframeApiContribution { @@ -57,31 +55,30 @@ class WorkadventureRoomCommands extends IframeApiContribution { leaveStreams.get(payloadData.name)?.next(); - } + }, }), apiCallback({ type: "gameState", typeChecker: isGameStateEvent, callback: (payloadData) => { stateResolvers.next(payloadData); - } + }, }), apiCallback({ type: "dataLayer", typeChecker: isDataLayerEvent, callback: (payloadData) => { dataLayerResolver.next(payloadData); - } + }, }), - ] - + ]; onEnterZone(name: string, callback: () => void): void { let subject = enterStreams.get(name); @@ -90,7 +87,6 @@ class WorkadventureRoomCommands extends IframeApiContribution void): void { let subject = leaveStreams.get(name); @@ -101,35 +97,38 @@ class WorkadventureRoomCommands extends IframeApiContribution { return getGameState().then((gameState) => { - return getDataLayer().then((mapJson) => { - return {id: gameState.roomId, map: mapJson.data as ITiledMap, mapUrl: gameState.mapUrl, startLayer: gameState.startLayerName}; - }) - }) + return getDataLayer().then((mapJson) => { + return { + id: gameState.roomId, + map: mapJson.data as ITiledMap, + mapUrl: gameState.mapUrl, + startLayer: gameState.startLayerName, + }; + }); + }); } getCurrentUser(): Promise { return getGameState().then((gameState) => { - return {id: gameState.uuid, nickName: gameState.nickname, tags: gameState.tags}; - }) + return { id: gameState.uuid, nickName: gameState.nickname, tags: gameState.tags }; + }); } - } - export default new WorkadventureRoomCommands(); From 330a795fee9e88a4d9d41b1123daf8080f6e9994 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20N=C3=A9grier?= Date: Mon, 28 Jun 2021 11:51:13 +0200 Subject: [PATCH 2/5] Trying to find iframe_api.js URL script dynamically This would allow us to have tests that don't rely on the iframe_api.js from prod, and would allow scripts that target the correct iframe API, no matter if they are running on workadventu.re or on self-hosted maps. --- maps/tests/iframe.html | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/maps/tests/iframe.html b/maps/tests/iframe.html index aa8e55ec..f3d48a77 100644 --- a/maps/tests/iframe.html +++ b/maps/tests/iframe.html @@ -1,22 +1,31 @@ - + +
From 7f79c2dc4a6008bd3fb7fe3b02bb69ad42615557 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20N=C3=A9grier?= Date: Mon, 28 Jun 2021 13:54:49 +0200 Subject: [PATCH 3/5] Making the test page URL dynamic depending on the environment --- .github/workflows/build-and-deploy.yml | 2 +- maps/tests/index.html | 17 ++++++++++++++++- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-and-deploy.yml b/.github/workflows/build-and-deploy.yml index 3bf00b99..e33346d0 100644 --- a/.github/workflows/build-and-deploy.yml +++ b/.github/workflows/build-and-deploy.yml @@ -199,4 +199,4 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: - msg: Environment deployed at https://play-${{ env.GITHUB_HEAD_REF_SLUG }}.test.workadventu.re + msg: "Environment deployed at https://play-${{ env.GITHUB_HEAD_REF_SLUG }}.test.workadventu.re \nTests available at https://maps-${{ env.GITHUB_HEAD_REF_SLUG }}.test.workadventu.re/tests" diff --git a/maps/tests/index.html b/maps/tests/index.html index 0929ab83..1f5f2a0e 100644 --- a/maps/tests/index.html +++ b/maps/tests/index.html @@ -4,7 +4,7 @@ - + @@ -166,6 +166,21 @@ From 3fd4f9d38423026ef9e651023e8cd0e5b4d7e782 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20N=C3=A9grier?= Date: Mon, 28 Jun 2021 15:20:27 +0200 Subject: [PATCH 5/5] Adding a warning message if an unauthorized iFrame tries to communicate with WA Closes #1241 --- front/src/Api/IframeListener.ts | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/front/src/Api/IframeListener.ts b/front/src/Api/IframeListener.ts index 9311d7b6..0adaac85 100644 --- a/front/src/Api/IframeListener.ts +++ b/front/src/Api/IframeListener.ts @@ -123,11 +123,18 @@ class IframeListener { } } + const payload = message.data; + if (foundSrc === undefined) { + if (isIframeEventWrapper(payload)) { + console.warn('It seems an iFrame is trying to communicate with WorkAdventure but was not explicitly granted the permission to do so. ' + + 'If you are looking to use the WorkAdventure Scripting API inside an iFrame, you should allow the ' + + 'iFrame to communicate with WorkAdventure by using the "openWebsiteAllowApi" property in your map (or passing "true" as a second' + + 'parameter to WA.nav.openCoWebSite())'); + } return; } - const payload = message.data; if (isIframeEventWrapper(payload)) { if (payload.type === 'showLayer' && isLayerEvent(payload.data)) { this._showLayerStream.next(payload.data);
Result