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); } }