2021-07-15 14:54:23 +00:00
< ? php
namespace App\Jobs ;
2021-10-18 12:10:15 +00:00
use Carbon\Carbon ;
2021-07-15 14:54:23 +00:00
use Illuminate\Bus\Queueable ;
use Illuminate\Contracts\Queue\ShouldQueue ;
use Illuminate\Foundation\Bus\Dispatchable ;
use Illuminate\Queue\InteractsWithQueue ;
use Illuminate\Queue\SerializesModels ;
2021-07-23 14:53:35 +00:00
use Illuminate\Support\Facades\Log ;
2023-07-23 07:27:52 +00:00
use Illuminate\Support\Facades\Notification ;
2021-07-15 14:54:23 +00:00
2023-07-23 07:27:52 +00:00
use App\Classes\FTN\Message ;
2023-07-15 00:46:19 +00:00
use App\Models\ { Address , Echoarea , Echomail , Netmail , Setup };
2023-07-29 03:17:36 +00:00
use App\Notifications\Netmails\ { EchoareaNotExist , EchoareaNotSubscribed , EchoareaNoWrite , Reject };
2021-07-15 14:54:23 +00:00
2021-09-06 13:39:32 +00:00
class MessageProcess implements ShouldQueue
2021-07-15 14:54:23 +00:00
{
2021-09-11 14:07:02 +00:00
private const LOGKEY = 'JMP' ;
2021-08-18 14:20:34 +00:00
2021-07-15 14:54:23 +00:00
use Dispatchable , InteractsWithQueue , Queueable , SerializesModels ;
2023-07-15 00:46:19 +00:00
private Address $sender ;
2021-07-15 14:54:23 +00:00
private Message $msg ;
2021-09-10 14:38:11 +00:00
private bool $skipbot ;
2023-01-24 11:37:41 +00:00
private string $packet ;
2021-07-15 14:54:23 +00:00
2023-07-15 00:46:19 +00:00
public function __construct ( Message $msg , string $packet , Address $sender , bool $skipbot = FALSE )
2021-07-15 14:54:23 +00:00
{
$this -> msg = $msg ;
2023-01-24 11:37:41 +00:00
$this -> packet = $packet ;
2023-07-15 00:46:19 +00:00
$this -> sender = $sender ;
$this -> skipbot = $skipbot ;
2021-07-15 14:54:23 +00:00
}
/**
2023-07-20 10:04:41 +00:00
* When calling MessageProcess - we assume that the packet is from a valid source , and
* the destination ( netmail / echomail ) is also valid
2021-07-15 14:54:23 +00:00
*/
public function handle ()
{
// Load our details
$ftns = Setup :: findOrFail ( config ( 'app.id' )) -> system -> addresses ;
// If we are a netmail
if ( $this -> msg -> isNetmail ()) {
2023-07-15 00:46:19 +00:00
Log :: info ( sprintf ( '%s:- Processing Netmail [%s] to (%s) [%s] from (%s) [%s].' ,
2023-01-25 05:26:10 +00:00
self :: LOGKEY ,
$this -> msg -> msgid ,
$this -> msg -> user_to , $this -> msg -> tftn ,
$this -> msg -> user_from , $this -> msg -> fftn ,
));
2021-07-15 14:54:23 +00:00
// @todo Enable checks to reject old messages
2023-07-15 00:46:19 +00:00
// Check for duplicate messages
// FTS-0009.001
if ( $this -> msg -> msgid ) {
$o = Netmail :: where ( 'msgid' , $this -> msg -> msgid )
-> where ( 'fftn_id' ,( $x = $this -> msg -> fboss_o ) ? $x -> id : NULL )
-> where ( 'datetime' , '>' , Carbon :: now () -> subYears ( 3 ))
-> single ();
Log :: debug ( sprintf ( '%s:- Checking for duplicate from host id [%d].' , self :: LOGKEY ,( $x = $this -> msg -> fboss_o ) ? $x -> id : NULL ));
if ( $o ) {
Log :: alert ( sprintf ( '%s:! Duplicate netmail [%s] in [%s] from (%s) [%s] to (%s) - ignorning.' ,
self :: LOGKEY ,
$this -> msg -> msgid ,
$this -> msg -> echoarea ,
$this -> msg -> user_from , $this -> msg -> fftn ,
$this -> msg -> user_to ,
));
if ( ! $o -> msg_crc )
$o -> msg_crc = md5 ( $this -> msg -> message );
$o -> save ();
return ;
}
}
2021-07-23 14:53:35 +00:00
// @todo Enable checks to see if this is a file request or file send
2021-07-15 14:54:23 +00:00
2023-07-23 07:27:52 +00:00
$o = new Netmail ;
$o -> to = $this -> msg -> user_to ;
$o -> from = $this -> msg -> user_from ;
$o -> fftn_id = ( $x = $this -> msg -> fftn_o ) ? $x -> id : NULL ;
$o -> tftn_id = ( $x = $this -> msg -> tftn_o ) ? $x -> id : NULL ;
$o -> datetime = $this -> msg -> date ;
$o -> tzoffset = $this -> msg -> date -> utcOffset ();
$o -> flags = $this -> msg -> flags ;
$o -> cost = $this -> msg -> cost ;
$o -> msgid = $this -> msg -> msgid ;
$o -> subject = $this -> msg -> subject ;
$o -> msg = $this -> msg -> message ;
foreach ( $this -> msg -> via as $v )
$o -> msg .= sprintf ( " \01 Via %s \r " , $v );
$o -> msg_src = $this -> msg -> message_src ;
$o -> msg_crc = md5 ( $this -> msg -> message );
2023-07-15 00:46:19 +00:00
$o -> set_pkt = $this -> packet ;
$o -> set_sender = $this -> sender ;
2023-06-18 13:33:26 +00:00
$o -> set_path = $this -> msg -> pathaddress ;
2023-07-20 10:04:41 +00:00
// Strip any local/transit flags
$o -> flags &= ~ ( Message :: FLAG_LOCAL | Message :: FLAG_INTRANSIT );
2023-01-24 11:37:41 +00:00
2021-07-15 14:54:23 +00:00
// Determine if the message is to this system, or in transit
2023-06-27 07:39:11 +00:00
if ( $ftns -> search ( function ( $item ) { return $this -> msg -> tftn === $item -> ftn ; }) !== FALSE ) {
2021-07-15 14:54:23 +00:00
// @todo Check if it is a duplicate message
// @todo Check if the message is from a system we know about
$processed = FALSE ;
// If the message is to a bot, we'll process it
2021-09-10 14:38:11 +00:00
if ( ! $this -> skipbot )
foreach ( config ( 'process.robots' ) as $class ) {
if ( $processed = $class :: handle ( $this -> msg )) {
2023-07-15 00:46:19 +00:00
$o -> flags |= Message :: FLAG_RECD ;
2023-01-25 05:35:58 +00:00
$o -> save ();
2023-07-17 06:36:53 +00:00
Log :: info ( sprintf ( '%s:= Netmail [%s] from (%s:%s) - was processed by us internally [%d]' ,
2023-07-15 12:10:05 +00:00
self :: LOGKEY ,
$this -> msg -> msgid ,
$this -> msg -> user_from ,
$this -> msg -> fftn ,
$o -> id ,
));
2021-09-10 14:38:11 +00:00
break ;
}
2021-07-15 14:54:23 +00:00
}
2021-08-14 14:21:04 +00:00
// We'll ignore messages from *fix users
if ( in_array ( strtolower ( $this -> msg -> user_from ),[ 'filefix' , 'areafix' ])) {
2023-07-15 00:46:19 +00:00
$o -> flags |= Message :: FLAG_RECD ;
2021-08-14 14:21:04 +00:00
$o -> save ();
2023-07-15 12:10:05 +00:00
Log :: alert ( sprintf ( '%s:! Ignoring Netmail [%s] to the Hub from (%s:%s) - its from a bot [%d]' ,
2023-01-24 11:37:41 +00:00
self :: LOGKEY ,
$this -> msg -> msgid ,
$this -> msg -> user_from ,
2023-07-15 00:46:19 +00:00
$this -> msg -> fftn ,
$o -> id ,
));
2023-01-24 11:37:41 +00:00
2021-08-14 14:21:04 +00:00
$processed = TRUE ;
}
2021-07-15 14:54:23 +00:00
// If not processed, no users here!
if ( ! $processed ) {
2023-07-15 00:46:19 +00:00
Log :: alert ( sprintf ( '%s:! Netmail to the Hub from (%s) [%s] but no users here.' , self :: LOGKEY , $this -> msg -> user_from , $this -> msg -> fftn ));
2021-07-23 14:53:35 +00:00
2023-07-23 07:27:52 +00:00
Notification :: route ( 'netmail' , $this -> msg -> fftn_o ) -> notify ( new Reject ( $this -> msg ));
2021-07-15 14:54:23 +00:00
}
// If in transit, store for collection
} else {
// @todo Check if the message is to a system we know about
// @todo In transit loop checking
// @todo In transit TRACE response
2023-07-15 00:46:19 +00:00
$o -> flags |= Message :: FLAG_INTRANSIT ;
2021-07-23 14:53:35 +00:00
$o -> save ();
2023-01-24 11:37:41 +00:00
2023-07-15 00:46:19 +00:00
Log :: info ( sprintf ( '%s:= Netmail [%s] in transit to (%s:%s) from (%s:%s) [%d].' ,
2023-01-24 11:37:41 +00:00
self :: LOGKEY ,
$this -> msg -> msgid ,
$this -> msg -> user_to , $this -> msg -> tftn ,
$this -> msg -> user_from , $this -> msg -> fftn ,
2023-07-15 00:46:19 +00:00
$o -> id ,
2023-01-24 11:37:41 +00:00
));
2021-07-15 14:54:23 +00:00
}
// Else we are echomail
} else {
2023-07-15 00:46:19 +00:00
Log :: debug ( sprintf ( '%s:- Looking for echomail area [%s] for mail from [%s]' , self :: LOGKEY , $this -> msg -> echoarea , $this -> msg -> fboss ));
2023-01-01 02:50:12 +00:00
if ( ! $this -> msg -> fboss_o ) {
Log :: error ( sprintf ( '%s:! Cannot process message for echomail area [%s] for mail from [%s] with msgid [%s] - no boss object?' , self :: LOGKEY , $this -> msg -> echoarea , $this -> msg -> fboss , $this -> msg -> msgid ));
return ;
}
2022-02-16 12:01:55 +00:00
$ea = Echoarea :: where ( 'name' , strtoupper ( $this -> msg -> echoarea ))
2021-08-22 06:25:43 +00:00
-> where ( 'domain_id' , $this -> msg -> fboss_o -> zone -> domain_id )
2021-08-11 13:45:30 +00:00
-> single ();
2022-02-11 23:21:46 +00:00
if ( ! $ea ) {
2023-01-01 02:35:56 +00:00
Log :: alert ( sprintf ( '%s:! Echoarea [%s] doesnt exist for zone [%d]' , self :: LOGKEY , $this -> msg -> echoarea , $this -> msg -> fboss_o -> zone -> zone_id ));
2023-07-29 03:17:36 +00:00
Notification :: route ( 'netmail' , $this -> msg -> fftn_o ) -> notify ( new EchoareaNotExist ( $this -> msg ));
2022-02-11 23:21:46 +00:00
return ;
}
2023-07-15 00:46:19 +00:00
Log :: debug ( sprintf ( '%s:- Processing echomail [%s] in [%s].' , self :: LOGKEY , $this -> msg -> msgid , $this -> msg -> echoarea ));
2021-11-24 11:34:40 +00:00
2021-08-18 14:20:34 +00:00
// Check for duplicate messages
2021-10-18 12:10:15 +00:00
// FTS-0009.001
2021-08-18 14:20:34 +00:00
if ( $this -> msg -> msgid ) {
2021-10-18 12:10:15 +00:00
$o = Echomail :: where ( 'msgid' , $this -> msg -> msgid )
-> where ( 'fftn_id' ,( $x = $this -> msg -> fboss_o ) ? $x -> id : NULL )
2021-11-24 11:34:40 +00:00
-> where ( 'datetime' , '>' , Carbon :: now () -> subYears ( 3 ))
2021-10-18 12:10:15 +00:00
-> single ();
2021-08-18 14:20:34 +00:00
2023-07-15 00:46:19 +00:00
Log :: debug ( sprintf ( '%s:- Checking for duplicate from host id [%d].' , self :: LOGKEY ,( $x = $this -> msg -> fboss_o ) ? $x -> id : NULL ));
2021-11-24 11:34:40 +00:00
2021-08-18 14:20:34 +00:00
if ( $o ) {
2021-11-24 11:34:40 +00:00
Log :: alert ( sprintf ( '%s:! Duplicate echomail [%s] in [%s] from (%s) [%s] to (%s) - updating seenby.' ,
2021-08-18 14:20:34 +00:00
self :: LOGKEY ,
$this -> msg -> msgid ,
$this -> msg -> echoarea ,
2022-01-22 12:08:46 +00:00
$this -> msg -> user_from , $this -> msg -> fftn ,
$this -> msg -> user_to ,
2021-08-18 14:20:34 +00:00
));
2021-11-24 11:34:40 +00:00
if ( ! $o -> msg_crc )
$o -> msg_crc = md5 ( $this -> msg -> message );
2022-01-15 02:06:15 +00:00
$o -> save ();
2021-11-25 10:22:36 +00:00
// If the path is empty, then its probably because of the previous bug, we'll replace it.
// @todo This duplicate message may have gone via a different path, be nice to record it.
2022-01-15 02:06:15 +00:00
//$o->path()->sync($o->path->pluck('id')->merge($this->msg->pathaddress)->toArray());
// @todo if we have an export for any of the seenby addresses, remove it
2023-01-24 11:37:41 +00:00
// @todo add received packet details
2022-01-15 02:06:15 +00:00
$o -> seenby () -> sync ( $o -> seenby -> pluck ( 'id' ) -> merge ( $this -> msg -> seenaddress ) -> filter () -> toArray ());
2021-11-24 11:34:40 +00:00
2021-08-18 14:20:34 +00:00
return ;
}
}
2021-11-24 11:34:40 +00:00
// Find another message with the same msg_crc
if ( $this -> msg -> message ) {
$o = Echomail :: where ( 'msg_crc' , $xx = md5 ( $this -> msg -> message ))
-> where ( 'fftn_id' ,( $x = $this -> msg -> fboss_o ) ? $x -> id : NULL )
-> where ( 'datetime' , '>' , Carbon :: now () -> subWeek ())
-> get ();
if ( $o -> count ())
Log :: alert ( sprintf ( '%s:! Duplicate message CRC [%s] in [%s].' ,
self :: LOGKEY ,
$xx ,
$o -> pluck ( 'id' ) -> join ( '|' )
));
}
2021-07-30 14:35:52 +00:00
// @todo Can the sender create it if it doesnt exist?
2023-07-29 03:17:36 +00:00
// Can the system send messages to this area?
if ( ! $ea -> sec_write || ( $this -> msg -> fftn_o -> security < $ea -> sec_write )) {
Notification :: route ( 'netmail' , $this -> msg -> fftn_o ) -> notify ( new EchoareaNoWrite ( $this -> msg ));
return ;
}
// If the node is not subsccribed
if ( $this -> msg -> fftn_o -> echoareas -> search ( function ( $item ) use ( $ea ) { return $item -> id === $ea -> id ; }) === FALSE ) {
Notification :: route ( 'netmail' , $this -> msg -> fftn_o ) -> notify ( new EchoareaNotSubscribed ( $this -> msg ));
}
2021-07-15 14:54:23 +00:00
// We know about this area, store it
2021-07-30 14:35:52 +00:00
$o = new Echomail ;
2022-11-04 12:14:47 +00:00
$o -> init ();
2021-07-30 14:35:52 +00:00
$o -> to = $this -> msg -> user_to ;
$o -> from = $this -> msg -> user_from ;
$o -> subject = $this -> msg -> subject ;
$o -> datetime = $this -> msg -> date ;
$o -> tzoffset = $this -> msg -> date -> utcOffset ();
2021-10-18 12:10:15 +00:00
$o -> fftn_id = ( $x = $this -> msg -> fboss_o ) ? $x -> id : NULL ; // @todo This should be the node that originated the message - but since that node is not in the DB it would be null
2022-02-11 23:21:46 +00:00
$o -> echoarea_id = $ea -> id ;
2021-07-30 14:35:52 +00:00
$o -> msgid = $this -> msg -> msgid ;
2022-10-30 12:42:30 +00:00
$o -> replyid = $this -> msg -> replyid ;
2021-07-30 14:35:52 +00:00
2022-02-16 12:01:55 +00:00
$o -> msg = $this -> msg -> message_src . " \r " ;
2022-10-30 12:42:30 +00:00
$o -> msg_src = $this -> msg -> message_src ;
2021-11-21 05:53:56 +00:00
$o -> msg_crc = md5 ( $this -> msg -> message );
2022-01-15 02:06:15 +00:00
$o -> rogue_seenby = $this -> msg -> rogue_seenby ;
$o -> rogue_path = $this -> msg -> rogue_path ;
2022-10-30 12:42:30 +00:00
$o -> set_path = $this -> msg -> pathaddress ;
$o -> set_seenby = $this -> msg -> seenaddress ;
2023-07-15 00:46:19 +00:00
// Record receiving packet and sender
2023-07-15 12:10:05 +00:00
$o -> set_pkt = $this -> packet ;
2021-07-30 14:35:52 +00:00
$o -> save ();
2023-07-15 00:46:19 +00:00
Log :: info ( sprintf ( '%s:= Echomail [%s] in [%s] from (%s) [%s] to (%s) - [%s].' ,
2021-08-19 13:35:48 +00:00
self :: LOGKEY ,
$this -> msg -> msgid ,
$this -> msg -> echoarea ,
2021-09-11 14:07:02 +00:00
$this -> msg -> user_from , $this -> msg -> fftn ,
$this -> msg -> user_to ,
2021-08-19 13:35:48 +00:00
$o -> id ,
));
2021-09-13 13:02:39 +00:00
// If the message is to a bot, but not rescanned, or purposely skipbot set, we'll process it
if (( ! $this -> skipbot ) && ( ! $this -> msg -> rescanned -> count ()))
2021-09-10 14:38:11 +00:00
foreach ( config ( 'process.echomail' ) as $class ) {
if ( $class :: handle ( $this -> msg )) {
break ;
}
2021-07-30 14:35:52 +00:00
}
2021-07-15 14:54:23 +00:00
}
}
}