toga-ai 1.0.502 → 1.0.503
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
| [Field-Service Dispatch (central / repair orders)](features/field-service-dispatch.md) | The **central** subsystem is TOGa Desk's field-service dispatch domain: repair-order lifecycle, technician scheduling, onsite vs depot service, parts, and shipm | desk/includes/controllers/actions/central/, desk/includes/classes/class.repair.php, desk/includes/classes/class.repairhistory.php, desk/_/browser/datatable/central.php, desk/template/pages/central.php, desk/template/pages/central/view.php, desk/template/modals/central/addTracking.php, library/app/model/togadesk/repairorder.php, library/app/model/togadesk/repairordertracking.php, library/app/api/carrier/ups.php |
|
|
8
8
|
| [Managed Service Order Create Flow (New MSO modal → tickets/add)](features/managed-service-order-create.md) | The **Managed Service Order (MSO) create flow** is how a TOGa Desk user manually creates a managed service order: pick an End User (or a Client Location), choos | desk/includes/controllers/actions/tickets/add.php, desk/template/modals/tickets/addNew.php, desk/template/pages/managed.php, desk/template/pages/getinfo.php, desk/template/footer.php, library/app/model/togadesk/repairorder.php |
|
|
9
9
|
| [Ticket Email Notifications (notifications table)](features/notifications.md) | Which TOGa Desk emails fire for a given client is driven **entirely by data**, not code: the `TOGaDeskSupport.notifications` table holds one row per `(clientid, | desk/includes/classes/class.notification.php, crons/tickets.php, crons/tickets_prod.php |
|
|
10
|
+
| [Per-Client Hostname Restriction (getRestrictedClient)](features/per-client-host-restriction.md) | TOGa Desk supports **per-client branded URLs** (e.g. | desk/includes/functions.php, desk/template/header.php, _/browser/datatable/tickets, desk/includes/classes/class.ticket.php, ebs/setup_phpini.php, ebs/http_to_https.php, desk/template/modals/kb/viewDocument.php, desk/template/modals/files/aws-view.php, desk/template/modals/files/contract-view.php, template/pages/documents/view.php, template/pages/tasks/view.php |
|
|
10
11
|
| [REST API (RPC-over-POST) & API-Key Auth](features/rest-api.md) | TOGa Desk exposes a programmatic API at `desk/api/`. | desk/api/index.php, desk/api/resources/tickets.php, desk/api/resources/assets.php, desk/api/resources/authenticate.php, desk/includes/classes/class.apikey.php, desk/includes/functions.php |
|
|
11
12
|
| [SMB Contract Editing & the clientMspId Corruption Trap](features/smb-contract-editing.md) | The SMB contracts page (`/desk/?route=toga/smbcontracts&togaClientId=<id>`) edits `TOGA_*.SMBContracts` rows via a modal. | desk/template/modals/toga/smbcontracts/smbContract.php, desk/includes/controllers/modals/toga/smbcontracts/smbContract.php, desk/includes/controllers/actions/toga/smbcontracts/smbContract.php, desk/includes/controllers/actions/toga/smbcontracts/edit.php |
|
|
12
13
|
| [Ticket Lifecycle (class.ticket.php)](features/ticket-lifecycle.md) | All TOGa Desk ticket creation and reply handling funnels through `Ticket` in `desk/includes/classes/class.ticket.php`. | desk/includes/classes/class.ticket.php, desk/includes/controllers/actions.php, desk/includes/controllers/actions/tickets/addReply.php, desk/api/resources/tickets.php, desk/api/resources/ticket_replies.php, crons/tickets.php, crons/pipe.php, desk/includes/controllers/actions/tickets/merge.php |
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Per-Client Hostname Restriction (getRestrictedClient)
|
|
3
|
+
framework: "1.0"
|
|
4
|
+
repo: togadesk
|
|
5
|
+
project: TOGa Desk
|
|
6
|
+
client: shared
|
|
7
|
+
type: feature
|
|
8
|
+
status: active
|
|
9
|
+
updated: 2026-08-04
|
|
10
|
+
owners: ["mhammontree"]
|
|
11
|
+
files:
|
|
12
|
+
- desk/includes/functions.php
|
|
13
|
+
- desk/template/header.php
|
|
14
|
+
- _/browser/datatable/tickets
|
|
15
|
+
- desk/includes/classes/class.ticket.php
|
|
16
|
+
- ebs/setup_phpini.php
|
|
17
|
+
- ebs/http_to_https.php
|
|
18
|
+
- desk/template/modals/kb/viewDocument.php
|
|
19
|
+
- desk/template/modals/files/aws-view.php
|
|
20
|
+
- desk/template/modals/files/contract-view.php
|
|
21
|
+
- template/pages/documents/view.php
|
|
22
|
+
- template/pages/tasks/view.php
|
|
23
|
+
related:
|
|
24
|
+
- ../architecture.md
|
|
25
|
+
- ../../togaview/architecture.md
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## Summary
|
|
29
|
+
|
|
30
|
+
TOGa Desk supports **per-client branded URLs** (e.g. `rumcsi.togadesk.togatech.com`). The whole
|
|
31
|
+
mechanism is host-based: `getRestrictedClient()` in `desk/includes/functions.php` (~L1513-1592)
|
|
32
|
+
derives a single "restricted client" from the request hostname, and `restrictByClient()` (L1508)
|
|
33
|
+
is the gate used throughout the UI. Adding a new per-client URL is therefore **one switch case
|
|
34
|
+
plus a lot of non-application work** (cert, sessions, hardcoded legacy domains).
|
|
35
|
+
|
|
36
|
+
This contradicts the impression that togadesk has no host-based logic — it does, and this is the
|
|
37
|
+
only place a new subdomain gets registered.
|
|
38
|
+
|
|
39
|
+
## How it works
|
|
40
|
+
|
|
41
|
+
1. `getRestrictedClient()` lowercases `$_SERVER['HTTP_HOST']`, strips the port, and matches a long
|
|
42
|
+
**hardcoded switch of per-client subdomains**, returning a `CLIENT_*` constant or `null`.
|
|
43
|
+
2. Client-ID constants are defined in the same file (~L1488-1506):
|
|
44
|
+
`CLIENT_AGILANT=2`, `CLIENT_OFFICEDEPOT=3`, `CLIENT_RUMCSI=146`, `CLIENT_IMHOUSTON=167`,
|
|
45
|
+
`CLIENT_FORDHAM=179`.
|
|
46
|
+
3. `restrictByClient()` (L1508) wraps that result and gates:
|
|
47
|
+
- navigation/menus in `desk/template/header.php` (~L1638-1665), and
|
|
48
|
+
- the ticket datatables under `_/browser/datatable/tickets/*`.
|
|
49
|
+
4. Post-login data filtering keys off the **session `clientid`**, not the host — the host
|
|
50
|
+
restriction is a UI/entry gate, not the record-level tenancy boundary.
|
|
51
|
+
|
|
52
|
+
**TOGa View resolves its host separately.** `togaview/_/app/framework.php` has its own
|
|
53
|
+
`switch($_SERVER['HTTP_HOST'])` that sets `$_SESSION['stylePath']` and selects the RUMCSI SAML
|
|
54
|
+
branch; an unregistered hostname falls through to default branding and **skips SAML**. So a
|
|
55
|
+
togadesk-side DNS record is safe on its own, but any new *togaview* hostname must be added there
|
|
56
|
+
too. _(Carried from the togaview architecture doc — not re-verified in code on 2026-08-04.)_
|
|
57
|
+
|
|
58
|
+
## Adding a new per-client TOGa Desk URL — checklist
|
|
59
|
+
|
|
60
|
+
The app code is the easy part. What actually bites:
|
|
61
|
+
|
|
62
|
+
- **Register the host** in the `getRestrictedClient()` switch (and add a `CLIENT_*` constant if the
|
|
63
|
+
client is new). Verified 2026-08-04: `rumcsi.togadesk.togatech.com` is **already a case**, so the
|
|
64
|
+
RUMCSI AWS DNS record needs no code change.
|
|
65
|
+
- **TLS cert.** A 4-label host such as `rumcsi.togadesk.togatech.com` is **not** covered by a
|
|
66
|
+
`*.togatech.com` wildcard. You need `*.togadesk.togatech.com` or an exact SAN on the ALB
|
|
67
|
+
listener, plus a host-header rule.
|
|
68
|
+
- **Sessions log everyone out on a domain change.** `ebs/setup_phpini.php` sets
|
|
69
|
+
`session.save_handler=rediscluster` but sets **no `session.cookie_domain`**, and there is no
|
|
70
|
+
`session_set_cookie_params()` anywhere — the cookie is host-scoped. Worse, `people.sessionid` is a
|
|
71
|
+
**single column**, so logging in on a second domain invalidates the session on the first.
|
|
72
|
+
- **Smoke-test Office document previews.** `desk/template/modals/kb/viewDocument.php`,
|
|
73
|
+
`modals/files/aws-view.php`, `modals/files/contract-view.php`, `template/pages/documents/view.php`
|
|
74
|
+
and `template/pages/tasks/view.php` embed `https://{HTTP_HOST}/...` into third-party viewers
|
|
75
|
+
(`docs.google.com/gview`, `view.officeapps.live.com`) which fetch **server-side**. On a host with
|
|
76
|
+
an untrusted cert, Word/Excel/PPT previews fail **silently** while same-origin PDF iframes still
|
|
77
|
+
work — making this the best post-cutover check.
|
|
78
|
+
- **Keep the old domain resolvable.** `class.ticket.php` L485-486 and L886-887 hardcode
|
|
79
|
+
`https://togadesk[-env].agilantsolutions.com/uploads/` when rewriting inline ticket images, so
|
|
80
|
+
outbound ticket emails keep serving images from the old domain. Other hardcoded legacy domains:
|
|
81
|
+
`csat.agilantsolutions.com`, `toga.agilantsolutions.com`,
|
|
82
|
+
`yourcloudhq.togaview.agilantsolutions.com`, and `toga_payment_easyurl` / `fullurl` in every
|
|
83
|
+
`config.*.ini`.
|
|
84
|
+
|
|
85
|
+
## Gotchas / known issues
|
|
86
|
+
|
|
87
|
+
- **Cross-tenant login hole (pre-existing, NOT fixed — deserves its own ticket).** The
|
|
88
|
+
password-login access condition in `desk/includes/functions.php` (~L627-631) is a chain of ORs,
|
|
89
|
+
and two clauses grant access **regardless of which client's subdomain is in use**:
|
|
90
|
+
`getRestrictedClient() != CLIENT_AGILANT && $restrictedClientId == CLIENT_IMHOUSTON` lets an IM
|
|
91
|
+
Houston user log in on the RUMCSI host, and
|
|
92
|
+
`getRestrictedClient() != CLIENT_FORDHAM && $restrictedClientId == CLIENT_FORDHAM` does the same
|
|
93
|
+
for Fordham. Post-login filtering keys off the session `clientid`, so it is not an immediate
|
|
94
|
+
record leak, but it **defeats the per-client URL restriction and contradicts the comment directly
|
|
95
|
+
above it** (L627-629). Recommended fix: replace with an explicit per-restricted-client allowlist
|
|
96
|
+
using guard clauses. Anyone touching login or adding a client URL must know this.
|
|
97
|
+
- **`siteURL()` emits `http://` behind the ALB.** `desk/includes/functions.php` (~L22-31) only emits
|
|
98
|
+
`https` when `$_SERVER['HTTPS'] == 'on'`; behind the ALB only `X-Forwarded-Proto` is set (see
|
|
99
|
+
`ebs/http_to_https.php`). It currently has **no callers** in togadesk — a latent trap for any new
|
|
100
|
+
absolute-link code.
|
|
101
|
+
- The host switch and the client-ID constants are hardcoded — there is no DB-driven mapping, so
|
|
102
|
+
every new branded URL is a code change.
|
|
103
|
+
|
|
104
|
+
## Change history
|
|
105
|
+
|
|
106
|
+
- 2026-08-04 — Documented from a read-only review (TRUE-80139) of the RUMCSI branded-URL cutover;
|
|
107
|
+
recorded the add-a-hostname checklist and the cross-tenant login hole. No code changed. (mhammontree)
|
package/knowledge/INDEX.md
CHANGED
|
@@ -8,7 +8,7 @@ _Auto-generated by `knowledge.js index`. Do not hand-edit._
|
|
|
8
8
|
- **worker** (Worker) — 18 doc(s) → [1.0/apps/worker/INDEX.md](1.0/apps/worker/INDEX.md)
|
|
9
9
|
- **dbchanges** (Database Changes) _(framework core)_ — 1 doc(s) → [1.0/apps/dbchanges/INDEX.md](1.0/apps/dbchanges/INDEX.md)
|
|
10
10
|
- **worker1.5** (Worker 1.5) — 0 doc(s) → [1.0/apps/worker1.5/INDEX.md](1.0/apps/worker1.5/INDEX.md)
|
|
11
|
-
- **togadesk** (TOGa Desk) —
|
|
11
|
+
- **togadesk** (TOGa Desk) — 11 doc(s) → [1.0/apps/togadesk/INDEX.md](1.0/apps/togadesk/INDEX.md)
|
|
12
12
|
- **togaview** (TOGa View) — 6 doc(s) → [1.0/apps/togaview/INDEX.md](1.0/apps/togaview/INDEX.md)
|
|
13
13
|
- **webhook** (Webhook) — 1 doc(s) → [1.0/apps/webhook/INDEX.md](1.0/apps/webhook/INDEX.md)
|
|
14
14
|
- **walmarttechservices** (Walmart Tech Services) — 1 doc(s) → [1.0/apps/walmarttechservices/INDEX.md](1.0/apps/walmarttechservices/INDEX.md)
|
|
@@ -56,6 +56,7 @@ _Auto-generated by `knowledge.js index`. Do not hand-edit._
|
|
|
56
56
|
- **Prudential Financial** (`prudential`) → [clients/prudential/INDEX.md](clients/prudential/INDEX.md)
|
|
57
57
|
- **Quad Graphics** (`quad`) → [clients/quad/INDEX.md](clients/quad/INDEX.md)
|
|
58
58
|
- **Rate** (`rate`) → [clients/rate/INDEX.md](clients/rate/INDEX.md)
|
|
59
|
+
- **Richmond University Medical Center** (`rumcsi`) → [clients/rumcsi/INDEX.md](clients/rumcsi/INDEX.md)
|
|
59
60
|
- **Tow Foundation** (`tow-foundation`) → [clients/tow-foundation/INDEX.md](clients/tow-foundation/INDEX.md)
|
|
60
61
|
- **TOGA Technology** (`true`) → [clients/true/INDEX.md](clients/true/INDEX.md)
|
|
61
62
|
- **Walmart Client Profile** (`walmart`) → [clients/walmart/INDEX.md](clients/walmart/INDEX.md)
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
# Client: Richmond University Medical Center `rumcsi`
|
|
2
|
+
|
|
3
|
+
| Doc | Framework | Summary | Files |
|
|
4
|
+
|-----|-----------|---------|-------|
|
|
5
|
+
| [Richmond University Medical Center](profile.md) | 1.0 | Richmond University Medical Center (**RUMCSI**) is a framework **1.0** client served by **TOGa Desk** (staff/analyst side) and **TOGa View** (client portal). | |
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Richmond University Medical Center"
|
|
3
|
+
framework: "1.0"
|
|
4
|
+
apps:
|
|
5
|
+
- togadesk
|
|
6
|
+
- togaview
|
|
7
|
+
- library
|
|
8
|
+
project: TOGa Desk
|
|
9
|
+
client: rumcsi
|
|
10
|
+
type: profile
|
|
11
|
+
status: active
|
|
12
|
+
updated: 2026-08-04
|
|
13
|
+
owners: ["mhammontree"]
|
|
14
|
+
files: []
|
|
15
|
+
related:
|
|
16
|
+
- ../../1.0/apps/togadesk/features/per-client-host-restriction.md
|
|
17
|
+
- ../../1.0/apps/togadesk/architecture.md
|
|
18
|
+
- ../../1.0/apps/togaview/architecture.md
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## Summary
|
|
22
|
+
|
|
23
|
+
Richmond University Medical Center (**RUMCSI**) is a framework **1.0** client served by
|
|
24
|
+
**TOGa Desk** (staff/analyst side) and **TOGa View** (client portal). Its TOGa Desk
|
|
25
|
+
`clients.clientId` is **146**, exposed in code as the constant `CLIENT_RUMCSI` in
|
|
26
|
+
`desk/includes/functions.php`.
|
|
27
|
+
|
|
28
|
+
## Platform footprint
|
|
29
|
+
|
|
30
|
+
- **Branded per-client URL.** RUMCSI is one of the clients gated by TOGa Desk's host-based
|
|
31
|
+
restriction: `rumcsi.togadesk.togatech.com` is already a case in `getRestrictedClient()`, which
|
|
32
|
+
returns `CLIENT_RUMCSI` and drives `restrictByClient()` nav/menu and ticket-datatable scoping.
|
|
33
|
+
See [Per-client hostname restriction](../../1.0/apps/togadesk/features/per-client-host-restriction.md)
|
|
34
|
+
for the full add-a-hostname checklist (cert scope, host-scoped sessions, hardcoded legacy domains).
|
|
35
|
+
- **TOGa View SAML.** `togaview/_/app/framework.php` has a RUMCSI-specific host branch that selects
|
|
36
|
+
branding (`$_SESSION['stylePath']`) and the SAML login path — an unregistered togaview hostname
|
|
37
|
+
falls through to default branding and skips SAML.
|
|
38
|
+
- **Hardcoded client-ID branching.** RUMCSI appears in TOGa Desk's hardcoded client-ID branching
|
|
39
|
+
(`central` dispatch, `tickets/add`) — verify the RUMCSI arm before changing shared logic.
|
|
40
|
+
|
|
41
|
+
## Change history
|
|
42
|
+
|
|
43
|
+
- 2026-08-04 — Client profile created during the TRUE-80139 read-only review of the RUMCSI branded
|
|
44
|
+
TOGa Desk URL. (mhammontree)
|
package/package.json
CHANGED