v2.0.7 — Show account email in settings auth section
This commit is contained in:
@@ -596,13 +596,31 @@ struct SettingsView: View {
|
|||||||
.font(.system(size: 12, weight: .medium))
|
.font(.system(size: 12, weight: .medium))
|
||||||
.foregroundColor(.secondary)
|
.foregroundColor(.secondary)
|
||||||
|
|
||||||
HStack(spacing: 6) {
|
if vm.isSignedIn {
|
||||||
Circle()
|
VStack(alignment: .leading, spacing: 2) {
|
||||||
.fill(vm.isSignedIn ? Color.green : Color.orange)
|
HStack(spacing: 6) {
|
||||||
.frame(width: 7, height: 7)
|
Circle()
|
||||||
Text(vm.isSignedIn ? "Signed in to claude.ai" : "Not signed in")
|
.fill(Color.green)
|
||||||
.font(.system(size: 12, weight: .medium))
|
.frame(width: 7, height: 7)
|
||||||
.foregroundColor(vm.isSignedIn ? .primary : .orange)
|
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.")
|
Text("Your session is stored locally and persists across restarts.")
|
||||||
|
|||||||
@@ -15,9 +15,9 @@
|
|||||||
<key>CFBundlePackageType</key>
|
<key>CFBundlePackageType</key>
|
||||||
<string>APPL</string>
|
<string>APPL</string>
|
||||||
<key>CFBundleShortVersionString</key>
|
<key>CFBundleShortVersionString</key>
|
||||||
<string>2.0.6</string>
|
<string>2.0.7</string>
|
||||||
<key>CFBundleVersion</key>
|
<key>CFBundleVersion</key>
|
||||||
<string>13</string>
|
<string>14</string>
|
||||||
<key>LSMinimumSystemVersion</key>
|
<key>LSMinimumSystemVersion</key>
|
||||||
<string>13.0</string>
|
<string>13.0</string>
|
||||||
<key>LSUIElement</key>
|
<key>LSUIElement</key>
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ class UsageViewModel: ObservableObject {
|
|||||||
@Published var planLabel: String = "Claude"
|
@Published var planLabel: String = "Claude"
|
||||||
@Published var isNotAuthenticated: Bool = false
|
@Published var isNotAuthenticated: Bool = false
|
||||||
@Published var isSignedIn: Bool = false
|
@Published var isSignedIn: Bool = false
|
||||||
|
@Published var userEmail: String = ""
|
||||||
@Published var triggerLogin: Bool = false
|
@Published var triggerLogin: Bool = false
|
||||||
@Published var showInMenuBar: Bool = true {
|
@Published var showInMenuBar: Bool = true {
|
||||||
didSet { UserDefaults.standard.set(showInMenuBar, forKey: "show_in_menubar") }
|
didSet { UserDefaults.standard.set(showInMenuBar, forKey: "show_in_menubar") }
|
||||||
@@ -46,6 +47,7 @@ class UsageViewModel: ObservableObject {
|
|||||||
isSignedIn = false
|
isSignedIn = false
|
||||||
isNotAuthenticated = true
|
isNotAuthenticated = true
|
||||||
lastUpdated = nil
|
lastUpdated = nil
|
||||||
|
userEmail = ""
|
||||||
limits = []
|
limits = []
|
||||||
extraUsage = nil
|
extraUsage = nil
|
||||||
prepaidCredits = nil
|
prepaidCredits = nil
|
||||||
@@ -63,7 +65,9 @@ class UsageViewModel: ObservableObject {
|
|||||||
async let usageFetch = fetchUsage(orgId: orgId)
|
async let usageFetch = fetchUsage(orgId: orgId)
|
||||||
async let prepaidFetch = fetchPrepaidCredits(orgId: orgId)
|
async let prepaidFetch = fetchPrepaidCredits(orgId: orgId)
|
||||||
async let overageFetch = fetchOverageSpendLimit(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)
|
limits = buildLimits(from: usage)
|
||||||
extraUsage = usage.extraUsage
|
extraUsage = usage.extraUsage
|
||||||
prepaidCredits = prepaid
|
prepaidCredits = prepaid
|
||||||
@@ -121,6 +125,23 @@ class UsageViewModel: ObservableObject {
|
|||||||
return try JSONDecoder().decode(UsageResponse.self, from: data)
|
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? {
|
private func fetchPrepaidCredits(orgId: String) async throws -> PrepaidCredits? {
|
||||||
let url = URL(string: "https://claude.ai/api/organizations/\(orgId)/prepaid/credits")!
|
let url = URL(string: "https://claude.ai/api/organizations/\(orgId)/prepaid/credits")!
|
||||||
var req = URLRequest(url: url)
|
var req = URLRequest(url: url)
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
[](https://www.apple.com/macos/)
|
[](https://www.apple.com/macos/)
|
||||||
[](https://swift.org)
|
[](https://swift.org)
|
||||||
[](https://github.com/superdooper86/claudechecker/releases)
|
[](https://github.com/superdooper86/claudechecker/releases)
|
||||||
[](LICENSE)
|
[](LICENSE)
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
@@ -138,7 +138,7 @@ ClaudeChecker reads from the following `claude.ai` API endpoints (authenticated
|
|||||||
|
|
||||||
| Endpoint | Used for |
|
| Endpoint | Used for |
|
||||||
|---|---|
|
|---|---|
|
||||||
| `/api/bootstrap` | Organisation UUID |
|
| `/api/bootstrap` | Organisation UUID and account email |
|
||||||
| `/api/organizations/{id}/usage` | 5-hour and 7-day quota windows |
|
| `/api/organizations/{id}/usage` | 5-hour and 7-day quota windows |
|
||||||
| `/api/organizations/{id}/overage_spend_limit` | Extra usage spent and monthly limit |
|
| `/api/organizations/{id}/overage_spend_limit` | Extra usage spent and monthly limit |
|
||||||
| `/api/organizations/{id}/prepaid/credits` | Current credit balance |
|
| `/api/organizations/{id}/prepaid/credits` | Current credit balance |
|
||||||
|
|||||||
+3
-3
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"version": "2.0.6",
|
"version": "2.0.7",
|
||||||
"url": "https://github.com/superdooper86/claudechecker/releases/download/v2.0.6/ClaudeChecker.zip",
|
"url": "https://github.com/superdooper86/claudechecker/releases/download/v2.0.7/ClaudeChecker.zip",
|
||||||
"notes": "Authentication section shows sign-in status with re-authenticate and sign out options."
|
"notes": "Show account email in settings auth section."
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user