|
|
|
@@ -14,7 +14,7 @@ use Illuminate\Support\Facades\Log;
|
|
|
|
|
|
|
|
|
|
use App\Classes\FTN\{Message,Packet};
|
|
|
|
|
use App\Exceptions\InvalidFTNException;
|
|
|
|
|
use App\Traits\{QueryCacheableConfig,ScopeActive};
|
|
|
|
|
use App\Traits\ScopeActive;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* This represents an FTN AKA.
|
|
|
|
@@ -48,7 +48,7 @@ use App\Traits\{QueryCacheableConfig,ScopeActive};
|
|
|
|
|
|
|
|
|
|
class Address extends Model
|
|
|
|
|
{
|
|
|
|
|
use QueryCacheableConfig,ScopeActive,SoftDeletes;
|
|
|
|
|
use ScopeActive,SoftDeletes;
|
|
|
|
|
|
|
|
|
|
private const LOGKEY = 'MA-';
|
|
|
|
|
|
|
|
|
@@ -359,8 +359,8 @@ class Address extends Model
|
|
|
|
|
// We can only work out region/zone if we have a domain - this is for 2D parsing
|
|
|
|
|
if ($matches[5] ?? NULL) {
|
|
|
|
|
$o = new self;
|
|
|
|
|
$o->host_id = $matches[2];
|
|
|
|
|
$o->node_id = $matches[3];
|
|
|
|
|
$o->host_id = (int)$matches[2];
|
|
|
|
|
$o->node_id = (int)$matches[3];
|
|
|
|
|
$o->point_id = empty($matches[4]) ? 0 : (int)$matches[4];
|
|
|
|
|
|
|
|
|
|
if ($matches[1] !== "0") {
|
|
|
|
@@ -469,8 +469,7 @@ class Address extends Model
|
|
|
|
|
->whereNotNull('export_at')
|
|
|
|
|
->whereNull('sent_at')
|
|
|
|
|
->whereNull('echomails.deleted_at')
|
|
|
|
|
->groupBy('addresses.id')
|
|
|
|
|
->dontCache();
|
|
|
|
|
->groupBy('addresses.id');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function scopeUncollectedEchomailTotal($query)
|
|
|
|
@@ -504,8 +503,7 @@ class Address extends Model
|
|
|
|
|
->whereNotNull('export_at')
|
|
|
|
|
->whereNull('sent_at')
|
|
|
|
|
->whereNull('files.deleted_at')
|
|
|
|
|
->groupBy('addresses.id')
|
|
|
|
|
->dontCache();
|
|
|
|
|
->groupBy('addresses.id');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function scopeUncollectedFilesTotal($query)
|
|
|
|
@@ -537,8 +535,7 @@ class Address extends Model
|
|
|
|
|
->whereNull('sent_pkt')
|
|
|
|
|
->whereNull('sent_at')
|
|
|
|
|
->whereNull('netmails.deleted_at')
|
|
|
|
|
->groupBy('addresses.id')
|
|
|
|
|
->dontCache();
|
|
|
|
|
->groupBy('addresses.id');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
@@ -639,7 +636,7 @@ class Address extends Model
|
|
|
|
|
public function nodes_hub(): HasMany
|
|
|
|
|
{
|
|
|
|
|
return $this->hasMany(Address::class,'hub_id','id')
|
|
|
|
|
->select(['id','addresses.zone_id','host_id','node_id','point_id','system_id'])
|
|
|
|
|
->select(['id','addresses.zone_id','region_id','host_id','node_id','point_id','system_id'])
|
|
|
|
|
->active()
|
|
|
|
|
->FTNorder()
|
|
|
|
|
->with([
|
|
|
|
@@ -810,7 +807,7 @@ class Address extends Model
|
|
|
|
|
|
|
|
|
|
public function getIsHostedAttribute(): bool
|
|
|
|
|
{
|
|
|
|
|
return strlen($this->getPassSessionAttribute()) > 0;
|
|
|
|
|
return strlen($this->getPassSessionAttribute() ?: '') > 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function getIsHoldAttribute(): bool
|
|
|
|
@@ -943,60 +940,96 @@ class Address extends Model
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Find the immediate children dependent on this record
|
|
|
|
|
* This is the children of this record, as per normal FTN routing ZC -> RC -> NC -> HUB -> Node -> Point
|
|
|
|
|
*
|
|
|
|
|
* This a ZC would return all records for the Zone,
|
|
|
|
|
* An RC would only return records in the region, etc
|
|
|
|
|
*
|
|
|
|
|
* @return Collection
|
|
|
|
|
* @see self::parent()
|
|
|
|
|
*/
|
|
|
|
|
public function children(): Collection
|
|
|
|
|
{
|
|
|
|
|
// If we are a point, our parent is the boss
|
|
|
|
|
switch ($this->role_id) {
|
|
|
|
|
case self::NODE_NN: // Normal Nodes -> Points
|
|
|
|
|
return $this->nodes_point;
|
|
|
|
|
case self::NODE_NN: // Normal Nodes
|
|
|
|
|
$o = self::active()
|
|
|
|
|
->where('zone_id',$this->zone_id)
|
|
|
|
|
->where('region_id',$this->region_id)
|
|
|
|
|
->where('host_id',$this->host_id)
|
|
|
|
|
->where('node_id',$this->node_id);
|
|
|
|
|
|
|
|
|
|
case self::NODE_HC: // Hubs -> Normal Nodes
|
|
|
|
|
return $this->nodes_hub;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case self::NODE_NC: // Nets -> Normal Nodes, excluding Hub's Nodes
|
|
|
|
|
return $this->nodes_net->diff($this
|
|
|
|
|
->nodes_net
|
|
|
|
|
->filter(function($item) { return $item->role_id === Address::NODE_HC; })
|
|
|
|
|
->transform(function($item) { return $item->children(); })
|
|
|
|
|
->flatten());
|
|
|
|
|
case self::NODE_HC: // Hubs
|
|
|
|
|
$o = self::active()
|
|
|
|
|
->where('zone_id',$this->zone_id)
|
|
|
|
|
->where('region_id',$this->region_id)
|
|
|
|
|
->where('host_id',$this->host_id)
|
|
|
|
|
->where('hub_id',$this->id)
|
|
|
|
|
->where('id','<>',$this->id)
|
|
|
|
|
->get();
|
|
|
|
|
|
|
|
|
|
case self::NODE_RC: // Regions, excluding NC's Nodes
|
|
|
|
|
return $this->nodes_region->diff($this
|
|
|
|
|
->nodes_region
|
|
|
|
|
->filter(function($item) { return $item->role_id === Address::NODE_NC; })
|
|
|
|
|
->transform(function($item) { return $item->nodes_net; })
|
|
|
|
|
->flatten());
|
|
|
|
|
// Need to add in points of this hub's nodes
|
|
|
|
|
return $o->merge(
|
|
|
|
|
self::active()
|
|
|
|
|
->where('zone_id',$this->zone_id)
|
|
|
|
|
->where('region_id',$this->region_id)
|
|
|
|
|
->where('host_id',$this->host_id)
|
|
|
|
|
->whereIn('node_id',$o->pluck('node_id'))
|
|
|
|
|
->where('point_id','<>',0)
|
|
|
|
|
->get()
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
case self::NODE_ZC: // Zones, excluding RC's Nodes
|
|
|
|
|
return $this->nodes_zone->diff($this
|
|
|
|
|
->nodes_zone
|
|
|
|
|
->filter(function($item) { return $item->role_id === Address::NODE_RC; })
|
|
|
|
|
->transform(function($item) { return $item->nodes_region; })
|
|
|
|
|
->flatten());
|
|
|
|
|
case self::NODE_NC: // Nets
|
|
|
|
|
$o = self::active()
|
|
|
|
|
->where('zone_id',$this->zone_id)
|
|
|
|
|
->where('region_id',$this->region_id)
|
|
|
|
|
->where('host_id',$this->host_id);
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case self::NODE_RC: // Regions
|
|
|
|
|
$o = self::active()
|
|
|
|
|
->where('zone_id',$this->zone_id)
|
|
|
|
|
->where('region_id',$this->region_id);
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case self::NODE_ZC: // Zone
|
|
|
|
|
$o = self::active()
|
|
|
|
|
->where('zone_id',$this->zone_id);
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
return new Collection;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return new Collection;
|
|
|
|
|
return $o
|
|
|
|
|
->where('id','<>',$this->id)
|
|
|
|
|
->get();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Find who we should forward mail onto, taking into account session details that we have
|
|
|
|
|
* Contrast to children(), this takes into account authentication details, and we route mail to this
|
|
|
|
|
* address (because we have session details) and it's children.
|
|
|
|
|
*
|
|
|
|
|
* @return Collection
|
|
|
|
|
* @throws \Exception
|
|
|
|
|
* @see self::children()
|
|
|
|
|
* @see self::uplink()
|
|
|
|
|
*/
|
|
|
|
|
public function downlinks(): Collection
|
|
|
|
|
{
|
|
|
|
|
// We have no session data for this address, by definition it has no children
|
|
|
|
|
// We have no session data for this address, (and its not our address), by definition it has no children
|
|
|
|
|
if (! $this->is_hosted && (! our_address()->pluck('id')->contains($this->id)))
|
|
|
|
|
return new Collection;
|
|
|
|
|
|
|
|
|
|
// If this system is not marked to default route for this address
|
|
|
|
|
if (! $this->is_default_route) {
|
|
|
|
|
$children = $this->children();
|
|
|
|
|
$children = $this->children()
|
|
|
|
|
->push($this);
|
|
|
|
|
|
|
|
|
|
// We route everything for this domain
|
|
|
|
|
} else {
|
|
|
|
@@ -1016,15 +1049,17 @@ class Address extends Model
|
|
|
|
|
|
|
|
|
|
// Exclude links and their children.
|
|
|
|
|
$exclude = collect();
|
|
|
|
|
foreach (our_nodes($this->zone->domain)->merge(our_address($this->zone->domain)) as $o) {
|
|
|
|
|
foreach (our_nodes($this->zone->domain)->diff([$this]) as $o) {
|
|
|
|
|
// We only exclude downlink children
|
|
|
|
|
if ($o->role_id < $this->role_id)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
// If this address is in our list, remove it and it's children
|
|
|
|
|
if ($children->contains($o)) {
|
|
|
|
|
$exclude = $exclude->merge($o->children());
|
|
|
|
|
$exclude->push($o);
|
|
|
|
|
}
|
|
|
|
|
$exclude = $exclude->merge($o->children());
|
|
|
|
|
$exclude->push($o);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return $children->filter(function($item) use ($exclude) { return ! $exclude->pluck('id')->contains($item->id);});
|
|
|
|
|
return $children->diff($exclude);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
@@ -1032,6 +1067,7 @@ class Address extends Model
|
|
|
|
|
*
|
|
|
|
|
* @return \Illuminate\Support\Collection
|
|
|
|
|
* @throws \Exception
|
|
|
|
|
* @deprecated use children()
|
|
|
|
|
*/
|
|
|
|
|
public function downstream(): \Illuminate\Support\Collection
|
|
|
|
|
{
|
|
|
|
@@ -1073,11 +1109,10 @@ class Address extends Model
|
|
|
|
|
'origin:id,value',
|
|
|
|
|
'echoarea:id,name,domain_id',
|
|
|
|
|
'echoarea.domain:id,name',
|
|
|
|
|
'fftn:id,zone_id,host_id,node_id,point_id',
|
|
|
|
|
'fftn:id,zone_id,region_id,host_id,node_id,point_id',
|
|
|
|
|
'fftn.zone:id,domain_id,zone_id',
|
|
|
|
|
'fftn.zone.domain:id,name',
|
|
|
|
|
])
|
|
|
|
|
->dontCache();
|
|
|
|
|
]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
@@ -1097,7 +1132,7 @@ class Address extends Model
|
|
|
|
|
->with([
|
|
|
|
|
'filearea:id,name,domain_id',
|
|
|
|
|
'filearea.domain:id,name',
|
|
|
|
|
'fftn:id,zone_id,host_id,node_id,point_id',
|
|
|
|
|
'fftn:id,zone_id,region_id,host_id,node_id,point_id',
|
|
|
|
|
'fftn.zone:id,domain_id,zone_id',
|
|
|
|
|
'fftn.zone.domain:id,name',
|
|
|
|
|
])
|
|
|
|
@@ -1137,7 +1172,7 @@ class Address extends Model
|
|
|
|
|
$role = self::NODE_ZC;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (is_null($role))
|
|
|
|
|
if (isset($this->region_id) && is_null($role))
|
|
|
|
|
Log::alert(sprintf('%s:! Address ROLE [%d] could not be determined for [%s]',self::LOGKEY,($this->role & Address::NODE_ALL),$this->ftn));
|
|
|
|
|
|
|
|
|
|
return $role;
|
|
|
|
@@ -1291,18 +1326,20 @@ class Address extends Model
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Find the immediate parent for this node.
|
|
|
|
|
* Find the immediate parent for this address, as per normal FTN routing ZC <- RC <- NC <- HUB <- Node <- Point
|
|
|
|
|
*
|
|
|
|
|
* @return Address|null
|
|
|
|
|
* @throws \Exception
|
|
|
|
|
* @see self::children()
|
|
|
|
|
*/
|
|
|
|
|
public function parent(): ?Address
|
|
|
|
|
{
|
|
|
|
|
// If we are a point, our parent is the boss
|
|
|
|
|
switch ($this->role_id) {
|
|
|
|
|
case self::NODE_POINT: // BOSS Node
|
|
|
|
|
return Address::active()
|
|
|
|
|
return self::active()
|
|
|
|
|
->where('zone_id',$this->zone_id)
|
|
|
|
|
->where('region_id',$this->region_id)
|
|
|
|
|
->where('host_id',$this->host_id)
|
|
|
|
|
->where('node_id',$this->node_id)
|
|
|
|
|
->where('point_id',0)
|
|
|
|
@@ -1314,16 +1351,17 @@ class Address extends Model
|
|
|
|
|
|
|
|
|
|
// Else fall through
|
|
|
|
|
|
|
|
|
|
case self::NODE_HC: // RC
|
|
|
|
|
return Address::active()
|
|
|
|
|
case self::NODE_HC: // NC
|
|
|
|
|
return self::active()
|
|
|
|
|
->where('zone_id',$this->zone_id)
|
|
|
|
|
->where('region_id',$this->region_id)
|
|
|
|
|
->where('host_id',$this->host_id)
|
|
|
|
|
->where('node_id',0)
|
|
|
|
|
->where('point_id',0)
|
|
|
|
|
->single();
|
|
|
|
|
|
|
|
|
|
case self::NODE_NC: // RC
|
|
|
|
|
return Address::active()
|
|
|
|
|
return self::active()
|
|
|
|
|
->where('zone_id',$this->zone_id)
|
|
|
|
|
->where('region_id',$this->region_id)
|
|
|
|
|
->where('host_id',$this->region_id)
|
|
|
|
@@ -1332,7 +1370,7 @@ class Address extends Model
|
|
|
|
|
->single();
|
|
|
|
|
|
|
|
|
|
case self::NODE_RC: // ZC
|
|
|
|
|
return Address::active()
|
|
|
|
|
return self::active()
|
|
|
|
|
->where('zone_id',$this->zone_id)
|
|
|
|
|
->where('region_id',0)
|
|
|
|
|
->where('node_id',0)
|
|
|
|
@@ -1356,10 +1394,13 @@ class Address extends Model
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Get the appropriate parent for this address, taking into account who we have session information with
|
|
|
|
|
* Contrast to parent(), this takes into account authentication details, and we route mail to this
|
|
|
|
|
* address (because we have session details) with that uplink.
|
|
|
|
|
*
|
|
|
|
|
* @return Address|$this|null
|
|
|
|
|
* @throws \Exception
|
|
|
|
|
* @see self::parent()
|
|
|
|
|
* @see self::downlinks()
|
|
|
|
|
*/
|
|
|
|
|
public function uplink(): ?Address
|
|
|
|
|
{
|
|
|
|
@@ -1371,15 +1412,17 @@ class Address extends Model
|
|
|
|
|
if ($this->is_hosted)
|
|
|
|
|
return $this;
|
|
|
|
|
|
|
|
|
|
// Traverse up our parents until we have one with session details
|
|
|
|
|
if ($x=$this->parent()?->uplink()) {
|
|
|
|
|
return $x;
|
|
|
|
|
|
|
|
|
|
// See if we have a node registered as the default route for this zone
|
|
|
|
|
} else {
|
|
|
|
|
$sz = SystemZone::whereIn('zone_id',$this->domain->zones->pluck('id'))
|
|
|
|
|
->where('default',TRUE)
|
|
|
|
|
->single();
|
|
|
|
|
|
|
|
|
|
return $sz?->system->addresses->sortBy('security')->last();
|
|
|
|
|
return $sz?->system->akas->sortBy('security')->last();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|