Mercurial > prosody-modules
comparison mod_invites_register_api/mod_invites_register_api.lua @ 6165:e977174082ee
mod_invites_register_api: Use set_password() for password resets
Previously the code relied on the (weird) behaviour of create_user(), which
would update the password for a user account if it already existed. This has
several issues, and we plan to deprecate this behaviour of create_user().
The larger issue is that this route does not trigger the user-password-changed
event, which can be a security problem. For example, it did not disconnect
existing user sessions (this occurs in mod_c2s in response to the event).
Switching to set_password() is the right thing to do
| author | Matthew Wild <mwild1@gmail.com> |
|---|---|
| date | Thu, 06 Feb 2025 10:24:30 +0000 |
| parents | 76ae646563ea |
| children |
comparison
equal
deleted
inserted
replaced
| 6164:76ae646563ea | 6165:e977174082ee |
|---|---|
| 73 if reset_for ~= nil then | 73 if reset_for ~= nil then |
| 74 module:log("debug", "handling password reset invite for %s", reset_for) | 74 module:log("debug", "handling password reset invite for %s", reset_for) |
| 75 if reset_for ~= prepped_username then | 75 if reset_for ~= prepped_username then |
| 76 return 403; -- Attempt to use reset invite for incorrect user | 76 return 403; -- Attempt to use reset invite for incorrect user |
| 77 end | 77 end |
| 78 local ok, err = usermanager.set_password(prepped_username, password, module.host); | |
| 79 if not ok then | |
| 80 module:log("error", "Unable to reset password for %s@%s: %s", prepped_username, module.host, err); | |
| 81 return 500; | |
| 82 end | |
| 83 module:fire_event("user-password-reset", user); | |
| 78 elseif usermanager.user_exists(prepped_username, module.host) then | 84 elseif usermanager.user_exists(prepped_username, module.host) then |
| 79 return 409; -- Conflict | 85 return 409; -- Conflict |
| 86 else | |
| 87 local registering = { | |
| 88 validated_invite = invite; | |
| 89 username = prepped_username; | |
| 90 host = module.host; | |
| 91 ip = request.ip; | |
| 92 allowed = true; | |
| 93 }; | |
| 94 | |
| 95 module:fire_event("user-registering", registering); | |
| 96 | |
| 97 if not registering.allowed then | |
| 98 return 403; | |
| 99 end | |
| 100 | |
| 101 local ok, err = usermanager.create_user(prepped_username, password, module.host); | |
| 102 | |
| 103 if not ok then | |
| 104 local err_id = id.short(); | |
| 105 module:log("warn", "Registration failed (%s): %s", err_id, tostring(err)); | |
| 106 return 500; | |
| 107 end | |
| 108 | |
| 109 module:fire_event("user-registered", { | |
| 110 username = prepped_username; | |
| 111 host = module.host; | |
| 112 source = "mod_"..module.name; | |
| 113 validated_invite = invite; | |
| 114 ip = request.ip; | |
| 115 }); | |
| 80 end | 116 end |
| 81 | |
| 82 local registering = { | |
| 83 validated_invite = invite; | |
| 84 username = prepped_username; | |
| 85 host = module.host; | |
| 86 ip = request.ip; | |
| 87 allowed = true; | |
| 88 }; | |
| 89 | |
| 90 module:fire_event("user-registering", registering); | |
| 91 | |
| 92 if not registering.allowed then | |
| 93 return 403; | |
| 94 end | |
| 95 | |
| 96 local ok, err = usermanager.create_user(prepped_username, password, module.host); | |
| 97 | |
| 98 if not ok then | |
| 99 local err_id = id.short(); | |
| 100 module:log("warn", "Registration failed (%s): %s", err_id, tostring(err)); | |
| 101 return 500; | |
| 102 end | |
| 103 | |
| 104 module:fire_event("user-registered", { | |
| 105 username = prepped_username; | |
| 106 host = module.host; | |
| 107 source = "mod_"..module.name; | |
| 108 validated_invite = invite; | |
| 109 ip = request.ip; | |
| 110 }); | |
| 111 | 117 |
| 112 return json.encode({ | 118 return json.encode({ |
| 113 jid = prepped_username .. "@" .. module.host; | 119 jid = prepped_username .. "@" .. module.host; |
| 114 }); | 120 }); |
| 115 end | 121 end |
