KVSun / kvsun.com

Kern Valley Sun website
GNU General Public License v3.0
5 stars 10 forks source link

Email notifications #108

Closed shgysk8zer0 closed 7 years ago

shgysk8zer0 commented 7 years ago

Steps to reproduce

  1. Register / subscribe / comment /etc.

Expected behavior

Certain actions should send email notifications. Not just for users, but also for staff who need to be notified.

Actual behavior

Nothing. Authorize sends emails for payments, but that's it.

shgysk8zer0 commented 7 years ago

This will be important for #36 . Resetting passwords will almost certainly require the ability to send emails.

This can be done using standard mail function if running on email server or it will require some use of SMTP.

shgysk8zer0 commented 7 years ago

One possible temporary solution is to create a simple API just to pass arguments into mail.

Cheap and ugly, but it'll work.

<?php
if (/* Check password or signature or something */) {
    mail($_GET['to'], $_GET['subject'], $_GET['message'], "From: {$_GET['from']}");
}
shgysk8zer0 commented 7 years ago

Should probably add some verification to prevent rogue emails. Add an RSA signature to the request using some unique details. Get the public key on the receiving server and verify the signature before sending.

shgysk8zer0 commented 7 years ago

Concept work. Remove use of private key and adding signature for actual use. The signature should be in the initial request.

<?php
namespace KVSun\Mail;

use \shgysk8zer0\Core\{FormData, Headers};
use \shgysk8zer0\PHPCrypt\{PublicKey, PrivateKey};
use \shgysk8zer0\Core_API\{Abstracts\HTTPStatusCodes as HTTP};

use const \KVSun\Consts\{PUBLIC_KEY, PRIVATE_KEY, PASSWD};

const FROM = 'no-reply@kvsun.com';

try {
    $data      = new FormData($_REQUEST);
    $private   = PrivateKey::importFromFile(PRIVATE_KEY, PASSWD);
    $data->sig = $private->sign(json_encode([
        'to'      => $data->to,
        'subject' => $data->subject,
        'message' => $data->message,
    ]));
    if (isset($data->to, $data->subject, $data->message, $data->sig)) {
        $header     = new Headers();
        $public     = PublicKey::importFromFile(PUBLIC_KEY);
        $data->from = $data->from ?? FROM;

        if ($public->verify(json_encode([
            'to'      => $data->to,
            'subject' => $data->subject,
            'message' => $data->message,
        ]), $data->sig)) {
            $header->content_type = 'application/json';
            mail($data->to, $data->subject, $data->message, "From: {$data->from}");
            exit(json_encode($data));
        } else {
            throw new \Exception('Invalid signature');
        }
    } else {
        throw new \Exception('Invalid request');
    }
} catch (\Throwable $e) {
    http_response_code(HTTP::UNAUTHORIZED);
}

Will probably want to add error handling using trigger_error and add IP addresses to the exceptions.

shgysk8zer0 commented 7 years ago

Closed in commit 3900238418ad087e88eab14af4030b2bcf61b0e4