* 'develop' of https://github.com/thecodingmachine/workadventure:
  Trying to enable back connection on admin from develop, knowing that the develop certificate is broken. Fixing priority.
  Trying to enable back connection on admin from develop, knowing that the develop certificate is broken
  Revert "Adding back admin in develop branch CI"
  Adding back admin in develop branch CI
  Fixing GA tag not included in play domain
  FEATURE: better implementation of the admin global message
  Fix ci
  Update private access
  Allow URLs relative to map base in iframe / openWebsite

# Conflicts:
#	front/src/Phaser/Game/GameScene.ts
This commit is contained in:
DESKTOP-FMM8UI0\CLV 2021-03-09 13:57:05 +01:00
commit b175b7164d
23 changed files with 227 additions and 337 deletions

View File

@ -1,5 +1,4 @@
import {HttpRequest, HttpResponse} from "uWebSockets.js"; import {HttpResponse} from "uWebSockets.js";
import {ADMIN_API_TOKEN} from "../Enum/EnvironmentVariable";
export class BaseController { export class BaseController {

View File

@ -4,7 +4,6 @@ import {HttpRequest, HttpResponse} from "uWebSockets.js";
import { parse } from 'query-string'; import { parse } from 'query-string';
import {App} from "../Server/sifrr.server"; import {App} from "../Server/sifrr.server";
import {socketManager} from "../Services/SocketManager"; import {socketManager} from "../Services/SocketManager";
import {ServerWritableStream} from "grpc";
export class DebugController { export class DebugController {
constructor(private App : App) { constructor(private App : App) {

View File

@ -2,7 +2,8 @@ import {IRoomManagerServer} from "./Messages/generated/messages_grpc_pb";
import { import {
AdminGlobalMessage, AdminGlobalMessage,
AdminMessage, AdminMessage,
AdminPusherToBackMessage, AdminPusherToBackMessage,
AdminRoomMessage,
BanMessage, BanMessage,
EmptyMessage, EmptyMessage,
ItemEventMessage, ItemEventMessage,
@ -51,12 +52,8 @@ const roomManager: IRoomManagerServer = {
} else { } else {
if (message.hasJoinroommessage()) { if (message.hasJoinroommessage()) {
throw new Error('Cannot call JoinRoomMessage twice!'); throw new Error('Cannot call JoinRoomMessage twice!');
/*} else if (message.hasViewportmessage()) {
socketManager.handleViewport(client, message.getViewportmessage() as ViewportMessage);*/
} else if (message.hasUsermovesmessage()) { } else if (message.hasUsermovesmessage()) {
socketManager.handleUserMovesMessage(room, user, message.getUsermovesmessage() as UserMovesMessage); socketManager.handleUserMovesMessage(room, user, message.getUsermovesmessage() as UserMovesMessage);
/*} else if (message.hasSetplayerdetailsmessage()) {
socketManager.handleSetPlayerDetails(client, message.getSetplayerdetailsmessage() as SetPlayerDetailsMessage);*/
} else if (message.hasSilentmessage()) { } else if (message.hasSilentmessage()) {
socketManager.handleSilentMessage(room, user, message.getSilentmessage() as SilentMessage); socketManager.handleSilentMessage(room, user, message.getSilentmessage() as SilentMessage);
} else if (message.hasItemeventmessage()) { } else if (message.hasItemeventmessage()) {
@ -67,8 +64,6 @@ const roomManager: IRoomManagerServer = {
socketManager.emitScreenSharing(room, user, message.getWebrtcscreensharingsignaltoservermessage() as WebRtcSignalToServerMessage); socketManager.emitScreenSharing(room, user, message.getWebrtcscreensharingsignaltoservermessage() as WebRtcSignalToServerMessage);
} else if (message.hasPlayglobalmessage()) { } else if (message.hasPlayglobalmessage()) {
socketManager.emitPlayGlobalMessage(room, message.getPlayglobalmessage() as PlayGlobalMessage); socketManager.emitPlayGlobalMessage(room, message.getPlayglobalmessage() as PlayGlobalMessage);
/*} else if (message.hasReportplayermessage()){
socketManager.handleReportMessage(client, message.getReportplayermessage() as ReportPlayerMessage);*/
} else if (message.hasQueryjitsijwtmessage()){ } else if (message.hasQueryjitsijwtmessage()){
socketManager.handleQueryJitsiJwtMessage(user, message.getQueryjitsijwtmessage() as QueryJitsiJwtMessage); socketManager.handleQueryJitsiJwtMessage(user, message.getQueryjitsijwtmessage() as QueryJitsiJwtMessage);
}else if (message.hasSendusermessage()) { }else if (message.hasSendusermessage()) {
@ -119,10 +114,7 @@ const roomManager: IRoomManagerServer = {
socketManager.removeZoneListener(call, zoneMessage.getRoomid(), zoneMessage.getX(), zoneMessage.getY()); socketManager.removeZoneListener(call, zoneMessage.getRoomid(), zoneMessage.getX(), zoneMessage.getY());
call.end(); call.end();
}) })
/*call.on('finish', () => {
debug('listenZone finish');
})*/
call.on('close', () => { call.on('close', () => {
debug('listenZone connection closed'); debug('listenZone connection closed');
socketManager.removeZoneListener(call, zoneMessage.getRoomid(), zoneMessage.getX(), zoneMessage.getY()); socketManager.removeZoneListener(call, zoneMessage.getRoomid(), zoneMessage.getX(), zoneMessage.getY());
@ -150,26 +142,6 @@ const roomManager: IRoomManagerServer = {
} else { } else {
throw new Error('The first message sent MUST be of type JoinRoomMessage'); throw new Error('The first message sent MUST be of type JoinRoomMessage');
} }
} else {
/*if (message.hasJoinroommessage()) {
throw new Error('Cannot call JoinRoomMessage twice!');
} else if (message.hasUsermovesmessage()) {
socketManager.handleUserMovesMessage(room, user, message.getUsermovesmessage() as UserMovesMessage);
} else if (message.hasSilentmessage()) {
socketManager.handleSilentMessage(room, user, message.getSilentmessage() as SilentMessage);
} else if (message.hasItemeventmessage()) {
socketManager.handleItemEvent(room, user, message.getItemeventmessage() as ItemEventMessage);
} else if (message.hasWebrtcsignaltoservermessage()) {
socketManager.emitVideo(room, user, message.getWebrtcsignaltoservermessage() as WebRtcSignalToServerMessage);
} else if (message.hasWebrtcscreensharingsignaltoservermessage()) {
socketManager.emitScreenSharing(room, user, message.getWebrtcscreensharingsignaltoservermessage() as WebRtcSignalToServerMessage);
} else if (message.hasPlayglobalmessage()) {
socketManager.emitPlayGlobalMessage(room, message.getPlayglobalmessage() as PlayGlobalMessage);
} else if (message.hasQueryjitsijwtmessage()){
socketManager.handleQueryJitsiJwtMessage(user, message.getQueryjitsijwtmessage() as QueryJitsiJwtMessage);
} else {
throw new Error('Unhandled message type');
}*/
} }
} catch (e) { } catch (e) {
emitError(call, e); emitError(call, e);
@ -208,6 +180,10 @@ const roomManager: IRoomManagerServer = {
callback(null, new EmptyMessage()); callback(null, new EmptyMessage());
}, },
sendAdminMessageToRoom(call: ServerUnaryCall<AdminRoomMessage>, callback: sendUnaryData<EmptyMessage>): void {
socketManager.sendAdminRoomMessage(call.request.getRoomid(), call.request.getMessage());
callback(null, new EmptyMessage());
},
}; };
export {roomManager}; export {roomManager};

View File

@ -1,6 +1,5 @@
import {ADMIN_API_TOKEN, ADMIN_API_URL} from "../Enum/EnvironmentVariable"; import {ADMIN_API_TOKEN, ADMIN_API_URL} from "../Enum/EnvironmentVariable";
import Axios from "axios"; import Axios from "axios";
import {v4} from "uuid";
export interface AdminApiData { export interface AdminApiData {
organizationSlug: string organizationSlug: string
@ -21,13 +20,6 @@ export interface CharacterTexture {
rights: string rights: string
} }
export interface FetchMemberDataByUuidResponse {
uuid: string;
tags: string[];
textures: CharacterTexture[];
messages: unknown[];
}
class AdminApi { class AdminApi {
async fetchMapDetails(organizationSlug: string, worldSlug: string, roomSlug: string|undefined): Promise<AdminApiData> { async fetchMapDetails(organizationSlug: string, worldSlug: string, roomSlug: string|undefined): Promise<AdminApiData> {
@ -52,65 +44,6 @@ class AdminApi {
) )
return res.data; return res.data;
} }
async fetchMemberDataByUuid(uuid: string): Promise<FetchMemberDataByUuidResponse> {
if (!ADMIN_API_URL) {
return Promise.reject('No admin backoffice set!');
}
try {
const res = await Axios.get(ADMIN_API_URL+'/api/membership/'+uuid,
{ headers: {"Authorization" : `${ADMIN_API_TOKEN}`} }
)
return res.data;
} catch (e) {
if (e?.response?.status == 404) {
// If we get an HTTP 404, the token is invalid. Let's perform an anonymous login!
console.warn('Cannot find user with uuid "'+uuid+'". Performing an anonymous login instead.');
return {
uuid: v4(),
tags: [],
textures: [],
messages: [],
}
} else {
throw e;
}
}
}
async fetchMemberDataByToken(organizationMemberToken: string): Promise<AdminApiData> {
if (!ADMIN_API_URL) {
return Promise.reject('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.
const res = await Axios.get(ADMIN_API_URL+'/api/login-url/'+organizationMemberToken,
{ headers: {"Authorization" : `${ADMIN_API_TOKEN}`} }
)
return res.data;
}
async fetchCheckUserByToken(organizationMemberToken: string): Promise<AdminApiData> {
if (!ADMIN_API_URL) {
return Promise.reject('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.
const res = await Axios.get(ADMIN_API_URL+'/api/check-user/'+organizationMemberToken,
{ headers: {"Authorization" : `${ADMIN_API_TOKEN}`} }
)
return res.data;
}
reportPlayer(reportedUserUuid: string, reportedUserComment: string, reporterUserUuid: string, reportWorldSlug: string) {
return Axios.post(`${ADMIN_API_URL}/api/report`, {
reportedUserUuid,
reportedUserComment,
reporterUserUuid,
reportWorldSlug,
},
{
headers: {"Authorization": `${ADMIN_API_TOKEN}`}
});
}
} }
export const adminApi = new AdminApi(); export const adminApi = new AdminApi();

View File

@ -1,5 +1,4 @@
import {GameRoom} from "../Model/GameRoom"; import {GameRoom} from "../Model/GameRoom";
import {CharacterLayer} from "_Model/Websocket/CharacterLayer";
import { import {
ItemEventMessage, ItemEventMessage,
ItemStateMessage, ItemStateMessage,
@ -22,7 +21,11 @@ import {
Zone as ProtoZone, Zone as ProtoZone,
BatchToPusherMessage, BatchToPusherMessage,
SubToPusherMessage, SubToPusherMessage,
UserJoinedZoneMessage, GroupUpdateZoneMessage, GroupLeftZoneMessage, UserLeftZoneMessage, BanUserMessage UserJoinedZoneMessage,
GroupUpdateZoneMessage,
GroupLeftZoneMessage,
UserLeftZoneMessage,
BanUserMessage,
} from "../Messages/generated/messages_pb"; } from "../Messages/generated/messages_pb";
import {User, UserSocket} from "../Model/User"; import {User, UserSocket} from "../Model/User";
import {ProtobufUtils} from "../Model/Websocket/ProtobufUtils"; import {ProtobufUtils} from "../Model/Websocket/ProtobufUtils";
@ -51,18 +54,6 @@ import crypto from "crypto";
const debug = Debug('sockermanager'); const debug = Debug('sockermanager');
interface AdminSocketRoomsList {
[index: string]: number;
}
interface AdminSocketUsersList {
[index: string]: boolean;
}
export interface AdminSocketData {
rooms: AdminSocketRoomsList,
users: AdminSocketUsersList,
}
function emitZoneMessage(subMessage: SubToPusherMessage, socket: ZoneSocket): void { function emitZoneMessage(subMessage: SubToPusherMessage, socket: ZoneSocket): void {
// TODO: should we batch those every 100ms? // TODO: should we batch those every 100ms?
const batchMessage = new BatchToPusherMessage(); const batchMessage = new BatchToPusherMessage();
@ -83,68 +74,13 @@ export class SocketManager {
}); });
} }
/*getAdminSocketDataFor(roomId:string): AdminSocketData {
const data:AdminSocketData = {
rooms: {},
users: {},
}
const room = this.rooms.get(roomId);
if (room === undefined) {
return data;
}
const users = room.getUsers();
data.rooms[roomId] = users.size;
users.forEach(user => {
data.users[user.uuid] = true
})
return data;
}*/
public async handleJoinRoom(socket: UserSocket, joinRoomMessage: JoinRoomMessage): Promise<{ room: GameRoom; user: User }> { public async handleJoinRoom(socket: UserSocket, joinRoomMessage: JoinRoomMessage): Promise<{ room: GameRoom; user: User }> {
/*const positionMessage = joinRoomMessage.getPositionmessage();
if (positionMessage === undefined) {
// TODO: send error message?
throw new Error('Empty pointMessage found in JoinRoomMessage');
}*/
//const position = ProtobufUtils.toPointInterface(positionMessage);
//const viewport = client.viewport;
//this.sockets.set(client.userId, client); //todo: should this be at the end of the function?
//join new previous room //join new previous room
const {room, user} = await this.joinRoom(socket, joinRoomMessage); const {room, user} = await this.joinRoom(socket, joinRoomMessage);
//const things = room.setViewport(client, viewport);
const roomJoinedMessage = new RoomJoinedMessage(); const roomJoinedMessage = new RoomJoinedMessage();
roomJoinedMessage.setTagList(joinRoomMessage.getTagList()); roomJoinedMessage.setTagList(joinRoomMessage.getTagList());
/*for (const thing of things) {
if (thing instanceof User) {
const player: ExSocketInterface|undefined = this.sockets.get(thing.id);
if (player === undefined) {
console.warn('Something went wrong. The World contains a user "'+thing.id+"' but this user does not exist in the sockets list!");
continue;
}
const userJoinedMessage = new UserJoinedMessage();
userJoinedMessage.setUserid(thing.id);
userJoinedMessage.setName(player.name);
userJoinedMessage.setCharacterlayersList(ProtobufUtils.toCharacterLayerMessages(player.characterLayers));
userJoinedMessage.setPosition(ProtobufUtils.toPositionMessage(player.position));
roomJoinedMessage.addUser(userJoinedMessage);
roomJoinedMessage.setTagList(joinRoomMessage.getTagList());
} else if (thing instanceof Group) {
const groupUpdateMessage = new GroupUpdateMessage();
groupUpdateMessage.setGroupid(thing.getId());
groupUpdateMessage.setPosition(ProtobufUtils.toPointMessage(thing.getPosition()));
roomJoinedMessage.addGroup(groupUpdateMessage);
} else {
console.error("Unexpected type for Movable returned by setViewport");
}
}*/
for (const [itemId, item] of room.getItemsState().entries()) { for (const [itemId, item] of room.getItemsState().entries()) {
const itemStateMessage = new ItemStateMessage(); const itemStateMessage = new ItemStateMessage();
@ -158,8 +94,6 @@ export class SocketManager {
const serverToClientMessage = new ServerToClientMessage(); const serverToClientMessage = new ServerToClientMessage();
serverToClientMessage.setRoomjoinedmessage(roomJoinedMessage); serverToClientMessage.setRoomjoinedmessage(roomJoinedMessage);
//user.socket.write(serverToClientMessage);
console.log('SENDING MESSAGE roomJoinedMessage'); console.log('SENDING MESSAGE roomJoinedMessage');
socket.write(serverToClientMessage); socket.write(serverToClientMessage);
@ -168,13 +102,6 @@ export class SocketManager {
user user
}; };
/*const serverToClientMessage = new ServerToClientMessage();
serverToClientMessage.setRoomjoinedmessage(roomJoinedMessage);
if (!client.disconnecting) {
client.send(serverToClientMessage.serializeBinary().buffer, true);
}*/
} }
handleUserMovesMessage(room: GameRoom, user: User, userMovesMessage: UserMovesMessage) { handleUserMovesMessage(room: GameRoom, user: User, userMovesMessage: UserMovesMessage) {
@ -693,33 +620,6 @@ export class SocketManager {
}, 10000); }, 10000);
} }
/**
* Merges the characterLayers received from the front (as an array of string) with the custom textures from the back.
*/
static mergeCharacterLayersAndCustomTextures(characterLayers: string[], memberTextures: CharacterTexture[]): CharacterLayer[] {
const characterLayerObjs: CharacterLayer[] = [];
for (const characterLayer of characterLayers) {
if (characterLayer.startsWith('customCharacterTexture')) {
const customCharacterLayerId: number = +characterLayer.substr(22);
for (const memberTexture of memberTextures) {
if (memberTexture.id == customCharacterLayerId) {
characterLayerObjs.push({
name: characterLayer,
url: memberTexture.url
})
break;
}
}
} else {
characterLayerObjs.push({
name: characterLayer,
url: undefined
})
}
}
return characterLayerObjs;
}
public addZoneListener(call: ZoneSocket, roomId: string, x: number, y: number): void { public addZoneListener(call: ZoneSocket, roomId: string, x: number, y: number): void {
const room = this.rooms.get(roomId); const room = this.rooms.get(roomId);
if (!room) { if (!room) {
@ -773,11 +673,6 @@ export class SocketManager {
public async handleJoinAdminRoom(admin: Admin, roomId: string): Promise<GameRoom> { public async handleJoinAdminRoom(admin: Admin, roomId: string): Promise<GameRoom> {
const room = await socketManager.getOrCreateRoom(roomId); const room = await socketManager.getOrCreateRoom(roomId);
// Dispatch groups position to newly connected user
/*world.getGroups().forEach((group: Group) => {
this.emitCreateUpdateGroupEvent(socket, group);
});*/
room.adminJoin(admin); room.adminJoin(admin);
return room; return room;
@ -807,7 +702,7 @@ export class SocketManager {
const sendUserMessage = new SendUserMessage(); const sendUserMessage = new SendUserMessage();
sendUserMessage.setMessage(message); sendUserMessage.setMessage(message);
sendUserMessage.setType('ban'); sendUserMessage.setType('ban'); //todo: is the type correct?
const subToPusherMessage = new SubToPusherMessage(); const subToPusherMessage = new SubToPusherMessage();
subToPusherMessage.setSendusermessage(sendUserMessage); subToPusherMessage.setSendusermessage(sendUserMessage);
@ -843,6 +738,27 @@ export class SocketManager {
// Let's close the connection when the user is banned. // Let's close the connection when the user is banned.
recipient.socket.end(); recipient.socket.end();
} }
sendAdminRoomMessage(roomId: string, message: string) {
const room = this.rooms.get(roomId);
if (!room) {
//todo: this should cause the http call to return a 500
console.error("In sendAdminRoomMessage, could not find room with id '" + roomId + "'. Maybe the room was closed a few milliseconds ago and there was a race condition?");
return;
}
room.getUsers().forEach((recipient) => {
const sendUserMessage = new SendUserMessage();
sendUserMessage.setMessage(message);
sendUserMessage.setType('message');
const clientMessage = new ServerToClientMessage();
clientMessage.setSendusermessage(sendUserMessage);
recipient.socket.write(clientMessage);
});
}
} }
export const socketManager = new SocketManager(); export const socketManager = new SocketManager();

View File

@ -4,7 +4,7 @@
local tag = namespace, local tag = namespace,
local url = if namespace == "master" then "workadventu.re" else namespace+".workadventure.test.thecodingmachine.com", local url = if namespace == "master" then "workadventu.re" else namespace+".workadventure.test.thecodingmachine.com",
// develop branch does not use admin because of issue with SSL certificate of admin as of now. // develop branch does not use admin because of issue with SSL certificate of admin as of now.
local adminUrl = if namespace == "master" /*|| namespace == "develop"*/ || std.startsWith(namespace, "admin") then "https://"+url else null, local adminUrl = if namespace == "master" || namespace == "develop" || std.startsWith(namespace, "admin") then "https://"+url else null,
"$schema": "https://raw.githubusercontent.com/thecodingmachine/deeployer/master/deeployer.schema.json", "$schema": "https://raw.githubusercontent.com/thecodingmachine/deeployer/master/deeployer.schema.json",
"version": "1.0", "version": "1.0",
"containers": { "containers": {
@ -23,9 +23,12 @@
"JITSI_URL": env.JITSI_URL, "JITSI_URL": env.JITSI_URL,
"SECRET_JITSI_KEY": env.SECRET_JITSI_KEY, "SECRET_JITSI_KEY": env.SECRET_JITSI_KEY,
"TURN_STATIC_AUTH_SECRET": env.TURN_STATIC_AUTH_SECRET, "TURN_STATIC_AUTH_SECRET": env.TURN_STATIC_AUTH_SECRET,
} + if adminUrl != null then { } + (if adminUrl != null then {
"ADMIN_API_URL": adminUrl, "ADMIN_API_URL": adminUrl,
} else {} } else {}) + if namespace != "master" then {
// Absolutely ugly WorkAround to circumvent broken certificates on the K8S test cluster. Don't do this in production kids!
"NODE_TLS_REJECT_UNAUTHORIZED": "0"
}
}, },
"back2": { "back2": {
"image": "thecodingmachine/workadventure-back:"+tag, "image": "thecodingmachine/workadventure-back:"+tag,
@ -42,9 +45,12 @@
"JITSI_URL": env.JITSI_URL, "JITSI_URL": env.JITSI_URL,
"SECRET_JITSI_KEY": env.SECRET_JITSI_KEY, "SECRET_JITSI_KEY": env.SECRET_JITSI_KEY,
"TURN_STATIC_AUTH_SECRET": env.TURN_STATIC_AUTH_SECRET, "TURN_STATIC_AUTH_SECRET": env.TURN_STATIC_AUTH_SECRET,
} + if adminUrl != null then { } + (if adminUrl != null then {
"ADMIN_API_URL": adminUrl, "ADMIN_API_URL": adminUrl,
} else {} } else {}) + if namespace != "master" then {
// Absolutely ugly WorkAround to circumvent broken certificates on the K8S test cluster. Don't do this in production kids!
"NODE_TLS_REJECT_UNAUTHORIZED": "0"
}
}, },
"pusher": { "pusher": {
"replicas": 2, "replicas": 2,
@ -61,9 +67,12 @@
"JITSI_URL": env.JITSI_URL, "JITSI_URL": env.JITSI_URL,
"API_URL": "back1:50051,back2:50051", "API_URL": "back1:50051,back2:50051",
"SECRET_JITSI_KEY": env.SECRET_JITSI_KEY, "SECRET_JITSI_KEY": env.SECRET_JITSI_KEY,
} + if adminUrl != null then { } + (if adminUrl != null then {
"ADMIN_API_URL": adminUrl, "ADMIN_API_URL": adminUrl,
} else {} } else {}) + if namespace != "master" then {
// Absolutely ugly WorkAround to circumvent broken certificates on the K8S test cluster. Don't do this in production kids!
"NODE_TLS_REJECT_UNAUTHORIZED": "0"
}
}, },
"front": { "front": {
"image": "thecodingmachine/workadventure-front:"+tag, "image": "thecodingmachine/workadventure-front:"+tag,

View File

@ -1 +1,2 @@
index.html index.html
index.tmpl.html.tmp

View File

@ -3,6 +3,7 @@ import {UserInputManager} from "../Phaser/UserInput/UserInputManager";
import {RoomConnection} from "../Connexion/RoomConnection"; import {RoomConnection} from "../Connexion/RoomConnection";
import {PlayGlobalMessageInterface} from "../Connexion/ConnexionModels"; import {PlayGlobalMessageInterface} from "../Connexion/ConnexionModels";
import {ADMIN_URL} from "../Enum/EnvironmentVariable"; import {ADMIN_URL} from "../Enum/EnvironmentVariable";
import {AdminMessageEventTypes} from "../Connexion/AdminMessagesService";
export const CLASS_CONSOLE_MESSAGE = 'main-console'; export const CLASS_CONSOLE_MESSAGE = 'main-console';
export const INPUT_CONSOLE_MESSAGE = 'input-send-text'; export const INPUT_CONSOLE_MESSAGE = 'input-send-text';
@ -10,13 +11,16 @@ export const UPLOAD_CONSOLE_MESSAGE = 'input-upload-music';
export const INPUT_TYPE_CONSOLE = 'input-type'; export const INPUT_TYPE_CONSOLE = 'input-type';
export const VIDEO_QUALITY_SELECT = 'select-video-quality'; export const VIDEO_QUALITY_SELECT = 'select-video-quality';
export const AUDIO_TYPE = 'audio'; export const AUDIO_TYPE = AdminMessageEventTypes.audio;
export const MESSAGE_TYPE = 'message'; export const MESSAGE_TYPE = AdminMessageEventTypes.admin;
interface EventTargetFiles extends EventTarget { interface EventTargetFiles extends EventTarget {
files: Array<File>; files: Array<File>;
} }
/**
* @deprecated
*/
export class ConsoleGlobalMessageManager { export class ConsoleGlobalMessageManager {
private readonly divMainConsole: HTMLDivElement; private readonly divMainConsole: HTMLDivElement;
@ -372,23 +376,6 @@ export class ConsoleGlobalMessageManager {
this.buttonSendMainConsole.classList.remove('active'); this.buttonSendMainConsole.classList.remove('active');
} }
/*activeSettingConsole(){
this.activeSetting = true;
if(this.activeMessage){
this.disabledSettingConsole();
}
this.active();
this.divSettingConsole.classList.add('active');
//this.buttonSettingsMainConsole.classList.add('active');
}
disabledSettingConsole(){
this.activeSetting = false;
this.disabled();
this.divSettingConsole.classList.remove('active');
//this.buttonSettingsMainConsole.classList.remove('active');
}*/
private getSectionId(id: string) : string { private getSectionId(id: string) : string {
return `section-${id}`; return `section-${id}`;
} }

View File

@ -1,39 +1,29 @@
import {RoomConnection} from "../Connexion/RoomConnection";
import * as TypeMessages from "./TypeMessage"; import * as TypeMessages from "./TypeMessage";
import List = Phaser.Structs.List;
import {UpdatedLocalStreamCallback} from "../WebRtc/MediaManager";
import {Banned} from "./TypeMessage"; import {Banned} from "./TypeMessage";
import {adminMessagesService} from "../Connexion/AdminMessagesService";
export interface TypeMessageInterface { export interface TypeMessageInterface {
showMessage(message: string): void; showMessage(message: string): void;
} }
export class UserMessageManager { class UserMessageManager {
typeMessages: Map<string, TypeMessageInterface> = new Map<string, TypeMessageInterface>(); typeMessages: Map<string, TypeMessageInterface> = new Map<string, TypeMessageInterface>();
receiveBannedMessageListener: Set<Function> = new Set<UpdatedLocalStreamCallback>(); receiveBannedMessageListener!: Function;
constructor(private Connection: RoomConnection) { constructor() {
const valueTypeMessageTab = Object.values(TypeMessages); const valueTypeMessageTab = Object.values(TypeMessages);
Object.keys(TypeMessages).forEach((value: string, index: number) => { Object.keys(TypeMessages).forEach((value: string, index: number) => {
const typeMessageInstance: TypeMessageInterface = (new valueTypeMessageTab[index]() as TypeMessageInterface); const typeMessageInstance: TypeMessageInterface = (new valueTypeMessageTab[index]() as TypeMessageInterface);
this.typeMessages.set(value.toLowerCase(), typeMessageInstance); this.typeMessages.set(value.toLowerCase(), typeMessageInstance);
}); });
this.initialise();
}
initialise() { adminMessagesService.messageStream.subscribe((event) => {
//receive signal to show message const typeMessage = this.showMessage(event.type, event.text);
this.Connection.receiveUserMessage((type: string, message: string) => {
const typeMessage = this.showMessage(type, message);
//listener on banned receive message
if(typeMessage instanceof Banned) { if(typeMessage instanceof Banned) {
for (const callback of this.receiveBannedMessageListener) { this.receiveBannedMessageListener();
callback();
}
} }
}); })
} }
showMessage(type: string, message: string) { showMessage(type: string, message: string) {
@ -47,6 +37,7 @@ export class UserMessageManager {
} }
setReceiveBanListener(callback: Function){ setReceiveBanListener(callback: Function){
this.receiveBannedMessageListener.add(callback); this.receiveBannedMessageListener = callback;
} }
} }
export const userMessageManager = new UserMessageManager()

View File

@ -0,0 +1,34 @@
import {Subject} from "rxjs";
import {SendUserMessage} from "../Messages/generated/messages_pb";
export enum AdminMessageEventTypes {
admin = 'message',
audio = 'audio',
ban = 'ban',
}
interface AdminMessageEvent {
type: AdminMessageEventTypes,
text: string;
//todo add optional properties for other event types
}
//this class is designed to easily allow communication between the RoomConnection objects (that receive the message)
//and the various objects that may render the message on screen
class AdminMessagesService {
private _messageStream: Subject<AdminMessageEvent> = new Subject();
public messageStream = this._messageStream.asObservable();
constructor() {
this.messageStream.subscribe((event) => console.log('message', event))
}
onSendusermessage(message: SendUserMessage) {
this._messageStream.next({
type: message.getType() as unknown as AdminMessageEventTypes,
text: message.getMessage(),
})
}
}
export const adminMessagesService = new AdminMessagesService();

View File

@ -42,6 +42,7 @@ import {
WebRtcSignalReceivedMessageInterface, WebRtcSignalReceivedMessageInterface,
} from "./ConnexionModels"; } from "./ConnexionModels";
import {BodyResourceDescriptionInterface} from "../Phaser/Entity/PlayerTextures"; import {BodyResourceDescriptionInterface} from "../Phaser/Entity/PlayerTextures";
import {adminMessagesService} from "./AdminMessagesService";
const manualPingDelay = 20000; const manualPingDelay = 20000;
@ -140,8 +141,6 @@ export class RoomConnection implements RoomConnection {
} else if (message.hasRoomjoinedmessage()) { } else if (message.hasRoomjoinedmessage()) {
const roomJoinedMessage = message.getRoomjoinedmessage() as RoomJoinedMessage; const roomJoinedMessage = message.getRoomjoinedmessage() as RoomJoinedMessage;
//const users: Array<MessageUserJoined> = roomJoinedMessage.getUserList().map(this.toMessageUserJoined.bind(this));
//const groups: Array<GroupCreatedUpdatedMessageInterface> = roomJoinedMessage.getGroupList().map(this.toGroupCreatedUpdatedMessage.bind(this));
const items: { [itemId: number] : unknown } = {}; const items: { [itemId: number] : unknown } = {};
for (const item of roomJoinedMessage.getItemList()) { for (const item of roomJoinedMessage.getItemList()) {
items[item.getItemid()] = JSON.parse(item.getStatejson()); items[item.getItemid()] = JSON.parse(item.getStatejson());
@ -150,22 +149,12 @@ export class RoomConnection implements RoomConnection {
this.userId = roomJoinedMessage.getCurrentuserid(); this.userId = roomJoinedMessage.getCurrentuserid();
this.tags = roomJoinedMessage.getTagList(); this.tags = roomJoinedMessage.getTagList();
//console.log('Dispatching CONNECT')
this.dispatch(EventMessage.CONNECT, { this.dispatch(EventMessage.CONNECT, {
connection: this, connection: this,
room: { room: {
//users,
//groups,
items items
} as RoomJoinedMessageInterface } as RoomJoinedMessageInterface
}); });
/*console.log('Dispatching START_ROOM')
this.dispatch(EventMessage.START_ROOM, {
//users,
//groups,
items
});*/
} else if (message.hasErrormessage()) { } else if (message.hasErrormessage()) {
console.error(EventMessage.MESSAGE_ERROR, message.getErrormessage()?.getMessage()); console.error(EventMessage.MESSAGE_ERROR, message.getErrormessage()?.getMessage());
} else if (message.hasWebrtcsignaltoclientmessage()) { } else if (message.hasWebrtcsignaltoclientmessage()) {
@ -185,7 +174,7 @@ export class RoomConnection implements RoomConnection {
} else if (message.hasSendjitsijwtmessage()) { } else if (message.hasSendjitsijwtmessage()) {
this.dispatch(EventMessage.START_JITSI_ROOM, message.getSendjitsijwtmessage()); this.dispatch(EventMessage.START_JITSI_ROOM, message.getSendjitsijwtmessage());
} else if (message.hasSendusermessage()) { } else if (message.hasSendusermessage()) {
this.dispatch(EventMessage.USER_MESSAGE, message.getSendusermessage()); adminMessagesService.onSendusermessage(message.getSendusermessage() as SendUserMessage);
} else { } else {
throw new Error('Unknown message received'); throw new Error('Unknown message received');
} }
@ -539,12 +528,6 @@ export class RoomConnection implements RoomConnection {
}); });
} }
public receiveUserMessage(callback: (type: string, message: string) => void) {
return this.onMessage(EventMessage.USER_MESSAGE, (message: SendUserMessage) => {
callback(message.getType(), message.getMessage());
});
}
public emitGlobalMessage(message: PlayGlobalMessageInterface){ public emitGlobalMessage(message: PlayGlobalMessageInterface){
const playGlobalMessage = new PlayGlobalMessage(); const playGlobalMessage = new PlayGlobalMessage();
playGlobalMessage.setId(message.id); playGlobalMessage.setId(message.id);

View File

@ -57,7 +57,7 @@ import {ProtobufClientUtils} from "../../Network/ProtobufClientUtils";
import {connectionManager} from "../../Connexion/ConnectionManager"; import {connectionManager} from "../../Connexion/ConnectionManager";
import {RoomConnection} from "../../Connexion/RoomConnection"; import {RoomConnection} from "../../Connexion/RoomConnection";
import {GlobalMessageManager} from "../../Administration/GlobalMessageManager"; import {GlobalMessageManager} from "../../Administration/GlobalMessageManager";
import {UserMessageManager} from "../../Administration/UserMessageManager"; import {userMessageManager} from "../../Administration/UserMessageManager";
import {ConsoleGlobalMessageManager} from "../../Administration/ConsoleGlobalMessageManager"; import {ConsoleGlobalMessageManager} from "../../Administration/ConsoleGlobalMessageManager";
import {ResizableScene} from "../Login/ResizableScene"; import {ResizableScene} from "../Login/ResizableScene";
import {Room} from "../../Connexion/Room"; import {Room} from "../../Connexion/Room";
@ -72,7 +72,6 @@ import {TextureError} from "../../Exception/TextureError";
import {addLoader} from "../Components/Loader"; import {addLoader} from "../Components/Loader";
import {ErrorSceneName} from "../Reconnecting/ErrorScene"; import {ErrorSceneName} from "../Reconnecting/ErrorScene";
import {localUserStore} from "../../Connexion/LocalUserStore"; import {localUserStore} from "../../Connexion/LocalUserStore";
import {BodyResourceDescriptionInterface} from "../Entity/PlayerTextures";
import DOMElement = Phaser.GameObjects.DOMElement; import DOMElement = Phaser.GameObjects.DOMElement;
import Tween = Phaser.Tweens.Tween; import Tween = Phaser.Tweens.Tween;
@ -133,7 +132,6 @@ export class GameScene extends ResizableScene implements CenterListener {
public connection!: RoomConnection; public connection!: RoomConnection;
private simplePeer!: SimplePeer; private simplePeer!: SimplePeer;
private GlobalMessageManager!: GlobalMessageManager; private GlobalMessageManager!: GlobalMessageManager;
private UserMessageManager!: UserMessageManager;
public ConsoleGlobalMessageManager!: ConsoleGlobalMessageManager; public ConsoleGlobalMessageManager!: ConsoleGlobalMessageManager;
private connectionAnswerPromise: Promise<RoomJoinedMessageInterface>; private connectionAnswerPromise: Promise<RoomJoinedMessageInterface>;
private connectionAnswerPromiseResolve!: (value?: RoomJoinedMessageInterface | PromiseLike<RoomJoinedMessageInterface>) => void; private connectionAnswerPromiseResolve!: (value?: RoomJoinedMessageInterface | PromiseLike<RoomJoinedMessageInterface>) => void;
@ -540,8 +538,7 @@ export class GameScene extends ResizableScene implements CenterListener {
// When connection is performed, let's connect SimplePeer // When connection is performed, let's connect SimplePeer
this.simplePeer = new SimplePeer(this.connection, !this.room.isPublic, this.playerName); this.simplePeer = new SimplePeer(this.connection, !this.room.isPublic, this.playerName);
this.GlobalMessageManager = new GlobalMessageManager(this.connection); this.GlobalMessageManager = new GlobalMessageManager(this.connection);
this.UserMessageManager = new UserMessageManager(this.connection); userMessageManager.setReceiveBanListener(this.bannedUser.bind(this));
this.UserMessageManager.setReceiveBanListener(this.bannedUser.bind(this));
const self = this; const self = this;
this.simplePeer.registerPeerConnectionListener({ this.simplePeer.registerPeerConnectionListener({
@ -687,7 +684,7 @@ export class GameScene extends ResizableScene implements CenterListener {
coWebsiteManager.closeCoWebsite(); coWebsiteManager.closeCoWebsite();
}else{ }else{
const openWebsiteFunction = () => { const openWebsiteFunction = () => {
coWebsiteManager.loadCoWebsite(newValue as string, allProps.get('openWebsitePolicy') as string | undefined); coWebsiteManager.loadCoWebsite(newValue as string, this.MapUrlFile, allProps.get('openWebsitePolicy') as string | undefined);
layoutManager.removeActionButton('openWebsite', this.userInputManager); layoutManager.removeActionButton('openWebsite', this.userInputManager);
}; };

View File

@ -42,7 +42,7 @@ class CoWebsiteManager {
this.opened = iframeStates.opened; this.opened = iframeStates.opened;
} }
public loadCoWebsite(url: string, allowPolicy?: string): void { public loadCoWebsite(url: string, base: string, allowPolicy?: string): void {
this.load(); this.load();
this.cowebsiteDiv.innerHTML = `<button class="close-btn" id="cowebsite-close"> this.cowebsiteDiv.innerHTML = `<button class="close-btn" id="cowebsite-close">
<img src="resources/logos/close.svg"> <img src="resources/logos/close.svg">
@ -55,7 +55,7 @@ class CoWebsiteManager {
const iframe = document.createElement('iframe'); const iframe = document.createElement('iframe');
iframe.id = 'cowebsite-iframe'; iframe.id = 'cowebsite-iframe';
iframe.src = url; iframe.src = (new URL(url, base)).toString();
if (allowPolicy) { if (allowPolicy) {
iframe.allow = allowPolicy; iframe.allow = allowPolicy;
} }

View File

@ -2,7 +2,7 @@
set -x set -x
set -o nounset errexit set -o nounset errexit
template_file_index=dist/index.tmpl.html template_file_index=dist/index.tmpl.html
generated_file_index=dist/index.html generated_file_index=dist/index.tmpl.html.tmp
tmp_trackcodefile=/tmp/trackcode tmp_trackcodefile=/tmp/trackcode
# To inject tracking code, you have two choices: # To inject tracking code, you have two choices:

View File

@ -39,7 +39,7 @@ module.exports = {
plugins: [ plugins: [
new HtmlWebpackPlugin( new HtmlWebpackPlugin(
{ {
template: './dist/index.tmpl.html', template: './dist/index.tmpl.html.tmp',
minify: { minify: {
collapseWhitespace: true, collapseWhitespace: true,
keepClosingSlash: true, keepClosingSlash: true,

View File

@ -217,6 +217,7 @@ message ServerToClientMessage {
SendJitsiJwtMessage sendJitsiJwtMessage = 11; SendJitsiJwtMessage sendJitsiJwtMessage = 11;
SendUserMessage sendUserMessage = 12; SendUserMessage sendUserMessage = 12;
BanUserMessage banUserMessage = 13; BanUserMessage banUserMessage = 13;
AdminRoomMessage adminRoomMessage = 14;
} }
} }
@ -351,6 +352,12 @@ message AdminMessage {
string roomId = 3; string roomId = 3;
} }
// A message sent by an administrator to everyone in a specific room
message AdminRoomMessage {
string message = 1;
string roomId = 2;
}
// A message sent by an administrator to absolutely everybody // A message sent by an administrator to absolutely everybody
message AdminGlobalMessage { message AdminGlobalMessage {
string message = 1; string message = 1;
@ -372,4 +379,5 @@ service RoomManager {
rpc sendAdminMessage(AdminMessage) returns (EmptyMessage); rpc sendAdminMessage(AdminMessage) returns (EmptyMessage);
rpc sendGlobalAdminMessage(AdminGlobalMessage) returns (EmptyMessage); rpc sendGlobalAdminMessage(AdminGlobalMessage) returns (EmptyMessage);
rpc ban(BanMessage) returns (EmptyMessage); rpc ban(BanMessage) returns (EmptyMessage);
rpc sendAdminMessageToRoom(AdminRoomMessage) returns (EmptyMessage);
} }

View File

@ -5,6 +5,7 @@ import {MapController} from "./Controller/MapController";
import {PrometheusController} from "./Controller/PrometheusController"; import {PrometheusController} from "./Controller/PrometheusController";
import {DebugController} from "./Controller/DebugController"; import {DebugController} from "./Controller/DebugController";
import {App as uwsApp} from "./Server/sifrr.server"; import {App as uwsApp} from "./Server/sifrr.server";
import {AdminController} from "./Controller/AdminController";
class App { class App {
public app: uwsApp; public app: uwsApp;
@ -13,6 +14,7 @@ class App {
public mapController: MapController; public mapController: MapController;
public prometheusController: PrometheusController; public prometheusController: PrometheusController;
private debugController: DebugController; private debugController: DebugController;
private adminController: AdminController;
constructor() { constructor() {
this.app = new uwsApp(); this.app = new uwsApp();
@ -23,6 +25,7 @@ class App {
this.mapController = new MapController(this.app); this.mapController = new MapController(this.app);
this.prometheusController = new PrometheusController(this.app); this.prometheusController = new PrometheusController(this.app);
this.debugController = new DebugController(this.app); this.debugController = new DebugController(this.app);
this.adminController = new AdminController(this.app);
} }
} }

View File

@ -0,0 +1,73 @@
import {BaseController} from "./BaseController";
import {HttpRequest, HttpResponse, TemplatedApp} from "uWebSockets.js";
import {ADMIN_API_TOKEN} from "../Enum/EnvironmentVariable";
import {apiClientRepository} from "../Services/ApiClientRepository";
import {AdminRoomMessage} from "../Messages/generated/messages_pb";
export class AdminController extends BaseController{
constructor(private App : TemplatedApp) {
super();
this.App = App;
this.receiveGlobalMessagePrompt();
}
receiveGlobalMessagePrompt() {
this.App.options("/message", (res: HttpResponse, req: HttpRequest) => {
this.addCorsHeaders(res);
res.end();
});
// eslint-disable-next-line @typescript-eslint/no-misused-promises
this.App.post("/message", async (res: HttpResponse, req: HttpRequest) => {
res.onAborted(() => {
console.warn('/message request was aborted');
})
const token = req.getHeader('admin-token');
const body = await res.json();
if (token !== ADMIN_API_TOKEN) {
console.error('Admin access refused for token: '+token)
res.writeStatus("401 Unauthorized").end('Incorrect token');
return;
}
try {
if (typeof body.text !== 'string') {
throw 'Incorrect text parameter'
}
if (!body.targets || typeof body.targets !== 'object') {
throw 'Incorrect targets parameter'
}
const text: string = body.text;
const targets: string[] = body.targets;
await Promise.all(targets.map((roomId) => {
return apiClientRepository.getClient(roomId).then((roomClient) =>{
return new Promise((res, rej) => {
const roomMessage = new AdminRoomMessage();
roomMessage.setMessage(text);
roomMessage.setRoomid(roomId);
roomClient.sendAdminMessageToRoom(roomMessage, (err) => {
err ? rej(err) : res();
});
});
});
}));
} catch (err) {
this.errorToResponse(err, res);
return;
}
res.writeStatus("200");
this.addCorsHeaders(res);
res.end('ok');
});
}
}

View File

@ -56,6 +56,7 @@ export class AuthenticateController extends BaseController {
worldSlug, worldSlug,
roomSlug, roomSlug,
mapUrlStart, mapUrlStart,
organizationMemberToken,
textures textures
})); }));

View File

@ -21,10 +21,10 @@ import {jwtTokenManager} from "../Services/JWTTokenManager";
import {adminApi, CharacterTexture, FetchMemberDataByUuidResponse} from "../Services/AdminApi"; import {adminApi, CharacterTexture, FetchMemberDataByUuidResponse} from "../Services/AdminApi";
import {SocketManager, socketManager} from "../Services/SocketManager"; import {SocketManager, socketManager} from "../Services/SocketManager";
import {emitInBatch} from "../Services/IoSocketHelpers"; import {emitInBatch} from "../Services/IoSocketHelpers";
import {clientEventsEmitter} from "../Services/ClientEventsEmitter";
import {ADMIN_API_TOKEN, ADMIN_API_URL, SOCKET_IDLE_TIMER} from "../Enum/EnvironmentVariable"; import {ADMIN_API_TOKEN, ADMIN_API_URL, SOCKET_IDLE_TIMER} from "../Enum/EnvironmentVariable";
import {Zone} from "_Model/Zone"; import {Zone} from "_Model/Zone";
import {ExAdminSocketInterface} from "_Model/Websocket/ExAdminSocketInterface"; import {ExAdminSocketInterface} from "_Model/Websocket/ExAdminSocketInterface";
import {v4} from "uuid";
export class IoSocketController { export class IoSocketController {
private nextUserId: number = 1; private nextUserId: number = 1;
@ -64,22 +64,6 @@ export class IoSocketController {
ws.disconnecting = false; ws.disconnecting = false;
socketManager.handleAdminRoom(ws as ExAdminSocketInterface, ws.roomId as string); socketManager.handleAdminRoom(ws as ExAdminSocketInterface, ws.roomId as string);
/*ws.send('Data:'+JSON.stringify(socketManager.getAdminSocketDataFor(ws.roomId as string)));
ws.clientJoinCallback = (clientUUid: string, roomId: string) => {
const wsroomId = ws.roomId as string;
if(wsroomId === roomId) {
ws.send('MemberJoin:'+clientUUid+';'+roomId);
}
};
ws.clientLeaveCallback = (clientUUid: string, roomId: string) => {
const wsroomId = ws.roomId as string;
if(wsroomId === roomId) {
ws.send('MemberLeave:'+clientUUid+';'+roomId);
}
};
clientEventsEmitter.registerToClientJoin(ws.clientJoinCallback);
clientEventsEmitter.registerToClientLeave(ws.clientLeaveCallback);*/
}, },
message: (ws, arrayBuffer, isBinary): void => { message: (ws, arrayBuffer, isBinary): void => {
try { try {
@ -106,7 +90,6 @@ export class IoSocketController {
const Client = (ws as ExAdminSocketInterface); const Client = (ws as ExAdminSocketInterface);
try { try {
Client.disconnecting = true; Client.disconnecting = true;
//leave room
socketManager.leaveAdminRoom(Client); socketManager.leaveAdminRoom(Client);
} catch (e) { } catch (e) {
console.error('An error occurred on admin "disconnect"'); console.error('An error occurred on admin "disconnect"');
@ -181,14 +164,31 @@ export class IoSocketController {
}*/ }*/
if (ADMIN_API_URL) { if (ADMIN_API_URL) {
try { try {
const userData = await adminApi.fetchMemberDataByUuid(userUuid); let userData : FetchMemberDataByUuidResponse = {
//console.log('USERDATA', userData) uuid: v4(),
tags: [],
textures: [],
messages: [],
anonymous: true
};
try {
userData = await adminApi.fetchMemberDataByUuid(userUuid);
}catch (err){
if (err?.response?.status == 404) {
// If we get an HTTP 404, the token is invalid. Let's perform an anonymous login!
console.warn('Cannot find user with uuid "'+userUuid+'". Performing an anonymous login instead.');
}else{
throw err;
}
}
memberTags = userData.tags; memberTags = userData.tags;
memberTextures = userData.textures; memberTextures = userData.textures;
if (!room.anonymous && room.policyType === GameRoomPolicyTypes.USE_TAGS_POLICY && !room.canAccess(memberTags)) { if (!room.anonymous && room.policyType === GameRoomPolicyTypes.USE_TAGS_POLICY && (userData.anonymous === true || !room.canAccess(memberTags))) {
throw new Error('No correct tags') throw new Error('No correct tags')
} }
//console.log('access granted for user '+userUuid+' and room '+roomId); if (!room.anonymous && room.policyType === GameRoomPolicyTypes.MEMBERS_ONLY_POLICY && userData.anonymous === true) {
throw new Error('No correct member')
}
} catch (e) { } catch (e) {
console.log('access not granted for user '+userUuid+' and room '+roomId); console.log('access not granted for user '+userUuid+' and room '+roomId);
console.error(e); console.error(e);

View File

@ -1,6 +1,5 @@
import {ADMIN_API_TOKEN, ADMIN_API_URL} from "../Enum/EnvironmentVariable"; import {ADMIN_API_TOKEN, ADMIN_API_URL} from "../Enum/EnvironmentVariable";
import Axios from "axios"; import Axios from "axios";
import {v4} from "uuid";
export interface AdminApiData { export interface AdminApiData {
organizationSlug: string organizationSlug: string
@ -31,6 +30,7 @@ export interface FetchMemberDataByUuidResponse {
tags: string[]; tags: string[];
textures: CharacterTexture[]; textures: CharacterTexture[];
messages: unknown[]; messages: unknown[];
anonymous?: boolean;
} }
class AdminApi { class AdminApi {
@ -62,25 +62,10 @@ class AdminApi {
if (!ADMIN_API_URL) { if (!ADMIN_API_URL) {
return Promise.reject('No admin backoffice set!'); return Promise.reject('No admin backoffice set!');
} }
try { const res = await Axios.get(ADMIN_API_URL+'/api/membership/'+uuid,
const res = await Axios.get(ADMIN_API_URL+'/api/membership/'+uuid, { headers: {"Authorization" : `${ADMIN_API_TOKEN}`} }
{ headers: {"Authorization" : `${ADMIN_API_TOKEN}`} } )
) return res.data;
return res.data;
} catch (e) {
if (e?.response?.status == 404) {
// If we get an HTTP 404, the token is invalid. Let's perform an anonymous login!
console.warn('Cannot find user with uuid "'+uuid+'". Performing an anonymous login instead.');
return {
uuid: v4(),
tags: [],
textures: [],
messages: [],
}
} else {
throw e;
}
}
} }
async fetchMemberDataByToken(organizationMemberToken: string): Promise<AdminApiData> { async fetchMemberDataByToken(organizationMemberToken: string): Promise<AdminApiData> {

View File

@ -13,8 +13,7 @@ const debug = Debug('apiClientRespository');
class ApiClientRepository { class ApiClientRepository {
private roomManagerClients: RoomManagerClient[] = []; private roomManagerClients: RoomManagerClient[] = [];
public constructor(private apiUrls: string[]) { public constructor(private apiUrls: string[]) {}
}
public async getClient(roomId: string): Promise<RoomManagerClient> { public async getClient(roomId: string): Promise<RoomManagerClient> {
const array = new Uint32Array(crypto.createHash('md5').update(roomId).digest()); const array = new Uint32Array(crypto.createHash('md5').update(roomId).digest());

View File

@ -493,11 +493,7 @@ export class SocketManager implements ZoneEventListener {
public getWorlds(): Map<string, PusherRoom> { public getWorlds(): Map<string, PusherRoom> {
return this.Worlds; return this.Worlds;
} }
/**
*
* @param token
*/
searchClientByUuid(uuid: string): ExSocketInterface | null { searchClientByUuid(uuid: string): ExSocketInterface | null {
for(const socket of this.sockets.values()){ for(const socket of this.sockets.values()){
if(socket.userUuid === uuid){ if(socket.userUuid === uuid){