v2.0.7 — Show account email in settings auth section

This commit is contained in:
superdooper86
2026-05-07 15:21:35 +02:00
parent a1c3c0b314
commit d2815d65ce
5 changed files with 54 additions and 15 deletions
+25 -7
View File
@@ -596,13 +596,31 @@ struct SettingsView: View {
.font(.system(size: 12, weight: .medium))
.foregroundColor(.secondary)
HStack(spacing: 6) {
Circle()
.fill(vm.isSignedIn ? Color.green : Color.orange)
.frame(width: 7, height: 7)
Text(vm.isSignedIn ? "Signed in to claude.ai" : "Not signed in")
.font(.system(size: 12, weight: .medium))
.foregroundColor(vm.isSignedIn ? .primary : .orange)
if vm.isSignedIn {
VStack(alignment: .leading, spacing: 2) {
HStack(spacing: 6) {
Circle()
.fill(Color.green)
.frame(width: 7, height: 7)
Text("Signed in to claude.ai")
.font(.system(size: 13, weight: .semibold))
}
if !vm.userEmail.isEmpty {
Text(vm.userEmail)
.font(.system(size: 11.5))
.foregroundColor(.secondary)
.padding(.leading, 13)
}
}
} else {
HStack(spacing: 6) {
Circle()
.fill(Color.orange)
.frame(width: 7, height: 7)
Text("Not signed in")
.font(.system(size: 13, weight: .semibold))
.foregroundColor(.orange)
}
}
Text("Your session is stored locally and persists across restarts.")
+2 -2
View File
@@ -15,9 +15,9 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>2.0.6</string>
<string>2.0.7</string>
<key>CFBundleVersion</key>
<string>13</string>
<string>14</string>
<key>LSMinimumSystemVersion</key>
<string>13.0</string>
<key>LSUIElement</key>
+22 -1
View File
@@ -14,6 +14,7 @@ class UsageViewModel: ObservableObject {
@Published var planLabel: String = "Claude"
@Published var isNotAuthenticated: Bool = false
@Published var isSignedIn: Bool = false
@Published var userEmail: String = ""
@Published var triggerLogin: Bool = false
@Published var showInMenuBar: Bool = true {
didSet { UserDefaults.standard.set(showInMenuBar, forKey: "show_in_menubar") }
@@ -46,6 +47,7 @@ class UsageViewModel: ObservableObject {
isSignedIn = false
isNotAuthenticated = true
lastUpdated = nil
userEmail = ""
limits = []
extraUsage = nil
prepaidCredits = nil
@@ -63,7 +65,9 @@ class UsageViewModel: ObservableObject {
async let usageFetch = fetchUsage(orgId: orgId)
async let prepaidFetch = fetchPrepaidCredits(orgId: orgId)
async let overageFetch = fetchOverageSpendLimit(orgId: orgId)
let (usage, prepaid, overage) = try await (usageFetch, prepaidFetch, overageFetch)
async let emailFetch = fetchUserEmail()
let (usage, prepaid, overage, email) = try await (usageFetch, prepaidFetch, overageFetch, emailFetch)
if let email { userEmail = email }
limits = buildLimits(from: usage)
extraUsage = usage.extraUsage
prepaidCredits = prepaid
@@ -121,6 +125,23 @@ class UsageViewModel: ObservableObject {
return try JSONDecoder().decode(UsageResponse.self, from: data)
}
private func fetchUserEmail() async throws -> String? {
let url = URL(string: "https://claude.ai/api/bootstrap")!
var req = URLRequest(url: url)
req.setValue("application/json", forHTTPHeaderField: "accept")
let cookies = await WKWebsiteDataStore.default().httpCookieStore.allCookies()
let claudeCookies = cookies.filter { $0.domain.contains("claude.ai") }
if let header = HTTPCookie.requestHeaderFields(with: claudeCookies)["Cookie"] {
req.setValue(header, forHTTPHeaderField: "Cookie")
}
let (data, response) = try await URLSession.shared.data(for: req)
guard let http = response as? HTTPURLResponse, http.statusCode == 200 else { return nil }
guard let json = try? JSONSerialization.jsonObject(with: data) as? [String: Any],
let account = json["account"] as? [String: Any],
let email = account["email_address"] as? String else { return nil }
return email
}
private func fetchPrepaidCredits(orgId: String) async throws -> PrepaidCredits? {
let url = URL(string: "https://claude.ai/api/organizations/\(orgId)/prepaid/credits")!
var req = URLRequest(url: url)