diff --git a/back/src/Controller/DebugController.ts b/back/src/Controller/DebugController.ts index e9fc0743..f571d6b2 100644 --- a/back/src/Controller/DebugController.ts +++ b/back/src/Controller/DebugController.ts @@ -15,6 +15,9 @@ export class DebugController { (async () => { const query = parse(req.getQuery()); + if (ADMIN_API_TOKEN === "") { + return res.writeStatus("401 Unauthorized").end("No token configured!"); + } if (query.token !== ADMIN_API_TOKEN) { return res.writeStatus("401 Unauthorized").end("Invalid token sent!"); } diff --git a/back/src/Enum/EnvironmentVariable.ts b/back/src/Enum/EnvironmentVariable.ts index f7f0b084..f0f46a62 100644 --- a/back/src/Enum/EnvironmentVariable.ts +++ b/back/src/Enum/EnvironmentVariable.ts @@ -2,7 +2,7 @@ const MINIMUM_DISTANCE = process.env.MINIMUM_DISTANCE ? Number(process.env.MINIM const GROUP_RADIUS = process.env.GROUP_RADIUS ? Number(process.env.GROUP_RADIUS) : 48; const ALLOW_ARTILLERY = process.env.ALLOW_ARTILLERY ? process.env.ALLOW_ARTILLERY == "true" : false; const ADMIN_API_URL = process.env.ADMIN_API_URL || ""; -const ADMIN_API_TOKEN = process.env.ADMIN_API_TOKEN || "myapitoken"; +const ADMIN_API_TOKEN = process.env.ADMIN_API_TOKEN || ""; const CPU_OVERHEAT_THRESHOLD = Number(process.env.CPU_OVERHEAT_THRESHOLD) || 80; const JITSI_URL: string | undefined = process.env.JITSI_URL === "" ? undefined : process.env.JITSI_URL; const JITSI_ISS = process.env.JITSI_ISS || ""; diff --git a/back/yarn.lock b/back/yarn.lock index d22087d2..04c6929b 100644 --- a/back/yarn.lock +++ b/back/yarn.lock @@ -1504,9 +1504,9 @@ natural-compare@^1.4.0: integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= node-fetch@^2.6.5: - version "2.6.6" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.6.tgz#1751a7c01834e8e1697758732e9efb6eeadfaf89" - integrity sha512-Z8/6vRlTUChSdIgMa51jxQ4lrw/Jy5SOW10ObaA47/RElsAN2c5Pn8bTgFGWn/ibwzXTE8qwr1Yzx28vsecXEA== + version "2.6.7" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.7.tgz#24de9fba827e3b4ae44dc8b20256a379160052ad" + integrity sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ== dependencies: whatwg-url "^5.0.0" diff --git a/deeployer.libsonnet b/deeployer.libsonnet index 0bbda264..4012b186 100644 --- a/deeployer.libsonnet +++ b/deeployer.libsonnet @@ -83,7 +83,8 @@ "SECRET_JITSI_KEY": env.SECRET_JITSI_KEY, "TURN_SERVER": "turn:coturn.workadventu.re:443,turns:coturn.workadventu.re:443", "JITSI_PRIVATE_MODE": if env.SECRET_JITSI_KEY != '' then "true" else "false", - "START_ROOM_URL": "/_/global/maps-"+url+"/starter/map.json" + "START_ROOM_URL": "/_/global/maps-"+url+"/starter/map.json", + "ICON_URL": "//icon-"+url, } }, "uploader": { @@ -109,7 +110,15 @@ "redis": { "image": "redis:6", "ports": [6379] - } + }, + "iconserver": { + "image": "matthiasluedtke/iconserver:v3.13.0", + "host": { + "url": "icon-"+url, + "containerPort": 8080, + }, + "ports": [8080] + }, }, "config": { k8sextension(k8sConf):: @@ -210,6 +219,16 @@ } } }, + iconserver+: { + ingress+: { + spec+: { + tls+: [{ + hosts: ["icon-"+url], + secretName: "certificate-tls" + }] + } + } + }, } } } diff --git a/docs/maps/api-nav.md b/docs/maps/api-nav.md index 47ee416e..2743d1ad 100644 --- a/docs/maps/api-nav.md +++ b/docs/maps/api-nav.md @@ -52,17 +52,17 @@ WA.nav.goToRoom("/_/global/.json#start-layer-2") ### Opening/closing web page in Co-Websites ``` -WA.nav.openCoWebSite(url: string, allowApi: boolean = false, allowPolicy: string = "", position: number = 0): Promise +WA.nav.openCoWebSite(url: string, allowApi: boolean = false, allowPolicy: string = "", position: number, closable: boolean, lazy: boolean): Promise ``` -Opens the webpage at "url" in an iFrame (on the right side of the screen) or close that iFrame. `allowApi` allows the webpage to use the "IFrame API" and execute script (it is equivalent to putting the `openWebsiteAllowApi` property in the map). `allowPolicy` grants additional access rights to the iFrame. The `allowPolicy` parameter is turned into an [`allow` feature policy in the iFrame](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe#attr-allow), position in whitch slot the web page will be open. -You can have only 5 co-wbesites open simultaneously. +Opens the webpage at "url" in an iFrame (on the right side of the screen) or close that iFrame. `allowApi` allows the webpage to use the "IFrame API" and execute script (it is equivalent to putting the `openWebsiteAllowApi` property in the map). `allowPolicy` grants additional access rights to the iFrame. The `allowPolicy` parameter is turned into an [`allow` feature policy in the iFrame](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe#attr-allow), position in whitch slot the web page will be open, closable allow to close the webpage also you need to close it by the api and lazy +it's to add the cowebsite but don't load it. Example: ```javascript const coWebsite = await WA.nav.openCoWebSite('https://www.wikipedia.org/'); -const coWebsiteWorkAdventure = await WA.nav.openCoWebSite('https://workadventu.re/', true, "", 1); +const coWebsiteWorkAdventure = await WA.nav.openCoWebSite('https://workadventu.re/', true, "", 1, true, true); // ... coWebsite.close(); ``` diff --git a/docs/maps/entry-exit.md b/docs/maps/entry-exit.md index 6f98af93..2040beb3 100644 --- a/docs/maps/entry-exit.md +++ b/docs/maps/entry-exit.md @@ -65,3 +65,24 @@ How to use entry point : * To enter via this entry point, simply add a hash with the entry point name to the URL ("#[_entryPointName_]"). For instance: "`https://workadventu.re/_/global/mymap.com/path/map.json#my-entry-point`". * You can of course use the "#" notation in an exit scene URL (so an exit scene URL will point to a given entry scene URL) + +## Defining destination point with moveTo parameter + +We are able to direct a Woka to the desired place immediately after spawn. To make users spawn on an entry point and then, walk automatically to a meeting room, simply add `moveTo` as an additional parameter of URL: + +*Use default entry point* +``` +.../my_map.json#&moveTo=exit +``` +*Define entry point and moveTo parameter like this...* +``` +.../my_map.json#start&moveTo=meeting-room +``` +*...or like this* +``` +.../my_map.json#moveTo=meeting-room&start +``` + +For this to work, moveTo must be equal to the layer name of interest. This layer should have at least one tile defined. In case of layer having many tiles, user will go to one of them, randomly selected. + +![](images/moveTo-layer-example.png) \ No newline at end of file diff --git a/docs/maps/images/moveTo-layer-example.png b/docs/maps/images/moveTo-layer-example.png new file mode 100644 index 00000000..12e8a4ad Binary files /dev/null and b/docs/maps/images/moveTo-layer-example.png differ diff --git a/front/Dockerfile b/front/Dockerfile index 80d525a9..14914ebf 100644 --- a/front/Dockerfile +++ b/front/Dockerfile @@ -1,23 +1,35 @@ FROM node:14.18.2-buster-slim@sha256:20bedf0c09de887379e59a41c04284974f5fb529cf0e13aab613473ce298da3d as builder -WORKDIR /usr/src + +WORKDIR /usr/src/messages COPY messages . RUN yarn install && yarn ts-proto -# we are rebuilding on each deploy to cope with the PUSHER_URL environment URL -FROM thecodingmachine/nodejs:14-apache +WORKDIR /usr/src/front +COPY front . -COPY --chown=docker:docker front . -COPY --from=builder --chown=docker:docker /usr/src/ts-proto-generated/protos /var/www/html/src/Messages/ts-proto-generated -RUN sed -i 's/import { Observable } from "rxjs";/import type { Observable } from "rxjs";/g' /var/www/html/src/Messages/ts-proto-generated/messages.ts -COPY --from=builder --chown=docker:docker /usr/src/JsonMessages /var/www/html/src/Messages/JsonMessages +# move messages to front +RUN cp -r ../messages/ts-proto-generated/protos/* src/Messages/ts-proto-generated +RUN sed -i 's/import { Observable } from "rxjs";/import type { Observable } from "rxjs";/g' src/Messages/ts-proto-generated/messages.ts +RUN cp -r ../messages/JsonMessages/* src/Messages/JsonMessages + +RUN yarn install && yarn run typesafe-i18n && yarn build # Removing the iframe.html file from the final image as this adds a XSS attack. # iframe.html is only in dev mode to circumvent a limitation RUN rm dist/iframe.html -RUN yarn install +FROM thecodingmachine/nodejs:14-apache + +COPY --from=builder --chown=docker:docker /usr/src/front/dist dist +COPY front/templater.sh . + +USER root +RUN DEBIAN_FRONTEND=noninteractive apt-get update \ + && apt-get install -y \ + gettext-base \ + && rm -rf /var/lib/apt/lists/* +USER docker -ENV NODE_ENV=production ENV STARTUP_COMMAND_0="./templater.sh" -ENV STARTUP_COMMAND_1="yarn run build" +ENV STARTUP_COMMAND_1="envsubst < dist/env-config.template.js > dist/env-config.js" ENV APACHE_DOCUMENT_ROOT=dist/ diff --git a/front/dist/.gitignore b/front/dist/.gitignore index 785f2eb9..bc766e57 100644 --- a/front/dist/.gitignore +++ b/front/dist/.gitignore @@ -1,4 +1,6 @@ index.html -index.tmpl.html.tmp /js/ +/fonts/ style.*.css +!env-config.template.js +*.png diff --git a/front/dist/env-config.template.js b/front/dist/env-config.template.js new file mode 100644 index 00000000..e672d7aa --- /dev/null +++ b/front/dist/env-config.template.js @@ -0,0 +1,27 @@ +window.env = { + SKIP_RENDER_OPTIMIZATIONS: '${SKIP_RENDER_OPTIMIZATIONS}', + DISABLE_NOTIFICATIONS: '${DISABLE_NOTIFICATIONS}', + PUSHER_URL: '${PUSHER_URL}', + UPLOADER_URL: '${UPLOADER_URL}', + ADMIN_URL: '${ADMIN_URL}', + CONTACT_URL: '${CONTACT_URL}', + PROFILE_URL: '${PROFILE_URL}', + ICON_URL: '${ICON_URL}', + DEBUG_MODE: '${DEBUG_MODE}', + STUN_SERVER: '${STUN_SERVER}', + TURN_SERVER: '${TURN_SERVER}', + TURN_USER: '${TURN_USER}', + TURN_PASSWORD: '${TURN_PASSWORD}', + JITSI_URL: '${JITSI_URL}', + JITSI_PRIVATE_MODE: '${JITSI_PRIVATE_MODE}', + START_ROOM_URL: '${START_ROOM_URL}', + MAX_USERNAME_LENGTH: '${MAX_USERNAME_LENGTH}', + MAX_PER_GROUP: '${MAX_PER_GROUP}', + DISPLAY_TERMS_OF_USE: '${DISPLAY_TERMS_OF_USE}', + POSTHOG_API_KEY: '${POSTHOG_API_KEY}', + POSTHOG_URL: '${POSTHOG_URL}', + NODE_ENV: '${NODE_ENV}', + DISABLE_ANONYMOUS: '${DISABLE_ANONYMOUS}', + OPID_LOGIN_SCREEN_PROVIDER: '${OPID_LOGIN_SCREEN_PROVIDER}', + FALLBACK_LOCALE: '${FALLBACK_LOCALE}', +}; diff --git a/front/dist/index.ejs b/front/dist/index.ejs new file mode 100644 index 00000000..07732877 --- /dev/null +++ b/front/dist/index.ejs @@ -0,0 +1,68 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + WorkAdventure + + +
+ +
+
+
+
+ +
+ +
+
+
+
+ + diff --git a/front/dist/index.tmpl.html b/front/dist/index.tmpl.html deleted file mode 100644 index 3b43a5ef..00000000 --- a/front/dist/index.tmpl.html +++ /dev/null @@ -1,126 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - WorkAdventure - - -
- -
-
-
-
-
- - -
-
-
- -
-
-
-
- -
-
- - -
-
-
- -
-
-
- -
-
- - -
-
-
- -
-
-
- -
-
- - -
-
-
-
-
-
-
-
-
- - -
-
- -
-
- -
-
- - - - diff --git a/front/dist/resources/logos/cowebsite-swipe.svg b/front/dist/resources/logos/cowebsite-swipe.svg new file mode 100644 index 00000000..1d4f9ebc --- /dev/null +++ b/front/dist/resources/logos/cowebsite-swipe.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/front/package.json b/front/package.json index 564e1485..9a17f4a0 100644 --- a/front/package.json +++ b/front/package.json @@ -15,6 +15,7 @@ "@typescript-eslint/eslint-plugin": "^5.6.0", "@typescript-eslint/parser": "^5.6.0", "css-loader": "^5.2.4", + "css-minimizer-webpack-plugin": "^3.3.1", "eslint": "^8.4.1", "eslint-plugin-svelte3": "^3.2.1", "fork-ts-checker-webpack-plugin": "^6.5.0", diff --git a/front/src/Api/Events/OpenCoWebsiteEvent.ts b/front/src/Api/Events/OpenCoWebsiteEvent.ts index 514fd110..51a17763 100644 --- a/front/src/Api/Events/OpenCoWebsiteEvent.ts +++ b/front/src/Api/Events/OpenCoWebsiteEvent.ts @@ -6,13 +6,14 @@ export const isOpenCoWebsiteEvent = new tg.IsInterface() allowApi: tg.isOptional(tg.isBoolean), allowPolicy: tg.isOptional(tg.isString), position: tg.isOptional(tg.isNumber), + closable: tg.isOptional(tg.isBoolean), + lazy: tg.isOptional(tg.isBoolean), }) .get(); export const isCoWebsite = new tg.IsInterface() .withProperties({ id: tg.isString, - position: tg.isNumber, }) .get(); diff --git a/front/src/Api/IframeListener.ts b/front/src/Api/IframeListener.ts index 27486d5d..65ab1303 100644 --- a/front/src/Api/IframeListener.ts +++ b/front/src/Api/IframeListener.ts @@ -8,7 +8,6 @@ import type { ButtonClickedEvent } from "./Events/ButtonClickedEvent"; import { ClosePopupEvent, isClosePopupEvent } from "./Events/ClosePopupEvent"; import { scriptUtils } from "./ScriptUtils"; import { isGoToPageEvent } from "./Events/GoToPageEvent"; -import { isCloseCoWebsite, CloseCoWebsiteEvent } from "./Events/CloseCoWebsiteEvent"; import { IframeErrorAnswerEvent, IframeQueryMap, diff --git a/front/src/Api/ScriptUtils.ts b/front/src/Api/ScriptUtils.ts index 10a80c92..f0a0625a 100644 --- a/front/src/Api/ScriptUtils.ts +++ b/front/src/Api/ScriptUtils.ts @@ -1,4 +1,3 @@ -import { coWebsiteManager, CoWebsite } from "../WebRtc/CoWebsiteManager"; import { playersStore } from "../Stores/PlayersStore"; import { chatMessagesStore } from "../Stores/ChatStore"; import type { ChatEvent } from "./Events/ChatEvent"; diff --git a/front/src/Api/iframe/nav.ts b/front/src/Api/iframe/nav.ts index 206961bf..d5362b4b 100644 --- a/front/src/Api/iframe/nav.ts +++ b/front/src/Api/iframe/nav.ts @@ -1,7 +1,7 @@ import { IframeApiContribution, sendToWorkadventure, queryWorkadventure } from "./IframeApiContribution"; export class CoWebsite { - constructor(private readonly id: string, public readonly position: number) {} + constructor(private readonly id: string) {} close() { return queryWorkadventure({ @@ -41,7 +41,14 @@ export class WorkadventureNavigationCommands extends IframeApiContribution { + async openCoWebSite( + url: string, + allowApi?: boolean, + allowPolicy?: string, + position?: number, + closable?: boolean, + lazy?: boolean + ): Promise { const result = await queryWorkadventure({ type: "openCoWebsite", data: { @@ -49,9 +56,11 @@ export class WorkadventureNavigationCommands extends IframeApiContribution { @@ -59,7 +68,7 @@ export class WorkadventureNavigationCommands extends IframeApiContribution new CoWebsite(cowebsiteEvent.id, cowebsiteEvent.position)); + return result.map((cowebsiteEvent) => new CoWebsite(cowebsiteEvent.id)); } /** diff --git a/front/src/Components/App.svelte b/front/src/Components/App.svelte index 366c3d85..620884cf 100644 --- a/front/src/Components/App.svelte +++ b/front/src/Components/App.svelte @@ -1,171 +1,52 @@ -
- {#if $loginSceneVisibleStore} -
- -
- {/if} - {#if $selectCharacterSceneVisibleStore} -
- -
- {/if} - {#if $customCharacterSceneVisibleStore} -
- -
- {/if} - {#if $selectCompanionSceneVisibleStore} -
- -
- {/if} - {#if $enableCameraSceneVisibilityStore} -
- -
- {/if} - {#if $banMessageStore.length > 0} -
- -
- {:else if $textMessageStore.length > 0} -
- -
- {/if} - {#if $soundPlayingStore} -
- -
- {/if} - {#if $audioManagerVisibilityStore} -
- -
- {/if} - {#if $layoutManagerVisibilityStore} -
- -
- {/if} - {#if $showReportScreenStore !== userReportEmpty} -
- -
- {/if} - {#if $followStateStore !== "off" || $peerStore.size > 0} -
- -
- {/if} - {#if $menuIconVisiblilityStore} -
- -
- {/if} - {#if $menuVisiblilityStore} -
- -
- {/if} - {#if $emoteMenuStore} -
- -
- {/if} - {#if $gameOverlayVisibilityStore} -
- - - -
- {/if} - {#if $helpCameraSettingsVisibleStore} -
- -
- {/if} - {#if $showLimitRoomModalStore} -
- -
- {/if} - {#if $showShareLinkMapModalStore} -
- -
- {/if} - {#if $requestVisitCardsStore} - - {/if} - {#if $actionsMenuStore} - - {/if} - {#if $errorStore.length > 0} -
- -
- {/if} +{#if $errorStore.length > 0} +
+ +
+{:else if $loginSceneVisibleStore} +
+ +
+{:else if $selectCharacterSceneVisibleStore} +
+ +
+{:else if $customCharacterSceneVisibleStore} +
+ +
+{:else if $selectCompanionSceneVisibleStore} +
+ +
+{:else if $enableCameraSceneVisibilityStore} +
+ +
+{:else} + + {#if $chatVisibilityStore} {/if} - {#if $warningContainerStore} - - {/if} -
+{/if} diff --git a/front/src/Components/AudioManager/AudioManager.svelte b/front/src/Components/AudioManager/AudioManager.svelte index 3385d6da..eec51572 100644 --- a/front/src/Components/AudioManager/AudioManager.svelte +++ b/front/src/Components/AudioManager/AudioManager.svelte @@ -157,13 +157,16 @@ diff --git a/front/src/Components/Chat/Chat.svelte b/front/src/Components/Chat/Chat.svelte index c4756a36..cd9b90b5 100644 --- a/front/src/Components/Chat/Chat.svelte +++ b/front/src/Components/Chat/Chat.svelte @@ -43,7 +43,7 @@