rewrote the authorisation flow: give more responsability to gameManager and less to gameScene

This commit is contained in:
arp 2020-10-12 16:23:07 +02:00
parent 032facb75f
commit 02c193a262
14 changed files with 244 additions and 170 deletions

View file

@ -2,54 +2,67 @@ import Axios from "axios";
import {API_URL} from "../Enum/EnvironmentVariable";
import {RoomConnection} from "./RoomConnection";
import {PositionInterface, ViewportInterface} from "./ConnexionModels";
interface LoginApiData {
authToken: string
userUuid: string
mapUrlStart: string
newUrl: string
}
import {GameConnexionTypes, urlManager} from "../Url/UrlManager";
import {localUserStore} from "./LocalUserStore";
import {LocalUser} from "./LocalUser";
import {Room} from "./Room";
class ConnectionManager {
private initPromise!: Promise<LoginApiData>;
private mapUrlStart: string|null = null;
private localUser!:LocalUser;
private authToken:string|null = null;
private userUuid: string|null = null;
/**
* Tries to login to the node server and return the starting map url to be loaded
*/
public async initGameConnexion(): Promise<Room> {
//todo: get map infos from url in anonym case
public async init(): Promise<void> {
let organizationMemberToken = null;
let teamSlug = null;
let mapSlug = null;
const match = /\/register\/(.+)/.exec(window.location.toString());
if (match) {
organizationMemberToken = match[1];
} else {
const match = /\/_\/(.+)\/(.+)/.exec(window.location.toString());
teamSlug = match ? match[1] : null;
mapSlug = match ? match[2] : null;
}
this.initPromise = Axios.post(`${API_URL}/login`, {organizationMemberToken, teamSlug, mapSlug}).then(res => res.data);
const data = await this.initPromise
this.authToken = data.authToken;
this.userUuid = data.userUuid;
this.mapUrlStart = data.mapUrlStart;
const newUrl = data.newUrl;
console.log('u', this.userUuid)
if (newUrl) {
history.pushState({}, '', newUrl);
const connexionType = urlManager.getGameConnexionType();
if(connexionType === GameConnexionTypes.register) {
const organizationMemberToken = urlManager.getOrganizationToken();
const data:any = await Axios.post(`${API_URL}/register`, {organizationMemberToken}).then(res => res.data);
this.localUser = new LocalUser(data.userUuid, data.authToken);
localUserStore.saveUser(this.localUser);
const organizationSlug = data.organizationSlug;
const worldSlug = data.worldSlug;
const roomSlug = data.roomSlug;
urlManager.editUrlForRoom(roomSlug, organizationSlug, worldSlug);
const room = new Room(window.location.pathname, data.mapUrlStart)
return Promise.resolve(room);
} else if (connexionType === GameConnexionTypes.anonymous) {
const localUser = localUserStore.getLocalUser();
if (localUser) {
this.localUser = localUser
} else {
const data:any = await Axios.post(`${API_URL}/anonymLogin`).then(res => res.data);
this.localUser = new LocalUser(data.userUuid, data.authToken);
localUserStore.saveUser(this.localUser);
}
const room = new Room(window.location.pathname, urlManager.getAnonymousMapUrlStart())
return Promise.resolve(room);
} else if (connexionType == GameConnexionTypes.organization) {
const localUser = localUserStore.getLocalUser();
if (localUser) {
this.localUser = localUser
//todo: ask the node api for the correct starting map Url from its slug
return Promise.reject('Case not handled: need to get the map\'s url from its slug');
} else {
//todo: find some kind of fallback?
return Promise.reject('Could not find a user in localstorage');
}
}
return Promise.reject('ConnexionManager initialization failed');
}
public initBenchmark(): void {
this.authToken = 'test';
this.localUser = new LocalUser('', 'test');
}
public connectToRoomSocket(roomId: string, name: string, characterLayers: string[], position: PositionInterface, viewport: ViewportInterface): Promise<RoomConnection> {
return new Promise<RoomConnection>((resolve, reject) => {
const connection = new RoomConnection(this.authToken, roomId, name, characterLayers, position, viewport);
const connection = new RoomConnection(this.localUser.jwtToken, roomId, name, characterLayers, position, viewport);
connection.onConnectError((error: object) => {
console.log('An error occurred while connecting to socket server. Retrying');
reject(error);
@ -67,15 +80,6 @@ class ConnectionManager {
});
});
}
public getMapUrlStart(): Promise<string> {
return this.initPromise.then(() => {
if (!this.mapUrlStart) {
throw new Error('No map url set!');
}
return this.mapUrlStart;
})
}
}
export const connectionManager = new ConnectionManager();

View file

@ -0,0 +1,9 @@
export class LocalUser {
public uuid: string;
public jwtToken: string;
constructor(uuid:string, jwtToken: string) {
this.uuid = uuid;
this.jwtToken = jwtToken;
}
}

View file

@ -0,0 +1,16 @@
import {LocalUser} from "./LocalUser";
class LocalUserStore {
saveUser(localUser: LocalUser) {
localStorage.setItem('localUser', JSON.stringify(localUser));
}
getLocalUser(): LocalUser|null {
const data = localStorage.getItem('localUser');
return data ? JSON.parse(data) : null;
}
}
export const localUserStore = new LocalUserStore();

View file

@ -0,0 +1,10 @@
export class Room {
public ID: string;
public url: string
constructor(ID: string, url: string) {
this.ID = ID;
this.url = url;
}
}

View file

@ -56,7 +56,8 @@ export class RoomConnection implements RoomConnection {
*/
public constructor(token: string|null, roomId: string, name: string, characterLayers: string[], position: PositionInterface, viewport: ViewportInterface) {
let url = API_URL.replace('http://', 'ws://').replace('https://', 'wss://');
url += '/room/'+roomId
url += '/room';
url += '?roomId='+(roomId ?encodeURIComponent(roomId):'');
url += '?token='+(token ?encodeURIComponent(token):'');
url += '&name='+encodeURIComponent(name);
for (const layer of characterLayers) {