diff --git a/bigbluebutton-html5/imports/api/users/server/eventHandlers.js b/bigbluebutton-html5/imports/api/users/server/eventHandlers.js
new file mode 100644
index 0000000000..a6a874ce0f
--- /dev/null
+++ b/bigbluebutton-html5/imports/api/users/server/eventHandlers.js
@@ -0,0 +1,4 @@
+import RedisPubSub from '/imports/startup/server/redis';
+// import handleSlideResize from './handlers/slideResize';
+
+// RedisPubSub.on('presentation_page_resized_message', handleSlideResize);
diff --git a/bigbluebutton-html5/imports/api/users/server/handlers/slideChange.js b/bigbluebutton-html5/imports/api/users/server/handlers/slideChange.js
new file mode 100644
index 0000000000..dd24043b97
--- /dev/null
+++ b/bigbluebutton-html5/imports/api/users/server/handlers/slideChange.js
@@ -0,0 +1,16 @@
+import Logger from '/imports/startup/server/logger';
+import { check } from 'meteor/check';
+import changeCurrentSlide from '../modifiers/changeCurrentSlide';
+
+export default function handleSlideChange({ payload }) {
+ const meetingId = payload.meeting_id;
+ const slide = payload.page;
+
+ check(meetingId, String);
+ check(slide, Object);
+
+ const slideId = slide.id;
+ const presentationId = slideId.split('/')[0];
+
+ return changeCurrentSlide(meetingId, presentationId, slideId);
+};
diff --git a/bigbluebutton-html5/imports/api/users/server/handlers/slideResize.js b/bigbluebutton-html5/imports/api/users/server/handlers/slideResize.js
new file mode 100644
index 0000000000..880d08daeb
--- /dev/null
+++ b/bigbluebutton-html5/imports/api/users/server/handlers/slideResize.js
@@ -0,0 +1,17 @@
+import Logger from '/imports/startup/server/logger';
+import Slides from '/imports/api/slides';
+import { check } from 'meteor/check';
+import resizeSlide from '../modifiers/resizeSlide';
+
+export default function handleSlideResize({ payload }) {
+ const meetingId = payload.meeting_id;
+ const slide = payload.page;
+
+ check(meetingId, String);
+ check(slide, Object);
+
+ const slideId = slide.id;
+ const presentationId = slideId.split('/')[0];
+
+ return resizeSlide(meetingId, presentationId, slideId, slide);
+};
diff --git a/bigbluebutton-html5/imports/api/users/server/index.js b/bigbluebutton-html5/imports/api/users/server/index.js
new file mode 100644
index 0000000000..92451ac76b
--- /dev/null
+++ b/bigbluebutton-html5/imports/api/users/server/index.js
@@ -0,0 +1,3 @@
+import './eventHandlers';
+import './methods';
+import './publishers';
diff --git a/bigbluebutton-html5/imports/api/users/server/methods.js b/bigbluebutton-html5/imports/api/users/server/methods.js
new file mode 100644
index 0000000000..7a06279985
--- /dev/null
+++ b/bigbluebutton-html5/imports/api/users/server/methods.js
@@ -0,0 +1,6 @@
+import { Meteor } from 'meteor/meteor';
+import kickUser from './methods/kickUser';
+
+Meteor.methods({
+ kickUser,
+});
diff --git a/bigbluebutton-html5/imports/api/users/server/methods/kickUser.js b/bigbluebutton-html5/imports/api/users/server/methods/kickUser.js
index 103104a388..7c9804d415 100755
--- a/bigbluebutton-html5/imports/api/users/server/methods/kickUser.js
+++ b/bigbluebutton-html5/imports/api/users/server/methods/kickUser.js
@@ -1,25 +1,30 @@
+import { check } from 'meteor/check';
+import RedisPubSub from '/imports/startup/server/redis';
+import Logger from '/imports/startup/server/logger';
import { isAllowedTo } from '/imports/startup/server/userPermissions';
-import { appendMessageHeader, publish } from '/imports/api/common/server/helpers';
-Meteor.methods({
- //meetingId: the meeting where the user is
- //toKickUserId: the userid of the user to kick
- //requesterUserId: the userid of the user that wants to kick
- //authToken: the authToken of the user that wants to kick
- kickUser(credentials, toKickUserId) {
- const REDIS_CONFIG = Meteor.settings.redis;
- const { meetingId, requesterUserId, requesterToken } = credentials;
- let message;
- if (isAllowedTo('kickUser', credentials)) {
- message = {
- payload: {
- userid: toKickUserId,
- ejected_by: requesterUserId,
- meeting_id: meetingId,
- },
- };
- message = appendMessageHeader('eject_user_from_meeting_request_message', message);
- return publish(REDIS_CONFIG.channels.toBBBApps.users, message);
- }
- },
-});
+export default function kickUser(credentials, userId) {
+ const REDIS_CONFIG = Meteor.settings.redis;
+ const CHANNEL = REDIS_CONFIG.channels.toBBBApps.users;
+ const EVENT_NAME = 'eject_user_from_meeting_request_message';
+
+ if (!isAllowedTo('kickUser', credentials)) {
+ throw new Meteor.Error('not-allowed', `You are not allowed to kickUser`);
+ }
+
+ const { meetingId, requesterUserId } = credentials;
+
+ check(meetingId, String);
+ check(requesterUserId, String);
+ check(userId, String);
+
+ let payload = {
+ userid: userId,
+ ejected_by: requesterUserId,
+ meeting_id: meetingId,
+ };
+
+ Logger.verbose(`User '${userId}' was kicked by '${requesterUserId}' from meeting '${meetingId}'`);
+
+ return RedisPubSub.publish(CHANNEL, EVENT_NAME, payload);
+};
diff --git a/bigbluebutton-html5/imports/api/users/server/publishers.js b/bigbluebutton-html5/imports/api/users/server/publishers.js
new file mode 100644
index 0000000000..1bd5a2cd00
--- /dev/null
+++ b/bigbluebutton-html5/imports/api/users/server/publishers.js
@@ -0,0 +1,44 @@
+import Users from '/imports/api/Users';
+import { Meteor } from 'meteor/meteor';
+import { check } from 'meteor/check';
+import Logger from '/imports/startup/server/logger';
+import { isAllowedTo } from '/imports/startup/server/userPermissions';
+
+Meteor.publish('Users', function (credentials) {
+ // TODO: Some publishers have ACL and others dont
+ // if (!isAllowedTo('@@@', credentials)) {
+ // this.error(new Meteor.Error(402, "The user was not authorized to subscribe for 'Users'"));
+ // }
+
+ const { meetingId, requesterUserId, requesterToken } = credentials;
+
+ check(meetingId, String);
+ check(requesterUserId, String);
+ check(requesterToken, String);
+
+ // TODO:
+ // - Add reconnection handlers
+ // - Add validateAuthToken stuff
+ // - Update `connection_status` when the user disconnects
+
+ this.onStop(() => {
+ // update connection_status info to offline
+ });
+
+ const selector = {
+ meetingId,
+ 'user.connection_status': {
+ $in: ['online', ''],
+ },
+ };
+
+ const options = {
+ fields: {
+ authToken: false,
+ },
+ };
+
+ Logger.info(`Publishing Users for ${meetingId} ${requesterUserId} ${requesterToken}`);
+
+ return Users.find(selector, options);
+});
diff --git a/bigbluebutton-html5/server/main.js b/bigbluebutton-html5/server/main.js
index ea6ded8183..eb9284b2fc 100755
--- a/bigbluebutton-html5/server/main.js
+++ b/bigbluebutton-html5/server/main.js
@@ -27,8 +27,7 @@ import '/imports/api/captions/server/publications';
import '/imports/api/captions/server/modifiers/clearCaptionsCollection';
import '/imports/api/captions/server/modifiers/eventHandlers';
-import '/imports/api/users/server/publications';
-import '/imports/api/users/server/methods/kickUser';
+import '/imports/api/users/server';
import '/imports/api/users/server/methods/listenOnlyRequestToggle';
import '/imports/api/users/server/methods/muteUser';
import '/imports/api/users/server/methods/setUserPresenter';