Fix ordering in perl subscription_list
[blerg.git] / aux / cgi / recovery.cgi
index 186bf2f..f63175a 100755 (executable)
@@ -3,6 +3,8 @@ use CGI::Fast qw/:cgi/;
 use Digest::SHA qw/hmac_sha256/;
 use MIME::Base64 qw/encode_base64url/;
 use Blerg::Database;
+use Mail::Message;
+use Time::HiRes qw/sleep/;
 use strict;
 use v5.10;
 
@@ -94,9 +96,56 @@ while (my $q = new CGI::Fast) {
             print generate_reset_url($username, $validity);
         }
         when ('mail') {
+            print header(-type => 'application/json');
+
+            if (!(defined $q->param('username') and defined $q->param('email'))) {
+                say '{"status": "failed"}';
+                next REQUEST;
+            }
+
+            # Sleep for a bit to scramble the timing
+            sleep(rand(1.0) + 1);
+
+            # From here on, we report success so as not to leak user information
+            my $username = $q->param('username');
+            if (!Blerg::Database::exists($username)) {
+                say '{"status": "success"}';
+                next REQUEST;
+            }
+
             # check that the user has a validated mail address
-            # generate reset message
-            # send mail
+            my $email_conf_path = Blerg::Database::configuration->{data_path} . "/$username/email";
+            my $email;
+            if (!open EMAIL, $email_conf_path) {
+                say '{"status": "success"}';
+                next REQUEST;
+            }
+            $email = <EMAIL>;
+            close EMAIL;
+
+            if ($q->param('email') ne $email) {
+                say '{"status": "success"}';
+                next REQUEST;
+            }
+
+            my $url = generate_reset_url($username, 900);
+            Mail::Message->build(
+                From => Mail::Address->new('BlergBot', 'noreply@blerg.cc'),
+                To => $email,
+                Subject => 'Blërg Password Recovery',
+                Mail::Message::Field->new('Content-Type', 'text/plain', 'charset="utf8"'),
+                data => <<EMAIL
+Here's a 15-minute recovery link to reset your password.
+
+$url
+
+If you didn't request a password reset, please ignore this email.
+
+- Blërg!
+EMAIL
+            )->send;
+
+            say '{"status": "success"}';
         }
         when ('validate') {
             print header(-type => 'application/json');