DB::table('pages')->where('published',true)->where('slug','features')->first()]);} public function page(string $slug) {return view('page',['page'=>DB::table('pages')->where('slug',$slug)->where('published',true)->firstOrFail()]);} public function releases() {return view('releases',['releases'=>DB::table('releases')->where('published',true)->latest()->paginate(15)]);} public function account(Request $r) { if(!$r->user()->account_token){$r->user()->forceFill(['account_token'=>(string)Str::uuid()])->save();} return view('account',['licenses'=>DB::table('licenses')->where('user_id',$r->user()->id)->get(),'purchases'=>DB::table('purchases')->where('user_id',$r->user()->id)->latest()->get(),'releases'=>DB::table('releases')->where('published',true)->latest()->get()]); } public function downloadLink(Request $r,int $release) { abort_unless(DB::table('licenses')->where('user_id',$r->user()->id)->where('status','active')->exists(),403); abort_unless(DB::table('releases')->where('id',$release)->where('published',true)->exists(),404); return redirect(URL::temporarySignedRoute('download.file',now()->addMinutes(5),['release'=>$release,'user'=>$r->user()->id])); } public function download(Request $r,int $release,int $user) { abort_unless($r->user()->id===$user && DB::table('licenses')->where('user_id',$user)->where('status','active')->exists(),403); $file=DB::table('releases')->where('id',$release)->where('published',true)->firstOrFail();abort_unless(Storage::disk('local')->exists($file->path),404); return Storage::disk('local')->download($file->path,'Tarnax-'.$file->version.'.'.pathinfo($file->path,PATHINFO_EXTENSION)); } public function consent(Request $r) { $v=$r->validate(['analytics'=>'required|boolean','marketing'=>'required|boolean']);$visitor=$r->cookie('tarnax_visitor');if(!Str::isUuid($visitor??'')){$visitor=(string)Str::uuid();} DB::table('consents')->insert([...$v,'visitor_id'=>$visitor,'user_id'=>$r->user()?->id,'policy_version'=>config('tarnax.consent_version'),'created_at'=>now(),'updated_at'=>now()]); return response()->json(['saved'=>true])->cookie('tarnax_visitor',$visitor,525600,'/',null,$r->isSecure(),true,false,'lax')->cookie('tarnax_consent',json_encode([...$v,'version'=>config('tarnax.consent_version')]),525600,'/',null,$r->isSecure(),false,false,'lax'); } public function export(Request $r) { $data=['profile'=>$r->user()->only('name','email','created_at'),'purchases'=>DB::table('purchases')->where('user_id',$r->user()->id)->get(),'support'=>DB::table('ticket_messages')->where('user_id',$r->user()->id)->get(),'consent'=>DB::table('consents')->where('user_id',$r->user()->id)->get(),'privacy_requests'=>DB::table('privacy_requests')->where('user_id',$r->user()->id)->get()]; return response()->streamDownload(fn()=>print(json_encode($data,JSON_PRETTY_PRINT)),'tarnax-personal-data.json',['Content-Type'=>'application/json']); } public function deletion(Request $r) { DB::table('privacy_requests')->updateOrInsert(['user_id'=>$r->user()->id,'type'=>'deletion','status'=>'pending'],['created_at'=>now(),'updated_at'=>now()]); return back()->with('status','Deletion requested. Support will review retained billing records and respond within the applicable deadline.'); } public function apple(Request $r,AppleVerifier $verifier) { $v=$r->validate(['signed_transaction'=>'required|string|max:25000']);$claims=$verifier->verify($v['signed_transaction'],$r->user()->account_token??''); DB::transaction(function()use($r,$claims){$id='apple:'.$claims['transactionId'];$purchase=DB::table('purchases')->where('transaction_id',$id)->lockForUpdate()->first();abort_if($purchase && $purchase->user_id!==$r->user()->id,403);if(!$purchase){DB::table('purchases')->insert(['user_id'=>$r->user()->id,'provider'=>'apple','transaction_id'=>$id,'status'=>'verified','created_at'=>now(),'updated_at'=>now()]);}}); return back()->with('status','Apple purchase verified. App Store entitlements remain separate from direct licenses.'); } }