Step 6 of 4712 (security review F17). A subscription kept the UserId sent by
the client, and object events (created, modified, deleted, age) were matched by
record type only, so a user could get record names of types it may not read,
delivered to any address. Now a subscription is created for the caller and an
update cannot move it to another user, unless the caller administers users; and
object events skip subscribers without read rights on the record type.
Checked: Service's subscription asked for SuperUser is saved as its own; with
"customer created" subscriptions, Inventory (no read on customers) got 0 events,
Service 1. Full suite: 109 passed, 5 skipped, the same 2 known failures.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Step 2 of 4712 (security review F13). The customer work-order rights checked
only tag-based feature switches, never which customer a work order belongs to.
New UserBiz.CustomerContactOwnsCustomerAsync (own customer, or for a head
office contact a customer of its head office), used by:
- workorder/customer/{id}: another customer's work order is not found (404);
- customer work order report (-100): exactly one work order, which must be the
contact's (the renderer used every id it was given);
- work order attachment list and download for contacts; other attachment types
are refused to contacts (the customer screens show them only on work orders).
Checked: other customer's work order 404 (was 200); report on another's or on
two work orders not found; own customer report still accepted (202).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Full Chrome 155 would not start under a Linux service user with no writable
home (chrome_crashpad_handler: --database is required). chrome-headless-shell
starts, and measured on a 1 GB droplet is 3-4x faster and smaller per render.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>