Adding a "allowApi" property to authorize the API in a website.

This commit is contained in:
David Négrier 2021-07-23 23:06:59 +02:00
parent ce3c53ae3f
commit 5bb29e99ba
3 changed files with 46 additions and 0 deletions

View File

@ -22,3 +22,19 @@ The `url` can be absolute, or relative to your map.
Internally, WorkAdventure will create an "iFrame" to load the website. Internally, WorkAdventure will create an "iFrame" to load the website.
Some websites forbid being opened by iframes using the [`X-Frame-Options](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options) Some websites forbid being opened by iframes using the [`X-Frame-Options](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options)
HTTP header. HTTP header.
{.alert.alert-warning}
Please note that the website always appears **on top** of the tiles (even if you put the object layer that
contains the "website" object under the tiles).
## Allowing the scripting API in your iframe
If you are planning to use the WorkAdventure scripting API inside your iframe, you need
to explicitly allow it, by setting an additional `allowApi` property to `true`.
<div>
<figure class="figure">
<img src="https://workadventu.re/img/docs/website_allowapi_property.png" class="figure-img img-fluid rounded" alt="" style="width: 70%" />
<figcaption class="figure-caption">A "website" object that can communicate using the Iframe API</figcaption>
</figure>
</div>

View File

@ -200,6 +200,7 @@ export class GameScene extends DirtyScene {
private startPositionCalculator!: StartPositionCalculator; private startPositionCalculator!: StartPositionCalculator;
private sharedVariablesManager!: SharedVariablesManager; private sharedVariablesManager!: SharedVariablesManager;
private objectsByType = new Map<string, ITiledMapObject[]>(); private objectsByType = new Map<string, ITiledMapObject[]>();
private inMapIframes = new Array<HTMLIFrameElement>();
constructor(private room: Room, MapUrlFile: string, customKey?: string | undefined) { constructor(private room: Room, MapUrlFile: string, customKey?: string | undefined) {
super({ super({
@ -497,6 +498,15 @@ export class GameScene extends DirtyScene {
iframe.style.border = "none"; iframe.style.border = "none";
this.add.dom(object.x, object.y).setElement(iframe).setOrigin(0, 0); this.add.dom(object.x, object.y).setElement(iframe).setOrigin(0, 0);
const allowApi = PropertyUtils.findBooleanProperty(
"allowApi",
object.properties,
);
if (allowApi) {
iframeListener.registerIframe(iframe);
this.inMapIframes.push(iframe);
}
} }
} }
} }
@ -1293,6 +1303,9 @@ ${escapedMessage}
for (const script of scripts) { for (const script of scripts) {
iframeListener.unregisterScript(script); iframeListener.unregisterScript(script);
} }
for (const iframe of this.inMapIframes) {
iframeListener.unregisterIframe(iframe);
}
this.stopJitsi(); this.stopJitsi();
audioManager.unloadAudio(); audioManager.unloadAudio();

View File

@ -8,6 +8,23 @@ export class PropertyUtils {
return properties?.find((property) => property.name === name)?.value; return properties?.find((property) => property.name === name)?.value;
} }
public static findBooleanProperty(
name: string,
properties: ITiledMapProperty[] | undefined,
context?: string
): boolean | undefined {
const property = PropertyUtils.findProperty(name, properties);
if (property === undefined) {
return undefined;
}
if (typeof property !== "boolean") {
throw new Error(
'Expected property "' + name + '" to be a boolean. ' + (context ? " (" + context + ")" : "")
);
}
return property;
}
public static mustFindProperty( public static mustFindProperty(
name: string, name: string,
properties: ITiledMapProperty[] | undefined, properties: ITiledMapProperty[] | undefined,