=== WPSecureOps Connector ===
Contributors: cmdgw
Tags: security, monitoring, alerts, malware, agency
Requires at least: 6.2
Tested up to: 7.1
Requires PHP: 7.4
Stable tag: 1.0.0
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Forward completed Wordfence scan findings to your WPSecureOps dashboard, so one team can triage alerts across every site it looks after.

== Description ==

If you look after more than a handful of WordPress sites, Wordfence findings
arrive as one email per site per scan, in as many inboxes as you have sites.
This connector sends each completed scan to a single WPSecureOps dashboard
instead, where findings from every site queue up in one place, keep their
history, and can be acknowledged or ignored once rather than again on every
re-scan.

The plugin does not scan anything itself and does not change how Wordfence
behaves. It reads the results of scans Wordfence has already finished.

**Setup is one click.** Activate the plugin, open Settings &rarr; WPSecureOps,
press **Connect now**. The site registers itself, an operator approves it in the
dashboard, and it collects its own key. There is nothing to copy or paste and no
switch to remember to turn on: once a site is connected, every completed scan is
forwarded automatically. Pressing **Disconnect** is how you stop it.

= What is sent =

* Site name, public URL, and the WordPress, Wordfence and connector versions.
* Scan completion time, and whether the scan succeeded or failed.
* For each finding: issue type, severity, and a redacted title and description.
* A check-in every 30 minutes carrying the versions above, whether Wordfence is
  still active and scanning, and how many reports are waiting in the local
  queue. This is what lets the dashboard tell "no findings" apart from "this
  site stopped talking to us" — silence otherwise looks identical to health.

= What is not sent =

Usernames, passwords, API credentials, file contents, database contents, visitor
data and the raw Wordfence issue structure never leave the site. Absolute server
paths are rewritten to `[site-root]/` before a report is queued, so a finding
cannot leak your directory layout.

= Reliability =

Reports go into a queue in your own database and are delivered by WP-Cron with
exponential backoff, so a dashboard outage or a network blip cannot lose a scan.
Every report carries a deterministic id derived from the installation and the
scan, so a retry can never create a duplicate entry in the dashboard. A report
that can never be delivered is dropped at the end of the retry ladder rather
than growing the queue forever.

== External services ==

This plugin connects to the WPSecureOps API at `https://wpsecureops.com` — the
service the plugin exists to talk to, and the only external service it contacts.

It sends data at these points, and no others:

* **When you press "Connect now"** — the site name, home URL, WordPress and
  Wordfence versions, a locally generated installation id, and the hash of a
  locally generated claim secret. Nothing is sent before you press it: installing
  and activating the plugin contacts nothing at all.
* **As part of that registration**, WPSecureOps fetches your home URL once to
  confirm you control it, and the plugin answers with a one-time nonce.
* **After a Wordfence scan completes**, one report as described under "What is
  sent" above.
* **Every 30 minutes while connected**, one check-in as described above. The
  dashboard may change this rate; the plugin clamps whatever it is told to a
  range between 5 minutes and 6 hours.

Nothing is sent once you press Disconnect, and nothing is sent by a site that has
never been connected.

Privacy policy: https://wpsecureops.com/privacy

Self-hosters can point the connector at their own install with the
`wpso_connector_endpoint` filter or the advanced field on the settings screen.

== Credits ==

Created by [Guido Schad](https://wpserverguard.com/), author of
[Lockora Security Audit](https://wordpress.org/plugins/lockora-security-audit/)
and [Who Changed It? – Activity Log & Audit Trail](https://wordpress.org/plugins/who-changed-it/).

== Installation ==

1. Install and activate Wordfence, if it is not already running.
2. Install and activate WPSecureOps Connector.
3. Open **Settings &rarr; WPSecureOps** and press **Connect now**. If whoever
   runs your dashboard gave you a connect code, paste it first so the site lands
   in their account automatically.
4. Approve the site in the WPSecureOps dashboard. The plugin finishes connecting
   on its own, usually within five minutes.

WP-Cron must be able to run. On a low-traffic site, have your host call
`wp-cron.php` on a schedule.

== Frequently Asked Questions ==

= Do I need Wordfence? =

Yes. This plugin reports what Wordfence finds; on its own it has nothing to
report.

= Does it modify or slow down Wordfence? =

No. It reads Wordfence's completed-scan timestamp and issue list after a scan
has finished, never while one is running.

= How do I stop it sending? =

Press **Disconnect** on the settings screen, or deactivate the plugin. Both stop
delivery immediately; Disconnect also discards this site's key.

= What happens if the dashboard is offline? =

The report waits in a queue in your database and retries with exponential
backoff. Nothing is lost and nothing is duplicated.

= Can one API key be used on several sites? =

No. The API binds a key to the first WordPress installation that uses it, and
refuses it everywhere else.

= Does it work on multisite? =

It runs per site, and each site connects separately. It is not network-activated.

= Where is my data stored? =

Findings are stored in the WPSecureOps dashboard your site is connected to. The
plugin itself stores only its queue table, its own options, and its key — all of
which are removed when you uninstall it.

== Changelog ==

= 1.0.0 =
* Forwarding is now automatic. A connected site sends every completed scan — the
  "Enable forwarding" checkbox is gone, along with the state where a site looked
  connected but had been left switched off and silently sent nothing. Connect and
  Disconnect are the only controls.
* The settings screen no longer repeats the endpoint it sends to; it reports
  whether forwarding is active instead.
* Says plainly when Wordfence is not installed, rather than reporting "Not
  detected" and leaving you to work out what that means.
* Uninstalling now removes the queue table and every option the plugin created.
* First release prepared for the WordPress plugin directory.

= 0.7.0 =
* Scheduled check-in every 30 minutes, so the dashboard can tell a healthy quiet
  site apart from one that has stopped reporting.

= 0.6.0 =
* Optional connect code on the Connect screen. Paste the code your WPSecureOps
  contact gave you and this site is assigned to their account automatically.
  Leave it blank and an administrator assigns the site instead.

= 0.5.0 =
* Domain-control verification. The dashboard issues a nonce at registration and
  fetches this site to see it echoed back before any key is handed over, so a
  registration can only succeed for a URL you actually control.
* Re-registering an existing site no longer changes anything until that check
  passes, so nobody can rewrite a connected site's record by knowing its URL.

= 0.4.0 =
* One-click connect. The plugin ships with no credentials at all: install it,
  press "Connect now" on the settings screen, and the site registers itself with
  the dashboard and collects its own API key. Nothing to copy or paste.
* New sites arrive in the dashboard as pending and cannot deliver a finding
  until an operator approves them; the site then finishes connecting on its own.
  Operators can switch on auto-approval for a bulk rollout.
* Replaces the 0.3.0 fleet-token build, which required baking a shared secret
  into the plugin.

= 0.3.0 =
* Fleet install: a connector built with an enrollment token can be installed
  unchanged on any number of sites. Each site registers itself on activation and
  receives its own per-site API key — nothing to configure per site.
* Single-site builds can also ship their key, so activating the plugin is the
  entire setup.
* Reports that can never be delivered are dropped after the full retry ladder
  instead of retrying forever.

= 0.2.0 =
* The dashboard endpoint is now built in — you only paste an API key. The
  endpoint field moved to an optional "Advanced" section for self-hosters.
* Fixed: a scheme-less or http:// endpoint was silently discarded, leaving the
  setting empty so nothing was ever sent and no error was recorded. Entries are
  now upgraded to https instead of thrown away, and anything genuinely invalid
  says so instead of failing quietly.
* Test connection no longer requires an endpoint to be entered first.

= 0.1.0 =
* Initial private MVP.

== Upgrade Notice ==

= 1.0.0 =
Forwarding is automatic for connected sites. If you had deliberately left the old
"Enable forwarding" checkbox off while staying connected, press Disconnect
instead — that checkbox no longer exists.
