Adding JWT authentication to Jitsi

This commit is contained in:
David Négrier 2020-10-16 19:13:26 +02:00
parent 4334ab0f54
commit 260b0ea408
10 changed files with 141 additions and 42 deletions

View file

@ -27,6 +27,7 @@ export enum EventMessage{
STOP_GLOBAL_MESSAGE = "stop-global-message",
TELEPORT = "teleport",
START_JITSI_ROOM = "start-jitsi-room",
}
export interface PointInterface {

View file

@ -22,7 +22,7 @@ import {
WebRtcSignalToServerMessage,
WebRtcStartMessage,
ReportPlayerMessage,
TeleportMessageMessage
TeleportMessageMessage, QueryJitsiJwtMessage, SendJitsiJwtMessage
} from "../Messages/generated/messages_pb"
import {UserSimplePeerInterface} from "../WebRtc/SimplePeer";
@ -150,6 +150,8 @@ export class RoomConnection implements RoomConnection {
this.dispatch(EventMessage.STOP_GLOBAL_MESSAGE, message.getStopglobalmessage());
} else if (message.hasTeleportmessagemessage()) {
this.dispatch(EventMessage.TELEPORT, message.getTeleportmessagemessage());
} else if (message.hasSendjitsijwtmessage()) {
this.dispatch(EventMessage.START_JITSI_ROOM, message.getSendjitsijwtmessage());
} else {
throw new Error('Unknown message received');
}
@ -501,6 +503,25 @@ export class RoomConnection implements RoomConnection {
this.socket.send(clientToServerMessage.serializeBinary().buffer);
}
public emitQueryJitsiJwtMessage(jitsiRoom: string, tag: string|undefined ): void {
const queryJitsiJwtMessage = new QueryJitsiJwtMessage();
queryJitsiJwtMessage.setJitsiroom(jitsiRoom);
if (tag !== undefined) {
queryJitsiJwtMessage.setTag(tag);
}
const clientToServerMessage = new ClientToServerMessage();
clientToServerMessage.setQueryjitsijwtmessage(queryJitsiJwtMessage);
this.socket.send(clientToServerMessage.serializeBinary().buffer);
}
public onStartJitsiRoom(callback: (jwt: string, room: string) => void): void {
this.onMessage(EventMessage.START_JITSI_ROOM, (message: SendJitsiJwtMessage) => {
callback(message.getJwt(), message.getJitsiroom());
});
}
public hasTag(tag: string): boolean {
return this.tags.includes(tag);
}

View file

@ -1,6 +1,6 @@
import {ITiledMap} from "../Map/ITiledMap";
export type PropertyChangeCallback = (newValue: string | number | boolean | undefined, oldValue: string | number | boolean | undefined) => void;
export type PropertyChangeCallback = (newValue: string | number | boolean | undefined, oldValue: string | number | boolean | undefined, allProps: Map<string, string | boolean | number>) => void;
/**
* A wrapper around a ITiledMap interface to provide additional capabilities.
@ -35,14 +35,14 @@ export class GameMap {
for (const [newPropName, newPropValue] of newProps.entries()) {
const oldPropValue = oldProps.get(newPropName);
if (oldPropValue !== newPropValue) {
this.trigger(newPropName, oldPropValue, newPropValue);
this.trigger(newPropName, oldPropValue, newPropValue, newProps);
}
}
for (const [oldPropName, oldPropValue] of oldProps.entries()) {
if (!newProps.has(oldPropName)) {
// We found a property that disappeared
this.trigger(oldPropName, oldPropValue, undefined);
this.trigger(oldPropName, oldPropValue, undefined, newProps);
}
}
@ -74,11 +74,11 @@ export class GameMap {
return properties;
}
private trigger(propName: string, oldValue: string | number | boolean | undefined, newValue: string | number | boolean | undefined) {
private trigger(propName: string, oldValue: string | number | boolean | undefined, newValue: string | number | boolean | undefined, allProps: Map<string, string | boolean | number>) {
const callbacksArray = this.callbacks.get(propName);
if (callbacksArray !== undefined) {
for (const callback of callbacksArray) {
callback(newValue, oldValue);
callback(newValue, oldValue, allProps);
}
}
}

View file

@ -137,6 +137,8 @@ export class GameScene extends ResizableScene implements CenterListener {
private outlinedItem: ActionableItem|null = null;
private userInputManager!: UserInputManager;
private jitsiApi: any; // eslint-disable-line @typescript-eslint/no-explicit-any
static createFromUrl(room: Room, mapUrlFile: string, gameSceneKey: string|null = null): GameScene {
// We use the map URL as a key
if (gameSceneKey === null) {
@ -460,34 +462,14 @@ export class GameScene extends ResizableScene implements CenterListener {
CoWebsiteManager.loadCoWebsite(newValue as string);
}
});
let jitsiApi: any; // eslint-disable-line @typescript-eslint/no-explicit-any
this.gameMap.onPropertyChange('jitsiRoom', (newValue, oldValue) => {
this.gameMap.onPropertyChange('jitsiRoom', (newValue, oldValue, allProps) => {
if (newValue === undefined) {
this.connection.setSilent(false);
jitsiApi?.dispose();
CoWebsiteManager.closeCoWebsite();
mediaManager.showGameOverlay();
this.stopJitsi();
} else {
CoWebsiteManager.insertCoWebsite((cowebsiteDiv => {
const domain = JITSI_URL;
const options = {
roomName: this.instance + "-" + newValue,
width: "100%",
height: "100%",
parentNode: cowebsiteDiv,
configOverwrite: {
prejoinPageEnabled: false
},
interfaceConfigOverwrite: {
SHOW_CHROME_EXTENSION_BANNER: false,
MOBILE_APP_PROMO: false
}
};
jitsiApi = new (window as any).JitsiMeetExternalAPI(domain, options); // eslint-disable-line @typescript-eslint/no-explicit-any
jitsiApi.executeCommand('displayName', gameManager.getPlayerName());
}));
this.connection.setSilent(true);
mediaManager.hideGameOverlay();
// TODO: get jitsiRoomAdminTag
const adminTag = allProps.get("jitsiRoomAdminTag") as string|undefined;
this.connection.emitQueryJitsiJwtMessage(this.instance + "-" + newValue, adminTag);
}
})
@ -597,6 +579,10 @@ export class GameScene extends ResizableScene implements CenterListener {
item.fire(message.event, message.state, message.parameters);
}));
connection.onStartJitsiRoom((jwt, room) => {
this.startJitsi(room, jwt);
});
// When connection is performed, let's connect SimplePeer
this.simplePeer = new SimplePeer(this.connection, !this.room.isPublic);
this.GlobalMessageManager = new GlobalMessageManager(this.connection);
@ -1191,4 +1177,35 @@ export class GameScene extends ResizableScene implements CenterListener {
public onCenterChange(): void {
this.updateCameraOffset();
}
public startJitsi(roomName: string, jwt: string): void {
CoWebsiteManager.insertCoWebsite((cowebsiteDiv => {
const domain = JITSI_URL;
const options = {
roomName: roomName,
jwt: jwt,
width: "100%",
height: "100%",
parentNode: cowebsiteDiv,
configOverwrite: {
prejoinPageEnabled: false
},
interfaceConfigOverwrite: {
SHOW_CHROME_EXTENSION_BANNER: false,
MOBILE_APP_PROMO: false
}
};
this.jitsiApi = new (window as any).JitsiMeetExternalAPI(domain, options); // eslint-disable-line @typescript-eslint/no-explicit-any
this.jitsiApi.executeCommand('displayName', gameManager.getPlayerName());
}));
this.connection.setSilent(true);
mediaManager.hideGameOverlay();
}
public stopJitsi(): void {
this.connection.setSilent(false);
this.jitsiApi?.dispose();
CoWebsiteManager.closeCoWebsite();
mediaManager.showGameOverlay();
}
}