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\Auth;
use Illuminate\Support\Facades\Validator; use Illuminate\Support\Facades\Validator;
use App\Http\Requests\UserRequest;
use App\Models\{Address,User}; use App\Models\{Address,User};
class UserController extends Controller class UserController extends Controller
@ -14,25 +15,10 @@ class UserController extends Controller
/** /**
* Add or edit a node * Add or edit a node
*/ */
public function add_edit(Request $request,User $o) public function add_edit(UserRequest $request,User $o)
{ {
if ($request->post()) { if ($request->post()) {
$this->authorize('admin',$o); foreach (['name','email','pgp_pubkey','active','admin','alias','system_id'] as $key)
$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)
$o->{$key} = $request->post($key); $o->{$key} = $request->post($key);
if (! $o->exists) 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 Illuminate\Support\Facades\Notification;
use App\Classes\FTN\Message; use App\Classes\FTN\Message;
use App\Models\{Address,Echoarea,Echomail,Netmail,Setup}; use App\Models\{Address,Echoarea,Echomail,Netmail,Setup,User};
use App\Notifications\Netmails\{EchoareaNotExist,EchoareaNotSubscribed,EchoareaNoWrite,Reject}; use App\Notifications\Netmails\{EchoareaNotExist,EchoareaNotSubscribed,EchoareaNoWrite,NetmailForward,Reject};
class MessageProcess implements ShouldQueue class MessageProcess implements ShouldQueue
{ {
@ -139,8 +139,33 @@ class MessageProcess implements ShouldQueue
} }
} }
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();
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;
// 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 // We'll ignore messages from *fix users
if (in_array(strtolower($this->msg->user_from),['filefix','areafix'])) { } elseif (in_array(strtolower($this->msg->user_from),config('app.areabots'))) {
$o->flags |= Message::FLAG_RECD; $o->flags |= Message::FLAG_RECD;
$o->save(); $o->save();
@ -154,6 +179,7 @@ class MessageProcess implements ShouldQueue
$processed = TRUE; $processed = TRUE;
} }
}
// If not processed, no users here! // If not processed, no users here!
if (! $processed) { if (! $processed) {

View File

@ -8,7 +8,7 @@ use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable; use Illuminate\Notifications\Notifiable;
use Laravel\Sanctum\HasApiTokens; use Laravel\Sanctum\HasApiTokens;
use App\Traits\UserSwitch; use App\Traits\{ScopeActive,UserSwitch};
/** /**
* Class User * Class User
@ -26,7 +26,7 @@ use App\Traits\UserSwitch;
*/ */
class User extends Authenticatable implements MustVerifyEmail class User extends Authenticatable implements MustVerifyEmail
{ {
use HasFactory,Notifiable,HasApiTokens,UserSwitch; use HasFactory,Notifiable,HasApiTokens,UserSwitch,ScopeActive;
/** /**
* The attributes that are mass assignable. * The attributes that are mass assignable.
@ -61,6 +61,11 @@ class User extends Authenticatable implements MustVerifyEmail
/* RELATIONS */ /* RELATIONS */
public function system()
{
return $this->belongsTo(System::class);
}
public function systems() public function systems()
{ {
return $this->belongsToMany(System::class); 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 // Number of messages in a packet that will result in them being queued for processing
'queue_msgs' => env('FIDO_QUEUE_MSGS', 50), 'queue_msgs' => env('FIDO_QUEUE_MSGS', 50),
'default_pkt' => env('FIDO_DEFAULT_PACKET', '2+'), '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> </span>
</div> </div>
</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>
<div class="row"> <div class="row">
@ -112,7 +131,22 @@
</form> </form>
@endsection @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') @section('page-scripts')
@js('select2')
@if($user->id === $o->id) @if($user->id === $o->id)
<script> <script>
var tooltipTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="tooltip"]')) var tooltipTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="tooltip"]'))
@ -121,4 +155,10 @@
}) })
</script> </script>
@endif @endif
<script type="text/javascript">
$(document).ready(function() {
$('#system_id').select2();
});
</script>
@append @append