Skip to content

Release - #1122

Merged
selul merged 26 commits into
masterfrom
development
Sep 30, 2026
Merged

Release#1122
selul merged 26 commits into
masterfrom
development

Conversation

@pirate-bot

@pirate-bot pirate-bot commented Sep 10, 2026 •

Copy link
Copy Markdown
Contributor

Linked issues

This release will close the following issues once merged:

Public changelog

  • Fixed editor crashes when stored license keys are shorter than four characters.
  • Fixed lock icons appearing on available networks during account connection.
  • Fixed social account connections that could disappear after authorization.
  • Fixed LinkedIn authorization failures that displayed a critical error screen.
  • Fixed scheduled sharing when Maximum Characters contains invalid values.
  • Fixed misleading dashboard messages when a Revive Social request fails.
  • Fixed the REST API warning after a dashboard request recovers.
  • Fixed X requests crashing when another plugin is active.
  • Updated dependencies

pirate-bot and others added 5 commits September 7, 2026 13:55
Mirrors the setup used in the other Codeinwp plugin repos: the
semantic-release-slack-bot plugin posts to the announcements channel on a
successful release from master, and the release workflow passes the
SLACK_WEBHOOK_ANNOUNCEMENTS org secret plus the package label.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@pirate-bot

pirate-bot commented Sep 10, 2026 •

Copy link
Copy Markdown
Contributor Author

Plugin build for 3d0011a is ready 🛎️!

selul and others added 21 commits September 10, 2026 19:01
* fix: prevent fatal errors when LinkedIn authorization fails

LinkedIn authorization failures could crash to the WordPress
critical-error screen instead of surfacing the LinkedIn error:

- authorize() called the non-existent Exception::getDescription() in
  its catch block, turning any caught error into a second fatal
- add_account_with_app() ran array_pop() on the result of
  unserialize() without validating the payload, fataling on PHP 8
  when the popup posts back an error payload instead of account data
- add_account_li() ignored the add_account_with_app() return value
  and registered the service regardless
- sign-in-btn.vue parsed every popup message as account data

Validation failures now log the LinkedIn error to the Revive Social
log and answer the REST call with a code 400 response.

Adds e2e coverage for the malformed-payload paths (red on the old
code) plus a happy-path guard, and drops the stale PHPStan baseline
entry for the fixed getDescription() call.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* test: expand LinkedIn e2e regression coverage

Adds regression tests for the remaining validation branches: empty
payload, pages without a notify entry, notify-only pages with no
accounts (asserting no service gets registered), the LinkedIn error
landing in the plugin log, and the happy path now verifies the
account is actually registered and exposed.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix: drop PHPStan baseline entry resolved by the payload validation

The add_account_with_app() validation guarantees the accounts loop
always runs, so PHPStan no longer reports 'Variable $account might
not be defined' and the baseline ignore became unmatched.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix: harden LinkedIn payload validation per review feedback

Addresses the Copilot review on #1100:

- require the decoded account id to be a non-empty string so it cannot
  reach str_replace()/array-key usage as an array or object
- validate that the notify entry timestamp is numeric before persisting
  the refresh-token notice
- validate every remaining pages entry is a complete account array
  before reading its fields, and reindex with array_values() so the
  consuming loop cannot hit missing offsets
- e2e: clear the plugin log before asserting the rejection entry so the
  test cannot pass on entries left by earlier tests; add regression
  tests for the string-account-entry and non-string-id payloads

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* test: build the ROP api URL from ropApiSettings.root safely

The e2e utils that came in with #1094 enable pretty permalinks in the
test site, so `rest_url()` — and therefore `ropApiSettings.root` — no
longer carries a query string. Appending `&req=...` to it produced
`/wp-json/tweet-old-post/v8/api/&req=add_account_li`, which the REST
server resolved to nothing: all 10 LinkedIn tests failed with
`rest_no_route` / 404 after merging development.

Let URL/searchParams place `?` or `&`, the way the plugin's own
`fetchAJAX` passes `req` through vue-resource's `params` option. Works
under either permalink mode.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* fix: reject array-valued LinkedIn id/pages before decoding them

Copilot review feedback on #1100.

`is_set_not_empty()` deliberately accepts array values — `is_valid_serialize_data()`
maps over them — so a payload of `{ id: [<valid>], pages: [<valid>] }` cleared
the guard and reached `base64_decode()`, which raises a PHP 8 TypeError. That is
the same critical-error response this PR set out to remove; verified locally,
the request returned HTTP 500 "There has been a critical error on this website"
without the new check.

Guard both encoded fields as strings before decoding, and cover the payload with
an e2e test that fails without it.

Also reset the services store in `beforeEach`. The happy-path test registers a
LinkedIn account and only cleans up on success, so with CI retries enabled a
failed run left that account behind and assertions like `not.toContain('linkedin')`
could pass or fail depending on order. Uses the `ropUtils` fixture that came in
with #1094 rather than a second bespoke helper.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* fix: unregister the auth message listener on a malformed payload

Copilot review feedback on #1100.

Both failure branches this PR added to getChildWindowMessage() are terminal —
the popup has already answered — but only the parsed-error one detached the
global `message` handler. After a malformed payload the component stayed
subscribed to the auth origin and would route any later message using the
stale `modal.serviceName`. Detach in the parse branch too, matching the
adjacent branch.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: lucadobrescu <lucadobrescu@users.noreply.github.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: lucadobrescu <luca.dobrescu@vertistudio.com>
* fix: cast maximum post length to integer to prevent TypeError

* Plan: resolve merge conflicts with development

Co-authored-by: pirate-bot <58979018+pirate-bot@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: pirate-bot <58979018+pirate-bot@users.noreply.github.com>
Bumps [codeinwp/themeisle-sdk](https://github.com/Codeinwp/themeisle-sdk) from 3.3.61 to 3.3.62.
- [Release notes](https://github.com/Codeinwp/themeisle-sdk/releases)
- [Changelog](https://github.com/Codeinwp/themeisle-sdk/blob/v3.3.62/CHANGELOG.md)
- [Commits](Codeinwp/themeisle-sdk@v3.3.61...v3.3.62)

---
updated-dependencies:
- dependency-name: codeinwp/themeisle-sdk
  dependency-version: 3.3.62
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018GJfggt4S4RuAfF24E93EK
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018GJfggt4S4RuAfF24E93EK
* fix: add state management for API availability confirmation

* fix: refactor REST API request control

* fix: scope rest api availability to request
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018GJfggt4S4RuAfF24E93EK
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018GJfggt4S4RuAfF24E93EK
* fix: isolate bundled TwitterOAuth from other plugins

Revive Social shipped a fork of abraham/twitteroauth under the upstream
Abraham\TwitterOAuth namespace. Autopost for X bundles upstream 4.0.1
under the same namespace with a different Request::fromConsumerAndToken()
signature. Every Composer autoloader registers globally, so PHP mixed the
two copies and Autopost's requests died with a TypeError.

Vendor the fork in lib/twitteroauth as Rop_Vendor\TwitterOAuth, drop the
Composer dependency and require its ca-bundle dependency directly. The
Twitter service now uses the namespaced class. Tests assert the plugin no
longer autoloads the shared namespace.

Refs: #1128

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* fix: keep ext-curl requirement and test coexistence with upstream TwitterOAuth

Address review on #1130. The bundled client calls cURL directly, so the
root package must keep the ext-curl platform requirement the removed
dependency carried. The docs no longer describe the fork as a copy of
upstream, because its Request contract differs. The isolation test now
checks the plugin autoloader instead of class_exists(), and a fixture
with the upstream 4.0.1 argument order proves both clients build their
requests from their own classes.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* test: assert only the plugin's own autoloader skips the shared TwitterOAuth namespace

Address review on #1130. Another plugin's Composer loader is expected
to map Abraham\TwitterOAuth, so the check now selects the loader that
maps Rop_Vendor\TwitterOAuth and asserts on that one alone.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* test: exercise both Composer loader orders against a foreign TwitterOAuth

Address review on #1130. The coexistence test now registers a real
Composer ClassLoader for a fake upstream 4.0.1 copy, once prepended and
once appended, and asserts which file each Abraham class resolves from.
Different classes are resolved per order because a loaded class cannot
be unloaded within one process. The autoloader check also inspects the
classmap and asserts nothing preloaded the shared namespace.

The README update command now names its input files.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
The first SDK release that carries the AI Connect module this PR opts into.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018GJfggt4S4RuAfF24E93EK
Picks up the AI Connect fixes since 3.3.64: the Enable button hides once
the connector is active, the notice matches core's height, and the
"enabled" event for products with their own notification UI.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018GJfggt4S4RuAfF24E93EK
Resolves conflicts in composer.json, composer.lock.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018GJfggt4S4RuAfF24E93EK
feat: register abilities with the Abilities API
The #tsdk_banner slot ran the full width above both the tabs panel and the
status sidebar and sat flush on the panel. It now rides the main column, so
the AI Connect notice lines up with the panel below it, leaves the sidebar
alone and keeps a small gap. The sale banner keeps its full-width rule.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018GJfggt4S4RuAfF24E93EK
#1126 reworded the api_not_available notice, while #1127 added the spec
asserting the old copy, so the unreachable-API test failed on every run.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@selul
selul merged commit 07d1807 into master Sep 30, 2026
8 checks passed
@pirate-bot

Copy link
Copy Markdown
Contributor Author

🎉 This PR is included in version 9.4.3 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

@pirate-bot pirate-bot added the released Indicate that an issue has been resolved and released in a particular version of the product. label Sep 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment