improvments
This commit is contained in:
parent
af4611ed29
commit
3f9659ef3c
@ -7,7 +7,6 @@ import bodyParser = require('body-parser');
|
|||||||
import * as http from "http";
|
import * as http from "http";
|
||||||
import {MapController} from "./Controller/MapController";
|
import {MapController} from "./Controller/MapController";
|
||||||
import {PrometheusController} from "./Controller/PrometheusController";
|
import {PrometheusController} from "./Controller/PrometheusController";
|
||||||
import {AdminController} from "./Controller/AdminController";
|
|
||||||
import {DebugController} from "./Controller/DebugController";
|
import {DebugController} from "./Controller/DebugController";
|
||||||
|
|
||||||
class App {
|
class App {
|
||||||
@ -17,7 +16,6 @@ class App {
|
|||||||
public authenticateController: AuthenticateController;
|
public authenticateController: AuthenticateController;
|
||||||
public mapController: MapController;
|
public mapController: MapController;
|
||||||
public prometheusController: PrometheusController;
|
public prometheusController: PrometheusController;
|
||||||
private adminController: AdminController;
|
|
||||||
private debugController: DebugController;
|
private debugController: DebugController;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
@ -36,7 +34,6 @@ class App {
|
|||||||
this.authenticateController = new AuthenticateController(this.app);
|
this.authenticateController = new AuthenticateController(this.app);
|
||||||
this.mapController = new MapController(this.app);
|
this.mapController = new MapController(this.app);
|
||||||
this.prometheusController = new PrometheusController(this.app, this.ioSocketController);
|
this.prometheusController = new PrometheusController(this.app, this.ioSocketController);
|
||||||
this.adminController = new AdminController(this.app);
|
|
||||||
this.debugController = new DebugController(this.app, this.ioSocketController);
|
this.debugController = new DebugController(this.app, this.ioSocketController);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,7 +6,14 @@ import { uuid } from 'uuidv4';
|
|||||||
import Axios from "axios";
|
import Axios from "axios";
|
||||||
|
|
||||||
export interface TokenInterface {
|
export interface TokenInterface {
|
||||||
name: string,
|
userUuid: string
|
||||||
|
}
|
||||||
|
|
||||||
|
interface AdminApiData {
|
||||||
|
organizationSlug: string
|
||||||
|
worldSlug: string
|
||||||
|
roomSlug: string
|
||||||
|
mapUrlStart: string
|
||||||
userUuid: string
|
userUuid: string
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -35,20 +42,20 @@ export class AuthenticateController {
|
|||||||
return res.status(401).send('No admin backoffice set!');
|
return res.status(401).send('No admin backoffice set!');
|
||||||
}
|
}
|
||||||
//todo: this call can fail if the corresponding world is not activated or if the token is invalid. Handle that case.
|
//todo: this call can fail if the corresponding world is not activated or if the token is invalid. Handle that case.
|
||||||
const response = await Axios.get(ADMIN_API_URL+'/api/login-url/'+organizationMemberToken,
|
const data = await Axios.get(ADMIN_API_URL+'/api/login-url/'+organizationMemberToken,
|
||||||
{ headers: {"Authorization" : `${ADMIN_API_TOKEN}`} }
|
{ headers: {"Authorization" : `${ADMIN_API_TOKEN}`} }
|
||||||
);
|
).then((res): AdminApiData => res.data);
|
||||||
|
|
||||||
userUuid = response.data.userUuid;
|
userUuid = data.userUuid;
|
||||||
mapUrlStart = response.data.mapUrlStart;
|
mapUrlStart = data.mapUrlStart;
|
||||||
newUrl = this.getNewUrlOnAdminAuth(response.data)
|
newUrl = this.getNewUrlOnAdminAuth(data)
|
||||||
} else {
|
} else {
|
||||||
userUuid = uuid();
|
userUuid = uuid();
|
||||||
mapUrlStart= URL_ROOM_STARTED;
|
mapUrlStart = req.headers.host?.replace('api.', 'maps.') + URL_ROOM_STARTED;
|
||||||
newUrl = null;
|
newUrl = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const authToken = Jwt.sign({userUuid: userUuid} as TokenInterface, SECRET_KEY, {expiresIn: '24h'});
|
const authToken = Jwt.sign({userUuid: userUuid}, SECRET_KEY, {expiresIn: '24h'});
|
||||||
return res.status(OK).send({
|
return res.status(OK).send({
|
||||||
authToken,
|
authToken,
|
||||||
userUuid,
|
userUuid,
|
||||||
@ -64,7 +71,7 @@ export class AuthenticateController {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
getNewUrlOnAdminAuth(data:any): string {
|
private getNewUrlOnAdminAuth(data:AdminApiData): string {
|
||||||
const organizationSlug = data.organizationSlug;
|
const organizationSlug = data.organizationSlug;
|
||||||
const worldSlug = data.worldSlug;
|
const worldSlug = data.worldSlug;
|
||||||
const roomSlug = data.roomSlug;
|
const roomSlug = data.roomSlug;
|
||||||
|
@ -121,18 +121,19 @@ export class IoSocketController {
|
|||||||
return next(new Error('Authentication error'));
|
return next(new Error('Authentication error'));
|
||||||
}
|
}
|
||||||
Jwt.verify(socket.handshake.query.token, SECRET_KEY, (err: JsonWebTokenError, tokenDecoded: object) => {
|
Jwt.verify(socket.handshake.query.token, SECRET_KEY, (err: JsonWebTokenError, tokenDecoded: object) => {
|
||||||
|
const tokenInterface = tokenDecoded as TokenInterface;
|
||||||
if (err) {
|
if (err) {
|
||||||
console.error('An authentication error happened, invalid JsonWebToken.', err);
|
console.error('An authentication error happened, invalid JsonWebToken.', err);
|
||||||
return next(new Error('Authentication error'));
|
return next(new Error('Authentication error'));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this.isValidToken(tokenDecoded)) {
|
if (!this.isValidToken(tokenInterface)) {
|
||||||
return next(new Error('Authentication error, invalid token structure'));
|
return next(new Error('Authentication error, invalid token structure'));
|
||||||
}
|
}
|
||||||
|
|
||||||
(socket as ExSocketInterface).token = socket.handshake.query.token;
|
(socket as ExSocketInterface).token = socket.handshake.query.token;
|
||||||
(socket as ExSocketInterface).userId = this.nextUserId;
|
(socket as ExSocketInterface).userId = this.nextUserId;
|
||||||
(socket as ExSocketInterface).userUuid = tokenDecoded.userUuid;
|
(socket as ExSocketInterface).userUuid = tokenInterface.userUuid;
|
||||||
this.nextUserId++;
|
this.nextUserId++;
|
||||||
next();
|
next();
|
||||||
});
|
});
|
||||||
@ -141,11 +142,8 @@ export class IoSocketController {
|
|||||||
this.ioConnection();
|
this.ioConnection();
|
||||||
}
|
}
|
||||||
|
|
||||||
private isValidToken(token: object): token is TokenInterface {
|
private isValidToken(token: TokenInterface): boolean {
|
||||||
if (typeof((token as TokenInterface).userUuid) !== 'string') {
|
if (typeof(token.userUuid) !== 'string') {
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (typeof((token as TokenInterface).name) !== 'string') {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -3,6 +3,7 @@ import {Application, Request, Response} from "express";
|
|||||||
import {OK} from "http-status-codes";
|
import {OK} from "http-status-codes";
|
||||||
import {URL_ROOM_STARTED} from "../Enum/EnvironmentVariable";
|
import {URL_ROOM_STARTED} from "../Enum/EnvironmentVariable";
|
||||||
|
|
||||||
|
//todo: delete this
|
||||||
export class MapController {
|
export class MapController {
|
||||||
App: Application;
|
App: Application;
|
||||||
|
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import {Socket} from "socket.io";
|
import {Socket} from "socket.io";
|
||||||
import {PointInterface} from "./PointInterface";
|
import {PointInterface} from "./PointInterface";
|
||||||
import {Identificable} from "./Identificable";
|
import {Identificable} from "./Identificable";
|
||||||
import {TokenInterface} from "../../Controller/AuthenticateController";
|
|
||||||
import {ViewportInterface} from "_Model/Websocket/ViewportMessage";
|
import {ViewportInterface} from "_Model/Websocket/ViewportMessage";
|
||||||
import {BatchMessage, SubMessage} from "../../Messages/generated/messages_pb";
|
import {BatchMessage, SubMessage} from "../../Messages/generated/messages_pb";
|
||||||
|
|
||||||
|
@ -2,43 +2,44 @@ import Axios from "axios";
|
|||||||
import {API_URL} from "../Enum/EnvironmentVariable";
|
import {API_URL} from "../Enum/EnvironmentVariable";
|
||||||
import {RoomConnection} from "./RoomConnection";
|
import {RoomConnection} from "./RoomConnection";
|
||||||
|
|
||||||
|
interface LoginApiData {
|
||||||
|
authToken: string
|
||||||
|
userUuid: string
|
||||||
|
mapUrlStart: string
|
||||||
|
newUrl: string
|
||||||
|
}
|
||||||
|
|
||||||
class ConnectionManager {
|
class ConnectionManager {
|
||||||
|
private initPromise: Promise<LoginApiData> = Promise.reject();
|
||||||
private mapUrlStart: string|null = null;
|
private mapUrlStart: string|null = null;
|
||||||
|
|
||||||
private authToken:string|null = null;
|
private authToken:string|null = null;
|
||||||
private userUuid: string|null = null;
|
private userUuid: string|null = null;
|
||||||
private userName:string|null = null;
|
|
||||||
|
|
||||||
public async init(): Promise<void> {
|
public async init(): Promise<void> {
|
||||||
const match = /\/register\/(.+)/.exec(window.location.toString());
|
const match = /\/register\/(.+)/.exec(window.location.toString());
|
||||||
const organizationMemberToken = match ? match[1] : null;
|
const organizationMemberToken = match ? match[1] : null;
|
||||||
const res = await Axios.post(`${API_URL}/login`, {organizationMemberToken});
|
this.initPromise = Axios.post(`${API_URL}/login`, {organizationMemberToken}).then(res => res.data);
|
||||||
this.authToken = res.data.authToken;
|
const data = await this.initPromise
|
||||||
this.userUuid = res.data.userUuid;
|
this.authToken = data.authToken;
|
||||||
this.mapUrlStart = res.data.mapUrlStart;
|
this.userUuid = data.userUuid;
|
||||||
const newUrl = res.data.newUrl;
|
this.mapUrlStart = data.mapUrlStart;
|
||||||
|
const newUrl = data.newUrl;
|
||||||
|
|
||||||
if (newUrl) {
|
if (newUrl) {
|
||||||
history.pushState({}, '', newUrl);
|
history.pushState({}, '', newUrl);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async setUserName(name:string): Promise<void> {
|
|
||||||
//todo
|
|
||||||
}
|
|
||||||
|
|
||||||
public connectToRoomSocket(): Promise<RoomConnection> {
|
public connectToRoomSocket(): Promise<RoomConnection> {
|
||||||
return Axios.post(`${API_URL}/connectToSocket`, {authToken: this.authToken}).then((res) => {
|
|
||||||
return new Promise<RoomConnection>((resolve, reject) => {
|
return new Promise<RoomConnection>((resolve, reject) => {
|
||||||
const connection = new RoomConnection(res.data.roomToken);
|
const connection = new RoomConnection(this.authToken as string);
|
||||||
connection.onConnectError((error: object) => {
|
connection.onConnectError((error: object) => {
|
||||||
console.log('An error occurred while connecting to socket server. Retrying');
|
console.log('An error occurred while connecting to socket server. Retrying');
|
||||||
reject(error);
|
reject(error);
|
||||||
});
|
});
|
||||||
resolve(connection);
|
resolve(connection);
|
||||||
});
|
}).catch((err) => {
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
// Let's retry in 4-6 seconds
|
// Let's retry in 4-6 seconds
|
||||||
return new Promise<RoomConnection>((resolve, reject) => {
|
return new Promise<RoomConnection>((resolve, reject) => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
@ -48,6 +49,15 @@ 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();
|
export const connectionManager = new ConnectionManager();
|
@ -83,9 +83,9 @@ export class RoomConnection implements RoomConnection {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
public emitPlayerDetailsMessage(characterLayersSelected: string[]) {
|
public emitPlayerDetailsMessage(userName: string, characterLayersSelected: string[]) {
|
||||||
const message = new SetPlayerDetailsMessage();
|
const message = new SetPlayerDetailsMessage();
|
||||||
message.setName(name);
|
message.setName(userName);
|
||||||
message.setCharacterlayersList(characterLayersSelected);
|
message.setCharacterlayersList(characterLayersSelected);
|
||||||
this.socket.emit(EventMessage.SET_PLAYER_DETAILS, message.serializeBinary().buffer, (id: number) => {
|
this.socket.emit(EventMessage.SET_PLAYER_DETAILS, message.serializeBinary().buffer, (id: number) => {
|
||||||
this.userId = id;
|
this.userId = id;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import {PointInterface} from "../../Connexion/Connection";
|
import {PointInterface} from "../../Connexion/ConnexionModels";
|
||||||
|
|
||||||
export interface AddPlayerInterface {
|
export interface AddPlayerInterface {
|
||||||
userId: number;
|
userId: number;
|
||||||
|
@ -4,7 +4,7 @@ import {
|
|||||||
} from "../../Connexion/ConnexionModels";
|
} from "../../Connexion/ConnexionModels";
|
||||||
import Axios from "axios";
|
import Axios from "axios";
|
||||||
import {API_URL} from "../../Enum/EnvironmentVariable";
|
import {API_URL} from "../../Enum/EnvironmentVariable";
|
||||||
import {adminDataFetchPromise} from "../../register";
|
import {connectionManager} from "../../Connexion/ConnectionManager";
|
||||||
|
|
||||||
export interface HasMovedEvent {
|
export interface HasMovedEvent {
|
||||||
direction: string;
|
direction: string;
|
||||||
@ -30,24 +30,13 @@ export class GameManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
loadStartMap() : Promise<StartMapInterface> {
|
loadStartMap() : Promise<StartMapInterface> {
|
||||||
if (adminDataFetchPromise) {
|
return connectionManager.getMapUrlStart().then(mapUrlStart => {
|
||||||
return adminDataFetchPromise.then(data => {
|
|
||||||
return {
|
return {
|
||||||
mapUrlStart: data.mapUrlStart,
|
mapUrlStart: mapUrlStart,
|
||||||
startInstance: data.startInstance,
|
startInstance: "global", //todo: is this property still usefull?
|
||||||
}
|
}
|
||||||
})
|
|
||||||
} else {
|
|
||||||
//todo: remove this call, merge with the admin workflow?
|
|
||||||
return Axios.get(`${API_URL}/start-map`)
|
|
||||||
.then((res) => {
|
|
||||||
return res.data;
|
|
||||||
}).catch((err) => {
|
|
||||||
console.error(err);
|
|
||||||
throw err;
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
getPlayerName(): string {
|
getPlayerName(): string {
|
||||||
return this.playerName;
|
return this.playerName;
|
||||||
|
@ -206,7 +206,7 @@ export class GameScene extends Phaser.Scene implements CenterListener {
|
|||||||
this.connectionPromise = connectionManager.connectToRoomSocket().then((connection : RoomConnection) => {
|
this.connectionPromise = connectionManager.connectToRoomSocket().then((connection : RoomConnection) => {
|
||||||
this.connection = connection;
|
this.connection = connection;
|
||||||
|
|
||||||
this.connection.emitPlayerDetailsMessage(gameManager.getCharacterSelected())
|
this.connection.emitPlayerDetailsMessage(gameManager.getPlayerName(), gameManager.getCharacterSelected())
|
||||||
|
|
||||||
connection.onUserJoins((message: MessageUserJoined) => {
|
connection.onUserJoins((message: MessageUserJoined) => {
|
||||||
const userMessage: AddPlayerInterface = {
|
const userMessage: AddPlayerInterface = {
|
||||||
|
Loading…
Reference in New Issue
Block a user