diff --git a/app/Casts/CompressedString.php b/app/Casts/CompressedStringOrNull.php similarity index 52% rename from app/Casts/CompressedString.php rename to app/Casts/CompressedStringOrNull.php index 918183d..ea9f8fd 100644 --- a/app/Casts/CompressedString.php +++ b/app/Casts/CompressedStringOrNull.php @@ -5,20 +5,19 @@ namespace App\Casts; use Illuminate\Contracts\Database\Eloquent\CastsAttributes; use Illuminate\Database\Eloquent\Model; -class CompressedString implements CastsAttributes +class CompressedStringOrNull implements CastsAttributes { /** * Cast the given value. * - * For postgresl bytea columns the value is a resource stream - * * @param Model $model * @param string $key * @param mixed $value * @param array $attributes - * @return string + * @return string|null + * @note postgres bytea columns the value is a resource stream */ - public function get($model,string $key,mixed $value,array $attributes): string + public function get(Model $model,string $key,mixed $value,array $attributes): ?string { // For stream resources, we to fseek in case we've already read it. if (is_resource($value)) @@ -28,13 +27,7 @@ class CompressedString implements CastsAttributes ? stream_get_contents($value) : $value; - // If we get an error decompressing, it might not be zstd (or its already been done) - try { - return $value ? zstd_uncompress(base64_decode($value)) : ''; - - } catch (\ErrorException $e) { - return $value; - } + return $value ? zstd_uncompress(base64_decode($value)) : NULL; } /** @@ -44,10 +37,10 @@ class CompressedString implements CastsAttributes * @param string $key * @param mixed $value * @param array $attributes - * @return string + * @return string|null */ - public function set($model,string $key,$value,array $attributes): string + public function set(Model $model,string $key,$value,array $attributes): ?string { - return $value ? base64_encode(zstd_compress($value)) : ''; + return $value ? base64_encode(zstd_compress($value)) : NULL; } } \ No newline at end of file diff --git a/app/Casts/UTF8StringOrNull.php b/app/Casts/UTF8StringOrNull.php new file mode 100644 index 0000000..53c85b7 --- /dev/null +++ b/app/Casts/UTF8StringOrNull.php @@ -0,0 +1,29 @@ + $attributes + */ + public function get(Model $model,string $key,mixed $value,array $attributes): ?string + { + return $value ? utf8_decode($value) : NULL; + } + + /** + * Prepare the given value for storage. + * + * @param array $attributes + */ + public function set(Model $model,string $key,mixed $value,array $attributes): ?string + { + return $value ? utf8_encode($value) : NULL; + } +} diff --git a/app/Jobs/MessageProcess.php b/app/Jobs/MessageProcess.php index 8ece903..cba05a0 100644 --- a/app/Jobs/MessageProcess.php +++ b/app/Jobs/MessageProcess.php @@ -14,21 +14,17 @@ use Illuminate\Support\Facades\Notification; use App\Classes\FTN\Message; use App\Models\{Echomail,Netmail,User}; use App\Notifications\Netmails\{EchoareaNotExist,EchoareaNotSubscribed,EchoareaNoWrite,NetmailForward,NetmailHubNoUser}; -use App\Traits\{EncodeUTF8,ParseAddresses}; +use App\Traits\ParseAddresses; class MessageProcess implements ShouldQueue { private const LOGKEY = 'JMP'; - use Dispatchable,InteractsWithQueue,Queueable,SerializesModels,ParseAddresses,EncodeUTF8; + use Dispatchable,InteractsWithQueue,Queueable,SerializesModels,ParseAddresses; private Echomail|Netmail|string $mo; private bool $skipbot; - private const cast_utf8 = [ - 'mo', - ]; - /** * Process a message from a packet * @@ -54,16 +50,6 @@ class MessageProcess implements ShouldQueue } } - public function __serialize() - { - return $this->encode(); - } - - public function __unserialize(array $values) - { - $this->decode($values); - } - /** * At this point, we know that the packet is from a system we know about, and the packet is to us: * + From a system that is configured with us, and the password has been validated @@ -144,8 +130,8 @@ class MessageProcess implements ShouldQueue // Check if the netmail is to a user, with netmail forwarding enabled $uo = User::active() ->where(function($query) { - return $query->whereRaw(sprintf("LOWER(name)='%s'",strtolower($this->mo->to))) - ->orWhereRaw(sprintf("LOWER(alias)='%s'",strtolower($this->mo->to))); + return $query->whereRaw(sprintf("LOWER(name)='%s'",strtolower(utf8_encode($this->mo->to)))) + ->orWhereRaw(sprintf("LOWER(alias)='%s'",strtolower(utf8_encode($this->mo->to)))); }) ->whereNotNull('system_id') ->single(); diff --git a/app/Jobs/PacketProcess.php b/app/Jobs/PacketProcess.php index 50fb5f4..bff445c 100644 --- a/app/Jobs/PacketProcess.php +++ b/app/Jobs/PacketProcess.php @@ -139,7 +139,7 @@ class PacketProcess implements ShouldQueue $count++; } catch (\Exception $e) { - Log::error(sprintf('%s:! Got error dispatching message [%s] (%d:%s-%s).',self::LOGKEY,$msg->msgid,$e->getLine(),$e->getFile(),$e->getMessage())); + Log::error(sprintf('%s:! Got error [%s] dispatching message [%s] (%d:%s-%s).',self::LOGKEY,get_class($e),$msg->msgid,$e->getLine(),$e->getFile(),$e->getMessage())); } } diff --git a/app/Models/Domain.php b/app/Models/Domain.php index c7398a5..e7032a5 100644 --- a/app/Models/Domain.php +++ b/app/Models/Domain.php @@ -11,7 +11,7 @@ use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Cache; use Illuminate\Support\Facades\DB; -use App\Casts\CompressedString; +use App\Casts\CompressedStringOrNull; use App\Traits\{QueryCacheableConfig,ScopeActive}; class Domain extends Model @@ -22,7 +22,7 @@ class Domain extends Model private const STATS_MONTHS = 6; protected $casts = [ - 'homepage' => CompressedString::class, + 'homepage' => CompressedStringOrNull::class, ]; /* SCOPES */ diff --git a/app/Models/Echomail.php b/app/Models/Echomail.php index 74bfd2e..3fe9b43 100644 --- a/app/Models/Echomail.php +++ b/app/Models/Echomail.php @@ -9,7 +9,7 @@ use Illuminate\Support\Collection; use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Log; -use App\Casts\{CollectionOrNull,CompressedString}; +use App\Casts\{CollectionOrNull,CompressedStringOrNull,UTF8StringOrNull}; use App\Classes\FTN\Message; use App\Interfaces\Packet; use App\Traits\{MessageAttributes,MsgID,ParseAddresses,QueryCacheableConfig}; @@ -32,10 +32,16 @@ final class Echomail extends Model implements Packet public Address $tftn; protected $casts = [ + 'to' => UTF8StringOrNull::class, + 'from' => UTF8StringOrNull::class, + 'subject' => UTF8StringOrNull::class, + 'origin' => UTF8StringOrNull::class, + 'tearline' => UTF8StringOrNull::class, + 'tagline' => UTF8StringOrNull::class, 'datetime' => 'datetime:Y-m-d H:i:s', 'kludges' => CollectionOrNull::class, - 'msg' => CompressedString::class, - 'msg_src' => CompressedString::class, + 'msg' => CompressedStringOrNull::class, + 'msg_src' => CompressedStringOrNull::class, 'rogue_seenby' => CollectionOrNull::class, 'rogue_path' => CollectionOrNull::class, // @deprecated? ]; diff --git a/app/Models/File.php b/app/Models/File.php index eab5588..77cbcf9 100644 --- a/app/Models/File.php +++ b/app/Models/File.php @@ -11,12 +11,11 @@ use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Storage; -use App\Casts\{CollectionOrNull,CompressedString}; -use App\Traits\EncodeUTF8; +use App\Casts\{CollectionOrNull,CompressedStringOrNull}; class File extends Model { - use SoftDeletes,EncodeUTF8; + use SoftDeletes; private const LOGKEY = 'MF-'; private bool $no_export = FALSE; @@ -28,18 +27,13 @@ class File extends Model protected $casts = [ 'kludges' => CollectionOrNull::class, 'datetime' => 'datetime:Y-m-d H:i:s', - 'desc' => CompressedString::class, - 'ldesc' => CompressedString::class, + 'desc' => CompressedStringOrNull::class, + 'ldesc' => CompressedStringOrNull::class, 'rogue_seenby' => CollectionOrNull::class, 'rogue_path' => CollectionOrNull::class, 'size' => 'int', ]; - private const cast_utf8 = [ - 'desc', - 'ldesc', - ]; - public static function boot() { parent::boot(); diff --git a/app/Models/Netmail.php b/app/Models/Netmail.php index 09308a5..3cde67b 100644 --- a/app/Models/Netmail.php +++ b/app/Models/Netmail.php @@ -10,7 +10,7 @@ use Illuminate\Support\Collection; use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Log; -use App\Casts\{CollectionOrNull,CompressedString}; +use App\Casts\{CollectionOrNull,CompressedStringOrNull,UTF8StringOrNull}; use App\Interfaces\Packet; use App\Pivots\ViaPivot; use App\Traits\{MessageAttributes,MsgID}; @@ -32,10 +32,16 @@ final class Netmail extends Model implements Packet ]; protected $casts = [ + 'to' => UTF8StringOrNull::class, + 'from' => UTF8StringOrNull::class, + 'subject' => UTF8StringOrNull::class, + 'origin' => UTF8StringOrNull::class, + 'tearline' => UTF8StringOrNull::class, + 'tagline' => UTF8StringOrNull::class, 'datetime' => 'datetime:Y-m-d H:i:s', 'kludges' => CollectionOrNull::class, - 'msg' => CompressedString::class, - 'msg_src' => CompressedString::class, + 'msg' => CompressedStringOrNull::class, + 'msg_src' => CompressedStringOrNull::class, 'sent_at' => 'datetime:Y-m-d H:i:s', ]; diff --git a/app/Traits/EncodeUTF8.php b/app/Traits/EncodeUTF8.php deleted file mode 100644 index 0e575b4..0000000 --- a/app/Traits/EncodeUTF8.php +++ /dev/null @@ -1,99 +0,0 @@ -getProperties(); - - $class = get_class($this); - - foreach ($properties as $property) { - if ($property->isStatic()) - continue; - - $name = $property->getName(); - $decode = in_array($name,self::cast_utf8); - - if ($property->isPrivate()) - $name = "\0{$class}\0{$name}"; - elseif ($property->isProtected()) - $name = "\0*\0{$name}"; - - if (! array_key_exists($name,$values)) - continue; - - $property->setAccessible(true); - - try { - $property->setValue( - $this,$decode ? utf8_decode($values[$name]) : $values[$name] - ); - - } catch (\Exception $e) { - dd(['e'=>$e->getMessage(),'name'=>$name,'values'=>$values[$name],'decode'=>$decode]); - } - } - } - - private function encode(): array - { - $values = []; - - $properties = (new \ReflectionClass($this))->getProperties(); - - $class = get_class($this); - - foreach ($properties as $property) { - // Dont serialize the validation error - if (($property->name === 'errors') || $property->isStatic()) - continue; - - $property->setAccessible(true); - - if (! $property->isInitialized($this)) - continue; - - $name = $property->getName(); - $encode = in_array($name,self::cast_utf8); - - if ($property->isPrivate()) - $name = "\0{$class}\0{$name}"; - elseif ($property->isProtected()) - $name = "\0*\0{$name}"; - - $property->setAccessible(true); - $value = $property->getValue($this); - $values[$name] = $encode ? utf8_encode($value) : $value; - } - - return $values; - } - - public function getAttribute($key) - { - if (in_array($key,self::cast_utf8) && Arr::get($this->attributes,$key) && (! Arr::get($this->_encoded,$key))) { - // We need to get it from the parent first, taking into account any casting - $this->attributes[$key] = utf8_decode(parent::getAttribute($key)); - $this->_encoded[$key] = TRUE; - - return $this->attributes[$key]; - } - - return Arr::get($this->_encoded,$key) ? $this->attributes[$key] : parent::getAttribute($key); - } - - public function setAttribute($key,$value) - { - return parent::setAttribute($key,in_array($key,self::cast_utf8) ? utf8_encode($value) : $value); - } -} \ No newline at end of file diff --git a/app/Traits/MessageAttributes.php b/app/Traits/MessageAttributes.php index 3eaf922..10db454 100644 --- a/app/Traits/MessageAttributes.php +++ b/app/Traits/MessageAttributes.php @@ -15,24 +15,11 @@ use App\Models\{Address,Echomail}; trait MessageAttributes { - use EncodeUTF8; - // Items we need to set when creating() public Collection $set; // Validation Errors public ?MessageBag $errors = NULL; - private const cast_utf8 = [ - 'to', - 'from', - 'subject', - 'msg', - 'msg_src', - 'origin', - 'tearline', - 'tagline', - ]; - public function __construct() { parent::__construct();