|
@@ -6,13 +6,6 @@ var Settings = require("../settings/Settings");
|
6
|
6
|
var AuthenticationEvents
|
7
|
7
|
= require("../../service/authentication/AuthenticationEvents");
|
8
|
8
|
|
9
|
|
-/**
|
10
|
|
- * Contains logic responsible for enabling/disabling functionality available
|
11
|
|
- * only to moderator users.
|
12
|
|
- */
|
13
|
|
-var connection = null;
|
14
|
|
-var focusUserJid;
|
15
|
|
-
|
16
|
9
|
function createExpBackoffTimer(step) {
|
17
|
10
|
var count = 1;
|
18
|
11
|
return function (reset) {
|
|
@@ -28,402 +21,396 @@ function createExpBackoffTimer(step) {
|
28
|
21
|
};
|
29
|
22
|
}
|
30
|
23
|
|
31
|
|
-var getNextTimeout = createExpBackoffTimer(1000);
|
32
|
|
-var getNextErrorTimeout = createExpBackoffTimer(1000);
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+function Moderator(roomName, xmpp, emitter) {
|
|
29
|
+ this.roomName = roomName;
|
|
30
|
+ this.xmppService = xmpp;
|
|
31
|
+ this.getNextTimeout = createExpBackoffTimer(1000);
|
|
32
|
+ this.getNextErrorTimeout = createExpBackoffTimer(1000);
|
33
|
33
|
// External authentication stuff
|
34
|
|
-var externalAuthEnabled = false;
|
|
34
|
+ this.externalAuthEnabled = false;
|
|
35
|
+ this.settings = new Settings(roomName);
|
35
|
36
|
// Sip gateway can be enabled by configuring Jigasi host in config.js or
|
36
|
37
|
// it will be enabled automatically if focus detects the component through
|
37
|
38
|
// service discovery.
|
38
|
|
-var sipGatewayEnabled = null;
|
39
|
|
-
|
40
|
|
-var eventEmitter = null;
|
41
|
|
-
|
42
|
|
-var Moderator = {
|
43
|
|
- isModerator: function () {
|
44
|
|
- return connection && connection.emuc.isModerator();
|
45
|
|
- },
|
46
|
|
-
|
47
|
|
- isPeerModerator: function (peerJid) {
|
48
|
|
- return connection &&
|
49
|
|
- connection.emuc.getMemberRole(peerJid) === 'moderator';
|
50
|
|
- },
|
51
|
|
-
|
52
|
|
- isExternalAuthEnabled: function () {
|
53
|
|
- return externalAuthEnabled;
|
54
|
|
- },
|
55
|
|
-
|
56
|
|
- isSipGatewayEnabled: function () {
|
57
|
|
- return sipGatewayEnabled;
|
58
|
|
- },
|
59
|
|
-
|
60
|
|
- setConnection: function (con) {
|
61
|
|
- connection = con;
|
62
|
|
- },
|
63
|
|
-
|
64
|
|
- init: function (xmpp, emitter) {
|
65
|
|
- this.xmppService = xmpp;
|
66
|
|
- sipGatewayEnabled = this.xmppService.options.hosts.call_control !== undefined;
|
67
|
|
- eventEmitter = emitter;
|
68
|
|
-
|
69
|
|
- // Message listener that talks to POPUP window
|
70
|
|
- function listener(event) {
|
71
|
|
- if (event.data && event.data.sessionId) {
|
72
|
|
- if (event.origin !== window.location.origin) {
|
73
|
|
- console.warn("Ignoring sessionId from different origin: " +
|
74
|
|
- event.origin);
|
75
|
|
- return;
|
76
|
|
- }
|
77
|
|
- localStorage.setItem('sessionId', event.data.sessionId);
|
78
|
|
- // After popup is closed we will authenticate
|
|
39
|
+ this.sipGatewayEnabled = this.xmppService.options.hosts.call_control !== undefined;
|
|
40
|
+
|
|
41
|
+ this.eventEmitter = emitter;
|
|
42
|
+
|
|
43
|
+ this.connection = this.xmppService.connection;
|
|
44
|
+ this.focusUserJid;
|
|
45
|
+ //FIXME:
|
|
46
|
+ // Message listener that talks to POPUP window
|
|
47
|
+ function listener(event) {
|
|
48
|
+ if (event.data && event.data.sessionId) {
|
|
49
|
+ if (event.origin !== window.location.origin) {
|
|
50
|
+ console.warn("Ignoring sessionId from different origin: " +
|
|
51
|
+ event.origin);
|
|
52
|
+ return;
|
79
|
53
|
}
|
|
54
|
+ localStorage.setItem('sessionId', event.data.sessionId);
|
|
55
|
+ // After popup is closed we will authenticate
|
80
|
56
|
}
|
81
|
|
- // Register
|
82
|
|
- if (window.addEventListener) {
|
83
|
|
- window.addEventListener("message", listener, false);
|
84
|
|
- } else {
|
85
|
|
- window.attachEvent("onmessage", listener);
|
86
|
|
- }
|
87
|
|
- },
|
88
|
|
-
|
89
|
|
- onMucMemberLeft: function (jid) {
|
90
|
|
- console.info("Someone left is it focus ? " + jid);
|
91
|
|
- var resource = Strophe.getResourceFromJid(jid);
|
92
|
|
- if (resource === 'focus' && !this.xmppService.sessionTerminated) {
|
93
|
|
- console.info(
|
94
|
|
- "Focus has left the room - leaving conference");
|
95
|
|
- //hangUp();
|
96
|
|
- // We'd rather reload to have everything re-initialized
|
97
|
|
- // FIXME: show some message before reload
|
98
|
|
- location.reload();
|
99
|
|
- }
|
100
|
|
- },
|
101
|
|
-
|
102
|
|
- setFocusUserJid: function (focusJid) {
|
103
|
|
- if (!focusUserJid) {
|
104
|
|
- focusUserJid = focusJid;
|
105
|
|
- console.info("Focus jid set to: " + focusUserJid);
|
106
|
|
- }
|
107
|
|
- },
|
108
|
|
-
|
109
|
|
- getFocusUserJid: function () {
|
110
|
|
- return focusUserJid;
|
111
|
|
- },
|
112
|
|
-
|
113
|
|
- getFocusComponent: function () {
|
114
|
|
- // Get focus component address
|
115
|
|
- var focusComponent = this.xmppService.options.hosts.focus;
|
116
|
|
- // If not specified use default: 'focus.domain'
|
117
|
|
- if (!focusComponent) {
|
118
|
|
- focusComponent = 'focus.' + this.xmppService.options.hosts.domain;
|
119
|
|
- }
|
120
|
|
- return focusComponent;
|
121
|
|
- },
|
|
57
|
+ }
|
|
58
|
+ // Register
|
|
59
|
+ if (window.addEventListener) {
|
|
60
|
+ window.addEventListener("message", listener, false);
|
|
61
|
+ } else {
|
|
62
|
+ window.attachEvent("onmessage", listener);
|
|
63
|
+ }
|
|
64
|
+}
|
|
65
|
+
|
|
66
|
+Moderator.prototype.isExternalAuthEnabled = function () {
|
|
67
|
+ return this.externalAuthEnabled;
|
|
68
|
+};
|
122
|
69
|
|
123
|
|
- createConferenceIq: function (roomName) {
|
124
|
|
- // Generate create conference IQ
|
125
|
|
- var elem = $iq({to: Moderator.getFocusComponent(), type: 'set'});
|
|
70
|
+Moderator.prototype.isSipGatewayEnabled = function () {
|
|
71
|
+ return this.sipGatewayEnabled;
|
|
72
|
+};
|
126
|
73
|
|
127
|
|
- // Session Id used for authentication
|
128
|
|
- var sessionId = localStorage.getItem('sessionId');
|
129
|
|
- var machineUID = Settings.getSettings().uid;
|
130
|
74
|
|
|
75
|
+Moderator.prototype.onMucMemberLeft = function (jid) {
|
|
76
|
+ console.info("Someone left is it focus ? " + jid);
|
|
77
|
+ var resource = Strophe.getResourceFromJid(jid);
|
|
78
|
+ if (resource === 'focus' && !this.xmppService.sessionTerminated) {
|
131
|
79
|
console.info(
|
132
|
|
- "Session ID: " + sessionId + " machine UID: " + machineUID);
|
|
80
|
+ "Focus has left the room - leaving conference");
|
|
81
|
+ //hangUp();
|
|
82
|
+ // We'd rather reload to have everything re-initialized
|
|
83
|
+ //FIXME: show some message before reload
|
|
84
|
+ this.eventEmitter.emit(XMPPEvents.FOCUS_LEFT);
|
|
85
|
+ }
|
|
86
|
+};
|
133
|
87
|
|
134
|
|
- elem.c('conference', {
|
135
|
|
- xmlns: 'http://jitsi.org/protocol/focus',
|
136
|
|
- room: roomName,
|
137
|
|
- 'machine-uid': machineUID
|
138
|
|
- });
|
139
|
88
|
|
140
|
|
- if (sessionId) {
|
141
|
|
- elem.attrs({ 'session-id': sessionId});
|
142
|
|
- }
|
|
89
|
+Moderator.prototype.setFocusUserJid = function (focusJid) {
|
|
90
|
+ if (!this.focusUserJid) {
|
|
91
|
+ this.focusUserJid = focusJid;
|
|
92
|
+ console.info("Focus jid set to: " + this.focusUserJid);
|
|
93
|
+ }
|
|
94
|
+};
|
143
|
95
|
|
144
|
|
- if (this.xmppService.options.hosts.bridge !== undefined) {
|
145
|
|
- elem.c(
|
146
|
|
- 'property',
|
147
|
|
- { name: 'bridge', value: this.xmppService.options.hosts.bridge})
|
148
|
|
- .up();
|
149
|
|
- }
|
150
|
|
- // Tell the focus we have Jigasi configured
|
151
|
|
- if (this.xmppService.options.hosts.call_control !== undefined) {
|
152
|
|
- elem.c(
|
153
|
|
- 'property',
|
154
|
|
- { name: 'call_control', value: this.xmppService.options.hosts.call_control})
|
155
|
|
- .up();
|
156
|
|
- }
|
157
|
|
- if (this.xmppService.options.channelLastN !== undefined) {
|
158
|
|
- elem.c(
|
159
|
|
- 'property',
|
160
|
|
- { name: 'channelLastN', value: this.xmppService.options.channelLastN})
|
161
|
|
- .up();
|
162
|
|
- }
|
163
|
|
- if (this.xmppService.options.adaptiveLastN !== undefined) {
|
164
|
|
- elem.c(
|
165
|
|
- 'property',
|
166
|
|
- { name: 'adaptiveLastN', value: this.xmppService.options.adaptiveLastN})
|
167
|
|
- .up();
|
168
|
|
- }
|
169
|
|
- if (this.xmppService.options.adaptiveSimulcast !== undefined) {
|
170
|
|
- elem.c(
|
171
|
|
- 'property',
|
172
|
|
- { name: 'adaptiveSimulcast', value: this.xmppService.options.adaptiveSimulcast})
|
173
|
|
- .up();
|
174
|
|
- }
|
175
|
|
- if (this.xmppService.options.openSctp !== undefined) {
|
176
|
|
- elem.c(
|
177
|
|
- 'property',
|
178
|
|
- { name: 'openSctp', value: this.xmppService.options.openSctp})
|
179
|
|
- .up();
|
180
|
|
- }
|
181
|
|
- if(this.xmppService.options.startAudioMuted !== undefined)
|
182
|
|
- {
|
183
|
|
- elem.c(
|
184
|
|
- 'property',
|
185
|
|
- { name: 'startAudioMuted', value: this.xmppService.options.startAudioMuted})
|
186
|
|
- .up();
|
187
|
|
- }
|
188
|
|
- if(this.xmppService.options.startVideoMuted !== undefined)
|
189
|
|
- {
|
190
|
|
- elem.c(
|
191
|
|
- 'property',
|
192
|
|
- { name: 'startVideoMuted', value: this.xmppService.options.startVideoMuted})
|
193
|
|
- .up();
|
194
|
|
- }
|
|
96
|
+
|
|
97
|
+Moderator.prototype.getFocusUserJid = function () {
|
|
98
|
+ return this.focusUserJid;
|
|
99
|
+};
|
|
100
|
+
|
|
101
|
+Moderator.prototype.getFocusComponent = function () {
|
|
102
|
+ // Get focus component address
|
|
103
|
+ var focusComponent = this.xmppService.options.hosts.focus;
|
|
104
|
+ // If not specified use default: 'focus.domain'
|
|
105
|
+ if (!focusComponent) {
|
|
106
|
+ focusComponent = 'focus.' + this.xmppService.options.hosts.domain;
|
|
107
|
+ }
|
|
108
|
+ return focusComponent;
|
|
109
|
+};
|
|
110
|
+
|
|
111
|
+Moderator.prototype.createConferenceIq = function () {
|
|
112
|
+ // Generate create conference IQ
|
|
113
|
+ var elem = $iq({to: this.getFocusComponent(), type: 'set'});
|
|
114
|
+
|
|
115
|
+ // Session Id used for authentication
|
|
116
|
+ var sessionId = localStorage.getItem('sessionId');
|
|
117
|
+ var machineUID = this.settings.getSettings().uid;
|
|
118
|
+
|
|
119
|
+ console.info(
|
|
120
|
+ "Session ID: " + sessionId + " machine UID: " + machineUID);
|
|
121
|
+
|
|
122
|
+ elem.c('conference', {
|
|
123
|
+ xmlns: 'http://jitsi.org/protocol/focus',
|
|
124
|
+ room: this.roomName,
|
|
125
|
+ 'machine-uid': machineUID
|
|
126
|
+ });
|
|
127
|
+
|
|
128
|
+ if (sessionId) {
|
|
129
|
+ elem.attrs({ 'session-id': sessionId});
|
|
130
|
+ }
|
|
131
|
+ if (this.xmppService.options.hosts.bridge !== undefined) {
|
195
|
132
|
elem.c(
|
196
|
133
|
'property',
|
197
|
|
- { name: 'simulcastMode', value: 'rewriting'})
|
|
134
|
+ {name: 'bridge',value: this.xmppService.options.hosts.bridge})
|
198
|
135
|
.up();
|
199
|
|
- elem.up();
|
200
|
|
- return elem;
|
201
|
|
- },
|
202
|
|
-
|
203
|
|
- parseSessionId: function (resultIq) {
|
204
|
|
- var sessionId = $(resultIq).find('conference').attr('session-id');
|
205
|
|
- if (sessionId) {
|
206
|
|
- console.info('Received sessionId: ' + sessionId);
|
207
|
|
- localStorage.setItem('sessionId', sessionId);
|
208
|
|
- }
|
209
|
|
- },
|
|
136
|
+ }
|
|
137
|
+ // Tell the focus we have Jigasi configured
|
|
138
|
+ if (this.xmppService.options.hosts.call_control !== undefined) {
|
|
139
|
+ elem.c(
|
|
140
|
+ 'property',
|
|
141
|
+ {name: 'call_control',value: this.xmppService.options.hosts.call_control})
|
|
142
|
+ .up();
|
|
143
|
+ }
|
|
144
|
+ if (this.xmppService.options.channelLastN !== undefined) {
|
|
145
|
+ elem.c(
|
|
146
|
+ 'property',
|
|
147
|
+ {name: 'channelLastN',value: this.xmppService.options.channelLastN})
|
|
148
|
+ .up();
|
|
149
|
+ }
|
|
150
|
+ if (this.xmppService.options.adaptiveLastN !== undefined) {
|
|
151
|
+ elem.c(
|
|
152
|
+ 'property',
|
|
153
|
+ {name: 'adaptiveLastN',value: this.xmppService.options.adaptiveLastN})
|
|
154
|
+ .up();
|
|
155
|
+ }
|
|
156
|
+ if (this.xmppService.options.adaptiveSimulcast !== undefined) {
|
|
157
|
+ elem.c(
|
|
158
|
+ 'property',
|
|
159
|
+ {name: 'adaptiveSimulcast',value: this.xmppService.options.adaptiveSimulcast})
|
|
160
|
+ .up();
|
|
161
|
+ }
|
|
162
|
+ if (this.xmppService.options.openSctp !== undefined) {
|
|
163
|
+ elem.c(
|
|
164
|
+ 'property',
|
|
165
|
+ {name: 'openSctp',value: this.xmppService.options.openSctp})
|
|
166
|
+ .up();
|
|
167
|
+ }
|
|
168
|
+ if(this.xmppService.options.startAudioMuted !== undefined)
|
|
169
|
+ {
|
|
170
|
+ elem.c(
|
|
171
|
+ 'property',
|
|
172
|
+ {name: 'startAudioMuted',value: this.xmppService.options.startAudioMuted})
|
|
173
|
+ .up();
|
|
174
|
+ }
|
|
175
|
+ if(this.xmppService.options.startVideoMuted !== undefined)
|
|
176
|
+ {
|
|
177
|
+ elem.c(
|
|
178
|
+ 'property',
|
|
179
|
+ {name: 'startVideoMuted',value: this.xmppService.options.startVideoMuted})
|
|
180
|
+ .up();
|
|
181
|
+ }
|
|
182
|
+ elem.c(
|
|
183
|
+ 'property',
|
|
184
|
+ {name: 'simulcastMode',value: 'rewriting'})
|
|
185
|
+ .up();
|
|
186
|
+ elem.up();
|
|
187
|
+ return elem;
|
|
188
|
+};
|
210
|
189
|
|
211
|
|
- parseConfigOptions: function (resultIq) {
|
212
|
190
|
|
213
|
|
- Moderator.setFocusUserJid(
|
214
|
|
- $(resultIq).find('conference').attr('focusjid'));
|
|
191
|
+Moderator.prototype.parseSessionId = function (resultIq) {
|
|
192
|
+ var sessionId = $(resultIq).find('conference').attr('session-id');
|
|
193
|
+ if (sessionId) {
|
|
194
|
+ console.info('Received sessionId: ' + sessionId);
|
|
195
|
+ localStorage.setItem('sessionId', sessionId);
|
|
196
|
+ }
|
|
197
|
+};
|
215
|
198
|
|
216
|
|
- var authenticationEnabled
|
217
|
|
- = $(resultIq).find(
|
218
|
|
- '>conference>property' +
|
219
|
|
- '[name=\'authentication\'][value=\'true\']').length > 0;
|
|
199
|
+Moderator.prototype.parseConfigOptions = function (resultIq) {
|
220
|
200
|
|
221
|
|
- console.info("Authentication enabled: " + authenticationEnabled);
|
|
201
|
+ this.setFocusUserJid(
|
|
202
|
+ $(resultIq).find('conference').attr('focusjid'));
|
222
|
203
|
|
223
|
|
- externalAuthEnabled = $(resultIq).find(
|
224
|
|
- '>conference>property' +
|
225
|
|
- '[name=\'externalAuth\'][value=\'true\']').length > 0;
|
|
204
|
+ var authenticationEnabled
|
|
205
|
+ = $(resultIq).find(
|
|
206
|
+ '>conference>property' +
|
|
207
|
+ '[name=\'authentication\'][value=\'true\']').length > 0;
|
226
|
208
|
|
227
|
|
- console.info('External authentication enabled: ' + externalAuthEnabled);
|
|
209
|
+ console.info("Authentication enabled: " + authenticationEnabled);
|
228
|
210
|
|
229
|
|
- if (!externalAuthEnabled) {
|
230
|
|
- // We expect to receive sessionId in 'internal' authentication mode
|
231
|
|
- Moderator.parseSessionId(resultIq);
|
232
|
|
- }
|
|
211
|
+ this.externalAuthEnabled = $(resultIq).find(
|
|
212
|
+ '>conference>property' +
|
|
213
|
+ '[name=\'externalAuth\'][value=\'true\']').length > 0;
|
233
|
214
|
|
234
|
|
- var authIdentity = $(resultIq).find('>conference').attr('identity');
|
|
215
|
+ console.info('External authentication enabled: ' + this.externalAuthEnabled);
|
235
|
216
|
|
236
|
|
- eventEmitter.emit(AuthenticationEvents.IDENTITY_UPDATED,
|
237
|
|
- authenticationEnabled, authIdentity);
|
238
|
|
-
|
239
|
|
- // Check if focus has auto-detected Jigasi component(this will be also
|
240
|
|
- // included if we have passed our host from the config)
|
241
|
|
- if ($(resultIq).find(
|
242
|
|
- '>conference>property' +
|
243
|
|
- '[name=\'sipGatewayEnabled\'][value=\'true\']').length) {
|
244
|
|
- sipGatewayEnabled = true;
|
245
|
|
- }
|
246
|
|
-
|
247
|
|
- console.info("Sip gateway enabled: " + sipGatewayEnabled);
|
248
|
|
- },
|
249
|
|
-
|
250
|
|
- // FIXME: we need to show the fact that we're waiting for the focus
|
251
|
|
- // to the user(or that focus is not available)
|
252
|
|
- allocateConferenceFocus: function (roomName, callback) {
|
253
|
|
- // Try to use focus user JID from the config
|
254
|
|
- Moderator.setFocusUserJid(this.xmppService.options.focusUserJid);
|
255
|
|
- // Send create conference IQ
|
256
|
|
- var iq = Moderator.createConferenceIq(roomName);
|
257
|
|
- var self = this;
|
258
|
|
- connection.sendIQ(
|
259
|
|
- iq,
|
260
|
|
- function (result) {
|
261
|
|
-
|
262
|
|
- // Setup config options
|
263
|
|
- Moderator.parseConfigOptions(result);
|
264
|
|
-
|
265
|
|
- if ('true' === $(result).find('conference').attr('ready')) {
|
266
|
|
- // Reset both timers
|
267
|
|
- getNextTimeout(true);
|
268
|
|
- getNextErrorTimeout(true);
|
269
|
|
- // Exec callback
|
270
|
|
- callback();
|
271
|
|
- } else {
|
272
|
|
- var waitMs = getNextTimeout();
|
273
|
|
- console.info("Waiting for the focus... " + waitMs);
|
274
|
|
- // Reset error timeout
|
275
|
|
- getNextErrorTimeout(true);
|
276
|
|
- window.setTimeout(
|
277
|
|
- function () {
|
278
|
|
- Moderator.allocateConferenceFocus(
|
279
|
|
- roomName, callback);
|
280
|
|
- }, waitMs);
|
281
|
|
- }
|
282
|
|
- },
|
283
|
|
- function (error) {
|
284
|
|
- // Invalid session ? remove and try again
|
285
|
|
- // without session ID to get a new one
|
286
|
|
- var invalidSession
|
287
|
|
- = $(error).find('>error>session-invalid').length;
|
288
|
|
- if (invalidSession) {
|
289
|
|
- console.info("Session expired! - removing");
|
290
|
|
- localStorage.removeItem("sessionId");
|
291
|
|
- }
|
292
|
|
- if ($(error).find('>error>graceful-shutdown').length) {
|
293
|
|
- eventEmitter.emit(XMPPEvents.GRACEFUL_SHUTDOWN);
|
294
|
|
- return;
|
295
|
|
- }
|
296
|
|
- // Check for error returned by the reservation system
|
297
|
|
- var reservationErr = $(error).find('>error>reservation-error');
|
298
|
|
- if (reservationErr.length) {
|
299
|
|
- // Trigger error event
|
300
|
|
- var errorCode = reservationErr.attr('error-code');
|
301
|
|
- var errorMsg;
|
302
|
|
- if ($(error).find('>error>text')) {
|
303
|
|
- errorMsg = $(error).find('>error>text').text();
|
304
|
|
- }
|
305
|
|
- eventEmitter.emit(
|
306
|
|
- XMPPEvents.RESERVATION_ERROR, errorCode, errorMsg);
|
307
|
|
- return;
|
308
|
|
- }
|
309
|
|
- // Not authorized to create new room
|
310
|
|
- if ($(error).find('>error>not-authorized').length) {
|
311
|
|
- console.warn("Unauthorized to start the conference", error);
|
312
|
|
- var toDomain
|
313
|
|
- = Strophe.getDomainFromJid(error.getAttribute('to'));
|
314
|
|
- if (toDomain !== this.xmppService.options.hosts.anonymousdomain) {
|
315
|
|
- // FIXME: "is external" should come either from
|
316
|
|
- // the focus or config.js
|
317
|
|
- externalAuthEnabled = true;
|
318
|
|
- }
|
319
|
|
- eventEmitter.emit(
|
320
|
|
- XMPPEvents.AUTHENTICATION_REQUIRED,
|
321
|
|
- function () {
|
322
|
|
- Moderator.allocateConferenceFocus(
|
323
|
|
- roomName, callback);
|
324
|
|
- });
|
325
|
|
- return;
|
326
|
|
- }
|
327
|
|
- var waitMs = getNextErrorTimeout();
|
328
|
|
- console.error("Focus error, retry after " + waitMs, error);
|
329
|
|
- // Show message
|
330
|
|
- var focusComponent = Moderator.getFocusComponent();
|
331
|
|
- var retrySec = waitMs / 1000;
|
332
|
|
- // FIXME: message is duplicated ?
|
333
|
|
- // Do not show in case of session invalid
|
334
|
|
- // which means just a retry
|
335
|
|
- if (!invalidSession) {
|
336
|
|
- eventEmitter.emit(XMPPEvents.FOCUS_DISCONNECTED,
|
337
|
|
- focusComponent, retrySec);
|
338
|
|
- }
|
339
|
|
- // Reset response timeout
|
340
|
|
- getNextTimeout(true);
|
|
217
|
+ if (!this.externalAuthEnabled) {
|
|
218
|
+ // We expect to receive sessionId in 'internal' authentication mode
|
|
219
|
+ this.parseSessionId(resultIq);
|
|
220
|
+ }
|
|
221
|
+
|
|
222
|
+ var authIdentity = $(resultIq).find('>conference').attr('identity');
|
|
223
|
+
|
|
224
|
+ this.eventEmitter.emit(AuthenticationEvents.IDENTITY_UPDATED,
|
|
225
|
+ authenticationEnabled, authIdentity);
|
|
226
|
+
|
|
227
|
+ // Check if focus has auto-detected Jigasi component(this will be also
|
|
228
|
+ // included if we have passed our host from the config)
|
|
229
|
+ if ($(resultIq).find(
|
|
230
|
+ '>conference>property' +
|
|
231
|
+ '[name=\'sipGatewayEnabled\'][value=\'true\']').length) {
|
|
232
|
+ this.sipGatewayEnabled = true;
|
|
233
|
+ }
|
|
234
|
+
|
|
235
|
+ console.info("Sip gateway enabled: " + this.sipGatewayEnabled);
|
|
236
|
+};
|
|
237
|
+
|
|
238
|
+// FIXME = we need to show the fact that we're waiting for the focus
|
|
239
|
+// to the user(or that focus is not available)
|
|
240
|
+Moderator.prototype.allocateConferenceFocus = function ( callback) {
|
|
241
|
+ // Try to use focus user JID from the config
|
|
242
|
+ this.setFocusUserJid(this.xmppService.options.focusUserJid);
|
|
243
|
+ // Send create conference IQ
|
|
244
|
+ var iq = this.createConferenceIq();
|
|
245
|
+ var self = this;
|
|
246
|
+ this.connection.sendIQ(
|
|
247
|
+ iq,
|
|
248
|
+ function (result) {
|
|
249
|
+
|
|
250
|
+ // Setup config options
|
|
251
|
+ self.parseConfigOptions(result);
|
|
252
|
+
|
|
253
|
+ if ('true' === $(result).find('conference').attr('ready')) {
|
|
254
|
+ // Reset both timers
|
|
255
|
+ self.getNextTimeout(true);
|
|
256
|
+ self.getNextErrorTimeout(true);
|
|
257
|
+ // Exec callback
|
|
258
|
+ callback();
|
|
259
|
+ } else {
|
|
260
|
+ var waitMs = self.getNextTimeout();
|
|
261
|
+ console.info("Waiting for the focus... " + waitMs);
|
|
262
|
+ // Reset error timeout
|
|
263
|
+ self.getNextErrorTimeout(true);
|
341
|
264
|
window.setTimeout(
|
342
|
265
|
function () {
|
343
|
|
- Moderator.allocateConferenceFocus(roomName, callback);
|
|
266
|
+ self.allocateConferenceFocus(callback);
|
344
|
267
|
}, waitMs);
|
345
|
268
|
}
|
346
|
|
- );
|
347
|
|
- },
|
348
|
|
-
|
349
|
|
- getLoginUrl: function (roomName, urlCallback) {
|
350
|
|
- var iq = $iq({to: Moderator.getFocusComponent(), type: 'get'});
|
351
|
|
- iq.c('login-url', {
|
352
|
|
- xmlns: 'http://jitsi.org/protocol/focus',
|
353
|
|
- room: roomName,
|
354
|
|
- 'machine-uid': Settings.getSettings().uid
|
355
|
|
- });
|
356
|
|
- connection.sendIQ(
|
357
|
|
- iq,
|
358
|
|
- function (result) {
|
359
|
|
- var url = $(result).find('login-url').attr('url');
|
360
|
|
- url = url = decodeURIComponent(url);
|
361
|
|
- if (url) {
|
362
|
|
- console.info("Got auth url: " + url);
|
363
|
|
- urlCallback(url);
|
364
|
|
- } else {
|
365
|
|
- console.error(
|
366
|
|
- "Failed to get auth url from the focus", result);
|
|
269
|
+ },
|
|
270
|
+ function (error) {
|
|
271
|
+ // Invalid session ? remove and try again
|
|
272
|
+ // without session ID to get a new one
|
|
273
|
+ var invalidSession
|
|
274
|
+ = $(error).find('>error>session-invalid').length;
|
|
275
|
+ if (invalidSession) {
|
|
276
|
+ console.info("Session expired! - removing");
|
|
277
|
+ localStorage.removeItem("sessionId");
|
|
278
|
+ }
|
|
279
|
+ if ($(error).find('>error>graceful-shutdown').length) {
|
|
280
|
+ self.eventEmitter.emit(XMPPEvents.GRACEFUL_SHUTDOWN);
|
|
281
|
+ return;
|
|
282
|
+ }
|
|
283
|
+ // Check for error returned by the reservation system
|
|
284
|
+ var reservationErr = $(error).find('>error>reservation-error');
|
|
285
|
+ if (reservationErr.length) {
|
|
286
|
+ // Trigger error event
|
|
287
|
+ var errorCode = reservationErr.attr('error-code');
|
|
288
|
+ var errorMsg;
|
|
289
|
+ if ($(error).find('>error>text')) {
|
|
290
|
+ errorMsg = $(error).find('>error>text').text();
|
367
|
291
|
}
|
368
|
|
- },
|
369
|
|
- function (error) {
|
370
|
|
- console.error("Get auth url error", error);
|
|
292
|
+ self.eventEmitter.emit(
|
|
293
|
+ XMPPEvents.RESERVATION_ERROR, errorCode, errorMsg);
|
|
294
|
+ return;
|
371
|
295
|
}
|
372
|
|
- );
|
373
|
|
- },
|
374
|
|
- getPopupLoginUrl: function (roomName, urlCallback) {
|
375
|
|
- var iq = $iq({to: Moderator.getFocusComponent(), type: 'get'});
|
376
|
|
- iq.c('login-url', {
|
377
|
|
- xmlns: 'http://jitsi.org/protocol/focus',
|
378
|
|
- room: roomName,
|
379
|
|
- 'machine-uid': Settings.getSettings().uid,
|
380
|
|
- popup: true
|
381
|
|
- });
|
382
|
|
- connection.sendIQ(
|
383
|
|
- iq,
|
384
|
|
- function (result) {
|
385
|
|
- var url = $(result).find('login-url').attr('url');
|
386
|
|
- url = url = decodeURIComponent(url);
|
387
|
|
- if (url) {
|
388
|
|
- console.info("Got POPUP auth url: " + url);
|
389
|
|
- urlCallback(url);
|
390
|
|
- } else {
|
391
|
|
- console.error(
|
392
|
|
- "Failed to get POPUP auth url from the focus", result);
|
|
296
|
+ // Not authorized to create new room
|
|
297
|
+ if ($(error).find('>error>not-authorized').length) {
|
|
298
|
+ console.warn("Unauthorized to start the conference", error);
|
|
299
|
+ var toDomain
|
|
300
|
+ = Strophe.getDomainFromJid(error.getAttribute('to'));
|
|
301
|
+ if (toDomain !== this.xmppService.options.hosts.anonymousdomain) {
|
|
302
|
+ //FIXME: "is external" should come either from
|
|
303
|
+ // the focus or config.js
|
|
304
|
+ self.externalAuthEnabled = true;
|
393
|
305
|
}
|
394
|
|
- },
|
395
|
|
- function (error) {
|
396
|
|
- console.error('Get POPUP auth url error', error);
|
|
306
|
+ self.eventEmitter.emit(
|
|
307
|
+ XMPPEvents.AUTHENTICATION_REQUIRED,
|
|
308
|
+ function () {
|
|
309
|
+ self.allocateConferenceFocus(
|
|
310
|
+ callback);
|
|
311
|
+ });
|
|
312
|
+ return;
|
397
|
313
|
}
|
398
|
|
- );
|
399
|
|
- },
|
400
|
|
- logout: function (callback) {
|
401
|
|
- var iq = $iq({to: Moderator.getFocusComponent(), type: 'set'});
|
402
|
|
- var sessionId = localStorage.getItem('sessionId');
|
403
|
|
- if (!sessionId) {
|
404
|
|
- callback();
|
405
|
|
- return;
|
|
314
|
+ var waitMs = self.getNextErrorTimeout();
|
|
315
|
+ console.error("Focus error, retry after " + waitMs, error);
|
|
316
|
+ // Show message
|
|
317
|
+ var focusComponent = self.getFocusComponent();
|
|
318
|
+ var retrySec = waitMs / 1000;
|
|
319
|
+ //FIXME: message is duplicated ?
|
|
320
|
+ // Do not show in case of session invalid
|
|
321
|
+ // which means just a retry
|
|
322
|
+ if (!invalidSession) {
|
|
323
|
+ self.eventEmitter.emit(XMPPEvents.FOCUS_DISCONNECTED,
|
|
324
|
+ focusComponent, retrySec);
|
|
325
|
+ }
|
|
326
|
+ // Reset response timeout
|
|
327
|
+ self.getNextTimeout(true);
|
|
328
|
+ window.setTimeout(
|
|
329
|
+ function () {
|
|
330
|
+ self.allocateConferenceFocus(callback);
|
|
331
|
+ }, waitMs);
|
406
|
332
|
}
|
407
|
|
- iq.c('logout', {
|
408
|
|
- xmlns: 'http://jitsi.org/protocol/focus',
|
409
|
|
- 'session-id': sessionId
|
410
|
|
- });
|
411
|
|
- connection.sendIQ(
|
412
|
|
- iq,
|
413
|
|
- function (result) {
|
414
|
|
- var logoutUrl = $(result).find('logout').attr('logout-url');
|
415
|
|
- if (logoutUrl) {
|
416
|
|
- logoutUrl = decodeURIComponent(logoutUrl);
|
417
|
|
- }
|
418
|
|
- console.info("Log out OK, url: " + logoutUrl, result);
|
419
|
|
- localStorage.removeItem('sessionId');
|
420
|
|
- callback(logoutUrl);
|
421
|
|
- },
|
422
|
|
- function (error) {
|
423
|
|
- console.error("Logout error", error);
|
|
333
|
+ );
|
|
334
|
+};
|
|
335
|
+
|
|
336
|
+Moderator.prototype.getLoginUrl = function (urlCallback) {
|
|
337
|
+ var iq = $iq({to: this.getFocusComponent(), type: 'get'});
|
|
338
|
+ iq.c('login-url', {
|
|
339
|
+ xmlns: 'http://jitsi.org/protocol/focus',
|
|
340
|
+ room: this.roomName,
|
|
341
|
+ 'machine-uid': this.settings.getSettings().uid
|
|
342
|
+ });
|
|
343
|
+ this.connection.sendIQ(
|
|
344
|
+ iq,
|
|
345
|
+ function (result) {
|
|
346
|
+ var url = $(result).find('login-url').attr('url');
|
|
347
|
+ url = url = decodeURIComponent(url);
|
|
348
|
+ if (url) {
|
|
349
|
+ console.info("Got auth url: " + url);
|
|
350
|
+ urlCallback(url);
|
|
351
|
+ } else {
|
|
352
|
+ console.error(
|
|
353
|
+ "Failed to get auth url from the focus", result);
|
424
|
354
|
}
|
425
|
|
- );
|
|
355
|
+ },
|
|
356
|
+ function (error) {
|
|
357
|
+ console.error("Get auth url error", error);
|
|
358
|
+ }
|
|
359
|
+ );
|
|
360
|
+};
|
|
361
|
+Moderator.prototype.getPopupLoginUrl = function (urlCallback) {
|
|
362
|
+ var iq = $iq({to: this.getFocusComponent(), type: 'get'});
|
|
363
|
+ iq.c('login-url', {
|
|
364
|
+ xmlns: 'http://jitsi.org/protocol/focus',
|
|
365
|
+ room: this.roomName,
|
|
366
|
+ 'machine-uid': this.settings.getSettings().uid,
|
|
367
|
+ popup: true
|
|
368
|
+ });
|
|
369
|
+ this.connection.sendIQ(
|
|
370
|
+ iq,
|
|
371
|
+ function (result) {
|
|
372
|
+ var url = $(result).find('login-url').attr('url');
|
|
373
|
+ url = url = decodeURIComponent(url);
|
|
374
|
+ if (url) {
|
|
375
|
+ console.info("Got POPUP auth url: " + url);
|
|
376
|
+ urlCallback(url);
|
|
377
|
+ } else {
|
|
378
|
+ console.error(
|
|
379
|
+ "Failed to get POPUP auth url from the focus", result);
|
|
380
|
+ }
|
|
381
|
+ },
|
|
382
|
+ function (error) {
|
|
383
|
+ console.error('Get POPUP auth url error', error);
|
|
384
|
+ }
|
|
385
|
+ );
|
|
386
|
+};
|
|
387
|
+
|
|
388
|
+Moderator.prototype.logout = function (callback) {
|
|
389
|
+ var iq = $iq({to: this.getFocusComponent(), type: 'set'});
|
|
390
|
+ var sessionId = localStorage.getItem('sessionId');
|
|
391
|
+ if (!sessionId) {
|
|
392
|
+ callback();
|
|
393
|
+ return;
|
426
|
394
|
}
|
|
395
|
+ iq.c('logout', {
|
|
396
|
+ xmlns: 'http://jitsi.org/protocol/focus',
|
|
397
|
+ 'session-id': sessionId
|
|
398
|
+ });
|
|
399
|
+ this.connection.sendIQ(
|
|
400
|
+ iq,
|
|
401
|
+ function (result) {
|
|
402
|
+ var logoutUrl = $(result).find('logout').attr('logout-url');
|
|
403
|
+ if (logoutUrl) {
|
|
404
|
+ logoutUrl = decodeURIComponent(logoutUrl);
|
|
405
|
+ }
|
|
406
|
+ console.info("Log out OK, url: " + logoutUrl, result);
|
|
407
|
+ localStorage.removeItem('sessionId');
|
|
408
|
+ callback(logoutUrl);
|
|
409
|
+ },
|
|
410
|
+ function (error) {
|
|
411
|
+ console.error("Logout error", error);
|
|
412
|
+ }
|
|
413
|
+ );
|
427
|
414
|
};
|
428
|
415
|
|
429
|
416
|
module.exports = Moderator;
|