v1.2.1 introduces configurable access-token expiry and closes a full set of security and data-integrity issues found in audit.
May–June 2026
New Features
- Configurable access-token expiry — A new “Authentication” settings tab lets you choose how long API access tokens remain valid: Never, 1 hour, 6 hours, 1 day, 7 days, or 30 days. Token expiry is now actually enforced on every authenticated request (previously tokens never expired), with a filter available to override the lifetime programmatically.
- Automated update migrations — Database migration hooks now run automatically when the plugin updates, keeping the API’s schema in step without manual steps.
Improvements
- Date and time values in API and webhook payloads now use WordPress locale formatting, with stray whitespace trimmed from joined datetime fields, for cleaner and locale-correct timestamps.
- The
datetime_typefield is now included in the journey-stops response so the documented field actually appears in output. - Webhook request parameters are now sanitised server-side before use.
Security Hardening
This release closes a set of security and data-integrity issues identified in a full audit:
- SQL injection — Hardened the job-filter and job-list queries, and the underlying table-existence and row-delete helpers, against injection.
- Credential exposure — The login endpoint no longer returns the user’s password hash in its successful authentication response.
- Webhook authentication — The Zapier webhook subscribe/unsubscribe endpoints now require authentication.
- Cross-site scripting (XSS) — Fixed unescaped output in the admin job list table columns.
- AJAX protection — Admin AJAX callbacks now enforce nonce and capability checks, and the required nonce is correctly delivered to the client.
- Output escaping & markup — General admin output-escaping hardening and corrected HTML markup in admin and public partials.
- Graceful degradation — Added guards so the API behaves correctly when TransitTeam is inactive.
- Debug log files — Webhook debug log files are now only written when
WP_DEBUGis enabled (and are appended to rather than overwritten), so production installs no longer create or truncate a log file unconditionally.
Bug Fixes
- Fixed webhook/formatter correctness issues: a key collision that overwrote array entries sharing the same key, a
leg_typetypo that corrupted return-leg output, date/time formatters being passed the wrong argument, an undefined-variable return for unknown rate types, and the booking stage rate not rendering (rate vs. job-rate key). - Fixed the jobs route and latest-jobs lookup never returning their data.
- Fixed request-header handling on servers without
apache_request_headers(). - Fixed table detection on multi-instance installs whose table prefix starts with the search term (e.g.
tq_pro4_…), which were previously misdetected as having no TransitQuote Pro tables. - Fixed the job-detail endpoint (
GET /jobs?id=) emitting PHP warnings and a raw database error before the JSON body — caused by missing column aliases and a swapped join key in the surcharge query — which broke JSON parsing on every job-detail request. - Jobs with no journey record (e.g. legacy or incomplete jobs) no longer produce a warning and malformed query in the job-detail response; they now degrade gracefully with empty stops.
- Fixed a PHP 8 type error when numeric job fields and latitude/longitude values were processed for output.
- Fixed corrupted field labels in the quote, waypoint, and job formatters caused by an always-true comparison that stripped
_idfrom every field name. - Fixed the get-quote webhook sending the vehicle list in place of the service list, and hardened webhook job-update sends against undefined-index access and PHP 8 errors.
- Fixed invalid SQL when no sort column was supplied, and a type error when a job had a false/empty date value.
- Single-sourced the purchase-email setting so the configured value is reliably used for updates (previously two different option names were referenced).
- Added the missing
driver_idparameter to the/jobs/update_assignedroute definition, and derived the API route prefix from the configured API base/version instead of a hardcoded path, so custom API base paths are respected. - The REST logout and update-job-status endpoints now return their response to the WordPress REST dispatcher instead of ending the request early, producing proper REST responses.
- API error responses no longer dump request headers or role lists, now return correct 401/403 status codes, and gate debug output behind
WP_DEBUGso it can’t corrupt JSON responses.



