Merge pull request #2991 from OZhurbenko/meteor-whiteboard
Reworked server-side ES6
This commit is contained in:
commit
227ae1bb72
@ -116,7 +116,7 @@ Handlebars.registerHelper("getUsersInMeeting", () => {
|
||||
});
|
||||
|
||||
Handlebars.registerHelper("getWhiteboardTitle", () => {
|
||||
return BBB.currentPresentationName() || "Loading presentation...";
|
||||
return BBB.currentPresentationName() || "No active presentation";
|
||||
});
|
||||
|
||||
Handlebars.registerHelper("getCurrentUserEmojiStatus", () => {
|
||||
|
@ -18,36 +18,36 @@ this.WhiteboardCursorModel = (function() {
|
||||
if(this.color == null) {
|
||||
this.color = "#ff6666"; // a pinkish red
|
||||
}
|
||||
this.cursor = null;
|
||||
this.cursorDOM = null;
|
||||
}
|
||||
|
||||
draw() {
|
||||
this.cursor = this.paper.circle(0, 0, this.radius);
|
||||
this.cursor.attr({
|
||||
this.cursorDOM = this.paper.circle(0, 0, this.radius);
|
||||
this.cursorDOM.attr({
|
||||
"fill": this.color,
|
||||
"stroke": this.color,
|
||||
"opacity": "0.8"
|
||||
});
|
||||
return $(this.cursor.node).on("mousewheel", _.bind(this._onMouseWheel, this));
|
||||
return $(this.cursorDOM.node).on("mousewheel", _.bind(this._onMouseWheel, this));
|
||||
}
|
||||
|
||||
toFront() {
|
||||
if(this.cursor != null) {
|
||||
return this.cursor.toFront();
|
||||
if(this.cursorDOM != null) {
|
||||
return this.cursorDOM.toFront();
|
||||
}
|
||||
}
|
||||
|
||||
setRadius(value) {
|
||||
if(this.cursor != null) {
|
||||
return this.cursor.attr({
|
||||
if(this.cursorDOM != null) {
|
||||
return this.cursorDOM.attr({
|
||||
r: value
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
setPosition(x, y) {
|
||||
if(this.cursor != null) {
|
||||
return this.cursor.attr({
|
||||
if(this.cursorDOM != null) {
|
||||
return this.cursorDOM.attr({
|
||||
cx: x,
|
||||
cy: y
|
||||
});
|
||||
@ -55,8 +55,8 @@ this.WhiteboardCursorModel = (function() {
|
||||
}
|
||||
|
||||
undrag() {
|
||||
if(this.cursor != null) {
|
||||
return this.cursor.undrag();
|
||||
if(this.cursorDOM != null) {
|
||||
return this.cursorDOM.undrag();
|
||||
}
|
||||
}
|
||||
|
||||
@ -64,9 +64,9 @@ this.WhiteboardCursorModel = (function() {
|
||||
if(target == null) {
|
||||
target = null;
|
||||
}
|
||||
if(this.cursor != null) {
|
||||
if(this.cursorDOM != null) {
|
||||
target || (target = this);
|
||||
return this.cursor.drag(_.bind(onMove, target), _.bind(onStart, target), _.bind(onEnd, target));
|
||||
return this.cursorDOM.drag(_.bind(onMove, target), _.bind(onStart, target), _.bind(onEnd, target));
|
||||
}
|
||||
}
|
||||
|
||||
@ -75,7 +75,7 @@ this.WhiteboardCursorModel = (function() {
|
||||
}
|
||||
|
||||
remove() {
|
||||
return this.cursor.remove();
|
||||
return this.cursorDOM.remove();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
// TODO: should be split on server and client side
|
||||
// // Global configurations file
|
||||
|
||||
let config, file, ref, transports, winston;
|
||||
let config, file, transports, winston;
|
||||
|
||||
config = {};
|
||||
|
||||
@ -84,7 +84,11 @@ config.redis.channels.toBBBApps.polling = "bigbluebutton:to-bbb-apps:polling";
|
||||
config.log = {};
|
||||
|
||||
if(Meteor.isServer) {
|
||||
config.log.path = (typeof process !== "undefined" && process !== null ? (ref = process.env) != null ? ref.NODE_ENV : void 0 : void 0) === "production" ? "/var/log/bigbluebutton/bbbnode.log" : `${process.env.PWD}/../log/development.log`;
|
||||
if(process != null && process.env != null && process.env.NODE_ENV == "production") {
|
||||
config.log.path = "/var/log/bigbluebutton/bbbnode.log";
|
||||
} else {
|
||||
config.log.path = `${process.env.PWD}/../log/development.log`
|
||||
}
|
||||
// Setting up a logger in Meteor.log
|
||||
winston = Winston; //Meteor.require 'winston'
|
||||
file = config.log.path;
|
||||
|
@ -1,19 +0,0 @@
|
||||
// Generated by CoffeeScript 1.10.0
|
||||
|
||||
/*
|
||||
bunyan = Meteor.require 'bunyan'
|
||||
|
||||
logger = bunyan.createLogger({
|
||||
name: 'bbbnode',
|
||||
streams: [
|
||||
{
|
||||
level: 'debug',
|
||||
stream: process.stdout,
|
||||
},
|
||||
{
|
||||
level: 'info',
|
||||
path: Meteor.config.log.path
|
||||
}
|
||||
]
|
||||
})
|
||||
*/
|
@ -52,17 +52,19 @@ Meteor.methods({
|
||||
// Private methods on server
|
||||
// --------------------------------------------------------------------------------------------
|
||||
this.addPollToCollection = function(poll, requester_id, users, meetingId) {
|
||||
let _users, answer, entry, i, j, len, len1, ref, user;
|
||||
let _users, answer, entry, i, j, user;
|
||||
//copying all the userids into an array
|
||||
_users = [];
|
||||
for (i = 0, len = users.length; i < len; i++) {
|
||||
_users_length = users.length;
|
||||
for (i = 0; i < _users_length; i++) {
|
||||
user = users[i];
|
||||
_users.push(user.user.userid);
|
||||
}
|
||||
//adding the initial number of votes for each answer
|
||||
ref = poll.answers;
|
||||
for (j = 0, len1 = ref.length; j < len1; j++) {
|
||||
answer = ref[j];
|
||||
_answers = poll.answers;
|
||||
_answers_length = _answers.length;
|
||||
for (j = 0; j < _answers_length; j++) {
|
||||
answer = _answers[j];
|
||||
answer.num_votes = 0;
|
||||
}
|
||||
//adding the initial number of responders and respondents to the poll, which will be displayed for presenter (in HTML5 client) when he starts the poll
|
||||
@ -83,10 +85,10 @@ this.addPollToCollection = function(poll, requester_id, users, meetingId) {
|
||||
};
|
||||
|
||||
this.clearPollCollection = function(meetingId, poll_id) {
|
||||
if ((meetingId != null) && (poll_id != null) && (Meteor.Polls.findOne({
|
||||
if (meetingId != null && poll_id != null && Meteor.Polls.findOne({
|
||||
"poll_info.meetingId": meetingId,
|
||||
"poll_info.poll.id": poll_id
|
||||
}) != null)) {
|
||||
}) != null) {
|
||||
return Meteor.Polls.remove({
|
||||
"poll_info.meetingId": meetingId,
|
||||
"poll_info.poll.id": poll_id
|
||||
|
@ -5,27 +5,31 @@ Meteor.methods({
|
||||
"meetingId": meetingId,
|
||||
"presentation.current": true
|
||||
});
|
||||
currentSlideDoc = Meteor.Slides.findOne({
|
||||
"meetingId": meetingId,
|
||||
"presentationId": currentPresentationDoc != null ? currentPresentationDoc.presentation.id : void 0,
|
||||
"slide.current": true
|
||||
});
|
||||
previousSlideDoc = Meteor.Slides.findOne({
|
||||
"meetingId": meetingId,
|
||||
"presentationId": currentPresentationDoc != null ? currentPresentationDoc.presentation.id : void 0,
|
||||
"slide.num": (currentSlideDoc != null ? currentSlideDoc.slide.num : void 0) - 1
|
||||
});
|
||||
if((previousSlideDoc != null) && isAllowedTo('switchSlide', meetingId, userId, authToken)) {
|
||||
message = {
|
||||
"payload": {
|
||||
"page": previousSlideDoc.slide.id,
|
||||
"meeting_id": meetingId
|
||||
},
|
||||
"header": {
|
||||
"name": "go_to_slide"
|
||||
if(currentPresentationDoc != null) {
|
||||
currentSlideDoc = Meteor.Slides.findOne({
|
||||
"meetingId": meetingId,
|
||||
"presentationId": currentPresentationDoc.presentation.id,
|
||||
"slide.current": true
|
||||
});
|
||||
if(currentSlideDoc != null) {
|
||||
previousSlideDoc = Meteor.Slides.findOne({
|
||||
"meetingId": meetingId,
|
||||
"presentationId": currentPresentationDoc.presentation.id,
|
||||
"slide.num": currentSlideDoc.slide.num - 1
|
||||
});
|
||||
if((previousSlideDoc != null) && isAllowedTo('switchSlide', meetingId, userId, authToken)) {
|
||||
message = {
|
||||
"payload": {
|
||||
"page": previousSlideDoc.slide.id,
|
||||
"meeting_id": meetingId
|
||||
},
|
||||
"header": {
|
||||
"name": "go_to_slide"
|
||||
}
|
||||
};
|
||||
return publish(Meteor.config.redis.channels.toBBBApps.presentation, message);
|
||||
}
|
||||
};
|
||||
return publish(Meteor.config.redis.channels.toBBBApps.presentation, message);
|
||||
}
|
||||
}
|
||||
},
|
||||
publishSwitchToNextSlideMessage(meetingId, userId, authToken) {
|
||||
@ -34,27 +38,31 @@ Meteor.methods({
|
||||
"meetingId": meetingId,
|
||||
"presentation.current": true
|
||||
});
|
||||
currentSlideDoc = Meteor.Slides.findOne({
|
||||
"meetingId": meetingId,
|
||||
"presentationId": currentPresentationDoc != null ? currentPresentationDoc.presentation.id : void 0,
|
||||
"slide.current": true
|
||||
});
|
||||
nextSlideDoc = Meteor.Slides.findOne({
|
||||
"meetingId": meetingId,
|
||||
"presentationId": currentPresentationDoc != null ? currentPresentationDoc.presentation.id : void 0,
|
||||
"slide.num": (currentSlideDoc != null ? currentSlideDoc.slide.num : void 0) + 1
|
||||
});
|
||||
if((nextSlideDoc != null) && isAllowedTo('switchSlide', meetingId, userId, authToken)) {
|
||||
message = {
|
||||
"payload": {
|
||||
"page": nextSlideDoc.slide.id,
|
||||
"meeting_id": meetingId
|
||||
},
|
||||
"header": {
|
||||
"name": "go_to_slide"
|
||||
if(currentPresentationDoc != null) {
|
||||
currentSlideDoc = Meteor.Slides.findOne({
|
||||
"meetingId": meetingId,
|
||||
"presentationId": currentPresentationDoc.presentation.id,
|
||||
"slide.current": true
|
||||
});
|
||||
if(currentSlideDoc != null) {
|
||||
nextSlideDoc = Meteor.Slides.findOne({
|
||||
"meetingId": meetingId,
|
||||
"presentationId": currentPresentationDoc.presentation.id,
|
||||
"slide.num": currentSlideDoc.slide.num + 1
|
||||
});
|
||||
if((nextSlideDoc != null) && isAllowedTo('switchSlide', meetingId, userId, authToken)) {
|
||||
message = {
|
||||
"payload": {
|
||||
"page": nextSlideDoc.slide.id,
|
||||
"meeting_id": meetingId
|
||||
},
|
||||
"header": {
|
||||
"name": "go_to_slide"
|
||||
}
|
||||
};
|
||||
return publish(Meteor.config.redis.channels.toBBBApps.presentation, message);
|
||||
}
|
||||
};
|
||||
return publish(Meteor.config.redis.channels.toBBBApps.presentation, message);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -63,12 +71,13 @@ Meteor.methods({
|
||||
// Private methods on server
|
||||
// --------------------------------------------------------------------------------------------
|
||||
this.addPresentationToCollection = function(meetingId, presentationObject) {
|
||||
let entry, id;
|
||||
let entry, id, presentationObj;
|
||||
//check if the presentation is already in the collection
|
||||
if(Meteor.Presentations.findOne({
|
||||
presentationObj = Meteor.Presentations.findOne({
|
||||
meetingId: meetingId,
|
||||
'presentation.id': presentationObject.id
|
||||
}) == null) {
|
||||
});
|
||||
if(presentationObj == null) {
|
||||
entry = {
|
||||
meetingId: meetingId,
|
||||
presentation: {
|
||||
@ -83,22 +92,17 @@ this.addPresentationToCollection = function(meetingId, presentationObject) {
|
||||
};
|
||||
|
||||
this.removePresentationFromCollection = function(meetingId, presentationId) {
|
||||
let id;
|
||||
if((meetingId != null) && (presentationId != null) && (Meteor.Presentations.findOne({
|
||||
let id, presentationObject;
|
||||
presentationObject = Meteor.Presentations.findOne({
|
||||
meetingId: meetingId,
|
||||
"presentation.id": presentationId
|
||||
}) != null)) {
|
||||
id = Meteor.Presentations.findOne({
|
||||
meetingId: meetingId,
|
||||
"presentation.id": presentationId
|
||||
});
|
||||
if(id != null) {
|
||||
Meteor.Slides.remove({
|
||||
});
|
||||
if(presentationObject != null){
|
||||
Meteor.Slides.remove({
|
||||
presentationId: presentationId
|
||||
}, Meteor.log.info(`cleared Slides Collection (presentationId: ${presentationId}!`));
|
||||
Meteor.Presentations.remove(id._id);
|
||||
return Meteor.log.info(`----removed presentation[${presentationId}] from ${meetingId}`);
|
||||
}
|
||||
Meteor.Presentations.remove(presentationObject._id);
|
||||
return Meteor.log.info(`----removed presentation[${presentationId}] from ${meetingId}`);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
// --------------------------------------------------------------------------------------------
|
||||
this.addShapeToCollection = function(meetingId, whiteboardId, shapeObject) {
|
||||
let entry, id, removeTempTextShape;
|
||||
if((shapeObject != null ? shapeObject.shape_type : void 0) === "text") {
|
||||
if(shapeObject != null && shapeObject.shape_type === "text") {
|
||||
Meteor.log.info(`we are dealing with a text shape and the event is:${shapeObject.status}`);
|
||||
entry = {
|
||||
meetingId: meetingId,
|
||||
@ -43,10 +43,9 @@ this.addShapeToCollection = function(meetingId, whiteboardId, shapeObject) {
|
||||
return Meteor.log.info(`${shapeObject.status} substituting the temp shapes with the newer one`);
|
||||
});
|
||||
}
|
||||
} else {
|
||||
// the mouse button was released - the drawing is complete
|
||||
// TODO: pencil messages currently don't send draw_end and are labeled all as DRAW_START
|
||||
if((shapeObject != null ? shapeObject.status : void 0) === "DRAW_END" || ((shapeObject != null ? shapeObject.status : void 0) === "DRAW_START" && (shapeObject != null ? shapeObject.shape_type : void 0) === "pencil")) {
|
||||
} else if(shapeObject != null && shapeObject.status === "DRAW_END" || (shapeObject != null && shapeObject.status === "DRAW_START" && shapeObject.shape_type === "pencil")) {
|
||||
entry = {
|
||||
meetingId: meetingId,
|
||||
whiteboardId: whiteboardId,
|
||||
@ -73,7 +72,6 @@ this.addShapeToCollection = function(meetingId, whiteboardId, shapeObject) {
|
||||
};
|
||||
return id = Meteor.Shapes.insert(entry);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
this.removeAllShapesFromSlide = function(meetingId, whiteboardId) {
|
||||
@ -104,18 +102,21 @@ this.removeAllShapesFromSlide = function(meetingId, whiteboardId) {
|
||||
|
||||
this.removeShapeFromSlide = function(meetingId, whiteboardId, shapeId) {
|
||||
let shapeToRemove;
|
||||
shapeToRemove = Meteor.Shapes.findOne({
|
||||
meetingId: meetingId,
|
||||
whiteboardId: whiteboardId,
|
||||
"shape.id": shapeId
|
||||
});
|
||||
if((meetingId != null) && (whiteboardId != null) && (shapeId != null) && (shapeToRemove != null)) {
|
||||
Meteor.Shapes.remove(shapeToRemove._id);
|
||||
Meteor.log.info(`----removed shape[${shapeId}] from ${whiteboardId}`);
|
||||
return Meteor.log.info(`remaining shapes on the slide:${Meteor.Shapes.find({
|
||||
meetingId: meetingId,
|
||||
whiteboardId: whiteboardId
|
||||
}).count()}`);
|
||||
if(meetingId != null && whiteboardId != null && shapeId != null) {
|
||||
shapeToRemove = Meteor.Shapes.findOne({
|
||||
meetingId: meetingId,
|
||||
whiteboardId: whiteboardId,
|
||||
"shape.id": shapeId
|
||||
});
|
||||
if(shapeToRemove != null) {
|
||||
Meteor.Shapes.remove(shapeToRemove._id);
|
||||
Meteor.log.info(`----removed shape[${shapeId}] from ${whiteboardId}`);
|
||||
return Meteor.log.info(`remaining shapes on the slide: ${
|
||||
Meteor.Shapes.find({
|
||||
meetingId: meetingId,
|
||||
whiteboardId: whiteboardId
|
||||
}).count()}`);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -44,7 +44,7 @@ this.addSlideToCollection = function(meetingId, presentationId, slideObject) {
|
||||
num: slideObject.num,
|
||||
x_offset: slideObject.x_offset,
|
||||
current: slideObject.current,
|
||||
img_uri: slideObject.svg_uri !== void 0 ? slideObject.svg_uri : slideObject.png_uri,
|
||||
img_uri: slideObject.svg_uri != null ? slideObject.svg_uri : slideObject.png_uri,
|
||||
txt_uri: slideObject.txt_uri,
|
||||
id: slideObject.id,
|
||||
width_ratio: slideObject.width_ratio,
|
||||
|
@ -11,14 +11,20 @@ Meteor.methods({
|
||||
// requesterUserId: the userId of the requester
|
||||
// requesterToken: the authToken of the requester
|
||||
listenOnlyRequestToggle(meetingId, userId, authToken, isJoining) {
|
||||
let message, ref, ref1, username, voiceConf;
|
||||
voiceConf = (ref = Meteor.Meetings.findOne({
|
||||
let message, userObject, username, voiceConf, meetingObject;
|
||||
meetingObject = Meteor.Meetings.findOne({
|
||||
meetingId: meetingId
|
||||
})) != null ? ref.voiceConf : void 0;
|
||||
username = (ref1 = Meteor.Users.findOne({
|
||||
});
|
||||
if(meetingObject != null) {
|
||||
voiceConf = meetingObject.voiceConf;
|
||||
}
|
||||
userObject = Meteor.Users.findOne({
|
||||
meetingId: meetingId,
|
||||
userId: userId
|
||||
})) != null ? ref1.user.name : void 0;
|
||||
});
|
||||
if(userObject != null) {
|
||||
username = userObject.user.name;
|
||||
}
|
||||
if(isJoining) {
|
||||
if(isAllowedTo('joinListenOnly', meetingId, userId, authToken)) {
|
||||
message = {
|
||||
@ -229,7 +235,7 @@ this.markUserOffline = function(meetingId, userId, callback) {
|
||||
meetingId: meetingId,
|
||||
userId: userId
|
||||
});
|
||||
if((user != null ? user.clientType : void 0) === "HTML5") {
|
||||
if(user != null && user.clientType === "HTML5") {
|
||||
Meteor.log.info(`marking html5 user [${userId}] as offline in meeting[${meetingId}]`);
|
||||
return Meteor.Users.update({
|
||||
meetingId: meetingId,
|
||||
@ -246,11 +252,11 @@ this.markUserOffline = function(meetingId, userId, callback) {
|
||||
}, (err, numChanged) => {
|
||||
let funct;
|
||||
if(err != null) {
|
||||
Meteor.log.error(`_unsucc update (mark as offline) of user ${user != null ? user.user.name : void 0} ${userId} err=${JSON.stringify(err)}`);
|
||||
Meteor.log.error(`_unsucc update (mark as offline) of user ${user.user.name} ${userId} err=${JSON.stringify(err)}`);
|
||||
return callback();
|
||||
} else {
|
||||
funct = function(cbk) {
|
||||
Meteor.log.info(`_marking as offline html5 user ${user != null ? user.user.name : void 0} ${userId} numChanged=${numChanged}`);
|
||||
Meteor.log.info(`_marking as offline html5 user ${user.user.name} ${userId} numChanged=${numChanged}`);
|
||||
return cbk();
|
||||
};
|
||||
return funct(callback);
|
||||
@ -280,14 +286,17 @@ this.markUserOffline = function(meetingId, userId, callback) {
|
||||
// After authorization, publish a user_leaving_request in redis
|
||||
// params: meetingid, userid as defined in BBB-App
|
||||
this.requestUserLeaving = function(meetingId, userId) {
|
||||
let listenOnlyMessage, message, ref, userObject, voiceConf;
|
||||
let listenOnlyMessage, message, userObject, meetingObject, voiceConf;
|
||||
userObject = Meteor.Users.findOne({
|
||||
'meetingId': meetingId,
|
||||
'userId': userId
|
||||
});
|
||||
voiceConf = (ref = Meteor.Meetings.findOne({
|
||||
meetingObject = Meteor.Meetings.findOne({
|
||||
meetingId: meetingId
|
||||
})) != null ? ref.voiceConf : void 0;
|
||||
});
|
||||
if(meetingObject != null) {
|
||||
voiceConf = meetingObject.voiceConf;
|
||||
}
|
||||
if((userObject != null) && (voiceConf != null) && (userId != null) && (meetingId != null)) {
|
||||
|
||||
// end listenOnly audio for the departing user
|
||||
@ -327,11 +336,11 @@ this.requestUserLeaving = function(meetingId, userId) {
|
||||
|
||||
//update a voiceUser - a helper method
|
||||
this.updateVoiceUser = function(meetingId, voiceUserObject, callback) {
|
||||
let u;
|
||||
u = Meteor.Users.findOne({
|
||||
let userObject;
|
||||
userObject = Meteor.Users.findOne({
|
||||
userId: voiceUserObject.web_userid
|
||||
});
|
||||
if(u != null) {
|
||||
if(userObject != null) {
|
||||
if(voiceUserObject.talking != null) {
|
||||
Meteor.Users.update({
|
||||
meetingId: meetingId,
|
||||
@ -416,9 +425,9 @@ this.updateVoiceUser = function(meetingId, voiceUserObject, callback) {
|
||||
};
|
||||
|
||||
this.userJoined = function(meetingId, user, callback) {
|
||||
let ref, ref1, u, userId, welcomeMessage;
|
||||
let userObject, userId, welcomeMessage, meetingObject;
|
||||
userId = user.userid;
|
||||
u = Meteor.Users.findOne({
|
||||
userObject = Meteor.Users.findOne({
|
||||
userId: user.userid,
|
||||
meetingId: meetingId
|
||||
});
|
||||
@ -426,7 +435,7 @@ this.userJoined = function(meetingId, user, callback) {
|
||||
// because the user is reconnecting OR
|
||||
// in the case of an html5 client user we added a dummy user on
|
||||
// register_user_message (to save authToken)
|
||||
if((u != null) && (u.authToken != null)) {
|
||||
if(userObject != null && userObject.authToken != null) {
|
||||
Meteor.Users.update({
|
||||
userId: user.userid,
|
||||
meetingId: meetingId
|
||||
@ -467,15 +476,18 @@ this.userJoined = function(meetingId, user, callback) {
|
||||
return callback();
|
||||
} else {
|
||||
funct = function(cbk) {
|
||||
Meteor.log.info(`_(case1) UPDATING USER ${user.userid}, authToken= ${u.authToken}, locked=${user.locked}, username=${user.name}`);
|
||||
Meteor.log.info(`_(case1) UPDATING USER ${user.userid}, authToken= ${userObject.authToken}, locked=${user.locked}, username=${user.name}`);
|
||||
return cbk();
|
||||
};
|
||||
return funct(callback);
|
||||
}
|
||||
});
|
||||
welcomeMessage = Meteor.config.defaultWelcomeMessage.replace(/%%CONFNAME%%/, (ref = Meteor.Meetings.findOne({
|
||||
meetingObject = Meteor.Meetings.findOne({
|
||||
meetingId: meetingId
|
||||
})) != null ? ref.meetingName : void 0);
|
||||
});
|
||||
if(meetingObject != null) {
|
||||
welcomeMessage = Meteor.config.defaultWelcomeMessage.replace(/%%CONFNAME%%/, meetingObject.meetingName);
|
||||
}
|
||||
welcomeMessage = welcomeMessage + Meteor.config.defaultWelcomeMessageFooter;
|
||||
// add the welcome message if it's not there already OR update time_of_joining
|
||||
return Meteor.Chat.upsert({
|
||||
@ -493,7 +505,7 @@ this.userJoined = function(meetingId, user, callback) {
|
||||
to_userid: userId,
|
||||
from_userid: 'SYSTEM_MESSAGE',
|
||||
from_username: '',
|
||||
from_time: (ref1 = user.timeOfJoining) != null ? ref1.toString() : void 0
|
||||
from_time: (user != null && user.timeOfJoining != null) ? user.timeOfJoining.toString() : void 0
|
||||
}
|
||||
}, err => {
|
||||
if(err != null) {
|
||||
@ -585,32 +597,33 @@ this.createDummyUser = function(meetingId, userId, authToken) {
|
||||
// all viewers that are in the audio bridge with a mic should be muted and locked
|
||||
this.handleLockingMic = function(meetingId, newSettings) {
|
||||
// send mute requests for the viewer users joined with mic
|
||||
let i, len, ref, ref1, results, u;
|
||||
ref1 = (ref = Meteor.Users.find({
|
||||
let i, results, userObject;
|
||||
userObjects = Meteor.Users.find({
|
||||
meetingId: meetingId,
|
||||
'user.role': 'VIEWER',
|
||||
'user.listenOnly': false,
|
||||
'user.locked': true,
|
||||
'user.voiceUser.joined': true,
|
||||
'user.voiceUser.muted': false
|
||||
})) != null ? ref.fetch() : void 0;
|
||||
}).fetch();
|
||||
|
||||
_userObjects_length = userObjects.length;
|
||||
results = [];
|
||||
for(i = 0, len = ref1.length; i < len; i++) {
|
||||
u = ref1[i];
|
||||
// Meteor.log.info u.user.name #
|
||||
results.push(Meteor.call('muteUser', meetingId, u.userId, u.userId, u.authToken, true)); //true for muted
|
||||
for(i = 0; i < _userObjects_length; i++) {
|
||||
userObject = userObjects[i];
|
||||
results.push(Meteor.call('muteUser', meetingId, userObject.userId, userObject.userId, userObject.authToken, true)); //true for muted
|
||||
}
|
||||
return results;
|
||||
};
|
||||
|
||||
// change the locked status of a user (lock settings)
|
||||
this.setUserLockedStatus = function(meetingId, userId, isLocked) {
|
||||
let u;
|
||||
u = Meteor.Users.findOne({
|
||||
let userObject;
|
||||
userObject = Meteor.Users.findOne({
|
||||
meetingId: meetingId,
|
||||
userId: userId
|
||||
});
|
||||
if(u != null) {
|
||||
if(userObject != null) {
|
||||
Meteor.Users.update({
|
||||
userId: userId,
|
||||
meetingId: meetingId
|
||||
@ -626,8 +639,8 @@ this.setUserLockedStatus = function(meetingId, userId, isLocked) {
|
||||
}
|
||||
});
|
||||
// if the user is sharing audio, he should be muted upon locking involving disableMic
|
||||
if(u.user.role === 'VIEWER' && !u.user.listenOnly && u.user.voiceUser.joined && !u.user.voiceUser.muted && isLocked) {
|
||||
return Meteor.call('muteUser', meetingId, u.userId, u.userId, u.authToken, true); //true for muted
|
||||
if(userObject.user.role === 'VIEWER' && !userObject.user.listenOnly && userObject.user.voiceUser.joined && !userObject.user.voiceUser.muted && isLocked) {
|
||||
return Meteor.call('muteUser', meetingId, userObject.userId, userObject.userId, userObject.authToken, true); //true for muted
|
||||
}
|
||||
} else {
|
||||
return Meteor.log.error(`(unsuccessful-no such user) setting user locked status for userid:[${userId}] from [${meetingId}] locked=${isLocked}`);
|
||||
|
@ -1,21 +1,25 @@
|
||||
// Publish only the online users that are in the particular meetingId
|
||||
// On the client side we pass the meetingId parameter
|
||||
Meteor.publish('users', function(meetingId, userid, authToken) {
|
||||
let ref, ref1, u, username;
|
||||
let user, userObject, username;
|
||||
Meteor.log.info(`attempt publishing users for ${meetingId}, ${userid}, ${authToken}`);
|
||||
u = Meteor.Users.findOne({
|
||||
userObject = Meteor.Users.findOne({
|
||||
'userId': userid,
|
||||
'meetingId': meetingId
|
||||
});
|
||||
if(u != null) {
|
||||
if(userObject != null) {
|
||||
Meteor.log.info("found it from the first time " + userid);
|
||||
if(isAllowedTo('subscribeUsers', meetingId, userid, authToken)) {
|
||||
Meteor.log.info(`${userid} was allowed to subscribe to 'users'`);
|
||||
username = (u != null ? (ref = u.user) != null ? ref.name : void 0 : void 0) || "UNKNOWN";
|
||||
|
||||
// offline -> online
|
||||
if(((ref1 = u.user) != null ? ref1.connection_status : void 0) !== 'online') {
|
||||
Meteor.call("validateAuthToken", meetingId, userid, authToken);
|
||||
user = userObject.user;
|
||||
if(user != null) {
|
||||
username = user.name;
|
||||
// offline -> online
|
||||
if(user.connection_status !== 'online') {
|
||||
Meteor.call("validateAuthToken", meetingId, userid, authToken);
|
||||
}
|
||||
} else {
|
||||
username = "UNKNOWN";
|
||||
}
|
||||
Meteor.Users.update({
|
||||
'meetingId': meetingId,
|
||||
|
@ -23,8 +23,11 @@ Meteor.startup(() => {
|
||||
// isPaused: true
|
||||
});
|
||||
Meteor.myQueue.taskHandler = function(data, next, failures) {
|
||||
let eventName, ref;
|
||||
eventName = (ref = JSON.parse(data.jsonMsg)) != null ? ref.header.name : void 0;
|
||||
let eventName, parsedMsg;
|
||||
parsedMsg = JSON.parse(data.jsonMsg);
|
||||
if(parsedMsg != null) {
|
||||
eventName = parsedMsg.header.name;
|
||||
}
|
||||
if(failures > 0) {
|
||||
return Meteor.log.error(`got a failure on taskHandler ${eventName} ${failures}`);
|
||||
} else {
|
||||
@ -54,11 +57,17 @@ Meteor.startup(() => {
|
||||
// for example: a user_left event reaching the collection before a user_joined
|
||||
// for the same user.
|
||||
return this.handleRedisMessage = function(data, callback) {
|
||||
let chatMessage, currentlyBeingRecorded, cursor, dbUser, duration, emojiStatus, eventName, heightRatio, i, intendedForRecording, isLocked, j, k, l, len, len1, len2, len3, len4, listOfMeetings, m, meetingId, meetingName, message, messageObject, newPresenterId, newSettings, newSlide, notLoggedEventTypes, oldSettings, page, pollObj, poll_id, presentation, presentationId, processMeeting, processUser, ref, ref1, ref10, ref11, ref12, ref13, ref14, ref15, ref16, ref17, ref18, ref19, ref2, ref20, ref21, ref3, ref4, ref5, ref6, ref7, ref8, ref9, replyTo, requesterId, set_emoji_time, shape, shapeId, slide, slideId, status, user, userId, userObj, users, validStatus, voiceConf, voiceUserObj, whiteboardId, widthRatio, xOffset, yOffset;
|
||||
let chatMessage, currentlyBeingRecorded, cursor, dbUser, duration, emojiStatus, eventName, heightRatio, i, intendedForRecording;
|
||||
let isLocked, j, k, l, listOfMeetings, m, meetingId, meetingName, meetingObject, message, messageObject, newPresenterId, newSettings;
|
||||
let newSlide, notLoggedEventTypes, oldSettings, page, pages, pollObj, poll_id, presentation, presentationId, processMeeting, processUser;
|
||||
let payload, chatHistory, _chat_history_length, presentations, shapes, shapes_length, replyTo, requesterId, set_emoji_time, shape, shapeId;
|
||||
let slide, slideId, status, user, userId, userObj, users, validStatus, voiceConf, voiceUserObj, _voiceUser, whiteboardId, widthRatio, xOffset, yOffset;
|
||||
message = JSON.parse(data.jsonMsg);
|
||||
// correlationId = message.payload?.reply_to or message.header?.reply_to
|
||||
meetingId = (ref = message.payload) != null ? ref.meeting_id : void 0;
|
||||
|
||||
payload = message.payload;
|
||||
if(payload != null) {
|
||||
meetingId = payload.meeting_id;
|
||||
}
|
||||
eventName = message.header.name;
|
||||
// Avoid cluttering the log with json messages carrying little or repetitive
|
||||
// information. Comment out a message type in the array to be able to see it
|
||||
// in the log upon restarting of the Meteor process.
|
||||
@ -82,49 +91,49 @@ Meteor.startup(() => {
|
||||
"user_voice_talking_message",
|
||||
"meeting_state_message",
|
||||
"get_recording_status_reply"];
|
||||
eventName = message.header.name;
|
||||
meetingId = (ref1 = message.payload) != null ? ref1.meeting_id : void 0;
|
||||
if(!(((message != null ? message.header : void 0) != null) && (message.payload != null))) {
|
||||
|
||||
if(message == null || message.header == null || payload == null) {
|
||||
Meteor.log.error("ERROR!! No header or payload");
|
||||
callback();
|
||||
}
|
||||
if(ref2 = message.header.name, indexOf.call(notLoggedEventTypes, ref2) < 0) {
|
||||
if(eventName, indexOf.call(notLoggedEventTypes, eventName) < 0) {
|
||||
Meteor.log.info(`redis incoming message ${eventName} `, {
|
||||
message: data.jsonMsg
|
||||
});
|
||||
}
|
||||
|
||||
// we currently disregard the pattern and channel
|
||||
if(((message != null ? message.header : void 0) != null) && (message.payload != null)) {
|
||||
if(message != null && message.header != null && payload != null) {
|
||||
if(eventName === 'meeting_created_message') {
|
||||
// Meteor.log.error JSON.stringify message
|
||||
meetingName = message.payload.name;
|
||||
intendedForRecording = message.payload.recorded;
|
||||
voiceConf = message.payload.voice_conf;
|
||||
duration = message.payload.duration;
|
||||
meetingName = payload.name;
|
||||
intendedForRecording = payload.recorded;
|
||||
voiceConf = payload.voice_conf;
|
||||
duration = payload.duration;
|
||||
return addMeetingToCollection(meetingId, meetingName, intendedForRecording, voiceConf, duration, callback);
|
||||
|
||||
// handle voice events
|
||||
} else if ((message.payload.user != null) && (eventName === 'user_left_voice_message' || eventName === 'user_joined_voice_message' || eventName === 'user_voice_talking_message' || eventName === 'user_voice_muted_message')) {
|
||||
} else if ((payload.user != null) && (eventName === 'user_left_voice_message' || eventName === 'user_joined_voice_message' || eventName === 'user_voice_talking_message' || eventName === 'user_voice_muted_message')) {
|
||||
_voiceUser = payload.user.voiceUser;
|
||||
voiceUserObj = {
|
||||
'web_userid': message.payload.user.voiceUser.web_userid,
|
||||
'listen_only': message.payload.listen_only,
|
||||
'talking': message.payload.user.voiceUser.talking,
|
||||
'joined': message.payload.user.voiceUser.joined,
|
||||
'locked': message.payload.user.voiceUser.locked,
|
||||
'muted': message.payload.user.voiceUser.muted
|
||||
'web_userid': _voiceUser.web_userid,
|
||||
'listen_only': payload.listen_only,
|
||||
'talking': _voiceUser.talking,
|
||||
'joined': _voiceUser.joined,
|
||||
'locked': _voiceUser.locked,
|
||||
'muted': _voiceUser.muted
|
||||
};
|
||||
return updateVoiceUser(meetingId, voiceUserObj, callback);
|
||||
} else if(eventName === 'user_listening_only') {
|
||||
voiceUserObj = {
|
||||
'web_userid': message.payload.userid,
|
||||
'listen_only': message.payload.listen_only
|
||||
'web_userid': payload.userid,
|
||||
'listen_only': payload.listen_only
|
||||
};
|
||||
return updateVoiceUser(meetingId, voiceUserObj, callback);
|
||||
} else if (eventName === 'get_all_meetings_reply') {
|
||||
Meteor.log.info("Let's store some data for the running meetings so that when an HTML5 client joins everything is ready!");
|
||||
Meteor.log.info(JSON.stringify(message));
|
||||
listOfMeetings = message.payload.meetings;
|
||||
listOfMeetings = payload.meetings;
|
||||
|
||||
// Processing the meetings recursively with a callback to notify us,
|
||||
// ensuring that we update the meeting collection serially
|
||||
@ -139,22 +148,23 @@ Meteor.startup(() => {
|
||||
};
|
||||
return processMeeting();
|
||||
} else if(eventName === 'user_joined_message') {
|
||||
userObj = message.payload.user;
|
||||
userObj = payload.user;
|
||||
dbUser = Meteor.Users.findOne({
|
||||
userId: userObj.userid,
|
||||
meetingId: message.payload.meeting_id
|
||||
meetingId: meetingId
|
||||
});
|
||||
|
||||
// On attempting reconnection of Flash clients (in voiceBridge) we receive
|
||||
// an extra user_joined_message. Ignore it as it will add an extra user
|
||||
// in the user list, creating discrepancy with the list in the Flash client
|
||||
if((dbUser != null ? (ref3 = dbUser.user) != null ? ref3.connection_status : void 0 : void 0) === "offline" && ((ref4 = message.payload.user) != null ? ref4.phone_user : void 0)) {
|
||||
if((dbUser != null && dbUser.user != null && dbUser.user.connection_status === "offline") && ( payload.user != null && payload.user.phone_user)) {
|
||||
Meteor.log.error("offline AND phone user");
|
||||
return callback(); //return without joining the user
|
||||
} else {
|
||||
if((dbUser != null ? dbUser.clientType : void 0) === "HTML5") { // typically html5 users will be in
|
||||
if(dbUser != null && dbUser.clientType === "HTML5") {
|
||||
// typically html5 users will be in
|
||||
// the db [as a dummy user] before the joining message
|
||||
status = dbUser != null ? dbUser.validated : void 0;
|
||||
status = dbUser.validated;
|
||||
Meteor.log.info(`in user_joined_message the validStatus of the user was ${status}`);
|
||||
userObj.timeOfJoining = message.header.current_time;
|
||||
return userJoined(meetingId, userObj, callback);
|
||||
@ -165,8 +175,8 @@ Meteor.startup(() => {
|
||||
|
||||
// only process if requester is nodeJSapp means only process in the case when
|
||||
// we explicitly request the users
|
||||
} else if(eventName === 'get_users_reply' && message.payload.requester_id === 'nodeJSapp') {
|
||||
users = message.payload.users;
|
||||
} else if(eventName === 'get_users_reply' && payload.requester_id === 'nodeJSapp') {
|
||||
users = payload.users;
|
||||
|
||||
//TODO make the serialization be split per meeting. This will allow us to
|
||||
// use N threads vs 1 and we'll take advantage of Mongo's concurrency tricks
|
||||
@ -179,11 +189,9 @@ Meteor.startup(() => {
|
||||
if(user != null) {
|
||||
user.timeOfJoining = message.header.current_time;
|
||||
if(user.emoji_status !== 'none' && typeof user.emoji_status === 'string') {
|
||||
console.log("3");
|
||||
user.set_emoji_time = new Date();
|
||||
return userJoined(meetingId, user, processUser);
|
||||
} else {
|
||||
// console.error("this is not supposed to happen")
|
||||
return userJoined(meetingId, user, processUser);
|
||||
}
|
||||
} else {
|
||||
@ -192,19 +200,19 @@ Meteor.startup(() => {
|
||||
};
|
||||
return processUser();
|
||||
} else if(eventName === 'validate_auth_token_reply') {
|
||||
userId = message.payload.userid;
|
||||
userId = payload.userid;
|
||||
user = Meteor.Users.findOne({
|
||||
userId: userId,
|
||||
meetingId: meetingId
|
||||
});
|
||||
validStatus = message.payload.valid;
|
||||
validStatus = payload.valid;
|
||||
|
||||
// if the user already exists in the db
|
||||
if((user != null ? user.clientType : void 0) === "HTML5") {
|
||||
if(user != null && user.clientType === "HTML5") {
|
||||
//if the html5 client user was validated successfully, add a flag
|
||||
return Meteor.Users.update({
|
||||
userId: userId,
|
||||
meetingId: message.payload.meeting_id
|
||||
meetingId: meetingId
|
||||
}, {
|
||||
$set: {
|
||||
validated: validStatus
|
||||
@ -213,11 +221,14 @@ Meteor.startup(() => {
|
||||
let funct;
|
||||
if(numChanged.insertedId != null) {
|
||||
funct = function(cbk) {
|
||||
let ref5, val;
|
||||
val = (ref5 = Meteor.Users.findOne({
|
||||
let user, val;
|
||||
user = Meteor.Users.findOne({
|
||||
userId: userId,
|
||||
meetingId: message.payload.meeting_id
|
||||
})) != null ? ref5.validated : void 0;
|
||||
meetingId: meetingId
|
||||
});
|
||||
if(user != null) {
|
||||
val = user.validated;
|
||||
}
|
||||
Meteor.log.info(`user.validated for user ${userId} in meeting ${user.meetingId} just became ${val}`);
|
||||
return cbk();
|
||||
};
|
||||
@ -231,8 +242,8 @@ Meteor.startup(() => {
|
||||
return callback();
|
||||
}
|
||||
} else if(eventName === 'user_left_message') {
|
||||
userId = (ref5 = message.payload.user) != null ? ref5.userid : void 0;
|
||||
if((userId != null) && (meetingId != null)) {
|
||||
if(payload.user != null && payload.user.userid != null && meetingId != null) {
|
||||
userId = payload.user.userid;
|
||||
return markUserOffline(meetingId, userId, callback);
|
||||
} else {
|
||||
return callback(); //TODO check how to get these cases out and reuse code
|
||||
@ -240,7 +251,7 @@ Meteor.startup(() => {
|
||||
|
||||
// for now not handling this serially #TODO
|
||||
} else if(eventName === 'presenter_assigned_message') {
|
||||
newPresenterId = message.payload.new_presenter_id;
|
||||
newPresenterId = payload.new_presenter_id;
|
||||
if(newPresenterId != null) {
|
||||
// reset the previous presenter
|
||||
Meteor.Users.update({
|
||||
@ -269,10 +280,9 @@ Meteor.startup(() => {
|
||||
|
||||
// for now not handling this serially #TODO
|
||||
} else if(eventName === 'user_emoji_status_message') {
|
||||
userId = message.payload.userid;
|
||||
meetingId = message.payload.meeting_id;
|
||||
emojiStatus = message.payload.emoji_status;
|
||||
if((userId != null) && (meetingId != null)) {
|
||||
userId = payload.userid;
|
||||
emojiStatus = payload.emoji_status;
|
||||
if(userId != null && meetingId != null) {
|
||||
set_emoji_time = new Date();
|
||||
Meteor.Users.update({
|
||||
"user.userid": userId
|
||||
@ -289,8 +299,8 @@ Meteor.startup(() => {
|
||||
|
||||
// for now not handling this serially #TODO
|
||||
} else if(eventName === 'user_locked_message' || eventName === 'user_unlocked_message') {
|
||||
userId = message.payload.userid;
|
||||
isLocked = message.payload.locked;
|
||||
userId = payload.userid;
|
||||
isLocked = payload.locked;
|
||||
setUserLockedStatus(meetingId, userId, isLocked);
|
||||
return callback();
|
||||
|
||||
@ -299,25 +309,15 @@ Meteor.startup(() => {
|
||||
Meteor.log.info(`DESTROYING MEETING ${meetingId}`);
|
||||
return removeMeetingFromCollection(meetingId, callback);
|
||||
|
||||
/*
|
||||
if Meteor.Meetings.findOne({meetingId: meetingId})?
|
||||
count=Meteor.Users.find({meetingId: meetingId}).count()
|
||||
Meteor.log.info "there are #{count} users in the meeting"
|
||||
for user in Meteor.Users.find({meetingId: meetingId}).fetch()
|
||||
markUserOffline meetingId, user.userId
|
||||
#TODO should we clear the chat messages for that meeting?!
|
||||
unless eventName is "disconnect_all_users_message"
|
||||
removeMeetingFromCollection meetingId
|
||||
*/
|
||||
|
||||
// for now not handling this serially #TODO
|
||||
} else if(eventName === "get_chat_history_reply" && message.payload.requester_id === "nodeJSapp") {
|
||||
} else if(eventName === "get_chat_history_reply" && payload.requester_id === "nodeJSapp") {
|
||||
if(Meteor.Meetings.findOne({
|
||||
MeetingId: message.payload.meeting_id
|
||||
MeetingId: meetingId
|
||||
}) == null) {
|
||||
ref6 = message.payload.chat_history;
|
||||
for(i = 0, len = ref6.length; i < len; i++) {
|
||||
chatMessage = ref6[i];
|
||||
chatHistory = payload.chat_history;
|
||||
_chat_history_length = chatHistory.length;
|
||||
for(i = 0; i < _chat_history_length; i++) {
|
||||
chatMessage = chatHistory[i];
|
||||
addChatToCollection(meetingId, chatMessage);
|
||||
}
|
||||
}
|
||||
@ -325,7 +325,7 @@ Meteor.startup(() => {
|
||||
|
||||
// for now not handling this serially #TODO
|
||||
} else if(eventName === "send_public_chat_message" || eventName === "send_private_chat_message") {
|
||||
messageObject = message.payload.message;
|
||||
messageObject = payload.message;
|
||||
// use current_time instead of message.from_time so that the chats from Flash and HTML5 have uniform times
|
||||
messageObject.from_time = message.header.current_time;
|
||||
addChatToCollection(meetingId, messageObject);
|
||||
@ -333,45 +333,47 @@ Meteor.startup(() => {
|
||||
|
||||
// for now not handling this serially #TODO
|
||||
} else if(eventName === "presentation_shared_message") {
|
||||
presentationId = (ref7 = message.payload.presentation) != null ? ref7.id : void 0;
|
||||
// change the currently displayed presentation to presentation.current = false
|
||||
Meteor.Presentations.update({
|
||||
"presentation.current": true,
|
||||
meetingId: meetingId
|
||||
}, {
|
||||
$set: {
|
||||
"presentation.current": false
|
||||
if(payload.presentation != null && payload.presentation.id != null && meetingId != null){
|
||||
presentationId = payload.presentation.id;
|
||||
// change the currently displayed presentation to presentation.current = false
|
||||
Meteor.Presentations.update({
|
||||
"presentation.current": true,
|
||||
meetingId: meetingId
|
||||
}, {
|
||||
$set: {
|
||||
"presentation.current": false
|
||||
}
|
||||
});
|
||||
//update(if already present) entirely the presentation with the fresh data
|
||||
removePresentationFromCollection(meetingId, presentationId);
|
||||
addPresentationToCollection(meetingId, payload.presentation);
|
||||
pages = payload.presentation.pages;
|
||||
for(j = 0; j < pages.length; j++) {
|
||||
slide = pages[j];
|
||||
addSlideToCollection(
|
||||
meetingId,
|
||||
presentationId,
|
||||
slide
|
||||
);
|
||||
}
|
||||
});
|
||||
//update(if already present) entirely the presentation with the fresh data
|
||||
removePresentationFromCollection(meetingId, presentationId);
|
||||
addPresentationToCollection(meetingId, message.payload.presentation);
|
||||
ref9 = (ref8 = message.payload.presentation) != null ? ref8.pages : void 0;
|
||||
for(j = 0, len1 = ref9.length; j < len1; j++) {
|
||||
slide = ref9[j];
|
||||
addSlideToCollection(
|
||||
meetingId,
|
||||
(ref10 = message.payload.presentation) != null ? ref10.id : void 0,
|
||||
slide
|
||||
);
|
||||
}
|
||||
return callback();
|
||||
|
||||
// for now not handling this serially #TODO
|
||||
} else if(eventName === "get_presentation_info_reply" && message.payload.requester_id === "nodeJSapp") {
|
||||
ref11 = message.payload.presentations;
|
||||
for(k = 0, len2 = ref11.length; k < len2; k++) {
|
||||
presentation = ref11[k];
|
||||
} else if(eventName === "get_presentation_info_reply" && payload.requester_id === "nodeJSapp") {
|
||||
presentations = payload.presentations;
|
||||
for(k = 0; k < payload.presentations.length; k++) {
|
||||
presentation = presentations[k];
|
||||
addPresentationToCollection(meetingId, presentation);
|
||||
ref12 = presentation.pages;
|
||||
for(l = 0, len3 = ref12.length; l < len3; l++) {
|
||||
page = ref12[l];
|
||||
pages = presentation.pages;
|
||||
for(l = 0; l < pages.length; l++) {
|
||||
page = pages[l];
|
||||
|
||||
//add the slide to the collection
|
||||
addSlideToCollection(meetingId, presentation.id, page);
|
||||
|
||||
//request for shapes
|
||||
whiteboardId = `${presentation.id}/${page.num}`; // d2d9a672040fbde2a47a10bf6c37b6a4b5ae187f-1404411622872/1
|
||||
whiteboardId = `${presentation.id}/${page.num}`;
|
||||
//Meteor.log.info "the whiteboard_id here is:" + whiteboardId
|
||||
|
||||
replyTo = `${meetingId}/nodeJSapp`;
|
||||
@ -387,7 +389,7 @@ Meteor.startup(() => {
|
||||
"name": "request_whiteboard_annotation_history_request"
|
||||
}
|
||||
};
|
||||
if((whiteboardId != null) && (meetingId != null)) {
|
||||
if(whiteboardId != null && meetingId != null) {
|
||||
publish(Meteor.config.redis.channels.toBBBApps.whiteboard, message);
|
||||
} else {
|
||||
Meteor.log.info("did not have enough information to send a user_leaving_request");
|
||||
@ -398,19 +400,22 @@ Meteor.startup(() => {
|
||||
|
||||
// for now not handling this serially #TODO
|
||||
} else if(eventName === "presentation_page_changed_message") {
|
||||
newSlide = message.payload.page;
|
||||
displayThisSlide(meetingId, newSlide != null ? newSlide.id : void 0, newSlide);
|
||||
newSlide = payload.page;
|
||||
if(newSlide != null && newSlide.id != null && meetingId != null) {
|
||||
displayThisSlide(meetingId, newSlide.id, newSlide);
|
||||
}
|
||||
return callback();
|
||||
|
||||
// for now not handling this serially #TODO
|
||||
} else if(eventName === "presentation_removed_message") {
|
||||
presentationId = message.payload.presentation_id;
|
||||
meetingId = message.payload.meeting_id;
|
||||
removePresentationFromCollection(meetingId, presentationId);
|
||||
presentationId = payload.presentation_id;
|
||||
if(meetingId != null && presentationId != null) {
|
||||
removePresentationFromCollection(meetingId, presentationId);
|
||||
}
|
||||
return callback();
|
||||
|
||||
// for now not handling this serially #TODO
|
||||
} else if(eventName === "get_whiteboard_shapes_reply" && message.payload.requester_id === "nodeJSapp") {
|
||||
} else if(eventName === "get_whiteboard_shapes_reply" && payload.requester_id === "nodeJSapp") {
|
||||
// Create a whiteboard clean status or find one for the current meeting
|
||||
if(Meteor.WhiteboardCleanStatus.findOne({
|
||||
meetingId: meetingId
|
||||
@ -420,9 +425,10 @@ Meteor.startup(() => {
|
||||
in_progress: false
|
||||
});
|
||||
}
|
||||
ref13 = message.payload.shapes;
|
||||
for(m = 0, len4 = ref13.length; m < len4; m++) {
|
||||
shape = ref13[m];
|
||||
shapes = payload.shapes;
|
||||
shapes_length = shapes.length
|
||||
for(m = 0; m < shapes_length; m++) {
|
||||
shape = shapes[m];
|
||||
whiteboardId = shape.wb_id;
|
||||
addShapeToCollection(meetingId, whiteboardId, shape);
|
||||
}
|
||||
@ -432,19 +438,21 @@ Meteor.startup(() => {
|
||||
} else if(eventName === "send_whiteboard_shape_message") {
|
||||
//Meteor stringifies an array of JSONs (...shape.result) in this message
|
||||
//parsing the String and reassigning the value
|
||||
if(message.payload.shape.shape_type === "poll_result" && typeof message.payload.shape.shape.result === 'string') {
|
||||
message.payload.shape.shape.result = JSON.parse(message.payload.shape.shape.result);
|
||||
if(payload.shape.shape_type === "poll_result" && typeof payload.shape.shape.result === 'string') {
|
||||
payload.shape.shape.result = JSON.parse(payload.shape.shape.result);
|
||||
}
|
||||
shape = payload.shape;
|
||||
if(shape != null && shape.wb_id != null) {
|
||||
whiteboardId = shape.wb_id;
|
||||
}
|
||||
shape = message.payload.shape;
|
||||
whiteboardId = shape != null ? shape.wb_id : void 0;
|
||||
addShapeToCollection(meetingId, whiteboardId, shape);
|
||||
return callback();
|
||||
|
||||
// for now not handling this serially #TODO
|
||||
} else if(eventName === "presentation_cursor_updated_message") {
|
||||
cursor = {
|
||||
x: message.payload.x_percent,
|
||||
y: message.payload.y_percent
|
||||
x: payload.x_percent,
|
||||
y: payload.y_percent
|
||||
};
|
||||
|
||||
// update the location of the cursor on the whiteboard
|
||||
@ -453,7 +461,7 @@ Meteor.startup(() => {
|
||||
|
||||
// for now not handling this serially #TODO
|
||||
} else if(eventName === "whiteboard_cleared_message") {
|
||||
whiteboardId = message.payload.whiteboard_id;
|
||||
whiteboardId = payload.whiteboard_id;
|
||||
Meteor.WhiteboardCleanStatus.update({
|
||||
meetingId: meetingId
|
||||
}, {
|
||||
@ -466,48 +474,51 @@ Meteor.startup(() => {
|
||||
|
||||
// for now not handling this serially #TODO
|
||||
} else if(eventName === "undo_whiteboard_request") {
|
||||
whiteboardId = message.payload.whiteboard_id;
|
||||
shapeId = message.payload.shape_id;
|
||||
whiteboardId = payload.whiteboard_id;
|
||||
shapeId = payload.shape_id;
|
||||
removeShapeFromSlide(meetingId, whiteboardId, shapeId);
|
||||
return callback();
|
||||
|
||||
// for now not handling this serially #TODO
|
||||
} else if(eventName === "presentation_page_resized_message") {
|
||||
slideId = (ref14 = message.payload.page) != null ? ref14.id : void 0;
|
||||
heightRatio = (ref15 = message.payload.page) != null ? ref15.height_ratio : void 0;
|
||||
widthRatio = (ref16 = message.payload.page) != null ? ref16.width_ratio : void 0;
|
||||
xOffset = (ref17 = message.payload.page) != null ? ref17.x_offset : void 0;
|
||||
yOffset = (ref18 = message.payload.page) != null ? ref18.y_offset : void 0;
|
||||
presentationId = slideId.split("/")[0];
|
||||
page = payload.page;
|
||||
if(page != null && page.id != null && page.height_ratio != null && page.width_ratio != null && page.x_offset != null && page.y_offset != null) {
|
||||
slideId = page.id;
|
||||
heightRatio = page.height_ratio;
|
||||
widthRatio = page.width_ratio;
|
||||
xOffset = page.x_offset;
|
||||
yOffset = page.y_offset;
|
||||
presentationId = slideId.split("/")[0];
|
||||
|
||||
/*In the case when we don't resize, but switch a slide, this message
|
||||
follows a 'presentation_page_changed' and all these properties are already set. */
|
||||
var currentSlide = Meteor.Slides.findOne({presentationId: presentationId,
|
||||
"slide.current": true});
|
||||
if(currentSlide) {
|
||||
currentSlide = currentSlide.slide;
|
||||
/*In the case when we don't resize, but switch a slide, this message
|
||||
follows a 'presentation_page_changed' and all these properties are already set. */
|
||||
var currentSlide = Meteor.Slides.findOne(
|
||||
{presentationId: presentationId,
|
||||
"slide.current": true});
|
||||
if(currentSlide) {
|
||||
currentSlide = currentSlide.slide;
|
||||
}
|
||||
if(currentSlide != null && (currentSlide.height_ratio != heightRatio || currentSlide.width_ratio != widthRatio
|
||||
|| currentSlide.x_offset != xOffset || currentSlide.y_offset != yOffset)) {
|
||||
Meteor.Slides.update({
|
||||
presentationId: presentationId,
|
||||
"slide.current": true
|
||||
}, {
|
||||
$set: {
|
||||
"slide.height_ratio": heightRatio,
|
||||
"slide.width_ratio": widthRatio,
|
||||
"slide.x_offset": xOffset,
|
||||
"slide.y_offset": yOffset
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
if(currentSlide.height_ratio != heightRatio || currentSlide.width_ratio != widthRatio
|
||||
|| currentSlide.x_offset != xOffset || currentSlide.y_offset != yOffset) {
|
||||
Meteor.Slides.update({
|
||||
presentationId: presentationId,
|
||||
"slide.current": true
|
||||
}, {
|
||||
$set: {
|
||||
"slide.height_ratio": heightRatio,
|
||||
"slide.width_ratio": widthRatio,
|
||||
"slide.x_offset": xOffset,
|
||||
"slide.y_offset": yOffset
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return callback();
|
||||
|
||||
// for now not handling this serially #TODO
|
||||
} else if(eventName === "recording_status_changed_message") {
|
||||
intendedForRecording = message.payload.recorded;
|
||||
currentlyBeingRecorded = message.payload.recording;
|
||||
intendedForRecording = payload.recorded;
|
||||
currentlyBeingRecorded = payload.recording;
|
||||
Meteor.Meetings.update({
|
||||
meetingId: meetingId,
|
||||
intendedForRecording: intendedForRecording
|
||||
@ -526,40 +537,42 @@ Meteor.startup(() => {
|
||||
|
||||
// for now not handling this serially #TODO
|
||||
} else if(eventName === "new_permission_settings") {
|
||||
oldSettings = (ref19 = Meteor.Meetings.findOne({
|
||||
meetingObject = Meteor.Meetings.findOne({
|
||||
meetingId: meetingId
|
||||
})) != null ? ref19.roomLockSettings : void 0;
|
||||
newSettings = (ref20 = message.payload) != null ? ref20.permissions : void 0;
|
||||
|
||||
// if the disableMic setting was turned on
|
||||
if(!(oldSettings != null ? oldSettings.disableMic : void 0) && newSettings.disableMic) {
|
||||
handleLockingMic(meetingId, newSettings);
|
||||
}
|
||||
|
||||
// substitute with the new lock settings
|
||||
Meteor.Meetings.update({
|
||||
meetingId: meetingId
|
||||
}, {
|
||||
$set: {
|
||||
'roomLockSettings.disablePrivateChat': newSettings.disablePrivateChat,
|
||||
'roomLockSettings.disableCam': newSettings.disableCam,
|
||||
'roomLockSettings.disableMic': newSettings.disableMic,
|
||||
'roomLockSettings.lockOnJoin': newSettings.lockOnJoin,
|
||||
'roomLockSettings.lockedLayout': newSettings.lockedLayout,
|
||||
'roomLockSettings.disablePublicChat': newSettings.disablePublicChat,
|
||||
'roomLockSettings.lockOnJoinConfigurable': newSettings.lockOnJoinConfigurable
|
||||
}
|
||||
});
|
||||
if(meetingObject != null && payload != null) {
|
||||
oldSettings = meetingObject.roomLockSettings;
|
||||
newSettings = payload.permissions;
|
||||
// if the disableMic setting was turned on
|
||||
if(oldSettings != null && !oldSettings.disableMic && newSettings.disableMic) {
|
||||
handleLockingMic(meetingId, newSettings);
|
||||
}
|
||||
|
||||
// substitute with the new lock settings
|
||||
Meteor.Meetings.update({
|
||||
meetingId: meetingId
|
||||
}, {
|
||||
$set: {
|
||||
'roomLockSettings.disablePrivateChat': newSettings.disablePrivateChat,
|
||||
'roomLockSettings.disableCam': newSettings.disableCam,
|
||||
'roomLockSettings.disableMic': newSettings.disableMic,
|
||||
'roomLockSettings.lockOnJoin': newSettings.lockOnJoin,
|
||||
'roomLockSettings.lockedLayout': newSettings.lockedLayout,
|
||||
'roomLockSettings.disablePublicChat': newSettings.disablePublicChat,
|
||||
'roomLockSettings.lockOnJoinConfigurable': newSettings.lockOnJoinConfigurable
|
||||
}
|
||||
});
|
||||
}
|
||||
return callback();
|
||||
|
||||
// for now not handling this serially #TODO
|
||||
} else if(eventName === "poll_started_message") {
|
||||
if((message.payload.meeting_id != null) && (message.payload.requester_id != null) && (message.payload.poll != null)) {
|
||||
if(payload != null && meetingId != null && payload.requester_id != null && payload.poll != null) {
|
||||
if(Meteor.Meetings.findOne({
|
||||
meetingId: message.payload.meeting_id
|
||||
meetingId: meetingId
|
||||
}) != null) {
|
||||
users = Meteor.Users.find({
|
||||
meetingId: message.payload.meeting_id
|
||||
meetingId: meetingId
|
||||
}, {
|
||||
fields: {
|
||||
"user.userid": 1,
|
||||
@ -567,10 +580,10 @@ Meteor.startup(() => {
|
||||
}
|
||||
}).fetch();
|
||||
addPollToCollection(
|
||||
message.payload.poll,
|
||||
message.payload.requester_id,
|
||||
payload.poll,
|
||||
payload.requester_id,
|
||||
users,
|
||||
message.payload.meeting_id
|
||||
meetingId
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -578,33 +591,32 @@ Meteor.startup(() => {
|
||||
|
||||
// for now not handling this serially #TODO
|
||||
} else if(eventName === "poll_stopped_message") {
|
||||
meetingId = message.payload.meeting_id;
|
||||
poll_id = message.payload.poll_id;
|
||||
clearPollCollection(meetingId, poll_id);
|
||||
if(meetingId != null && payload != null && payload.poll_id != null) {
|
||||
poll_id = payload.poll_id;
|
||||
clearPollCollection(meetingId, poll_id);
|
||||
}
|
||||
return callback();
|
||||
|
||||
// for now not handling this serially #TODO
|
||||
} else if(eventName === "user_voted_poll_message") {
|
||||
if((((ref21 = message.payload) != null ? ref21.poll : void 0) != null) && (message.payload.meeting_id != null) && (message.payload.presenter_id != null)) {
|
||||
pollObj = message.payload.poll;
|
||||
meetingId = message.payload.meeting_id;
|
||||
requesterId = message.payload.presenter_id;
|
||||
if(payload != null && payload.poll != null && meetingId != null && payload.presenter_id != null) {
|
||||
pollObj = payload.poll;
|
||||
requesterId = payload.presenter_id;
|
||||
updatePollCollection(pollObj, meetingId, requesterId);
|
||||
return callback();
|
||||
}
|
||||
|
||||
// for now not handling this serially #TODO
|
||||
} else if(eventName === "poll_show_result_message") {
|
||||
if((message.payload.poll.id != null) && (message.payload.meeting_id != null)) {
|
||||
poll_id = message.payload.poll.id;
|
||||
meetingId = message.payload.meeting_id;
|
||||
if(payload != null && payload.poll != null && payload.poll.id != null && meetingId != null) {
|
||||
poll_id = payload.poll.id;
|
||||
clearPollCollection(meetingId, poll_id);
|
||||
}
|
||||
return callback();
|
||||
} else { // keep moving in the queue
|
||||
if(indexOf.call(notLoggedEventTypes, eventName) < 0) {
|
||||
Meteor.log.info(`WARNING!!! THE JSON MESSAGE WAS NOT OF TYPE SUPPORTED BY THIS APPLICATION
|
||||
${eventName} {JSON.stringify message}`);
|
||||
${eventName} \n {JSON.stringify(message)}`);
|
||||
}
|
||||
return callback();
|
||||
}
|
||||
|
@ -52,7 +52,7 @@ moderator = {
|
||||
// holds the values for whether the viewer user is allowed to perform an action (true)
|
||||
// or false if not allowed. Some actions have dynamic values depending on the current lock settings
|
||||
viewer = function(meetingId, userId) {
|
||||
let ref, ref1, ref2, ref3, ref4, ref5, ref6, ref7;
|
||||
let meeting, user;
|
||||
return {
|
||||
|
||||
// listen only
|
||||
@ -68,12 +68,8 @@ viewer = function(meetingId, userId) {
|
||||
|
||||
// muting
|
||||
muteSelf: true,
|
||||
unmuteSelf: !((ref = Meteor.Meetings.findOne({
|
||||
meetingId: meetingId
|
||||
})) != null ? ref.roomLockSettings.disableMic : void 0) || !((ref1 = Meteor.Users.findOne({
|
||||
meetingId: meetingId,
|
||||
userId: userId
|
||||
})) != null ? ref1.user.locked : void 0),
|
||||
unmuteSelf: !((meeting = Meteor.Meetings.findOne({ meetingId: meetingId })) != null && meeting.roomLockSettings.disableMic) ||
|
||||
!((user = Meteor.Users.findOne({ meetingId: meetingId, userId: userId })) != null && user.user.locked),
|
||||
|
||||
logoutSelf: true,
|
||||
|
||||
@ -82,24 +78,13 @@ viewer = function(meetingId, userId) {
|
||||
subscribeChat: true,
|
||||
|
||||
//chat
|
||||
chatPublic: !((ref2 = Meteor.Meetings.findOne({
|
||||
meetingId: meetingId
|
||||
})) != null ? ref2.roomLockSettings.disablePublicChat : void 0) || !((ref3 = Meteor.Users.findOne({
|
||||
meetingId: meetingId,
|
||||
userId: userId
|
||||
})) != null ? ref3.user.locked : void 0) || ((ref4 = Meteor.Users.findOne({
|
||||
meetingId: meetingId,
|
||||
userId: userId
|
||||
})) != null ? ref4.user.presenter : void 0),
|
||||
chatPrivate: !((ref5 = Meteor.Meetings.findOne({
|
||||
meetingId: meetingId
|
||||
})) != null ? ref5.roomLockSettings.disablePrivateChat : void 0) || !((ref6 = Meteor.Users.findOne({
|
||||
meetingId: meetingId,
|
||||
userId: userId
|
||||
})) != null ? ref6.user.locked : void 0) || ((ref7 = Meteor.Users.findOne({
|
||||
meetingId: meetingId,
|
||||
userId: userId
|
||||
})) != null ? ref7.user.presenter : void 0),
|
||||
chatPublic: !((meeting = Meteor.Meetings.findOne({ meetingId: meetingId })) != null && meeting.roomLockSettings.disablePublicChat) ||
|
||||
!((user = Meteor.Users.findOne({ meetingId: meetingId, userId: userId })) != null && user.user.locked) ||
|
||||
(user != null && user.user.presenter),
|
||||
|
||||
chatPrivate: !((meeting = Meteor.Meetings.findOne({ meetingId: meetingId })) != null && meeting.roomLockSettings.disablePrivateChat) ||
|
||||
!((user = Meteor.Users.findOne({ meetingId: meetingId, userId: userId })) != null && user.user.locked) ||
|
||||
(user != null && user.user.presenter),
|
||||
|
||||
//poll
|
||||
subscribePoll: true,
|
||||
@ -114,11 +99,14 @@ viewer = function(meetingId, userId) {
|
||||
// carries out the decision making for actions affecting users. For the list of
|
||||
// actions and the default value - see 'viewer' and 'moderator' in the beginning of the file
|
||||
this.isAllowedTo = function(action, meetingId, userId, authToken) {
|
||||
let ref, ref1, ref2, ref3, user, validated;
|
||||
validated = (ref = Meteor.Users.findOne({
|
||||
let user, validated;
|
||||
user = Meteor.Users.findOne({
|
||||
meetingId: meetingId,
|
||||
userId: userId
|
||||
})) != null ? ref.validated : void 0;
|
||||
});
|
||||
if(user != null) {
|
||||
validated = user.validated;
|
||||
}
|
||||
Meteor.log.info(`in isAllowedTo: action-${action}, userId=${userId}, authToken=${authToken} validated:${validated}`);
|
||||
user = Meteor.Users.findOne({
|
||||
meetingId: meetingId,
|
||||
@ -130,17 +118,17 @@ this.isAllowedTo = function(action, meetingId, userId, authToken) {
|
||||
|
||||
// PRESENTER
|
||||
// check presenter specific actions or fallback to regular viewer actions
|
||||
if((ref1 = user.user) != null ? ref1.presenter : void 0) {
|
||||
if(user.user != null && user.user.presenter) {
|
||||
Meteor.log.info("user permissions presenter case");
|
||||
return presenter[action] || viewer(meetingId, userId)[action] || false;
|
||||
|
||||
// VIEWER
|
||||
} else if(((ref2 = user.user) != null ? ref2.role : void 0) === 'VIEWER') {
|
||||
} else if(user.user != null && user.user.role === 'VIEWER') {
|
||||
Meteor.log.info("user permissions viewer case");
|
||||
return viewer(meetingId, userId)[action] || false;
|
||||
|
||||
// MODERATOR
|
||||
} else if(((ref3 = user.user) != null ? ref3.role : void 0) === 'MODERATOR') {
|
||||
} else if(user.user != null && user.user.role === 'MODERATOR') {
|
||||
Meteor.log.info("user permissions moderator case");
|
||||
return moderator[action] || false;
|
||||
} else {
|
||||
@ -157,7 +145,9 @@ this.isAllowedTo = function(action, meetingId, userId, authToken) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
Meteor.log.error(`..while the authToken was ${user != null ? user.authToken : void 0} and the user's object is ${JSON.stringify(user)}in meetingId=${meetingId} userId=${userId} tried to perform ${action} without permission${"\n..while the authToken was " + (user != null ? user.authToken : void 0) + " and the user's object is " + (JSON.stringify(user))}`);
|
||||
Meteor.log.error(`in meetingId=${meetingId} userId=${userId} tried to perform ${action} without permission${"\n..while the authToken was " +
|
||||
(user != null && user.authToken != null ? user.authToken : void 0) + " and the user's object is " + (JSON.stringify(user))}`);
|
||||
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user