Releases: trustedlogin/client
1.10.1
A small patch release. The customer-facing change is a fix for a fatal error on PHP 7.4 sites when viewing the SDK's debug-log admin page.
🛠 Fixed
- Fix
Call to undefined function str_starts_with()fatal on PHP 7.4 when the SDK debug log admin page builds its log download URL.str_starts_with()is a PHP 8.0 function; replaced with the 7.4-compatible equivalent.
🚀 Added
- New
trustedlogin/{namespace}/in_local_developmentfilter for advanced testing scenarios where the SDK's lockdown / brute-force checks need to fire even thoughWP_ENVIRONMENT_TYPEreportslocalordevelopment. Documented in the Client hooks reference under "Advanced Internal Use Only".
1.10.0
When a support agent's access link doesn't work — expired, revoked, or blocked — they now see a clear explanation of what happened, and you see the failed attempt logged in the Connector plugin on your site. Previously, agents landed on the customer's login page without any signal why login failed.
You can now register the webhook URL in your TrustedLogin dashboard and have customer sites pick it up automatically, without needing to update the configuration code. Plus a security hardening pass on webhook delivery, a new reachability check on the Grant Access screen, and several capability and multisite fixes.
🚀 Added
- Failed support logins now post back to the TrustedLogin service so you get a record of failed logins.
- A standalone "Support login could not complete" page that renders on the customer site when the round-trip can't complete — for example, the support service is unreachable, or the redirect target isn't a URL you've allowlisted. Includes a "Go back" link that safely returns the agent to the surface they came from.
- A reachability check on the Grant Access screen — when the customer site can't reach your support site (firewall intercept, misconfigured installation, network failure), the grant button is replaced with a clear error banner, a "Contact support" button, and a "Try reconnecting" link.
- Friendlier feedback after the redirect: agents who hit an expired, revoked, or blocked access key now see an explanation instead of a silent no-op landing page. A success banner appears in wp-admin on a successful grant, and an info notice (with display name) shows when an already-signed-in user hits their own access link.
- Adds support for the new Gravity Forms field integration in Connector 1.5.0: the grant popup now posts
grant/extend/revokeevents back to its opener along with the support user's expiration date, so the field can update its displayed access status in real time without polling. - Customer sites can now pull the webhook URL from your TrustedLogin dashboard automatically — update it in the dashboard and customer sites use the new value on the next event, with no plugin update required.
- Per-namespace audit-log opt-out so vendors managing multiple TrustedLogin integrations on the same site can disable the audit log for one without affecting the others. See the Client hooks reference for the constant name.
- New optional
vendor/public_key_fingerprintConfig setting that lets you pin your encryption key, defending against substitution attacks if a customer site is tricked into talking to a different host. - New filter
trustedlogin/{namespace}/login_feedback/allowed_referer_urlsso support tools that span multiple domains (marketing site, help portal, white-label domains) can be added to the allowlist for the post-redirect "Go back" link. See the Client hooks reference. - New filter
trustedlogin/{namespace}/webhook/request_args, giving you full control over headers and body shape sent to the webhook URL.
🛠 Changed
- Customer-facing error messages on the Grant Access screen have all been rewritten to drop internal product names and tell the customer what to do next instead.
- The
caps/addandcaps/removesettings now accept both list (['edit_posts']) and associative (['edit_posts' => 'reason']) array shapes. Previously the list shape silently failed to add or remove the configured capability. - The support role is now reconciled against the current
capsconfiguration on each grant. Previously, once the role had been created, subsequent changes tocaps/addorcaps/removewere ignored until the role was deleted. - Creating a second support user with the same
vendor/emailnow returnsWP_Error('email_exists')unless the email contains the{hash}placeholder. Prevents accidental session-rebind on email collision. Client::revoke_access()returnstrueonce the local cleanup completes, regardless of whether the support-side sync succeeded. Failed syncs are automatically retried with backoff so the support-side record eventually drops without blocking the admin's revoke action on transient errors.- On WordPress multisite, deleting a support user now removes them from the network user table as well as per-site usermeta. Previously the per-site delete ran but the network-level cleanup didn't, leaving an orphan record that collided with subsequent grants on the same email.
- The grant button on the Grant Access screen now renders as a real
<button>element so the browser's nativedisabledattribute prevents a rapid double-click from minting two support users. - Transient rows are no longer autoloaded by WordPress, so Client SDK transients no longer pay the cost of being loaded on every page request.
- Webhook URLs are now treated as bearer secrets — validated on input, redacted to host-only in logs, and scrubbed from debug response dumps. Outbound delivery is hardened against internal-network targets.
- The
webhook/urlConfig key (and its legacywebhook_urlalias) still work but emit a one-time-per-request deprecation log; the dashboard-registered URL takes precedence when both are set.
🐛 Fixed
- Fixes webhook POST requests being blocked by security plugins (Wordfence, Cloudflare, Imunify360, Sucuri) as false-positive XSS. The webhook body is now sent as JSON by default, avoiding the pattern that tripped those rules. If your custom receiver needs form encoding, you can revert via the
webhook/request_argsfilter. - Adding or removing capabilities with
caps/addandcaps/removewould fail if the capability arrays weren't associative with the capability as the key. - A site running two TrustedLogin-enabled plugins now correctly isolates each plugin's namespace. Previously, the second plugin's namespaced filters, hooks, options, menus, and role could collide with the first.
- Tightens scoping of the lockdown counter to prevent a denial-of-service vector.
- Fixes
Client::revoke_access( 'all' )not returningtrueafter a successful revoke loop. - Fixes a rare hang during support-user creation under specific username conditions.
- Tightens per-user scoping of the revoke nonce.
🔒 Security
- Hardens the post-redirect "Go back" link against phishing.
- Tightens vendor public-key validation before caching.
- Sensitive headers are now scrubbed from debug log output.
- Log filenames are now derived with a per-site random salt.
💻 Developer Updates
- New helper
Remote::redact_url()returns the host portion of a URL (or[invalid-url]on parse failure) — useful if you want to surface a webhook URL in admin notices or logs without leaking the secret-bearing portion. - Adds
Utils::delete_transient( $transient )as the counterpart toUtils::set_transient(). Previously callers had to reach past the abstraction. - Adds new error codes returned by
Remote::handle_response():vendor_response_not_json(firewall/CDN intercept detected),missing_public_key(your installation isn't fully configured yet), andunexpected_response_code(HTTP status preserved in the error data). - Replaces the
bool $sanitizeparameter onUtils::get_request_param()with acallable $sanitize_callback(default:'sanitize_text_field'). The oldboolsignature is still honored for back-compatibility. Remote::send()gains an optional 5th$timeoutargument (defaultnull→ existing 15-second behaviour, back-compat with all existing callers).- Adds a proper
requireblock tocomposer.jsonpinning PHP 5.3+ andext-curl/ext-json. Previously the PHP floor lived inrequire-devand was not enforced at install time.
1.9.0
1.9.0 (August 25, 2024)
- Added a minimum
vendor/namespacelength of five characters to help prevent collisions with other instances - Fixed a flash of un-styled content on the Grant Access screens by outputting CSS earlier
- Addressed potential error when the
WP_Filesystemclass is not found - Moved TrustedLogin images to inline CSS to simplify the build process
- Removed need for
--relative_images_dirflag inbuild-sassscript - Removed
src/assets/loading.svg - Removed
src/assets/lock.svg
- Removed need for
- Improved coding standards and documentation
1.8.0
1.8.0 (July 18, 2024)
- Implemented many speed enhancements
- Moved logging directory creation into own private method:
Logging::setup_logging_directory()to clean up theLogging::setup_klogger()method - Now compliant with WordPress PHPCS
- Use
gmdate()instead ofdate()for log files and for users registration dates - Moved
SecurityChecks::get_ip()toUtils::get_ip() - Added
Utils::get_user_agent()to generate a user agent string with an optional max length - Improved handling of potential errors
- Security enhancements
- Escaped all error messages
- Removed usage of
$_REQUESTin favor of$_POSTand$_GET
- Implemented PHPCS and PHPStan checks (thanks, Daniel)
1.7.0
1.7.0 (January 29, 2024)
- Added Utils class to handle common utility functions
- Converted usage of
get_site_transient()andset_site_transient()to usingUtils::get_transient()andUtils::set_transient().- Scopes the storage to each blog instead of per-network, preventing potential issues with multisite
- Fixes potential issues with object caching plugins that don't support transients, while allowing for auto-expiring data to be stored in the database
- Prevents data from being "cleaned up" by site optimization plugins that remove expired transients
1.6.2
1.6.1
1.6.1 (September 22, 2023)
- Improved error logging:
- Added error data to the logging, in addition to the code & message
- Now returns the full API response when the response body is invalid
- Switched to just-in-time creation of logging directory and log file
- Added "Learn more" link to the logging directory
index.html - Renamed the log files to
client-{namespace}-{Y-m-d}-{hash}.logto be easier to distinguish and less verbose
- Fixed AJAX status code not being properly set when encountering an error
1.6.0
1.6.0 (September 7, 2023)
- Added
clone_roleconfiguration setting to allow the support user to be created with an existing role, rather than a clone of a role - Added a
trustedlogin_{ns}_support_rolecapability to the cloned support user role in order to better identify that the role is created by TrustedLogin - Added
terms_of_service/urlsetting to allow linking to a custom terms of service page- If not defined, the Terms of Service text and link will not be shown
- Converted CSS generation to use SCSS mixins to allow easier overrides by themes and plugins
- Removed borders around the role descriptions in the Grant Access form
- Clarified the language surrounding user roles in the Grant Access form
- Moved the admin toolbar link to next to the "Howdy, {username}" menu
- Relabeled the link from "Revoke TrustedLogin" to "Revoke Access"
- Improved user creation flow to prevent errors when creating a user with an existing email address
- Fixed error when using PHP in strict mode
- Fixed error creating the Support User when the
vendor/websiteconfiguration exceeded 100 characters in length
1.5.1
1.5.0
- Added the ability for users to create support tickets when granting access—to enable, set
webhook/create_tickettotruein the configuration array- Added second parameter,
$ticket_datatoClient::grant_access()method - Added
ticketto the webhook data, with the following keys:message(string)
- Added second parameter,
- Added
Config::get_settings()public method to get all settings - Added
Encryption::get_remote_encryption_key_url()public method to get the final URL used to fetch the vendor public key - Added
Logging::get_log_file_path()public method to get the full path to the log file - Added a bin file
build-sassto namespace the CSS file usingscssphp(see thecomposer.jsonconfiguration) - Filtered the
$_POSTrequest that generates access to allow only defined fields - Created new
Form.phpfile andFormclass to handle form rendering- Moved form-related methods from
AdmintoForm
- Moved form-related methods from
- Modified
auth.scssto support new ticket fields, admin debugging rendering, and improve styling