1
0
Fork 0
mirror of synced 2024-06-29 03:30:34 +12:00

Merge pull request #411 from TorstenDittmann/mails

[Feature] Mail background worker
This commit is contained in:
Eldad A. Fux 2020-06-14 19:32:34 +03:00 committed by GitHub
commit 2af2cec0e3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 101 additions and 50 deletions

View file

@ -27,6 +27,7 @@ $services = include __DIR__.'/config/services.php'; // List of services
$webhook = new Event('v1-webhooks', 'WebhooksV1');
$audit = new Event('v1-audits', 'AuditsV1');
$usage = new Event('v1-usage', 'UsageV1');
$mail = new Event('v1-mails', 'MailsV1');
$deletes = new Event('v1-deletes', 'DeletesV1');
/**
@ -53,7 +54,7 @@ $clients = array_unique(array_merge($clientsConsole, array_map(function ($node)
return false;
}))));
$utopia->init(function () use ($utopia, $request, $response, &$user, $project, $console, $roles, $webhook, $audit, $usage, $clients) {
$utopia->init(function () use ($utopia, $request, $response, &$user, $project, $console, $roles, $webhook, $mail, $audit, $usage, $clients) {
$route = $utopia->match($request);

View file

@ -1,7 +1,7 @@
<?php
global $utopia, $register, $request, $response, $user, $audit,
$webhook, $project, $projectDB, $clients;
$webhook, $mail, $project, $projectDB, $clients;
use Utopia\Exception;
use Utopia\Response;
@ -60,7 +60,7 @@ $utopia->post('/v1/account')
->param('password', '', function () { return new Password(); }, 'User password. Must be between 6 to 32 chars.')
->param('name', '', function () { return new Text(100); }, 'User name.', true)
->action(
function ($email, $password, $name) use ($register, $request, $response, $audit, $projectDB, $project, $webhook, $oauth2Keys) {
function ($email, $password, $name) use ($request, $response, $audit, $projectDB, $project, $webhook, $oauth2Keys) {
if ('console' === $project->getId()) {
$whitlistEmails = $project->getAttribute('authWhitelistEmails');
$whitlistIPs = $project->getAttribute('authWhitelistIPs');
@ -1053,7 +1053,7 @@ $utopia->post('/v1/account/recovery')
->param('email', '', function () { return new Email(); }, 'User email.')
->param('url', '', function () use ($clients) { return new Host($clients); }, 'URL to redirect the user back to your app from the recovery email. Only URLs from hostnames in your project platform list are allowed. This requirement helps to prevent an [open redirect](https://cheatsheetseries.owasp.org/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.html) attack against your project API.')
->action(
function ($email, $url) use ($request, $response, $projectDB, $register, $audit, $project) {
function ($email, $url) use ($request, $response, $projectDB, $mail, $audit, $project) {
$profile = $projectDB->getCollection([ // Get user by email address
'limit' => 1,
'first' => true,
@ -1106,19 +1106,14 @@ $utopia->post('/v1/account/recovery')
->setParam('{{redirect}}', $url)
;
$mail = $register->get('smtp'); /* @var $mail \PHPMailer\PHPMailer\PHPMailer */
$mail->addAddress($profile->getAttribute('email', ''), $profile->getAttribute('name', ''));
$mail->Subject = Locale::getText('account.emails.recovery.title');
$mail->Body = $body->render();
$mail->AltBody = strip_tags($body->render());
try {
$mail->send();
} catch (\Exception $error) {
throw new Exception('Error sending mail: ' . $error->getMessage(), 500);
}
$mail
->setParam('event', 'account.recovery.create')
->setParam('recipient', $profile->getAttribute('email', ''))
->setParam('name', $profile->getAttribute('name', ''))
->setParam('subject', Locale::getText('account.emails.recovery.title'))
->setParam('body', $body->render())
->trigger();
;
$audit
->setParam('userId', $profile->getId())
@ -1214,7 +1209,7 @@ $utopia->post('/v1/account/verification')
->label('abuse-key', 'url:{url},email:{param-email}')
->param('url', '', function () use ($clients) { return new Host($clients); }, 'URL to redirect the user back to your app from the verification email. Only URLs from hostnames in your project platform list are allowed. This requirement helps to prevent an [open redirect](https://cheatsheetseries.owasp.org/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.html) attack against your project API.') // TODO add built-in confirm page
->action(
function ($url) use ($request, $response, $register, $user, $project, $projectDB, $audit) {
function ($url) use ($request, $response, $mail, $user, $project, $projectDB, $audit) {
$verificationSecret = Auth::tokenGenerator();
$verification = new Document([
@ -1255,19 +1250,14 @@ $utopia->post('/v1/account/verification')
->setParam('{{redirect}}', $url)
;
$mail = $register->get('smtp'); /* @var $mail \PHPMailer\PHPMailer\PHPMailer */
$mail->addAddress($user->getAttribute('email'), $user->getAttribute('name'));
$mail->Subject = Locale::getText('account.emails.verification.title');
$mail->Body = $body->render();
$mail->AltBody = strip_tags($body->render());
try {
$mail->send();
} catch (\Exception $error) {
throw new Exception('Problem sending mail: ' . $error->getMessage(), 500);
}
$mail
->setParam('event', 'account.verification.create')
->setParam('recipient', $user->getAttribute('email'))
->setParam('name', $user->getAttribute('name'))
->setParam('subject', Locale::getText('account.emails.verification.title'))
->setParam('body', $body->render())
->trigger()
;
$audit
->setParam('userId', $user->getId())

View file

@ -1,6 +1,6 @@
<?php
global $utopia, $register, $request, $response, $projectDB, $project, $user, $audit, $mode, $clients;
global $utopia, $register, $request, $response, $projectDB, $project, $user, $audit, $mail, $mode, $clients;
use Utopia\Exception;
use Utopia\Response;
@ -215,7 +215,7 @@ $utopia->post('/v1/teams/:teamId/memberships')
->param('roles', [], function () { return new ArrayList(new Text(128)); }, 'Array of strings. Use this param to set the user roles in the team. A role can be any string. Learn more about [roles and permissions](/docs/permissions).')
->param('url', '', function () use ($clients) { return new Host($clients); }, 'URL to redirect the user back to your app from the invitation email. Only URLs from hostnames in your project platform list are allowed. This requirement helps to prevent an [open redirect](https://cheatsheetseries.owasp.org/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.html) attack against your project API.') // TODO add our own built-in confirm page
->action(
function ($teamId, $email, $name, $roles, $url) use ($response, $register, $project, $user, $audit, $projectDB, $mode) {
function ($teamId, $email, $name, $roles, $url) use ($response, $mail, $project, $user, $audit, $projectDB, $mode) {
$name = (empty($name)) ? $email : $name;
$team = $projectDB->getDocument($teamId);
@ -332,20 +332,15 @@ $utopia->post('/v1/teams/:teamId/memberships')
->setParam('{{redirect}}', $url)
;
$mail = $register->get('smtp'); /* @var $mail \PHPMailer\PHPMailer\PHPMailer */
$mail->addAddress($email, $name);
$mail->Subject = sprintf(Locale::getText('account.emails.invitation.title'), $team->getAttribute('name', '[TEAM-NAME]'), $project->getAttribute('name', ['[APP-NAME]']));
$mail->Body = $body->render();
$mail->AltBody = strip_tags($body->render());
try {
if(APP_MODE_ADMIN !== $mode) { // No need in comfirmation when in admin mode
$mail->send();
}
} catch (\Exception $error) {
throw new Exception('Error sending mail: ' . $error->getMessage(), 500);
if(APP_MODE_ADMIN !== $mode) { // No need in comfirmation when in admin mode
$mail
->setParam('event', 'teams.membership.create')
->setParam('recipient', $email)
->setParam('name', $name)
->setParam('subject', sprintf(Locale::getText('account.emails.invitation.title'), $team->getAttribute('name', '[TEAM-NAME]'), $project->getAttribute('name', ['[APP-NAME]'])))
->setParam('body', $body->render())
->trigger();
;
}
$audit

48
app/workers/mails.php Normal file
View file

@ -0,0 +1,48 @@
<?php
require_once __DIR__.'/../init.php';
cli_set_process_title('Mails V1 Worker');
echo APP_NAME.' mails worker v1 has started';
class MailsV1
{
/**
* @var array
*/
public $args = [];
public function setUp()
{
}
public function perform()
{
global $register;
$event = $this->args['event'];
$recipient = $this->args['recipient'];
$name = $this->args['name'];
$subject = $this->args['subject'];
$body = $this->args['body'];
$mail = $register->get('smtp'); /* @var $mail \PHPMailer\PHPMailer\PHPMailer */
$mail->addAddress($recipient, $name);
$mail->Subject = $subject;
$mail->Body = $body;
$mail->AltBody = strip_tags($body);
try {
$mail->send();
} catch (\Exception $error) {
throw new Exception('Error sending mail: ' . $error->getMessage(), 500);
}
}
public function tearDown()
{
// ... Remove environment for this job
}
}

View file

@ -65,6 +65,23 @@ stdout_logfile_maxbytes=5000000
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes = 0
[program:v1-mails]
command=php /usr/share/nginx/html/vendor/bin/resque
autostart=true
autorestart=true
priority=10
environment=QUEUE='v1-mails',APP_INCLUDE='/usr/share/nginx/html/app/workers/mails.php',REDIS_BACKEND='%(ENV__APP_REDIS_HOST)s:%(ENV__APP_REDIS_PORT)s'
stdout_events_enabled=true
stderr_events_enabled=true
stopsignal=QUIT
startretries=10
;stdout_logfile=/dev/stdout
;stdout_logfile_maxbytes=0
stdout_logfile=/var/log/appwrite.log
stdout_logfile_maxbytes=5000000
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes = 0
[program:v1-audits]
command=php /usr/share/nginx/html/vendor/bin/resque
autostart=true

View file

@ -33,7 +33,7 @@ abstract class Scope extends TestCase
protected function getLastEmail():array
{
sleep(3);
sleep(10);
$emails = json_decode(file_get_contents('http://maildev/email'), true);
if($emails && is_array($emails)) {

View file

@ -658,7 +658,7 @@ trait AccountBase
$this->assertNotEmpty($response['body']['$id']);
$this->assertEquals(2, $response['body']['type']);
$this->assertIsNumeric($response['body']['expire']);
$lastEmail = $this->getLastEmail();
$this->assertEquals($email, $lastEmail['to'][0]['address']);
@ -950,7 +950,7 @@ trait AccountBase
$this->assertNotEmpty($response['body']['$id']);
$this->assertEquals(3, $response['body']['type']);
$this->assertIsNumeric($response['body']['expire']);
$lastEmail = $this->getLastEmail();
$this->assertEquals($email, $lastEmail['to'][0]['address']);