=== BrenWP Client Safe Mode ===
Contributors: brendigo
Tags: security, troubleshooting, hardening, client, restrictions
Requires at least: 6.0
Tested up to: 6.9
Requires PHP: 7.4
Stable tag: 1.7.2
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Per-user Safe Mode plus role-based client restrictions for safer troubleshooting and cleaner client handoff.

== Description ==

BrenWP Client Safe Mode helps you troubleshoot safely and reduce risk when handing a WordPress site to clients or non-technical users.

Safe Mode is *per-user*: it applies only to the currently logged-in user who enabled it. Visitors and other users are not affected.

= Safe Mode (per-user) can optionally =
* Block access to risky wp-admin screens (plugin/theme management, core updates, Site Health, and update actions)
* Disable file modifications (plugin/theme installs, updates, editors)
* Optionally block update/install capabilities (prevents running updates/installs even via alternative flows)
* Optionally block destructive capabilities (prevents deleting plugins/themes while Safe Mode is enabled)
* Optionally disable the built-in plugin/theme editors (capability-based) while Safe Mode is enabled
* Hide update notices
* Trim selected admin bar nodes (Updates / Comments / New Content)
* Auto-disable after a configurable number of minutes (optional)

= Client restrictions (role-based + optional user targeting) can =
* Optionally target a specific user account (in addition to roles)
* Hide risky menus
* Block direct access to sensitive wp-admin screens
* Disable file modifications
* Hide update notices
* Optionally limit the Media Library to a user’s own uploads (privacy on multi-author sites)
* Optionally hide common Dashboard widgets for restricted roles (UI cleanup)
* Optionally hide the Screen Options dropdown (independent toggle)
* Optionally hide the Admin Bar on the front end for restricted roles
* Optionally block Customizer access (customize.php)
* Optionally block Users screens (Users list/Add/Edit) even if the broader screen blocklist is disabled
* Optionally block Tools screens (Tools/Import/Export) even if the broader screen blocklist is disabled
* Optionally lock profile email/password changes for restricted roles (prevents self-service account takeover)
* Optionally show a dismissible 2FA security reminder notice (notice only)
* Optionally hide the Admin Bar on the front end for restricted roles

= General hardening (site-wide, optional) =
* Disable XML-RPC
* Disable the built-in plugin/theme editors for all users (capability-based)
* Optional settings export download (admin-only) via a nonce-protected endpoint (default OFF)

Administrators are never restricted by client restrictions. On multisite, super-admins are also excluded.

= Privacy =
This plugin does not send data to external services. It performs **no tracking, telemetry, analytics, or “phone-home” requests**.

= Data stored on your site =
The plugin stores the minimum required data to provide Safe Mode and optional auditing:

* **Options (Settings)**: stored in the `brenwp_csm_options` option (site option). This contains your configured settings.
* **Activity log (optional)**: stored in the `brenwp_csm_activity_log` option **only if Activity logging is enabled**. This log is bounded by **Max entries** and can optionally be pruned by age (Retention days).
* **Operational options**: internal housekeeping options such as `brenwp_csm_last_settings_change` and a short-lived lock key used to avoid concurrent log writes.
* **User meta (Safe Mode)**:
  * `brenwp_csm_safe_mode` (on/off flag for a user)
  * `brenwp_csm_safe_mode_until` (optional expiry timestamp if auto-off is enabled)

= Data minimization and retention =
* Activity logging is **disabled by default**.
* The activity log does **not** store IP addresses and attempts to redact likely secrets from context values.
* Retention controls:
  * **Max entries** caps log size.
  * **Retention days** can automatically prune older entries (0 = disabled).
  * The **Clear log** action removes all log entries immediately (admin-only, nonce protected).

= Privacy tools =
The plugin:
* Adds suggested text to the Privacy Policy Guide (Settings → Privacy)
* Registers a personal data exporter and eraser for the Safe Mode user meta

= Data deletion =
On uninstall (delete), the plugin removes its options, optional log option, Safe Mode user meta, and (best-effort) the optional `bren_client` role if it was created by the plugin.

== Installation ==
1. Upload the plugin folder to /wp-content/plugins/brenwp-client-safe-mode/
2. Activate the plugin via Plugins → Installed Plugins
3. Open BrenWP Safe Mode in wp-admin
4. Configure Safe Mode and Restrictions as needed

== Frequently Asked Questions ==

= Does Safe Mode affect visitors? =
No. Safe Mode is per-user. Visitors and users without Safe Mode enabled see the normal site.

= Will administrators be restricted? =
Administrators are never restricted by client restrictions (role/user targeting). If an administrator enables Safe Mode for their own account, optional Safe Mode policies (like blocking file modifications) can apply to that account.

= Can I restrict a single user without creating a new role? =
Yes. In the **Restrictions** tab, you can select a specific user account in **Restricted user (optional)**. This applies the same restrictions even if that user’s role is not selected. Administrators (and multisite super-admins) are excluded to prevent lock-outs.

= Does this plugin collect personal data? =
It stores a per-user Safe Mode flag so it can remember whether Safe Mode is enabled for that account. If auto-expiry is enabled, it also stores an expiry timestamp. No tracking, analytics, or external requests.

= How do I remove all plugin data? =
When you uninstall (delete) the plugin, it removes its options, its activity log option, Safe Mode user meta, and the optional bren_client role (best-effort).

= Why does the admin bar Safe Mode toggle require JavaScript? =
To prevent state changes via GET requests (and potential link prefetch), the admin bar toggle submits the action as a POST request. This is handled using lightweight JavaScript.

== Security ==

This plugin follows WordPress hardening best practices:

* **CSRF protection**: all state-changing actions use **POST** and require a **WordPress nonce**.
* **Authorization**: privileged admin actions are gated by **capability checks** (`manage_options` by default, filterable).
* **XSS defense**: user-controlled data is sanitized on input and escaped on output.
* **No remote requests**: the plugin does not make outbound HTTP requests.
* **Data minimization**: the activity log is bounded, does not store IP addresses, and redacts likely secrets in log context values.

Assumptions and scope:

* The plugin enforces policies inside WordPress; it does not replace server/WAF hardening.
* Safe Mode is **per-user** and does not modify the site’s active plugins/themes list.

== Troubleshooting ==

= I don’t see the Safe Mode toggle in the admin bar =
* Confirm the WordPress admin bar is enabled for your account.
* Confirm **Enforcement** is enabled in the plugin settings.
* Confirm your role is included in **Who can toggle Safe Mode** (or you are an administrator / multisite super-admin).

= My profile email/password cannot be changed =
If **Restrictions → Lock profile email/password** is enabled and your account is restricted, you will not be able to change your own email or password. Contact an administrator.

= XML-RPC stopped working =
If you rely on legacy services that require XML-RPC (some old mobile apps / integrations), disable **General → Disable XML-RPC**.

= I get redirected with an “Access blocked” notice =
A configured policy blocked a sensitive admin screen. Review:
* **Restrictions → Block direct screen access** (for restricted roles)
* **Safe Mode → Block risky admin screens** (for your account if Safe Mode is enabled)

= Safe Mode is enabled but I want to turn it off =
* Use the **Safe Mode** tab to toggle it off.
* If auto-off is enabled, it will disable automatically after the configured time window.
* If Enforcement is OFF, the UI provides a **Clear stored Safe Mode** button to remove the stored flag.

== Developer Hooks ==

Filters:
* `brenwp_csm_required_cap` — change the capability required to manage this plugin (default: `manage_options`).
* `brenwp_csm_presets` — customize Dashboard presets (label/description/patch arrays).
* `brenwp_csm_create_client_role` — return `false` to prevent creating the `bren_client` role on activation.
* `brenwp_csm_client_role_caps` — customize capabilities assigned to the `bren_client` role on activation.
* `brenwp_csm_remove_client_role_on_uninstall` — return `false` to keep the `bren_client` role during uninstall cleanup.



== Changelog ==

= 1.7.2 =
* UX: About tab expanded with clearer purpose, use cases, scenarios, and direct links (plugin/author/support).
* New (General): Optional “Settings export download” toggle (admin-only, nonce-protected endpoint) to download settings JSON as a file.
* New (Restrictions): Optional, dismissible 2FA reminder notice for restricted users (notice only; no integrations).
* Fix: Prevent redirect loops when a blocked-screen redirect destination is also restricted.
* Maintenance: Documentation updates and minor UI consistency cleanup.

= 1.7.1 =
* UX: Simplified settings layout (Basics/Recommended/Advanced) so new users are not overwhelmed.
* UX: Moved the About screen into an “About” tab to reduce admin menu clutter.
* New: Admin-managed Safe Mode for other users (optional per-user expiry).
* New: Activity log export (JSON/CSV) and configurable retention with daily auto-prune.
* New: Custom wp-admin screen blocklists (separate lists for Safe Mode and Restrictions).
* New: Optional restriction toggles: Hide Screen Options only, Block Customizer access, Block Users screens.
* New: Safe Mode toggle to block destructive capabilities (delete plugins/themes).
* Fix: Improved i18n compliance (missing translators comment for placeholders).
* Security: Hardened admin actions (capability checks, POST-only, nonces) and safer input handling/escaping.
* Compatibility: Multisite safeguards (never restrict Network Admin; protect super-admin accounts).
* Performance: Per-request caching and safer option storage (autoload off for log / large options).

= 1.7.0 =
* Dashboard: Added Quick Actions (presets, settings export/import JSON, reset to defaults).
* Restrictions: Added optional “Restricted access” banner and user selector with AJAX search (better for large sites).
* Restrictions: Added optional profile hardening (lock email/password) for restricted roles.
* Safe Mode: Added optional UI hardening (hide admin notices) and additional safety toggles.
* Security/Hardening: Improved state-changing admin actions (nonces, capability checks, POST-only), and safer activity log writes.

= 1.6.9 =
* Security: Hardened settings submission capability checks and improved defensive checks around admin assets.
* Compatibility: Replaced PHP filter_input() usage with WordPress-native input handling (wp_unslash + sanitize_*).
* Performance: Added lightweight per-request caching for Safe Mode and restriction checks.
* Multisite: Avoided applying restrictions inside Network Admin.

== Upgrade Notice ==

= 1.7.2 =
This is a maintenance + hardening + UX release.

New in 1.7.2:
* Expanded About tab with clearer purpose, scenarios, and links (plugin/author/support)
* Optional settings export download (admin-only)
* Optional 2FA reminder notice for restricted users (notice only)
* Existing restrictions and redirect behavior refined for stability (loop prevention)

= 1.7.1 =
This is a feature + hardening release.

New in 1.7.1:
* Admin-managed Safe Mode for other users (optional expiry; multisite-safe)
* Activity log export (JSON/CSV) + configurable retention with daily auto-prune
* Custom wp-admin screen blocklists (separate lists for Safe Mode and Restrictions)

If you use Restrictions, review settings after update (recommended: start with a single role and test with a staging user).
