Skip to content

feat(audit): add system-wide audit log - #73

Merged
mpge merged 1 commit into
mainfrom
feat/system-audit-log
Aug 2, 2026
Merged

feat(audit): add system-wide audit log#73
mpge merged 1 commit into
mainfrom
feat/system-audit-log

Conversation

@mpge

@mpge mpge commented Aug 2, 2026

Copy link
Copy Markdown
Member

What

Adds a system-wide audit log, porting the Laravel reference into this plugin's table-based convention. Previously only per-ticket ticket_activities existed; admin / configuration / security / user actions outside a ticket were not recorded.

Changes

  • Schema — new escalated_audit_logs table added to Activator::create_tables() (dbDelta), mirroring the Laravel audit_logs schema: user_id, action, auditable_type/auditable_id (nullable, for non-model system events), JSON old_values/new_values, ip_address, user_agent, created_at, plus indexes. Plugin version bumped 1.3.01.4.0 so maybe_upgrade() creates the table on existing installs.
  • ModelEscalated\Models\AuditLog follows the static $wpdb helper pattern (like ApiToken/TwoFactor), exposing a single reusable record() helper reused at every mutation site, plus all()/count()/distinct_actions()/distinct_types() for the admin surface.
  • RESTAudit_Log_Controller (GET /escalated/v1/admin/audit-logs) registered in Api_Bootstrap, gated by the existing escalated_audit_view capability. Supports filtering by user_id, action, auditable_type, and a date_from/date_to range, with pagination.
  • Recording sitessettings.updated (+ webhooks, secrets redacted), user.role_granted/user.role_revoked, api_token.created/api_token.deleted, two_factor.enabled/two_factor.disabled, and kb_article.* / kb_category.* CRUD. Admin_Settings was refactored to extract a testable persist() method.

Notes

  • No new capabilities — reuses the existing audit.view slug; the Activator capability-count assertion (54) is unchanged.
  • Bearer-token endpoints (API tokens, 2FA) pass the resolved token user explicitly since get_current_user_id() is 0 under token auth.

Tests

New Test_Audit_Log (18 tests) proves each mutation site writes a row and that the admin list returns and filters entries (auth gating, action/user/type/date filters). Test_Activator updated to assert the new table. Full suite green on a fresh DB: 409 tests, 0 failures (4 pre-existing skips).

Only per-ticket ticket_activities existed; admin, configuration,
security, and user actions outside a ticket were not recorded. Port the
Laravel reference AuditLog into the plugin's table-based convention:

- add the escalated_audit_logs table (Activator + dbDelta) with actor,
  action, polymorphic auditable, JSON old/new snapshots, IP + user agent
- add the AuditLog model with a single reusable record() helper
- add an admin list/filter REST endpoint (GET /admin/audit-logs) gated
  by the existing audit.view capability
- record entries at key mutation sites: settings + webhooks, role
  grant/revoke, API token create/revoke, 2FA enable/disable, and
  knowledge base article/category CRUD
- bump plugin version to 1.4.0 so maybe_upgrade() creates the table on
  existing installs

No new capabilities are introduced; the Activator capability count is
unchanged. Adds WP_UnitTestCase coverage proving each site writes a row
and that the admin list returns and filters entries.
@mpge
mpge merged commit 2643c8c into main Aug 2, 2026
3 checks passed
@mpge
mpge deleted the feat/system-audit-log branch August 2, 2026 17:11
mpge added a commit that referenced this pull request Aug 2, 2026
Only per-ticket ticket_activities existed; admin, configuration,
security, and user actions outside a ticket were not recorded. Port the
Laravel reference AuditLog into the plugin's table-based convention:

- add the escalated_audit_logs table (Activator + dbDelta) with actor,
  action, polymorphic auditable, JSON old/new snapshots, IP + user agent
- add the AuditLog model with a single reusable record() helper
- add an admin list/filter REST endpoint (GET /admin/audit-logs) gated
  by the existing audit.view capability
- record entries at key mutation sites: settings + webhooks, role
  grant/revoke, API token create/revoke, 2FA enable/disable, and
  knowledge base article/category CRUD
- bump plugin version to 1.4.0 so maybe_upgrade() creates the table on
  existing installs

No new capabilities are introduced; the Activator capability count is
unchanged. Adds WP_UnitTestCase coverage proving each site writes a row
and that the admin list returns and filters entries.

Co-authored-by: Matt Gros <mpge@users.noreply.github.com>
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.

1 participant