From f279d85b088539d9137095f8390166bc4a2479cf Mon Sep 17 00:00:00 2001 From: Deon George Date: Sun, 19 May 2024 23:28:45 +1000 Subject: [PATCH] More complete rework of packet parsing and packet generation with 29710c --- app/Classes/FTN/Message.php | 46 +++++---- app/Classes/FTN/Packet.php | 61 ++++++++---- app/Classes/FTN/Packet/FSC48.php | 21 ++-- app/Classes/FTN/Process.php | 6 +- app/Classes/FTN/Process/Echomail/Test.php | 4 +- app/Classes/FTN/Process/Netmail/Areafix.php | 15 +-- app/Classes/FTN/Process/Netmail/Ping.php | 11 ++- app/Classes/File/Mail.php | 4 +- app/Classes/File/Receive.php | 7 +- app/Classes/File/Send.php | 7 +- app/Classes/Protocol/Binkp.php | 3 + app/Console/Commands/Debug/PacketAddress.php | 7 +- app/Console/Commands/PacketInfo.php | 4 +- app/Console/Commands/PacketProcess.php | 39 ++++++-- app/Console/Commands/PacketSystem.php | 12 +-- app/Http/Controllers/SystemController.php | 22 ++--- app/Http/Requests/SystemEchoareaRequest.php | 71 ++++++++++++++ app/Jobs/MessageProcess.php | 29 +++--- app/Jobs/PacketProcess.php | 7 +- app/Models/Address.php | 95 +++++++------------ app/Models/Netmail.php | 5 +- app/Models/System.php | 10 +- .../Channels/EchomailChannel.php | 2 +- app/Notifications/Echomails.php | 12 +-- app/Notifications/Echomails/Test.php | 14 +-- app/Notifications/Netmails.php | 3 +- app/Notifications/Netmails/AddressLink.php | 2 +- app/Notifications/Netmails/Areafix.php | 11 +-- .../Netmails/Areafix/NotConfiguredHere.php | 11 +-- .../Netmails/EchoareaNoWrite.php | 17 ++-- .../Netmails/EchoareaNotExist.php | 4 +- .../Netmails/EchoareaNotSubscribed.php | 17 ++-- .../Netmails/EchomailBadAddress.php | 4 +- app/Notifications/Netmails/NetmailForward.php | 17 ++-- .../{Reject.php => NetmailHubNoUser.php} | 17 ++-- .../Netmails/PacketPasswordInvalid.php | 2 +- app/Notifications/Netmails/Ping.php | 8 +- app/Notifications/Netmails/PollingFailed.php | 3 +- app/Notifications/Netmails/Test.php | 2 +- app/Traits/EncodeUTF8.php | 2 +- app/Traits/MessageAttributes.php | 33 +++++-- app/Traits/MessagePath.php | 24 +++-- resources/views/widgets/message.blade.php | 12 ++- 43 files changed, 412 insertions(+), 291 deletions(-) create mode 100644 app/Http/Requests/SystemEchoareaRequest.php rename app/Notifications/Netmails/{Reject.php => NetmailHubNoUser.php} (81%) diff --git a/app/Classes/FTN/Message.php b/app/Classes/FTN/Message.php index f78ae44..0c3228d 100644 --- a/app/Classes/FTN/Message.php +++ b/app/Classes/FTN/Message.php @@ -12,9 +12,9 @@ use Illuminate\Validation\Validator as ValidatorResult; use App\Classes\FTN as FTNBase; use App\Exceptions\InvalidPacketException; -use App\Models\{Address,Domain,Echomail,Netmail,Zone}; +use App\Models\{Address,Domain,Echomail,Netmail,Setup,Zone}; use App\Rules\{TwoByteInteger,TwoByteIntegerWithZero}; -use App\Traits\{EncodeUTF8,ObjectIssetFix}; +use App\Traits\ObjectIssetFix; /** * Class Message @@ -91,6 +91,7 @@ class Message extends FTNBase private array $header; // Message Header private int $tzutc = 0; // TZUTC that needs to be converted to be used by Carbon @see self::kludges private Echomail|Netmail $mo; // The object storing this packet message + private Address $us; // Our address for this message /** @deprecated Not sure why this is needed? */ public bool $packed = FALSE; // Has the message been packed successfully @@ -156,6 +157,7 @@ class Message extends FTNBase { $oo = new self($o->fftn->zone); $oo->mo = $o; + $oo->us = our_address($o->tftn); return $oo; } @@ -507,6 +509,8 @@ class Message extends FTNBase */ public function __toString(): string { + $s = Setup::findOrFail(config('app.id')); + $return = pack(collect(self::HEADER)->pluck(1)->join(''), $this->mo->fftn->node_id, // Originating Node $this->mo->tftn->node_id, // Destination Node @@ -521,22 +525,26 @@ class Message extends FTNBase $return .= $this->mo->from."\00"; $return .= $this->mo->subject."\00"; + if (($this->mo instanceof Netmail) && $this->mo->isFlagSet(self::FLAG_LOCAL)) { + // If there isnt an INTL kludge, we'll add it + if (! $this->mo->kludges->has('INTL')) + $this->mo->kludges->put('INTL',sprintf('%s %s',$this->mo->tftn->ftn3d,$this->mo->fftn->ftn3d)); + + if ((! $this->mo->kludges->has('FMPT')) && $this->mo->fftn->point_id) + $this->mo->kludges->put('FMPT',$this->mo->fftn->point_id); + + if ((! $this->mo->kludges->has('TOPT')) && $this->mo->tftn->point_id) + $this->mo->kludges->put('TOPT',$this->mo->tftn->point_id); + } + + if ($this->mo->isFlagSet(self::FLAG_LOCAL)) + $this->mo->kludges->put('PID',sprintf('clrghouz %s',$s->version)); + else + $this->mo->kludges->put('TID',sprintf('clrghouz %s',$s->version)); + if ($this->mo instanceof Echomail) $return .= sprintf("AREA:%s\r",strtoupper($this->mo->echoarea->name)); - if ($this->mo instanceof Netmail) { - // @todo If the message is local, then our kludges are not in the msg itself, we'll add them - if ($this->isFlagSet(self::FLAG_LOCAL)) - Log::debug(sprintf('%s:^ Local message, we may need to set our INTL/FMPT/TOPT',self::LOGKEY)); - - $return .= sprintf("\01INTL %s\r",$this->mo->kludges->get('INTL')); - - if ($this->mo->kludges->has('FMPT')) - $return .= sprintf("\01FMPT %d\r",$this->mo->kludges->get('FMPT')); - if ($this->mo->kludges->has('TOPT')) - $return .= sprintf("\01TOPT %d\r",$this->mo->kludges->get('TOPT')); - } - // Add some kludges $return .= sprintf("\01TZUTC: %s\r",str_replace('+','',$this->mo->date->getOffsetString(''))); @@ -551,11 +559,15 @@ class Message extends FTNBase $return .= $this->mo->content; if ($this->mo instanceof Netmail) { - // @todo automatically include our address in the path - foreach ($this->mo->path as $ao) $return .= sprintf("\x01Via %s\r",$this->mo->via($ao)); + // Add our address + $return .= sprintf("\x01Via %s @%s.UTC %s (%04X)\r", + $this->us->ftn3d, + Carbon::now()->format('Ymd.His'), + Setup::PRODUCT_NAME,Setup::PRODUCT_ID); + } else { // FTS-0004.001/FSC-0068.001 The message SEEN-BY lines // FTS-0004.001/FSC-0068.001 The message PATH lines diff --git a/app/Classes/FTN/Packet.php b/app/Classes/FTN/Packet.php index 033f13d..e08a512 100644 --- a/app/Classes/FTN/Packet.php +++ b/app/Classes/FTN/Packet.php @@ -50,6 +50,20 @@ abstract class Packet extends FTNBase implements \Iterator, \Countable protected Collection $messages; // Messages in the Packet public Collection $errors; // Messages that fail validation protected int $index; // Our array index + protected $pass_p = NULL; // Overwrite the packet password (when packing messages) + + /* ABSTRACT */ + + /** + * This function is intended to be implemented in child classes to test if the packet + * is defined by the child object + * + * @see self::PACKET_TYPES + * @param string $header + * @return bool + */ + abstract public static function is_type(string $header): bool; + abstract protected function header(): string; /* STATIC */ @@ -63,16 +77,6 @@ abstract class Packet extends FTNBase implements \Iterator, \Countable return collect(static::HEADER)->sum(function($item) { return Arr::get($item,2); }); } - /** - * This function is intended to be implemented in child classes to test if the packet - * is defined by the child object - * - * @see self::PACKET_TYPES - * @param string $header - * @return bool - */ - abstract public static function is_type(string $header): bool; - /** * Process a packet file * @@ -261,6 +265,9 @@ abstract class Packet extends FTNBase implements \Iterator, \Countable case 'name': return $this->{$key} ?: sprintf('%08x',timew()); + case 'messages': + return $this->{$key}; + default: throw new \Exception('Unknown key: '.$key); } @@ -274,6 +281,12 @@ abstract class Packet extends FTNBase implements \Iterator, \Countable */ public function __toString(): string { + if (empty($this->messages)) + throw new InvalidPacketException('Refusing to make an empty packet'); + + if (empty($this->tftn_p) || empty($this->fftn_p)) + throw new InvalidPacketException('Cannot generate a packet without a destination address'); + $return = $this->header(); foreach ($this->messages as $o) @@ -379,18 +392,18 @@ abstract class Packet extends FTNBase implements \Iterator, \Countable /** * Generate a packet * - * @param Collection $msgs * @return string - * @throws InvalidPacketException */ - public function generate(Collection $msgs): string + public function generate(): string + { + return (string)$this; + } + + public function mail(Collection $msgs): self { $this->messages = $msgs; - if (empty($this->tftn_p) || empty($this->fftn_p)) - throw new InvalidPacketException('Cannot generate a packet without a destination address'); - - return (string)$this; + return $this; } /** @@ -500,6 +513,20 @@ abstract class Packet extends FTNBase implements \Iterator, \Countable $this->messages->push($msg); } + /** + * Overwrite the packet password + * + * @param string|null $password + * @return self + */ + public function password(string $password=NULL): self + { + if ($password && (strlen($password) < 9)) + $this->pass_p = $password; + + return $this; + } + /** @deprecated Is this used? */ public function pluck(string $key): Collection { diff --git a/app/Classes/FTN/Packet/FSC48.php b/app/Classes/FTN/Packet/FSC48.php index 84574ed..558f8f6 100644 --- a/app/Classes/FTN/Packet/FSC48.php +++ b/app/Classes/FTN/Packet/FSC48.php @@ -59,11 +59,10 @@ final class FSC48 extends Packet /** * Create our message packet header - * // @todo add the ability to overwrite the password */ protected function header(): string { - $oldest = $this->messages->sortBy(function($item) { return $item->datetime; })->last(); + $oldest = $this->messages->sortBy('datetime')->last(); try { return pack(collect(self::HEADER)->pluck(1)->join(''), @@ -77,22 +76,22 @@ final class FSC48 extends Packet $oldest->datetime->format('s'), // Second 0, // Baud 2, // Packet Version (should be 2) - $this->fftn_p->point_id ? 0xffff : $this->fftn_p->node_id, // Orig Net (0xFFFF when OrigPoint != 0) + $this->fftn_p->point_id ? 0xffff : $this->fftn_p->host_id, // Orig Net (0xFFFF when OrigPoint != 0) $this->tftn_p->host_id, // Dest Net (Setup::PRODUCT_ID & 0xff), // Product Code Lo Setup::PRODUCT_VERSION_MAJ, // Product Version Major - $this->tftn_p->session('pktpass'), // Packet Password - $this->fftn_p->zone->zone_id, // Orig Zone - $this->tftn_p->zone->zone_id, // Dest Zone - $this->fftn_p->point_id ? $this->fftn_p->node_id : 0x00, // Aux Net + $this->pass_p ?: $this->tftn_p->session('pktpass'), // Packet Password + $this->fftn_p->zone->zone_id, // Orig Zone + $this->tftn_p->zone->zone_id, // Dest Zone + $this->fftn_p->point_id ? $this->fftn_p->host_id : 0x00, // Aux Net 1<<0, // fsc-0039.004 (copy of 0x2c) ((Setup::PRODUCT_ID >> 8) & 0xff), // Product Code Hi Setup::PRODUCT_VERSION_MIN, // Product Version Minor 1<<0, // Capability Word - $this->fftn_p->zone->zone_id, // Orig Zone - $this->tftn_p->zone->zone_id, // Dest Zone - $this->fftn_p->point_id, // Orig Point - $this->tftn_p->point_id, // Dest Point + $this->fftn_p->zone->zone_id, // Orig Zone + $this->tftn_p->zone->zone_id, // Dest Zone + $this->fftn_p->point_id, // Orig Point + $this->tftn_p->point_id, // Dest Point strtoupper(hexstr(Setup::PRODUCT_ID)), // ProdData ); diff --git a/app/Classes/FTN/Process.php b/app/Classes/FTN/Process.php index 0542054..5fc1669 100644 --- a/app/Classes/FTN/Process.php +++ b/app/Classes/FTN/Process.php @@ -9,11 +9,9 @@ use App\Models\{Echoarea,Echomail,Netmail}; */ abstract class Process { - public static function canProcess(string $echoarea): bool + public static function canProcess(Echoarea $eao): bool { - $eao = Echoarea::where('name',$echoarea)->single(); - - return $eao && $eao->automsgs; + return $eao->automsgs; } /** diff --git a/app/Classes/FTN/Process/Echomail/Test.php b/app/Classes/FTN/Process/Echomail/Test.php index 8208f7d..c92aff2 100644 --- a/app/Classes/FTN/Process/Echomail/Test.php +++ b/app/Classes/FTN/Process/Echomail/Test.php @@ -27,9 +27,9 @@ final class Test extends Process || (! in_array(strtolower($mo->subject),self::testing))) return FALSE; - Log::info(sprintf('%s:- Processing TEST message from (%s) [%s] in [%s]',self::LOGKEY,$msg->user_from,$msg->fftn,$msg->echoarea)); + Log::info(sprintf('%s:- Processing TEST message from (%s) [%s] in [%s]',self::LOGKEY,$mo->from,$mo->fftn->ftn,$mo->echoarea->name)); - Notification::route('echomail',$mo->echoarea)->notify(new TestNotification($msg)); + Notification::route('echomail',$mo->echoarea->withoutRelations())->notify(new TestNotification($mo)); return TRUE; } diff --git a/app/Classes/FTN/Process/Netmail/Areafix.php b/app/Classes/FTN/Process/Netmail/Areafix.php index 82356b1..82a3260 100644 --- a/app/Classes/FTN/Process/Netmail/Areafix.php +++ b/app/Classes/FTN/Process/Netmail/Areafix.php @@ -5,7 +5,8 @@ namespace App\Classes\FTN\Process\Netmail; use Illuminate\Support\Facades\Notification; use Illuminate\Support\Facades\Log; -use App\Classes\FTN\{Message,Process}; +use App\Classes\FTN\Process; +use App\Models\{Echomail,Netmail}; use App\Notifications\Netmails\Areafix as AreafixNotification; use App\Notifications\Netmails\Areafix\NotConfiguredHere as AreafixNotConfiguredHereNotification; @@ -18,18 +19,18 @@ final class Areafix extends Process { private const LOGKEY = 'RP-'; - public static function handle(Message $msg): bool + public static function handle(Echomail|Netmail $mo): bool { - if (strtolower($msg->user_to) !== 'areafix') + if (strtolower($mo->to) !== 'areafix') return FALSE; - Log::info(sprintf('%s:- Processing AREAFIX message from (%s) [%s]',self::LOGKEY,$msg->user_from,$msg->fftn)); + Log::info(sprintf('%s:- Processing AREAFIX message from (%s) [%s]',self::LOGKEY,$mo->from,$mo->fftn)); // If this is not a node we manage, then respond with a sorry can help you - if ($msg->fftn_o->system->sessions->count()) - Notification::route('netmail',$msg->fftn_o)->notify(new AreafixNotification($msg)); + if ($mo->fftn->system->sessions->count()) + Notification::route('netmail',$mo->fftn)->notify(new AreafixNotification($mo)); else - Notification::route('netmail',$msg->fftn_o)->notify(new AreafixNotConfiguredHereNotification($msg)); + Notification::route('netmail',$mo->fftn)->notify(new AreafixNotConfiguredHereNotification($mo)); return TRUE; } diff --git a/app/Classes/FTN/Process/Netmail/Ping.php b/app/Classes/FTN/Process/Netmail/Ping.php index 04cb449..689c4fc 100644 --- a/app/Classes/FTN/Process/Netmail/Ping.php +++ b/app/Classes/FTN/Process/Netmail/Ping.php @@ -5,7 +5,8 @@ namespace App\Classes\FTN\Process\Netmail; use Illuminate\Support\Facades\Notification; use Illuminate\Support\Facades\Log; -use App\Classes\FTN\{Message,Process}; +use App\Classes\FTN\Process; +use App\Models\{Echomail,Netmail}; use App\Notifications\Netmails\Ping as PingNotification; /** @@ -17,14 +18,14 @@ final class Ping extends Process { private const LOGKEY = 'RP-'; - public static function handle(Message $msg): bool + public static function handle(Echomail|Netmail $mo): bool { - if (strtolower($msg->user_to) !== 'ping') + if (strtolower($mo->to) !== 'ping') return FALSE; - Log::info(sprintf('%s:- Processing PING message from (%s) [%s]',self::LOGKEY,$msg->user_from,$msg->fftn)); + Log::info(sprintf('%s:- Processing PING message from (%s) [%s]',self::LOGKEY,$mo->from,$mo->fftn->ftn)); - Notification::route('netmail',$msg->fftn_o)->notify(new PingNotification($msg)); + Notification::route('netmail',$mo->fftn)->notify(new PingNotification($mo)); return TRUE; } diff --git a/app/Classes/File/Mail.php b/app/Classes/File/Mail.php index 590a5de..e07ec78 100644 --- a/app/Classes/File/Mail.php +++ b/app/Classes/File/Mail.php @@ -32,7 +32,7 @@ final class Mail extends Send public function __get($key) { switch ($key) { case 'dbids': - return $this->f->messages->pluck('dbid'); + return $this->f->messages->pluck('id'); case 'name': return sprintf('%08x',timew($this->youngest())); @@ -111,7 +111,7 @@ final class Mail extends Send return TRUE; } - public function youngest(): Carbon + private function youngest(): Carbon { return $this->f->messages->pluck('date')->sort()->last(); } diff --git a/app/Classes/File/Receive.php b/app/Classes/File/Receive.php index b2f192f..ad35b17 100644 --- a/app/Classes/File/Receive.php +++ b/app/Classes/File/Receive.php @@ -128,13 +128,12 @@ class Receive extends Base // If packet is greater than a size, lets queue it if ($this->queue || ($this->receiving->size > config('fido.queue_size',0))) { Log::info(sprintf('%s:- Packet [%s] will be sent to the queue for processing because its [%d] size, or queue forced',self::LOGKEY,$this->receiving->full_name,$this->receiving->size)); - PacketProcess::dispatch($this->receiving,$this->ao->withoutRelations(),$rcvd_time); - + PacketProcess::dispatch($this->receiving->rel_name,$this->ao->zone->domain,FALSE,$rcvd_time); } else - PacketProcess::dispatchSync($this->receiving,$this->ao->withoutRelations(),$rcvd_time); + PacketProcess::dispatchSync($this->receiving->rel_name,$this->ao->zone->domain,TRUE,$rcvd_time); } catch (\Exception $e) { - Log::error(sprintf('%s:! Got error dispatching packet [%s] (%d:%s-%s).',self::LOGKEY,$this->receiving->full_name,$e->getLine(),$e->getFile(),$e->getMessage())); + Log::error(sprintf('%s:! Got error dispatching packet [%s] (%d:%s-%s).',self::LOGKEY,$this->receiving->rel_name,$e->getLine(),$e->getFile(),$e->getMessage())); } break; diff --git a/app/Classes/File/Send.php b/app/Classes/File/Send.php index f20a376..b0a17cf 100644 --- a/app/Classes/File/Send.php +++ b/app/Classes/File/Send.php @@ -249,11 +249,10 @@ class Send extends Base * Add our mail to the send queue * * @param Address $ao - * @param bool $update * @return bool * @throws Exception */ - public function mail(Address $ao,bool $update=TRUE): bool + public function mail(Address $ao): bool { $mail = FALSE; @@ -265,7 +264,7 @@ class Send extends Base } // Netmail - if ($x=$ao->getNetmail($update)) { + if ($x=$ao->getNetmail()) { Log::debug(sprintf('%s:- Netmail(s) added for sending to [%s]',self::LOGKEY,$ao->ftn)); $this->list->push(new Mail($x,self::T_NETMAIL)); @@ -273,7 +272,7 @@ class Send extends Base } // Echomail - if ($x=$ao->getEchomail($update)) { + if ($x=$ao->getEchomail()) { Log::debug(sprintf('%s:- Echomail(s) added for sending to [%s]',self::LOGKEY,$ao->ftn)); $this->list->push(new Mail($x,self::T_ECHOMAIL)); diff --git a/app/Classes/Protocol/Binkp.php b/app/Classes/Protocol/Binkp.php index eead618..0f952ae 100644 --- a/app/Classes/Protocol/Binkp.php +++ b/app/Classes/Protocol/Binkp.php @@ -1009,6 +1009,9 @@ final class Binkp extends BaseProtocol $this->send->close(TRUE,$this->node); } + + } else { + Log::error(sprintf('%s:! M_got[skip] not for our file? [%s]',self::LOGKEY,$buf)); } } else { diff --git a/app/Console/Commands/Debug/PacketAddress.php b/app/Console/Commands/Debug/PacketAddress.php index 27ce0bf..09fa76c 100644 --- a/app/Console/Commands/Debug/PacketAddress.php +++ b/app/Console/Commands/Debug/PacketAddress.php @@ -50,7 +50,12 @@ class PacketAddress extends Command exit(1); } - echo hex_dump($ao->system->packet($ao)->generate($o->where('id',$this->argument('dbid'))->get())); + echo hex_dump($ao + ->system + ->packet($ao) + ->mail($o->where('id',$this->argument('dbid'))->get()) + ->generate() + ); return Command::SUCCESS; } diff --git a/app/Console/Commands/PacketInfo.php b/app/Console/Commands/PacketInfo.php index 2e03ed4..43bd5a6 100644 --- a/app/Console/Commands/PacketInfo.php +++ b/app/Console/Commands/PacketInfo.php @@ -99,8 +99,8 @@ class PacketInfo extends Command foreach ($pkt->errors as $msg) { $this->error(sprintf('- Date: %s',$msg->date)); $this->error(sprintf(' - FLAGS: %s',$msg->flags()->filter()->keys()->join(', '))); - $this->error(sprintf(' - From: %s (%s)',$msg->user_from,$msg->fftn)); - $this->error(sprintf(' - To: %s (%s)',$msg->user_to,$msg->tftn)); + $this->error(sprintf(' - From: %s (%s)',$msg->from,$msg->fftn)); + $this->error(sprintf(' - To: %s (%s)',$msg->to,$msg->tftn)); $this->error(sprintf(' - Subject: %s',$msg->subject)); foreach ($msg->errors->errors()->all() as $error) diff --git a/app/Console/Commands/PacketProcess.php b/app/Console/Commands/PacketProcess.php index 5dee3db..be222de 100644 --- a/app/Console/Commands/PacketProcess.php +++ b/app/Console/Commands/PacketProcess.php @@ -10,6 +10,33 @@ use App\Classes\FTN\Packet; use App\Jobs\PacketProcess as Job; use App\Models\Address; +/** + * Things to test + * + Packet + * - Sender doesnt exist (try and send a bounce message in the same session) + * - Sender defined in DB by not ours + * - Sender has wrong password + * - Packet too old + * + * + Echomail + * - Area doesnt exist (to uplink) + * - Sender not subscribed (to uplink) + * - Sender cannot post (to uplink) + * - Sender has wrong address for echorea domain (to uplink) + * - Test message in echoarea + * - Echomail from address doesnt match packet envelope (to uplink) + * - Echomail too old (to uplink) + * - Rescanned dont generate notifications + * - Rescanned dont trigger bots + * - Some Notifications to an uplink should go to the admin instead? + * + * + Netmail + * - To hub, and user not defined (reject) + * - To hub, but user redirect (redirected) + * - To areafix (processed) + * - To ping (respond) + * - With trace turned on (respond) + */ class PacketProcess extends Command { /** @@ -38,25 +65,25 @@ class PacketProcess extends Command */ public function handle() { - $fs = Storage::disk(config('fido.local_disk')); + //$fs = Storage::disk(config('fido.local_disk')); $rel_name = sprintf('%s/%s',config('fido.dir'),$this->argument('file')); - $f = new File($fs->path($rel_name)); + //$f = new File($fs->path($rel_name)); $m = []; if ($this->argument('ftn')) { - $a = Address::findFTN($this->argument('ftn')); + $ao = Address::findFTN($this->argument('ftn')); } elseif (preg_match(sprintf('/^%s\.(.{3})$/',Packet::regex),$this->argument('file'),$m)) { - $a = Address::findOrFail(hexdec($m[1])); + $ao = Address::findOrFail(hexdec($m[1])); } else { $this->error('Unable to determine sender FTN address'); exit(1); } - $x = Job::dispatchSync($rel_name,$a->zone->domain,$this->option('dontqueue')); + Job::dispatchSync($rel_name,$ao->zone->domain,$this->option('dontqueue')); - dd(['job completed'=>$x]); + return Command::SUCCESS; } } \ No newline at end of file diff --git a/app/Console/Commands/PacketSystem.php b/app/Console/Commands/PacketSystem.php index 272379b..e2b7d29 100644 --- a/app/Console/Commands/PacketSystem.php +++ b/app/Console/Commands/PacketSystem.php @@ -4,7 +4,7 @@ namespace App\Console\Commands; use Illuminate\Console\Command; -use App\Models\System; +use App\Models\Address; class PacketSystem extends Command { @@ -14,7 +14,7 @@ class PacketSystem extends Command * @var string */ protected $signature = 'packet:system' - .' {sid : System ID}'; + .' {ftn : System address}'; /** * The console command description. @@ -31,15 +31,15 @@ class PacketSystem extends Command */ public function handle() { - $so = System::findOrFail($this->argument('sid')); + $ao = Address::findFTN($this->argument('ftn')); - foreach ($so->addresses as $ao) { - $pkt = $ao->getEchomail(FALSE); + foreach ($ao->system->addresses as $o) { + $pkt = $o->getEchomail(); $this->info(sprintf('System address [%s] has [%d] messages.',$ao->ftn,$pkt?->count())); if ($pkt) { foreach ($pkt as $msg) - $this->warn(sprintf('- %s',$msg->msgid)); + $this->warn(sprintf('- %s (%s)',$msg->msgid,$msg->id)); } } } diff --git a/app/Http/Controllers/SystemController.php b/app/Http/Controllers/SystemController.php index 3c25561..e2c7ead 100644 --- a/app/Http/Controllers/SystemController.php +++ b/app/Http/Controllers/SystemController.php @@ -16,7 +16,7 @@ use Illuminate\Support\Facades\Notification; use Illuminate\Support\ViewErrorBag; use App\Classes\FTN\Message; -use App\Http\Requests\{AddressMerge,AreafixRequest,SystemRegister,SystemSessionRequest}; +use App\Http\Requests\{AddressMerge,AreafixRequest,SystemEchoareaRequest,SystemRegister,SystemSessionRequest}; use App\Jobs\AddressPoll; use App\Models\{Address,Echoarea,Echomail,Filearea,Netmail,Setup,System,Zone}; use App\Notifications\Netmails\AddressLink; @@ -694,30 +694,20 @@ class SystemController extends Controller /** * Update the systems echoareas * - * @param Request $request + * @param SystemEchoareaRequest $request * @param System $o * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View|\Illuminate\Http\RedirectResponse */ - public function echoareas(Request $request,System $o) + public function echoareas(SystemEchoareaRequest $request,System $o) { $ao = $o->addresses->firstWhere('id',$request->address_id); - if (($request->method() === 'POST') && $request->post()) { - session()->flash('accordion','echoarea'); - - if ($ao->trashed() && collect($request->get('id'))->diff($ao->echoareas->pluck('id'))->count()) - return redirect()->back()->withErrors(sprintf('Address [%s] has been deleted, cannot add additional echos',$ao->ftn3d)); - - // Ensure we have session details for this address. - if (! $ao->session('sespass')) - return redirect()->back()->withErrors('System doesnt belong to this network'); - - $ao->echoareas()->syncWithPivotValues($request->get('id',[]),['subscribed'=>Carbon::now()]); + if (($request->method() === 'POST') && $request->validated()) { + $ao->echoareas()->syncWithPivotValues($request->validated('id',[]),['subscribed'=>Carbon::now()]); return redirect()->back()->with('success','Echoareas updated'); } - // @todo Allow a NC/RC/ZC to override $eo = Echoarea::active() ->where('domain_id',$ao->zone->domain_id) ->where(function($query) use ($ao) { @@ -869,7 +859,7 @@ class SystemController extends Controller */ public function session_del(System $o,Zone $zo) { - $this->authorize('admin',$zo); + $this->authorize('update_nn',$o); session()->flash('accordion','session'); $o->sessions()->detach($zo); diff --git a/app/Http/Requests/SystemEchoareaRequest.php b/app/Http/Requests/SystemEchoareaRequest.php new file mode 100644 index 0000000..65e5d9b --- /dev/null +++ b/app/Http/Requests/SystemEchoareaRequest.php @@ -0,0 +1,71 @@ + "address" // address_id that will receive the echos + * + "domain_id" => "domain" // Of the echoareas + * + "id" => array of IDs // The echos being subscribed (or if absent, are removed) + * + * Rules: + * @see AddressAdd::class for description of authorisation + */ +class SystemEchoareaRequest extends FormRequest +{ + /** + * Determine if the user is authorized to make this request. + */ + public function authorize(): bool + { + return request()->isMethod('get') + || Gate::allows('update_nn',$this->route('o')); + } + + /** + * Get the validation rules that apply to the request. + * + * @return array|string> + */ + public function rules(Request $request): array + { + if (request()->isMethod('get')) + return []; + + session()->flash('accordion','echoarea'); + return [ + 'address_id'=>[ + 'exists:addresses,id', + // Make sure we have session details for the area + function ($attribute,$value,$fail) use ($request) { + $ao = request()->route('o')->addresses->firstWhere('id',$request->address_id); + + if ((! $ao) || (! $ao->active) || (! $ao->system->zones->pluck('domain_id')->contains($request->domain_id))) + $fail('Address must be ACTIVE, and have session details for the domain'); + }, + ], + 'domain_id'=>'exists:domains,id', + 'id'=>[ + 'array', + 'min:1', + // Make sure the echoareas are in the domain + function ($attribute,$value,$fail) use ($request) { + $do = Domain::findOrFail($request->domain_id); + + if ($do->echoareas->pluck('id')->intersect($value)->count() !== count($value)) + $fail('Some echaoreas dont exist in the domain?'); + }, + ] + ]; + } +} \ No newline at end of file diff --git a/app/Jobs/MessageProcess.php b/app/Jobs/MessageProcess.php index 05a02d8..2f3a803 100644 --- a/app/Jobs/MessageProcess.php +++ b/app/Jobs/MessageProcess.php @@ -8,13 +8,12 @@ use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Foundation\Bus\Dispatchable; use Illuminate\Queue\InteractsWithQueue; use Illuminate\Queue\SerializesModels; -use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Notification; use App\Classes\FTN\Message; -use App\Models\{Echoarea,Echomail,Netmail,User}; -use App\Notifications\Netmails\{EchoareaNotExist,EchoareaNotSubscribed,EchoareaNoWrite,NetmailForward,Reject}; +use App\Models\{Echomail,Netmail,User}; +use App\Notifications\Netmails\{EchoareaNotExist,EchoareaNotSubscribed,EchoareaNoWrite,NetmailForward,NetmailHubNoUser}; use App\Traits\ParseAddresses; class MessageProcess implements ShouldQueue @@ -174,7 +173,7 @@ class MessageProcess implements ShouldQueue if (! $processed) { Log::alert(sprintf('%s:! Netmail to the Hub from (%s) [%s] but no users here.',self::LOGKEY,$this->mo->from,$this->mo->fftn->ftn)); - Notification::route('netmail',$this->mo->fftn)->notify(new Reject($this->mo)); + Notification::route('netmail',$this->mo->fftn)->notify(new NetmailHubNoUser($this->mo)); } // If in transit, store for collection @@ -269,11 +268,11 @@ class MessageProcess implements ShouldQueue // @todo if we have an export for any of the seenby addresses, remove it - $seenby = $this->parseAddresses('seenby',$this->mo->seenby,$sender->zone,$o->rogue_seenby); - $this->mo->seenby()->syncWithoutDetaching($seenby); + //$seenby = $this->parseAddresses('seenby',$this->mo->seenby,$sender->zone,$o->rogue_seenby); + //$this->mo->seenby()->syncWithoutDetaching($seenby); // In case our rogue_seenby changed - $this->mo->save(); + //$this->mo->save(); return; } @@ -294,14 +293,6 @@ class MessageProcess implements ShouldQueue )); } - // If the node is not subscribed - if ($sender->echoareas->search(function($item) { return $item->id === $this->mo->echoarea->id; }) === FALSE) { - Log::alert(sprintf('%s:! FTN [%s] is not subscribed to [%s] for [%s].',self::LOGKEY,$sender->ftn,$this->mo->echoarea->name,$this->mo->msgid)); - - if (! $rescanned) - Notification::route('netmail',$sender)->notify(new EchoareaNotSubscribed($this->mo)); - } - // Can the system send messages to this area? if (! $this->mo->echoarea->can_write($sender->security)) { Log::alert(sprintf('%s:! FTN [%s] is not allowed to post [%s] to [%s].',self::LOGKEY,$sender->ftn,$this->mo->msgid,$this->mo->echoarea->name)); @@ -311,6 +302,14 @@ class MessageProcess implements ShouldQueue return; } + // If the node is not subscribed, we'll accept it, but let them know + if (! $sender->echoareas->contains($this->mo->echoarea)) { + Log::alert(sprintf('%s:! FTN [%s] is not subscribed to [%s] for [%s].',self::LOGKEY,$sender->ftn,$this->mo->echoarea->name,$this->mo->msgid)); + + if (! $rescanned) + Notification::route('netmail',$sender)->notify(new EchoareaNotSubscribed($this->mo)); + } + // We know about this area, store it $this->mo->save(); diff --git a/app/Jobs/PacketProcess.php b/app/Jobs/PacketProcess.php index 92c84f3..0b90cf8 100644 --- a/app/Jobs/PacketProcess.php +++ b/app/Jobs/PacketProcess.php @@ -32,7 +32,7 @@ class PacketProcess implements ShouldQueue private bool $interactive; private bool $nobot; - public function __construct(string $filename,Domain $do,bool $interactive=FALSE,Carbon $rcvd_time=NULL,bool $nobot=FALSE) + public function __construct(string $filename,Domain $do,bool $interactive=TRUE,Carbon $rcvd_time=NULL,bool $nobot=FALSE) { $this->filename = $filename; $this->do = $do; @@ -98,7 +98,7 @@ class PacketProcess implements ShouldQueue if (strtoupper($pkt->fftn->session('pktpass')) !== strtoupper($pkt->password)) { Log::error(sprintf('%s:! Packet from [%s] with password [%s] is invalid.',self::LOGKEY,$pkt->fftn->ftn,$pkt->password)); - Notification::route('netmail',$pkt->fftn)->notify(new PacketPasswordInvalid($pkt->password,$this->filename)); + Notification::route('netmail',$pkt->fftn)->notify(new PacketPasswordInvalid($pkt->password,$f->pktName())); break; } @@ -126,6 +126,9 @@ class PacketProcess implements ShouldQueue $msg->set_pkt = $f->pktName(); $msg->set_recvtime = $this->rcvd_time; + if ($queue || (! $this->interactive)) + Log::info(sprintf('%s:! Message [%s] will be sent to the queue to process',self::LOGKEY,$msg->msgid)); + try { // Dispatch job. if ($queue || (! $this->interactive)) diff --git a/app/Models/Address.php b/app/Models/Address.php index 0fe3c3e..7af8b01 100644 --- a/app/Models/Address.php +++ b/app/Models/Address.php @@ -978,47 +978,26 @@ class Address extends Model /** * Get echomail for this node * - * @param bool $update - * @param Collection|null $echomail * @return Packet|null * @throws \Exception * @todo If we export to uplink hubs without our address in the seenby, they should send the message back to * us with their seenby's. */ - public function getEchomail(bool $update=TRUE,Collection $echomail=NULL): ?Packet + public function getEchomail(): ?Packet { - $pkt = NULL; - if ($echomail) - return $this->getPacket($echomail); + if (($num=$this->echomailWaiting())->count()) { + $s = Setup::findOrFail(config('app.id')); - $s = Setup::findOrFail(config('app.id')); - - $num = self::UncollectedEchomail() - ->select('echomails.id') - ->where('addresses.id',$this->id) - ->groupBy(['echomails.id']) - ->get(); - - if ($num->count()) { - // Limit to max messages Log::info(sprintf('%s:= Got [%d] echomails for [%s] for sending',self::LOGKEY,$num->count(),$this->ftn)); + // Limit to max messages if ($num->count() > $s->msgs_pkt) Log::notice(sprintf('%s:= Only sending [%d] echomails for [%s]',self::LOGKEY,$s->msgs_pkt,$this->ftn)); - $x = $this->echomailWaiting($s->msgs_pkt); - $pkt = $this->getPacket($x); - - if ($pkt && $pkt->count() && $update) - DB::table('echomail_seenby') - ->whereIn('echomail_id',$x->pluck('id')) - ->where('address_id',$this->id) - ->whereNull('sent_at') - ->whereNotNull('export_at') - ->update(['sent_pkt'=>$pkt->name]); + return $this->system->packet($this)->mail($num->take($s->msgs_pkt)); } - return $pkt; + return NULL; } /** @@ -1036,54 +1015,47 @@ class Address extends Model /** * Get netmail for this node (including it's children) * - * @param bool $update * @return Packet|null * @throws \Exception */ - public function getNetmail(bool $update=FALSE): ?Packet + public function getNetmail(): ?Packet { - $pkt = NULL; + if (($num=$this->netmailAlertWaiting())->count()) { + Log::debug(sprintf('%s:= Packaging [%d] netmail alerts to [%s]',self::LOGKEY,$num->count(),$this->ftn)); - $s = Setup::findOrFail(config('app.id')); + // Find any message that defines a packet password + $pass = $num + ->map(function($item) { + $passpos = strpos($item->subject,':'); + return (($passpos > 0) && ($passpos < 8)) ? substr($item->subject,0,$passpos) : NULL; + }) + ->filter() + ->pop(); - if (($x=$this->netmailAlertWaiting())->count()) { - Log::debug(sprintf('%s:= Packaging [%d] netmail alerts to [%s]',self::LOGKEY,$x->count(),$this->ftn)); - $passpos = strpos($x->last()->subject,':'); + Log::debug(sprintf('%s:= Overwriting system packet password with [%s] for [%s]',self::LOGKEY,$pass,$this->ftn)); - if ($passpos > 8) - Log::alert(sprintf('%s:! Password would be greater than 8 chars? [%d]',self::LOGKEY,$passpos)); - - // @todo Do the strip pass where, if we dont want the password in the netmail - - $pkt = $this->getPacket($x,substr($x->last()->subject,0,$passpos)); - - if ($pkt && $pkt->count() && $update) - DB::table('netmails') - ->whereIn('id',$x->pluck('id')) - ->update(['sent_pkt'=>$pkt->name]); - - return $pkt; + return $this->system->packet($this,$pass)->mail( + $num->filter(fn($item)=>preg_match("/^{$pass}:/",$item->subject)) + ->transform(function($item) use ($pass) { + $item->subject = preg_replace("/^{$pass}:/",'',$item->subject); + return $item; + }) + ); } - if (($x=$this->netmailWaiting()) - ->count()) - { - Log::debug(sprintf('%s:= Got [%d] netmails for [%s] for sending',self::LOGKEY,$x->count(),$this->ftn)); + if (($num=$this->netmailWaiting())->count()) { + $s = Setup::findOrFail(config('app.id')); - if ($x->count() > $s->msgs_pkt) { - $x = $x->take($s->msgs_pkt); - Log::alert(sprintf('%s:= Only sending [%d] netmails for [%s]',self::LOGKEY,$x->count(),$this->ftn)); - } + Log::debug(sprintf('%s:= Got [%d] netmails for [%s] for sending',self::LOGKEY,$num->count(),$this->ftn)); - $pkt = $this->getPacket($x); + // Limit to max messages + if ($num->count() > $s->msgs_pkt) + Log::alert(sprintf('%s:= Only sending [%d] netmails for [%s]',self::LOGKEY,$num->count(),$this->ftn)); - if ($pkt && $pkt->count() && $update) - DB::table('netmails') - ->whereIn('id',$x->pluck('id')) - ->update(['sent_pkt'=>$pkt->name]); + return $this->system->packet($this)->mail($num->take($s->msgs_pkt)); } - return $pkt; + return NULL; } /** @@ -1154,6 +1126,7 @@ class Address extends Model * * @return Collection * @throws \Exception + * @note The packet password to use is on the subject line for these alerts */ public function netmailAlertWaiting(): Collection { diff --git a/app/Models/Netmail.php b/app/Models/Netmail.php index 46cacf7..1ed78c6 100644 --- a/app/Models/Netmail.php +++ b/app/Models/Netmail.php @@ -92,7 +92,6 @@ final class Netmail extends Model implements Packet $nodes = collect(); // Parse PATH - // @todo dont save us in the path, we'll add it dynamically when we send out. // @YYYYMMDD.HHMMSS[.Precise][.Time Zone] [Serial Number] if ($model->set->has('set_path')) { foreach ($model->set->get('set_path') as $line) { @@ -123,8 +122,8 @@ final class Netmail extends Model implements Packet } // If there are no details (Mystic), we'll create a blank - } else { - $nodes->push(['node'=>$model->set->get('set_sender'),'datetime'=>Carbon::now(),'program'=>sprintf('%s (%04X)',Setup::PRODUCT_NAME,Setup::PRODUCT_ID)]); + } elseif ($model->set->has('set_sender')) { + $nodes->push(['node'=>$model->set->get('set_sender'),'datetime'=>Carbon::now(),'program'=>'Unknown']); } // Save the Path diff --git a/app/Models/System.php b/app/Models/System.php index c4637df..6c76d45 100644 --- a/app/Models/System.php +++ b/app/Models/System.php @@ -253,14 +253,18 @@ class System extends Model * Return the packet that this system uses * * @param Address $ao + * @param string|null $password * @return Packet */ - public function packet(Address $ao): Packet + public function packet(Address $ao,string $password=NULL): Packet { // @todo Check that the address is one of the system's addresses - return (new (collect(Packet::PACKET_TYPES) - ->get($this->pkt_type ?: config('fido.packet_default'))))->for($ao); + return + (new (collect(Packet::PACKET_TYPES) + ->get($this->pkt_type ?: config('fido.packet_default')))) + ->for($ao) + ->password($password); } public function poll(): ?Job diff --git a/app/Notifications/Channels/EchomailChannel.php b/app/Notifications/Channels/EchomailChannel.php index c56357e..f3ee1a4 100644 --- a/app/Notifications/Channels/EchomailChannel.php +++ b/app/Notifications/Channels/EchomailChannel.php @@ -41,6 +41,6 @@ class EchomailChannel $o = $notification->toEchomail($notifiable); - Log::info(sprintf('%s:= Posted echomail (%d) [%s] to [%s]',self::LOGKEY,$o->id,$o->msgid,$echoarea)); + Log::info(sprintf('%s:= Posted echomail (%d) [%s] to [%s]',self::LOGKEY,$o->id,$o->msgid,$echoarea->name)); } } \ No newline at end of file diff --git a/app/Notifications/Echomails.php b/app/Notifications/Echomails.php index 58c1a07..c705018 100644 --- a/app/Notifications/Echomails.php +++ b/app/Notifications/Echomails.php @@ -8,7 +8,7 @@ use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Notifications\Notification; use App\Classes\FTN\Message; -use App\Models\{Echoarea, Echomail, Setup, System}; +use App\Models\{Echoarea,Echomail,Setup}; abstract class Echomails extends Notification //implements ShouldQueue { @@ -46,26 +46,24 @@ abstract class Echomails extends Notification //implements ShouldQueue */ abstract public function toEchomail(object $notifiable): Echomail; - protected function setupEchomail(Message $mo,object $notifiable): Echomail + protected function setupEchomail(Echomail $mo,object $notifiable): Echomail { $echoarea = $notifiable->routeNotificationFor(static::via); - $eo = Echoarea::where('name',$echoarea)->singleOrFail(); $o = new Echomail; - $o->init(); $o->from = Setup::PRODUCT_NAME; $o->replyid = $mo->msgid; - $o->echoarea_id = $eo->id; + $o->echoarea_id = $echoarea->id; $o->datetime = Carbon::now(); $o->tzoffset = $o->datetime->utcOffset(); - $o->fftn_id = ($x=our_address($mo->fboss_o))->id; + $o->fftn_id = ($x=our_address($mo->fftn))->id; $o->flags = (Message::FLAG_LOCAL); $o->tearline = sprintf('%s (%04X)',Setup::PRODUCT_NAME,Setup::PRODUCT_ID); $o->origin = sprintf('%s (%s)',Setup::PRODUCT_NAME,$x->ftn4d); - $o->kludges = collect(['chrs'=>$mo->kludge->get('chrs') ?: 'CP437 2']); + $o->kludges->put('CHRS:',$mo->kludges->get('chrs') ?: 'CP437 2'); return $o; } diff --git a/app/Notifications/Echomails/Test.php b/app/Notifications/Echomails/Test.php index 031f931..14e3d63 100644 --- a/app/Notifications/Echomails/Test.php +++ b/app/Notifications/Echomails/Test.php @@ -6,8 +6,8 @@ use Carbon\Carbon; use Carbon\CarbonInterface; use Illuminate\Support\Facades\Log; -use App\Classes\{Fonts\Thick,Fonts\Thin,FTN\Message,Page}; -use App\Models\{Echomail,System}; +use App\Classes\{Fonts\Thick,Fonts\Thin,Page}; +use App\Models\Echomail; use App\Notifications\Echomails; use App\Traits\MessagePath; @@ -17,14 +17,14 @@ class Test extends Echomails private const LOGKEY = 'NNP'; - private Message $mo; + private Echomail $mo; /** * Reply to a netmail ping request. * - * @param Message $mo + * @param Echomail $mo */ - public function __construct(Message $mo) + public function __construct(Echomail $mo) { parent::__construct(); @@ -43,9 +43,9 @@ class Test extends Echomails $o = $this->setupEchomail($this->mo,$notifiable); $echoarea = $notifiable->routeNotificationFor(static::via); - Log::info(sprintf('%s:+ Creating test echomail to [%s]',self::LOGKEY,$echoarea)); + Log::info(sprintf('%s:+ Creating TEST echomail in [%s]',self::LOGKEY,$echoarea->name)); - $o->to = $this->mo->user_from; + $o->to = $this->mo->from; $o->subject = 'Test Reply'; // Message diff --git a/app/Notifications/Netmails.php b/app/Notifications/Netmails.php index eecc844..3276680 100644 --- a/app/Notifications/Netmails.php +++ b/app/Notifications/Netmails.php @@ -52,14 +52,13 @@ abstract class Netmails extends Notification //implements ShouldQueue $ao = $notifiable->routeNotificationFor(static::via); $o = new Netmail; - $o->set_sender = our_address($ao); $o->to = $ao->system->sysop; $o->from = Setup::PRODUCT_NAME; $o->datetime = Carbon::now(); $o->tzoffset = $o->datetime->utcOffset(); - $o->fftn_id = $o->set->get('set_sender')->id; + $o->fftn_id = our_address($ao)->id; $o->tftn_id = $ao->id; $o->flags = (Message::FLAG_LOCAL|Message::FLAG_PRIVATE); $o->cost = 0; diff --git a/app/Notifications/Netmails/AddressLink.php b/app/Notifications/Netmails/AddressLink.php index 5aa15d3..c975fe0 100644 --- a/app/Notifications/Netmails/AddressLink.php +++ b/app/Notifications/Netmails/AddressLink.php @@ -6,7 +6,7 @@ use Illuminate\Support\Facades\Log; use App\Classes\FTN\Message; use App\Notifications\Netmails; -use App\Models\{Netmail,System,User}; +use App\Models\{Netmail,User}; use App\Traits\PageTemplate; class AddressLink extends Netmails diff --git a/app/Notifications/Netmails/Areafix.php b/app/Notifications/Netmails/Areafix.php index 17ee5c4..1a86f38 100644 --- a/app/Notifications/Netmails/Areafix.php +++ b/app/Notifications/Netmails/Areafix.php @@ -4,9 +4,8 @@ namespace App\Notifications\Netmails; use Illuminate\Support\Facades\Log; -use App\Classes\FTN\Message; use App\Notifications\Netmails; -use App\Models\{Netmail,System}; +use App\Models\Netmail; use App\Traits\{MessagePath,PageTemplate}; class Areafix extends Netmails @@ -15,14 +14,14 @@ class Areafix extends Netmails private const LOGKEY = 'NAF'; - private Message $mo; + private Netmail $mo; /** * Reply to an areafix request. * - * @param Message $mo + * @param Netmail $mo */ - public function __construct(Message $mo) + public function __construct(Netmail $mo) { parent::__construct(); @@ -43,7 +42,7 @@ class Areafix extends Netmails Log::info(sprintf('%s:+ Responding to areafix with netmail to [%s]',self::LOGKEY,$ao->ftn)); - $o->to = $this->mo->user_from; + $o->to = $this->mo->from; $o->replyid = $this->mo->msgid; $o->subject = 'Areafix Reply'; diff --git a/app/Notifications/Netmails/Areafix/NotConfiguredHere.php b/app/Notifications/Netmails/Areafix/NotConfiguredHere.php index 8650007..b0cafba 100644 --- a/app/Notifications/Netmails/Areafix/NotConfiguredHere.php +++ b/app/Notifications/Netmails/Areafix/NotConfiguredHere.php @@ -4,9 +4,8 @@ namespace App\Notifications\Netmails\Areafix; use Illuminate\Support\Facades\Log; -use App\Classes\FTN\Message; use App\Notifications\Netmails; -use App\Models\{Netmail,System}; +use App\Models\Netmail; use App\Traits\{MessagePath,PageTemplate}; class NotConfiguredHere extends Netmails @@ -15,14 +14,14 @@ class NotConfiguredHere extends Netmails private const LOGKEY = 'NCH'; - private Message $mo; + private Netmail $mo; /** * Reply to a areafix, but the system isnt configured here. * - * @param Message $mo + * @param Netmail $mo */ - public function __construct(Message $mo) + public function __construct(Netmail $mo) { parent::__construct(); @@ -43,7 +42,7 @@ class NotConfiguredHere extends Netmails Log::info(sprintf('%s:+ Responding to areafix for a node [%s] not configured here',self::LOGKEY,$ao->ftn)); - $o->to = $this->mo->user_from; + $o->to = $this->mo->from; $o->replyid = $this->mo->msgid; $o->subject = 'Areafix - Not Configured Here'; diff --git a/app/Notifications/Netmails/EchoareaNoWrite.php b/app/Notifications/Netmails/EchoareaNoWrite.php index 1707554..fc0a758 100644 --- a/app/Notifications/Netmails/EchoareaNoWrite.php +++ b/app/Notifications/Netmails/EchoareaNoWrite.php @@ -5,9 +5,8 @@ namespace App\Notifications\Netmails; use Carbon\Carbon; use Illuminate\Support\Facades\Log; -use App\Classes\FTN\Message; use App\Notifications\Netmails; -use App\Models\{Netmail,System}; +use App\Models\{Echomail,Netmail}; use App\Traits\{MessagePath,PageTemplate}; class EchoareaNoWrite extends Netmails @@ -16,14 +15,14 @@ class EchoareaNoWrite extends Netmails private const LOGKEY = 'NNW'; - private Message $mo; + private Echomail $mo; /** * Send a sysop a message if they attempt to write to an area that they dont have permission. * - * @param Message $mo + * @param Echomail $mo */ - public function __construct(Message $mo) + public function __construct(Echomail $mo) { parent::__construct(); @@ -42,9 +41,9 @@ class EchoareaNoWrite extends Netmails $o = $this->setupNetmail($notifiable); $ao = $notifiable->routeNotificationFor(static::via); - Log::info(sprintf('%s:+ Creating ECHOMAIL NO WRITE netmail to [%s]',self::LOGKEY,$ao->ftn)); + Log::info(sprintf('%s:+ Creating ECHOAREA NO WRITE netmail to [%s]',self::LOGKEY,$ao->ftn)); - $o->subject = 'Echomail rejected - '.$this->mo->msgid; + $o->subject = sprintf('Echomail #%s rejected to %s',$this->mo->msgid,$this->mo->echoarea->name); // Message $msg = $this->page(FALSE,'nowrite'); @@ -52,13 +51,13 @@ class EchoareaNoWrite extends Netmails $msg->addText( sprintf("Your echomail with ID [%s] to [%s] here was received here on [%s] and it looks like you sent it on [%s].\r\r", $this->mo->msgid, - $this->mo->user_to, + $this->mo->to, Carbon::now()->utc()->toDateTimeString(), $this->mo->date->utc()->toDateTimeString(), ) ); - $msg->addText(sprintf("It appears that you do not have permission to post in this echoarea using the address [%s], so the message from your system was rejected.\r\r",$ao->ftn)); + $msg->addText(sprintf("It appears that you do not have permission to post in [%s] using the address [%s], so the message from your system was rejected.\r\r",$this->mo->echoarea->name,$ao->ftn)); $msg->addText("Please contact the ZC if you think this is a mistake.\r\r"); $msg->addText($this->message_path($this->mo)); diff --git a/app/Notifications/Netmails/EchoareaNotExist.php b/app/Notifications/Netmails/EchoareaNotExist.php index cd66bee..c21622d 100644 --- a/app/Notifications/Netmails/EchoareaNotExist.php +++ b/app/Notifications/Netmails/EchoareaNotExist.php @@ -42,7 +42,7 @@ class EchoareaNotExist extends Netmails $o = $this->setupNetmail($notifiable); $ao = $notifiable->routeNotificationFor(static::via); - Log::info(sprintf('%s:+ Creating ECHOMAIL NOT EXIST netmail to [%s]',self::LOGKEY,$ao->ftn)); + Log::info(sprintf('%s:+ Creating ECHOAREA NOT EXIST netmail to [%s]',self::LOGKEY,$ao->ftn)); $o->subject = 'Echoarea doesnt exist - '.$this->mo->set->get('set_echoarea'); @@ -58,7 +58,7 @@ class EchoareaNotExist extends Netmails ) ); - $msg->addText("It appears that the echoarea that this message is for doesnt exist, so the message from your system was rejected.\r\r"); + $msg->addText(sprintf("It appears that the echoarea [%s] that this message is for doesnt exist, so the message from your system was rejected.\r\r",$this->mo->set->get('set_echoarea'))); $msg->addText("Please contact the ZC if you think this is a mistake.\r\r"); $msg->addText($this->message_path($this->mo)); diff --git a/app/Notifications/Netmails/EchoareaNotSubscribed.php b/app/Notifications/Netmails/EchoareaNotSubscribed.php index b8a2c07..16cc738 100644 --- a/app/Notifications/Netmails/EchoareaNotSubscribed.php +++ b/app/Notifications/Netmails/EchoareaNotSubscribed.php @@ -5,9 +5,8 @@ namespace App\Notifications\Netmails; use Carbon\Carbon; use Illuminate\Support\Facades\Log; -use App\Classes\FTN\Message; use App\Notifications\Netmails; -use App\Models\{Netmail,System}; +use App\Models\{Echomail,Netmail}; use App\Traits\{MessagePath,PageTemplate}; class EchoareaNotSubscribed extends Netmails @@ -16,14 +15,14 @@ class EchoareaNotSubscribed extends Netmails private const LOGKEY = 'NNW'; - private Message $mo; + private Echomail $mo; /** * Send a sysop a message if they write to an area that they hadnt previously subscribed to. * - * @param Message $mo + * @param Echomail $mo */ - public function __construct(Message $mo) + public function __construct(Echomail $mo) { parent::__construct(); @@ -42,17 +41,17 @@ class EchoareaNotSubscribed extends Netmails $o = $this->setupNetmail($notifiable); $ao = $notifiable->routeNotificationFor(static::via); - Log::info(sprintf('%s:+ Creating ECHOMAIL NOT SUBSCRIBED netmail to [%s]',self::LOGKEY,$ao->ftn)); + Log::info(sprintf('%s:+ Creating ECHOAREA NOT SUBSCRIBED netmail to [%s]',self::LOGKEY,$ao->ftn)); - $o->subject = 'Echoarea not subscribed - '.$this->mo->echoarea; + $o->subject = 'Echoarea not subscribed - '.$this->mo->echoarea->name; // Message - $msg = $this->page(FALSE,'nothere'); + $msg = $this->page(FALSE,'nosub'); $msg->addText( sprintf("Your echomail with ID [%s] to [%s] here was received here on [%s] and it looks like you sent it on [%s].\r\r", $this->mo->msgid, - $this->mo->user_to, + $this->mo->to, Carbon::now()->utc()->toDateTimeString(), $this->mo->date->utc()->toDateTimeString(), ) diff --git a/app/Notifications/Netmails/EchomailBadAddress.php b/app/Notifications/Netmails/EchomailBadAddress.php index 20c5ae3..4e4aad8 100644 --- a/app/Notifications/Netmails/EchomailBadAddress.php +++ b/app/Notifications/Netmails/EchomailBadAddress.php @@ -7,7 +7,7 @@ use Illuminate\Support\Facades\Log; use App\Classes\FTN\Message; use App\Notifications\Netmails; -use App\Models\{Netmail,System}; +use App\Models\Netmail; use App\Traits\{MessagePath,PageTemplate}; class EchomailBadAddress extends Netmails @@ -52,7 +52,7 @@ class EchomailBadAddress extends Netmails $msg->addText( sprintf("Your echomail with ID [%s] to [%s] here was received here on [%s] and it looks like you sent it on [%s].\r\r", $this->mo->msgid, - $this->mo->user_to, + $this->mo->to, Carbon::now()->utc()->toDateTimeString(), $this->mo->date->utc()->toDateTimeString(), ) diff --git a/app/Notifications/Netmails/NetmailForward.php b/app/Notifications/Netmails/NetmailForward.php index 95b067a..3cb6103 100644 --- a/app/Notifications/Netmails/NetmailForward.php +++ b/app/Notifications/Netmails/NetmailForward.php @@ -4,9 +4,8 @@ namespace App\Notifications\Netmails; use Illuminate\Support\Facades\Log; -use App\Classes\FTN\Message; use App\Notifications\Netmails; -use App\Models\{Address,Netmail,System}; +use App\Models\{Address,Netmail}; use App\Traits\{MessagePath,PageTemplate}; class NetmailForward extends Netmails @@ -16,15 +15,15 @@ class NetmailForward extends Netmails private const LOGKEY = 'NNP'; private Address $ao; - private Message $mo; + private Netmail $mo; /** * Reply to a netmail ping request. * - * @param Message $mo + * @param Netmail $mo * @param Address $ao */ - public function __construct(Message $mo,Address $ao) + public function __construct(Netmail $mo,Address $ao) { parent::__construct(); @@ -44,9 +43,9 @@ class NetmailForward extends Netmails $o = $this->setupNetmail($notifiable); $ao = $notifiable->routeNotificationFor(static::via); - Log::info(sprintf('%s:+ Advising [%s@%s] that netmail to [%s] will be forwarded to [%s].',self::LOGKEY,$this->mo->user_from,$ao->ftn,$this->mo->user_to,$this->ao->ftn)); + Log::info(sprintf('%s:+ Advising [%s@%s] that netmail to [%s] will be forwarded to [%s].',self::LOGKEY,$this->mo->from,$ao->ftn,$this->mo->to,$this->ao->ftn)); - $o->to = $this->mo->user_from; + $o->to = $this->mo->from; $o->replyid = $this->mo->msgid; $o->subject = sprintf('Your netmail is being forwarded to %s',$this->ao->ftn3d); @@ -56,10 +55,10 @@ class NetmailForward extends Netmails $msg->addText("Howdy, Clrghouz is not a BBS, so users cannot login to collect netmail.\r\r\r"); $msg->addText(sprintf("Never fear, your msg [%s] to [%s] has been forwarded, to [%s].\r\r", $this->mo->msgid, - $this->mo->user_to, + $this->mo->to, $this->ao->ftn3d, )); - $msg->addText(sprintf("To avoid receiving this netmail, send messages to [%s] to [%s].\r\r",$this->mo->user_to,$this->ao->ftn3d)); + $msg->addText(sprintf("To avoid receiving this netmail, send messages to [%s] to [%s].\r\r",$this->mo->to,$this->ao->ftn3d)); $o->msg = $msg->render(); $o->tagline = 'Thank you so much for your mail. I love it already.'; diff --git a/app/Notifications/Netmails/Reject.php b/app/Notifications/Netmails/NetmailHubNoUser.php similarity index 81% rename from app/Notifications/Netmails/Reject.php rename to app/Notifications/Netmails/NetmailHubNoUser.php index 87d98ed..118f7d6 100644 --- a/app/Notifications/Netmails/Reject.php +++ b/app/Notifications/Netmails/NetmailHubNoUser.php @@ -5,25 +5,24 @@ namespace App\Notifications\Netmails; use Carbon\Carbon; use Illuminate\Support\Facades\Log; -use App\Classes\FTN\Message; use App\Notifications\Netmails; -use App\Models\{Netmail,System}; +use App\Models\Netmail; use App\Traits\{MessagePath,PageTemplate}; -class Reject extends Netmails +class NetmailHubNoUser extends Netmails { use MessagePath,PageTemplate; private const LOGKEY = 'NNP'; - private Message $mo; + private Netmail $mo; /** * Reply to a netmail ping request. * - * @param Message $mo + * @param Netmail $mo */ - public function __construct(Message $mo) + public function __construct(Netmail $mo) { parent::__construct(); @@ -42,9 +41,9 @@ class Reject extends Netmails $o = $this->setupNetmail($notifiable); $ao = $notifiable->routeNotificationFor(static::via); - Log::info(sprintf('%s:+ Creating reject netmail to [%s]',self::LOGKEY,$ao->ftn)); + Log::info(sprintf('%s:+ Creating HUB NO USER netmail to [%s]',self::LOGKEY,$ao->ftn)); - $o->to = $this->mo->user_from; + $o->to = $this->mo->from; $o->replyid = $this->mo->msgid; $o->subject = 'Message Undeliverable - '.$this->mo->msgid; @@ -54,7 +53,7 @@ class Reject extends Netmails $msg->addText( sprintf("Your netmail with ID [%s] to [%s] here was received here on [%s] and it looks like you sent it on [%s].\r\r", $this->mo->msgid, - $this->mo->user_to, + $this->mo->to, Carbon::now()->utc()->toDateTimeString(), $this->mo->date->utc()->toDateTimeString(), ) diff --git a/app/Notifications/Netmails/PacketPasswordInvalid.php b/app/Notifications/Netmails/PacketPasswordInvalid.php index 3040c46..555d035 100644 --- a/app/Notifications/Netmails/PacketPasswordInvalid.php +++ b/app/Notifications/Netmails/PacketPasswordInvalid.php @@ -6,7 +6,7 @@ use Illuminate\Support\Facades\Log; use App\Notifications\Netmails; use App\Classes\FTN\Message; -use App\Models\{Netmail,System}; +use App\Models\Netmail; use App\Traits\PageTemplate; class PacketPasswordInvalid extends Netmails diff --git a/app/Notifications/Netmails/Ping.php b/app/Notifications/Netmails/Ping.php index 08708b8..abc324c 100644 --- a/app/Notifications/Netmails/Ping.php +++ b/app/Notifications/Netmails/Ping.php @@ -8,7 +8,7 @@ use Illuminate\Support\Facades\Log; use App\Classes\FTN\Message; use App\Notifications\Netmails; -use App\Models\{Netmail,System}; +use App\Models\Netmail; use App\Traits\{MessagePath,PageTemplate}; class Ping extends Netmails @@ -17,14 +17,14 @@ class Ping extends Netmails private const LOGKEY = 'NNP'; - private Message $mo; + private Netmail $mo; /** * Reply to a netmail ping request. * * @param Message $mo */ - public function __construct(Message $mo) + public function __construct(Netmail $mo) { parent::__construct(); @@ -45,7 +45,7 @@ class Ping extends Netmails Log::info(sprintf('%s:+ Creating PING netmail to [%s]',self::LOGKEY,$ao->ftn)); - $o->to = $this->mo->user_from; + $o->to = $this->mo->from; $o->replyid = $this->mo->msgid; $o->subject = 'Ping Reply'; diff --git a/app/Notifications/Netmails/PollingFailed.php b/app/Notifications/Netmails/PollingFailed.php index 7208ebe..822ab3d 100644 --- a/app/Notifications/Netmails/PollingFailed.php +++ b/app/Notifications/Netmails/PollingFailed.php @@ -5,9 +5,8 @@ namespace App\Notifications\Netmails; use Carbon\Carbon; use Illuminate\Support\Facades\Log; -use App\Classes\FTN\Message; use App\Notifications\Netmails; -use App\Models\{Netmail,System}; +use App\Models\Netmail; use App\Traits\{MessagePath,PageTemplate}; class PollingFailed extends Netmails diff --git a/app/Notifications/Netmails/Test.php b/app/Notifications/Netmails/Test.php index 71b398f..37b72f0 100644 --- a/app/Notifications/Netmails/Test.php +++ b/app/Notifications/Netmails/Test.php @@ -5,7 +5,7 @@ namespace App\Notifications\Netmails; use Illuminate\Support\Facades\Log; use App\Notifications\Netmails; -use App\Models\{Netmail,System}; +use App\Models\Netmail; use App\Traits\PageTemplate; class Test extends Netmails diff --git a/app/Traits/EncodeUTF8.php b/app/Traits/EncodeUTF8.php index 3b88a3e..0e575b4 100644 --- a/app/Traits/EncodeUTF8.php +++ b/app/Traits/EncodeUTF8.php @@ -89,7 +89,7 @@ trait EncodeUTF8 return $this->attributes[$key]; } - return parent::getAttribute($key); + return Arr::get($this->_encoded,$key) ? $this->attributes[$key] : parent::getAttribute($key); } public function setAttribute($key,$value) diff --git a/app/Traits/MessageAttributes.php b/app/Traits/MessageAttributes.php index 6d858e7..f04b38d 100644 --- a/app/Traits/MessageAttributes.php +++ b/app/Traits/MessageAttributes.php @@ -70,26 +70,38 @@ trait MessageAttributes public function getOriginAttribute(string $val=NULL): ?string { + if ($this->exists && (! $val)) + return $val; + // If $val is not set, then it may be an unsaved object - return ((! $this->exists) && $this->set->has('set_origin')) - ? sprintf(' * Origin: %s',$this->set->get('set_origin')) - : $val; + return sprintf(' * Origin: %s', + ((! $this->exists) && $this->set->has('set_origin')) + ? $this->set->get('set_origin') + : $val); } public function getTaglineAttribute(string $val=NULL): ?string { + if ($this->exists && (! $val)) + return $val; + // If $val is not set, then it may be an unsaved object - return ((! $this->exists) && $this->set->has('set_tagline')) - ? sprintf('... %s',$this->set->get('set_tagline')) - : $val; + return sprintf('... %s', + ((! $this->exists) && $this->set->has('set_tagline')) + ? $this->set->get('set_tagline') + : $val); } public function getTearlineAttribute(string $val=NULL): ?string { + if ($this->exists && (! $val)) + return $val; + // If $val is not set, then it may be an unsaved object - return ((! $this->exists) && $this->set->has('set_tearline')) - ? sprintf('--- %s',$this->set->get('set_tearline')) - : $val; + return sprintf('--- %s', + ((! $this->exists) && $this->set->has('set_tearline')) + ? $this->set->get('set_tearline') + : $val); } /* METHODS */ @@ -141,10 +153,11 @@ trait MessageAttributes 'receipt' => $this->isFlagSet(Message::FLAG_ISRETRECEIPT), 'audit' => $this->isFlagSet(Message::FLAG_AUDITREQ), 'fileupdate' => $this->isFlagSet(Message::FLAG_FILEUPDATEREQ), + 'pktpasswd' => $this->isFlagSet(Message::FLAG_PKTPASSWD), ])->filter(); } - private function isFlagSet($flag): bool + public function isFlagSet($flag): bool { return ($this->flags & $flag); } diff --git a/app/Traits/MessagePath.php b/app/Traits/MessagePath.php index 98f9c3d..42f896e 100644 --- a/app/Traits/MessagePath.php +++ b/app/Traits/MessagePath.php @@ -27,20 +27,18 @@ trait MessagePath $reply .= "+--[ PATH ]-------------------------------------------+\r"; - if ($mo instanceof Netmail) { - if ($mo->via->count()) - foreach ($mo->via as $ao) - $reply .= sprintf("VIA: %s\r",$mo->via($ao)); - else - $reply .= "No path information? This would be normal if this message came directly to the hub\r"; + if ($mo->path->count()) + if ($mo instanceof Netmail) { + foreach ($mo->path as $o) + $reply .= sprintf("VIA: %s\r",$mo->via($o)); - } else { - if ($mo->path->count()) - foreach ($mo->path as $via) - $reply .= sprintf("VIA: %s\r",$via); - else - $reply .= "No path information? This would be normal if this message came directly to the hub\r"; - } + } else { + foreach ($mo->path as $o) + $reply .= sprintf("VIA: %s\r",$o->ftn); + } + + else + $reply .= "No path information? This would be normal if this message came directly to the hub\r"; $reply .= "+--[ END MESSAGE ]------------------------------------+\r\r"; diff --git a/resources/views/widgets/message.blade.php b/resources/views/widgets/message.blade.php index 9cab574..3b08a5b 100644 --- a/resources/views/widgets/message.blade.php +++ b/resources/views/widgets/message.blade.php @@ -97,6 +97,17 @@ use App\Models\{Echomail,Netmail}; +@if($msg instanceof Netmail) +
+ SENT: + @if($msg->sent_pkt && $msg->sent_at) + {{ $msg->sent_at }} ({{ $msg->sent_pkt }}.pkt) + @else + NOT SENT + @endif +
+@endif + @section('page-scripts') @@ -114,5 +125,4 @@ use App\Models\{Echomail,Netmail}; ); }); - @append \ No newline at end of file