annotate mod_sms_free/mod_sms_free.lua @ 5401:c8d04ac200fc

mod_http_oauth2: Reject loopback URIs as client_uri This really should be a proper website with info, https://localhost is not good enough. Ideally we'd validate that it's got proper DNS and is actually reachable, but triggering HTTP or even DNS lookups seems like it would carry abuse potential that would best to avoid.
author Kim Alvefur <zash@zash.se>
date Tue, 02 May 2023 16:20:55 +0200
parents 5a70dd2349a7
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
3695
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
1 local http = require "net.http";
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
2 local jid_split = require "util.jid".split;
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
3 local dataforms_new = require "util.dataforms".new;
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
4 local adhoc_new = module:require "adhoc".new;
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
5 local adhoc_simple_form = require "util.adhoc".new_simple_form;
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
6 local t_concat = table.concat;
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
7
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
8 local store = module:open_store();
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
9
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
10 local function api_handler(body, code)
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
11 if code == 200 then
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
12 module:log("debug", "SMS correctly sent.");
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
13 elseif code == 0 then
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
14 module:log("error", "error querying Free API: %s", body);
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
15 elseif code >= 400 then
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
16 module:log("warn", "received error code %d: %s", code, body);
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
17 end
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
18 end
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
19
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
20 local function message_handler(event)
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
21 local message = event.stanza;
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
22 local username, host = jid_split(message.attr.to);
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
23
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
24 -- Only proceed if the user has set Free credentials.
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
25 local data = store:get(username);
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
26 if not data then
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
27 return;
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
28 end
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
29
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
30 -- Only proceed if the message is of type chat or normal.
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
31 local message_type = message.attr.type;
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
32 if message_type == "error" or message_type == "headline" or message_type == "groupchat" then
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
33 -- TODO: Maybe handle groupchat or headline in the future.
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
34 return;
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
35 end
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
36
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
37 -- Only proceed if the message contains a body.
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
38 local body = message:get_child_text("body");
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
39 if not body then
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
40 return;
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
41 end
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
42
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
43 -- Only proceed if all sessions are "xa", or if there are no sessions.
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
44 local sessions = prosody.hosts[host].sessions[username];
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
45 if sessions then
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
46 local do_send = true;
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
47 for _, session in pairs(sessions.sessions) do
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
48 local show = session.presence:get_child_text("show");
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
49 if show ~= "xa" then
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
50 do_send = false;
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
51 end
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
52 end
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
53 if not do_send then
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
54 return;
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
55 end
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
56 end
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
57
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
58 -- Then do the actual request to send the SMS.
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
59 local headers = {
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
60 user = data.user,
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
61 pass = data.pass,
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
62 msg = http.urlencode(body),
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
63 };
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
64 http.request("https://smsapi.free-mobile.fr/sendmsg", { headers = headers }, api_handler);
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
65 end
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
66
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
67 local set_form = dataforms_new {
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
68 title = "Set mobile.free.fr SMS credentials";
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
69 instructions = "Enable the “Notifications by SMS” service at https://mobile.free.fr/moncompte/ and paste the credentials in this form.";
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
70 {
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
71 type = "hidden";
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
72 name = "FORM_TYPE";
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
73 value = "http://prosody.im/protocol/sms_free#set";
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
74 };
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
75 {
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
76 type = "text-single";
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
77 name = "user";
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
78 label = "Your login on Free’s website";
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
79 };
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
80 {
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
81 type = "text-single";
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
82 name = "pass";
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
83 label = "Your authentication key";
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
84 };
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
85 };
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
86
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
87 local set_adhoc = adhoc_simple_form(set_form, function (data, errors, state)
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
88 if errors then
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
89 local errmsg = {};
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
90 for name, text in pairs(errors) do
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
91 errmsg[#errmsg + 1] = name .. ": " .. text;
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
92 end
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
93 return { status = "completed", error = { message = t_concat(errmsg, "\n") } };
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
94 end
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
95
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
96 local username, host = jid_split(state.from);
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
97 module:log("debug", "Setting mobile.free.fr credentials for %s@%s: user=%s, pass=%s", username, host, data.user, data.pass);
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
98 local ok, err = store:set(username, { user = data.user, pass = data.pass });
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
99 if ok then
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
100 return { status = "completed", info = "SMS notifications to your phone enabled." };
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
101 else
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
102 return { status = "completed", error = { message = err } };
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
103 end
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
104 end);
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
105
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
106 module:provides("adhoc", adhoc_new("Set mobile.free.fr SMS notification credentials", "http://prosody.im/protocol/sms_free#set", set_adhoc));
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
107
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
108 module:provides("adhoc", adhoc_new("Unset mobile.free.fr SMS notifications", "http://prosody.im/protocol/sms_free#unset", function (_, data)
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
109 if data.action ~= "execute" then
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
110 return { status = "canceled" };
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
111 end
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
112
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
113 module:log("debug", "Unsetting mobile.free.fr credentials.");
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
114 local username, host = jid_split(data.from);
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
115 local ok, err = store:set(username, nil);
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
116 if ok then
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
117 return { status = "completed", info = "SMS notifications to your phone disabled." };
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
118 else
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
119 return { status = "completed", error = { message = err } };
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
120 end
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
121 end));
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
122
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
123 -- Stanzas sent to local clients.
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
124 module:hook("message/bare", message_handler);
5a70dd2349a7 mod_sms_free: New module!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
125 module:hook("message/full", message_handler);