Show netmails to admins, record netmail path in the DB
This commit is contained in:
parent
f147b33b60
commit
58341db0fb
@ -14,11 +14,11 @@ class CompressedString implements CastsAttributes
|
|||||||
* @param string $key
|
* @param string $key
|
||||||
* @param mixed $value
|
* @param mixed $value
|
||||||
* @param array $attributes
|
* @param array $attributes
|
||||||
* @return string|null
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function get($model,string $key,$value,array $attributes): ?string
|
public function get($model,string $key,$value,array $attributes): string
|
||||||
{
|
{
|
||||||
return $value ? zstd_uncompress(base64_decode($value)) : NULL;
|
return $value ? zstd_uncompress(base64_decode($value)) : '';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -28,10 +28,10 @@ class CompressedString implements CastsAttributes
|
|||||||
* @param string $key
|
* @param string $key
|
||||||
* @param mixed $value
|
* @param mixed $value
|
||||||
* @param array $attributes
|
* @param array $attributes
|
||||||
* @return string|null
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function set($model,string $key,$value,array $attributes): ?string
|
public function set($model,string $key,$value,array $attributes): string
|
||||||
{
|
{
|
||||||
return $value ? base64_encode(zstd_compress($value)) : NULL;
|
return $value ? base64_encode(zstd_compress($value)) : '';
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -11,6 +11,7 @@ use Illuminate\Support\Facades\Validator;
|
|||||||
use Illuminate\Validation\Validator as ValidatorResult;
|
use Illuminate\Validation\Validator as ValidatorResult;
|
||||||
|
|
||||||
use App\Classes\FTN as FTNBase;
|
use App\Classes\FTN as FTNBase;
|
||||||
|
use App\Http\Controllers\DomainController;
|
||||||
use App\Models\{Address,Domain,Zone};
|
use App\Models\{Address,Domain,Zone};
|
||||||
use App\Rules\{TwoByteInteger,TwoByteIntegerWithZero};
|
use App\Rules\{TwoByteInteger,TwoByteIntegerWithZero};
|
||||||
use App\Traits\EncodeUTF8;
|
use App\Traits\EncodeUTF8;
|
||||||
@ -632,7 +633,7 @@ class Message extends FTNBase
|
|||||||
/**
|
/**
|
||||||
* Parse the Seenby/path lines and return a collection of addresses
|
* Parse the Seenby/path lines and return a collection of addresses
|
||||||
*
|
*
|
||||||
* @param string $type
|
* @param string $type Type of address, ie: seenby/path
|
||||||
* @param Collection $addresses
|
* @param Collection $addresses
|
||||||
* @param Collection $rogue
|
* @param Collection $rogue
|
||||||
* @return Collection
|
* @return Collection
|
||||||
@ -658,7 +659,7 @@ class Message extends FTNBase
|
|||||||
$node = (int)$item;
|
$node = (int)$item;
|
||||||
};
|
};
|
||||||
|
|
||||||
$ftn = sprintf('%d:%d/%d',$this->fz,$net&0x7fff,$node&0x7fff);
|
$ftn = sprintf('%d:%d/%d',$this->fz,$net&DomainController::NUMBER_MAX,$node&DomainController::NUMBER_MAX);
|
||||||
// @todo This should be enhanced to include the address at the time of the message.
|
// @todo This should be enhanced to include the address at the time of the message.
|
||||||
if ($aos->has($ftn))
|
if ($aos->has($ftn))
|
||||||
$ao = $aos->get($ftn);
|
$ao = $aos->get($ftn);
|
||||||
@ -712,6 +713,48 @@ class Message extends FTNBase
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse the via address and return a collection of addresses
|
||||||
|
*
|
||||||
|
* <FTN Address> @YYYYMMDD.HHMMSS[.Precise][.Time Zone] <Program Name> <Version> [Serial Number]
|
||||||
|
*
|
||||||
|
* @param Collection $via
|
||||||
|
* @param Collection $rogue
|
||||||
|
* @return Collection
|
||||||
|
*/
|
||||||
|
private function parseVia(Collection $via,Collection &$rogue): Collection
|
||||||
|
{
|
||||||
|
$nodes = collect();
|
||||||
|
|
||||||
|
foreach ($via as $line) {
|
||||||
|
$m = [];
|
||||||
|
|
||||||
|
if (preg_match('/^([0-9]+:[0-9]+\/[0-9]+(\..*)?)\s+@([0-9.a-zA-Z]+)\s+(.*)$/',$line,$m)) {
|
||||||
|
// Address
|
||||||
|
$ao = Address::findFTN($m[1]);
|
||||||
|
|
||||||
|
// Time
|
||||||
|
$t = [];
|
||||||
|
$datetime = '';
|
||||||
|
|
||||||
|
if (! preg_match('/^([0-9]+\.[0-9]+)(\.?(.*))?$/',$m[3],$t))
|
||||||
|
Log::alert(sprintf('%s:! Unable to determine time from [%s]',self::LOGKEY,$m[3]));
|
||||||
|
else
|
||||||
|
$datetime = Carbon::createFromFormat('Ymd.His',$t[1],$t[3] ?? '');
|
||||||
|
|
||||||
|
if (! $ao) {
|
||||||
|
Log::alert(sprintf('%s:! Undefined Node [%s] for Netmail.',self::LOGKEY,$m[1]));
|
||||||
|
//$rogue->push(['node'=>$m[1],'datetime'=>$datetime,'program'=>$m[4]]);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
$nodes->push(['node'=>$ao,'datetime'=>$datetime,'program'=>$m[4]]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $nodes;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extract information out of the message text.
|
* Extract information out of the message text.
|
||||||
*
|
*
|
||||||
@ -904,6 +947,10 @@ class Message extends FTNBase
|
|||||||
// Parse PATH
|
// Parse PATH
|
||||||
if ($this->path->count())
|
if ($this->path->count())
|
||||||
$this->pathaddress = $this->parseAddresses('path',$this->path,$this->rogue_path);
|
$this->pathaddress = $this->parseAddresses('path',$this->path,$this->rogue_path);
|
||||||
|
|
||||||
|
// Parse VIA
|
||||||
|
if ($this->via->count())
|
||||||
|
$this->pathaddress = $this->parseVia($this->via,$this->rogue_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -10,7 +10,7 @@ use Illuminate\Support\Facades\Gate;
|
|||||||
|
|
||||||
use App\Classes\File;
|
use App\Classes\File;
|
||||||
use App\Classes\FTN\Packet;
|
use App\Classes\FTN\Packet;
|
||||||
use App\Models\{Address,Domain,Echomail,Setup};
|
use App\Models\{Address,Domain,Echomail,Netmail,Setup};
|
||||||
|
|
||||||
class HomeController extends Controller
|
class HomeController extends Controller
|
||||||
{
|
{
|
||||||
@ -97,7 +97,7 @@ class HomeController extends Controller
|
|||||||
|
|
||||||
list($zone_id,$host_id,$node_id,$point_id,$domain) = sscanf($request->query('term'),'%d:%d/%d.%d@%s');
|
list($zone_id,$host_id,$node_id,$point_id,$domain) = sscanf($request->query('term'),'%d:%d/%d.%d@%s');
|
||||||
|
|
||||||
# Look for Systems
|
// Look for Systems
|
||||||
foreach (Address::select(['systems.name',DB::raw('systems.id AS system_id'),'zones.zone_id','region_id','host_id','node_id','point_id'])
|
foreach (Address::select(['systems.name',DB::raw('systems.id AS system_id'),'zones.zone_id','region_id','host_id','node_id','point_id'])
|
||||||
->join('zones',['zones.id'=>'addresses.zone_id'])
|
->join('zones',['zones.id'=>'addresses.zone_id'])
|
||||||
->rightjoin('systems',['systems.id'=>'addresses.system_id'])
|
->rightjoin('systems',['systems.id'=>'addresses.system_id'])
|
||||||
@ -124,7 +124,7 @@ class HomeController extends Controller
|
|||||||
$result->push(['id'=>$o->system_id,'name'=>$o->name.($ftn ? ' '.$ftn : ''),'value'=>url('system/view',[$o->system_id]),'category'=>'Systems']);
|
$result->push(['id'=>$o->system_id,'name'=>$o->name.($ftn ? ' '.$ftn : ''),'value'=>url('system/view',[$o->system_id]),'category'=>'Systems']);
|
||||||
}
|
}
|
||||||
|
|
||||||
# Look for Messages
|
// Look for Echomail
|
||||||
foreach (Echomail::select(['id','fftn_id','from'])
|
foreach (Echomail::select(['id','fftn_id','from'])
|
||||||
->where('msgid','like','%'.$request->query('term').'%')
|
->where('msgid','like','%'.$request->query('term').'%')
|
||||||
->orWhere('replyid','like','%'.$request->query('term').'%')
|
->orWhere('replyid','like','%'.$request->query('term').'%')
|
||||||
@ -133,6 +133,16 @@ class HomeController extends Controller
|
|||||||
$result->push(['id'=>$o->id,'name'=>sprintf('%s (%s)',$o->from,$o->fftn->ftn3d),'value'=>url('echomail/view',[$o->id]),'category'=>'Echomail']);
|
$result->push(['id'=>$o->id,'name'=>sprintf('%s (%s)',$o->from,$o->fftn->ftn3d),'value'=>url('echomail/view',[$o->id]),'category'=>'Echomail']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Look for Netmail
|
||||||
|
if (Gate::check('admin'))
|
||||||
|
foreach (Netmail::select(['id','fftn_id','from'])
|
||||||
|
->where('msgid','like','%'.$request->query('term').'%')
|
||||||
|
->orWhere('replyid','like','%'.$request->query('term').'%')
|
||||||
|
->get() as $o)
|
||||||
|
{
|
||||||
|
$result->push(['id'=>$o->id,'name'=>sprintf('%s (%s)',$o->from,$o->fftn->ftn3d),'value'=>url('netmail/view',[$o->id]),'category'=>'Netmail']);
|
||||||
|
}
|
||||||
|
|
||||||
return $result->unique(['id'])->take(10)->values();
|
return $result->unique(['id'])->take(10)->values();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
19
app/Http/Controllers/NetmailController.php
Normal file
19
app/Http/Controllers/NetmailController.php
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use App\Models\Netmail;
|
||||||
|
|
||||||
|
class NetmailController extends Controller
|
||||||
|
{
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->middleware('auth');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function view(Netmail $o)
|
||||||
|
{
|
||||||
|
return view('netmail.view')
|
||||||
|
->with('o',$o);
|
||||||
|
}
|
||||||
|
}
|
@ -54,6 +54,7 @@ class MessageProcess implements ShouldQueue
|
|||||||
|
|
||||||
$o = $this->create_netmail($this->msg);
|
$o = $this->create_netmail($this->msg);
|
||||||
$o->recv_pkt = $this->packet;
|
$o->recv_pkt = $this->packet;
|
||||||
|
$o->set_path = $this->msg->pathaddress;
|
||||||
|
|
||||||
// Determine if the message is to this system, or in transit
|
// Determine if the message is to this system, or in transit
|
||||||
if ($ftns->search(function($item) { return $this->msg->tftn == $item->ftn; }) !== FALSE) {
|
if ($ftns->search(function($item) { return $this->msg->tftn == $item->ftn; }) !== FALSE) {
|
||||||
|
@ -5,8 +5,11 @@ namespace App\Models;
|
|||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||||
|
use Illuminate\Support\Collection;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
use Illuminate\Support\Facades\Log;
|
use Illuminate\Support\Facades\Log;
|
||||||
|
|
||||||
|
use App\Casts\CompressedString;
|
||||||
use App\Classes\FTN\Message;
|
use App\Classes\FTN\Message;
|
||||||
use App\Interfaces\Packet;
|
use App\Interfaces\Packet;
|
||||||
use App\Traits\{EncodeUTF8,MsgID};
|
use App\Traits\{EncodeUTF8,MsgID};
|
||||||
@ -17,6 +20,8 @@ final class Netmail extends Model implements Packet
|
|||||||
|
|
||||||
use SoftDeletes,EncodeUTF8,MsgID;
|
use SoftDeletes,EncodeUTF8,MsgID;
|
||||||
|
|
||||||
|
private Collection $set_path;
|
||||||
|
|
||||||
private const cast_utf8 = [
|
private const cast_utf8 = [
|
||||||
'to',
|
'to',
|
||||||
'from',
|
'from',
|
||||||
@ -30,6 +35,44 @@ final class Netmail extends Model implements Packet
|
|||||||
|
|
||||||
protected $dates = ['datetime','sent_at'];
|
protected $dates = ['datetime','sent_at'];
|
||||||
|
|
||||||
|
protected $casts = [
|
||||||
|
'msg' => CompressedString::class,
|
||||||
|
'msg_src' => CompressedString::class,
|
||||||
|
];
|
||||||
|
|
||||||
|
public function __set($key,$value)
|
||||||
|
{
|
||||||
|
switch ($key) {
|
||||||
|
case 'set_path':
|
||||||
|
$this->{$key} = $value;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
parent::__set($key,$value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function boot()
|
||||||
|
{
|
||||||
|
parent::boot();
|
||||||
|
|
||||||
|
static::created(function($model) {
|
||||||
|
// Save the Path
|
||||||
|
$ppoid = NULL;
|
||||||
|
foreach ($model->set_path as $path) {
|
||||||
|
$po = DB::select('INSERT INTO netmail_path (netmail_id,address_id,parent_id,datetime,program) VALUES (?,?,?,?,?) RETURNING id',[
|
||||||
|
$model->id,
|
||||||
|
$path['node']->id,
|
||||||
|
$ppoid,
|
||||||
|
(string)$path['datetime'],
|
||||||
|
$path['program'],
|
||||||
|
]);
|
||||||
|
|
||||||
|
$ppoid = $po[0]->id;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/* RELATIONS */
|
/* RELATIONS */
|
||||||
|
|
||||||
public function fftn()
|
public function fftn()
|
||||||
@ -39,6 +82,12 @@ final class Netmail extends Model implements Packet
|
|||||||
->withTrashed();
|
->withTrashed();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function path()
|
||||||
|
{
|
||||||
|
return $this->belongsToMany(Address::class,'netmail_path')
|
||||||
|
->withPivot(['id','parent_id','datetime','program']);
|
||||||
|
}
|
||||||
|
|
||||||
public function tftn()
|
public function tftn()
|
||||||
{
|
{
|
||||||
return $this
|
return $this
|
||||||
@ -113,4 +162,16 @@ final class Netmail extends Model implements Packet
|
|||||||
|
|
||||||
return $o;
|
return $o;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function pathorder(string $display='ftn2d',int $start=NULL): Collection
|
||||||
|
{
|
||||||
|
$result = collect();
|
||||||
|
|
||||||
|
if ($x=$this->path->firstWhere('pivot.parent_id',$start)) {
|
||||||
|
$result->push($x->$display);
|
||||||
|
$result->push($this->pathorder($display,$x->pivot->id));
|
||||||
|
};
|
||||||
|
|
||||||
|
return $result->flatten()->filter();
|
||||||
|
}
|
||||||
}
|
}
|
45
database/migrations/2023_06_18_160504_netmailpath.php
Normal file
45
database/migrations/2023_06_18_160504_netmailpath.php
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
Schema::create('netmail_path', function (Blueprint $table) {
|
||||||
|
$table->id();
|
||||||
|
|
||||||
|
$table->bigInteger('address_id');
|
||||||
|
$table->foreign('address_id')->references('id')->on('addresses');
|
||||||
|
|
||||||
|
$table->unique(['id','netmail_id']);
|
||||||
|
$table->unique(['netmail_id','address_id','parent_id']);
|
||||||
|
|
||||||
|
$table->bigInteger('parent_id')->nullable();
|
||||||
|
$table->foreign(['parent_id','netmail_id'])->references(['id','netmail_id'])->on('netmail_path');
|
||||||
|
|
||||||
|
$table->bigInteger('netmail_id');
|
||||||
|
$table->foreign('netmail_id')->references('id')->on('netmails');
|
||||||
|
|
||||||
|
$table->dateTime('datetime');
|
||||||
|
$table->string('program');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('netmail_path');
|
||||||
|
}
|
||||||
|
};
|
10
resources/views/netmail/view.blade.php
Normal file
10
resources/views/netmail/view.blade.php
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
@extends('layouts.app')
|
||||||
|
@section('htmlheader_title')
|
||||||
|
Message View
|
||||||
|
@endsection
|
||||||
|
|
||||||
|
@section('content')
|
||||||
|
<h3>Netmail</h3>
|
||||||
|
|
||||||
|
@include('widgets.message',['msg'=>$o])
|
||||||
|
@endsection
|
@ -1,6 +1,6 @@
|
|||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-4">
|
<div class="col-4">
|
||||||
TO: <strong class="highlight">{!! \App\Classes\FTN\Message::tr($msg->to) !!}</strong>
|
TO: <strong class="highlight">{!! \App\Classes\FTN\Message::tr($msg->to) !!}</strong>@if ($msg instanceof \App\Models\Netmail)(<strong class="highlight">{{ $msg->tftn->ftn }}</strong>)@endif
|
||||||
</div>
|
</div>
|
||||||
<div class="col-4">
|
<div class="col-4">
|
||||||
DATE: <strong class="highlight">{{ $msg->datetime->format('Y-m-d H:i:s') }}</strong>
|
DATE: <strong class="highlight">{{ $msg->datetime->format('Y-m-d H:i:s') }}</strong>
|
||||||
@ -35,11 +35,13 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="row pb-2">
|
@if ($msg instanceof \App\Models\Echomail)
|
||||||
|
<div class="row pb-2">
|
||||||
<div class="col-8">
|
<div class="col-8">
|
||||||
SEENBY: <br><strong class="highlight">{!! optimize_path($msg->seenby->pluck('ftn2d'))->join('</strong>, <strong class="highlight">') !!}</strong>
|
SEENBY: <br><strong class="highlight">{!! optimize_path($msg->seenby->pluck('ftn2d'))->join('</strong>, <strong class="highlight">') !!}</strong>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@endif
|
||||||
|
|
||||||
<div class="row pb-2">
|
<div class="row pb-2">
|
||||||
<div class="col-8">
|
<div class="col-8">
|
||||||
|
@ -8,6 +8,7 @@ use App\Http\Controllers\{HomeController,
|
|||||||
EchoareaController,
|
EchoareaController,
|
||||||
EchomailController,
|
EchomailController,
|
||||||
FileareaController,
|
FileareaController,
|
||||||
|
NetmailController,
|
||||||
SystemController,
|
SystemController,
|
||||||
UserController,
|
UserController,
|
||||||
UserSwitchController,
|
UserSwitchController,
|
||||||
@ -106,6 +107,7 @@ Route::middleware(['auth','can:admin'])->group(function () {
|
|||||||
Route::match(['get','post'],'setup',[HomeController::class,'setup']);
|
Route::match(['get','post'],'setup',[HomeController::class,'setup']);
|
||||||
|
|
||||||
Route::get('echomail/view/{o}',[EchomailController::class,'view']);
|
Route::get('echomail/view/{o}',[EchomailController::class,'view']);
|
||||||
|
Route::get('netmail/view/{o}',[NetmailController::class,'view']);
|
||||||
Route::get('user/list',[UserController::class,'home']);
|
Route::get('user/list',[UserController::class,'home']);
|
||||||
Route::match(['get','post'],'user/addedit/{o?}',[UserController::class,'add_edit'])
|
Route::match(['get','post'],'user/addedit/{o?}',[UserController::class,'add_edit'])
|
||||||
->where('o','[0-9]+');
|
->where('o','[0-9]+');
|
||||||
|
Loading…
Reference in New Issue
Block a user