Implement IMAP email-to-ticket gateway
This commit is contained in:
1 parent
b7e5884457
commit
6f25869345
33 files changed
+5619
-5
No files matched your search
@@ -0,0 +1,101 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Box\Mod\Mailgateway;
|
||||
|
||||
use FOSSBilling\InformationException;
|
||||
|
||||
class InboundPolicy
|
||||
{
|
||||
private const FIELDS = [
|
||||
'auto-submitted', 'precedence', 'return-path', 'content-type',
|
||||
'x-auto-response-suppress', 'x-autoreply', 'x-autorespond', 'list-id',
|
||||
];
|
||||
|
||||
/** Normalize parsed MIME headers and supported flat header fields. */
|
||||
public function headers(array $data): array
|
||||
{
|
||||
$raw = $data['headers'] ?? [];
|
||||
if (!is_array($raw)) {
|
||||
throw new InformationException('headers must be an array of header values');
|
||||
}
|
||||
foreach (self::FIELDS as $field) {
|
||||
$flat = str_replace('-', '_', $field);
|
||||
if (array_key_exists($flat, $data)) {
|
||||
$raw[$field] = array_merge((array) ($raw[$field] ?? []), (array) $data[$flat]);
|
||||
}
|
||||
}
|
||||
$headers = [];
|
||||
foreach ($raw as $name => $values) {
|
||||
if (!is_string($name)) {
|
||||
throw new InformationException('Header names must be strings');
|
||||
}
|
||||
$name = strtolower(str_replace('_', '-', $name));
|
||||
if (!in_array($name, self::FIELDS, true)) {
|
||||
continue;
|
||||
}
|
||||
$values = is_array($values) ? $values : [$values];
|
||||
if (count($values) > 20) {
|
||||
throw new InformationException('Too many repeated header values');
|
||||
}
|
||||
foreach ($values as $value) {
|
||||
if (!is_string($value) || strlen($value) > 16384) {
|
||||
throw new InformationException('Header values must be strings of at most 16384 bytes');
|
||||
}
|
||||
$value = preg_replace('/\r?\n[ \t]+/', ' ', $value);
|
||||
if (preg_match('/[\x00-\x08\x0A-\x1F\x7F]/', $value)) {
|
||||
throw new InformationException('Invalid control character in header value');
|
||||
}
|
||||
$headers[$name][] = strtolower(trim($value));
|
||||
}
|
||||
}
|
||||
ksort($headers);
|
||||
|
||||
return $headers;
|
||||
}
|
||||
|
||||
public function ignoreReason(array $headers): ?string
|
||||
{
|
||||
foreach ($headers['auto-submitted'] ?? [] as $value) {
|
||||
if (trim(explode(';', $value, 2)[0]) !== 'no') {
|
||||
return 'auto_submitted';
|
||||
}
|
||||
}
|
||||
foreach ($headers['return-path'] ?? [] as $value) {
|
||||
if (preg_match('/^<\s*>$/D', $value)) {
|
||||
return 'null_return_path';
|
||||
}
|
||||
}
|
||||
foreach ($headers['content-type'] ?? [] as $value) {
|
||||
if (preg_match('/^multipart\/report\s*(?:;|$)/', $value)
|
||||
|| preg_match('/^message\/(?:delivery-status|disposition-notification|global-delivery-status)\s*(?:;|$)/', $value)) {
|
||||
return 'delivery_report';
|
||||
}
|
||||
}
|
||||
foreach ($headers['precedence'] ?? [] as $value) {
|
||||
if (in_array(trim(explode(';', $value, 2)[0]), ['bulk', 'list', 'junk'], true)) {
|
||||
return 'bulk_mail';
|
||||
}
|
||||
}
|
||||
foreach ($headers['list-id'] ?? [] as $value) {
|
||||
if ($value !== '') {
|
||||
return 'mailing_list';
|
||||
}
|
||||
}
|
||||
foreach ($headers['x-auto-response-suppress'] ?? [] as $value) {
|
||||
if (preg_match('/(?:^|[\s,;])(?:all|autoreply|oof|dr|ndr|rn|nrn)(?:$|[\s,;])/', $value)) {
|
||||
return 'response_suppressed';
|
||||
}
|
||||
}
|
||||
foreach (['x-autoreply', 'x-autorespond'] as $field) {
|
||||
foreach ($headers[$field] ?? [] as $value) {
|
||||
if (!in_array($value, ['', 'no', 'false', '0'], true)) {
|
||||
return 'legacy_autoresponder';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user