anonaddy/app/Traits/CheckUserRules.php
2024-07-30 10:58:10 +01:00

184 lines
6.5 KiB
PHP

<?php
namespace App\Traits;
use Illuminate\Support\Str;
trait CheckUserRules
{
protected $emailType;
public function checkRules(string $emailType)
{
$this->emailType = $emailType;
$method = "activeRulesFor{$emailType}Ordered";
$this->user->{$method}->each(function ($rule) {
// Check if the conditions of the rule are satisfied
if ($this->ruleConditionsSatisfied($rule->conditions, $rule->operator)) {
// Apply actions for that rule
collect($rule->actions)->each(function ($action) {
$this->applyAction($action);
});
// Increment applied count
$rule->increment('applied', 1, ['last_applied' => now()]);
}
});
}
protected function ruleConditionsSatisfied($conditions, $logicalOperator)
{
$results = collect();
collect($conditions)->each(function ($condition) use ($results) {
$results->push($this->lookupConditionType($condition));
});
$result = $results->unique();
if ($logicalOperator === 'OR') {
return $result->contains(true);
}
// Logical operator is AND so return false if any conditions are not met
return ! $result->contains(false);
}
protected function lookupConditionType($condition)
{
switch ($condition['type']) {
case 'sender':
return $this->conditionSatisfied($this->sender, $condition);
break;
case 'subject':
return $this->conditionSatisfied($this->subject, $condition);
break;
case 'alias':
return $this->conditionSatisfied($this->alias->email, $condition);
break;
case 'alias_description':
return $this->conditionSatisfied($this->alias->description, $condition);
break;
}
}
protected function conditionSatisfied($variable, $condition)
{
$values = collect($condition['values']);
switch ($condition['match']) {
case 'is exactly':
return $values->contains(function ($value) use ($variable) {
return $variable === $value;
});
break;
case 'is not':
return ! $values->contains(function ($value) use ($variable) {
return $variable === $value;
});
break;
case 'contains':
return $values->contains(function ($value) use ($variable) {
return Str::contains($variable, $value);
});
break;
case 'does not contain':
return ! $values->contains(function ($value) use ($variable) {
return Str::contains($variable, $value);
});
break;
case 'starts with':
return $values->contains(function ($value) use ($variable) {
return Str::startsWith($variable, $value);
});
break;
case 'does not start with':
return ! $values->contains(function ($value) use ($variable) {
return Str::startsWith($variable, $value);
});
break;
case 'ends with':
return $values->contains(function ($value) use ($variable) {
return Str::endsWith($variable, $value);
});
break;
case 'does not end with':
return ! $values->contains(function ($value) use ($variable) {
return Str::endsWith($variable, $value);
});
break;
case 'matches regex':
return $values->contains(function ($value) use ($variable) {
return Str::isMatch("/{$value}/", $variable);
});
break;
case 'does not match regex':
return ! $values->contains(function ($value) use ($variable) {
return Str::isMatch("/{$value}/", $variable);
});
break;
}
}
protected function applyAction($action)
{
switch ($action['type']) {
case 'subject':
$this->replacedSubject = ' with subject "'.base64_decode($this->emailSubject).'"';
$this->email->subject = $action['value'];
break;
case 'displayFrom':
$this->email->from = [];
$this->email->from($this->fromEmail, $action['value']);
break;
case 'encryption':
if ($action['value'] == false) {
if (isset($this->fingerprint)) {
$this->fingerprint = null;
}
}
break;
case 'banner':
if (in_array($action['value'], ['top', 'bottom', 'off'])) {
if ($this->emailHtml) {
// Turn off the banner for the plain text version
$this->bannerLocationText = 'off';
$this->bannerLocationHtml = $action['value'];
} else {
$this->bannerLocationText = $action['value'];
}
}
break;
case 'block':
$this->alias->increment('emails_blocked', 1, ['last_blocked' => now()]);
$this->size = 0;
exit(0);
break;
case 'removeAttachments':
$this->email->rawAttachments = [];
break;
case 'forwardTo':
// Only apply on forwards
if ($this->emailType !== 'Forwards') {
break;
}
$recipient = $this->user->verifiedRecipients()->select(['id', 'email', 'should_encrypt', 'fingerprint'])->find($action['value']);
if (! $recipient) {
break;
}
$this->recipientId = $recipient->id;
$this->fingerprint = $recipient->should_encrypt && ! $this->isAlreadyEncrypted() ? $recipient->fingerprint : null;
$this->email->to[0]['address'] = $recipient->email;
break;
case 'webhook':
// http payload to url
break;
}
}
}