Files
BarangaySystem/app/Http/Controllers/Admin/PosAccessKeyController.php
2026-06-06 18:43:00 +08:00

175 lines
6.0 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Helpers\ResponseHelper;
use App\Models\Market\PosAccessKey;
use App\Models\Market\Store;
use App\Models\User;
use Hypervel\Http\Request;
use Hypervel\Support\Facades\Auth;
use Hyperf\Stringable\Str;
use App\Http\Controllers\Helpers\Permissions\UserPermissions;
use App\Enums\UserActions;
class PosAccessKeyController
{
/**
* List POS access keys. Auto-expires any past-due keys first.
* - Ultimate/super operator/operator: see all keys
* - Store owner/manager: see keys for stores they own or manage
*/
public function index(Request $request)
{
if (!UserPermissions::isActionPermitted(Auth::user()->acct_type, UserActions::ViewPosAccessKeys)) {
return ResponseHelper::returnUnauthorized();
}
// Auto-deactivate any expired keys
PosAccessKey::autoExpire();
$user = Auth::user();
$acctType = $user->acct_type->value ?? $user->acct_type ?? '';
// Ultimate, Super Operator, and Operator see everything
if (in_array($acctType, ['ult', 'super operator', 'operator'])) {
$query = PosAccessKey::with(['store:id,name,hashkey,owner_id', 'store.owner:id,name,nickname,hashkey'])
->orderBy('id', 'desc');
} else {
// Non-ultimate users see their own and their descendants' stores' keys
$descendants = $user->getAllDescendants();
$descendantIds = $descendants->pluck('id')->push($user->id)->toArray();
$storeIds = Store::whereIn('owner_id', $descendantIds)
->orWhereIn('manager_id', $descendantIds)
->pluck('id')
->toArray();
$query = PosAccessKey::with(['store:id,name,hashkey,owner_id', 'store.owner:id,name,nickname,hashkey'])
->whereIn('store_id', $storeIds)
->orderBy('id', 'desc');
}
$keys = $query->get();
return ResponseHelper::returnSuccessResponse($keys, 'pos_access_keys');
}
public function store(Request $request)
{
if (!UserPermissions::isActionPermitted(Auth::user()->acct_type, UserActions::CreatePosAccessKey)) {
return ResponseHelper::returnUnauthorized();
}
$validated = $request->validate([
'name' => 'required|string|max:255',
'store_hash' => 'required|string',
'expires_at' => 'nullable|string',
]);
$store = Store::where('hashkey', $validated['store_hash'])->first();
if (!$store) {
return ResponseHelper::returnError('Store not found', 404);
}
$user = Auth::user();
$acctType = $user->acct_type->value ?? $user->acct_type ?? '';
if (!in_array($acctType, ['ult', 'super operator', 'operator'])) {
$descendants = $user->getAllDescendants();
$allowedIds = $descendants->pluck('id')->push($user->id)->toArray();
if (!in_array($store->owner_id, $allowedIds) && !in_array($store->manager_id, $allowedIds)) {
return ResponseHelper::returnError('Unauthorized to create keys for this store', 403);
}
}
$data = [
'access_key' => 'PK-' . Str::upper(Str::random(16)),
'store_id' => $store->id,
'name' => $validated['name'],
'created_by' => Auth::id(),
'status' => 'active',
];
// Set expiry if provided
if (!empty($validated['expires_at'])) {
$data['expires_at'] = $validated['expires_at'];
}
$key = PosAccessKey::create($data);
return ResponseHelper::returnSuccessResponse($key, $key->hashkey, 'POS Access Key created');
}
public function destroy(Request $request)
{
if (!UserPermissions::isActionPermitted(Auth::user()->acct_type, UserActions::DeletePosAccessKey)) {
return ResponseHelper::returnUnauthorized();
}
$hashkey = $request->input('target');
$key = PosAccessKey::with('store')->where('hashkey', $hashkey)->first();
if (!$key) {
return ResponseHelper::returnError('Key not found', 404);
}
if (!$this->userOwnsKeyStore($key)) {
return ResponseHelper::returnError('Unauthorized to delete this key', 403);
}
$key->delete();
return ResponseHelper::returnSuccessResponse([], $hashkey, 'Key deleted');
}
public function toggleStatus(Request $request)
{
if (!UserPermissions::isActionPermitted(Auth::user()->acct_type, UserActions::TogglePosAccessKey)) {
return ResponseHelper::returnUnauthorized();
}
$hashkey = $request->input('target');
$key = PosAccessKey::with('store')->where('hashkey', $hashkey)->first();
if (!$key) {
return ResponseHelper::returnError('Key not found', 404);
}
if (!$this->userOwnsKeyStore($key)) {
return ResponseHelper::returnError('Unauthorized to modify this key', 403);
}
$key->status = $key->status === 'active' ? 'inactive' : 'active';
$key->save();
return ResponseHelper::returnSuccessResponse($key, $hashkey, 'Status updated');
}
/**
* Ownership gate shared by destroy/toggleStatus: Big 3 always pass;
* everyone else must own or manage (directly or via descendants) the
* store the key belongs to.
*/
private function userOwnsKeyStore(PosAccessKey $key): bool
{
$user = Auth::user();
if (!$user) {
return false;
}
$acctType = $user->acct_type->value ?? $user->acct_type ?? '';
if (in_array($acctType, ['ult', 'super operator', 'operator'])) {
return true;
}
$store = $key->store;
if (!$store) {
return false;
}
$allowedIds = $user->getAllDescendants()->pluck('id')->push($user->id)->toArray();
return in_array($store->owner_id, $allowedIds) || in_array($store->manager_id, $allowedIds);
}
}