Skip to content

Feature/plugins poc 4 - #9113

Open
henryjonathanquispe wants to merge 15 commits into
developfrom
feature/plugins-poc-4
Open

henryjonathanquispe wants to merge 15 commits into
developfrom
feature/plugins-poc-4

Conversation

@henryjonathanquispe

Copy link
Copy Markdown
Contributor

Related Tickets & Packages

  • Link to any related FOUR tickets, PRDs, or packages

Code Review Checklist

  • I have pulled this code locally and tested it on my instance, along with any associated packages.
  • This code adheres to ProcessMaker Coding Guidelines.
  • This code includes a unit test or an E2E test that tests its functionality, or is covered by an existing test.
  • This solution fixes the bug reported in the original ticket.
  • This solution does not alter the expected output of a component in a way that would break existing Processes.
  • This solution does not implement any breaking changes that would invalidate documentation or cause existing Processes to fail.
  • This solution has been tested with enterprise packages that rely on its functionality and does not introduce bugs in those packages.
  • This code does not duplicate functionality that already exists in the framework or in ProcessMaker.
  • This ticket conforms to the PRD associated with this part of ProcessMaker.

ci:deploy

julceslauhub and others added 8 commits July 31, 2026 16:54
commit b84543b
Author: AugustoLopezProcess <augusto.lopez+github@processmaker.com>
Date:   Tue Apr 21 08:27:15 2026 -0400

    Adding plugin admin ui

commit ca8a863
Author: Nolan Ehrstrom <github@nolanpro.com>
Date:   Mon Mar 9 11:01:46 2026 -0700

    Add controllers and routes for plugin UI

    Copied from feature/plugins-poc-vite-ui (just without the vite/Vue3 integration)

commit 3cc89bc
Merge: 9e9b4aa 5da27ce
Author: Nolan Ehrstrom <github@nolanpro.com>
Date:   Mon Mar 9 10:58:27 2026 -0700

    Merge branch 'task/FOUR-28803' into feature/plugins-poc

commit 9e9b4aa
Author: Nolan Ehrstrom <github@nolanpro.com>
Date:   Mon Jan 19 12:30:54 2026 -0800

    Add install command and cached routes

commit 4a5df14
Author: Nolan Ehrstrom <github@nolanpro.com>
Date:   Wed Dec 10 09:29:20 2025 -0800

    Start on plugins
Updating feature/plugins-poc-4 with last changes in develop
FOUR-32722 Some adjustments in plugins installation
FOUR-32760 After install/enable/disable a plugin, should be executed the command: php artisan horizon:terminate
@cursor

cursor Bot commented Oct 26, 2026 •

Copy link
Copy Markdown

PR Summary

High Risk
Plugin install runs git/composer and loads third-party code with route-cache and worker restarts; admin APIs accept repository URLs and zip uploads under a single permission gate.

Overview
This PR adds storage-based plugin lifecycle management (install from Git URL, local path, or zip; uninstall; enable/disable via folder rename) plus an admin Plugins UI and API that queue long-running work and stream progress over PluginLog on the operator’s private Echo channel. PluginManager validates composer.json, runs composer install and optional {name}:install / :uninstall artisan hooks, then rebuilds tenant route cache and restarts Horizon so new code loads; PluginServiceProvider registers enabled plugins under storage/plugins after tenant resolution. Multitenancy updates set per-tenant APP_ROUTES_CACHE, reload cached routes in Octane/console, and extend broadcasting for tenant-scoped channels. Screen builder also picks up published JS from enabled storage plugins. New manage-plugins (and related) permissions, menu entry, routes, and plugin:* CLI commands round out the surface.

In parallel, it introduces the cross-project manage-requirements agent skill: JSON schemas, validate-requirements / check-requirements npm scripts (schema + Python heuristic QC), templates, and a Python quality harness (optional Laya). ai-docs/processmaker/requirements catalogs document the plugin manager component and admin screen.

Reviewed by Cursor Bugbot for commit 5bbed5d. Bugbot is set up for automated code reviews on this repo. Configure here.

@cursor cursor Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale Bugbot comment from a previous run.

Comment thread ProcessMaker/Managers/PluginManager.php Resolved
$pluginPath = $pluginDisabledPath;
} elseif (!is_dir($pluginPath)) {
throw new RuntimeException("Plugin not found: {$pluginName}");
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Plugin name allows path traversal

High Severity

uninstall and toggle join the route {name} onto storage/plugins with no basename or allowlist check. A name of .. resolves to the tenant storage root, so delete or rename can wipe or move the entire storage tree.

Additional Locations (2)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit a96f564. Configure here.


try {
$zip->extractTo($tmpExtractDir);
$zip->close();

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Zip extract allows path traversal

High Severity

installFromZip calls ZipArchive::extractTo on the uploaded archive without checking entry names. Entries with .. or absolute paths write outside the temp directory as the application user before validation or copy.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit a96f564. Configure here.

Comment thread ProcessMaker/Managers/PluginManager.php Resolved
// Extend BroadcastManager to our custom implementation that prefixes the channel names with the tenant id.
$app->extend(BroadcastManager::class, function ($manager, $app) use ($tenant) {
return new TenantAwareBroadcastManager($app, $tenant->id);
});

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tenant switch crashes on broadcast extend

High Severity

makeCurrent extends BroadcastManager by constructing TenantAwareBroadcastManager with a tenant id. Those names resolve in ProcessMaker\Multitenancy, and the real class only accepts the app instance. Every tenant switch fatals. BroadcastServiceProvider already installs the tenant-aware manager.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit a96f564. Configure here.

}
} else {
$this->logRunning("Plugin {$command} command output:\n\n{$result->output()}", $pluginName, $userId);
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Failed plugin commands still report success

Medium Severity

runCommand logs {plugin}:install, route:cache, and horizon:terminate failures and returns. Install still calls logDone and the API responds with success, so a failed plugin setup or stale route cache looks like a completed install.

Additional Locations (2)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit a96f564. Configure here.

throw new RuntimeException(
"Invalid JSON in composer.json at {$composerJsonPath}: " . json_last_error_msg()
);
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Invalid plugin composer.json crashes tenant

High Severity

loadPlugins rethrows on invalid composer.json or a missing PSR-4 path during TenantResolved. One leftover or corrupt folder under storage/plugins then 500s every request for that tenant. PluginManager::list already skips invalid plugins.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit a96f564. Configure here.

Comment thread ProcessMaker/Managers/PluginManager.php Resolved

@cursor cursor Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale Bugbot comment from a previous run.

Comment thread ProcessMaker/Jobs/InstallPlugin.php Resolved
Comment thread resources/js/admin/plugins/Plugins.vue Resolved
Comment thread resources/js/admin/plugins/Plugins.vue Resolved

@cursor cursor Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale Bugbot comment from a previous run.

Comment thread resources/js/admin/plugins/Plugins.vue Resolved
Comment thread resources/js/admin/plugins/Plugins.vue Resolved
…ink, add load screen-builder-form.js files from plugin
…ink, add load screen-builder-form.js files from plugin

@cursor cursor Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale Bugbot comment from a previous run.

Comment thread ProcessMaker/Managers/PluginManager.php Resolved
…ink, add load screen-builder-form.js files from plugin
…ink, add load screen-builder-form.js files from plugin
@decisions-sonarqube

Copy link
Copy Markdown

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.

There are 6 total unresolved issues (including 5 from previous reviews).

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 5bbed5d. Configure here.

Comment thread ProcessMaker/Managers/PluginManager.php Resolved
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants