some fixes
This commit is contained in:
parent
4af46b1b3f
commit
5e54fc2c26
@ -1,9 +1,9 @@
|
|||||||
import Jwt from "jsonwebtoken";
|
import {URL_ROOM_STARTED} from "../Enum/EnvironmentVariable"; //TODO fix import by "_Enum/..."
|
||||||
import {ADMIN_API_TOKEN, ADMIN_API_URL, SECRET_KEY, URL_ROOM_STARTED} from "../Enum/EnvironmentVariable"; //TODO fix import by "_Enum/..."
|
|
||||||
import { uuid } from 'uuidv4';
|
import { uuid } from 'uuidv4';
|
||||||
import {HttpRequest, HttpResponse, TemplatedApp} from "uWebSockets.js";
|
import {HttpRequest, HttpResponse, TemplatedApp} from "uWebSockets.js";
|
||||||
import {BaseController} from "./BaseController";
|
import {BaseController} from "./BaseController";
|
||||||
import {adminApi, AdminApiData} from "../Services/AdminApi";
|
import {adminApi, AdminApiData} from "../Services/AdminApi";
|
||||||
|
import {jwtTokenManager} from "../Services/JWTTokenManager";
|
||||||
|
|
||||||
export interface TokenInterface {
|
export interface TokenInterface {
|
||||||
userUuid: string
|
userUuid: string
|
||||||
@ -59,7 +59,7 @@ export class AuthenticateController extends BaseController {
|
|||||||
newUrl = '_/global/'+mapUrlStart;
|
newUrl = '_/global/'+mapUrlStart;
|
||||||
}
|
}
|
||||||
|
|
||||||
const authToken = Jwt.sign({userUuid: userUuid}, SECRET_KEY, {expiresIn: '24h'});
|
const authToken = jwtTokenManager.createJWTToken(userUuid);
|
||||||
res.writeStatus("200 OK").end(JSON.stringify({
|
res.writeStatus("200 OK").end(JSON.stringify({
|
||||||
authToken,
|
authToken,
|
||||||
userUuid,
|
userUuid,
|
||||||
|
@ -1,14 +1,11 @@
|
|||||||
import {ExSocketInterface} from "../Model/Websocket/ExSocketInterface"; //TODO fix import by "_Model/.."
|
import {ExSocketInterface} from "../Model/Websocket/ExSocketInterface"; //TODO fix import by "_Model/.."
|
||||||
import Jwt from "jsonwebtoken";
|
import {MINIMUM_DISTANCE, GROUP_RADIUS} from "../Enum/EnvironmentVariable"; //TODO fix import by "_Enum/..."
|
||||||
import {SECRET_KEY, MINIMUM_DISTANCE, GROUP_RADIUS, ALLOW_ARTILLERY} from "../Enum/EnvironmentVariable"; //TODO fix import by "_Enum/..."
|
|
||||||
import {GameRoom} from "../Model/GameRoom";
|
import {GameRoom} from "../Model/GameRoom";
|
||||||
import {Group} from "../Model/Group";
|
import {Group} from "../Model/Group";
|
||||||
import {User} from "../Model/User";
|
import {User} from "../Model/User";
|
||||||
import {isSetPlayerDetailsMessage,} from "../Model/Websocket/SetPlayerDetailsMessage";
|
import {isSetPlayerDetailsMessage,} from "../Model/Websocket/SetPlayerDetailsMessage";
|
||||||
import {Gauge} from "prom-client";
|
import {Gauge} from "prom-client";
|
||||||
import {TokenInterface} from "../Controller/AuthenticateController";
|
|
||||||
import {PointInterface} from "../Model/Websocket/PointInterface";
|
import {PointInterface} from "../Model/Websocket/PointInterface";
|
||||||
import {uuid} from 'uuidv4';
|
|
||||||
import {Movable} from "../Model/Movable";
|
import {Movable} from "../Model/Movable";
|
||||||
import {
|
import {
|
||||||
PositionMessage,
|
PositionMessage,
|
||||||
@ -43,6 +40,8 @@ import {TemplatedApp} from "uWebSockets.js"
|
|||||||
import {parse} from "query-string";
|
import {parse} from "query-string";
|
||||||
import {cpuTracker} from "../Services/CpuTracker";
|
import {cpuTracker} from "../Services/CpuTracker";
|
||||||
import {ViewportInterface} from "../Model/Websocket/ViewportMessage";
|
import {ViewportInterface} from "../Model/Websocket/ViewportMessage";
|
||||||
|
import {jwtTokenManager} from "../Services/JWTTokenManager";
|
||||||
|
import {adminApi} from "../Services/AdminApi";
|
||||||
|
|
||||||
function emitInBatch(socket: ExSocketInterface, payload: SubMessage): void {
|
function emitInBatch(socket: ExSocketInterface, payload: SubMessage): void {
|
||||||
socket.batchedMessages.addPayload(payload);
|
socket.batchedMessages.addPayload(payload);
|
||||||
@ -86,54 +85,7 @@ export class IoSocketController {
|
|||||||
this.ioConnection();
|
this.ioConnection();
|
||||||
}
|
}
|
||||||
|
|
||||||
private isValidToken(token: object): token is TokenInterface {
|
|
||||||
if (typeof((token as TokenInterface).userUuid) !== 'string') {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private async getUserUuidFromToken(token: unknown): Promise<string> {
|
|
||||||
|
|
||||||
if (!token) {
|
|
||||||
throw new Error('An authentication error happened, a user tried to connect without a token.');
|
|
||||||
}
|
|
||||||
if (typeof(token) !== "string") {
|
|
||||||
throw new Error('Token is expected to be a string');
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if(token === 'test') {
|
|
||||||
if (ALLOW_ARTILLERY) {
|
|
||||||
return uuid();
|
|
||||||
} else {
|
|
||||||
throw new Error("In order to perform a load-testing test on this environment, you must set the ALLOW_ARTILLERY environment variable to 'true'");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return new Promise<string>((resolve, reject) => {
|
|
||||||
Jwt.verify(token, SECRET_KEY, {},(err, tokenDecoded) => {
|
|
||||||
const tokenInterface = tokenDecoded as TokenInterface;
|
|
||||||
if (err) {
|
|
||||||
console.error('An authentication error happened, invalid JsonWebToken.', err);
|
|
||||||
reject(new Error('An authentication error happened, invalid JsonWebToken. '+err.message));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (tokenDecoded === undefined) {
|
|
||||||
console.error('Empty token found.');
|
|
||||||
reject(new Error('Empty token found.'));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!this.isValidToken(tokenInterface)) {
|
|
||||||
reject(new Error('Authentication error, invalid token structure.'));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
resolve(tokenInterface.userUuid);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
ioConnection() {
|
ioConnection() {
|
||||||
this.app.ws('/room/*', {
|
this.app.ws('/room/*', {
|
||||||
@ -181,7 +133,12 @@ export class IoSocketController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const userUuid = await this.getUserUuidFromToken(token);
|
const userUuid = await jwtTokenManager.getUserUuidFromToken(token);
|
||||||
|
|
||||||
|
const isGranted = await adminApi.memberIsGrantedAccessToRoom(userUuid, roomId);
|
||||||
|
if (!isGranted) {
|
||||||
|
throw Error('Client cannot acces this ressource.');
|
||||||
|
}
|
||||||
|
|
||||||
if (upgradeAborted.aborted) {
|
if (upgradeAborted.aborted) {
|
||||||
console.log("Ouch! Client disconnected before we could upgrade it!");
|
console.log("Ouch! Client disconnected before we could upgrade it!");
|
||||||
@ -256,11 +213,6 @@ export class IoSocketController {
|
|||||||
// Let's join the room
|
// Let's join the room
|
||||||
this.handleJoinRoom(client, client.roomId, client.position, client.viewport, client.name, client.characterLayers);
|
this.handleJoinRoom(client, client.roomId, client.position, client.viewport, client.name, client.characterLayers);
|
||||||
|
|
||||||
/*const isGranted = await adminApi.memberIsGrantedAccessToRoom(client.userUuid, roomId);
|
|
||||||
if (!isGranted) {
|
|
||||||
throw Error('Client cannot acces this ressource.');
|
|
||||||
}*/
|
|
||||||
|
|
||||||
const setUserIdMessage = new SetUserIdMessage();
|
const setUserIdMessage = new SetUserIdMessage();
|
||||||
setUserIdMessage.setUserid(client.userId);
|
setUserIdMessage.setUserid(client.userId);
|
||||||
|
|
||||||
|
60
back/src/Services/JWTTokenManager.ts
Normal file
60
back/src/Services/JWTTokenManager.ts
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
import {ALLOW_ARTILLERY, SECRET_KEY} from "../Enum/EnvironmentVariable";
|
||||||
|
import {uuid} from "uuidv4";
|
||||||
|
import Jwt from "jsonwebtoken";
|
||||||
|
import {TokenInterface} from "../Controller/AuthenticateController";
|
||||||
|
|
||||||
|
class JWTTokenManager {
|
||||||
|
|
||||||
|
public createJWTToken(userUuid: string) {
|
||||||
|
return Jwt.sign({userUuid: userUuid}, SECRET_KEY, {expiresIn: '24h'});
|
||||||
|
}
|
||||||
|
|
||||||
|
public async getUserUuidFromToken(token: unknown): Promise<string> {
|
||||||
|
|
||||||
|
if (!token) {
|
||||||
|
throw new Error('An authentication error happened, a user tried to connect without a token.');
|
||||||
|
}
|
||||||
|
if (typeof(token) !== "string") {
|
||||||
|
throw new Error('Token is expected to be a string');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if(token === 'test') {
|
||||||
|
if (ALLOW_ARTILLERY) {
|
||||||
|
return uuid();
|
||||||
|
} else {
|
||||||
|
throw new Error("In order to perform a load-testing test on this environment, you must set the ALLOW_ARTILLERY environment variable to 'true'");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Promise<string>((resolve, reject) => {
|
||||||
|
Jwt.verify(token, SECRET_KEY, {},(err, tokenDecoded) => {
|
||||||
|
const tokenInterface = tokenDecoded as TokenInterface;
|
||||||
|
if (err) {
|
||||||
|
console.error('An authentication error happened, invalid JsonWebToken.', err);
|
||||||
|
reject(new Error('An authentication error happened, invalid JsonWebToken. '+err.message));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (tokenDecoded === undefined) {
|
||||||
|
console.error('Empty token found.');
|
||||||
|
reject(new Error('Empty token found.'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.isValidToken(tokenInterface)) {
|
||||||
|
reject(new Error('Authentication error, invalid token structure.'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
resolve(tokenInterface.userUuid);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private isValidToken(token: object): token is TokenInterface {
|
||||||
|
return !(typeof((token as TokenInterface).userUuid) !== 'string');
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export const jwtTokenManager = new JWTTokenManager();
|
@ -48,7 +48,7 @@ class ConnectionManager {
|
|||||||
|
|
||||||
public connectToRoomSocket(roomId: string, name: string, characterLayers: string[], position: PositionInterface, viewport: ViewportInterface): Promise<RoomConnection> {
|
public connectToRoomSocket(roomId: string, name: string, characterLayers: string[], position: PositionInterface, viewport: ViewportInterface): Promise<RoomConnection> {
|
||||||
return new Promise<RoomConnection>((resolve, reject) => {
|
return new Promise<RoomConnection>((resolve, reject) => {
|
||||||
const connection = new RoomConnection(this.authToken as string, roomId, name, characterLayers, position, viewport);
|
const connection = new RoomConnection(this.authToken, roomId, name, characterLayers, position, viewport);
|
||||||
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);
|
||||||
|
@ -53,10 +53,10 @@ export class RoomConnection implements RoomConnection {
|
|||||||
* @param token A JWT token containing the UUID of the user
|
* @param token A JWT token containing the UUID of the user
|
||||||
* @param roomId The ID of the room in the form "_/[instance]/[map_url]" or "@/[org]/[event]/[map]"
|
* @param roomId The ID of the room in the form "_/[instance]/[map_url]" or "@/[org]/[event]/[map]"
|
||||||
*/
|
*/
|
||||||
public constructor(token: string, roomId: string, name: string, characterLayers: string[], position: PositionInterface, viewport: ViewportInterface) {
|
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://');
|
let url = API_URL.replace('http://', 'ws://').replace('https://', 'wss://');
|
||||||
url += '/room/'+roomId
|
url += '/room/'+roomId
|
||||||
url += '?token='+encodeURIComponent(token);
|
url += '?token='+(token ?encodeURIComponent(token):'');
|
||||||
url += '&name='+encodeURIComponent(name);
|
url += '&name='+encodeURIComponent(name);
|
||||||
for (let layer of characterLayers) {
|
for (let layer of characterLayers) {
|
||||||
url += '&characterLayers='+encodeURIComponent(layer);
|
url += '&characterLayers='+encodeURIComponent(layer);
|
||||||
|
@ -1,6 +0,0 @@
|
|||||||
export class GameSceneDescriptor {
|
|
||||||
|
|
||||||
constructor(MapKey : string, MapUrlFile: string, instance: string, key: string) {
|
|
||||||
this.roomId = '';//
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user