diff --git a/app/Http/Controllers/UserController.php b/app/Http/Controllers/UserController.php index 3ee0363..95fd856 100644 --- a/app/Http/Controllers/UserController.php +++ b/app/Http/Controllers/UserController.php @@ -7,6 +7,7 @@ use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Validator; +use App\Http\Requests\UserRequest; use App\Models\{Address,User}; class UserController extends Controller @@ -14,25 +15,10 @@ class UserController extends Controller /** * Add or edit a node */ - public function add_edit(Request $request,User $o) + public function add_edit(UserRequest $request,User $o) { if ($request->post()) { - $this->authorize('admin',$o); - - $request->validate([ - 'email' => 'required|email|unique:users,email,'.($o->exists ? $o->id : 0), - 'name' => 'required|min:3', - 'pgp_pubkey' => [ - 'nullable', - 'min:64', - //function ($attribute,$value,$fail) { return $fail('Not this time'); } - ], - 'alias' => 'nullable|min:1', - 'active' => 'required|boolean', - 'admin' => 'required|boolean', - ]); - - foreach (['name','email','pgp_pubkey','active','admin','alias'] as $key) + foreach (['name','email','pgp_pubkey','active','admin','alias','system_id'] as $key) $o->{$key} = $request->post($key); if (! $o->exists) diff --git a/app/Http/Requests/UserRequest.php b/app/Http/Requests/UserRequest.php new file mode 100644 index 0000000..3331f06 --- /dev/null +++ b/app/Http/Requests/UserRequest.php @@ -0,0 +1,42 @@ +isMethod('post')) + return []; + + $o = $this->route('o'); + return [ + 'email' => 'required|email|unique:users,email,'.($o->exists ? $o->id : 0), + 'name' => 'required|min:3', + 'pgp_pubkey' => [ + 'nullable', + 'min:64', + //function ($attribute,$value,$fail) { return $fail('Not this time'); } + ], + 'alias' => 'nullable|min:1', + 'active' => 'required|boolean', + 'admin' => 'required|boolean', + 'system_id' => [ + 'nullable', + Rule::in($o->systems->pluck('id')), + ], + ]; + } +} \ No newline at end of file diff --git a/app/Jobs/MessageProcess.php b/app/Jobs/MessageProcess.php index 6cf3798..c9fcc37 100644 --- a/app/Jobs/MessageProcess.php +++ b/app/Jobs/MessageProcess.php @@ -12,8 +12,8 @@ use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Notification; use App\Classes\FTN\Message; -use App\Models\{Address,Echoarea,Echomail,Netmail,Setup}; -use App\Notifications\Netmails\{EchoareaNotExist,EchoareaNotSubscribed,EchoareaNoWrite,Reject}; +use App\Models\{Address,Echoarea,Echomail,Netmail,Setup,User}; +use App\Notifications\Netmails\{EchoareaNotExist,EchoareaNotSubscribed,EchoareaNoWrite,NetmailForward,Reject}; class MessageProcess implements ShouldQueue { @@ -124,7 +124,7 @@ class MessageProcess implements ShouldQueue // If the message is to a bot, we'll process it if (! $this->skipbot) foreach (config('process.robots') as $class) { - if ($processed = $class::handle($this->msg)) { + if ($processed=$class::handle($this->msg)) { $o->flags |= Message::FLAG_RECD; $o->save(); @@ -139,20 +139,46 @@ class MessageProcess implements ShouldQueue } } - // We'll ignore messages from *fix users - if (in_array(strtolower($this->msg->user_from),['filefix','areafix'])) { - $o->flags |= Message::FLAG_RECD; - $o->save(); + if (! $processed) { + // Check if the netmail is to a user, with netmail forwarding enabled + $uo = User::active() + ->where(function($query) { + return $query->whereRaw(sprintf("LOWER(name)='%s'",strtolower($this->msg->user_to))) + ->orWhereRaw(sprintf("LOWER(alias)='%s'",strtolower($this->msg->user_to))); + }) + ->whereNotNull('system_id') + ->single(); - Log::alert(sprintf('%s:! Ignoring Netmail [%s] to the Hub from (%s:%s) - its from a bot [%d]', - self::LOGKEY, - $this->msg->msgid, - $this->msg->user_from, - $this->msg->fftn, - $o->id, - )); + if ($uo && ($ao=$uo->system->match($this->msg->tftn_o->zone)?->pop())) { + $note = "+--[ FORWARDED MESSAGE ]----------------------------------+\r"; + $note .= "+ This message has been forwarded to you, it was originally sent to you\r"; + $note .= sprintf("+ at [%s]\r",$this->msg->tftn_o->ftn); + $note .= "+---------------------------------------------------------+\r\r"; + $o->msg = $note.$this->msg->message; + $o->tftn_id = $ao->id; + $o->flags |= Message::FLAG_INTRANSIT; + $o->save(); + $processed = TRUE; - $processed = TRUE; + // Dont send an advisement to an areabot + if (! in_array(strtolower($this->msg->user_from),config('app.areabots'))) + Notification::route('netmail',$this->msg->fftn_o)->notify(new NetmailForward($this->msg,$ao)); + + // We'll ignore messages from *fix users + } elseif (in_array(strtolower($this->msg->user_from),config('app.areabots'))) { + $o->flags |= Message::FLAG_RECD; + $o->save(); + + Log::alert(sprintf('%s:! Ignoring Netmail [%s] to the Hub from (%s:%s) - its from a bot [%d]', + self::LOGKEY, + $this->msg->msgid, + $this->msg->user_from, + $this->msg->fftn, + $o->id, + )); + + $processed = TRUE; + } } // If not processed, no users here! diff --git a/app/Models/User.php b/app/Models/User.php index 610b953..e5e0286 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -8,7 +8,7 @@ use Illuminate\Foundation\Auth\User as Authenticatable; use Illuminate\Notifications\Notifiable; use Laravel\Sanctum\HasApiTokens; -use App\Traits\UserSwitch; +use App\Traits\{ScopeActive,UserSwitch}; /** * Class User @@ -26,7 +26,7 @@ use App\Traits\UserSwitch; */ class User extends Authenticatable implements MustVerifyEmail { - use HasFactory,Notifiable,HasApiTokens,UserSwitch; + use HasFactory,Notifiable,HasApiTokens,UserSwitch,ScopeActive; /** * The attributes that are mass assignable. @@ -61,6 +61,11 @@ class User extends Authenticatable implements MustVerifyEmail /* RELATIONS */ + public function system() + { + return $this->belongsTo(System::class); + } + public function systems() { return $this->belongsToMany(System::class); diff --git a/app/Notifications/Netmails/NetmailForward.php b/app/Notifications/Netmails/NetmailForward.php new file mode 100644 index 0000000..fd41466 --- /dev/null +++ b/app/Notifications/Netmails/NetmailForward.php @@ -0,0 +1,72 @@ +mo = $mo; + $this->ao = $ao; + } + + /** + * Get the mail representation of the notification. + * + * @param System $so + * @param mixed $notifiable + * @return Netmail + * @throws \Exception + */ + public function toNetmail(System $so,object $notifiable): Netmail + { + $o = $this->setupNetmail($so,$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)); + + $o->to = $this->mo->user_from; + $o->replyid = $this->mo->msgid; + $o->subject = sprintf('Your netmail is being forwarded to %s',$this->ao->ftn3d); + + // Message + $msg = $this->page(FALSE,'Forward'); + + $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->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)); + + $o->msg = $msg->render(); + $o->tagline = 'Thank you so much for your mail. I love it already.'; + + $o->save(); + + return $o; + } +} \ No newline at end of file diff --git a/config/app.php b/config/app.php index aa05c62..38095dd 100644 --- a/config/app.php +++ b/config/app.php @@ -21,6 +21,8 @@ return [ // Number of messages in a packet that will result in them being queued for processing 'queue_msgs' => env('FIDO_QUEUE_MSGS', 50), 'default_pkt' => env('FIDO_DEFAULT_PACKET', '2+'), + 'areafilefix' => ['areafix','filefix'], + 'areabots' => array_merge(['sbbsecho'],['areafix','filefix']), /* |-------------------------------------------------------------------------- diff --git a/database/migrations/2023_08_02_203857_netmail_forward.php b/database/migrations/2023_08_02_203857_netmail_forward.php new file mode 100644 index 0000000..0a13c1e --- /dev/null +++ b/database/migrations/2023_08_02_203857_netmail_forward.php @@ -0,0 +1,30 @@ +bigInteger('system_id')->nullable(); + $table->foreign('system_id')->references('id')->on('systems'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('users',function (Blueprint $table) { + $table->dropForeign(['system_id']); + $table->dropColumn('system_id'); + }); + } +}; diff --git a/resources/views/user/addedit.blade.php b/resources/views/user/addedit.blade.php index 5be6878..6f7f9ac 100644 --- a/resources/views/user/addedit.blade.php +++ b/resources/views/user/addedit.blade.php @@ -41,6 +41,25 @@ + + +
+ +
+ + + + @error('system_id') + {{ $message }} + @enderror + +
+
@@ -112,13 +131,34 @@ @endsection +@section('page-css') + @css('select2') + + +@append + @section('page-scripts') + @js('select2') + @if($user->id === $o->id) - + @endif + + @append \ No newline at end of file