Comparison

mod_invites_register_api/mod_invites_register_api.lua @ 4380:cba8cd564641

mod_invites_register_api: New module to allow turning invites into accounts via a HTTP API
author Matthew Wild <mwild1@gmail.com>
date Mon, 25 Jan 2021 12:44:20 +0000
child 4381:a1256e376dca
comparison
equal deleted inserted replaced
4379:950abc6c67b8 4380:cba8cd564641
1 local id = require "util.id";
2 local json = require "util.json";
3 local usermanager = require "core.usermanager";
4 local nodeprep = require "util.encodings".stringprep.nodeprep;
5
6 local site_name = module:get_option_string("site_name", module.host);
7
8 local json_content_type = "application/json";
9
10 module:depends("http");
11
12 local invites = module:depends("invites");
13
14 function get_invite_info(event, invite_token)
15 if not invite_token or #invite_token == 0 then
16 return 404;
17 end
18 local invite = invites.get(invite_token);
19 if not invite then
20 return 404;
21 end
22
23 event.response.headers["Content-Type"] = json_content_type;
24 return json.encode({
25 site_name = site_name;
26 token = invite.token;
27 domain = module.host;
28 uri = invite.uri;
29 type = invite.type;
30 jid = invite.jid;
31 inviter = invite.inviter;
32 });
33 end
34
35 function register_with_invite(event, invite_token)
36 if not invite_token or #invite_token == 0 then
37 return 404;
38 end
39
40 local request, response = event.request, event.response;
41
42 if not request.body or #request.body == 0
43 or request.headers.content_type ~= json_content_type then
44 module:log("warn", "Invalid payload");
45 return 400;
46 end
47
48 local register_data = json.decode(event.request.body);
49 if not register_data then
50 module:log("warn", "Invalid JSON");
51 return 400;
52 end
53
54 local user, password, token = register_data.username, register_data.password, register_data.token;
55
56 local invite = invites.get(token);
57 if not invite then
58 return 404;
59 end
60
61 response.headers["Content-Type"] = json_content_type;
62
63 if not user or #user == 0 or not password or #password == 0 or not token then
64 module:log("warn", "Invalid data");
65 return 400;
66 end
67
68 -- Shamelessly copied from mod_register_web.
69 local prepped_username = nodeprep(user);
70
71 if not prepped_username or #prepped_username == 0 then
72 return 400;
73 end
74
75 if usermanager.user_exists(prepped_username, module.host) then
76 return 409; -- Conflict
77 end
78
79 local registering = {
80 validated_invite = invite;
81 username = prepped_username;
82 host = module.host;
83 ip = request.ip;
84 allowed = true;
85 };
86
87 module:fire_event("user-registering", registering);
88
89 if not registering.allowed then
90 return 403;
91 end
92
93 local ok, err = usermanager.create_user(prepped_username, password, module.host);
94
95 if not ok then
96 local err_id = id.short();
97 module:log("warn", "Registration failed (%s): %s", err_id, tostring(err));
98 return 500;
99 end
100
101 module:fire_event("user-registered", {
102 username = prepped_username;
103 host = module.host;
104 source = "mod_"..module.name;
105 validated_invite = invite;
106 ip = request.ip;
107 });
108
109 return 200;
110 end
111
112 module:provides("http", {
113 default_path = "register_api";
114 route = {
115 ["GET /invite/*"] = get_invite_info;
116 ["POST /register/*"] = register_with_invite;
117 };
118 });