342 length = math.min(tonumber(length) or default_history_length, self._data_max_history_length or math.huge); |
342 length = math.min(tonumber(length) or default_history_length, self._data_max_history_length or math.huge); |
343 if length == default_history_length then |
343 if length == default_history_length then |
344 length = nil; |
344 length = nil; |
345 end |
345 end |
346 self._data.history_length = length; |
346 self._data.history_length = length; |
|
347 end |
|
348 |
|
349 |
|
350 local function construct_stanza_id(room, stanza) |
|
351 local from_jid, to_nick = stanza.attr.from, stanza.attr.to; |
|
352 local from_nick = room._jid_nick[from_jid]; |
|
353 local occupant = room._occupants[to_nick]; |
|
354 local to_jid = occupant.jid; |
|
355 |
|
356 return from_nick, to_jid, base64.encode(to_jid.."\0"..stanza.attr.id.."\0"..md5(from_jid)); |
|
357 end |
|
358 local function deconstruct_stanza_id(room, stanza) |
|
359 local from_jid_possiblybare, to_nick = stanza.attr.from, stanza.attr.to; |
|
360 local from_jid, id, to_jid_hash = (base64.decode(stanza.attr.id) or ""):match("^(.+)%z(.*)%z(.+)$"); |
|
361 local from_nick = room._jid_nick[from_jid]; |
|
362 |
|
363 if not(from_nick) then return; end |
|
364 if not(from_jid_possiblybare == from_jid or from_jid_possiblybare == jid_bare(from_jid)) then return; end |
|
365 |
|
366 local occupant = room._occupants[to_nick]; |
|
367 for to_jid in pairs(occupant and occupant.sessions or {}) do |
|
368 if md5(to_jid) == to_jid_hash then |
|
369 return from_nick, to_jid, id; |
|
370 end |
|
371 end |
347 end |
372 end |
348 |
373 |
349 |
374 |
350 function room_mt:handle_to_occupant(origin, stanza) -- PM, vCards, etc |
375 function room_mt:handle_to_occupant(origin, stanza) -- PM, vCards, etc |
351 local from, to = stanza.attr.from, stanza.attr.to; |
376 local from, to = stanza.attr.from, stanza.attr.to; |
495 if type ~= 'visible' and type ~= 'invisible' then -- COMPAT ejabberd can broadcast or forward XEP-0018 presences |
520 if type ~= 'visible' and type ~= 'invisible' then -- COMPAT ejabberd can broadcast or forward XEP-0018 presences |
496 origin.send(st.error_reply(stanza, "modify", "bad-request")); -- FIXME correct error? |
521 origin.send(st.error_reply(stanza, "modify", "bad-request")); -- FIXME correct error? |
497 end |
522 end |
498 end |
523 end |
499 elseif not current_nick then -- not in room |
524 elseif not current_nick then -- not in room |
500 if type == "error" or type == "result" then |
525 if type == "error" or type == "result" and stanza.name == "iq" then |
501 local id = stanza.name == "iq" and stanza.attr.id and base64.decode(stanza.attr.id); |
526 local id = stanza.attr.id; |
502 local _nick, _id, _hash = (id or ""):match("^(.+)%z(.*)%z(.+)$"); |
527 stanza.attr.from, stanza.attr.to, stanza.attr.id = deconstruct_stanza_id(self, stanza); |
503 local occupant = self._occupants[stanza.attr.to]; |
528 self:_route_stanza(stanza); |
504 if occupant and _nick and self._jid_nick[_nick] and _id and _hash then |
529 stanza.attr.from, stanza.attr.to, stanza.attr.id = from, to, id; |
505 local id, _to = stanza.attr.id; |
|
506 for jid in pairs(occupant.sessions) do |
|
507 if md5(jid) == _hash then |
|
508 _to = jid; |
|
509 break; |
|
510 end |
|
511 end |
|
512 if _to then |
|
513 stanza.attr.to, stanza.attr.from, stanza.attr.id = _to, self._jid_nick[_nick], _id; |
|
514 self:_route_stanza(stanza); |
|
515 stanza.attr.to, stanza.attr.from, stanza.attr.id = to, from, id; |
|
516 end |
|
517 end |
|
518 else |
530 else |
519 origin.send(st.error_reply(stanza, "cancel", "not-acceptable")); |
531 origin.send(st.error_reply(stanza, "cancel", "not-acceptable")); |
520 end |
532 end |
521 elseif stanza.name == "message" and type == "groupchat" then -- groupchat messages not allowed in PM |
533 elseif stanza.name == "message" and type == "groupchat" then -- groupchat messages not allowed in PM |
522 origin.send(st.error_reply(stanza, "modify", "bad-request")); |
534 origin.send(st.error_reply(stanza, "modify", "bad-request")); |
525 self:handle_to_occupant(origin, build_unavailable_presence_from_error(stanza)); -- send unavailable |
537 self:handle_to_occupant(origin, build_unavailable_presence_from_error(stanza)); -- send unavailable |
526 else -- private stanza |
538 else -- private stanza |
527 local o_data = self._occupants[to]; |
539 local o_data = self._occupants[to]; |
528 if o_data then |
540 if o_data then |
529 log("debug", "%s sent private stanza to %s (%s)", from, to, o_data.jid); |
541 log("debug", "%s sent private stanza to %s (%s)", from, to, o_data.jid); |
530 local jid = o_data.jid; |
542 if stanza.name == "iq" then |
531 local bare = jid_bare(jid); |
543 local id = stanza.attr.id; |
532 stanza.attr.to, stanza.attr.from = jid, current_nick; |
544 stanza.attr.from, stanza.attr.to, stanza.attr.id = construct_stanza_id(self, stanza); |
533 local id = stanza.attr.id; |
545 if type == 'get' and stanza.tags[1].attr.xmlns == 'vcard-temp' then |
534 if stanza.name=='iq' and type=='get' and stanza.tags[1].attr.xmlns == 'vcard-temp' and bare ~= jid then |
546 stanza.attr.to = jid_bare(stanza.attr.to); |
535 stanza.attr.to = bare; |
547 end |
536 stanza.attr.id = base64.encode(jid.."\0"..id.."\0"..md5(from)); |
548 self:_route_stanza(stanza); |
537 end |
549 stanza.attr.from, stanza.attr.to, stanza.attr.id = from, to, id; |
538 self:_route_stanza(stanza); |
550 else -- message |
539 stanza.attr.to, stanza.attr.from, stanza.attr.id = to, from, id; |
551 stanza.attr.from = current_nick; |
|
552 for jid in pairs(o_data.sessions) do |
|
553 stanza.attr.to = jid; |
|
554 self:_route_stanza(stanza); |
|
555 end |
|
556 stanza.attr.from, stanza.attr.to = from, to; |
|
557 end |
540 elseif type ~= "error" and type ~= "result" then -- recipient not in room |
558 elseif type ~= "error" and type ~= "result" then -- recipient not in room |
541 origin.send(st.error_reply(stanza, "cancel", "item-not-found", "Recipient not in room")); |
559 origin.send(st.error_reply(stanza, "cancel", "item-not-found", "Recipient not in room")); |
542 end |
560 end |
543 end |
561 end |
544 end |
562 end |