<?php namespace App\Http\Controllers; use Carbon\Carbon; use Illuminate\Http\Request; use Illuminate\Support\Collection; use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Gate; use App\Classes\File; use App\Classes\FTN\{Message,Packet}; use App\Http\Requests\SetupRequest; use App\Models\File as FileModel; use App\Models\{Address,Echomail,Netmail,Setup,System}; class HomeController extends Controller { public function home() { return redirect(Auth::check() ? 'dashboard' : 'about'); } public function file_contents(System $o,string $date) { $f = FileModel::select('files.*') ->distinct() ->leftJoin('file_seenby',['file_seenby.file_id'=>'files.id']) ->where(function($query) use ($o,$date) { return $query ->where('created_at',$date) ->whereIn('fftn_id',$o->addresses->pluck('id')); }) ->Orwhere(function($query) use ($o,$date) { return $query ->where('sent_at',$date) ->whereIn('address_id',$o->addresses->pluck('id')); }) ->get(); return view('widgets.file') ->with('f',$f); } public function packet_contents(System $o,string $packet) { $nm = Netmail::select(['netmails.id','fftn_id','tftn_id','netmails.datetime']) ->leftJoin('netmail_path',['netmail_path.netmail_id'=>'netmails.id']) ->where(function($query) use ($o,$packet) { return $query ->where('sent_pkt',$packet) ->orWhere('netmail_path.recv_pkt',$packet); }) ->get(); $em = Echomail::select(['echomails.id','fftn_id','echoarea_id','msgid','datetime']) ->leftJoin('echomail_seenby',['echomail_seenby.echomail_id'=>'echomails.id']) ->where(function($query) use ($o,$packet) { return $query ->where('sent_pkt',$packet) ->whereIn('echomail_seenby.address_id',$o->addresses->pluck('id')); }) ->union( Echomail::select(['echomails.id','fftn_id','echoarea_id','msgid','datetime']) ->leftJoin('echomail_path',['echomail_path.echomail_id'=>'echomails.id']) ->where(function($query) use ($o,$packet) { return $query ->where('recv_pkt',$packet) ->whereIn('echomail_path.address_id',$o->addresses->pluck('id')); }) ) ->with(['echoarea']) ->get(); return view('widgets.packet') ->with('nm',$nm) ->with('em',$em); } /** * Show a packet dump * * @param Request $request * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View|\Illuminate\Http\RedirectResponse */ public function pkt(Request $request) { $pkt = collect(); $file = NULL; $f = NULL; if ($request->post()) { $request->validate([ 'file' => 'required|filled|min:1', ]); foreach ($request->allFiles() as $key => $filegroup) { if ($key !== 'file') continue; foreach ($filegroup as $file) { try { $f = new File($file); foreach ($f as $packet) $pkt->push([$f->itemName()=>Packet::process($packet,$f->itemName(),$f->itemSize())]); } catch (\Exception $e) { return redirect()->back()->withErrors(sprintf('%s (%s:%d)',$e->getMessage(),$e->getFile(),$e->getLine())); } break; } } } return view('pkt') ->with('file',$f) ->with('filename',$f ? $file->getClientOriginalName() : NULL) ->with('results',$pkt) ->with('hexdump',$file ? hex_dump(file_get_contents($file)) : ''); } /** * Process searching * * @param Request $request * @return Collection */ public function search(Request $request): Collection { $this->middleware('auth'); $result = collect(); list($zone_id,$host_id,$node_id,$point_id,$domain) = sscanf($request->query('term'),'%d:%d/%d.%d@%s'); // Look for Systems foreach (Address::select(['systems.name',DB::raw('systems.id AS system_id'),'zones.zone_id','region_id','host_id','node_id','point_id']) ->join('zones',['zones.id'=>'addresses.zone_id']) ->rightjoin('systems',['systems.id'=>'addresses.system_id']) ->when($zone_id || $host_id || $node_id,function($query) use ($zone_id,$host_id,$node_id) { return $query ->when($zone_id,function($q,$zone_id) { return $q->where('zones.zone_id',$zone_id); }) ->where(function($q) use ($host_id) { return $q ->when($host_id,function($q,$host_id) { return $q->where('region_id',$host_id); }) ->when($host_id,function($q,$host_id) { return $q->orWhere('host_id',$host_id); }); }) ->when($node_id,function($q,$node_id) { return $q->where('node_id',$node_id); }); }) ->orWhere('systems.name','ilike','%'.$request->query('term').'%') ->orWhere('systems.sysop','ilike','%'.$request->query('term').'%') ->OrderBy('systems.name') ->get() as $o) { $ftn = NULL; if ($o->zone_id && ($o->region_id||$o->host_id) && is_numeric($o->node_id) && is_numeric($o->point_id)) $ftn = sprintf('%d:%d/%d.%d',$o->zone_id,$o->host_id ?: $o->region_id,$o->node_id,$o->point_id); $result->push(['id'=>$o->system_id,'name'=>htmlspecialchars($o->name).($ftn ? ' '.$ftn : ''),'value'=>url('system/view',[$o->system_id]),'category'=>'Systems']); } // Look for Echomail foreach (Echomail::select(['id','fftn_id','from']) ->where('msgid','like','%'.$request->query('term').'%') ->orWhere('replyid','like','%'.$request->query('term').'%') ->get() as $o) { $result->push(['id'=>$o->id,'name'=>sprintf('%s (%s)',Message::tr($o->from),$o->fftn->ftn3d),'value'=>url('echomail/view',[$o->id]),'category'=>'Echomail']); } // Look for Netmail if (Gate::check('admin')) foreach (Netmail::select(['id','fftn_id','from']) ->where('msgid','like','%'.$request->query('term').'%') ->orWhere('replyid','like','%'.$request->query('term').'%') ->get() as $o) { $result->push(['id'=>$o->id,'name'=>sprintf('%s (%s)',$o->from,$o->fftn->ftn3d),'value'=>url('netmail/view',[$o->id]),'category'=>'Netmail']); } return $result->unique(['id'])->take(10)->values(); } /** * System Setup * * @note: Protected by Route */ public function setup(SetupRequest $request) { $o = Setup::findOrNew(config('app.id')); if ($request->post()) { if (! $o->exists) $o->id = config('app.id'); $servers = collect(); $options = collect(); $x = collect(); $x->put('options',collect($request->post('binkp'))->sum()); $x->put('port',$request->post('binkp_port')); $x->put('bind',$request->post('binkp_bind')); $x->put('active',(bool)$request->post('binkp_active')); $servers->put('binkp',$x); $x = collect(); $x->put('options',collect($request->post('emsi'))->sum()); $x->put('port',$request->post('emsi_port')); $x->put('bind',$request->post('emsi_bind')); $x->put('active',(bool)$request->post('emsi_active')); $servers->put('emsi',$x); $x = collect(); $x->put('options',collect($request->post('dns'))->sum()); $x->put('port',$request->post('dns_port')); $x->put('bind',$request->post('dns_bind')); $x->put('active',(bool)$request->post('dns_active')); $servers->put('dns',$x); $options->put('options',collect($request->post('options'))->sum()); $options->put('msgs_pkt',$request->post('msgs_pkt')); $o->servers = $servers; $o->options = $options; $o->system_id = $request->post('system_id'); $o->save(); } return view('setup') ->with('o',$o); } /** * Return a list of unsent items * * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View|\Illuminate\Foundation\Application * @see \App\Jobs\AddressIdle:class */ public function status() { $date = Carbon::now()->yesterday()->endOfday(); $r = Address::select([ 'a.id', 'a.system_id', 'a.zone_id', 'addresses.region_id', 'a.host_id', 'a.node_id', 'a.point_id', 'addresses.hub_id', 'addresses.role', DB::raw('sum(a.uncollected_echomail) as uncollected_echomail'), DB::raw('sum(a.uncollected_netmail) as uncollected_netmail'), DB::raw('sum(a.uncollected_files) as uncollected_files') ]) ->from( Address::UncollectedEchomailTotal() ->where('echomails.created_at','<',$this->yesterdayEOD()) ->union(Address::UncollectedNetmailTotal() ->where('netmails.created_at','<',$this->yesterdayEOD()) ) ->union(Address::UncollectedFilesTotal() ->where('files.created_at','<',$this->yesterdayEOD()) ),'a') ->where('systems.active',TRUE) ->where('addresses.active',TRUE) ->where('zones.active',TRUE) ->where('domains.active',TRUE) ->when(! ($x=Auth::user()) || (! $x->isAdmin()),function($query) { return $query->where('domains.public',TRUE); }) ->join('addresses',['addresses.id'=>'a.id']) ->join('systems',['systems.id'=>'a.system_id']) ->join('zones',['zones.id'=>'addresses.zone_id']) ->join('domains',['domains.id'=>'zones.domain_id']) ->ftnOrder() ->groupBy('a.system_id','a.id','a.zone_id','addresses.region_id','a.host_id','a.node_id','a.point_id','addresses.hub_id','addresses.role') ->with(['system','zone.domain']); return view('status') ->with('date',$date) ->with('uncollected',$r->get()); } private function yesterdayEOD(): Carbon { return Carbon::now()->yesterday()->endOfday(); } }