Skip to content

Release diff: master → previous_release - #22

Closed
Th0rgal wants to merge 2 commits into
previous_releasefrom
master
Closed

Release diff: master → previous_release#22
Th0rgal wants to merge 2 commits into
previous_releasefrom
master

Conversation

@Th0rgal

@Th0rgal Th0rgal commented Dec 28, 2025

Copy link
Copy Markdown
Member

Automated PR. The 'previous_release' branch is force-updated on every push to master to point at the commit before the push, so this PR always represents the current release diff.


Note

Security/Auth and API changes

  • New api/src/auth.rs with parse_bearer_token, sha256_hex, constant‑time equality, and server address extraction; all routes (handshake, ingest, heartbeat, observations, callbacks) now use it for token validation and timing‑attack resistance
  • Store optional server address (callback_url) detected from headers; handshake/ingest upsert it and validate tokens before state updates
  • Add subtle crate; expose auth in lib.rs

CORS configuration

  • Add Config.cors_permissive_dev; CORS is restrictive by default and only permissive when CORS_PERMISSIVE_DEV=true

Plugin (core/bukkit)

  • Config adds api.server_address; HttpUploader sends X-Server-Address in handshake/ingest
  • DiskSpool writes to temp then atomically renames to avoid partial files
  • Sampling logic clarified; always capture PLAYER_ABILITIES packets even for exempt players; improve USE_ITEM_ON extraction across versions
  • Bump pluginVersion to 0.3.0

Web (dashboard/docs)

  • Connection status: show API→Server only when address present; better unknown/offline handling and overall status calculation; minor UI truncation fixes
  • Docs add guidance for API→Server ping and configuring server_address

Written by Cursor Bugbot for commit 6eb860f. This will update automatically on new commits. Configure here.

* feat: improve healthcheck logging, empty state UI, and security hardening

- Add detailed logging to module healthcheck to help diagnose connectivity issues
- Improve players page empty state with icon and helpful message
- Early return when no players exist to avoid unnecessary queries
- Add path traversal protection in S3 key generation via sanitization
- Normalize server_id in module registration
- Add cursor pointer to PWA install banner buttons for better UX

* feat: add dev-release profile and UI improvements

- Add dev-release cargo profile for faster development builds
- Optimize release profile with strip and panic=abort
- Fix empty player grid conditional rendering
- Improve delete dialog with escape key handling and loading state
- Center loading and empty states in settings page

* fix: settings modal scroll lock and escape key handling

* fix: prevent empty path components in S3 keys and propagate errors

- sanitize_path_component now returns Option<String> and rejects
  empty results (e.g., malicious server_id like "../../../")
- batch_key returns Option<String> to propagate sanitization failures
- put_batch and ingest routes now return proper 400 errors for
  invalid server_id/session_id instead of creating malformed S3 keys
- useFalsePositiveReports now throws errors instead of silently
  converting them to empty data, fixing error visibility for
  RLS/permission misconfigurations

* feat: add skeleton loading states for dashboard pages

- Add comprehensive skeleton components for all dashboard pages
- Replace spinner-only loading with content-aware skeletons
- Improve perceived performance during data fetching
- Add skeleton for modules, players, findings, settings, and sidebar

* fix: resolve dashboard UI bugs and improve server switching

- Fix error objects rendered directly in JSX causing React crash
  (use error?.message instead of error in findings, players, modules pages)
- Fix stale modules shown when switching servers mid-toggle
  (clear localModules, pendingToggles, and sync refs on server change)
- Add cursor-pointer to all clickable buttons across dashboard
- Fix modal stacking for configuration modal over module detail panel
- Make dashboard HUD elements non-selectable with CSS
- Add refreshServers to context for proper server list refresh after deletion

* fix: prevent deleted servers from reappearing after page reload

The refreshServers function had two issues causing deleted servers to
persist:
1. When API returned zero servers, it returned early without clearing
   localStorage, leaving stale entries intact
2. A "keep purely-local entries" loop re-added any server found in
   localStorage but not in the remote API

Now refreshServers clears localStorage when API returns empty and only
keeps servers that exist in the API (while merging local metadata like
custom names).

* docs: align documentation with backend API format

- Update severity levels from info/warning/violation/ban to low/medium/high/critical
- Fix findings callback format to match backend (detector_name, severity, title, description, evidence_json)
- Fix response format (ok/inserted instead of status/accepted)
- Update S3 key path to include date partition (events/{server_id}/{date}/...)
- Update all example findings in check documentation (movement, combat, interaction)
- Fix creating-modules.mdx example code to use correct backend format

* feat: add audit logging for module enabled state changes

Add comprehensive debugging infrastructure to track what's setting
modules to enabled=false:

- module_enabled_audit table: captures all INSERT/UPDATE/DELETE on
  server_modules.enabled field with source info (application_name,
  client_addr, query preview)
- Postgres trigger on server_modules to auto-log changes
- Enhanced toggle_module endpoint with detailed logging
- New GET /dashboard/:server_id/modules/audit endpoint to view audit log

* chore: update modules submodule

Updates to aac-modules@a615c6d which includes:
- Severity values aligned with API (high/medium instead of violation/warning)
- dev-release profile for fast deployments
- Updated deployment documentation and .cursorrules
@vercel

vercel Bot commented Dec 28, 2025

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Review Updated (UTC)
asyncanticheat.com Ready Ready Preview, Comment Dec 28, 2025 5:30pm

* feat: implement automatic server address discovery for API ping feature

Add Option 4 (hybrid auto-detect with override) for the dashboard's "API → Server" ping feature:

**Plugin Changes:**
- Add `server_address` config option to AsyncAnticheatConfig
- Send `X-Server-Address` header from plugin when configured

**API Changes:**
- Extract and store server address from headers in order of priority:
  1. Explicit `X-Server-Address` header (from plugin config)
  2. Auto-detected from `X-Forwarded-For` header
  3. Auto-detected from `X-Real-IP` header
- Filter out local/private IPs to avoid storing unusable addresses
- Store detected address in `callback_url` column for both handshake and ingest endpoints
- Moved `parse_bearer_token` and `sha256_hex` to shared `auth` module
- Add `extract_server_address` and `is_local_ip` utilities to `auth` module

**Security Improvements:**
- Add constant-time comparison for module callback token authentication
- Make CORS permissive mode explicit opt-in (requires `CORS_PERMISSIVE_DEV=true`)
- Use `subtle` crate for constant-time operations

**Documentation:**
- Update dashboard docs to explain automatic detection and manual override
- Clarify priority order and how the feature works

This allows most servers to automatically report their IP without configuration, while providing an override for edge cases (NAT, reverse proxies, etc).

* chore: bump plugin version to 0.3.0
Comment thread api/src/auth.rs
|| ip.starts_with("172.17.")
|| ip.starts_with("172.18.")
|| ip.starts_with("172.19.")
|| ip.starts_with("172.2")

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Public IPs incorrectly classified as private addresses

The is_local_ip function uses ip.starts_with("172.2") which incorrectly matches public IP addresses in the 172.2.x.x range. The RFC 1918 private range is 172.16.0.0/12 (172.16.0.0 - 172.31.255.255), so 172.2.x.x addresses are public. The pattern was intended to match 172.20.x.x through 172.29.x.x but the missing dot means it also catches 172.2.x.x. Servers with public IPs like 172.2.1.50 would have their address incorrectly filtered out, preventing the dashboard ping feature from working.

Fix in Cursor Fix in Web

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