# 15 – Data isolation (who can see whose data)

**Method (local copy of the database, nothing on live was touched, everything the pages wrote was rolled back)**
Instead of clicking, every page was loaded automatically as 15 different logins and every record that reached the answer was checked: *does it belong to this login's company / customer / carrier / assigned user?*

- Logins: company admins (a big company, a medium one, and **an empty one**), staff on **My Data** (2), staff with **All Data** in an empty company, **brand-new empty customers and carriers** (under a company with data and under an empty one), real customers (2) and real carriers (2) with data.
- **Round 1 – every page without an id** (235 pages × 15 logins = 3,500 page loads, incl. AJAX answers) and **Round 2 – every page that takes an id** (582 requests per login) asking for **another company's** orders, quotations, invoices, customers, carriers, users, expenses, drivers, bids, payments …
- The checker found every leak you reported and several you had not found, so it does catch leaks (it was also corrected twice for false alarms – see the bottom).

## Leaks found – all fixed locally, **need upload**

| # | Who could see it | What | Fix |
|---|---|---|---|
| 1 | **Carrier** | *Delivered Orders* listed delivered orders of **every company** (customer, PO, cities). Reported by you; confirmed on live (QA carrier saw Codemeg and Sealink Fleet orders). | Condition moved inside the carrier filter |
| 2 | **Carrier** | *Load Board* listed published loads of **every company** | Only the carrier's own companies (same rule as bidding) |
| 3 | **Customer** | *Dashboard* (and RFQ / quotation lists) showed other people's orders and quotations when the customer had no customer record yet | A customer without a record sees nothing |
| 4 | **Customer, carrier, staff, admin** | Pages `/State`, `/City`, `/country` (meant for the superadmin) opened for every login and listed **other companies' hand-added states / cities and the admin who added them** | Superadmin only |
| 5 | **Customer, carrier** | `/company-trucks/list` (trucks of all the company's carriers) and `/ajax/leads` (CRM lead list) opened for portal logins | Staff only |
| 6 | **Customer** | *Settings* page listed **every company's Custom Brokers and Equipment** | Only the customer's company |
| 7 | **Staff on My Data** | *Main dashboard*: counts, bids and "recent orders" were company-wide | Every figure follows the role's My / All setting |
| 8 | **Staff on My Data** | *Closed Bids* showed approved bids of all customers | My Data limit added |
| 9 | **Staff on My Data** | *Grouped payments* (customer and carrier): the invoices inside a group showed other users' customers; customer filter lists | Company + My Data limit added |
| 10 | **Staff on My Data** | Customer / company **filter and form lists** (Follow Up, Missed Follow-ups, Quotation Leads, Customers, Direct Customers, Rate History, Quotation and Load Board forms, 3 report filters) listed every customer of the company | My Data limit added |
| 11 | **Everyone (public lists)** | States / cities a company added by hand were offered in the drop-downs of **other** companies (`get-states`, `get-cities`, Cities master) | Shown only to the company that added them |

## Result after the fixes

- Round 1: **13 of 15 logins show 0 leaks**; the other two showed only item 11, now fixed and checked.
- Round 2: **0 leaks for all 9 logins tried** (admin of the big company, admin of the empty company, staff on My Data, staff with All Data, new and real customers, new and real carrier). per login about 490–505 of the 582 requests were refused, the rest returned empty pages or harmless lookups.
- A customer or carrier login can no longer open staff pages that return data.

## Still to confirm / not covered

- **Not covered by this test:** actions that **change** data (save, delete, approve) with another company's id – these are guarded by the earlier "record guard" work but were not re-tested here; pages that need two ids or a search text; Excel / CSV downloads.
- **To confirm with you:** carriers see the **customer's phone, email and company name** on their own orders; the customer's **credit limit** and the carrier's **Approved / Rating / Internal notes** can be edited by the customer / carrier themselves (not a leak of other people's data, but company-only fields).
- Some pages crash (error 500) instead of "not found" when given another company's id (about 30 per login) – harmless for privacy.

## False alarms removed from the checker (not leaks)

Partial column lists, old rows whose creator account was deleted (tax / states), and the customer record shown on a carrier's own order.

## Files to upload

`routes/web.php`, `app/Services/DataScope.php`, and in `app/Http/Controllers/`: `LoadOrderController`, `loadRequestController`, `HomeController`, `CustomerController`, `QuotationController`, `CrmController`, `ReportController`, `InvoiceController`, `SettingController`, `MasterManageController`, `Superadmin/CompanyController`. Then `php artisan route:clear` and `php artisan view:clear`.
