Update to have token when user is connected

- Update menu design

Signed-off-by: Gregoire Parant <g.parant@thecodingmachine.com>
This commit is contained in:
Gregoire Parant 2021-11-12 12:13:44 +01:00
parent 1db22d82af
commit d3f120f2bb
7 changed files with 220 additions and 123 deletions

View File

@ -1,10 +1,60 @@
<script lang="ts"> <script lang="ts">
function goToGettingStarted() {
const sparkHost = "https://workadventu.re/getting-started";
window.open(sparkHost, "_blank");
}
function goToBuildingMap() {
const sparkHost = "https://workadventu.re/map-building/";
window.open(sparkHost, "_blank");
}
import {contactPageStore} from "../../Stores/MenuStore"; import {contactPageStore} from "../../Stores/MenuStore";
</script> </script>
<iframe title="contact" src="{$contactPageStore}" allow="clipboard-read; clipboard-write self {$contactPageStore}" allowfullscreen></iframe> <div class="create-map-main">
<section class="container-overflow">
<section>
<h3>Getting started</h3>
<p>
WorkAdventure allows you to create an online space to communicate spontaneously with others.
And it all starts with creating your own space. Choose from a large selection of prefabricated maps by our team.
</p>
<button type="button" class="nes-btn is-primary" on:click={goToGettingStarted}>Getting started</button>
</section>
<section>
<h3>Create your map</h3>
<p>You can also create your own custom map by following the step of the documentation.</p>
<button type="button" class="nes-btn" on:click={goToBuildingMap}>Create your map</button>
</section>
<iframe title="contact"
src="{$contactPageStore}"
allow="clipboard-read; clipboard-write self {$contactPageStore}"
allowfullscreen></iframe>
</section>
</div>
<style lang="scss"> <style lang="scss">
div.create-map-main {
height: calc(100% - 56px);
text-align: center;
section {
margin-bottom: 50px;
}
section.container-overflow {
height: 100%;
margin: 0;
padding: 0;
overflow: auto;
}
}
iframe { iframe {
border: none; border: none;
height: calc(100% - 56px); height: calc(100% - 56px);

View File

@ -1,51 +0,0 @@
<script lang="ts">
function goToGettingStarted() {
const sparkHost = "https://workadventu.re/getting-started";
window.open(sparkHost, "_blank");
}
function goToBuildingMap() {
const sparkHost = "https://workadventu.re/map-building/";
window.open(sparkHost, "_blank");
}
</script>
<div class="create-map-main">
<section class="container-overflow">
<section>
<h3>Getting started</h3>
<p>
WorkAdventure allows you to create an online space to communicate spontaneously with others.
And it all starts with creating your own space. Choose from a large selection of prefabricated maps by our team.
</p>
<button type="button" class="nes-btn is-primary" on:click={goToGettingStarted}>Getting started</button>
</section>
<section>
<h3>Create your map</h3>
<p>You can also create your own custom map by following the step of the documentation.</p>
<button type="button" class="nes-btn" on:click={goToBuildingMap}>Create your map</button>
</section>
</section>
</div>
<style lang="scss">
div.create-map-main {
height: calc(100% - 56px);
text-align: center;
section {
margin-bottom: 50px;
}
section.container-overflow {
height: 100%;
margin: 0;
padding: 0;
overflow: auto;
}
}
</style>

View File

@ -0,0 +1,75 @@
<script lang="ts">
let HTMLShareLink: HTMLInputElement;
function copyLink() {
HTMLShareLink.select();
document.execCommand('copy');
}
async function shareLink() {
const shareData = {url: location.toString()};
try {
await navigator.share(shareData);
} catch (err) {
console.error('Error: ' + err);
copyLink();
}
}
</script>
<div class="guest-main">
<section class="container-overflow">
<section class="share-url not-mobile">
<h3>Share the link of the room !</h3>
<input type="text" readonly bind:this={HTMLShareLink} value={location.toString()}>
<button type="button" class="nes-btn is-primary" on:click={copyLink}>Copy</button>
</section>
<section class="is-mobile">
<h3>Share the link of the room !</h3>
<input type="hidden" readonly bind:this={HTMLShareLink} value={location.toString()}>
<button type="button" class="nes-btn is-primary" on:click={shareLink}>Share</button>
</section>
</section>
</div>
<style lang="scss">
div.guest-main {
height: calc(100% - 56px);
text-align: center;
section {
margin-bottom: 50px;
}
section.container-overflow {
height: 100%;
margin: 0;
padding: 0;
overflow: auto;
}
section.is-mobile {
display: none;
}
}
@media only screen and (max-width: 900px), only screen and (max-height: 600px) {
div.guest-main {
section.share-url.not-mobile {
display: none;
}
section.is-mobile {
display: block;
text-align: center;
margin-bottom: 20px;
}
section.container-overflow {
height: calc(100% - 120px);
}
}
}
</style>

View File

@ -2,11 +2,11 @@
import {fly} from "svelte/transition"; import {fly} from "svelte/transition";
import SettingsSubMenu from "./SettingsSubMenu.svelte"; import SettingsSubMenu from "./SettingsSubMenu.svelte";
import ProfileSubMenu from "./ProfileSubMenu.svelte"; import ProfileSubMenu from "./ProfileSubMenu.svelte";
import CreateMapSubMenu from "./CreateMapSubMenu.svelte";
import AboutRoomSubMenu from "./AboutRoomSubMenu.svelte"; import AboutRoomSubMenu from "./AboutRoomSubMenu.svelte";
import GlobalMessageSubMenu from "./GlobalMessagesSubMenu.svelte"; import GlobalMessageSubMenu from "./GlobalMessagesSubMenu.svelte";
import ContactSubMenu from "./ContactSubMenu.svelte"; import ContactSubMenu from "./ContactSubMenu.svelte";
import CustomSubMenu from "./CustomSubMenu.svelte" import CustomSubMenu from "./CustomSubMenu.svelte"
import GuestSubMenu from "./GuestSubMenu.svelte";
import { import {
checkSubMenuToShow, checkSubMenuToShow,
customMenuIframe, customMenuIframe,
@ -19,21 +19,21 @@
import type {Unsubscriber} from "svelte/store"; import type {Unsubscriber} from "svelte/store";
import {sendMenuClickedEvent} from "../../Api/iframe/Ui/MenuItem"; import {sendMenuClickedEvent} from "../../Api/iframe/Ui/MenuItem";
let activeSubMenu: string = SubMenusInterface.settings; let activeSubMenu: string = SubMenusInterface.profile;
let activeComponent: typeof SettingsSubMenu | typeof CustomSubMenu = SettingsSubMenu; let activeComponent: typeof ProfileSubMenu | typeof CustomSubMenu = ProfileSubMenu;
let props: { url: string, allowApi: boolean }; let props: { url: string, allowApi: boolean };
let unsubscriberSubMenuStore: Unsubscriber; let unsubscriberSubMenuStore: Unsubscriber;
onMount(() => { onMount(() => {
unsubscriberSubMenuStore = subMenusStore.subscribe(() => { unsubscriberSubMenuStore = subMenusStore.subscribe(() => {
if(!get(subMenusStore).includes(activeSubMenu)) { if(!get(subMenusStore).includes(activeSubMenu)) {
switchMenu(SubMenusInterface.settings); switchMenu(SubMenusInterface.profile);
} }
}) })
checkSubMenuToShow(); checkSubMenuToShow();
switchMenu(SubMenusInterface.settings); switchMenu(SubMenusInterface.profile);
}) })
onDestroy(() => { onDestroy(() => {
@ -52,8 +52,8 @@
case SubMenusInterface.profile: case SubMenusInterface.profile:
activeComponent = ProfileSubMenu; activeComponent = ProfileSubMenu;
break; break;
case SubMenusInterface.createMap: case SubMenusInterface.invite:
activeComponent = CreateMapSubMenu; activeComponent = GuestSubMenu;
break; break;
case SubMenusInterface.aboutRoom: case SubMenusInterface.aboutRoom:
activeComponent = AboutRoomSubMenu; activeComponent = AboutRoomSubMenu;

View File

@ -55,54 +55,73 @@
</script> </script>
<div class="customize-main"> <div class="customize-main">
{#if $userIsConnected} <div class="submenu">
<section> <section>
{#if PROFILE_URL != undefined} <button type="button" class="nes-btn" on:click|preventDefault={openEditNameScene}>Edit Name</button>
<iframe title="profile" src="{getProfileUrl()}"></iframe> <button type="button" class="nes-btn" on:click|preventDefault={openEditSkinScene}>Edit Skin</button>
{/if} <button type="button" class="nes-btn" on:click|preventDefault={openEditCompanionScene}>Edit Companion</button>
</section> </section>
<section> <section>
<button type="button" class="nes-btn" on:click|preventDefault={logOut}>Log out</button> <button type="button" class="nes-btn" on:click|preventDefault={openEnableCameraScene}>Setup camera</button>
</section> </section>
{:else} </div>
<section>
<a type="button" class="nes-btn" href="/login">Sign in</a> <div class="content">
</section> {#if $userIsConnected}
{/if} <section>
<section> {#if PROFILE_URL != undefined}
<button type="button" class="nes-btn" on:click|preventDefault={openEditNameScene}>Edit Name</button> <iframe title="profile" src="{getProfileUrl()}"></iframe>
<button type="button" class="nes-btn" on:click|preventDefault={openEditSkinScene}>Edit Skin</button> {/if}
<button type="button" class="nes-btn" on:click|preventDefault={openEditCompanionScene}>Edit Companion</button> </section>
</section> <section>
<section> <button type="button" class="nes-btn" on:click|preventDefault={logOut}>Log out</button>
<button type="button" class="nes-btn" on:click|preventDefault={openEnableCameraScene}>Setup camera</button> </section>
</section> {:else}
<section>
<a type="button" class="nes-btn" href="/login">Sign in</a>
</section>
{/if}
</div>
</div> </div>
<style lang="scss"> <style lang="scss">
div.customize-submenu{
}
div.customize-main{ div.customize-main{
section { width: 100%;
display: flex; display: inline-flex;
justify-content: center;
align-items: center;
flex-wrap: wrap;
margin-bottom: 20px;
iframe{ div.submenu{
width: 100%; height: 100%;
height: 50vh; width: 180px;
border: none; }
}
button { div.content {
height: 50px; width: 100%;
width: 250px; section {
display: flex;
justify-content: center;
align-items: center;
flex-wrap: wrap;
margin-bottom: 20px;
iframe {
width: 100%;
height: 50vh;
border: none;
}
button {
height: 50px;
width: 250px;
}
} }
} }
} }
@media only screen and (max-width: 800px) { @media only screen and (max-width: 800px) {
div.customize-main section button { div.customize-main.content section button {
width: 130px; width: 130px;
} }
} }

View File

@ -41,7 +41,6 @@ class ConnectionManager {
const nonce = localUserStore.generateNonce(); const nonce = localUserStore.generateNonce();
localUserStore.setAuthToken(null); localUserStore.setAuthToken(null);
//TODO fix me to redirect this URL by pusher
if (!this._currentRoom || !this._currentRoom.iframeAuthentication) { if (!this._currentRoom || !this._currentRoom.iframeAuthentication) {
loginSceneVisibleIframeStore.set(false); loginSceneVisibleIframeStore.set(false);
return null; return null;
@ -79,6 +78,16 @@ class ConnectionManager {
const connexionType = urlManager.getGameConnexionType(); const connexionType = urlManager.getGameConnexionType();
this.connexionType = connexionType; this.connexionType = connexionType;
this._currentRoom = null; this._currentRoom = null;
const urlParams = new URLSearchParams(window.location.search);
const token = urlParams.get("token");
if (token) {
this.authToken = token;
localUserStore.setAuthToken(token);
//token was saved, clear url
urlParams.delete("token");
}
if (connexionType === GameConnexionTypes.login) { if (connexionType === GameConnexionTypes.login) {
this._currentRoom = await Room.createRoom(new URL(localUserStore.getLastRoomUrl())); this._currentRoom = await Room.createRoom(new URL(localUserStore.getLastRoomUrl()));
if (this.loadOpenIDScreen() !== null) { if (this.loadOpenIDScreen() !== null) {
@ -88,26 +97,18 @@ class ConnectionManager {
} else if (connexionType === GameConnexionTypes.jwt) { } else if (connexionType === GameConnexionTypes.jwt) {
const urlParams = new URLSearchParams(window.location.search); const urlParams = new URLSearchParams(window.location.search);
//TODO if jwt is defined, state and nonce can to be deleted if (!token) {
const code = urlParams.get("code"); const code = urlParams.get("code");
const state = urlParams.get("state"); const state = urlParams.get("state");
const jwt = urlParams.get("jwt"); if (!state || !localUserStore.verifyState(state)) {
throw "Could not validate state!";
if (jwt) {
this.authToken = jwt;
localUserStore.setAuthToken(jwt);
//if we use jwt we can update new state from openid provider
if (state) {
localUserStore.setState(state);
} }
if (!code) {
throw "No Auth code provided";
}
localUserStore.setCode(code);
} }
if (!state || !localUserStore.verifyState(state)) {
throw "Could not validate state!";
}
if (!code) {
throw "No Auth code provided";
}
localUserStore.setCode(code);
this._currentRoom = await Room.createRoom(new URL(localUserStore.getLastRoomUrl())); this._currentRoom = await Room.createRoom(new URL(localUserStore.getLastRoomUrl()));
try { try {
await this.checkAuthUserConnexion(); await this.checkAuthUserConnexion();
@ -291,16 +292,19 @@ class ConnectionManager {
//set connected store for menu at false //set connected store for menu at false
userIsConnected.set(false); userIsConnected.set(false);
const token = localUserStore.getAuthToken();
const state = localUserStore.getState(); const state = localUserStore.getState();
const code = localUserStore.getCode(); const code = localUserStore.getCode();
if (!state || !localUserStore.verifyState(state)) {
throw "Could not validate state!";
}
if (!code) {
throw "No Auth code provided";
}
const nonce = localUserStore.getNonce(); const nonce = localUserStore.getNonce();
const token = localUserStore.getAuthToken();
if (!token) {
if (!state || !localUserStore.verifyState(state)) {
throw "Could not validate state!";
}
if (!code) {
throw "No Auth code provided";
}
}
const { authToken } = await Axios.get(`${PUSHER_URL}/login-callback`, { params: { code, nonce, token } }).then( const { authToken } = await Axios.get(`${PUSHER_URL}/login-callback`, { params: { code, nonce, token } }).then(
(res) => res.data (res) => res.data
); );

View File

@ -34,20 +34,20 @@ export const warningContainerStore = createWarningContainerStore();
export enum SubMenusInterface { export enum SubMenusInterface {
settings = "Settings", settings = "Settings",
profile = "Profile", profile = "Profile",
createMap = "Create a Map", invite = "Invite",
aboutRoom = "About the Room", aboutRoom = "Credit",
globalMessages = "Global Messages", globalMessages = "Global Messages",
contact = "Contact", contact = "Contact",
} }
function createSubMenusStore() { function createSubMenusStore() {
const { subscribe, update } = writable<string[]>([ const { subscribe, update } = writable<string[]>([
SubMenusInterface.settings,
SubMenusInterface.profile, SubMenusInterface.profile,
SubMenusInterface.createMap,
SubMenusInterface.aboutRoom,
SubMenusInterface.globalMessages, SubMenusInterface.globalMessages,
SubMenusInterface.contact, SubMenusInterface.contact,
SubMenusInterface.settings,
SubMenusInterface.invite,
SubMenusInterface.aboutRoom,
]); ]);
return { return {