|
@@ -20,18 +20,28 @@ local get_room_from_jid = util.get_room_from_jid;
|
20
|
20
|
local get_focus_occupant = util.get_focus_occupant;
|
21
|
21
|
local internal_room_jid_match_rewrite = util.internal_room_jid_match_rewrite;
|
22
|
22
|
|
|
23
|
+-- this is the main virtual host of this vnode
|
|
24
|
+local local_domain = module:get_option_string('muc_mapper_domain_base');
|
|
25
|
+if not local_domain then
|
|
26
|
+ module:log('warn', "No 'muc_mapper_domain_base' option set, disabling fmuc plugin");
|
|
27
|
+ return;
|
|
28
|
+end
|
|
29
|
+
|
|
30
|
+-- this is the main virtual host of the main prosody that this vnode serves
|
|
31
|
+local main_domain = module:get_option_string('main_domain');
|
|
32
|
+if not main_domain then
|
|
33
|
+ module:log('warn', "No 'main_domain' option set, disabling fmuc plugin");
|
|
34
|
+ return;
|
|
35
|
+end
|
|
36
|
+
|
23
|
37
|
local muc_domain_prefix = module:get_option_string('muc_mapper_domain_prefix', 'conference');
|
24
|
|
-local main_domain = string.gsub(module.host, muc_domain_prefix..'.', '');
|
25
|
38
|
|
26
|
39
|
local NICK_NS = 'http://jabber.org/protocol/nick';
|
27
|
40
|
|
28
|
41
|
-- we send stats for the total number of rooms, total number of participants and total number of visitors
|
29
|
|
-local measure_rooms = module:measure("vnode-rooms", "amount");
|
30
|
|
-local measure_participants = module:measure("vnode-participants", "amount");
|
31
|
|
-local measure_visitors = module:measure("vnode-visitors", "amount");
|
32
|
|
-
|
33
|
|
-local fmuc_main_domain;
|
|
42
|
+local measure_rooms = module:measure('vnode-rooms', 'amount');
|
|
43
|
+local measure_participants = module:measure('vnode-participants', 'amount');
|
|
44
|
+local measure_visitors = module:measure('vnode-visitors', 'amount');
|
34
|
45
|
|
35
|
46
|
local sent_iq_cache = require 'util.cache'.new(200);
|
36
|
47
|
|
|
@@ -45,12 +55,8 @@ module:hook('muc-occupant-pre-join', function (event)
|
45
|
55
|
local occupant, session = event.occupant, event.origin;
|
46
|
56
|
local node, host = jid.split(occupant.bare_jid);
|
47
|
57
|
|
48
|
|
- if host == main_domain then
|
|
58
|
+ if host == local_domain then
|
49
|
59
|
occupant.role = 'visitor';
|
50
|
|
- elseif not fmuc_main_domain then
|
51
|
|
- if node ~= 'focus' then
|
52
|
|
- fmuc_main_domain = host;
|
53
|
|
- end
|
54
|
60
|
end
|
55
|
61
|
end, 3);
|
56
|
62
|
|
|
@@ -103,7 +109,7 @@ module:hook('muc-occupant-left', function (event)
|
103
|
109
|
local room, occupant = event.room, event.occupant;
|
104
|
110
|
local occupant_domain = jid.host(occupant.bare_jid);
|
105
|
111
|
|
106
|
|
- if occupant_domain == main_domain then
|
|
112
|
+ if occupant_domain == local_domain then
|
107
|
113
|
local focus_occupant = get_focus_occupant(room);
|
108
|
114
|
if not focus_occupant then
|
109
|
115
|
module:log('warn', 'No focus found for %s', room.jid);
|
|
@@ -181,11 +187,11 @@ module:hook('muc-broadcast-presence', function (event)
|
181
|
187
|
sent_iq_cache:set(iq_id, socket.gettime());
|
182
|
188
|
local promotion_request = st.iq({
|
183
|
189
|
type = 'set',
|
184
|
|
- to = 'visitors.'..fmuc_main_domain,
|
185
|
|
- from = main_domain,
|
|
190
|
+ to = 'visitors.'..main_domain,
|
|
191
|
+ from = local_domain,
|
186
|
192
|
id = iq_id })
|
187
|
193
|
:tag('visitors', { xmlns = 'jitsi:visitors',
|
188
|
|
- room = jid.join(jid.node(room.jid), muc_domain_prefix..'.'..fmuc_main_domain) })
|
|
194
|
+ room = jid.join(jid.node(room.jid), muc_domain_prefix..'.'..main_domain) })
|
189
|
195
|
:tag('promotion-request', { xmlns = 'jitsi:visitors', jid = occupant.jid }):up();
|
190
|
196
|
|
191
|
197
|
local nick_element = occupant:get_presence():get_child('nick', NICK_NS);
|
|
@@ -221,8 +227,8 @@ local function stanza_handler(event)
|
221
|
227
|
return;
|
222
|
228
|
end
|
223
|
229
|
|
224
|
|
- if stanza.attr.from ~= 'visitors.'..fmuc_main_domain then
|
225
|
|
- module:log('warn', 'not from visitors component, ignore! %s %s', stanza.attr.from, stanza);
|
|
230
|
+ if stanza.attr.from ~= 'visitors.'..main_domain then
|
|
231
|
+ module:log('warn', 'not from visitors component, ignore! %s', stanza);
|
226
|
232
|
return true;
|
227
|
233
|
end
|
228
|
234
|
|
|
@@ -241,7 +247,7 @@ local function stanza_handler(event)
|
241
|
247
|
|
242
|
248
|
-- respond with successful receiving the iq
|
243
|
249
|
origin.send(st.iq({
|
244
|
|
- type = "result";
|
|
250
|
+ type = 'result';
|
245
|
251
|
from = stanza.attr.to;
|
246
|
252
|
to = stanza.attr.from;
|
247
|
253
|
id = stanza.attr.id
|
|
@@ -276,12 +282,12 @@ function process_host_module(name, callback)
|
276
|
282
|
process_host(name);
|
277
|
283
|
end
|
278
|
284
|
end
|
279
|
|
-process_host_module(main_domain, function(host_module, host)
|
|
285
|
+process_host_module(local_domain, function(host_module, host)
|
280
|
286
|
host_module:hook('iq/host', stanza_handler, 10);
|
281
|
287
|
end);
|
282
|
288
|
|
283
|
289
|
-- only live chat is supported for visitors
|
284
|
|
-module:hook("muc-occupant-groupchat", function(event)
|
|
290
|
+module:hook('muc-occupant-groupchat', function(event)
|
285
|
291
|
local occupant, room, stanza = event.occupant, event.room, event.stanza;
|
286
|
292
|
local from = stanza.attr.from;
|
287
|
293
|
local occupant_host = jid.host(occupant.bare_jid);
|
|
@@ -289,7 +295,7 @@ module:hook("muc-occupant-groupchat", function(event)
|
289
|
295
|
-- if there is no occupant this is a message from main, probably coming from other vnode
|
290
|
296
|
if occupant then
|
291
|
297
|
-- we manage nick only for visitors
|
292
|
|
- if occupant_host ~= fmuc_main_domain then
|
|
298
|
+ if occupant_host ~= main_domain then
|
293
|
299
|
-- add to message stanza display name for the visitor
|
294
|
300
|
-- remove existing nick to avoid forgery
|
295
|
301
|
stanza:remove_children('nick', NICK_NS);
|
|
@@ -310,15 +316,15 @@ module:hook("muc-occupant-groupchat", function(event)
|
310
|
316
|
-- let's send it to main chat and rest of visitors here
|
311
|
317
|
for _, o in room:each_occupant() do
|
312
|
318
|
-- filter remote occupants
|
313
|
|
- if jid.host(o.bare_jid) == main_domain then
|
|
319
|
+ if jid.host(o.bare_jid) == local_domain then
|
314
|
320
|
room:route_to_occupant(o, stanza)
|
315
|
321
|
end
|
316
|
322
|
end
|
317
|
323
|
|
318
|
324
|
-- send to main participants only messages from local occupants (skip from remote vnodes)
|
319
|
|
- if occupant and occupant_host ~= fmuc_main_domain then
|
|
325
|
+ if occupant and occupant_host ~= main_domain then
|
320
|
326
|
local main_message = st.clone(stanza);
|
321
|
|
- main_message.attr.to = jid.join(jid.node(room.jid), muc_domain_prefix..'.'..fmuc_main_domain);
|
|
327
|
+ main_message.attr.to = jid.join(jid.node(room.jid), muc_domain_prefix..'.'..main_domain);
|
322
|
328
|
module:send(main_message);
|
323
|
329
|
end
|
324
|
330
|
stanza.attr.from = from; -- something prosody does internally
|
|
@@ -328,20 +334,20 @@ end, 55); -- prosody check for visitor's chat is prio 50, we want to override it
|
328
|
334
|
|
329
|
335
|
module:hook('muc-private-message', function(event)
|
330
|
336
|
-- private messaging is forbidden
|
331
|
|
- event.origin.send(st.error_reply(event.stanza, "auth", "forbidden",
|
332
|
|
- "Private messaging is disabled on visitor nodes"));
|
|
337
|
+ event.origin.send(st.error_reply(event.stanza, 'auth', 'forbidden',
|
|
338
|
+ 'Private messaging is disabled on visitor nodes'));
|
333
|
339
|
return true;
|
334
|
340
|
end, 10);
|
335
|
341
|
|
336
|
342
|
-- we calculate the stats on the configured interval (60 seconds by default)
|
337
|
|
-module:hook_global("stats-update", function ()
|
|
343
|
+module:hook_global('stats-update', function ()
|
338
|
344
|
local participants_count, rooms_count, visitors_count = 0, 0, 0;
|
339
|
345
|
|
340
|
346
|
-- iterate over all rooms
|
341
|
347
|
for room in prosody.hosts[module.host].modules.muc.each_room() do
|
342
|
348
|
rooms_count = rooms_count + 1;
|
343
|
349
|
for _, o in room:each_occupant() do
|
344
|
|
- if jid.host(o.bare_jid) == main_domain then
|
|
350
|
+ if jid.host(o.bare_jid) == local_domain then
|
345
|
351
|
visitors_count = visitors_count + 1;
|
346
|
352
|
else
|
347
|
353
|
participants_count = participants_count + 1;
|
|
@@ -356,4 +362,80 @@ module:hook_global("stats-update", function ()
|
356
|
362
|
measure_participants(participants_count);
|
357
|
363
|
end);
|
358
|
364
|
|
|
365
|
+-- we skip it till the main participants are added from the main prosody
|
|
366
|
+module:hook('jicofo-unlock-room', function(e)
|
|
367
|
+ -- we do not block events we fired
|
|
368
|
+ if e.fmuc_fired then
|
|
369
|
+ return;
|
|
370
|
+ end
|
|
371
|
+
|
|
372
|
+ return true;
|
|
373
|
+end);
|
|
374
|
+
|
|
375
|
+-- handles incoming iq connect stanzas
|
|
376
|
+local function iq_from_main_handler(event)
|
|
377
|
+ local origin, stanza = event.origin, event.stanza;
|
|
378
|
+
|
|
379
|
+ if stanza.name ~= 'iq' then
|
|
380
|
+ return;
|
|
381
|
+ end
|
|
382
|
+
|
|
383
|
+ if stanza.attr.type == 'result' and sent_iq_cache:get(stanza.attr.id) then
|
|
384
|
+ sent_iq_cache:set(stanza.attr.id, nil);
|
|
385
|
+ return true;
|
|
386
|
+ end
|
|
387
|
+
|
|
388
|
+ if stanza.attr.type ~= 'set' then
|
|
389
|
+ return;
|
|
390
|
+ end
|
|
391
|
+
|
|
392
|
+ local visitors_iq = event.stanza:get_child('visitors', 'jitsi:visitors');
|
|
393
|
+ if not visitors_iq then
|
|
394
|
+ return;
|
|
395
|
+ end
|
|
396
|
+
|
|
397
|
+ if stanza.attr.from ~= main_domain then
|
|
398
|
+ module:log('warn', 'not from main prosody, ignore! %s', stanza);
|
|
399
|
+ return true;
|
|
400
|
+ end
|
|
401
|
+
|
|
402
|
+ local room_jid = visitors_iq.attr.room;
|
|
403
|
+ local room = get_room_from_jid(room_jid_match_rewrite(room_jid));
|
|
404
|
+
|
|
405
|
+ if not room then
|
|
406
|
+ module:log('warn', 'No room found %s', room_jid);
|
|
407
|
+ return;
|
|
408
|
+ end
|
|
409
|
+
|
|
410
|
+ local node = visitors_iq:get_child('connect');
|
|
411
|
+ local fire_jicofo_unlock = true;
|
|
412
|
+
|
|
413
|
+ if not node then
|
|
414
|
+ node = visitors_iq:get_child('update');
|
|
415
|
+ fire_jicofo_unlock = false;
|
|
416
|
+ end
|
359
|
417
|
|
|
418
|
+ if not node then
|
|
419
|
+ return;
|
|
420
|
+ end
|
|
421
|
+
|
|
422
|
+ -- respond with successful receiving the iq
|
|
423
|
+ origin.send(st.iq({
|
|
424
|
+ type = 'result';
|
|
425
|
+ from = stanza.attr.to;
|
|
426
|
+ to = stanza.attr.from;
|
|
427
|
+ id = stanza.attr.id
|
|
428
|
+ }));
|
|
429
|
+
|
|
430
|
+ -- if there is password supplied use it
|
|
431
|
+ -- if this is update it will either set or remove the password
|
|
432
|
+ room:set_password(node.attr.password);
|
|
433
|
+
|
|
434
|
+ if fire_jicofo_unlock then
|
|
435
|
+ -- everything is connected allow participants to join
|
|
436
|
+ module:fire_event('jicofo-unlock-room', { room = room; fmuc_fired = true; });
|
|
437
|
+ end
|
|
438
|
+
|
|
439
|
+ return true;
|
|
440
|
+end
|
|
441
|
+module:hook('iq/host', iq_from_main_handler, 10);
|