You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

moderator.js 7.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. /* global $, $iq, config, connection, Etherpad, hangUp, messageHandler,
  2. roomName, sessionTerminated, Strophe, Toolbar, Util, VideoLayout */
  3. /**
  4. * Contains logic responsible for enabling/disabling functionality available
  5. * only to moderator users.
  6. */
  7. var Moderator = (function (my) {
  8. var focusUserJid;
  9. var getNextTimeout = Util.createExpBackoffTimer(1000);
  10. var getNextErrorTimeout = Util.createExpBackoffTimer(1000);
  11. // External authentication stuff
  12. var externalAuthEnabled = false;
  13. my.isModerator = function () {
  14. return connection.emuc.isModerator();
  15. };
  16. my.isPeerModerator = function (peerJid) {
  17. return connection.emuc.getMemberRole(peerJid) === 'moderator';
  18. };
  19. my.isExternalAuthEnabled = function () {
  20. return externalAuthEnabled;
  21. };
  22. my.onModeratorStatusChanged = function (isModerator) {
  23. Toolbar.showSipCallButton(isModerator);
  24. Toolbar.showRecordingButton(
  25. isModerator); //&&
  26. // FIXME:
  27. // Recording visible if
  28. // there are at least 2(+ 1 focus) participants
  29. //Object.keys(connection.emuc.members).length >= 3);
  30. if (isModerator && config.etherpad_base) {
  31. Etherpad.init();
  32. }
  33. };
  34. my.init = function () {
  35. $(document).bind(
  36. 'local.role.changed.muc',
  37. function (event, jid, info, pres) {
  38. Moderator.onModeratorStatusChanged(Moderator.isModerator());
  39. }
  40. );
  41. $(document).bind(
  42. 'left.muc',
  43. function (event, jid) {
  44. console.info("Someone left is it focus ? " + jid);
  45. var resource = Strophe.getResourceFromJid(jid);
  46. if (resource === 'focus' && !sessionTerminated) {
  47. console.info(
  48. "Focus has left the room - leaving conference");
  49. //hangUp();
  50. // We'd rather reload to have everything re-initialized
  51. // FIXME: show some message before reload
  52. location.reload();
  53. }
  54. }
  55. );
  56. };
  57. my.setFocusUserJid = function (focusJid) {
  58. if (!focusUserJid) {
  59. focusUserJid = focusJid;
  60. console.info("Focus jid set to: " + focusUserJid);
  61. }
  62. };
  63. my.getFocusUserJid = function () {
  64. return focusUserJid;
  65. };
  66. my.getFocusComponent = function () {
  67. // Get focus component address
  68. var focusComponent = config.hosts.focus;
  69. // If not specified use default: 'focus.domain'
  70. if (!focusComponent) {
  71. focusComponent = 'focus.' + config.hosts.domain;
  72. }
  73. return focusComponent;
  74. };
  75. my.createConferenceIq = function () {
  76. // Generate create conference IQ
  77. var elem = $iq({to: Moderator.getFocusComponent(), type: 'set'});
  78. elem.c('conference', {
  79. xmlns: 'http://jitsi.org/protocol/focus',
  80. room: roomName
  81. });
  82. if (config.hosts.bridge !== undefined)
  83. {
  84. elem.c(
  85. 'property',
  86. { name: 'bridge', value: config.hosts.bridge})
  87. .up();
  88. }
  89. if (config.channelLastN !== undefined)
  90. {
  91. elem.c(
  92. 'property',
  93. { name: 'channelLastN', value: config.channelLastN})
  94. .up();
  95. }
  96. if (config.adaptiveLastN !== undefined)
  97. {
  98. elem.c(
  99. 'property',
  100. { name: 'adaptiveLastN', value: config.adaptiveLastN})
  101. .up();
  102. }
  103. if (config.adaptiveSimulcast !== undefined)
  104. {
  105. elem.c(
  106. 'property',
  107. { name: 'adaptiveSimulcast', value: config.adaptiveSimulcast})
  108. .up();
  109. }
  110. if (config.openSctp !== undefined)
  111. {
  112. elem.c(
  113. 'property',
  114. { name: 'openSctp', value: config.openSctp})
  115. .up();
  116. }
  117. if (config.enableFirefoxSupport !== undefined)
  118. {
  119. elem.c(
  120. 'property',
  121. { name: 'enableFirefoxHacks', value: config.enableFirefoxSupport})
  122. .up();
  123. }
  124. elem.up();
  125. return elem;
  126. };
  127. my.parseConfigOptions = function (resultIq) {
  128. Moderator.setFocusUserJid(
  129. $(resultIq).find('conference').attr('focusjid'));
  130. var extAuthParam
  131. = $(resultIq).find('>conference>property[name=\'externalAuth\']');
  132. if (extAuthParam.length) {
  133. externalAuthEnabled = extAuthParam.attr('value') === 'true';
  134. }
  135. console.info("External authentication enabled: " + externalAuthEnabled);
  136. };
  137. // FIXME: we need to show the fact that we're waiting for the focus
  138. // to the user(or that focus is not available)
  139. my.allocateConferenceFocus = function (roomName, callback) {
  140. // Try to use focus user JID from the config
  141. Moderator.setFocusUserJid(config.focusUserJid);
  142. // Send create conference IQ
  143. var iq = Moderator.createConferenceIq();
  144. connection.sendIQ(
  145. iq,
  146. function (result) {
  147. if ('true' === $(result).find('conference').attr('ready')) {
  148. // Reset both timers
  149. getNextTimeout(true);
  150. getNextErrorTimeout(true);
  151. // Setup config options
  152. Moderator.parseConfigOptions(result);
  153. // Exec callback
  154. callback();
  155. } else {
  156. var waitMs = getNextTimeout();
  157. console.info("Waiting for the focus... " + waitMs);
  158. // Reset error timeout
  159. getNextErrorTimeout(true);
  160. window.setTimeout(
  161. function () {
  162. Moderator.allocateConferenceFocus(
  163. roomName, callback);
  164. }, waitMs);
  165. }
  166. },
  167. function (error) {
  168. // Not authorized to create new room
  169. if ($(error).find('>error>not-authorized').length) {
  170. console.warn("Unauthorized to start the conference");
  171. $(document).trigger('auth_required.moderator');
  172. return;
  173. }
  174. var waitMs = getNextErrorTimeout();
  175. console.error("Focus error, retry after " + waitMs, error);
  176. // Show message
  177. messageHandler.notify(
  178. 'Conference focus', 'disconnected',
  179. Moderator.getFocusComponent() +
  180. ' not available - retry in ' + (waitMs / 1000) + ' sec');
  181. // Reset response timeout
  182. getNextTimeout(true);
  183. window.setTimeout(
  184. function () {
  185. Moderator.allocateConferenceFocus(roomName, callback);
  186. }, waitMs);
  187. }
  188. );
  189. };
  190. my.getAuthUrl = function (urlCallback) {
  191. var iq = $iq({to: Moderator.getFocusComponent(), type: 'get'});
  192. iq.c('auth-url', {
  193. xmlns: 'http://jitsi.org/protocol/focus',
  194. room: roomName
  195. });
  196. connection.sendIQ(
  197. iq,
  198. function (result) {
  199. var url = $(result).find('auth-url').attr('url');
  200. if (url) {
  201. console.info("Got auth url: " + url);
  202. urlCallback(url);
  203. } else {
  204. console.error(
  205. "Failed to get auth url fro mthe focus", result);
  206. }
  207. },
  208. function (error) {
  209. console.error("Get auth url error", error);
  210. }
  211. );
  212. };
  213. return my;
  214. }(Moderator || {}));