| 开发者 | tommybordas |
|---|---|
| 更新时间 | 2026年9月9日 04:31 |
| PHP版本: | 7.0 及以上 |
| WordPress版本: | 7.1 |
| 版权: | GPLv2 or later |
| 版权网址: | 版权信息 |
No. As long as the site is not paired, no event hook is even registered and the
inventory REST routes answer 403. The only thing that starts an exchange is an
administrator deliberately pairing the site, from the settings screen, from
WP-CLI, or through the /pair REST route.
You enter it when pairing. No address is hardcoded in the plugin. If you manage
a fleet of sites, you can also enforce it in wp-config.php:
define( 'SUMOTORI_DASH_AGENT_URL', 'https://your-dashboard.example' );
The settings screen field then displays that value instead of being editable.
Nothing. Deleting the plugin erases the configuration option: the site option, the network option, and any options left on sub-sites.
Yes, since version 1.4.0. An administrator of the site — in practice a dashboard
authenticating with an administrator application password the site owner issued
to it — can call this site's own REST API:
POST /wp-json/sumotori-dash/v1/pair
{"url": "https://your-dashboard.example", "code": "XXXX-XXXX"}
The agent then performs exactly the same exchange as the settings form: it calls
<url>/api/pair and stores the endpoint and secret it gets back. The second
accepted body registers the link directly, as wp dash-agent connect does:
POST /wp-json/sumotori-dash/v1/pair
{"endpoint": "https://your-dashboard.example/api/ingest", "secret": "…"}
Send one form or the other, never both. The endpoint must be an https URL and
the secret 16 to 512 printable characters with no space.
Both forms require the manage_options capability (manage_network_options on
a multisite network) — exactly the capability the settings screen already
requires. The route therefore grants its caller nothing they could not already do
by hand in wp-admin; anyone else gets a 403.
A site that is already paired answers 409 and keeps its current link, unless the
body also carries "force": true.
The answer to a successful call is:
{"paired": true, "endpoint": "…", "paired_at": "…", "site_url": "…",
"agent_version": "…", "message": "…"}
The shared secret is never returned, never logged, and never quoted in an
error message. An invalid body gives a 400, a dashboard that cannot be reached or
whose answer cannot be read gives a 502.
Finally, DELETE /wp-json/sumotori-dash/v1/pair, with the same capability,
clears the link: it is the REST equivalent of the "Disconnect this site" button,
so a dashboard can withdraw cleanly from a site it no longer manages.
No. Both inventory routes (/inventory and /sites) are read-only: they write
no option, schedule no task, execute no command, and include no file whose path
would come from the request.
The only route that writes anything is /pair, and all it ever writes is the
link itself — the dashboard endpoint and the shared secret, the same single
option the settings screen saves. It is reserved to administrators of the site,
and it touches nothing else.
Yes. The link is unique for the whole network and is configured from the network
administration (manage_network_options capability). The inventory can target
any sub-site through the blog_id parameter.
GET /wp-json/sumotori-dash/v1/scan: structural checks
that only WordPress can perform. A dashboard scanning files over SSH sees
the disk, including what sits outside the document root, and cannot be lied to
by code running inside the site; it does not see the database, the scheduler,
or the plugin list as WordPress actually renders it. This endpoint covers that
second half, and nothing else — it deliberately does not scan files.wp-cron hook with no registered
callback (a backdoor can live in the scheduler with no file at all); an option
over 20 KB whose value contains PHP source, a call to eval() or a long
encoded block (a payload that rewrites a theme file on every visit leaves no
suspicious file to find); a plugin directory carrying a valid plugin header
that get_plugins() does not return, which means it removes itself through the
all_plugins filter; a plugin marked active whose file is missing; the
effective auto_prepend_file and auto_append_file as PHP applies them; and
the list of must-use plugins, which run without ever being activated.themes_updates count is unchanged, so dashboards written
against an earlier version keep working.POST /wp-json/sumotori-dash/v1/pair. The body carries either
url + code, which runs exactly the same exchange as the settings form, or
endpoint + secret, the equivalent of wp dash-agent connect. This closes
the last gap for a dashboard that installed the agent remotely and has no shell
access to the site: until now a human had to copy a code by hand.manage_options (manage_network_options on multisite) —
the very capability the settings screen already requires — so it grants its
caller nothing they could not already do from wp-admin. Every other request
gets a 403."force": true. An invalid body gives a 400, an unreachable or unreadable
dashboard a 502.DELETE /wp-json/sumotori-dash/v1/pair, same capability, clearing the
link: the REST equivalent of the "Disconnect this site" button.wp-content/mu-plugins/. Plugins are not meant to write
executable code outside their own directory, so the feature has been dropped
entirely rather than kept behind a checkbox. The agent is now an ordinary
plugin that is activated, deactivated and uninstalled like any other.uninstall.php no longer touches the mu-plugins directory.load_plugin_textdomain() removed — WordPress has loaded translations by
itself for plugins hosted on WordPress.org since version 4.6.mu-plugins copy becomes an explicit option, disabled by default, with a
"Remove from mu-plugins" button. It is no longer performed automatically on
activation: the plugin stays normally deactivatable and uninstallable.uninstall.php: uninstalling erases all options and the mu-plugins copy.sumotori-dash-agent) and a .pot template is provided./sites route, blog_id parameter.