TransitQuote API v1.2.1

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_type field 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_DEBUG is 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_type typo 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 _id from 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_id parameter to the /jobs/update_assigned route 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_DEBUG so it can’t corrupt JSON responses.