A security and repair release. It closes an administrator-escalation path in kiosk mode, removes credentials from the shipped sample company, hardens the login-code flow and the Company Data importer, and brings five broken features back to life. Install the theme first, then the apps. No configuration is required; one Inbox setting is new and off by default. If you loaded the TestCo sample company on any site, read the first Security note.
Security
- TestCo sample company no longer installs credentials. The seed shipped in 1.8.0 through 1.10.1 carried a Web Push signing key, a switch that turned on a web-readable debug log, and password hashes for its 13 demo accounts (one with an administrator-level role). The seed is rebuilt without them, and the loader now gives every demo account its own random password, drops per-install state, refuses to overwrite accounts it did not create (the dry run reports this too), and defaults to a dry run. Reloading on a site that loaded the sample before 1.10.2 recognizes those demo accounts and gives each a new random password. If you loaded the sample before 1.10.2: reset the demo accounts' passwords (or delete them), delete the options
zim_vapid_private_pem,zim_vapid_public_b64andzim_vapid_created_atso Team generates a fresh push keypair, turn off debug capture, and deletewp-content/zorderz-debug.logif it exists (the upgrade removes it). - Kiosk / Demo mode: a guest could become the administrator. The demo
enterroute accepted a request already running as the kiosk account and overwrote the exit PIN, so the person holding the device could set their own PIN and exit into the administrator's session. Enter is now refused while a demo is active or from a switched request. A demo now applies only to the login session that started it, so the administrator's other devices stay administrator; the check fails closed, so missing or altered cookies on the kiosk device never lift it. A demo whose session has ended can be replaced instead of stranding the account, and wrong exit PINs are capped per day as well as per minute. - Login codes. The six-digit code was written to the PHP error log; it no longer is. The start and send-code rate limits keyed on a forwarded header any client can set; they now key on the connecting address, the start limit is counted before the account lookup (so it no longer reveals which addresses have accounts), and one account can have at most three codes sent per ten minutes from any one address (ten in total). Behind a reverse proxy or CDN that does not pass the visitor's address as
REMOTE_ADDR, every visitor now shares one rate-limit bucket; such a site should restore the real client address at the web server, or return a proxy-validated address from thezdz_magic_link_rate_limit_ipfilter. - Company Data import. The tables section accepted any table name, so a crafted bundle could write rows into WordPress' own options, users and user-meta tables. Import now accepts only Zorderz tables (the same rule export uses), only Zorderz post types, and never lets an attachment or post id overwrite a record of another type. Schema markers, migration flags, debug switches and the Web Push keypair no longer travel in either direction, and private-key options (
*_pem, the Web Push key) are treated as secrets. - Self-registration. The register page created a staff account (Field Tech) for anyone who posted the form, and only hid the form when registration was off. The server now refuses unless WordPress' "Anyone can register" is on, assigns WordPress' default role (never a role that can manage the site or users), requires a 12-character password, and limits attempts per address.
- Profile save. Saving your own WordPress profile wiped your app grants, and a staff member could post their own app grants and data-permission overrides. The Zorderz profile fields are now saved only by someone who can edit other users, with the section's nonce.
- Jobs completion gate. A job's creator, including a solo operator, could set their own job straight to Done, skipping the finish photos and the attestation record; finish-photo ids were never checked. The worker now always goes through "mark my part complete" and close-out or attestation, a manager's direct close is recorded as
manager_marked, and only photos uploaded for that job count. - pdf.js upgraded from 3.11.174 to 6.3.289 (CVE-2024-4367, script execution from a crafted PDF). The Estimates PDF import and the Knowledge vault's browser-side extraction both use the vendored copy; the Knowledge vault previously fetched the old version from a CDN at runtime.
- Leads no longer disables TLS verification on its background relay, which carries the token that authorises the background endpoints. Verification is on by default; a host with a self-signed loopback certificate can turn it off through WordPress'
https_local_ssl_verifyfilter. - Debug capture writes to a directory named from the site's salt, with deny rules, instead of the fixed public
wp-content/zorderz-debug.log.
Fixed
- Sketch Pad, Camera and Media work again. Their server hooks were still registered under pre-rename action names, so every save, upload, list and delete failed and camera captures stayed in the offline queue. The old names remain as aliases for one release so queued uploads from an older build still land.
- Inbox mail client is reachable. The folder list now falls back to Inbox and Sent when no folder index exists, so the message list opens. Compose, reply, forward and triage appear when the new Sending & triage setting is on (Settings, Zorderz Inbox) and the user has granted
Mail.SendandMail.ReadWrite; the server enforces the same rule. Nothing is ever sent automatically. - Settings, App Authorizations reported every connection as "not connected" and its connect buttons failed with "plugin is not active". Status and the company Nutshell save now use the Core credential store; the FreshBooks button explains where the connection is made (in-dashboard authorization is not available yet).
- Leads background batches reach the CRM. The pipeline called two methods that did not exist, so no lead was created in the CRM and no batch summary was written. Test batches are never pushed. A fresh install now also gets the full Leads schema (the forward-to-team table and four columns) and the default permission set.
- Safety floors only rise. A filter could lower the Answer Authority thresholds, and a rule fragment could empty a safety rule's triggers or rewrite its title; both are now ignored and logged. The contact card disclosed full details when the asked name was merely a substring of another person's ("Don Lee" for "Brandon Lee"); it now compares whole words, and the shared name matcher treats only an anchored prefix (or a known nickname) as the same first name.
Changed
- Unit tests grow from 19 to 43, adding the import guard, the shipped seed, the safety floors, the AJAX action contract (every action a script posts must be registered), version lockstep, and the seven standalone test scripts, which now run in CI.
- Theme and apps bundle move to 1.10.2 in lockstep.
ZDZ_THEME_VER_FLOORand the apps fallback version are back in step with the headers.
Assets: zorderz-theme-1.10.2.zip and zorderz-apps-1.10.2.zip. Install or upgrade the theme first.