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 ;
2021-07-15 14:54:23 +00:00
2021-07-23 14:53:35 +00:00
use App\Classes\FTN\ { Message , Process };
2021-08-24 13:42:03 +00:00
use App\Models\ { Echoarea , Echomail , Netmail , Setup };
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 ;
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-01-24 11:37:41 +00:00
public function __construct ( Message $msg , string $packet , bool $skipbot = FALSE )
2021-07-15 14:54:23 +00:00
{
// Some checks
$this -> msg = $msg ;
2021-09-10 14:38:11 +00:00
$this -> skipbot = $skipbot ;
2023-01-24 11:37:41 +00:00
$this -> packet = $packet ;
2021-07-15 14:54:23 +00:00
}
/**
2021-09-06 13:39:32 +00:00
* When calling MessageProcess - we assume that the packet is from a valid source
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-01-25 05:26:10 +00:00
Log :: info ( sprintf ( '%s:Processing Netmail [%s] to (%s) [%s] from (%s) [%s].' ,
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
2021-07-23 14:53:35 +00:00
// @todo Enable checks to reject duplicate
// @todo Enable checks to see if this is a file request or file send
2021-07-15 14:54:23 +00:00
2023-01-24 11:37:41 +00:00
$o = $this -> create_netmail ( $this -> msg );
$o -> recv_pkt = $this -> packet ;
2021-07-15 14:54:23 +00:00
// Determine if the message is to this system, or in transit
2021-07-18 12:10:21 +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-01-25 05:35:58 +00:00
$o -> local = TRUE ;
$o -> save ();
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' ])) {
$o -> local = TRUE ;
$o -> save ();
2023-01-24 11:37:41 +00:00
Log :: info ( sprintf ( '%s:Ignoring Netmail [%d-%s] to the Hub from (%s) [%s] - its from a bot.' ,
self :: LOGKEY ,
$o -> id ,
$this -> msg -> msgid ,
$this -> msg -> user_from ,
$this -> msg -> fftn )
);
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 ) {
2021-07-23 14:53:35 +00:00
$reject = [
'ÚÄ¿ÚÄ¿ ÂÚÄ¿ÚÄ¿Ú¿' ,
'³ ³ÄÙ ³³ÄÙ³ ³ ' ,
'Á ÀÄÙÀÄÙÀÄÙÀÄÙ Á '
];
Log :: info ( sprintf ( 'Netmail to the Hub from (%s) [%s] but no users here.' , $this -> msg -> user_from , $this -> msg -> fftn ));
$reply = " Your Netmail was not processed by the hub and cannot be delivered to anybody (as there are no users here). \r " ;
$reply .= " \r " ;
$reply .= " \r " ;
$reply .= " This is your original message: \r " ;
$reply .= " ------------------------------ BEING MESSAGE ------------------------------ \r " ;
$reply .= sprintf ( " TO: %s \r " , $this -> msg -> user_to );
$reply .= sprintf ( " SUBJECT: %s \r " , $this -> msg -> subject );
$reply .= $this -> msg -> message ;
$reply .= " ------------------------------ CONTROL LINES ------------------------------ \r " ;
$reply .= sprintf ( " DATE: %s \r " , $this -> msg -> date -> format ( 'Y-m-d H:i:s' ));
$reply .= sprintf ( " MSGID: %s \r " , $this -> msg -> msgid );
foreach ( $this -> msg -> kludge as $k => $v )
2022-02-16 12:01:55 +00:00
$reply .= sprintf ( " @%s: %s \r " , strtoupper ( $k ), $v );
2021-07-23 14:53:35 +00:00
foreach ( $this -> msg -> via as $via )
2022-02-16 12:01:55 +00:00
$reply .= sprintf ( " VIA: %s \r " , $via );
2021-07-23 14:53:35 +00:00
$reply .= " ------------------------------ END MESSAGE ------------------------------ \r " ;
2021-09-11 13:32:10 +00:00
$o = new Netmail ;
2021-07-23 14:53:35 +00:00
$o -> to = $this -> msg -> user_from ;
$o -> from = Setup :: PRODUCT_NAME ;
$o -> subject = 'Message Undeliverable - ' . $this -> msg -> msgid ;
2021-07-30 14:35:52 +00:00
$o -> datetime = $this -> msg -> date ;
$o -> tzoffset = $this -> msg -> date -> utcOffset ();
$o -> cost = 0 ;
$o -> flags = Message :: FLAG_LOCAL ;
2021-07-23 14:53:35 +00:00
$o -> fftn_id = ( $x = $this -> msg -> tftn_o ) ? $x -> id : NULL ;
$o -> tftn_id = ( $x = $this -> msg -> fftn_o ) ? $x -> id : NULL ;
2022-01-01 05:59:35 +00:00
$o -> replyid = $this -> msg -> msgid ;
2021-07-30 14:35:52 +00:00
$o -> msg = Process :: format_msg ( $reply , $reject );
2021-07-23 14:53:35 +00:00
$o -> tagline = 'Do you think it was fate which brought us together? Nah, bad luck :(' ;
2021-07-30 14:35:52 +00:00
$o -> tearline = sprintf ( '%s (%04X)' , Setup :: PRODUCT_NAME , Setup :: PRODUCT_ID );
2021-07-23 14:53:35 +00:00
$o -> save ();
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
2021-07-23 14:53:35 +00:00
$o -> save ();
2023-01-24 11:37:41 +00:00
Log :: info ( sprintf ( '%s:Netmail [%d-%s] in transit to (%s) [%s] from (%s) [%s].' ,
self :: LOGKEY ,
$o -> id ,
$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
}
// Else we are echomail
} else {
2023-01-01 03:30:15 +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 ));
2022-02-11 23:21:46 +00:00
return ;
}
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
2021-11-24 11:34:40 +00:00
Log :: debug ( sprintf ( '%s: - Checking for duplicate from host id [%d].' , self :: LOGKEY ,( $x = $this -> msg -> fboss_o ) ? $x -> id : NULL ));
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?
2021-08-19 13:35:48 +00:00
// @todo Can the sender send messages to this area?
2021-07-30 14:35:52 +00:00
// - Create it, or
// - Else record in bad area
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 ;
2021-07-30 14:35:52 +00:00
$o -> save ();
2021-08-19 13:35:48 +00:00
Log :: info ( sprintf ( '%s: - Echomail [%s] in [%s] from (%s) [%s] to (%s) - [%s].' ,
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
}
}
2021-09-12 12:14:04 +00:00
private function create_netmail ( Message $msg ) : Netmail
{
$o = new Netmail ;
$o -> to = $msg -> user_to ;
$o -> from = $msg -> user_from ;
$o -> fftn_id = ( $x = $msg -> fftn_o ) ? $x -> id : NULL ;
$o -> tftn_id = ( $x = $msg -> tftn_o ) ? $x -> id : NULL ;
$o -> datetime = $msg -> date ;
$o -> tzoffset = $msg -> date -> utcOffset ();
$o -> flags = $msg -> flags ;
$o -> cost = $msg -> cost ;
$o -> msgid = $msg -> msgid ;
$o -> subject = $msg -> subject ;
2022-02-16 12:01:55 +00:00
$o -> msg = $msg -> message ;
foreach ( $msg -> via as $v )
$o -> msg .= sprintf ( " \01 Via %s \r " , $v );
$o -> msg_src = $msg -> message_src ;
$o -> msg_crc = md5 ( $msg -> message ); // @todo DB schema needs to handle this
2021-09-12 12:14:04 +00:00
return $o ;
}
2021-07-15 14:54:23 +00:00
}