resetpw.pl
212 lines of code
1
#!/usr/bin/perl
2
3
# must have's!
4
use strict;
5
use warnings;
6
use CGI::Carp qw(fatalsToBrowser);
7
use DBI;
8
use URI::Escape;
9
10
use lib "/var/www/html/Pm";
11
12
use Html qw(pre_html_header header html_end);
13
use Redir;
14
use Bc_chef qw(cookie_get cookie_delete);
15
use Bc_misc qw(get_param new_id referrer get_params_asHash);
16
use Bc_sql qw(sql_execute
17
              get_constant
18
19
              $DB
20
              $QUERY_UID
21
              $SITE_NAME
22
             );
23
use Date qw(get_today_cookie_style get_today add_date isBeforeDate);
24
use User qw(get_uid_byNickname get_user_stat);
25
26
my $DEBUG = 0;
27
28
my %params = get_params_asHash();
29
30
my $output;
31
32
if ($DEBUG) {
33
  $output = pre_html_header();
34
  $output .= "DEBUG MODE ENABLED<hr><br>\n\n";
35
  $output .= "\%params:<br>\n";
36
  foreach my $key (sort keys %params) {
37
    $output .= "    $key => $params{$key}<br>\n";
38
  }
39
}
40
41
my $nickname = get_param("n");
42
43
my $url = "https://night-stand.ca/resetpw.pl";
44
45
my $uid = get_uid_byNickname($nickname);
46
my $code = get_param("code");
47
my $e = cookie_get("e");
48
my $n = cookie_get("n");
49
50
if ($uid) {
51
  # send an email with new code
52
  # new code must be added to db
53
  #  eg: ID, code, uid, date (db format)
54
  $code = new_id(512);
55
  my $today = get_today("db", 1);
56
  #$today = add_date($today, -5, "d");
57
  my $sql = "insert into pw_reset values(NULL, " . $DB->quote($code) . ", " . $DB->quote($uid) . ", " . $DB->quote($today) . ")";
58
  my $result = sql_execute($sql, "resetpw.pl");
59
60
  if ($result) {
61
    # send email!
62
    # this msg needs serious work!
63
    my $msg = "Password Reset Request\n\n";
64
    $msg .= "Hi, " . get_user_stat($uid, "nickname") . "\n";
65
    $msg .= "\n";
66
    $msg .= "$SITE_NAME here!\n";
67
    $msg .= "\n";
68
    $msg .= "You are receiving this message because a request was placed to reset your password.\n";
69
    $msg .= "Please, click the link below to bring up the password reset screen.  Type your password\n";
70
    $msg .= "into both of the boxes provided, and click the green button.  Your password will be reset\n";
71
    $msg .= "and the request deleted.\n";
72
    $msg .= "\n";
73
    $msg .= "This will be the only message related to this request you will get from us.\n";
74
    $msg .= "\n";
75
    $msg .= "$url?code=$code\n";
76
    $msg .= "\n";
77
    $msg .= "Thank-You\n";
78
    $msg .= "\n";
79
    $msg .= "\n";
80
    $msg .= "Night-Stand\n";
81
    $msg .= "https://night-stand.ca/\n";
82
    $msg .= "\n";
83
    $msg .= "\n";
84
    $msg .= "\n";
85
    $msg .= "***note: if you did not submit this request, you may disregard it; the request will expire in a few days.\n";
86
    $msg .= "\n";
87
88
    my $email = get_user_stat($uid, "email");
89
    my $command = 'echo "' . $msg . '" | mail -s "Password Reset" -r noreply@night-stand.ca -aFrom:Password\ Reset\<noreply@night-stand.ca\> -- ' . $email;
90
91
    my $result = `$command`;
92
93
    $output = notice_redir(referrer(), "Password Reset Request Email Sent");
94
  } else {
95
    # could be a duplicate entry?
96
    # or something like the DB file is deleted?
97
    # or busy?  something...
98
    $output = error_redir(referrer(), "Glitch in the matrix!");
99
  }
100
} else {
101
  if ($code) {
102
    # look it up in database
103
    my $sql = "select * from pw_reset where code=" . $DB->quote($code);
104
    my $results = sql_execute($sql, "resetpw.pl");
105
106
    my $inDB = 0;
107
    if (ref $results eq "HASH") { $inDB = 1; }
108
109
    if ($inDB) {
110
      # if the date of the request is more than 3 days old,
111
      # it needs to be deleted from the db, and the user
112
      # should be told it's an invalid code
113
      my $notOld = 1;
114
      # if today > +3 days of $results->{date}
115
      my $expireDate = add_date($results->{date}, 4, "d");
116
      if (isBeforeDate($expireDate, get_today("db", 1))) {
117
        $notOld = 0;
118
      }
119
120
      if ($notOld) {
121
        my $pw = get_param("pw");
122
        my $pwa = get_param("pwa");
123
124
        if (($pw and $pwa) and ($pw eq $pwa)) {
125
          # yay, pw's match
126
          # $pw needs to be encrypted now
127
          my $pb = Crypt::PBKDF2->new;
128
          $pw = $pb->generate($pw);
129
          if (ref $results eq "HASH") {
130
            $uid = $results->{uid};
131
          } else {
132
            die "woah! hey, how'd we get here??\n";
133
          }
134
135
          my $sql = "update users set password=" . $DB->quote($pw) . " where ID=" . $DB->quote($uid);
136
          my $success = sql_execute($sql, "reset pw - update user pw");
137
          if ($success == 1) {
138
            # now we remove the "code" from the database, so to prevent this code from being reused!
139
            my $remove_code_sql = "delete from pw_reset where uid=" . $DB->quote($uid);
140
            my $removed = sql_execute($remove_code_sql, "reset pw - delete request");
141
            if ($removed > 0) {
142
              $output = notice_redir("/", "Password Reset Complete! ($removed)");
143
            } else {
144
              $output = error_redir("/", "Request Removal Failed! ($removed)");
145
            }
146
          } else {
147
            $output = error_redir(referrer(), "Password Reset Failed! ($success)");
148
          }
149
        } else {
150
          if ($pw and $pwa) {
151
            # pw mismatch
152
            $output = error_redir(referrer(), "password mismatch, pls try again!");
153
          } else {
154
            my $onload = "setTimeout(removeMsg, " . get_constant("REMOVE_MSG_TIMEOUT") . ");";
155
156
            $uid = $results->{uid};
157
            my $nn = get_user_stat($uid, "nickname");
158
159
            # present the pw text boxes
160
            $output = cookie_delete("e");
161
            $output .= cookie_delete("e");
162
            $output .= pre_html_header();
163
            $output .= header("Password Reset", "", "", $onload);
164
165
            $output .= "<table cellpadding=0 cellspacing=0 class=fullsize><tr><td align=center><table cellpadding=0 cellspacing=0><tr><td class=subnavbar>\n";
166
            $output .= "  Okay, all seems good to go.  Change your password by typing your<br>\n";
167
            $output .= "  password into each box below, and click the green button.<br>\n";
168
            $output .= "</td></tr><tr><td class=spacery_largest>\n";
169
            if ($e or $n) {
170
              $output .= "  <div id=MSGS";
171
              if ($e) { $output .= " class=error>$e"; }
172
              elsif ($n) { $output .= " class=notice>$n"; }
173
              $output .= "</div>\n";
174
            }
175
            $output .= "</td></tr><tr><td class=subnavbar>\n";
176
            $output .= "  <form method=post action='/resetpw.pl'>\n";
177
            $output .= "\n";
178
            $output .= "    Nickname: <input type=hidden name=$QUERY_UID value=\"$uid\">\n";
179
            $output .= "    <input type=hidden name=code value=\"$code\">\n";
180
            $output .= "    <input name=nickname placeholder='Nickname' required title='type your nickname here' value=\"$nn\" onclick='blur();'><br>\n";
181
            $output .= "    Password <input name=pw type=password placeholder='Password' required title='type your password here'><br>\n";
182
            $output .= "    Re-Type Password <input name=pwa type=password placeholder='password123'><br>\n";
183
            $output .= "    <button class=danger type=button onclick=\"document.location.href='/';\">Cancel</button>\n";
184
            $output .= "    <button class=green_button>Reset Password</button>\n";
185
            $output .= "\n";
186
            $output .= "\n";
187
            $output .= "  </form>\n";
188
            $output .= "</td></tr></table></td></tr></table>\n";
189
190
            $output .= html_end();
191
          }
192
        }
193
      } else {
194
        my $sql = "delete from pw_reset where code=" . $DB->quote($code);
195
        sql_execute($sql, "resetpw.pl");
196
        $output = error_redir("/", "bad code, bad!");
197
      }
198
    } else {
199
      $output = error_redir("/", "bad code, bad!");
200
    }
201
  } else {
202
    if ($DEBUG) {
203
      $output .= "wtf!";
204
    } else {
205
      $output = notice_redir(referrer(), "Password Reset Request Email Sent");
206
    }
207
  }
208
}
209
210
print $output;
211
212
exit 1;