Merge branch 'master' of https://github.com/thecodingmachine/workadventure into feature/back-players-proximity
This commit is contained in:
commit
bb2315e7ac
12 changed files with 248 additions and 21 deletions
|
@ -1,5 +1,6 @@
|
|||
// lib/app.ts
|
||||
import {IoSocketController} from "./Controller/IoSocketController";
|
||||
import {IoSocketController} from "./Controller/IoSocketController"; //TODO fix impot by "_Controller/..."
|
||||
import {AuthenticateController} from "./Controller/AuthenticateController"; //TODO fix impot by "_Controller/..."
|
||||
import express from "express";
|
||||
import {Application} from 'express';
|
||||
import bodyParser = require('body-parser');
|
||||
|
@ -9,14 +10,21 @@ class App {
|
|||
public app: Application;
|
||||
public server: http.Server;
|
||||
public ioSocketController: IoSocketController;
|
||||
public authenticateController: AuthenticateController;
|
||||
|
||||
constructor() {
|
||||
this.app = express();
|
||||
|
||||
//config server http
|
||||
this.config();
|
||||
this.server = http.createServer(this.app);
|
||||
|
||||
//create controllers
|
||||
this.ioSocketController = new IoSocketController(this.server);
|
||||
this.authenticateController = new AuthenticateController(this.app);
|
||||
}
|
||||
|
||||
// TODO add session user
|
||||
private config(): void {
|
||||
this.app.use(bodyParser.json());
|
||||
this.app.use(bodyParser.urlencoded({extended: false}));
|
||||
|
|
28
back/src/Controller/AuthenticateController.ts
Normal file
28
back/src/Controller/AuthenticateController.ts
Normal file
|
@ -0,0 +1,28 @@
|
|||
import {Application, Request, Response} from "express";
|
||||
import Jwt, {JsonWebTokenError} from "jsonwebtoken";
|
||||
import {BAD_REQUEST, OK} from "http-status-codes";
|
||||
import {SECRET_KEY} from "../Enum/EnvironmentVariable";
|
||||
|
||||
export class AuthenticateController{
|
||||
App : Application;
|
||||
|
||||
constructor(App : Application) {
|
||||
this.App = App;
|
||||
this.login();
|
||||
}
|
||||
|
||||
//permit to login on application. Return token to connect on Websocket IO.
|
||||
login(){
|
||||
this.App.post("/login", (req: Request, res: Response) => {
|
||||
let param = req.body;
|
||||
if(!param.email){
|
||||
return res.status(BAD_REQUEST).send({
|
||||
message: "email parameter is empty"
|
||||
});
|
||||
}
|
||||
//TODO check user email for The Coding Machine game
|
||||
let token = Jwt.sign({email: param.email}, SECRET_KEY, {expiresIn: '24h'});
|
||||
return res.status(OK).send({token: token});
|
||||
});
|
||||
}
|
||||
}
|
|
@ -1,36 +1,80 @@
|
|||
import socketIO = require('socket.io');
|
||||
import {Socket} from "socket.io";
|
||||
import * as http from "http";
|
||||
import {MessageUserPosition} from "@Model/Websocket/MessageUserPosition";
|
||||
import {MessageUserPosition} from "../Model/Websocket/MessageUserPosition"; //TODO fix import by "_Model/.."
|
||||
import {ExSocketInterface} from "../Model/Websocket/ExSocketInterface"; //TODO fix import by "_Model/.."
|
||||
import Jwt, {JsonWebTokenError} from "jsonwebtoken";
|
||||
import {SECRET_KEY} from "../Enum/EnvironmentVariable"; //TODO fix import by "_Enum/..."
|
||||
|
||||
export class IoSocketController{
|
||||
Io: socketIO.Server;
|
||||
constructor(server : http.Server) {
|
||||
this.Io = socketIO(server);
|
||||
|
||||
// Authentication with token. it will be decoded and stored in the socket.
|
||||
this.Io.use( (socket: Socket, next) => {
|
||||
if (!socket.handshake.query || !socket.handshake.query.token) {
|
||||
return next(new Error('Authentication error'));
|
||||
}
|
||||
Jwt.verify(socket.handshake.query.token, SECRET_KEY, (err: JsonWebTokenError, tokenDecoded: object) => {
|
||||
if (err) {
|
||||
return next(new Error('Authentication error'));
|
||||
}
|
||||
(socket as ExSocketInterface).token = tokenDecoded;
|
||||
next();
|
||||
});
|
||||
});
|
||||
|
||||
this.ioConnection();
|
||||
}
|
||||
|
||||
ioConnection() {
|
||||
this.Io.on('connection', (socket: Socket) => {
|
||||
//TODO check token access
|
||||
|
||||
/*join-rom event permit to join one room.
|
||||
message :
|
||||
userId : user identification
|
||||
roomId: room identification
|
||||
positionXUser: user x position map
|
||||
positionYUser: user y position on map
|
||||
position: position of user in map
|
||||
x: user x position on map
|
||||
y: user y position on map
|
||||
*/
|
||||
socket.on('join-room', (message : MessageUserPosition) => {
|
||||
socket.join(message.roomId);
|
||||
|
||||
socket.on('join-room', (message : string) => {
|
||||
let messageUserPosition = this.hydrateMessageReceive(message);
|
||||
if(messageUserPosition instanceof Error){
|
||||
return socket.emit("message-error", JSON.stringify({message: messageUserPosition.message}))
|
||||
}
|
||||
//join user in room
|
||||
socket.join(messageUserPosition.roomId);
|
||||
// sending to all clients in room except sender
|
||||
socket.to(message.roomId).emit('join-room', message.toString());
|
||||
this.saveUserPosition((socket as ExSocketInterface), messageUserPosition);
|
||||
socket.to(messageUserPosition.roomId).emit('join-room', messageUserPosition.toString());
|
||||
});
|
||||
|
||||
socket.on('user-position', (message : MessageUserPosition) => {
|
||||
socket.on('user-position', (message : string) => {
|
||||
let messageUserPosition = this.hydrateMessageReceive(message);
|
||||
if(messageUserPosition instanceof Error){
|
||||
return socket.emit("message-error", JSON.stringify({message: messageUserPosition.message}));
|
||||
}
|
||||
// sending to all clients in room except sender
|
||||
socket.to(message.roomId).emit('join-room', message.toString());
|
||||
this.saveUserPosition((socket as ExSocketInterface), messageUserPosition);
|
||||
socket.to(messageUserPosition.roomId).emit('join-room', messageUserPosition.toString());
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
//permit to save user position in socket
|
||||
saveUserPosition(socket : ExSocketInterface, message : MessageUserPosition){
|
||||
socket.position = message.position;
|
||||
}
|
||||
|
||||
//Hydrate and manage error
|
||||
hydrateMessageReceive(message : string) : MessageUserPosition | Error{
|
||||
try {
|
||||
return new MessageUserPosition(message);
|
||||
}catch (err) {
|
||||
//TODO log error
|
||||
return new Error(err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
5
back/src/Enum/EnvironmentVariable.ts
Normal file
5
back/src/Enum/EnvironmentVariable.ts
Normal file
|
@ -0,0 +1,5 @@
|
|||
const SECRET_KEY = process.env.SECRET_KEY || "THECODINGMACHINE_SECRET_KEY";
|
||||
|
||||
export {
|
||||
SECRET_KEY
|
||||
}
|
7
back/src/Model/Websocket/ExSocketInterface.ts
Normal file
7
back/src/Model/Websocket/ExSocketInterface.ts
Normal file
|
@ -0,0 +1,7 @@
|
|||
import {Socket} from "socket.io";
|
||||
import {PointInterface} from "./PointInterface";
|
||||
|
||||
export interface ExSocketInterface extends Socket {
|
||||
token: object;
|
||||
position: PointInterface;
|
||||
}
|
|
@ -4,6 +4,9 @@ export class Message {
|
|||
|
||||
constructor(message: string) {
|
||||
let data = JSON.parse(message);
|
||||
if(!data.userId || !data.roomId){
|
||||
throw Error("userId and roomId cannot be null");
|
||||
}
|
||||
this.userId = data.userId;
|
||||
this.roomId = data.roomId;
|
||||
}
|
||||
|
|
|
@ -1,14 +1,33 @@
|
|||
import {Message} from "./Message";
|
||||
import {PointInterface} from "./PointInterface";
|
||||
|
||||
export class Point implements PointInterface{
|
||||
x: number;
|
||||
y: number;
|
||||
|
||||
constructor(x : number, y : number) {
|
||||
if(!x || !y){
|
||||
throw Error("position x and y cannot be null");
|
||||
}
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
toJson(){
|
||||
return {
|
||||
x : this.x,
|
||||
y: this.y
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export class MessageUserPosition extends Message{
|
||||
positionXUser: string;
|
||||
positionYUser: string;
|
||||
position: PointInterface
|
||||
|
||||
constructor(message: string) {
|
||||
super(message);
|
||||
let data = JSON.parse(message);
|
||||
this.positionXUser = data.positionXUser;
|
||||
this.positionYUser = data.positionYUser;
|
||||
this.position = new Point(data.position.x, data.position.y);
|
||||
}
|
||||
|
||||
toString() {
|
||||
|
@ -16,8 +35,7 @@ export class MessageUserPosition extends Message{
|
|||
Object.assign(
|
||||
super.toJson(),
|
||||
{
|
||||
positionXUser: this.positionXUser,
|
||||
positionYUser: this.positionYUser
|
||||
position: this.position.toJson()
|
||||
})
|
||||
);
|
||||
}
|
||||
|
|
5
back/src/Model/Websocket/PointInterface.ts
Normal file
5
back/src/Model/Websocket/PointInterface.ts
Normal file
|
@ -0,0 +1,5 @@
|
|||
export interface PointInterface {
|
||||
x: number;
|
||||
y: number;
|
||||
toJson() : object;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue