Software /
code /
prosody
Comparison
plugins/mod_bookmarks.lua @ 12170:750abaf99baf
mod_bookmarks: Broadcast notifications per XEP-0048 and XEP-0411
For compatibility with clients relying on the notifications
author | Kim Alvefur <zash@zash.se> |
---|---|
date | Sun, 09 Jan 2022 18:42:22 +0100 |
parent | 12156:17cffaa78f48 |
child | 12171:b2923a3b4e02 |
comparison
equal
deleted
inserted
replaced
12169:866d06644956 | 12170:750abaf99baf |
---|---|
10 local private_storage = module:open_store("private", "map"); | 10 local private_storage = module:open_store("private", "map"); |
11 | 11 |
12 local namespace = "urn:xmpp:bookmarks:1"; | 12 local namespace = "urn:xmpp:bookmarks:1"; |
13 local namespace_private = "jabber:iq:private"; | 13 local namespace_private = "jabber:iq:private"; |
14 local namespace_legacy = "storage:bookmarks"; | 14 local namespace_legacy = "storage:bookmarks"; |
15 local xmlns_pubsub = "http://jabber.org/protocol/pubsub"; | |
15 | 16 |
16 local default_options = { | 17 local default_options = { |
17 ["persist_items"] = true; | 18 ["persist_items"] = true; |
18 ["max_items"] = "max"; | 19 ["max_items"] = "max"; |
19 ["send_last_published_item"] = "never"; | 20 ["send_last_published_item"] = "never"; |
22 | 23 |
23 module:hook("account-disco-info", function (event) | 24 module:hook("account-disco-info", function (event) |
24 -- This Time it’s Serious! | 25 -- This Time it’s Serious! |
25 event.reply:tag("feature", { var = namespace.."#compat" }):up(); | 26 event.reply:tag("feature", { var = namespace.."#compat" }):up(); |
26 event.reply:tag("feature", { var = namespace.."#compat-pep" }):up(); | 27 event.reply:tag("feature", { var = namespace.."#compat-pep" }):up(); |
28 | |
29 -- COMPAT XEP-0411 | |
30 event.reply:tag("feature", { var = "urn:xmpp:bookmarks-conversion:0" }):up(); | |
27 end); | 31 end); |
28 | 32 |
29 -- This must be declared on the domain JID, not the account JID. Note that | 33 -- This must be declared on the domain JID, not the account JID. Note that |
30 -- this isn’t defined in the XEP. | 34 -- this isn’t defined in the XEP. |
31 module:add_feature(namespace_private); | 35 module:add_feature(namespace_private); |
36 | |
32 | 37 |
33 local function generate_legacy_storage(items) | 38 local function generate_legacy_storage(items) |
34 local storage = st.stanza("storage", { xmlns = namespace_legacy }); | 39 local storage = st.stanza("storage", { xmlns = namespace_legacy }); |
35 for _, item_id in ipairs(items) do | 40 for _, item_id in ipairs(items) do |
36 local item = items[item_id]; | 41 local item = items[item_id]; |
415 end | 420 end |
416 end, 1); | 421 end, 1); |
417 if module:get_option_boolean("upgrade_legacy_bookmarks", true) then | 422 if module:get_option_boolean("upgrade_legacy_bookmarks", true) then |
418 module:hook("resource-bind", migrate_legacy_bookmarks); | 423 module:hook("resource-bind", migrate_legacy_bookmarks); |
419 end | 424 end |
425 -- COMPAT XEP-0411 Broadcast as per XEP-0048 + PEP | |
426 local function legacy_broadcast(event) | |
427 local service = event.service; | |
428 local ok, bookmarks = service:get_items(namespace, event.actor); | |
429 if bookmarks == "item-not-found" then ok, bookmarks = true, {} end | |
430 if not ok then return end | |
431 local legacy_bookmarks_item = st.stanza("item", { xmlns = xmlns_pubsub; id = "current" }) | |
432 :add_child(generate_legacy_storage(bookmarks)); | |
433 -- FIXME This broadcasts to any and all contacts who sent +notify because the node does not exist, so defaults apply. | |
434 service:broadcast("items", namespace_legacy, { --[[ no subscribers ]] }, legacy_bookmarks_item, event.actor); | |
435 end | |
436 local function broadcast_legacy_removal(event) | |
437 if event.node ~= namespace then return end | |
438 return legacy_broadcast(event); | |
439 end | |
440 module:hook("presence/initial", function (event) | |
441 -- Broadcasts to all clients with legacy+notify, not just the one coming online. | |
442 -- Upgrade to XEP-0402 to avoid it | |
443 local service = mod_pep.get_pep_service(event.origin.username); | |
444 legacy_broadcast({ service = service, actor = event.origin.full_jid }); | |
445 end); | |
420 module:handle_items("pep-service", function (event) | 446 module:handle_items("pep-service", function (event) |
421 local service = event.item.service; | 447 local service = event.item.service; |
422 module:hook_object_event(service.events, "node-created", on_node_created); | 448 module:hook_object_event(service.events, "node-created", on_node_created); |
449 module:hook_object_event(service.events, "item-published/" .. namespace, legacy_broadcast); | |
450 module:hook_object_event(service.events, "item-retracted", broadcast_legacy_removal); | |
451 module:hook_object_event(service.events, "node-purged", broadcast_legacy_removal); | |
452 module:hook_object_event(service.events, "node-deleted", broadcast_legacy_removal); | |
423 end, function (event) | 453 end, function (event) |
424 local service = event.item.service; | 454 local service = event.item.service; |
425 module:unhook_object_event(service.events, "node-created", on_node_created); | 455 module:unhook_object_event(service.events, "node-created", on_node_created); |
456 module:unhook_object_event(service.events, "item-published/" .. namespace, legacy_broadcast); | |
457 module:unhook_object_event(service.events, "item-retracted", broadcast_legacy_removal); | |
458 module:unhook_object_event(service.events, "node-purged", broadcast_legacy_removal); | |
459 module:unhook_object_event(service.events, "node-deleted", broadcast_legacy_removal); | |
426 end, true); | 460 end, true); |