2 use CGI::Fast qw/:cgi/;
3 use Digest::SHA qw/hmac_sha256/;
4 use MIME::Base64 qw/encode_base64url decode_base64url/;
12 open HMAC_KEY, "$ENV{BLERG_HOME}/etc/hmac_key"
13 or die "Could not open $ENV{BLERG_HOME}/etc/hmac_key";
14 read(HMAC_KEY, $hmac_key, 256);
18 print header(-type => 'text/html',
19 -status => '404 Not Found');
22 <h1>404 Not Found</h1>
27 print header(-type => 'text/html',
28 -status => '403 Forbidden');
31 <h1>403 Forbidden</h1>
36 sub generate_email_verify_url {
37 my ($username, $email) = @_;
39 # generate verification data
40 my $expiry = time + 900;
41 my $email_b64 = encode_base64url($email);
42 my $data = "$username:$email_b64:$expiry";
45 my $hmac = encode_base64url(hmac_sha256($data, $hmac_key));
47 return Blerg::Database::BASEURL . "#/email-verify/$data:$hmac";
50 sub validate_email_data {
54 if ($data =~ /^(.*):([^:]+)$/) {
61 my $computed_hmac = encode_base64url(hmac_sha256($payload, $hmac_key));
62 if ($hmac ne $computed_hmac) {
66 my ($username, $email, $expiry) = split(':', $payload);
67 $email = decode_base64url($email);
72 return ($username, $email);
75 sub validate_authentication {
78 my $auth = $q->cookie('auth');
82 my ($username, $token) = split('/', $auth);
83 if (Blerg::Database::auth_check_token($username, $token)) {
91 while (my $q = new CGI::Fast) {
92 my (undef, $cmd, $args) = split '/', $ENV{PATH_INFO}, 3;
96 my $username = validate_authentication($q);
97 if (!defined $username) {
102 print header(-type => 'application/json');
103 my $email = $q->param('email');
104 if (!defined $email) {
105 say '{"status": "failure"}';
109 my $url = generate_email_verify_url($username, $email);
110 Mail::Message->build(
111 From => Mail::Address->new('BlergBot', 'noreply@blerg.cc'),
113 Subject => 'Blërg Email Verification',
114 Mail::Message::Field->new('Content-Type', 'text/plain', 'charset="utf8"'),
116 To verify this email address, please click or copy/paste the following link
117 into your web browser.
121 If you received this email by mistake, just ignore it.
127 say '{"status": "success"}';
130 print header(-type => 'application/json');
132 my ($username, $email) = validate_email_data($q->param('data'));
134 if (!defined $username) {
135 say '{"status": "failure"}';
139 my $email_conf_path = Blerg::Database::configuration->{data_path} . "/$username/email";
140 open CONF, '>', $email_conf_path;
144 say '{"status": "success"}';
147 my $username = validate_authentication($q);
148 if (!defined $username) {
154 my $email_conf_path = Blerg::Database::configuration->{data_path} . "/$username/email";
155 if (-f $email_conf_path) {
156 open CONF, $email_conf_path;
161 say header(-type => 'application/json'),
162 JSON->new->utf8->encode({email => $email});
165 my $username = validate_authentication($q);
166 if (!defined $username) {
171 print header(-type => 'application/json');
173 my $email_conf_path = Blerg::Database::configuration->{data_path} . "/$username/email";
174 if (unlink $email_conf_path) {
175 say '{"status": "success"}';
177 say '{"status": "failure"}';