Skip to content

feat(support): "Support-Paket senden" in Settings → Help - #31

Merged
CallMeTechie merged 1 commit into
mainfrom
feat/support-bundle
Oct 2, 2026
Merged

CallMeTechie merged 1 commit into
mainfrom
feat/support-bundle

Conversation

@CallMeTechie

Copy link
Copy Markdown
Owner

Android part of "Support-Paket per Knopfdruck". Server side: CallMeTechie/gatecontrol#257, contract in docs/feature-support-bundle.md there. Desktop: gatecontrol-client-core#15.

Changes

  • core/common SupportRedactor: the same rule set as client-core and the server pass.
    • PrivateKey/PresharedKey lines.
    • Header values: Authorization, Proxy-Authorization, Cookie, Set-Cookie, X-API-Token, X-API-Key.
    • key=value / JSON pairs with a secret-like key.
    • Free-standing patterns: gc_… tokens, JWTs, PEM private keys, 44-char base64 keys, hex strings of 32+ chars, setup codes.
    • redactValue masks secret-named keys at any depth and drops __proto__/constructor/prototype. All regexes run in linear time.
  • core/network:
    • ApiClient.uploadSupportBundle(peerId, RequestBody) → POST api/v1/client/support-bundle.
    • SupportBundleUploader runs a final redaction pass, then Gson (no HTML escaping), then gzip as application/gzip.
    • HeartbeatResponse gains supportBundleRequested and supportBundleRequestedAt.
  • app SupportBundleCollector builds a schema 1 bundle with:
    • client: product android, app version, Android version/API, device, ABI, locale;
    • tunnel: state, connected since, last handshake age, rx/tx;
    • settings: snapshot without the API token;
    • the stored WireGuard config with keys masked;
    • network: interfaces (no MAC addresses) plus the active network's transports, DNS servers and routes;
    • the last 2000 lines of cacheDir/logs (rotated file included) and recent W/E lines.
  • Settings → Hilfe:
    • New row "Support-Paket senden".
    • Tapping it opens an AlertDialog: "Diagnosedaten an senden?", listing what is included and what is not.
    • Only "Senden" uploads. The result is shown as a Toast (UiText, so it uses the app language).
    • Error mapping: 429 → rate limited, 413 → too large, 401/403 → rejected, 404 → server too old, otherwise a generic error.
  • Admin request: TunnelSupervisor puts the heartbeat flag into SupportRequestHolder. The Settings row then shows "Dein Administrator hat ein Support-Paket angefordert" in the accent colour, and the dialog says so too. The upload is sent with reason: admin_request and clears the flag. Nothing is sent without confirmation.
  • de/en strings. Timber lines carry no credential words (CI grep passes).

Tests

  • SupportRedactorTest (8), SupportBundleUploaderTest (3, MockWebServer: path, peerId, gzip, redaction, 429 → HttpException, heartbeat model), SupportBundleCollectorTest (4: all sections, no leak of the WG key, PSK or token in the serialized JSON, log tail across rotation, request holder), SettingsViewModelTest (+5: dialog before upload, settings without the token, 429 mapping, admin request flow, not configured).
  • Local runs, all green:
    • ./gradlew testDebugUnitTest lintDebug assembleDebug
    • ./gradlew lintRelease test

Follow-up (not in this PR)

The admin request is shown only in Settings. A system notification that leads there would make it visible without opening the app.

🤖 Generated with Claude Code

https://claude.ai/code/session_016xX1efcZF1f6G9rhmaJNLD


Generated by Claude Code

- SupportRedactor (core/common): same rules as the desktop/server
  redaction — WireGuard PrivateKey/PresharedKey, Authorization /
  X-API-Token / Cookie values, secret-named keys, gc_ tokens, JWTs, PEM
  keys, key-like base64/hex, setup codes; unsafe keys dropped
- SupportBundleCollector (app): app/Android version, device, tunnel state
  + handshake age, settings without the API token, WireGuard config
  without keys, interfaces / active network (DNS, routes), last 2000 log
  lines from cacheDir/logs, recent W/E lines
- SupportBundleUploader + Retrofit endpoint (core/network): final
  redaction pass, gzip JSON to POST /api/v1/client/support-bundle
- Settings: row "Support-Paket senden", confirmation dialog
  ("Diagnosedaten an <server> senden?" with what is included),
  toast with the result; an admin request reported by the heartbeat is
  highlighted in the row and sent as reason admin_request
- de/en strings, unit tests for redaction, collector, uploader and the
  view model flow

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016xX1efcZF1f6G9rhmaJNLD
@CallMeTechie
CallMeTechie merged commit 3244e79 into main Oct 2, 2026
3 checks passed
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.

2 participants