0365018e92
Moderators are able to send a message to the meeting's guest lobby. This new event reaches bbb-web and is sent to the guest user with her/his status response while polling. All guest users that are waiting for acceptance will be able to read this message. enableGuestLobbyMessage is disabled by default.
198 lines
5.7 KiB
JavaScript
Executable File
198 lines
5.7 KiB
JavaScript
Executable File
import flat from 'flat';
|
|
import {
|
|
check,
|
|
Match,
|
|
} from 'meteor/check';
|
|
import SanitizeHTML from 'sanitize-html';
|
|
import Meetings, { RecordMeetings } from '/imports/api/meetings';
|
|
import Logger from '/imports/startup/server/logger';
|
|
import createNote from '/imports/api/note/server/methods/createNote';
|
|
import createCaptions from '/imports/api/captions/server/methods/createCaptions';
|
|
import { addAnnotationsStreamer } from '/imports/api/annotations/server/streamer';
|
|
import { addCursorStreamer } from '/imports/api/cursor/server/streamer';
|
|
import { addExternalVideoStreamer } from '/imports/api/external-videos/server/streamer';
|
|
import BannedUsers from '/imports/api/users/server/store/bannedUsers';
|
|
|
|
export default function addMeeting(meeting) {
|
|
const meetingId = meeting.meetingProp.intId;
|
|
|
|
check(meetingId, String);
|
|
check(meeting, {
|
|
breakoutProps: {
|
|
sequence: Number,
|
|
freeJoin: Boolean,
|
|
breakoutRooms: Array,
|
|
parentId: String,
|
|
enabled: Boolean,
|
|
record: Boolean,
|
|
privateChatEnabled: Boolean,
|
|
},
|
|
meetingProp: {
|
|
intId: String,
|
|
extId: String,
|
|
isBreakout: Boolean,
|
|
name: String,
|
|
},
|
|
usersProp: {
|
|
webcamsOnlyForModerator: Boolean,
|
|
guestPolicy: String,
|
|
authenticatedGuest: Boolean,
|
|
maxUsers: Number,
|
|
allowModsToUnmuteUsers: Boolean,
|
|
},
|
|
durationProps: {
|
|
createdTime: Number,
|
|
duration: Number,
|
|
createdDate: String,
|
|
meetingExpireIfNoUserJoinedInMinutes: Number,
|
|
meetingExpireWhenLastUserLeftInMinutes: Number,
|
|
userInactivityInspectTimerInMinutes: Number,
|
|
userInactivityThresholdInMinutes: Number,
|
|
userActivitySignResponseDelayInMinutes: Number,
|
|
timeRemaining: Number,
|
|
},
|
|
welcomeProp: {
|
|
welcomeMsg: String,
|
|
modOnlyMessage: String,
|
|
welcomeMsgTemplate: String,
|
|
},
|
|
recordProp: Match.ObjectIncluding({
|
|
allowStartStopRecording: Boolean,
|
|
autoStartRecording: Boolean,
|
|
record: Boolean,
|
|
}),
|
|
password: {
|
|
viewerPass: String,
|
|
moderatorPass: String,
|
|
},
|
|
voiceProp: {
|
|
voiceConf: String,
|
|
dialNumber: String,
|
|
telVoice: String,
|
|
muteOnStart: Boolean,
|
|
},
|
|
screenshareProps: {
|
|
red5ScreenshareIp: String,
|
|
red5ScreenshareApp: String,
|
|
screenshareConf: String,
|
|
},
|
|
metadataProp: Object,
|
|
lockSettingsProps: {
|
|
disableCam: Boolean,
|
|
disableMic: Boolean,
|
|
disablePrivateChat: Boolean,
|
|
disablePublicChat: Boolean,
|
|
disableNote: Boolean,
|
|
hideUserList: Boolean,
|
|
lockOnJoin: Boolean,
|
|
lockOnJoinConfigurable: Boolean,
|
|
lockedLayout: Boolean,
|
|
},
|
|
systemProps: {
|
|
html5InstanceId: Number,
|
|
},
|
|
});
|
|
|
|
const {
|
|
recordProp,
|
|
...restProps
|
|
} = meeting;
|
|
|
|
const newMeeting = restProps;
|
|
|
|
const selector = {
|
|
meetingId,
|
|
};
|
|
|
|
newMeeting.lockSettingsProps = Object.assign(meeting.lockSettingsProps, { setBy: 'temp' });
|
|
|
|
const meetingEnded = false;
|
|
|
|
let { welcomeMsg } = newMeeting.welcomeProp;
|
|
|
|
const sanitizeTextInChat = original => SanitizeHTML(original, {
|
|
allowedTags: ['a', 'b', 'br', 'i', 'img', 'li', 'small', 'span', 'strong', 'u', 'ul'],
|
|
allowedAttributes: {
|
|
a: ['href', 'name', 'target'],
|
|
img: ['src', 'width', 'height'],
|
|
},
|
|
allowedSchemes: ['https'],
|
|
});
|
|
|
|
const sanitizedWelcomeText = sanitizeTextInChat(welcomeMsg);
|
|
welcomeMsg = sanitizedWelcomeText.replace(
|
|
'href="event:',
|
|
'href="',
|
|
);
|
|
|
|
const insertBlankTarget = (s, i) => `${s.substr(0, i)} target="_blank"${s.substr(i)}`;
|
|
const linkWithoutTarget = new RegExp('<a href="(.*?)">', 'g');
|
|
linkWithoutTarget.test(welcomeMsg);
|
|
|
|
if (linkWithoutTarget.lastIndex > 0) {
|
|
welcomeMsg = insertBlankTarget(
|
|
welcomeMsg,
|
|
linkWithoutTarget.lastIndex - 1,
|
|
);
|
|
}
|
|
|
|
newMeeting.welcomeProp.welcomeMsg = welcomeMsg;
|
|
|
|
// note: as of July 2020 `modOnlyMessage` is not published to the client side.
|
|
// We are sanitizing this data simply to prevent future potential usage
|
|
// At the moment `modOnlyMessage` is obtained from client side as a response to Enter API
|
|
newMeeting.welcomeProp.modOnlyMessage = sanitizeTextInChat(newMeeting.welcomeProp.modOnlyMessage);
|
|
|
|
const modifier = {
|
|
$set: Object.assign({
|
|
meetingId,
|
|
meetingEnded,
|
|
publishedPoll: false,
|
|
guestLobbyMessage: '',
|
|
randomlySelectedUser: '',
|
|
}, flat(newMeeting, {
|
|
safe: true,
|
|
})),
|
|
};
|
|
|
|
if (!process.env.BBB_HTML5_ROLE || process.env.BBB_HTML5_ROLE === 'frontend') {
|
|
addAnnotationsStreamer(meetingId);
|
|
addCursorStreamer(meetingId);
|
|
addExternalVideoStreamer(meetingId);
|
|
|
|
// we don't want to fully process the create meeting message in frontend since it can lead to duplication of meetings in mongo.
|
|
if (process.env.BBB_HTML5_ROLE === 'frontend') {
|
|
return;
|
|
}
|
|
}
|
|
|
|
try {
|
|
const { insertedId, numberAffected } = RecordMeetings.upsert(selector, { meetingId, ...recordProp });
|
|
|
|
if (insertedId) {
|
|
Logger.info(`Added record prop id=${meetingId}`);
|
|
} else if (numberAffected) {
|
|
Logger.info(`Upserted record prop id=${meetingId}`);
|
|
}
|
|
} catch (err) {
|
|
Logger.error(`Adding record prop to collection: ${err}`);
|
|
}
|
|
|
|
try {
|
|
const { insertedId, numberAffected } = Meetings.upsert(selector, modifier);
|
|
|
|
if (insertedId) {
|
|
Logger.info(`Added meeting id=${meetingId}`);
|
|
// TODO: Here we call Etherpad API to create this meeting notes. Is there a
|
|
// better place we can run this post-creation routine?
|
|
createNote(meetingId);
|
|
createCaptions(meetingId);
|
|
BannedUsers.init(meetingId);
|
|
} else if (numberAffected) {
|
|
Logger.info(`Upserted meeting id=${meetingId}`);
|
|
}
|
|
} catch (err) {
|
|
Logger.error(`Adding meeting to collection: ${err}`);
|
|
}
|
|
}
|