From cdf4023928d3ed6e8ddfdd38b3dfcd0f7a06a12f Mon Sep 17 00:00:00 2001 From: Alexis Faizeau Date: Thu, 14 Oct 2021 17:32:27 +0200 Subject: [PATCH 01/58] Change character depth to 0 --- front/src/Phaser/Entity/Character.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/front/src/Phaser/Entity/Character.ts b/front/src/Phaser/Entity/Character.ts index 3cdc60dc..17bb6a27 100644 --- a/front/src/Phaser/Entity/Character.ts +++ b/front/src/Phaser/Entity/Character.ts @@ -107,7 +107,7 @@ export abstract class Character extends Container { this.setSize(16, 16); this.getBody().setSize(16, 16); //edit the hitbox to better match the character model this.getBody().setOffset(0, 8); - this.setDepth(-1); + this.setDepth(0); this.playAnimation(direction, moving); From 79a5916057a3886fffd64b7a821160804c6703b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20N=C3=A9grier?= Date: Fri, 15 Oct 2021 15:08:06 +0200 Subject: [PATCH 02/58] Removing dead code --- front/src/Phaser/Game/GameScene.ts | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/front/src/Phaser/Game/GameScene.ts b/front/src/Phaser/Game/GameScene.ts index 057f9fb1..7f4d97a7 100644 --- a/front/src/Phaser/Game/GameScene.ts +++ b/front/src/Phaser/Game/GameScene.ts @@ -1186,26 +1186,6 @@ ${escapedMessage} layoutManagerActionStore.removeAction(message.uuid); }); - this.iframeSubscriptionList.push( - iframeListener.modifyEmbeddedWebsiteStream.subscribe((embeddedWebsite) => { - // TODO - // TODO - // TODO - // TODO - // TODO - // TODO - // TODO - // TODO - // TODO - // TODO - // TODO - // TODO - // TODO - // TODO - // TODO - // TODO - }) - ); } private setPropertyLayer( From 8b76e5bc363b99a056fd44f5ffa280df5bff6d72 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20N=C3=A9grier?= Date: Fri, 15 Oct 2021 15:24:34 +0200 Subject: [PATCH 03/58] Adding test case for exits --- maps/tests/exit1.json | 167 ++++++++++++++++++++++++++++++++++++++++++ maps/tests/exit2.json | 149 +++++++++++++++++++++++++++++++++++++ maps/tests/index.html | 8 ++ 3 files changed, 324 insertions(+) create mode 100644 maps/tests/exit1.json create mode 100644 maps/tests/exit2.json diff --git a/maps/tests/exit1.json b/maps/tests/exit1.json new file mode 100644 index 00000000..c0d82c41 --- /dev/null +++ b/maps/tests/exit1.json @@ -0,0 +1,167 @@ +{ "compressionlevel":-1, + "height":10, + "infinite":false, + "layers":[ + { + "data":[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + "height":10, + "id":1, + "name":"floor", + "opacity":1, + "type":"tilelayer", + "visible":true, + "width":10, + "x":0, + "y":0 + }, + { + "data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "height":10, + "id":2, + "name":"start", + "opacity":1, + "type":"tilelayer", + "visible":true, + "width":10, + "x":0, + "y":0 + }, + { + "data":[17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 34, 17, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17], + "height":10, + "id":7, + "name":"walls", + "opacity":1, + "type":"tilelayer", + "visible":true, + "width":10, + "x":0, + "y":0 + }, + { + "data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "height":10, + "id":8, + "name":"exit", + "opacity":1, + "properties":[ + { + "name":"exitUrl", + "type":"string", + "value":"exit2.json" + }], + "type":"tilelayer", + "visible":true, + "width":10, + "x":0, + "y":0 + }, + { + "data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "height":10, + "id":9, + "name":"from_exit2", + "opacity":1, + "properties":[ + { + "name":"startLayer", + "type":"bool", + "value":true + }], + "type":"tilelayer", + "visible":true, + "width":10, + "x":0, + "y":0 + }, + { + "draworder":"topdown", + "id":3, + "name":"floorLayer", + "objects":[ + { + "height":263.008397229317, + "id":1, + "name":"", + "rotation":0, + "text": + { + "fontfamily":"Sans Serif", + "pixelsize":13, + "text":"You are on Map 1\n\nTest:\nWalk through the exit.\n\nResult:\nYou should arrive to Map 2\n", + "wrap":true + }, + "type":"", + "visible":true, + "width":249.954975648686, + "x":35.2740564642832, + "y":34.4372323693377 + }], + "opacity":1, + "type":"objectgroup", + "visible":true, + "x":0, + "y":0 + }], + "nextlayerid":10, + "nextobjectid":2, + "orientation":"orthogonal", + "renderorder":"right-down", + "tiledversion":"2021.03.23", + "tileheight":32, + "tilesets":[ + { + "columns":11, + "firstgid":1, + "image":"tileset1.png", + "imageheight":352, + "imagewidth":352, + "margin":0, + "name":"tileset1", + "spacing":0, + "tilecount":121, + "tileheight":32, + "tiles":[ + { + "id":16, + "properties":[ + { + "name":"collides", + "type":"bool", + "value":true + }] + }, + { + "id":17, + "properties":[ + { + "name":"collides", + "type":"bool", + "value":true + }] + }, + { + "id":18, + "properties":[ + { + "name":"collides", + "type":"bool", + "value":true + }] + }, + { + "id":19, + "properties":[ + { + "name":"collides", + "type":"bool", + "value":true + }] + }], + "tilewidth":32 + }], + "tilewidth":32, + "type":"map", + "version":1.5, + "width":10 +} \ No newline at end of file diff --git a/maps/tests/exit2.json b/maps/tests/exit2.json new file mode 100644 index 00000000..181e80d5 --- /dev/null +++ b/maps/tests/exit2.json @@ -0,0 +1,149 @@ +{ "compressionlevel":-1, + "height":10, + "infinite":false, + "layers":[ + { + "data":[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + "height":10, + "id":1, + "name":"floor", + "opacity":1, + "type":"tilelayer", + "visible":true, + "width":10, + "x":0, + "y":0 + }, + { + "data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "height":10, + "id":2, + "name":"start", + "opacity":1, + "type":"tilelayer", + "visible":true, + "width":10, + "x":0, + "y":0 + }, + { + "data":[17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17], + "height":10, + "id":7, + "name":"walls", + "opacity":1, + "type":"tilelayer", + "visible":true, + "width":10, + "x":0, + "y":0 + }, + { + "data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "height":10, + "id":8, + "name":"exit", + "opacity":1, + "properties":[ + { + "name":"exitUrl", + "type":"string", + "value":"exit1.json#from_exit2" + }], + "type":"tilelayer", + "visible":true, + "width":10, + "x":0, + "y":0 + }, + { + "draworder":"topdown", + "id":3, + "name":"floorLayer", + "objects":[ + { + "height":263.008397229317, + "id":1, + "name":"", + "rotation":0, + "text": + { + "fontfamily":"Sans Serif", + "pixelsize":13, + "text":"You are on Map 2\n\nTest:\nWalk back through the exit.\n\nResult:\nYou should arrive back to Map 1\n", + "wrap":true + }, + "type":"", + "visible":true, + "width":249.954975648686, + "x":35.2740564642832, + "y":34.4372323693377 + }], + "opacity":1, + "type":"objectgroup", + "visible":true, + "x":0, + "y":0 + }], + "nextlayerid":9, + "nextobjectid":2, + "orientation":"orthogonal", + "renderorder":"right-down", + "tiledversion":"2021.03.23", + "tileheight":32, + "tilesets":[ + { + "columns":11, + "firstgid":1, + "image":"tileset1.png", + "imageheight":352, + "imagewidth":352, + "margin":0, + "name":"tileset1", + "spacing":0, + "tilecount":121, + "tileheight":32, + "tiles":[ + { + "id":16, + "properties":[ + { + "name":"collides", + "type":"bool", + "value":true + }] + }, + { + "id":17, + "properties":[ + { + "name":"collides", + "type":"bool", + "value":true + }] + }, + { + "id":18, + "properties":[ + { + "name":"collides", + "type":"bool", + "value":true + }] + }, + { + "id":19, + "properties":[ + { + "name":"collides", + "type":"bool", + "value":true + }] + }], + "tilewidth":32 + }], + "tilewidth":32, + "type":"map", + "version":1.5, + "width":10 +} \ No newline at end of file diff --git a/maps/tests/index.html b/maps/tests/index.html index 149e2868..c30b54a5 100644 --- a/maps/tests/index.html +++ b/maps/tests/index.html @@ -55,6 +55,14 @@ Test start tile (S2) + + + Success Failure Pending + + + Test exits + + Success Failure Pending From a8d6024352b22c17f5c0c1e28c0128222346028b Mon Sep 17 00:00:00 2001 From: Gregoire Parant Date: Fri, 15 Oct 2021 15:25:23 +0200 Subject: [PATCH 04/58] Fix share link for website Signed-off-by: Gregoire Parant --- front/src/Components/Menu/AboutRoomSubMenu.svelte | 2 ++ 1 file changed, 2 insertions(+) diff --git a/front/src/Components/Menu/AboutRoomSubMenu.svelte b/front/src/Components/Menu/AboutRoomSubMenu.svelte index 3ccc9669..16b5c057 100644 --- a/front/src/Components/Menu/AboutRoomSubMenu.svelte +++ b/front/src/Components/Menu/AboutRoomSubMenu.svelte @@ -51,6 +51,7 @@ await navigator.share(shareData); } catch (err) { console.error('Error: ' + err); + copyLink(); } } @@ -63,6 +64,7 @@

Share the link of the room !

+

Information on the map

From 70d5c7f658f5d4d900f2cc4cb7ee1167086c8a85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20N=C3=A9grier?= Date: Fri, 15 Oct 2021 16:14:17 +0200 Subject: [PATCH 05/58] Triggering onload even if file already loaded for files loaded via http:// --- front/src/Phaser/Game/GameScene.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/front/src/Phaser/Game/GameScene.ts b/front/src/Phaser/Game/GameScene.ts index 7f4d97a7..f91c339b 100644 --- a/front/src/Phaser/Game/GameScene.ts +++ b/front/src/Phaser/Game/GameScene.ts @@ -290,6 +290,12 @@ export class GameScene extends DirtyScene { this.onMapLoad(data); } ); + // If the map has already been loaded as part of another GameScene, the "on load" event will not be triggered. + // In this case, we check in the cache to see if the map is here and trigger the event manually. + if (this.cache.tilemap.exists(this.MapUrlFile)) { + const data = this.cache.tilemap.get(this.MapUrlFile); + this.onMapLoad(data); + } return; } @@ -1185,7 +1191,6 @@ ${escapedMessage} iframeListener.registerAnswerer("removeActionMessage", (message) => { layoutManagerActionStore.removeAction(message.uuid); }); - } private setPropertyLayer( From c13839ce8d5c338a55de1ccc8c2ce453e54da743 Mon Sep 17 00:00:00 2001 From: Alexis Faizeau Date: Fri, 15 Oct 2021 16:14:48 +0200 Subject: [PATCH 06/58] Display the real sprite direction on character loaded --- front/src/Phaser/Entity/Character.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/front/src/Phaser/Entity/Character.ts b/front/src/Phaser/Entity/Character.ts index 3cdc60dc..fa09ccf2 100644 --- a/front/src/Phaser/Entity/Character.ts +++ b/front/src/Phaser/Entity/Character.ts @@ -62,11 +62,13 @@ export abstract class Character extends Container { .then((textures) => { this.addTextures(textures, frame); this.invisible = false; + this.playAnimation(direction, moving); }) .catch(() => { return lazyLoadPlayerCharacterTextures(scene.load, ["color_22", "eyes_23"]).then((textures) => { this.addTextures(textures, frame); this.invisible = false; + this.playAnimation(direction, moving); }); }); @@ -109,8 +111,6 @@ export abstract class Character extends Container { this.getBody().setOffset(0, 8); this.setDepth(-1); - this.playAnimation(direction, moving); - if (typeof companion === "string") { this.addCompanion(companion, companionTexturePromise); } From b201165b8172edfdd4c6fdf859086e181aabc378 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20N=C3=A9grier?= Date: Mon, 18 Oct 2021 14:11:24 +0200 Subject: [PATCH 07/58] Upgrading @workadventure/tiled-map-type-guard to 1.0.3 This will fix the issue with maps containing group layers. --- back/package.json | 2 +- back/yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/back/package.json b/back/package.json index 76039479..aacd0c96 100644 --- a/back/package.json +++ b/back/package.json @@ -40,7 +40,7 @@ }, "homepage": "https://github.com/thecodingmachine/workadventure#readme", "dependencies": { - "@workadventure/tiled-map-type-guard": "^1.0.2", + "@workadventure/tiled-map-type-guard": "^1.0.3", "axios": "^0.21.2", "busboy": "^0.3.1", "circular-json": "^0.5.9", diff --git a/back/yarn.lock b/back/yarn.lock index 74218f8f..ff9cb180 100644 --- a/back/yarn.lock +++ b/back/yarn.lock @@ -194,10 +194,10 @@ semver "^7.3.2" tsutils "^3.17.1" -"@workadventure/tiled-map-type-guard@^1.0.2": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@workadventure/tiled-map-type-guard/-/tiled-map-type-guard-1.0.2.tgz#4171550f6cd71be19791faef48360d65d698bcb0" - integrity sha512-RCtygGV5y9cb7QoyGMINBE9arM5pyXjkxvXgA5uXEv4GDbXKorhFim/rHgwbVR+eFnVF3rDgWbRnk3DIaHt+lQ== +"@workadventure/tiled-map-type-guard@^1.0.3": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@workadventure/tiled-map-type-guard/-/tiled-map-type-guard-1.0.3.tgz#62c2061cacbe1360b84162af0b7e4639ed8bfa7e" + integrity sha512-pUMxBBZHYAFkpnGWZAVAE8+M+Wn9UtzqZhXvBBBbB1gEakHIka7ahdTGfh0DgRaWrVszVXOP3tf49Dhdmn9pDg== dependencies: generic-type-guard "^3.4.1" From f8b506144dffaa2ef103632efdee795cf1ff286d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20N=C3=A9grier?= Date: Mon, 18 Oct 2021 14:34:47 +0200 Subject: [PATCH 08/58] When there are many virtual users (generated by chat), only the name of a first user is displayed. Adding a test case for this. --- maps/tests/script.js | 1 + maps/tests/script_api.json | 18 +++++++++--------- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/maps/tests/script.js b/maps/tests/script.js index 52b201d6..f92deb84 100644 --- a/maps/tests/script.js +++ b/maps/tests/script.js @@ -40,6 +40,7 @@ WA.chat.onChatMessage((message => { WA.room.onEnterZone('myTrigger', () => { WA.chat.sendChatMessage("Don't step on my carpet!", 'Poly Parrot'); + WA.chat.sendChatMessage("Yeah, don't step on her carpet!", 'Peter Parrot'); }) WA.room.onLeaveZone('popupZone', () => { diff --git a/maps/tests/script_api.json b/maps/tests/script_api.json index 73ef9d01..8e5534e9 100644 --- a/maps/tests/script_api.json +++ b/maps/tests/script_api.json @@ -13,7 +13,7 @@ "width":10, "x":0, "y":0 - }, + }, { "data":[0, 0, 0, 0, 0, 0, 0, 0, 23, 23, 0, 0, 0, 0, 0, 0, 0, 0, 23, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], "height":10, @@ -31,7 +31,7 @@ "width":10, "x":0, "y":0 - }, + }, { "data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 23, 0, 0, 0, 0, 0, 0, 0, 0, 23, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], "height":10, @@ -49,7 +49,7 @@ "width":10, "x":0, "y":0 - }, + }, { "data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], "height":10, @@ -61,7 +61,7 @@ "width":10, "x":0, "y":0 - }, + }, { "draworder":"topdown", "id":3, @@ -77,7 +77,7 @@ "width":104.442827410047, "x":142.817125079855, "y":147.448134926559 - }, + }, { "height":132.434722966794, "id":2, @@ -88,7 +88,7 @@ "width":125.735549178518, "x":13.649632619596, "y":50.8502491249093 - }, + }, { "height":67, "id":3, @@ -98,7 +98,7 @@ { "fontfamily":"Sans Serif", "pixelsize":11, - "text":"Test:\nWalk on top carpet\nResult:\nA message \"Don't step on my carpet\" is displayed", + "text":"Test:\nWalk on top carpet\nResult:\nA message \"Don't step on my carpet\" is displayed from Poly Parrot and another message from Peter Parrot", "wrap":true }, "type":"", @@ -106,7 +106,7 @@ "width":252.4375, "x":2.78125, "y":2.5 - }, + }, { "height":67, "id":4, @@ -161,4 +161,4 @@ "type":"map", "version":1.5, "width":10 -} \ No newline at end of file +} From 4a40c0857881aa85c30d958e3258417bbabcae99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20N=C3=A9grier?= Date: Mon, 18 Oct 2021 14:58:29 +0200 Subject: [PATCH 09/58] Fixing chat message attributed to wrong user When a new user entered a chat message, the message was still attributed to the last user who wrote. --- CHANGELOG.md | 1 + front/src/Stores/ChatStore.ts | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 18f26012..ef120a3f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ - Moving a discussion over a user will now add this user to the discussion - Being in a silent zone new forces mediaConstraints to false (#1508) - Fixes for the emote menu (#1501) +- Fixing chat message attributed to wrong user (#1507 #1528) ## Version 1.5.0 ### Updates diff --git a/front/src/Stores/ChatStore.ts b/front/src/Stores/ChatStore.ts index feb1f3ec..1bb763cf 100644 --- a/front/src/Stores/ChatStore.ts +++ b/front/src/Stores/ChatStore.ts @@ -84,7 +84,7 @@ function createChatMessagesStore() { addExternalMessage(authorId: number, text: string) { update((list) => { const lastMessage = list[list.length - 1]; - if (lastMessage && lastMessage.type === ChatMessageTypes.text && lastMessage.text) { + if (lastMessage && lastMessage.type === ChatMessageTypes.text && lastMessage.text && lastMessage?.author?.userId === authorId) { lastMessage.text.push(text); } else { list.push({ From ee432341daee44af5c38941baa4d111ee60c53e3 Mon Sep 17 00:00:00 2001 From: Mathieu Reynaud Date: Tue, 19 Oct 2021 20:07:23 +0200 Subject: [PATCH 10/58] Change pusher host from testing to localhost --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index dd109ada..427c514c 100644 --- a/README.md +++ b/README.md @@ -38,7 +38,7 @@ Note: on some OSes, you will need to add this line to your `/etc/hosts` file: ``` Note: If on the first run you get a page with "network error". Try to ``docker-compose stop`` , then ``docker-compose start``. -Note 2: If you are still getting "network error". Make sure you are authorizing the self-signed certificate by entering https://pusher.workadventure.testing and accepting them. +Note 2: If you are still getting "network error". Make sure you are authorizing the self-signed certificate by entering https://pusher.workadventure.localhost and accepting them. ### MacOS developers, your environment with Vagrant From 6832fe49901ce28b3413000337a142cc9dae445c Mon Sep 17 00:00:00 2001 From: Lurkars Date: Thu, 21 Oct 2021 16:28:57 +0200 Subject: [PATCH 11/58] use OIDC without admin api, option to disable anonymous login --- .env.template | 1 + docker-compose.single-domain.yaml | 1 + docker-compose.yaml | 1 + front/src/Connexion/ConnectionManager.ts | 34 ++++++++++++++----- .../src/Controller/AuthenticateController.ts | 26 ++++++++------ pusher/src/Controller/IoSocketController.ts | 7 +++- pusher/src/Controller/MapController.ts | 9 +++-- pusher/src/Enum/EnvironmentVariable.ts | 1 + .../src/Services/AdminApi/MapDetailsData.ts | 1 + 9 files changed, 59 insertions(+), 22 deletions(-) diff --git a/.env.template b/.env.template index 715ebeec..f511b398 100644 --- a/.env.template +++ b/.env.template @@ -22,6 +22,7 @@ MAX_USERNAME_LENGTH=8 OPID_CLIENT_ID= OPID_CLIENT_SECRET= OPID_CLIENT_ISSUER= +DISABLE_ANONYMOUS= # If you want to have a contact page in your menu, you MUST set CONTACT_URL to the URL of the page that you want CONTACT_URL= \ No newline at end of file diff --git a/docker-compose.single-domain.yaml b/docker-compose.single-domain.yaml index 4e85d702..2e2cab7d 100644 --- a/docker-compose.single-domain.yaml +++ b/docker-compose.single-domain.yaml @@ -70,6 +70,7 @@ services: OPID_CLIENT_ID: $OPID_CLIENT_ID OPID_CLIENT_SECRET: $OPID_CLIENT_SECRET OPID_CLIENT_ISSUER: $OPID_CLIENT_ISSUER + DISABLE_ANONYMOUS: $DISABLE_ANONYMOUS volumes: - ./pusher:/usr/src/app labels: diff --git a/docker-compose.yaml b/docker-compose.yaml index 4b3904dd..65dcc61f 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -70,6 +70,7 @@ services: OPID_CLIENT_ID: $OPID_CLIENT_ID OPID_CLIENT_SECRET: $OPID_CLIENT_SECRET OPID_CLIENT_ISSUER: $OPID_CLIENT_ISSUER + DISABLE_ANONYMOUS: $DISABLE_ANONYMOUS volumes: - ./pusher:/usr/src/app labels: diff --git a/front/src/Connexion/ConnectionManager.ts b/front/src/Connexion/ConnectionManager.ts index b346f450..c91e4590 100644 --- a/front/src/Connexion/ConnectionManager.ts +++ b/front/src/Connexion/ConnectionManager.ts @@ -42,11 +42,22 @@ class ConnectionManager { localUserStore.setAuthToken(null); //TODO fix me to redirect this URL by pusher - if (!this._currentRoom || !this._currentRoom.iframeAuthentication) { + if (!this._currentRoom) { loginSceneVisibleIframeStore.set(false); return null; } - const redirectUrl = new URL(`${this._currentRoom.iframeAuthentication}`); + + // also allow OIDC login without admin API by using pusher + let redirectUrl: URL; + if (this._currentRoom.iframeAuthentication) { + redirectUrl = new URL(`${this._currentRoom.iframeAuthentication}`); + } else { + // need origin if PUSHER_URL is relative (in Single-Domain-Deployment) + redirectUrl = new URL( + `${PUSHER_URL}/login-screen`, + !PUSHER_URL.startsWith("http:") || !PUSHER_URL.startsWith("https:") ? window.location.origin : undefined + ); + } redirectUrl.searchParams.append("state", state); redirectUrl.searchParams.append("nonce", nonce); redirectUrl.searchParams.append("playUri", this._currentRoom.key); @@ -204,13 +215,18 @@ class ConnectionManager { } public async anonymousLogin(isBenchmark: boolean = false): Promise { - const data = await Axios.post(`${PUSHER_URL}/anonymLogin`).then((res) => res.data); - this.localUser = new LocalUser(data.userUuid, []); - this.authToken = data.authToken; - if (!isBenchmark) { - // In benchmark, we don't have a local storage. - localUserStore.saveUser(this.localUser); - localUserStore.setAuthToken(this.authToken); + try { + const data = await Axios.post(`${PUSHER_URL}/anonymLogin`).then((res) => res.data); + this.localUser = new LocalUser(data.userUuid, []); + this.authToken = data.authToken; + if (!isBenchmark) { + // In benchmark, we don't have a local storage. + localUserStore.saveUser(this.localUser); + localUserStore.setAuthToken(this.authToken); + } + } catch (error) { + // anonymous login failed (through 403 DISABLE_ANONYMOUS) + this.loadOpenIDScreen(); } } diff --git a/pusher/src/Controller/AuthenticateController.ts b/pusher/src/Controller/AuthenticateController.ts index 972cc102..2dafe065 100644 --- a/pusher/src/Controller/AuthenticateController.ts +++ b/pusher/src/Controller/AuthenticateController.ts @@ -5,6 +5,7 @@ import { adminApi } from "../Services/AdminApi"; import { AuthTokenData, jwtTokenManager } from "../Services/JWTTokenManager"; import { parse } from "query-string"; import { openIDClient } from "../Services/OpenIDClient"; +import { DISABLE_ANONYMOUS } from "../Enum/EnvironmentVariable"; export interface TokenInterface { userUuid: string; @@ -175,16 +176,21 @@ export class AuthenticateController extends BaseController { console.warn("Login request was aborted"); }); - const userUuid = v4(); - const authToken = jwtTokenManager.createAuthToken(userUuid); - res.writeStatus("200 OK"); - this.addCorsHeaders(res); - res.end( - JSON.stringify({ - authToken, - userUuid, - }) - ); + if (DISABLE_ANONYMOUS) { + res.writeStatus("403 FORBIDDEN"); + res.end(); + } else { + const userUuid = v4(); + const authToken = jwtTokenManager.createAuthToken(userUuid); + res.writeStatus("200 OK"); + this.addCorsHeaders(res); + res.end( + JSON.stringify({ + authToken, + userUuid, + }) + ); + } }); } diff --git a/pusher/src/Controller/IoSocketController.ts b/pusher/src/Controller/IoSocketController.ts index 0466100c..500f4142 100644 --- a/pusher/src/Controller/IoSocketController.ts +++ b/pusher/src/Controller/IoSocketController.ts @@ -26,7 +26,7 @@ import { jwtTokenManager, tokenInvalidException } from "../Services/JWTTokenMana import { adminApi, FetchMemberDataByUuidResponse } from "../Services/AdminApi"; import { SocketManager, socketManager } from "../Services/SocketManager"; import { emitInBatch } from "../Services/IoSocketHelpers"; -import { ADMIN_API_TOKEN, ADMIN_API_URL, SOCKET_IDLE_TIMER } from "../Enum/EnvironmentVariable"; +import { ADMIN_API_TOKEN, ADMIN_API_URL, SOCKET_IDLE_TIMER, DISABLE_ANONYMOUS } from "../Enum/EnvironmentVariable"; import { Zone } from "_Model/Zone"; import { ExAdminSocketInterface } from "_Model/Websocket/ExAdminSocketInterface"; import { v4 } from "uuid"; @@ -175,6 +175,11 @@ export class IoSocketController { const tokenData = token && typeof token === "string" ? jwtTokenManager.verifyJWTToken(token) : null; + + if (DISABLE_ANONYMOUS && !tokenData) { + throw new Error("Expecting token"); + } + const userIdentifier = tokenData ? tokenData.identifier : ""; let memberTags: string[] = []; diff --git a/pusher/src/Controller/MapController.ts b/pusher/src/Controller/MapController.ts index f775b50c..437bac6a 100644 --- a/pusher/src/Controller/MapController.ts +++ b/pusher/src/Controller/MapController.ts @@ -2,9 +2,9 @@ import { HttpRequest, HttpResponse, TemplatedApp } from "uWebSockets.js"; import { BaseController } from "./BaseController"; import { parse } from "query-string"; import { adminApi } from "../Services/AdminApi"; -import { ADMIN_API_URL } from "../Enum/EnvironmentVariable"; +import { ADMIN_API_URL, DISABLE_ANONYMOUS } from "../Enum/EnvironmentVariable"; import { GameRoomPolicyTypes } from "../Model/PusherRoom"; -import { MapDetailsData } from "../Services/AdminApi/MapDetailsData"; +import { isMapDetailsData, MapDetailsData } from "../Services/AdminApi/MapDetailsData"; import { socketManager } from "../Services/SocketManager"; import { AuthTokenData, jwtTokenManager } from "../Services/JWTTokenManager"; import { v4 } from "uuid"; @@ -64,6 +64,7 @@ export class MapController extends BaseController { tags: [], textures: [], contactPage: undefined, + authenticationMandatory: DISABLE_ANONYMOUS, } as MapDetailsData) ); @@ -87,6 +88,10 @@ export class MapController extends BaseController { } const mapDetails = await adminApi.fetchMapDetails(query.playUri as string, userId); + if (isMapDetailsData(mapDetails) && DISABLE_ANONYMOUS) { + (mapDetails as MapDetailsData).authenticationMandatory = true; + } + res.writeStatus("200 OK"); this.addCorsHeaders(res); res.end(JSON.stringify(mapDetails)); diff --git a/pusher/src/Enum/EnvironmentVariable.ts b/pusher/src/Enum/EnvironmentVariable.ts index ab1ce110..be81871d 100644 --- a/pusher/src/Enum/EnvironmentVariable.ts +++ b/pusher/src/Enum/EnvironmentVariable.ts @@ -15,6 +15,7 @@ export const FRONT_URL = process.env.FRONT_URL || "http://localhost"; export const OPID_CLIENT_ID = process.env.OPID_CLIENT_ID || ""; export const OPID_CLIENT_SECRET = process.env.OPID_CLIENT_SECRET || ""; export const OPID_CLIENT_ISSUER = process.env.OPID_CLIENT_ISSUER || ""; +export const DISABLE_ANONYMOUS = process.env.DISABLE_ANONYMOUS ? process.env.DISABLE_ANONYMOUS == "true" : false; export { SECRET_KEY, diff --git a/pusher/src/Services/AdminApi/MapDetailsData.ts b/pusher/src/Services/AdminApi/MapDetailsData.ts index 278b81bb..7a1f57ff 100644 --- a/pusher/src/Services/AdminApi/MapDetailsData.ts +++ b/pusher/src/Services/AdminApi/MapDetailsData.ts @@ -16,6 +16,7 @@ export const isMapDetailsData = new tg.IsInterface() tags: tg.isArray(tg.isString), textures: tg.isArray(isCharacterTexture), contactPage: tg.isUnion(tg.isString, tg.isUndefined), + authenticationMandatory: tg.isUnion(tg.isBoolean, tg.isUndefined), }) .get(); From 78e0d1bead402348f36a3341ceea68b3f8e462e3 Mon Sep 17 00:00:00 2001 From: Lurkars Date: Thu, 21 Oct 2021 16:53:24 +0200 Subject: [PATCH 12/58] fix linter, cleanup --- front/src/Connexion/ConnectionManager.ts | 19 +++++++------------ pusher/src/Controller/MapController.ts | 2 +- 2 files changed, 8 insertions(+), 13 deletions(-) diff --git a/front/src/Connexion/ConnectionManager.ts b/front/src/Connexion/ConnectionManager.ts index c91e4590..aae8440a 100644 --- a/front/src/Connexion/ConnectionManager.ts +++ b/front/src/Connexion/ConnectionManager.ts @@ -215,18 +215,13 @@ class ConnectionManager { } public async anonymousLogin(isBenchmark: boolean = false): Promise { - try { - const data = await Axios.post(`${PUSHER_URL}/anonymLogin`).then((res) => res.data); - this.localUser = new LocalUser(data.userUuid, []); - this.authToken = data.authToken; - if (!isBenchmark) { - // In benchmark, we don't have a local storage. - localUserStore.saveUser(this.localUser); - localUserStore.setAuthToken(this.authToken); - } - } catch (error) { - // anonymous login failed (through 403 DISABLE_ANONYMOUS) - this.loadOpenIDScreen(); + const data = await Axios.post(`${PUSHER_URL}/anonymLogin`).then((res) => res.data); + this.localUser = new LocalUser(data.userUuid, []); + this.authToken = data.authToken; + if (!isBenchmark) { + // In benchmark, we don't have a local storage. + localUserStore.saveUser(this.localUser); + localUserStore.setAuthToken(this.authToken); } } diff --git a/pusher/src/Controller/MapController.ts b/pusher/src/Controller/MapController.ts index 437bac6a..18748d9e 100644 --- a/pusher/src/Controller/MapController.ts +++ b/pusher/src/Controller/MapController.ts @@ -89,7 +89,7 @@ export class MapController extends BaseController { const mapDetails = await adminApi.fetchMapDetails(query.playUri as string, userId); if (isMapDetailsData(mapDetails) && DISABLE_ANONYMOUS) { - (mapDetails as MapDetailsData).authenticationMandatory = true; + mapDetails.authenticationMandatory = true; } res.writeStatus("200 OK"); From 1ee0b28f66ac251a339fa7617e8848bdf69d4913 Mon Sep 17 00:00:00 2001 From: Alexis Faizeau Date: Thu, 7 Oct 2021 14:40:02 +0200 Subject: [PATCH 13/58] Fix co website closing on exit zone --- .../Phaser/Game/GameMapPropertiesListener.ts | 65 ++++++++++--------- 1 file changed, 36 insertions(+), 29 deletions(-) diff --git a/front/src/Phaser/Game/GameMapPropertiesListener.ts b/front/src/Phaser/Game/GameMapPropertiesListener.ts index 950e1ebc..29084d2a 100644 --- a/front/src/Phaser/Game/GameMapPropertiesListener.ts +++ b/front/src/Phaser/Game/GameMapPropertiesListener.ts @@ -37,37 +37,44 @@ export class GameMapPropertiesListener { } }); this.gameMap.onPropertyChange("openWebsite", (newValue, oldValue, allProps) => { - if (newValue === undefined) { - layoutManagerActionStore.removeAction("openWebsite"); - coWebsiteManager.closeCoWebsite(); - } else { - const openWebsiteFunction = () => { - coWebsiteManager.loadCoWebsite( - newValue as string, - this.scene.MapUrlFile, - allProps.get("openWebsiteAllowApi") as boolean | undefined, - allProps.get("openWebsitePolicy") as string | undefined, - allProps.get("openWebsiteWidth") as number | undefined - ); + const handler = async () => { + if (newValue === undefined || newValue !== oldValue) { layoutManagerActionStore.removeAction("openWebsite"); - }; - const openWebsiteTriggerValue = allProps.get(TRIGGER_WEBSITE_PROPERTIES); - if (openWebsiteTriggerValue && openWebsiteTriggerValue === ON_ACTION_TRIGGER_BUTTON) { - let message = allProps.get(WEBSITE_MESSAGE_PROPERTIES); - if (message === undefined) { - message = "Press SPACE or touch here to open web site"; - } - layoutManagerActionStore.addAction({ - uuid: "openWebsite", - type: "message", - message: message, - callback: () => openWebsiteFunction(), - userInputManager: this.scene.userInputManager, - }); - } else { - openWebsiteFunction(); + await coWebsiteManager.closeCoWebsites(); } - } + + if (newValue !== undefined) { + const openWebsiteFunction = () => { + coWebsiteManager.loadCoWebsite( + newValue as string, + this.scene.MapUrlFile, + allProps.get("openWebsiteAllowApi") as boolean | undefined, + allProps.get("openWebsitePolicy") as string | undefined, + allProps.get("openWebsiteWidth") as number | undefined + ); + + layoutManagerActionStore.removeAction("openWebsite"); + }; + const openWebsiteTriggerValue = allProps.get(TRIGGER_WEBSITE_PROPERTIES); + if (openWebsiteTriggerValue && openWebsiteTriggerValue === ON_ACTION_TRIGGER_BUTTON) { + let message = allProps.get(WEBSITE_MESSAGE_PROPERTIES); + if (message === undefined) { + message = "Press SPACE or touch here to open web site"; + } + layoutManagerActionStore.addAction({ + uuid: "openWebsite", + type: "message", + message: message, + callback: () => openWebsiteFunction(), + userInputManager: this.scene.userInputManager, + }); + } else { + openWebsiteFunction(); + } + } + }; + + handler(); }); } } From da8cc661b72766b4140e63af6f4fa8a8e9a091b6 Mon Sep 17 00:00:00 2001 From: Alexis Faizeau Date: Thu, 7 Oct 2021 14:44:15 +0200 Subject: [PATCH 14/58] Implement the new co website system --- front/dist/index.tmpl.html | 74 ++- front/src/Components/Menu/Menu.svelte | 1 + front/src/Components/Menu/MenuIcon.svelte | 2 + front/src/Phaser/Game/GameScene.ts | 2 +- front/src/WebRtc/CoWebsiteManager.ts | 566 ++++++++++++++++++---- front/src/WebRtc/JitsiFactory.ts | 10 +- front/src/index.ts | 2 +- front/style/cowebsite-mobile.scss | 79 ++- front/style/cowebsite.scss | 167 ++++++- front/style/style.scss | 17 +- 10 files changed, 761 insertions(+), 159 deletions(-) diff --git a/front/dist/index.tmpl.html b/front/dist/index.tmpl.html index 0c89b611..dc21765b 100644 --- a/front/dist/index.tmpl.html +++ b/front/dist/index.tmpl.html @@ -37,6 +37,54 @@
+
+
+
+
+ + +
+
+
+ +
+
+
+
+ +
+
+ + +
+
+
+ +
+
+
+ +
+
+ + +
+
+
+ +
+
+
+ +
+
+ + +
+
+
+
+
@@ -48,19 +96,25 @@
+
diff --git a/front/src/Components/Menu/Menu.svelte b/front/src/Components/Menu/Menu.svelte index 6cbef9c1..4eecb370 100644 --- a/front/src/Components/Menu/Menu.svelte +++ b/front/src/Components/Menu/Menu.svelte @@ -124,6 +124,7 @@ top: 10%; position: relative; + z-index: 80; margin: auto; display: grid; diff --git a/front/src/Components/Menu/MenuIcon.svelte b/front/src/Components/Menu/MenuIcon.svelte index 02d6eb53..fa177c88 100644 --- a/front/src/Components/Menu/MenuIcon.svelte +++ b/front/src/Components/Menu/MenuIcon.svelte @@ -29,6 +29,8 @@ diff --git a/front/src/Components/Menu/GuestSubMenu.svelte b/front/src/Components/Menu/GuestSubMenu.svelte new file mode 100644 index 00000000..13a7981a --- /dev/null +++ b/front/src/Components/Menu/GuestSubMenu.svelte @@ -0,0 +1,75 @@ + + +
+
+ +
+

Share the link of the room !

+ + +
+
+
+ + \ No newline at end of file diff --git a/front/src/Components/Menu/Menu.svelte b/front/src/Components/Menu/Menu.svelte index 4eecb370..83715304 100644 --- a/front/src/Components/Menu/Menu.svelte +++ b/front/src/Components/Menu/Menu.svelte @@ -2,11 +2,11 @@ import {fly} from "svelte/transition"; import SettingsSubMenu from "./SettingsSubMenu.svelte"; import ProfileSubMenu from "./ProfileSubMenu.svelte"; - import CreateMapSubMenu from "./CreateMapSubMenu.svelte"; import AboutRoomSubMenu from "./AboutRoomSubMenu.svelte"; import GlobalMessageSubMenu from "./GlobalMessagesSubMenu.svelte"; import ContactSubMenu from "./ContactSubMenu.svelte"; import CustomSubMenu from "./CustomSubMenu.svelte" + import GuestSubMenu from "./GuestSubMenu.svelte"; import { checkSubMenuToShow, customMenuIframe, @@ -19,21 +19,21 @@ import type {Unsubscriber} from "svelte/store"; import {sendMenuClickedEvent} from "../../Api/iframe/Ui/MenuItem"; - let activeSubMenu: string = SubMenusInterface.settings; - let activeComponent: typeof SettingsSubMenu | typeof CustomSubMenu = SettingsSubMenu; + let activeSubMenu: string = SubMenusInterface.profile; + let activeComponent: typeof ProfileSubMenu | typeof CustomSubMenu = ProfileSubMenu; let props: { url: string, allowApi: boolean }; let unsubscriberSubMenuStore: Unsubscriber; onMount(() => { unsubscriberSubMenuStore = subMenusStore.subscribe(() => { if(!get(subMenusStore).includes(activeSubMenu)) { - switchMenu(SubMenusInterface.settings); + switchMenu(SubMenusInterface.profile); } }) checkSubMenuToShow(); - switchMenu(SubMenusInterface.settings); + switchMenu(SubMenusInterface.profile); }) onDestroy(() => { @@ -52,8 +52,8 @@ case SubMenusInterface.profile: activeComponent = ProfileSubMenu; break; - case SubMenusInterface.createMap: - activeComponent = CreateMapSubMenu; + case SubMenusInterface.invite: + activeComponent = GuestSubMenu; break; case SubMenusInterface.aboutRoom: activeComponent = AboutRoomSubMenu; diff --git a/front/src/Components/Menu/ProfileSubMenu.svelte b/front/src/Components/Menu/ProfileSubMenu.svelte index 83ec329c..e543096e 100644 --- a/front/src/Components/Menu/ProfileSubMenu.svelte +++ b/front/src/Components/Menu/ProfileSubMenu.svelte @@ -55,54 +55,73 @@
- {#if $userIsConnected} + + +
+ {#if $userIsConnected} +
+ {#if PROFILE_URL != undefined} + + {/if} +
+
+ +
+ {:else} +
+ Sign in +
+ {/if} +
+ + +
+
+ +
+
+ Profile validated by domain: ${domain} +
+
+ Your email: ${email} +
+
+ + ` + ); + } +} diff --git a/pusher/src/Enum/EnvironmentVariable.ts b/pusher/src/Enum/EnvironmentVariable.ts index 43bfc7bf..52382266 100644 --- a/pusher/src/Enum/EnvironmentVariable.ts +++ b/pusher/src/Enum/EnvironmentVariable.ts @@ -16,6 +16,7 @@ export const OPID_CLIENT_ID = process.env.OPID_CLIENT_ID || ""; export const OPID_CLIENT_SECRET = process.env.OPID_CLIENT_SECRET || ""; export const OPID_CLIENT_ISSUER = process.env.OPID_CLIENT_ISSUER || ""; export const OPID_CLIENT_REDIREC_URL = process.env.OPID_CLIENT_REDIREC_URL || FRONT_URL + "/jwt"; +export const OPID_PROFILE_SCREEN_PROVIDER = process.env.OPID_PROFILE_SCREEN_PROVIDER || ADMIN_URL + "/profile"; export const DISABLE_ANONYMOUS = process.env.DISABLE_ANONYMOUS || false; export { diff --git a/pusher/src/Services/AdminApi.ts b/pusher/src/Services/AdminApi.ts index d002ff8b..6e1848eb 100644 --- a/pusher/src/Services/AdminApi.ts +++ b/pusher/src/Services/AdminApi.ts @@ -1,4 +1,4 @@ -import { ADMIN_API_TOKEN, ADMIN_API_URL, ADMIN_URL } from "../Enum/EnvironmentVariable"; +import { ADMIN_API_TOKEN, ADMIN_API_URL, ADMIN_URL, OPID_PROFILE_SCREEN_PROVIDER } from "../Enum/EnvironmentVariable"; import Axios from "axios"; import { GameRoomPolicyTypes } from "_Model/PusherRoom"; import { CharacterTexture } from "./AdminApi/CharacterTexture"; @@ -142,13 +142,15 @@ class AdminApi { }); } - /*TODO add constant to use profile companny*/ + /** + * + * @param accessToken + */ getProfileUrl(accessToken: string): string { - if (!ADMIN_URL) { + if (!OPID_PROFILE_SCREEN_PROVIDER) { throw new Error("No admin backoffice set!"); } - - return ADMIN_URL + `/profile?token=${accessToken}`; + return `${OPID_PROFILE_SCREEN_PROVIDER}?accessToken=${accessToken}`; } async logoutOauth(token: string) { From 16c08d86f29e144bf995b72b136d48fc5f41c5ba Mon Sep 17 00:00:00 2001 From: Gregoire Parant Date: Mon, 15 Nov 2021 12:30:25 +0100 Subject: [PATCH 53/58] Update hydraAccessToken to accessToken --- pusher/src/Controller/AuthenticateController.ts | 15 ++++++++------- pusher/src/Services/JWTTokenManager.ts | 6 +++--- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/pusher/src/Controller/AuthenticateController.ts b/pusher/src/Controller/AuthenticateController.ts index 2dafe065..7b1f50bd 100644 --- a/pusher/src/Controller/AuthenticateController.ts +++ b/pusher/src/Controller/AuthenticateController.ts @@ -62,10 +62,11 @@ export class AuthenticateController extends BaseController { if (token != undefined) { try { const authTokenData: AuthTokenData = jwtTokenManager.verifyJWTToken(token as string, false); - if (authTokenData.hydraAccessToken == undefined) { + if (authTokenData.accessToken == undefined) { throw Error("Token cannot to be check on Hydra"); } - await openIDClient.checkTokenAuth(authTokenData.hydraAccessToken); + const resCheckTokenAuth = await openIDClient.checkTokenAuth(authTokenData.accessToken); + console.log("resCheckTokenAuth", resCheckTokenAuth); res.writeStatus("200"); this.addCorsHeaders(res); return res.end(JSON.stringify({ authToken: token })); @@ -100,10 +101,10 @@ export class AuthenticateController extends BaseController { try { const authTokenData: AuthTokenData = jwtTokenManager.verifyJWTToken(token as string, false); - if (authTokenData.hydraAccessToken == undefined) { + if (authTokenData.accessToken == undefined) { throw Error("Token cannot to be logout on Hydra"); } - await openIDClient.logoutUser(authTokenData.hydraAccessToken); + await openIDClient.logoutUser(authTokenData.accessToken); } catch (error) { console.error("openIDCallback => logout-callback", error); } finally { @@ -208,14 +209,14 @@ export class AuthenticateController extends BaseController { if (token != undefined) { try { const authTokenData: AuthTokenData = jwtTokenManager.verifyJWTToken(token as string, false); - if (authTokenData.hydraAccessToken == undefined) { + if (authTokenData.accessToken == undefined) { throw Error("Token cannot to be check on Hydra"); } - await openIDClient.checkTokenAuth(authTokenData.hydraAccessToken); + await openIDClient.checkTokenAuth(authTokenData.accessToken); //get login profile res.writeStatus("302"); - res.writeHeader("Location", adminApi.getProfileUrl(authTokenData.hydraAccessToken)); + res.writeHeader("Location", adminApi.getProfileUrl(authTokenData.accessToken)); this.addCorsHeaders(res); // eslint-disable-next-line no-unsafe-finally return res.end(); diff --git a/pusher/src/Services/JWTTokenManager.ts b/pusher/src/Services/JWTTokenManager.ts index 24393084..2f482dbf 100644 --- a/pusher/src/Services/JWTTokenManager.ts +++ b/pusher/src/Services/JWTTokenManager.ts @@ -6,13 +6,13 @@ import { adminApi, AdminBannedData } from "../Services/AdminApi"; export interface AuthTokenData { identifier: string; //will be a email if logged in or an uuid if anonymous - hydraAccessToken?: string; + accessToken?: string; } export const tokenInvalidException = "tokenInvalid"; class JWTTokenManager { - public createAuthToken(identifier: string, hydraAccessToken?: string) { - return Jwt.sign({ identifier, hydraAccessToken }, SECRET_KEY, { expiresIn: "30d" }); + public createAuthToken(identifier: string, accessToken?: string) { + return Jwt.sign({ identifier, accessToken }, SECRET_KEY, { expiresIn: "30d" }); } public verifyJWTToken(token: string, ignoreExpiration: boolean = false): AuthTokenData { From 61b8d584af01432deca9b4d014c5b97f3e086e2e Mon Sep 17 00:00:00 2001 From: Gregoire Parant Date: Mon, 15 Nov 2021 14:34:23 +0100 Subject: [PATCH 54/58] delete useless userIdentify --- pusher/src/Controller/AuthenticateController.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pusher/src/Controller/AuthenticateController.ts b/pusher/src/Controller/AuthenticateController.ts index 7b1f50bd..0cef24bb 100644 --- a/pusher/src/Controller/AuthenticateController.ts +++ b/pusher/src/Controller/AuthenticateController.ts @@ -203,7 +203,7 @@ export class AuthenticateController extends BaseController { res.onAborted(() => { console.warn("/message request was aborted"); }); - const { userIdentify, token } = parse(req.getQuery()); + const { token } = parse(req.getQuery()); try { //verify connected by token if (token != undefined) { From bbc2ac255002133b00607b0cb8d6e73bc0c6dfc9 Mon Sep 17 00:00:00 2001 From: Gregoire Parant Date: Mon, 15 Nov 2021 15:25:49 +0100 Subject: [PATCH 55/58] Update Connection manager to clean url history of navigator --- front/src/Connexion/ConnectionManager.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/front/src/Connexion/ConnectionManager.ts b/front/src/Connexion/ConnectionManager.ts index 1f844bf2..793831bf 100644 --- a/front/src/Connexion/ConnectionManager.ts +++ b/front/src/Connexion/ConnectionManager.ts @@ -212,6 +212,8 @@ class ConnectionManager { analyticsClient.identifyUser(this.localUser.uuid, this.localUser.email); } + //clean history with new URL + window.history.pushState({}, document.title, window.location.pathname); this.serviceWorker = new _ServiceWorker(); return Promise.resolve(this._currentRoom); } From 210a789aa460c63d759dc3d85e3eb5a49def0346 Mon Sep 17 00:00:00 2001 From: Gregoire Parant Date: Mon, 15 Nov 2021 15:58:08 +0100 Subject: [PATCH 56/58] Fix feedback @moufmouf --- .env.template | 2 +- docker-compose.single-domain.yaml | 2 +- docker-compose.yaml | 2 +- front/src/Connexion/ConnectionManager.ts | 3 + .../src/Controller/AuthenticateController.ts | 1 - .../src/Controller/OpenIdProfileController.ts | 64 +++++++++---------- pusher/src/Enum/EnvironmentVariable.ts | 2 +- pusher/src/Services/OpenIDClient.ts | 6 +- 8 files changed, 42 insertions(+), 40 deletions(-) diff --git a/.env.template b/.env.template index 5328fe08..0bd7bf6d 100644 --- a/.env.template +++ b/.env.template @@ -22,7 +22,7 @@ MAX_USERNAME_LENGTH=8 OPID_CLIENT_ID= OPID_CLIENT_SECRET= OPID_CLIENT_ISSUER= -OPID_CLIENT_REDIREC_URL= +OPID_CLIENT_REDIRECT_URL= OPID_LOGIN_SCREEN_PROVIDER=http://pusher.workadventure.localhost/login-screen OPID_PROFILE_SCREEN_PROVIDER= DISABLE_ANONYMOUS= diff --git a/docker-compose.single-domain.yaml b/docker-compose.single-domain.yaml index e241c108..cd38a0f9 100644 --- a/docker-compose.single-domain.yaml +++ b/docker-compose.single-domain.yaml @@ -71,7 +71,7 @@ services: OPID_CLIENT_ID: $OPID_CLIENT_ID OPID_CLIENT_SECRET: $OPID_CLIENT_SECRET OPID_CLIENT_ISSUER: $OPID_CLIENT_ISSUER - OPID_CLIENT_REDIREC_URL: $OPID_CLIENT_REDIREC_URL + OPID_CLIENT_REDIRECT_URL: $OPID_CLIENT_REDIRECT_URL OPID_PROFILE_SCREEN_PROVIDER: $OPID_PROFILE_SCREEN_PROVIDER DISABLE_ANONYMOUS: $DISABLE_ANONYMOUS volumes: diff --git a/docker-compose.yaml b/docker-compose.yaml index 03395f22..0e22fa91 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -73,7 +73,7 @@ services: OPID_CLIENT_ID: $OPID_CLIENT_ID OPID_CLIENT_SECRET: $OPID_CLIENT_SECRET OPID_CLIENT_ISSUER: $OPID_CLIENT_ISSUER - OPID_CLIENT_REDIREC_URL: $OPID_CLIENT_REDIREC_URL + OPID_CLIENT_REDIRECT_URL: $OPID_CLIENT_REDIRECT_URL OPID_PROFILE_SCREEN_PROVIDER: $OPID_PROFILE_SCREEN_PROVIDER DISABLE_ANONYMOUS: $DISABLE_ANONYMOUS volumes: diff --git a/front/src/Connexion/ConnectionManager.ts b/front/src/Connexion/ConnectionManager.ts index 793831bf..9316e37f 100644 --- a/front/src/Connexion/ConnectionManager.ts +++ b/front/src/Connexion/ConnectionManager.ts @@ -183,8 +183,11 @@ class ConnectionManager { } else { try { await this.checkAuthUserConnexion(); + analyticsClient.loggedWithSso(); } catch (err) { console.error(err); + this.loadOpenIDScreen(); + return Promise.reject(new Error("You will be redirect on login page")); } } this.localUser = localUserStore.getLocalUser() as LocalUser; //if authToken exist in localStorage then localUser cannot be null diff --git a/pusher/src/Controller/AuthenticateController.ts b/pusher/src/Controller/AuthenticateController.ts index 0cef24bb..70e333a8 100644 --- a/pusher/src/Controller/AuthenticateController.ts +++ b/pusher/src/Controller/AuthenticateController.ts @@ -66,7 +66,6 @@ export class AuthenticateController extends BaseController { throw Error("Token cannot to be check on Hydra"); } const resCheckTokenAuth = await openIDClient.checkTokenAuth(authTokenData.accessToken); - console.log("resCheckTokenAuth", resCheckTokenAuth); res.writeStatus("200"); this.addCorsHeaders(res); return res.end(JSON.stringify({ authToken: token })); diff --git a/pusher/src/Controller/OpenIdProfileController.ts b/pusher/src/Controller/OpenIdProfileController.ts index 372b603b..f33e7a22 100644 --- a/pusher/src/Controller/OpenIdProfileController.ts +++ b/pusher/src/Controller/OpenIdProfileController.ts @@ -44,37 +44,37 @@ export class OpenIdProfileController extends BaseController { } buildHtml(domain: string, email: string, pictureUrl?: string) { - return ( - "" + - ` -
- -
- -
-
- -
-
- Profile validated by domain: ${domain} -
-
- Your email: ${email} -
-
- - ` - ); + return ` + + + + + + +
+
+ +
+
+ Profile validated by domain: ${domain} +
+
+ Your email: ${email} +
+
+ + + `; } } diff --git a/pusher/src/Enum/EnvironmentVariable.ts b/pusher/src/Enum/EnvironmentVariable.ts index 52382266..23d2c23f 100644 --- a/pusher/src/Enum/EnvironmentVariable.ts +++ b/pusher/src/Enum/EnvironmentVariable.ts @@ -15,7 +15,7 @@ export const FRONT_URL = process.env.FRONT_URL || "http://localhost"; export const OPID_CLIENT_ID = process.env.OPID_CLIENT_ID || ""; export const OPID_CLIENT_SECRET = process.env.OPID_CLIENT_SECRET || ""; export const OPID_CLIENT_ISSUER = process.env.OPID_CLIENT_ISSUER || ""; -export const OPID_CLIENT_REDIREC_URL = process.env.OPID_CLIENT_REDIREC_URL || FRONT_URL + "/jwt"; +export const OPID_CLIENT_REDIRECT_URL = process.env.OPID_CLIENT_REDIRECT_URL || FRONT_URL + "/jwt"; export const OPID_PROFILE_SCREEN_PROVIDER = process.env.OPID_PROFILE_SCREEN_PROVIDER || ADMIN_URL + "/profile"; export const DISABLE_ANONYMOUS = process.env.DISABLE_ANONYMOUS || false; diff --git a/pusher/src/Services/OpenIDClient.ts b/pusher/src/Services/OpenIDClient.ts index bc0dd6c9..13bf6f76 100644 --- a/pusher/src/Services/OpenIDClient.ts +++ b/pusher/src/Services/OpenIDClient.ts @@ -3,7 +3,7 @@ import { OPID_CLIENT_ID, OPID_CLIENT_SECRET, OPID_CLIENT_ISSUER, - OPID_CLIENT_REDIREC_URL, + OPID_CLIENT_REDIRECT_URL, } from "../Enum/EnvironmentVariable"; class OpenIDClient { @@ -15,7 +15,7 @@ class OpenIDClient { return new issuer.Client({ client_id: OPID_CLIENT_ID, client_secret: OPID_CLIENT_SECRET, - redirect_uris: [OPID_CLIENT_REDIREC_URL], + redirect_uris: [OPID_CLIENT_REDIRECT_URL], response_types: ["code"], }); }); @@ -38,7 +38,7 @@ class OpenIDClient { public getUserInfo(code: string, nonce: string): Promise<{ email: string; sub: string; access_token: string }> { return this.initClient().then((client) => { - return client.callback(OPID_CLIENT_REDIREC_URL, { code }, { nonce }).then((tokenSet) => { + return client.callback(OPID_CLIENT_REDIRECT_URL, { code }, { nonce }).then((tokenSet) => { return client.userinfo(tokenSet).then((res) => { return { ...res, From 20164417fb2be7149bd0885138828ceb1267d606 Mon Sep 17 00:00:00 2001 From: Gregoire Parant Date: Mon, 15 Nov 2021 16:34:23 +0100 Subject: [PATCH 57/58] Change data by resCheckTokenAuth --- pusher/src/Controller/AuthenticateController.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pusher/src/Controller/AuthenticateController.ts b/pusher/src/Controller/AuthenticateController.ts index 21b636f9..f505923c 100644 --- a/pusher/src/Controller/AuthenticateController.ts +++ b/pusher/src/Controller/AuthenticateController.ts @@ -69,7 +69,7 @@ export class AuthenticateController extends BaseController { const resCheckTokenAuth = await openIDClient.checkTokenAuth(authTokenData.accessToken); res.writeStatus("200"); this.addCorsHeaders(res); - return res.end(JSON.stringify({ ...data, authToken: token })); + return res.end(JSON.stringify({ ...resCheckTokenAuth, authToken: token })); } catch (err) { console.info("User was not connected", err); } From d3964ae25b86ee03af1a212a8412eda89365b86a Mon Sep 17 00:00:00 2001 From: Gregoire Parant Date: Mon, 15 Nov 2021 16:36:10 +0100 Subject: [PATCH 58/58] HotFix conflict merging --- front/src/Connexion/ConnectionManager.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/front/src/Connexion/ConnectionManager.ts b/front/src/Connexion/ConnectionManager.ts index 87f23843..00e721ae 100644 --- a/front/src/Connexion/ConnectionManager.ts +++ b/front/src/Connexion/ConnectionManager.ts @@ -111,7 +111,7 @@ class ConnectionManager { this._currentRoom = await Room.createRoom(new URL(localUserStore.getLastRoomUrl())); try { - await this.checkAuthUserConnexion(this._currentRoom.key); + await this.checkAuthUserConnexion(); analyticsClient.loggedWithSso(); } catch (err) { console.error(err); @@ -296,7 +296,7 @@ class ConnectionManager { return this.connexionType; } - async checkAuthUserConnexion(playUri: string) { + async checkAuthUserConnexion() { //set connected store for menu at false userIsConnected.set(false); @@ -313,9 +313,9 @@ class ConnectionManager { throw "No Auth code provided"; } } - const { authToken, userUuid, textures, email } = await Axios.get(`${PUSHER_URL}/login-callback`, { params: { code, nonce, token } }).then( - (res) => res.data - ); + const { authToken, userUuid, textures, email } = await Axios.get(`${PUSHER_URL}/login-callback`, { + params: { code, nonce, token }, + }).then((res) => res.data); localUserStore.setAuthToken(authToken); this.localUser = new LocalUser(userUuid, textures, email); localUserStore.saveUser(this.localUser);