release 1.3.1: remove API response bodies from diagnostics panel

This commit is contained in:
superdooper86
2026-05-11 13:45:09 +02:00
parent 7cb2159b4c
commit 9af0d6401c
4 changed files with 5 additions and 53 deletions
-35
View File
@@ -66,36 +66,6 @@ struct DiagnosticsView: View {
Divider() Divider()
// Bootstrap body
if !vm.diagBootstrapBody.isEmpty {
DiagSection(title: "Bootstrap Response (first 500 chars)") {
Text(vm.diagBootstrapBody)
.font(.system(size: 10, design: .monospaced))
.foregroundColor(.secondary)
.textSelection(.enabled)
.frame(maxWidth: .infinity, alignment: .leading)
.padding(8)
.background(Color.primary.opacity(0.04))
.cornerRadius(5)
}
Divider()
}
// Response body
if !vm.diagLastBody.isEmpty {
DiagSection(title: "Last API Response (first 500 chars)") {
Text(vm.diagLastBody)
.font(.system(size: 10, design: .monospaced))
.foregroundColor(.secondary)
.textSelection(.enabled)
.frame(maxWidth: .infinity, alignment: .leading)
.padding(8)
.background(Color.primary.opacity(0.04))
.cornerRadius(5)
}
Divider()
}
// Cookie summary // Cookie summary
DiagSection(title: "Cookie Store") { DiagSection(title: "Cookie Store") {
DiagRow("Total cookies", "\(vm.diagCookieCount)") DiagRow("Total cookies", "\(vm.diagCookieCount)")
@@ -190,11 +160,6 @@ struct DiagnosticsView: View {
lines.append("Claude cookies: \(vm.diagClaudeCookieCount)") lines.append("Claude cookies: \(vm.diagClaudeCookieCount)")
lines.append("Domains: \(vm.diagCookieDomains.joined(separator: ", "))") lines.append("Domains: \(vm.diagCookieDomains.joined(separator: ", "))")
lines.append("") lines.append("")
lines.append("Bootstrap body:")
lines.append(vm.diagBootstrapBody)
lines.append("")
lines.append("Last API response:")
lines.append(vm.diagLastBody)
lines.append("") lines.append("")
lines.append("Live cookies:") lines.append("Live cookies:")
for c in liveAllCookies { for c in liveAllCookies {
+2 -2
View File
@@ -15,9 +15,9 @@
<key>CFBundlePackageType</key> <key>CFBundlePackageType</key>
<string>APPL</string> <string>APPL</string>
<key>CFBundleShortVersionString</key> <key>CFBundleShortVersionString</key>
<string>1.3.0</string> <string>1.3.1</string>
<key>CFBundleVersion</key> <key>CFBundleVersion</key>
<string>74</string> <string>75</string>
<key>LSMinimumSystemVersion</key> <key>LSMinimumSystemVersion</key>
<string>13.0</string> <string>13.0</string>
<key>LSUIElement</key> <key>LSUIElement</key>
-5
View File
@@ -40,10 +40,8 @@ class UsageViewModel: ObservableObject {
@Published var diagCookieDomains: [String] = [] @Published var diagCookieDomains: [String] = []
@Published var diagLastPath: String = "" @Published var diagLastPath: String = ""
@Published var diagLastStatus: Int = 0 @Published var diagLastStatus: Int = 0
@Published var diagLastBody: String = ""
@Published var diagLastError: String = "" @Published var diagLastError: String = ""
@Published var diagLastActiveOrg: String = "" // lastActiveOrg cookie value from JS @Published var diagLastActiveOrg: String = "" // lastActiveOrg cookie value from JS
@Published var diagBootstrapBody: String = "" // raw bootstrap response (first 500 chars)
@Published var diagLastFetch: Date? = nil @Published var diagLastFetch: Date? = nil
init() { init() {
@@ -117,7 +115,6 @@ class UsageViewModel: ObservableObject {
diagLastPath = path diagLastPath = path
diagLastFetch = Date() diagLastFetch = Date()
diagLastStatus = status diagLastStatus = status
diagLastBody = String(body.prefix(500))
diagLastError = status != 200 ? "JS HTTP \(status)" : "" diagLastError = status != 200 ? "JS HTTP \(status)" : ""
return (status, body) return (status, body)
} }
@@ -181,7 +178,6 @@ class UsageViewModel: ObservableObject {
guard let http = response as? HTTPURLResponse else { throw AppError.networkError } guard let http = response as? HTTPURLResponse else { throw AppError.networkError }
let body = String(data: data, encoding: .utf8) ?? "" let body = String(data: data, encoding: .utf8) ?? ""
diagLastStatus = http.statusCode diagLastStatus = http.statusCode
diagLastBody = String(body.prefix(500))
if http.statusCode != 200 { if http.statusCode != 200 {
diagLastError = "HTTP \(http.statusCode)" diagLastError = "HTTP \(http.statusCode)"
} }
@@ -315,7 +311,6 @@ class UsageViewModel: ObservableObject {
guard body.trimmingCharacters(in: .whitespacesAndNewlines).hasPrefix("{") else { guard body.trimmingCharacters(in: .whitespacesAndNewlines).hasPrefix("{") else {
throw AppError.detail("Non-JSON response (HTML?): \(body.prefix(80))") throw AppError.detail("Non-JSON response (HTML?): \(body.prefix(80))")
} }
diagBootstrapBody = String(body.prefix(500))
guard let data = body.data(using: .utf8), guard let data = body.data(using: .utf8),
let json = try? JSONSerialization.jsonObject(with: data) as? [String: Any] else { let json = try? JSONSerialization.jsonObject(with: data) as? [String: Any] else {
return (nil, nil, nil) return (nil, nil, nil)
+3 -11
View File
@@ -1,12 +1,4 @@
## What's new in v1.3.0 ## What's new in v1.3.1
### Multi-org support ### Privacy
- App now uses the `lastActiveOrg` cookie to identify which organisation is active, matching exactly what the claude.ai frontend does. Previously the app always picked the first org returned by bootstrap, which is the personal "Individual Org" for users with multiple organisations — causing persistent 403 errors on all usage endpoints. - Diagnostics panel no longer displays API response bodies, which could contain account and financial data. Status codes, error messages, cookie names, and request paths are still shown.
- Plan label (e.g. **Max**, **Pro**, **Team**) now reads capabilities from the active org, not the first membership.
### Reliable API access via WebView
- All API calls now run through `WKWebView.callAsyncJavaScript`, making real same-origin browser requests instead of URLSession. Claude.ai's org-specific endpoints reject native HTTP clients (403) even with correct cookies and headers; running inside the browser context passes all server-side checks.
- A background WebView is created at startup when session cookies are detected, so usage data loads immediately without requiring a manual sign-in.
### Diagnostics
- New **Diagnostics** panel in Settings shows cookie store, last API request/response, bootstrap body, and the `lastActiveOrg` cookie value — making it easy to report issues.