24 |
24 |
25 -- This table has the tokens submited by the server |
25 -- This table has the tokens submited by the server |
26 tokens_mails = {}; |
26 tokens_mails = {}; |
27 tokens_expiration = {}; |
27 tokens_expiration = {}; |
28 |
28 |
29 -- URL |
29 -- URL |
30 local https_host = module:get_option_string("https_host"); |
30 local https_host = module:get_option_string("https_host"); |
31 local http_host = module:get_option_string("http_host"); |
31 local http_host = module:get_option_string("http_host"); |
32 local https_port = module:get_option("https_ports", { 443 }); |
32 local https_port = module:get_option("https_ports", { 443 }); |
33 local http_port = module:get_option("http_ports", { 80 }); |
33 local http_port = module:get_option("http_ports", { 80 }); |
34 |
34 |
160 module:log("error", "Reset password token collision: '%s'", token); |
160 module:log("error", "Reset password token collision: '%s'", token); |
161 return generateToken(address) |
161 return generateToken(address) |
162 end |
162 end |
163 end |
163 end |
164 |
164 |
165 function isExpired(token) |
165 function isExpired(token) |
166 if not tokens_expiration[token] then |
166 if not tokens_expiration[token] then |
167 return nil; |
167 return nil; |
168 end |
168 end |
169 if os.difftime(os.time(), tokens_expiration[token]) < 86400 then -- 86400 secs == 24h |
169 if os.difftime(os.time(), tokens_expiration[token]) < 86400 then -- 86400 secs == 24h |
170 -- token is valid yet |
170 -- token is valid yet |
171 return nil; |
171 return nil; |
172 else |
172 else |
173 -- token invalid, we can create a fresh one. |
173 -- token invalid, we can create a fresh one. |
174 return true; |
174 return true; |
175 end |
175 end |
176 end |
176 end |
177 |
177 |
178 -- Expire tokens |
178 -- Expire tokens |
179 expireTokens = function() |
179 expireTokens = function() |
180 for token,value in pairs(tokens_mails) do |
180 for token,value in pairs(tokens_mails) do |
181 if isExpired(token) then |
181 if isExpired(token) then |
182 module:log("info","Expiring password reset request from user '%s', not used.", tokens_mails[token]); |
182 module:log("info","Expiring password reset request from user '%s', not used.", tokens_mails[token]); |
183 tokens_mails[token] = nil; |
183 tokens_mails[token] = nil; |
197 return nil; |
197 return nil; |
198 end |
198 end |
199 |
199 |
200 function generateUrl(token) |
200 function generateUrl(token) |
201 local url; |
201 local url; |
202 |
202 |
203 if https_host then |
203 if https_host then |
204 url = "https://" .. https_host; |
204 url = "https://" .. https_host; |
205 else |
205 else |
206 url = "http://" .. http_host; |
206 url = "http://" .. http_host; |
207 end |
207 end |
208 |
208 |
209 if https_port then |
209 if https_port then |
210 url = url .. ":" .. https_port[1]; |
210 url = url .. ":" .. https_port[1]; |
211 else |
211 else |
212 url = url .. ":" .. http_port[1]; |
212 url = url .. ":" .. http_port[1]; |
213 end |
213 end |
214 |
214 |
215 url = url .. url_path .. "token.html?" .. token; |
215 url = url .. url_path .. "token.html?" .. token; |
216 |
216 |
217 return url; |
217 return url; |
218 end |
218 end |
219 |
219 |
220 function sendMessage(jid, subject, message) |
220 function sendMessage(jid, subject, message) |
221 local msg = st.message({ from = module.host; to = jid; }): |
221 local msg = st.message({ from = module.host; to = jid; }): |
227 function send_token_mail(form, origin) |
227 function send_token_mail(form, origin) |
228 local user, host, resource = jidutil.split(form.username); |
228 local user, host, resource = jidutil.split(form.username); |
229 local prepped_username = nodeprep(user); |
229 local prepped_username = nodeprep(user); |
230 local prepped_mail = form.email; |
230 local prepped_mail = form.email; |
231 local jid = prepped_username .. "@" .. host; |
231 local jid = prepped_username .. "@" .. host; |
232 |
232 |
233 if not prepped_username then |
233 if not prepped_username then |
234 return nil, "El usuario contiene caracteres incorrectos"; |
234 return nil, "El usuario contiene caracteres incorrectos"; |
235 end |
235 end |
236 if #prepped_username == 0 then |
236 if #prepped_username == 0 then |
237 return nil, "El campo usuario está vacio"; |
237 return nil, "El campo usuario está vacio"; |
238 end |
238 end |
239 if not usermanager.user_exists(prepped_username, module.host) then |
239 if not usermanager.user_exists(prepped_username, module.host) then |
240 return nil, "El usuario NO existe"; |
240 return nil, "El usuario NO existe"; |
241 end |
241 end |
242 |
242 |
243 if #prepped_mail == 0 then |
243 if #prepped_mail == 0 then |
244 return nil, "El campo email está vacio"; |
244 return nil, "El campo email está vacio"; |
245 end |
245 end |
246 |
246 |
247 local vcarduser = get_user_vcard(prepped_username, module.host); |
247 local vcarduser = get_user_vcard(prepped_username, module.host); |
248 |
248 |
249 if not vcarduser then |
249 if not vcarduser then |
250 return nil, "User has not vCard"; |
250 return nil, "User has not vCard"; |
251 else |
251 else |
252 if not vcarduser.EMAIL then |
252 if not vcarduser.EMAIL then |
253 return nil, "Esa cuente no tiene ningún email configurado en su vCard"; |
253 return nil, "Esa cuente no tiene ningún email configurado en su vCard"; |
256 email = string.lower(vcarduser.EMAIL[1]); |
256 email = string.lower(vcarduser.EMAIL[1]); |
257 |
257 |
258 if email ~= string.lower(prepped_mail) then |
258 if email ~= string.lower(prepped_mail) then |
259 return nil, "Dirección eMail incorrecta"; |
259 return nil, "Dirección eMail incorrecta"; |
260 end |
260 end |
261 |
261 |
262 -- Check if has already a valid token, not used yet. |
262 -- Check if has already a valid token, not used yet. |
263 if hasTokenActive(jid) then |
263 if hasTokenActive(jid) then |
264 local valid_until = tokens_expiration[hasTokenActive(jid)] + 86400; |
264 local valid_until = tokens_expiration[hasTokenActive(jid)] + 86400; |
265 return nil, "Ya tienes una petición de restablecimiento de clave válida hasta: " .. datetime.date(valid_until) .. " " .. datetime.time(valid_until); |
265 return nil, "Ya tienes una petición de restablecimiento de clave válida hasta: " .. datetime.date(valid_until) .. " " .. datetime.time(valid_until); |
266 end |
266 end |
267 |
267 |
268 local url_token = generateToken(jid); |
268 local url_token = generateToken(jid); |
269 local url = generateUrl(url_token); |
269 local url = generateUrl(url_token); |
270 local email_body = render(get_template("sendtoken",".mail"), {jid = jid, url = url} ); |
270 local email_body = render(get_template("sendtoken",".mail"), {jid = jid, url = url} ); |
271 |
271 |
272 module:log("info", "Sending password reset mail to user %s", jid); |
272 module:log("info", "Sending password reset mail to user %s", jid); |
273 send_email(email, smtp_address, email_body, mail_subject); |
273 send_email(email, smtp_address, email_body, mail_subject); |
274 return "ok"; |
274 return "ok"; |
275 end |
275 end |
276 |
276 |
277 end |
277 end |
278 |
278 |
279 function reset_password_with_token(form, origin) |
279 function reset_password_with_token(form, origin) |
280 local token = form.token; |
280 local token = form.token; |
281 local password = form.newpassword; |
281 local password = form.newpassword; |
282 |
282 |
283 if not token then |
283 if not token then |
284 return nil, "El Token es inválido"; |
284 return nil, "El Token es inválido"; |
285 end |
285 end |
286 if not tokens_mails[token] then |
286 if not tokens_mails[token] then |
287 return nil, "El Token no existe o ya fué usado"; |
287 return nil, "El Token no existe o ya fué usado"; |
292 if #password < 5 then |
292 if #password < 5 then |
293 return nil, "La clave debe tener una longitud de al menos 5 caracteres"; |
293 return nil, "La clave debe tener una longitud de al menos 5 caracteres"; |
294 end |
294 end |
295 local jid = tokens_mails[token]; |
295 local jid = tokens_mails[token]; |
296 local user, host, resource = jidutil.split(jid); |
296 local user, host, resource = jidutil.split(jid); |
297 |
297 |
298 usermanager.set_password(user, password, host); |
298 usermanager.set_password(user, password, host); |
299 module:log("info", "Password changed with token for user %s", jid); |
299 module:log("info", "Password changed with token for user %s", jid); |
300 tokens_mails[token] = nil; |
300 tokens_mails[token] = nil; |
301 tokens_expiration[token] = nil; |
301 tokens_expiration[token] = nil; |
302 sendMessage(jid, mail_subject, mail_body); |
302 sendMessage(jid, mail_subject, mail_body); |