using static qdr.app.tools.claudecodebalancewidget.MainForm; namespace qdr.app.tools.claudecodebalancewidget { public partial class EnhancedSettingsForm : Form { private TabControl tabControl; private TabPage sessionTabPage; private TabPage apiTabPage; private TabPage helpTabPage; // Session Cookie Tab Controls private TextBox sessionTokenTextBox; private Button sessionShowHideButton; private Button sessionTestButton; private Label sessionStatusLabel; private Label sessionInstructionsLabel; private bool isSessionTokenVisible = false; // API Key Tab Controls private TextBox apiKeyTextBox; private Button apiShowHideButton; private Button apiTestButton; private Label apiStatusLabel; private Label apiInstructionsLabel; private bool isApiKeyVisible = false; // Common Controls private RadioButton sessionRadioButton; private RadioButton apiRadioButton; private Button okButton; private Button cancelButton; public string SessionToken { get; private set; } public string ApiKey { get; private set; } public AuthenticationMethod AuthMethod { get; private set; } public EnhancedSettingsForm(string currentSessionToken, string currentApiKey, AuthenticationMethod currentAuthMethod) { SessionToken = currentSessionToken; ApiKey = currentApiKey; AuthMethod = currentAuthMethod; InitializeComponent(); sessionTokenTextBox.Text = currentSessionToken; apiKeyTextBox.Text = currentApiKey; if (currentAuthMethod == AuthenticationMethod.ApiKey) { apiRadioButton.Checked = true; tabControl.SelectedTab = apiTabPage; } else { sessionRadioButton.Checked = true; tabControl.SelectedTab = sessionTabPage; } } //private void InitializeComponent() //{ // this.SuspendLayout(); // // Form // this.ClientSize = new Size(600, 500); // this.Text = "Settings - Claude Balance Monitor"; // this.StartPosition = FormStartPosition.CenterParent; // this.FormBorderStyle = FormBorderStyle.FixedDialog; // this.MaximizeBox = false; // this.MinimizeBox = false; // // Authentication Method Selection // var authMethodLabel = new Label(); // authMethodLabel.Text = "Authentication Method:"; // authMethodLabel.Location = new Point(10, 10); // authMethodLabel.Size = new Size(150, 20); // authMethodLabel.Font = new Font("Segoe UI", 9, FontStyle.Bold); // this.Controls.Add(authMethodLabel); // sessionRadioButton = new RadioButton(); // sessionRadioButton.Text = "Session Cookie (Legacy)"; // sessionRadioButton.Location = new Point(10, 35); // sessionRadioButton.Size = new Size(200, 20); // sessionRadioButton.Checked = true; // sessionRadioButton.CheckedChanged += AuthMethod_CheckedChanged; // this.Controls.Add(sessionRadioButton); // apiRadioButton = new RadioButton(); // apiRadioButton.Text = "API Key (Recommended)"; // apiRadioButton.Location = new Point(220, 35); // apiRadioButton.Size = new Size(200, 20); // apiRadioButton.CheckedChanged += AuthMethod_CheckedChanged; // this.Controls.Add(apiRadioButton); // // Tab Control // tabControl = new TabControl(); // tabControl.Location = new Point(10, 65); // tabControl.Size = new Size(570, 350); // this.Controls.Add(tabControl); // // Session Cookie Tab // sessionTabPage = new TabPage("Session Cookie"); // CreateSessionTab(); // tabControl.TabPages.Add(sessionTabPage); // // API Key Tab // apiTabPage = new TabPage("API Key"); // CreateApiTab(); // tabControl.TabPages.Add(apiTabPage); // // Help Tab // helpTabPage = new TabPage("Help"); // CreateHelpTab(); // tabControl.TabPages.Add(helpTabPage); // // OK Button // okButton = new Button(); // okButton.Text = "OK"; // okButton.Location = new Point(405, 430); // okButton.Size = new Size(90, 30); // okButton.Click += OkButton_Click; // this.Controls.Add(okButton); // // Cancel Button // cancelButton = new Button(); // cancelButton.Text = "Cancel"; // cancelButton.Location = new Point(505, 430); // cancelButton.Size = new Size(90, 30); // cancelButton.Click += CancelButton_Click; // this.Controls.Add(cancelButton); // this.ResumeLayout(false); //} private void CreateSessionTab() { // Instructions sessionInstructionsLabel = new Label(); sessionInstructionsLabel.Text = "⚠️ WARNING: Session cookie method may no longer work due to enhanced security.\n\n" + "To get your session token (if still working):\n" + "1. Go to https://console.anthropic.com/settings/billing\n" + "2. Open Developer Tools (F12)\n" + "3. Go to Application → Cookies\n" + "4. Find and copy the 'sessionKey' cookie value\n\n" + "Note: This method is deprecated. Use API Key instead."; sessionInstructionsLabel.Location = new Point(10, 10); sessionInstructionsLabel.Size = new Size(540, 120); sessionInstructionsLabel.Font = new Font("Segoe UI", 9); sessionInstructionsLabel.ForeColor = Color.DarkOrange; sessionTabPage.Controls.Add(sessionInstructionsLabel); // Session Token Label var sessionTokenLabel = new Label(); sessionTokenLabel.Text = "Session Token:"; sessionTokenLabel.Location = new Point(10, 140); sessionTokenLabel.Size = new Size(100, 20); sessionTokenLabel.Font = new Font("Segoe UI", 9, FontStyle.Bold); sessionTabPage.Controls.Add(sessionTokenLabel); // Session Token TextBox sessionTokenTextBox = new TextBox(); sessionTokenTextBox.Location = new Point(10, 165); sessionTokenTextBox.Size = new Size(420, 23); sessionTokenTextBox.UseSystemPasswordChar = true; sessionTokenTextBox.Font = new Font("Consolas", 9); sessionTabPage.Controls.Add(sessionTokenTextBox); // Session Show/Hide Button sessionShowHideButton = new Button(); sessionShowHideButton.Text = "Show"; sessionShowHideButton.Location = new Point(440, 165); sessionShowHideButton.Size = new Size(60, 23); sessionShowHideButton.Click += SessionShowHideButton_Click; sessionTabPage.Controls.Add(sessionShowHideButton); // Session Test Button sessionTestButton = new Button(); sessionTestButton.Text = "Test Connection"; sessionTestButton.Location = new Point(10, 200); sessionTestButton.Size = new Size(120, 30); sessionTestButton.Click += SessionTestButton_Click; sessionTabPage.Controls.Add(sessionTestButton); // Session Status Label sessionStatusLabel = new Label(); sessionStatusLabel.Name = "sessionStatusLabel"; sessionStatusLabel.Text = "Enter your session token and click 'Test Connection'"; sessionStatusLabel.Location = new Point(140, 205); sessionStatusLabel.Size = new Size(360, 20); sessionStatusLabel.ForeColor = Color.Gray; sessionTabPage.Controls.Add(sessionStatusLabel); } private void CreateApiTab() { // Instructions apiInstructionsLabel = new Label(); apiInstructionsLabel.Text = "✅ RECOMMENDED: Use API Key for reliable access.\n\n" + "To get your API key:\n" + "1. Go to https://console.anthropic.com/\n" + "2. Sign up or log in to your account\n" + "3. Go to Settings → API Keys\n" + "4. Click 'Create Key' and copy the generated key\n" + "5. Make sure you have billing set up and credits available\n\n" + "Note: API keys provide more reliable access than session cookies."; apiInstructionsLabel.Location = new Point(10, 10); apiInstructionsLabel.Size = new Size(540, 120); apiInstructionsLabel.Font = new Font("Segoe UI", 9); apiInstructionsLabel.ForeColor = Color.DarkGreen; apiTabPage.Controls.Add(apiInstructionsLabel); // API Key Label var apiKeyLabel = new Label(); apiKeyLabel.Text = "API Key:"; apiKeyLabel.Location = new Point(10, 140); apiKeyLabel.Size = new Size(100, 20); apiKeyLabel.Font = new Font("Segoe UI", 9, FontStyle.Bold); apiTabPage.Controls.Add(apiKeyLabel); // API Key TextBox apiKeyTextBox = new TextBox(); apiKeyTextBox.Location = new Point(10, 165); apiKeyTextBox.Size = new Size(420, 23); apiKeyTextBox.UseSystemPasswordChar = true; apiKeyTextBox.Font = new Font("Consolas", 9); apiTabPage.Controls.Add(apiKeyTextBox); // API Show/Hide Button apiShowHideButton = new Button(); apiShowHideButton.Text = "Show"; apiShowHideButton.Location = new Point(440, 165); apiShowHideButton.Size = new Size(60, 23); apiShowHideButton.Click += ApiShowHideButton_Click; apiTabPage.Controls.Add(apiShowHideButton); // API Test Button apiTestButton = new Button(); apiTestButton.Text = "Test API Key"; apiTestButton.Location = new Point(10, 200); apiTestButton.Size = new Size(120, 30); apiTestButton.Click += ApiTestButton_Click; apiTabPage.Controls.Add(apiTestButton); // API Status Label apiStatusLabel = new Label(); apiStatusLabel.Name = "apiStatusLabel"; apiStatusLabel.Text = "Enter your API key and click 'Test API Key'"; apiStatusLabel.Location = new Point(140, 205); apiStatusLabel.Size = new Size(360, 20); apiStatusLabel.ForeColor = Color.Gray; apiTabPage.Controls.Add(apiStatusLabel); // Additional API Information var apiInfoLabel = new Label(); apiInfoLabel.Text = "💡 Tips:\n" + "• API keys start with 'sk-ant-api03-'\n" + "• Keep your API key secure and don't share it\n" + "• You can monitor usage in the Anthropic Console\n" + "• API access requires a paid plan with credits"; apiInfoLabel.Location = new Point(10, 240); apiInfoLabel.Size = new Size(540, 80); apiInfoLabel.Font = new Font("Segoe UI", 8.5f); apiInfoLabel.ForeColor = Color.DarkBlue; apiTabPage.Controls.Add(apiInfoLabel); } private void CreateHelpTab() { var helpText = new RichTextBox(); helpText.Text = "CLAUDE BALANCE MONITOR HELP\n\n" + "AUTHENTICATION METHODS:\n\n" + "1. API Key (Recommended)\n" + " ✅ Most reliable method\n" + " ✅ Official Anthropic authentication\n" + " ✅ Works with current security measures\n" + " ❌ Requires paid Anthropic Console account\n\n" + "2. Session Cookie (Legacy)\n" + " ❌ May not work due to enhanced security\n" + " ❌ Prone to expiration\n" + " ❌ May trigger Forbidden errors\n" + " ✅ No additional setup if it works\n\n" + "TROUBLESHOOTING:\n\n" + "Forbidden Error:\n" + "• Anthropic has enhanced security measures\n" + "• Session cookies may no longer work\n" + "• Switch to API Key authentication\n" + "• Ensure you have a valid Anthropic Console account\n\n" + "API Key Issues:\n" + "• Verify the key starts with 'sk-ant-api03-'\n" + "• Check that billing is set up in Console\n" + "• Ensure you have available credits\n" + "• Make sure the key has proper permissions\n\n" + "No Balance Found:\n" + "• Check your Anthropic Console billing page manually\n" + "• Verify your account has API access\n" + "• Try refreshing the widget manually\n\n" + "GETTING HELP:\n" + "• Check Anthropic's official documentation\n" + "• Visit https://support.anthropic.com/\n" + "• Ensure your account is properly set up\n\n" + "Note: This tool is unofficial and may break if Anthropic changes their systems."; helpText.Location = new Point(10, 10); helpText.Size = new Size(540, 300); helpText.Font = new Font("Segoe UI", 9); helpText.ReadOnly = true; helpText.BackColor = SystemColors.Control; helpTabPage.Controls.Add(helpText); } private void AuthMethod_CheckedChanged(object sender, EventArgs e) { if (sessionRadioButton.Checked) { tabControl.SelectedTab = sessionTabPage; } else if (apiRadioButton.Checked) { tabControl.SelectedTab = apiTabPage; } } private void SessionShowHideButton_Click(object sender, EventArgs e) { isSessionTokenVisible = !isSessionTokenVisible; sessionTokenTextBox.UseSystemPasswordChar = !isSessionTokenVisible; sessionShowHideButton.Text = isSessionTokenVisible ? "Hide" : "Show"; } private void ApiShowHideButton_Click(object sender, EventArgs e) { isApiKeyVisible = !isApiKeyVisible; apiKeyTextBox.UseSystemPasswordChar = !isApiKeyVisible; apiShowHideButton.Text = isApiKeyVisible ? "Hide" : "Show"; } private async void SessionTestButton_Click(object sender, EventArgs e) { var testToken = sessionTokenTextBox.Text.Trim(); if (string.IsNullOrEmpty(testToken)) { sessionStatusLabel.Text = "Please enter a session token"; sessionStatusLabel.ForeColor = Color.Red; return; } sessionStatusLabel.Text = "Testing connection..."; sessionStatusLabel.ForeColor = Color.Blue; sessionTestButton.Enabled = false; try { using (var testClient = new HttpClient()) { testClient.Timeout = TimeSpan.FromSeconds(10); testClient.DefaultRequestHeaders.Add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"); testClient.DefaultRequestHeaders.Add("Cookie", $"sessionKey={testToken}"); testClient.DefaultRequestHeaders.Add("X-Requested-With", "XMLHttpRequest"); testClient.DefaultRequestHeaders.Add("Referer", "https://console.anthropic.com/"); var response = await testClient.GetAsync("https://console.anthropic.com/settings/billing"); if (response.IsSuccessStatusCode) { sessionStatusLabel.Text = "✓ Connection successful!"; sessionStatusLabel.ForeColor = Color.Green; } else if (response.StatusCode == System.Net.HttpStatusCode.Forbidden) { sessionStatusLabel.Text = "✗ Forbidden - Session cookies may no longer work. Try API Key."; sessionStatusLabel.ForeColor = Color.Red; } else { sessionStatusLabel.Text = $"✗ Connection failed (Status: {response.StatusCode})"; sessionStatusLabel.ForeColor = Color.Red; } } } catch (Exception ex) { sessionStatusLabel.Text = $"✗ Connection error: {ex.Message}"; sessionStatusLabel.ForeColor = Color.Red; } finally { sessionTestButton.Enabled = true; } } private async void ApiTestButton_Click(object sender, EventArgs e) { var testApiKey = apiKeyTextBox.Text.Trim(); if (string.IsNullOrEmpty(testApiKey)) { apiStatusLabel.Text = "Please enter an API key"; apiStatusLabel.ForeColor = Color.Red; return; } if (!testApiKey.StartsWith("sk-ant-api03-")) { apiStatusLabel.Text = "API key should start with 'sk-ant-api03-'"; apiStatusLabel.ForeColor = Color.Orange; return; } apiStatusLabel.Text = "Testing API key..."; apiStatusLabel.ForeColor = Color.Blue; apiTestButton.Enabled = false; try { using (var testClient = new HttpClient()) { testClient.Timeout = TimeSpan.FromSeconds(10); // Test with a simple API call var request = new HttpRequestMessage(HttpMethod.Post, "https://api.anthropic.com/v1/messages"); request.Headers.Add("x-api-key", testApiKey); request.Headers.Add("anthropic-version", "2023-06-01"); // Simple test message var testContent = @"{ ""model"": ""claude-3-5-haiku-20241022"", ""max_tokens"": 10, ""messages"": [{ ""role"": ""user"", ""content"": ""Hello"" }] }"; request.Content = new StringContent(testContent, System.Text.Encoding.UTF8, "application/json"); var response = await testClient.SendAsync(request); if (response.IsSuccessStatusCode) { apiStatusLabel.Text = "✓ API key is valid and working!"; apiStatusLabel.ForeColor = Color.Green; } else if (response.StatusCode == System.Net.HttpStatusCode.Unauthorized) { apiStatusLabel.Text = "✗ Invalid API key"; apiStatusLabel.ForeColor = Color.Red; } else if (response.StatusCode == System.Net.HttpStatusCode.PaymentRequired) { apiStatusLabel.Text = "✗ No credits available. Add funds to your account."; apiStatusLabel.ForeColor = Color.Orange; } else { apiStatusLabel.Text = $"✗ API error (Status: {response.StatusCode})"; apiStatusLabel.ForeColor = Color.Red; } } } catch (Exception ex) { apiStatusLabel.Text = $"✗ Connection error: {ex.Message}"; apiStatusLabel.ForeColor = Color.Red; } finally { apiTestButton.Enabled = true; } } private void OkButton_Click(object sender, EventArgs e) { SessionToken = sessionTokenTextBox.Text.Trim(); ApiKey = apiKeyTextBox.Text.Trim(); if (apiRadioButton.Checked) { AuthMethod = AuthenticationMethod.ApiKey; if (string.IsNullOrEmpty(ApiKey)) { MessageBox.Show("Please enter an API key or switch to session cookie method.", "Missing API Key", MessageBoxButtons.OK, MessageBoxIcon.Warning); return; } } else { AuthMethod = AuthenticationMethod.SessionCookie; if (string.IsNullOrEmpty(SessionToken)) { MessageBox.Show("Please enter a session token or switch to API key method.", "Missing Session Token", MessageBoxButtons.OK, MessageBoxIcon.Warning); return; } } DialogResult = DialogResult.OK; Close(); } private void CancelButton_Click(object sender, EventArgs e) { DialogResult = DialogResult.Cancel; Close(); } } }