Enable netmail forwarding for users that receive messages directed at clrghouz
This commit is contained in:
parent
b6082b6ae5
commit
f281575b15
@ -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)
|
||||||
|
42
app/Http/Requests/UserRequest.php
Normal file
42
app/Http/Requests/UserRequest.php
Normal 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')),
|
||||||
|
],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
@ -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
|
||||||
{
|
{
|
||||||
@ -124,7 +124,7 @@ class MessageProcess implements ShouldQueue
|
|||||||
// If the message is to a bot, we'll process it
|
// If the message is to a bot, we'll process it
|
||||||
if (! $this->skipbot)
|
if (! $this->skipbot)
|
||||||
foreach (config('process.robots') as $class) {
|
foreach (config('process.robots') as $class) {
|
||||||
if ($processed = $class::handle($this->msg)) {
|
if ($processed=$class::handle($this->msg)) {
|
||||||
$o->flags |= Message::FLAG_RECD;
|
$o->flags |= Message::FLAG_RECD;
|
||||||
$o->save();
|
$o->save();
|
||||||
|
|
||||||
@ -139,20 +139,46 @@ class MessageProcess implements ShouldQueue
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// We'll ignore messages from *fix users
|
if (! $processed) {
|
||||||
if (in_array(strtolower($this->msg->user_from),['filefix','areafix'])) {
|
// Check if the netmail is to a user, with netmail forwarding enabled
|
||||||
$o->flags |= Message::FLAG_RECD;
|
$uo = User::active()
|
||||||
$o->save();
|
->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]',
|
if ($uo && ($ao=$uo->system->match($this->msg->tftn_o->zone)?->pop())) {
|
||||||
self::LOGKEY,
|
$note = "+--[ FORWARDED MESSAGE ]----------------------------------+\r";
|
||||||
$this->msg->msgid,
|
$note .= "+ This message has been forwarded to you, it was originally sent to you\r";
|
||||||
$this->msg->user_from,
|
$note .= sprintf("+ at [%s]\r",$this->msg->tftn_o->ftn);
|
||||||
$this->msg->fftn,
|
$note .= "+---------------------------------------------------------+\r\r";
|
||||||
$o->id,
|
$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!
|
// If not processed, no users here!
|
||||||
|
@ -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);
|
||||||
|
72
app/Notifications/Netmails/NetmailForward.php
Normal file
72
app/Notifications/Netmails/NetmailForward.php
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
@ -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']),
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
|
30
database/migrations/2023_08_02_203857_netmail_forward.php
Normal file
30
database/migrations/2023_08_02_203857_netmail_forward.php
Normal 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');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
@ -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=""> </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,13 +131,34 @@
|
|||||||
</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"]'))
|
||||||
var tooltipList = tooltipTriggerList.map(function (tooltipTriggerEl) {
|
var tooltipList = tooltipTriggerList.map(function (tooltipTriggerEl) {
|
||||||
return new bootstrap.Tooltip(tooltipTriggerEl)
|
return new bootstrap.Tooltip(tooltipTriggerEl)
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
|
<script type="text/javascript">
|
||||||
|
$(document).ready(function() {
|
||||||
|
$('#system_id').select2();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
@append
|
@append
|
Loading…
Reference in New Issue
Block a user