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); |