Enable netmail forwarding for users that receive messages directed at clrghouz

This commit is contained in:
Deon George 2023-08-02 22:42:59 +10:00
parent b6082b6ae5
commit f281575b15
8 changed files with 243 additions and 40 deletions

View File

@ -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)

View File

@ -0,0 +1,42 @@
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Gate;
use Illuminate\Validation\Rule;
use App\Models\User;
class UserRequest extends FormRequest
{
public function authorize()
{
return Gate::allows( 'admin');
}
public function rules(Request $request)
{
if (! $request->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')),
],
];
}
}

View File

@ -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!

View File

@ -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);

View File

@ -0,0 +1,72 @@
<?php
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\Traits\{MessagePath,PageTemplate};
class NetmailForward extends Netmails
{
use MessagePath,PageTemplate;
private const LOGKEY = 'NNP';
private Address $ao;
private Message $mo;
/**
* Reply to a netmail ping request.
*
* @param Message $mo
* @param Address $ao
*/
public function __construct(Message $mo,Address $ao)
{
parent::__construct();
$this->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;
}
}

View File

@ -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']),
/*
|--------------------------------------------------------------------------

View File

@ -0,0 +1,30 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('users',function (Blueprint $table) {
$table->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');
});
}
};

View File

@ -41,6 +41,25 @@
</span>
</div>
</div>
<!-- Forward Netmail -->
<div class="col-4">
<label for="system_id" class="form-label">Forward Netmails</label>
<div class="input-group has-validation">
<span class="input-group-text"><i class="bi bi-envelope-at-fill"></i></span>
<select style="width: 80%;" class="form-select @error('system_id') is-invalid @enderror" id="system_id" name="system_id" required @cannot('admin',$o)disabled @endcannot>
<option value="">&nbsp;</option>
@foreach ($o->systems as $oo)
<option value="{{ $oo->id }}" @if(old('system_id',$o->system_id)==$oo->id)selected @endif>{{ $oo->name }}</option>
@endforeach
</select>
<span class="invalid-feedback" role="alert">
@error('system_id')
{{ $message }}
@enderror
</span>
</div>
</div>
</div>
<div class="row">
@ -112,13 +131,34 @@
</form>
@endsection
@section('page-css')
@css('select2')
<style>
#content h3 {
margin-bottom: 5px;
}
#content ul li:last-child {
margin-bottom: inherit;
}
</style>
@append
@section('page-scripts')
@js('select2')
@if($user->id === $o->id)
<script>
var tooltipTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="tooltip"]'))
var tooltipList = tooltipTriggerList.map(function (tooltipTriggerEl) {
return new bootstrap.Tooltip(tooltipTriggerEl)
})
</script>
<script>
var tooltipTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="tooltip"]'))
var tooltipList = tooltipTriggerList.map(function (tooltipTriggerEl) {
return new bootstrap.Tooltip(tooltipTriggerEl)
})
</script>
@endif
<script type="text/javascript">
$(document).ready(function() {
$('#system_id').select2();
});
</script>
@append