Files

126 lines
4.6 KiB
PHP

<?php
namespace App\Http\Livewire;
use App\Models\Transaction;
use App\Models\User;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Session;
use Illuminate\Support\Facades\URL;
use Livewire\Component;
class SingleTransactionTable extends Component
{
public $balance = 0;
public $transaction;
public $qrModalVisible = false;
public $transactionId;
protected $queryString = [
'qrModalVisible' => ['except' => false],
];
public function mount($transactionId)
{
$profile = getActiveProfile();
if (!$profile) {
abort(403, 'No active profile');
}
// CRITICAL SECURITY: Validate user has ownership/access to this profile
// This prevents unauthorized access to transaction statements via session manipulation
\App\Helpers\ProfileAuthorizationHelper::authorize($profile);
// Convert string '1' or 'true' to boolean
$this->qrModalVisible = filter_var($this->qrModalVisible, FILTER_VALIDATE_BOOLEAN);
$this->transactionId = $transactionId;
$this->getTransaction($transactionId);
}
public function getTransaction()
{
$results = Transaction::with([
'accountTo.accountable',
'accountTo.accountable.locations.city.translations',
'accountTo.accountable.locations.division.translations',
'accountTo.accountable.locations.country.translations',
'accountFrom.accountable',
'accountFrom.accountable.locations.city.translations',
'accountFrom.accountable.locations.division.translations',
'accountFrom.accountable.locations.country.translations',
'transactionType',
])->findOrFail($this->transactionId);
$fromType = get_class($results->accountFrom->accountable);
$toType = get_class($results->accountTo->accountable);
$fromId = $results->accountFrom->accountable->id;
$toId = $results->accountTo->accountable->id;
// Check if the user is authorized to view the transaction
if (
!in_array(Session::get('activeProfileType'), [$fromType, $toType]) ||
!in_array(Session::get('activeProfileId'), [$fromId, $toId])
) {
// TODO: redirect to public custom page with more info
abort(403, 'Unauthorized action.');
}
$transaction[] = [
'trans_id' => $results->id,
'amount' => $results->amount,
'from_account' => $results->accountFrom->name,
'from_profile_path' => $results->accountFrom->accountable->profile_url,
'from_profile_name' => $results->accountFrom->accountable->name,
'from_profile_full_name' => $results->accountFrom->accountable->full_name,
'from_profile_location' => $results->accountFrom->accountable->getLocationFirst()['name_short'],
'from_profile_photo' => $results->accountFrom->accountable->profile_photo_path,
'to_account' => $results->accountTo->name,
'to_profile_path' => $results->accountTo->accountable->profile_url,
'to_profile_name' => $results->accountTo->accountable->name,
'to_profile_full_name' => $results->accountTo->accountable->full_name,
'to_profile_location' => $results->accountTo->accountable->getLocationFirst()['name_short'],
'to_profile_photo' => $results->accountTo->accountable->profile_photo_path,
'description' => $results->description,
'type_label' => $results->transactionType->label ?? '',
'type_icon' => $results->transactionType->icon ?? '',
'creator_user' => $results->creator_user_id ? $this->getCreatorUser($results->creator_user_id) : '',
'datetime' => $results->created_at,
];
return Arr::collapse($transaction);
}
public function getCreatorUser($id)
{
// The creator may no longer exist; the view skips an empty creator
$creator = '';
$model = $id ? User::find($id) : null;
if ($model) {
$creator = [
'name' => $model->name,
'full_name' => $model->full_name,
'path' => $model->profile_url,
];
}
return $creator;
}
public function qrModal()
{
$this->qrModalVisible = true;
}
public function render()
{
$this->transaction = $this->getTransaction();
return view('livewire.single-transaction-table');
}
}