author | Matthew Wild <mwild1@gmail.com> |
Sun, 03 Mar 2024 16:10:14 +0000 | |
changeset 5860 | 6fe4dab27187 |
parent 4683 | f95a1e197a07 |
permissions | -rw-r--r-- |
4683
f95a1e197a07
mod_auto_moved: New module implementing XEP-0283 r0.2.0
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
1 |
local id = require "util.id"; |
f95a1e197a07
mod_auto_moved: New module implementing XEP-0283 r0.2.0
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
2 |
local jid = require "util.jid"; |
f95a1e197a07
mod_auto_moved: New module implementing XEP-0283 r0.2.0
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
3 |
local promise = require "util.promise"; |
f95a1e197a07
mod_auto_moved: New module implementing XEP-0283 r0.2.0
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
4 |
local rm = require "core.rostermanager"; |
f95a1e197a07
mod_auto_moved: New module implementing XEP-0283 r0.2.0
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
5 |
local st = require "util.stanza"; |
f95a1e197a07
mod_auto_moved: New module implementing XEP-0283 r0.2.0
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
6 |
|
f95a1e197a07
mod_auto_moved: New module implementing XEP-0283 r0.2.0
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
7 |
local errors = require "util.error".init(module.name, { |
f95a1e197a07
mod_auto_moved: New module implementing XEP-0283 r0.2.0
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
8 |
["statement-not-found"] = { type = "cancel", condition = "item-not-found" }; |
f95a1e197a07
mod_auto_moved: New module implementing XEP-0283 r0.2.0
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
9 |
["statement-mismatch"] = { type = "cancel", condition = "conlict" }; |
f95a1e197a07
mod_auto_moved: New module implementing XEP-0283 r0.2.0
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
10 |
}); |
f95a1e197a07
mod_auto_moved: New module implementing XEP-0283 r0.2.0
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
11 |
|
f95a1e197a07
mod_auto_moved: New module implementing XEP-0283 r0.2.0
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
12 |
module:hook("presence/bare", function (event) |
f95a1e197a07
mod_auto_moved: New module implementing XEP-0283 r0.2.0
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
13 |
local origin, stanza = event.origin, event.stanza; |
f95a1e197a07
mod_auto_moved: New module implementing XEP-0283 r0.2.0
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
14 |
if stanza.attr.type ~= "subscribe" then |
f95a1e197a07
mod_auto_moved: New module implementing XEP-0283 r0.2.0
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
15 |
return; -- We're only interested in subscription requests |
f95a1e197a07
mod_auto_moved: New module implementing XEP-0283 r0.2.0
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
16 |
end |
f95a1e197a07
mod_auto_moved: New module implementing XEP-0283 r0.2.0
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
17 |
local moved = stanza:get_child("moved", "urn:xmpp:moved:1"); |
f95a1e197a07
mod_auto_moved: New module implementing XEP-0283 r0.2.0
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
18 |
if not moved then |
f95a1e197a07
mod_auto_moved: New module implementing XEP-0283 r0.2.0
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
19 |
return; -- We're only interested in stanzas with a moved notification |
f95a1e197a07
mod_auto_moved: New module implementing XEP-0283 r0.2.0
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
20 |
end |
f95a1e197a07
mod_auto_moved: New module implementing XEP-0283 r0.2.0
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
21 |
|
f95a1e197a07
mod_auto_moved: New module implementing XEP-0283 r0.2.0
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
22 |
local verification = stanza:get_child("moved-verification", "https://prosody.im/protocol/moved"); |
f95a1e197a07
mod_auto_moved: New module implementing XEP-0283 r0.2.0
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
23 |
if verification then |
f95a1e197a07
mod_auto_moved: New module implementing XEP-0283 r0.2.0
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
24 |
return; -- We already attempted to verify this stanza |
f95a1e197a07
mod_auto_moved: New module implementing XEP-0283 r0.2.0
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
25 |
end |
f95a1e197a07
mod_auto_moved: New module implementing XEP-0283 r0.2.0
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
26 |
|
f95a1e197a07
mod_auto_moved: New module implementing XEP-0283 r0.2.0
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
27 |
module:log("debug", "Received moved notification from %s", stanza.attr.from); |
f95a1e197a07
mod_auto_moved: New module implementing XEP-0283 r0.2.0
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
28 |
|
f95a1e197a07
mod_auto_moved: New module implementing XEP-0283 r0.2.0
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
29 |
local old_jid = moved:get_child_text("old-jid"); |
f95a1e197a07
mod_auto_moved: New module implementing XEP-0283 r0.2.0
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
30 |
if not old_jid then |
f95a1e197a07
mod_auto_moved: New module implementing XEP-0283 r0.2.0
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
31 |
return; -- Failed to read old JID |
f95a1e197a07
mod_auto_moved: New module implementing XEP-0283 r0.2.0
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
32 |
end |
f95a1e197a07
mod_auto_moved: New module implementing XEP-0283 r0.2.0
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
33 |
|
f95a1e197a07
mod_auto_moved: New module implementing XEP-0283 r0.2.0
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
34 |
local to_user = jid.node(stanza.attr.to); |
f95a1e197a07
mod_auto_moved: New module implementing XEP-0283 r0.2.0
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
35 |
local new_jid_unverified = jid.bare(stanza.attr.from); |
f95a1e197a07
mod_auto_moved: New module implementing XEP-0283 r0.2.0
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
36 |
|
f95a1e197a07
mod_auto_moved: New module implementing XEP-0283 r0.2.0
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
37 |
if not rm.is_contact_subscribed(to_user, module.host, old_jid) then |
f95a1e197a07
mod_auto_moved: New module implementing XEP-0283 r0.2.0
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
38 |
return; -- Old JID was not an existing contact, ignore |
f95a1e197a07
mod_auto_moved: New module implementing XEP-0283 r0.2.0
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
39 |
end |
f95a1e197a07
mod_auto_moved: New module implementing XEP-0283 r0.2.0
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
40 |
|
f95a1e197a07
mod_auto_moved: New module implementing XEP-0283 r0.2.0
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
41 |
if rm.is_contact_pending_in(to_user, module.host, new_jid_unverified) |
f95a1e197a07
mod_auto_moved: New module implementing XEP-0283 r0.2.0
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
42 |
or rm.is_contact_subscribed(to_user, module.host, new_jid_unverified) then |
f95a1e197a07
mod_auto_moved: New module implementing XEP-0283 r0.2.0
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
43 |
return; -- New JID already subscribed or pending, ignore |
f95a1e197a07
mod_auto_moved: New module implementing XEP-0283 r0.2.0
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
44 |
end |
f95a1e197a07
mod_auto_moved: New module implementing XEP-0283 r0.2.0
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
45 |
|
f95a1e197a07
mod_auto_moved: New module implementing XEP-0283 r0.2.0
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
46 |
local moved_statement_query = st.iq({ to = old_jid, type = "get", id = id.short() }) |
f95a1e197a07
mod_auto_moved: New module implementing XEP-0283 r0.2.0
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
47 |
:tag("pubsub", { xmlns = "http://jabber.org/protocol/pubsub" }) |
f95a1e197a07
mod_auto_moved: New module implementing XEP-0283 r0.2.0
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
48 |
:tag("items", { node = "urn:xmpp:moved:1" }) |
f95a1e197a07
mod_auto_moved: New module implementing XEP-0283 r0.2.0
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
49 |
:tag("item", { id = "current" }):up() |
f95a1e197a07
mod_auto_moved: New module implementing XEP-0283 r0.2.0
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
50 |
:up() |
f95a1e197a07
mod_auto_moved: New module implementing XEP-0283 r0.2.0
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
51 |
:up(); |
f95a1e197a07
mod_auto_moved: New module implementing XEP-0283 r0.2.0
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
52 |
-- TODO: Catch and handle <gone/> errors per note in XEP-0283. |
f95a1e197a07
mod_auto_moved: New module implementing XEP-0283 r0.2.0
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
53 |
module:send_iq(moved_statement_query):next(function (reply) |
f95a1e197a07
mod_auto_moved: New module implementing XEP-0283 r0.2.0
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
54 |
module:log("debug", "Statement reply: %s", reply.stanza); |
f95a1e197a07
mod_auto_moved: New module implementing XEP-0283 r0.2.0
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
55 |
local moved_statement = reply.stanza:find("{http://jabber.org/protocol/pubsub}pubsub/items/{http://jabber.org/protocol/pubsub}item/{urn:xmpp:moved:1}moved"); |
f95a1e197a07
mod_auto_moved: New module implementing XEP-0283 r0.2.0
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
56 |
if not moved_statement then |
f95a1e197a07
mod_auto_moved: New module implementing XEP-0283 r0.2.0
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
57 |
return promise.reject(errors.new("statement-not-found")); -- No statement found |
f95a1e197a07
mod_auto_moved: New module implementing XEP-0283 r0.2.0
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
58 |
end |
f95a1e197a07
mod_auto_moved: New module implementing XEP-0283 r0.2.0
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
59 |
|
f95a1e197a07
mod_auto_moved: New module implementing XEP-0283 r0.2.0
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
60 |
local new_jid = jid.prep(moved_statement:get_child_text("new-jid")); |
f95a1e197a07
mod_auto_moved: New module implementing XEP-0283 r0.2.0
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
61 |
if new_jid ~= new_jid_unverified then |
f95a1e197a07
mod_auto_moved: New module implementing XEP-0283 r0.2.0
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
62 |
return promise.reject(errors.new("statement-mismatch")); -- Verification failed; JIDs do not match |
f95a1e197a07
mod_auto_moved: New module implementing XEP-0283 r0.2.0
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
63 |
end |
f95a1e197a07
mod_auto_moved: New module implementing XEP-0283 r0.2.0
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
64 |
|
f95a1e197a07
mod_auto_moved: New module implementing XEP-0283 r0.2.0
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
65 |
-- Verified! |
f95a1e197a07
mod_auto_moved: New module implementing XEP-0283 r0.2.0
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
66 |
module:log("info", "Verified moved notification <%s> -> <%s>", old_jid, new_jid); |
f95a1e197a07
mod_auto_moved: New module implementing XEP-0283 r0.2.0
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
67 |
|
f95a1e197a07
mod_auto_moved: New module implementing XEP-0283 r0.2.0
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
68 |
-- Add incoming subscription and respond |
f95a1e197a07
mod_auto_moved: New module implementing XEP-0283 r0.2.0
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
69 |
rm.set_contact_pending_in(to_user, module.host, new_jid); |
f95a1e197a07
mod_auto_moved: New module implementing XEP-0283 r0.2.0
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
70 |
rm.subscribed(to_user, module.host, new_jid); |
f95a1e197a07
mod_auto_moved: New module implementing XEP-0283 r0.2.0
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
71 |
module:send(st.presence({ to = new_jid, from = to_user.."@"..module.host, type = "subscribed" })); |
f95a1e197a07
mod_auto_moved: New module implementing XEP-0283 r0.2.0
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
72 |
rm.roster_push(to_user, module.host, new_jid); |
f95a1e197a07
mod_auto_moved: New module implementing XEP-0283 r0.2.0
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
73 |
|
f95a1e197a07
mod_auto_moved: New module implementing XEP-0283 r0.2.0
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
74 |
-- Request outgoing subscription if old JID had one |
f95a1e197a07
mod_auto_moved: New module implementing XEP-0283 r0.2.0
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
75 |
if rm.is_user_subscribed(to_user, module.host, old_jid) then |
f95a1e197a07
mod_auto_moved: New module implementing XEP-0283 r0.2.0
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
76 |
module:log("debug", "Requesting subscription to new JID"); |
f95a1e197a07
mod_auto_moved: New module implementing XEP-0283 r0.2.0
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
77 |
rm.set_contact_pending_out(to_user, module.host, new_jid); |
f95a1e197a07
mod_auto_moved: New module implementing XEP-0283 r0.2.0
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
78 |
module:send(st.presence({ to = new_jid, from = to_user.."@"..module.host, type = "subscribe" })); |
f95a1e197a07
mod_auto_moved: New module implementing XEP-0283 r0.2.0
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
79 |
end |
f95a1e197a07
mod_auto_moved: New module implementing XEP-0283 r0.2.0
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
80 |
end):catch(function (err) |
f95a1e197a07
mod_auto_moved: New module implementing XEP-0283 r0.2.0
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
81 |
module:log("debug", "Failed to verify moved statement for <%s> -> <%s>: %s", old_jid, new_jid_unverified, require "util.serialization".serialize(err, "debug")); |
f95a1e197a07
mod_auto_moved: New module implementing XEP-0283 r0.2.0
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
82 |
stanza:reset() |
f95a1e197a07
mod_auto_moved: New module implementing XEP-0283 r0.2.0
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
83 |
:tag("moved-verification", { xmlns = "https://prosody.im/protocol/moved", status = "failed" }) |
f95a1e197a07
mod_auto_moved: New module implementing XEP-0283 r0.2.0
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
84 |
:up(); |
f95a1e197a07
mod_auto_moved: New module implementing XEP-0283 r0.2.0
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
85 |
module:send(stanza, origin); |
f95a1e197a07
mod_auto_moved: New module implementing XEP-0283 r0.2.0
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
86 |
end); |
f95a1e197a07
mod_auto_moved: New module implementing XEP-0283 r0.2.0
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
87 |
|
f95a1e197a07
mod_auto_moved: New module implementing XEP-0283 r0.2.0
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
88 |
-- Halt processing of the stanza, for now |
f95a1e197a07
mod_auto_moved: New module implementing XEP-0283 r0.2.0
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
89 |
return true; |
f95a1e197a07
mod_auto_moved: New module implementing XEP-0283 r0.2.0
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
90 |
end, 1); |