Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions JitsiConference.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4480,9 +4480,9 @@ export default class JitsiConference extends Listenable {
*
* @returns {Function} Handler returned to be able to remove it later.
*/
public addLobbyMessageListener(listener: (message: object) => void): Optional<EventListener> {
public addLobbyMessageListener(listener: (message: string, participantId: string) => void): Optional<(participantId: string, message: string) => void> {
if (this.room) {
return this.room.getLobby().addMessageListener(listener) as Optional<EventListener>;
return this.room.getLobby().addMessageListener(listener);
}
}

Expand Down
96 changes: 49 additions & 47 deletions modules/xmpp/Lobby.js → modules/xmpp/Lobby.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ import { $msg, Strophe } from 'strophe.js';

import { XMPPEvents } from '../../service/xmpp/XMPPEvents';

import ChatRoom from './ChatRoom';
import XMPP from './xmpp';

const logger = getLogger('xmpp:Lobby');

/**
Expand All @@ -17,13 +20,17 @@ const EMAIL_COMMAND = 'email';
* approving or denying access to participants from the lobby room.
*/
export default class Lobby {
xmpp: XMPP;
mainRoom: any;
lobbyRoomJid?: string;
lobbyRoom?: any;

/**
* Constructs lobby room.
*
* @param {ChatRoom} room the main room.
*/
constructor(room) {
constructor(room: ChatRoom) {
this.xmpp = room.xmpp;
this.mainRoom = room;

Expand All @@ -39,7 +46,7 @@ export default class Lobby {

this.mainRoom.addEventListener(
XMPPEvents.ROOM_CONNECT_MEMBERS_ONLY_ERROR,
jid => {
(jid: string) => {
this.lobbyRoomJid = jid;
});
}
Expand All @@ -49,24 +56,24 @@ export default class Lobby {
*
* @returns {boolean} whether lobby is supported on backend.
*/
isSupported() {
isSupported(): boolean {
return this.xmpp.lobbySupported;
}

/**
* Enables lobby by setting the main room to be members only and joins the lobby chat room.
*
* @returns {Promise}
* @returns {Promise<void>}
*/
enable() {
enable(): Promise<void> {
if (!this.isSupported()) {
return Promise.reject(new Error('Lobby not supported!'));
}

// let's wait for the room data form to be populated after XMPPEvents.MUC_JOINED
if (!this.mainRoom.initialDiscoRoomInfoReceived) {
return new Promise((resolve, reject) => {
let unsubscribers = [];
let unsubscribers: Array<() => void> = [];
const unsubscribe = () => {
unsubscribers.forEach(remove => remove());
unsubscribers = [];
Expand All @@ -86,7 +93,7 @@ export default class Lobby {
}));

// on timeout or failure
unsubscribers.push(this.mainRoom.addCancellableListener(XMPPEvents.ROOM_DISCO_INFO_FAILED, e => {
unsubscribers.push(this.mainRoom.addCancellableListener(XMPPEvents.ROOM_DISCO_INFO_FAILED, (e: any) => {
unsubscribe();
reject(e);
}));
Expand All @@ -107,7 +114,7 @@ export default class Lobby {
*
* @returns {void}
*/
disable() {
disable(): void {
if (!this.isSupported() || !this.mainRoom.isModerator()
|| !this.lobbyRoom || !this.mainRoom.membersOnlyEnabled) {
return;
Expand All @@ -122,7 +129,7 @@ export default class Lobby {
*
* @returns {void}
*/
sendMessage(message) {
sendMessage(message: object): void {
if (this.lobbyRoom) {
this.lobbyRoom.sendMessage(JSON.stringify(message), 'json-message');
}
Expand All @@ -135,7 +142,7 @@ export default class Lobby {
*
* @returns {void}
*/
sendPrivateMessage(id, message) {
sendPrivateMessage(id: string, message: object): void {
if (this.lobbyRoom) {
this.lobbyRoom.sendPrivateMessage(id, JSON.stringify(message), 'json-message');
}
Expand All @@ -145,9 +152,9 @@ export default class Lobby {
* Gets the local id for a participant in a lobby room.
* This is used for lobby room private chat messages.
*
* @returns {string}
* @returns {Optional<string>}
*/
getLocalId() {
getLocalId(): Optional<string> {
if (this.lobbyRoom) {
return Strophe.getResourceFromJid(this.lobbyRoom.myroomjid);
}
Expand All @@ -158,11 +165,11 @@ export default class Lobby {
* @param {Function} listener The listener function,
* called when a new message is received in the lobby room.
*
* @returns {Function} Handler returned to be able to remove it later.
* @returns {Function|undefined} Handler returned to be able to remove it later.
*/
addMessageListener(listener) {
addMessageListener(listener: (message: string, participantId: string) => void): Optional<((participantId: string, message: any) => void) > {
if (this.lobbyRoom) {
const handler = (participantId, message) => {
const handler = (participantId: string, message: string) => {
listener(message, Strophe.getResourceFromJid(participantId));
};

Expand All @@ -178,7 +185,7 @@ export default class Lobby {
*
* @returns {void}
*/
removeMessageHandler(handler) {
removeMessageHandler(handler: (...args: any[]) => void): void {
if (this.lobbyRoom) {
this.lobbyRoom.off(XMPPEvents.JSON_MESSAGE_RECEIVED, handler);
}
Expand All @@ -187,16 +194,16 @@ export default class Lobby {
/**
* Leaves the lobby room.
*
* @returns {Promise}
* @returns {Promise<void>}
*/
leave() {
leave(): Promise<void> {
if (this.lobbyRoom) {
return this.lobbyRoom.leave()
.then(() => {
this.lobbyRoom = undefined;
logger.info('Lobby room left!');
})
.catch(() => {}); // eslint-disable-line no-empty-function
.catch(() => {}); // eslint-disable-line @typescript-eslint/no-empty-function
}

return Promise.reject(
Expand All @@ -208,15 +215,15 @@ export default class Lobby {
*
* @param jid the lobby room jid to join.
*/
setLobbyRoomJid(jid) {
setLobbyRoomJid(jid: string): void {
this.lobbyRoomJid = jid;
}

/**
* Checks the state of mainRoom, lobbyRoom and current user role to decide whether to join lobby room.
* @private
*/
_maybeJoinLobbyRoom() {
_maybeJoinLobbyRoom(): void {
if (!this.isSupported()) {
return;
}
Expand All @@ -227,18 +234,18 @@ export default class Lobby {
// join the lobby
this.join()
.then(() => logger.info('Joined lobby room'))
.catch(e => logger.error('Failed joining lobby', e));
.catch((e: Error) => logger.error('Failed joining lobby', e));
}
}

/**
* Joins a lobby room setting display name and eventually avatar(using the email provided).
*
* @param {string} username is required.
* @param {string} displayName is required.
* @param {string} email is optional.
* @returns {Promise} resolves once we join the room.
* @returns {Promise<void>} resolves once we join the room.
*/
join(displayName, email) {
join(displayName?: string, email?: string): Promise<void> {
const isModerator = this.mainRoom.joined && this.mainRoom.isModerator();

if (!this.lobbyRoomJid) {
Expand Down Expand Up @@ -266,21 +273,21 @@ export default class Lobby {
}

if (isModerator) {
this.lobbyRoom.addPresenceListener(EMAIL_COMMAND, (node, from) => {
this.lobbyRoom.addPresenceListener(EMAIL_COMMAND, (node: any, from: string) => {
this.mainRoom.eventEmitter.emit(XMPPEvents.MUC_LOBBY_MEMBER_UPDATED, from, { email: node.value });
});
this.lobbyRoom.addEventListener(
XMPPEvents.MUC_MEMBER_JOINED,
// eslint-disable-next-line max-params
(from, nick, role, isHiddenDomain, statsID, status, identity, botType, jid) => {
(from: string, nick: string, role: string, isHiddenDomain: boolean, statsID: any, status: any, identity: any, botType: any, jid: string) => {
// we need to ignore joins on lobby for participants that are already in the main room
if (Object.values(this.mainRoom.members).find(m => m.jid === jid)) {
if (Object.values(this.mainRoom.members).find((m: any) => m.jid === jid)) {
return;
}

// Check if the user is a member if any breakout room.
for (const room of Object.values(this.mainRoom.getBreakoutRooms()._rooms)) {
if (Object.values(room.participants).find(p => p.jid === jid)) {
if (Object.values((room as { participants: { jid: string; }[]; }).participants).find(p => p.jid === jid)) {
return;
}
}
Expand All @@ -295,7 +302,7 @@ export default class Lobby {
);
});
this.lobbyRoom.addEventListener(
XMPPEvents.MUC_MEMBER_LEFT, from => {
XMPPEvents.MUC_MEMBER_LEFT, (from: string) => {
// we emit the new event on the main room so we can propagate
// events to the conference
this.mainRoom.eventEmitter.emit(
Expand All @@ -318,13 +325,11 @@ export default class Lobby {
});
} else {
// this should only be handled by those waiting in lobby
this.lobbyRoom.addEventListener(XMPPEvents.KICKED, isSelfPresence => {
this.lobbyRoom.addEventListener(XMPPEvents.KICKED, (isSelfPresence: boolean) => {
if (isSelfPresence) {
this.mainRoom.eventEmitter.emit(XMPPEvents.MUC_DENIED_ACCESS);

this.lobbyRoom.clean();


}
});

Expand All @@ -333,7 +338,7 @@ export default class Lobby {
// the invite message should be received directly to the xmpp conn in general
this.mainRoom.addEventListener(
XMPPEvents.INVITE_MESSAGE_RECEIVED,
(roomJid, from, txt, invitePassword) => {
(roomJid: string, from: string, txt: string, invitePassword: string) => {
logger.debug(`Received approval to join ${roomJid} ${from} ${txt}`);
if (roomJid === this.mainRoom.roomjid) {
// we are now allowed, so let's join
Expand All @@ -342,7 +347,7 @@ export default class Lobby {
});
this.lobbyRoom.addEventListener(
XMPPEvents.MUC_DESTROYED,
(reason, jid) => {
(reason: any, jid: string) => {
this.lobbyRoom?.clean();

this.lobbyRoom = undefined;
Expand Down Expand Up @@ -370,7 +375,7 @@ export default class Lobby {
});
}

return new Promise((resolve, reject) => {
return new Promise<void>((resolve, reject) => {
this.lobbyRoom.addEventListener(XMPPEvents.MUC_JOINED, () => {
resolve();

Expand All @@ -393,7 +398,7 @@ export default class Lobby {
* Should be possible only for moderators.
* @param id
*/
denyAccess(id) {
denyAccess(id: string): void {
if (!this.isSupported() || !this.mainRoom.isModerator()) {
return;
}
Expand All @@ -412,7 +417,7 @@ export default class Lobby {
* Should be possible only for moderators.
* @param param or an array of ids.
*/
approveAccess(param) {
approveAccess(param: string | string[]): void {
if (!this.isSupported() || !this.mainRoom.isModerator()) {
return;
}
Expand All @@ -425,12 +430,8 @@ export default class Lobby {
mainRoomJid = this.mainRoom.getBreakoutRooms().getMainRoomJid();
}

const membersToApprove = [];
let ids = param;

if (!Array.isArray(param)) {
ids = [ param ];
}
const membersToApprove: string[] = [];
const ids: string[] = Array.isArray(param) ? param : [ param ];

ids.forEach(id => {
const memberRoomJid = Object.keys(this.lobbyRoom.members)
Expand All @@ -453,10 +454,11 @@ export default class Lobby {
});

this.xmpp.connection.sendIQ(msgToSend,
() => { }, // eslint-disable-line no-empty-function
e => {
() => { }, // eslint-disable-line @typescript-eslint/no-empty-function
(e: Error) => {
logger.error(`Error sending invite for ${membersToApprove}`, e);
});
},
undefined);
}
}
}
5 changes: 4 additions & 1 deletion modules/xmpp/xmpp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@ interface IConnectionCredentials {
*/
interface IRoomCreationOptions {
customDomain?: string;
disableDiscoInfo?: boolean;
disableFocus?: boolean;
enableLobby?: boolean;
statsId?: string;
}

Expand Down Expand Up @@ -1109,7 +1112,7 @@ export default class XMPP extends Listenable {
* is to be added to the jid.
* @returns {ChatRoom} Resolves with an instance of a strophe muc.
*/
public createRoom(roomName: string, options: IRoomCreationOptions, onCreateResource: (jid: string, user: any) => string): ChatRoom {
public createRoom(roomName: string, options: IRoomCreationOptions, onCreateResource?: (jid: string, user: any) => string): ChatRoom {
// Support passing the domain in a String object as part of the room name.
const domain = (roomName as { domain?: string; }).domain || options.customDomain;

Expand Down