Saturday, 16 August 2025

Ubuntu 24.x/25.x VMware Ultimate Optimization Script



#!/bin/bash




# Ubuntu 24.x/25.x VMware Ultimate Optimization Script

# Includes display/audio drivers, networking tools, and productivity software

# Compatible with VMware Workstation 17.x




# Check if running as root

if [ "$(id -u)" -ne 0 ]; then

echo "This script must be run as root. Use sudo." >&2

exit 1

fi




# Check if we're running in a VMware VM

if ! dmidecode -s system-product-name | grep -iq "VMware"; then

echo "This script should only be run in a VMware virtual machine." >&2

exit 1

fi




# Determine Ubuntu version

UBUNTU_VERSION=$(lsb_release -rs)

echo "Detected Ubuntu version: $UBUNTU_VERSION"




# Update system first

echo "Updating system packages..."

apt update && apt upgrade -y




# 1. Install VMware tools and drivers

echo "Installing VMware display and audio drivers..."

apt install -y --no-install-recommends open-vm-tools open-vm-tools-desktop \

open-vm-tools-dkms pulseaudio pavucontrol




# Enable services

systemctl enable vmtoolsd

systemctl enable vmware-tools

systemctl restart vmtoolsd




# 2. Install VMware Workstation 17.x specific audio components

echo "Configuring audio for VMware Workstation 17.x..."

apt install -y alsa-utils libasound2-plugins

cat > /etc/pulse/default.pa << 'EOL'

load-module module-alsa-sink device=hw:0,0

load-module module-alsa-source device=hw:0,0

load-module module-alsa-card device_id=0 name=vmware

EOL




# 3. Enhanced display configuration

echo "Optimizing display settings..."

cat > /etc/X11/xorg.conf.d/10-vmware.conf << 'EOL'

Section "Device"

Identifier "VMware SVGA"

Driver "vmware"

Option "Accel" "true"

Option "UseFBDev" "true"

Option "UseGLX" "true"

EndSection




Section "Screen"

Identifier "Default Screen"

Device "VMware SVGA"

DefaultDepth 24

SubSection "Display"

Depth 24

Modes "1920x1080" "1600x900" "1366x768"

EndSubSection

EndSection

EOL




# 4. Networking tools and utilities

echo "Installing advanced networking tools..."

apt install -y \

net-tools iproute2 nmap tcpdump wireshark iperf3 \

netcat-openbsd curl wget whois dnsutils openssh-server \

bridge-utils openvpn network-manager-openvpn \

iftop nethogs vnstat traceroute mtr-tiny




# Enable SSH

systemctl enable ssh

systemctl start ssh




# 5. Productivity tools and editors

echo "Installing productivity tools..."

apt install -y \

vim neovem micro emacs-nox \

git git-extras tig \

tmux screen byobu \

htop bashtop gotop \

tree silversearcher-ag ripgrep fzf \

jq yq csvkit xmlstarlet \

python3-pip python3-venv \

build-essential cmake gdb \

unzip p7zip-full rar unrar \

ncdu rsync




# Install Visual Studio Code (official Microsoft repo)

if [ ! -f /usr/share/keyrings/packages.microsoft.gpg ]; then

curl -sSL https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > /usr/share/keyrings/packages.microsoft.gpg

echo "deb [arch=amd64 signed-by=/usr/share/keyrings/packages.microsoft.gpg] https://packages.microsoft.com/repos/vscode stable main" > /etc/apt/sources.list.d/vscode.list

apt update

fi

apt install -y code




# 6. System monitoring and optimization

echo "Installing system monitoring tools..."

apt install -y \

sysstat iotop smartmontools lm-sensors \

cockpit cockpit-storaged cockpit-networkmanager \

earlyoom




# Configure early OOM killer

sed -i 's/EARLYOOM_ARGS="-r 60"/EARLYOOM_ARGS="-r 60 -m 5 -s 10"/g' /etc/default/earlyoom

systemctl enable earlyoom

systemctl start earlyoom




# 7. Filesystem and storage tools

echo "Installing filesystem tools..."

apt install -y \

ntfs-3g exfat-utils fuseiso \

duf baobab disk-manager \

udisks2 udiskie




# 8. Multimedia and graphics

echo "Installing multimedia support..."

apt install -y \

ffmpeg vlc gimp inkscape \

imagemagick graphicsmagick \

libavcodec-extra




# 9. Virtualization and container tools

echo "Installing container tools..."

apt install -y \

docker.io docker-compose podman \

virt-manager libvirt-daemon-system




# Add user to virtualization groups

usermod -aG docker $SUDO_USER

usermod -aG libvirt $SUDO_USER

usermod -aG kvm $SUDO_USER




# 10. Final system optimizations

echo "Applying final optimizations..."




# Enable TRIM if using SSD

systemctl enable fstrim.timer

systemctl start fstrim.timer




# Improve swapiness

echo "vm.swappiness=10" >> /etc/sysctl.conf




# Improve filesystem access

echo "vm.dirty_ratio=10" >> /etc/sysctl.conf

echo "vm.dirty_background_ratio=5" >> /etc/sysctl.conf




# Apply changes

sysctl -p




# Enable VMware shared folders (if configured)

mkdir -p /mnt/hgfs

systemctl enable vmware-vmblock-fuse

systemctl start vmware-vmblock-fuse




# Enable drag and drop

cat > /etc/vmware-tools/dnd.conf << 'EOL'

dnd.enable = true

copy.maxFileSize = "2000000000"

copy.maxBlockSize = "1000000"

EOL




# Enable clipboard

cat > /etc/vmware-tools/tools.conf << 'EOL'

[guestinfo]

primary-nics=eth0

[isolation]

busy-timeout = 300

[resolution]

perSession = TRUE

[ui]

show-dnd-tip = TRUE

show-copy-tip = TRUE

EOL




# Create desktop shortcuts for common tools

if [ -d "/home/$SUDO_USER/Desktop" ]; then

# Create VMTools restart shortcut

cat > "/home/$SUDO_USER/Desktop/Restart VMTools.desktop" << 'EOL'

[Desktop Entry]

Version=1.0

Type=Application

Name=Restart VMware Tools

Exec=sudo systemctl restart vmtoolsd

Icon=vmware

Terminal=true

Categories=System;

EOL

chown $SUDO_USER:$SUDO_USER "/home/$SUDO_USER/Desktop/Restart VMTools.desktop"

chmod +x "/home/$SUDO_USER/Desktop/Restart VMTools.desktop"

fi




echo "################################################################"

echo "# Optimization complete! #"

echo "# #"

echo "# Installed components: #"

echo "# - VMware display and audio drivers #"

echo "# - Advanced networking tools #"

echo "# - Productivity editors and utilities #"

echo "# - System monitoring tools #"

echo "# - Container and virtualization support #"

echo "# #"

echo "# Recommended actions: #"

echo "# 1. Reboot the VM #"

echo "# 2. In VMware settings, enable: #"

echo "# - 3D acceleration #"

echo "# - Clipboard sharing #"

echo "# - Drag and drop #"

echo "# - Shared folders (if needed) #"

echo "################################################################"

Sunday, 16 June 2024

Joomla 5 LDAP Plugin

 <?php

defined('_JEXEC') or die;


use Joomla\CMS\Plugin\CMSPlugin;

use Joomla\CMS\Factory;

use Joomla\CMS\Router\Route;

use Joomla\CMS\HTML\HTMLHelper;

use Joomla\CMS\Language\Text;

use Joomla\CMS\Log\Log;

use Joomla\CMS\Form\Form;

use Joomla\Utilities\ArrayHelper;


JLoader::register('JFormFieldLdapTestButton', JPATH_PLUGINS . '/authentication/ldapauth/fields/ldaptestbutton.php');


class PlgAuthenticationLdapauth extends CMSPlugin

{

    public function onUserAuthenticate($credentials, $options, &$response)

    {

        // Load plugin parameters

        $params = $this->params;


        // LDAP connection parameters

        $ldaphosts = [

            $params->get('ldaphost1'),

            $params->get('ldaphost2'),

            $params->get('ldaphost3')

        ];

        $port = $params->get('portdefault', '389') === 'custom' ? $params->get('customport', 389) : $params->get('portdefault', 389);

        $ldapv3 = $params->get('ldapv3', 0);

        $connectionsecurity = $params->get('connectionsecurity', 'none');

        $followreferrals = $params->get('followreferrals', 0);

        $authorisationmethod = $params->get('authorisationmethod', 'binddirectly');

        $basedn = $params->get('basedn');

        $searchstring = $params->get('searchstring');

        $usersdn = $params->get('usersdn');

        $connectusername = $params->get('connectusername');

        $connectpassword = $params->get('connectpassword');

        $mapfullname = $params->get('mapfullname');

        $mapemail = $params->get('mapemail');

        $mapuserid = $params->get('mapuserid');

        $debug = $params->get('debug', 0);

        $gssapi = $params->get('gssapi', 0);

        $sasl = $params->get('sasl', 0);


        foreach ($ldaphosts as $ldaphost) {

            if (empty($ldaphost)) {

                continue;

            }


            // Determine LDAP protocol

            $protocol = 'ldap://';

            if ($connectionsecurity === 'ssl') {

                $protocol = 'ldaps://';

            }


            // Construct the full hostname with protocol

            $fullLdaphost = $protocol . $ldaphost;


            // Initialize LDAP connection

            $ldapconn = ldap_connect($fullLdaphost, $port);


            if ($ldapconn) {

                // Set LDAP options

                ldap_set_option($ldapconn, LDAP_OPT_PROTOCOL_VERSION, $ldapv3 ? 3 : 2);

                ldap_set_option($ldapconn, LDAP_OPT_REFERRALS, $followreferrals ? 1 : 0);

                ldap_set_option($ldapconn, LDAP_OPT_NETWORK_TIMEOUT, 10); // 10 seconds timeout

                ldap_set_option($ldapconn, LDAP_OPT_DEBUG_LEVEL, 7); // Enable debug level


                // Connection security (STARTTLS)

                if ($connectionsecurity === 'starttls') {

                    if (!ldap_start_tls($ldapconn)) {

                        $response->status = JAuthentication::STATUS_FAILURE;

                        $response->error_message = 'Failed to start TLS connection.';

                        continue;

                    }

                }


                // Binding to LDAP

                if ($debug) {

                    Log::add('Attempting to bind with username: ' . $connectusername, Log::DEBUG, 'ldapauth');

                }


                $bind = @ldap_bind($ldapconn, $connectusername, $connectpassword);


                if ($bind) {

                    if ($debug) {

                        Log::add('Bind successful.', Log::DEBUG, 'ldapauth');

                    }


                    // Search for the user

                    $filter = "({$searchstring}={$credentials['username']})";

                    if ($debug) {

                        Log::add('LDAP search filter: ' . $filter, Log::DEBUG, 'ldapauth');

                    }


                    $result = ldap_search($ldapconn, $basedn, $filter);


                    if ($result) {

                        $entries = ldap_get_entries($ldapconn, $result);


                        if ($entries['count'] > 0) {

                            $userdn = $entries[0]['dn'];


                            // Attempt to bind as the user

                            if ($debug) {

                                Log::add('Attempting to bind as user: ' . $userdn, Log::DEBUG, 'ldapauth');

                            }


                            $bindUser = @ldap_bind($ldapconn, $userdn, $credentials['password']);


                            if ($bindUser) {

                                if ($debug) {

                                    Log::add('User bind successful.', Log::DEBUG, 'ldapauth');

                                }


                                // Authentication successful

                                $response->status = JAuthentication::STATUS_SUCCESS;

                                $response->email = ArrayHelper::getValue($entries[0], $mapemail . '.0', '');

                                $response->fullname = ArrayHelper::getValue($entries[0], $mapfullname . '.0', '');

                                $response->username = $credentials['username'];

                                return;

                            } else {

                                // Authentication failed

                                $response->status = JAuthentication::STATUS_FAILURE;

                                $response->error_message = 'Invalid username or password.';

                                if ($debug) {

                                    Log::add('User bind failed. Invalid username or password.', Log::DEBUG, 'ldapauth');

                                    Log::add('LDAP Error: ' . ldap_error($ldapconn), Log::DEBUG, 'ldapauth');

                                }

                            }

                        } else {

                            // User not found

                            $response->status = JAuthentication::STATUS_FAILURE;

                            $response->error_message = 'User not found.';

                            if ($debug) {

                                Log::add('LDAP search returned no entries.', Log::DEBUG, 'ldapauth');

                            }

                        }

                    } else {

                        // Search failed

                        $response->status = JAuthentication::STATUS_FAILURE;

                        $response->error_message = 'LDAP search failed.';

                        if ($debug) {

                            Log::add('LDAP search failed.', Log::DEBUG, 'ldapauth');

                            Log::add('LDAP Error: ' . ldap_error($ldapconn), Log::DEBUG, 'ldapauth');

                        }

                    }

                } else {

                    // Could not bind to LDAP

                    $response->status = JAuthentication::STATUS_FAILURE;

                    $response->error_message = 'Could not bind to LDAP server.';

                    if ($debug) {

                        Log::add('LDAP bind failed.', Log::DEBUG, 'ldapauth');

                        Log::add('LDAP Error: ' . ldap_error($ldapconn), Log::DEBUG, 'ldapauth');

                    }

                }


                ldap_unbind($ldapconn);

            } else {

                // Could not connect to LDAP

                $response->status = JAuthentication::STATUS_FAILURE;

                $response->error_message = 'Could not connect to LDAP server.';

                if ($debug) {

                    Log::add('Could not connect to LDAP server: ' . $fullLdaphost, Log::DEBUG, 'ldapauth');

                }

            }

        }


        // Logging for debugging

        if ($debug) {

            Log::addLogger(

                array('text_file' => 'ldapauth.debug.php'),

                Log::ALL,

                array('ldapauth')

            );


            Log::add('LDAP Hosts: ' . implode(', ', $ldaphosts), Log::DEBUG, 'ldapauth');

            Log::add('Port: ' . $port, Log::DEBUG, 'ldapauth');

            Log::add('Using LDAP V3: ' . ($ldapv3 ? 'Yes' : 'No'), Log::DEBUG, 'ldapauth');

            Log::add('Connection Security: ' . $connectionsecurity, Log::DEBUG, 'ldapauth');

            Log::add('Follow Referrals: ' . ($followreferrals ? 'Yes' : 'No'), Log::DEBUG, 'ldapauth');

            Log::add('Authorisation Method: ' . $authorisationmethod, Log::DEBUG, 'ldapauth');

            Log::add('Base DN: ' . $basedn, Log::DEBUG, 'ldapauth');

            Log::add('Search String: ' . $searchstring, Log::DEBUG, 'ldapauth');

            Log::add('User DN: ' . $usersdn, Log::DEBUG, 'ldapauth');

            Log::add('Connect Username: ' . $connectusername, Log::DEBUG, 'ldapauth');

            Log::add('Mapping Full Name: ' . $mapfullname, Log::DEBUG, 'ldapauth');

            Log::add('Mapping Email: ' . $mapemail, Log::DEBUG, 'ldapauth');

            Log::add('Mapping User ID: ' . $mapuserid, Log::DEBUG, 'ldapauth');

            Log::add('GSSAPI: ' . ($gssapi ? 'Yes' : 'No'), Log::DEBUG, 'ldapauth');

            Log::add('SASL: ' . ($sasl ? 'Yes' : 'No'), Log::DEBUG, 'ldapauth');

        }

    }


    // Function to handle LDAP test

    public function testLdapAuthentication()

    {

        $app = Factory::getApplication();

        $input = $app->input;


        $testUsername = $input->getString('test_username');

        $testPassword = $input->getString('test_password');


        if (empty($testUsername) || empty($testPassword)) {

            $app->enqueueMessage(Text::_('Please enter both username and password for testing.'), 'warning');

            return;

        }


        $response = new stdClass();

        $this->onUserAuthenticate(['username' => $testUsername, 'password' => $testPassword], [], $response);


        if ($response->status === JAuthentication::STATUS_SUCCESS) {

            $app->enqueueMessage(Text::_('LDAP authentication successful'), 'message');

            $input->set('test_result', 'LDAP authentication successful');

        } else {

            $app->enqueueMessage(Text::_('LDAP authentication failed: ' . $response->error_message), 'error');

            $input->set('test_result', 'LDAP authentication failed: ' . $response->error_message);

        }

    }


    // Add HTML and JavaScript for the configuration form

    public function onAfterRender()

    {

        $app = Factory::getApplication();


        if ($app->isClient('administrator')) {

            $input = $app->input;

            $option = $input->getCmd('option');

            $view = $input->getCmd('view');

            $layout = $input->getCmd('layout');

            $plugin = $input->getCmd('plugin');


            if ($option == 'com_plugins' && $view == 'plugin' && $layout == 'edit' && $input->getInt('id') == $this->params->get('id')) {

                $doc = $app->getDocument();


                // Include Bootstrap CDN

$doc->addStyleSheet('https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css');

$doc->addScript('https://releases.jquery.com/git/jquery-3.x-git.slim.min.js');

$doc->addScript('https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js');


                // Output the form

                $html = '

                <div class="row-fluid">

                    <div class="span10 form-horizontal">

                        ' . HTMLHelper::_('bootstrap.startTabSet', 'myTab', ['active' => 'general']) . '

                        ' . HTMLHelper::_('bootstrap.addTab', 'myTab', 'general', Text::_('General', true)) . '

                        <div class="row-fluid">

                            <div class="span6">';

                

                foreach ($this->params->getFieldset('general') as $field) {

                    $html .= '

                                <div class="control-group">

                                    <div class="control-label">' . $field->label . '</div>

                                    <div class="controls">' . $field->input . '</div>

                                </div>';

                }


                $html .= '

                            </div>

                        </div>

                        ' . HTMLHelper::_('bootstrap.endTab') . '


                        ' . HTMLHelper::_('bootstrap.addTab', 'myTab', 'test', Text::_('Test LDAP Settings', true)) . '

                        <div class="row-fluid">

                            <div class="span6">';

                

                foreach ($this->params->getFieldset('test') as $field) {

                    $html .= '

                                <div class="control-group">

                                    <div class="control-label">' . $field->label . '</div>

                                    <div class="controls">' . $field->input . '</div>

                                </div>';

                }


        $html = '

        <div class="control-group">

            <div class="controls">

                <button type="button" style="background-color: red; color: white; padding: 10px 20px; border: none; cursor: pointer;" onclick="testLdapAuthentication();">Test LDAP Authentication</button>

            </div>

        </div>

        <script type="text/javascript">

        function testLdapAuthentication() {

            Joomla.submitbutton = function(task) {

                if (task == "") {

                    return false;

                } else {

                    var form = document.getElementById("adminForm");

                    form.task.value = task;

                    form.submit();

                }

            }

            Joomla.submitbutton("plugin.testLdapAuthentication");

        }

        </script>';


                $body = $doc->getBuffer('component');

                $doc->setBuffer($body . $html, 'component');

            }

        }

    }

}





ldapauth.xml


<?xml version="1.0" encoding="utf-8"?>
<extension type="plugin" group="authentication" method="upgrade">
    <name>PLG_AUTHENTICATION_LDPAUTH</name>
    <author>Your Name</author>
    <creationDate>2024-06-16</creationDate>
    <version>1.0.0</version>
    <description>LDAP Authentication Plugin</description>
<files>
    <filename plugin="ldapauth">ldapauth.php</filename>
    <folder>fields</folder> <!-- This ensures all files in the fields directory are loaded -->
</files>
    <config>
        <fields name="params">
            <fieldset name="general" label="General Settings">
                <field name="ldaphost1" type="text" label="LDAPHOST 1" description="LDAP Host 1" />
                <field name="ldaphost2" type="text" label="LDAPHOST 2" description="LDAP Host 2" />
                <field name="ldaphost3" type="text" label="LDAPHOST 3" description="LDAP Host 3" />
                <field name="portdefault" type="list" label="Port" description="LDAP Port" default="389">
                    <option value="389">389</option>
                    <option value="636">636</option>
                    <option value="custom">Custom</option>
                </field>
                <field name="customport" type="text" label="Custom Port" description="Custom Port" />
                <field name="ldapv3" type="checkbox" label="LDAPV3" description="Use LDAP V3" />
                <field name="connectionsecurity" type="list" label="Connection Security" description="Connection Security">
                    <option value="none">None</option>
                    <option value="ssl">SSL/TLS</option>
                    <option value="starttls">STARTTLS</option>
                </field>
                <field name="followreferrals" type="checkbox" label="Follow Referrals" description="Follow Referrals" />
                <field name="authorisationmethod" type="list" label="Authorisation Method" description="Authorisation Method">
                    <option value="binddirectly">Bind directly as user</option>
                    <option value="bindsearch">Bind and search</option>
                </field>
                <field name="basedn" type="text" label="BaseDN" description="Base DN" />
                <field name="searchstring" type="text" label="Search String" description="Search String" />
                <field name="usersdn" type="text" label="User's DN" description="User's DN" />
                <field name="connectusername" type="text" label="Connect Username" description="Connect Username" />
                <field name="connectpassword" type="password" label="Connect Password" description="Connect Password" />
                <field name="mapfullname" type="text" label="Map Full Name" description="Map Full Name" />
                <field name="mapemail" type="text" label="Map Email" description="Map Email" />
                <field name="mapuserid" type="text" label="Map User ID" description="Map User ID" />
                <field name="debug" type="checkbox" label="Debug" description="Enable Debugging" />
                <field name="gssapi" type="checkbox" label="GSSAPI" description="Use GSSAPI" />
                <field name="sasl" type="checkbox" label="SASL" description="Use SASL" />
            </fieldset>
<fieldset name="test" label="Test LDAP Settings">
    <!-- Existing fields -->
    <field name="test_username" type="text" label="Test Username" description="Enter a username to test LDAP authentication" />
    <field name="test_password" type="password" label="Test Password" description="Enter a password to test LDAP authentication" />

    <!-- Custom button field for testing -->
    <field name="test_button" type="ldaptestbutton" label="Test Connection" description="Click to test LDAP settings" />

    <!-- Display test results -->
    <field name="test_result" type="textarea" label="Test Result" description="Result of the LDAP test" readonly="true" />
</fieldset>
        </fields>
    </config>
</extension>

Monday, 25 December 2023

Edge Browser Cache Cleaner V2






Manifest.json


{
  "manifest_version": 3,
  "name": "Browser Cache Cleaner",
  "version": "1.0",
  "description": "Quickly clear browser cache, cookies, and history with Browser Cache Cleaner, enhancing your browsing speed and privacy.",
  "action": {
    "default_popup": "popup.html"
  },
  "icons": {
    "16": "icons/bcc16.png",
    "48": "icons/bcc48.png",
    "128": "icons/bcc128.png"
},
  "permissions": [
    "storage",
    "activeTab",
    "scripting",
    "browsingData",
    "tabs"    
  ],
  "host_permissions": [
    "*://*/*"
  ],
  "background": {
    "service_worker": "background.js"
  }
}

 popup.html

<!DOCTYPE html>
<html>

<head>
    <title>Browser Cache Clearer</title>
    <link rel="stylesheet" type="text/css" href="style.css">
</head>

<body>
    <span class="head-ing"> Browser Cache Cleaner. V2 <br></span>
    <span class="subhead-ing">for Microsoft Edge Browser</span>
    <p></p>
    <div id="browserVersionInfo"></div>
    <form id="dataOptions">
        <div>
            <input type="checkbox" id="selectAll"> Select All
        </div>
        <hr>
        <div>
            <input type="checkbox" id="cache" checked>
            <span class="checkbox-label">1. Cache</span>
            <span class="desc">(Clears browser cache)</span>
        </div>
        <div>
            <input type="checkbox" id="cookies">
            <span class="checkbox-label">2. Cookies</span>
            <span class="desc">(Removes cookies storing user activity and preferences)</span>
        </div>
        <div>
            <input type="checkbox" id="history">
            <span class="checkbox-label">3. Browsing History</span>
            <span class="desc">(Deletes the record of visited web pages)</span>
        </div>
        <div>
            <input type="checkbox" id="fileSystems">
            <span class="checkbox-label">4. File Systems</span>
            <span class="desc">(Clears data in file systems API used by some web apps)</span>
        </div>
        <div>
            <input type="checkbox" id="indexedDB">
            <span class="checkbox-label">5. IndexedDB</span>
            <span class="desc">(Removes data in IndexedDB for structured data storage)</span>
        </div>
        <div>
            <input type="checkbox" id="localStorage">
            <span class="checkbox-label">6. Local Storage</span>
            <span class="desc">(Clears local storage used for key-value pair data)</span>
        </div>
        <div>
            <input type="checkbox" id="serviceWorkers">
            <span class="checkbox-label">7. Service Workers</span>
            <span class="desc">(Clears data related to background scripts for web apps)</span>
        </div>
        <div>
            <input type="checkbox" id="downloads">
            <span class="checkbox-label">8. Downloads</span>
            <span class="desc">(Removes the browser's download history records)</span>
        </div>
        <div>
            <input type="checkbox" id="formdata">
            <span class="checkbox-label">9. Form Data</span>
            <span class="desc">(Clears saved form information like names and addresses)</span>
        </div>
        <div>
            <input type="checkbox" id="passwords">
            <span class="checkbox-label">10. Passwords</span>
            <span class="desc">(Removes saved passwords from the browser)</span>
        </div>
        <div>
            <input type="checkbox" id="pluginData">
            <span class="checkbox-label">11. Plugin Data</span>
            <span class="desc">(Clears data stored by plugins)</span>
        </div>
    </form>
    <div id="statusMessage" style="margin-top: 10px;margin-bottom: 10px;"></div>
    <hr>
    <button id="clearDataButton">Clear Selected Data</button>
    <button id="captureBtn">Capture Screenshot</button>
    <script src="popup.js"></script>
    <span class="copyright"><br> <br>Edge extension by AdventHealth Infra Admin Team<br>(Copyrights 2023. All rights reserved)</span>
</body>

</html>


style.css

        /* Add your styling here */

        #clearDataButton {
            padding: 10px 20px;
            font-size: 16px;
            cursor: pointer;
        }

        body {
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            margin: 0;
            padding: 10px;
            text-align: center;
            background-color: #f4f4f4;
            color: #333;
            width: 550px;
            height: 580px;
            margin: auto;
            overflow-y: auto;
            overflow: hidden;


        }


        h1 {
            color: #5a5a5a;
        }

        #dataOptions {
            margin: 20px 0;
            text-align: left;
        }

        #dataOptions div {
            margin-bottom: 10px;
        }

        input[type="checkbox"] {
            margin-right: 10px;
        }

        button {
            background-color: #3c2cca;
            color: white;
            padding: 10px 20px;
            border: none;
            border-radius: 5px;
            cursor: pointer;
            font-size: 16px;
            transition: background-color 0.3s ease;
            margin-right: 20px
        }

        #captureBtn {
            background-color: green;
            color: white;
            padding: 10px 20px;
            border: none;
            border-radius: 5px;
            cursor: pointer;
            font-size: 16px;
            transition: background-color 0.3s ease;
        }

        button:hover {
            background-color: #3c2cca;
        }

        .cleared {
            position: relative;
            padding-left: 25px;
            /* Adjust space for check mark */
        }

        .cleared::before {
            content: '\2714';
            /* Unicode check mark */
            position: absolute;
            left: 0;
            color: green;
        }

        .checkbox-label {
            font-weight: bold;
            color: rgb(11, 31, 212);
        }

        .head-ing {
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            font-size: 30px;
        }

        .subhead-ing {
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            color: rgb(11, 31, 212);
        }

        .copyright {
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            color: rgb(96, 113, 136);
        }


popup.js

document.addEventListener("DOMContentLoaded", function () {
  var selectAllCheckbox = document.getElementById("selectAll");
  var otherCheckboxes = document.querySelectorAll(
    '#dataOptions input[type="checkbox"]:not(#selectAll)'
  );
  var clearDataButton = document.getElementById("clearDataButton");
  var statusMessage = document.getElementById("statusMessage");
  var checkboxes = document.querySelectorAll(
    '#dataOptions input[type="checkbox"]'
  );

  selectAllCheckbox.addEventListener("change", function () {
    checkboxes.forEach((checkbox) => {
      checkbox.checked = this.checked;
      checkbox.parentElement.classList.remove("cleared"); // Remove cleared class if needed
      document.getElementById("statusMessage").innerHTML = "";
    });
  });

  checkboxes.forEach(function (checkbox) {
    checkbox.addEventListener("change", function () {
      // If any checkbox is unchecked, uncheck the selectAllCheckbox
      if (!this.checked) {
        selectAllCheckbox.checked = false;
      }
    });
  });

  clearDataButton.addEventListener("click", function () {
    // Check if any checkbox is selected
    var isAnyCheckboxSelected = Array.from(checkboxes).some(
      (checkbox) => checkbox.checked
    );

    if (!isAnyCheckboxSelected) {
      // Show 'nothing selected' message
      statusMessage.textContent = "No selection(s) found!";
      statusMessage.style.color = "red";
      checkboxes.forEach((checkbox) => {
        checkbox.parentElement.classList.remove("cleared");
      });
      return; // Exit the function
    }

    var options = {
      cache: document.getElementById("cache").checked,
      cookies: document.getElementById("cookies").checked,
      history: document.getElementById("history").checked,
      fileSystems: document.getElementById("fileSystems").checked,
      indexedDB: document.getElementById("indexedDB").checked,
      localStorage: document.getElementById("localStorage").checked,
      serviceWorkers: document.getElementById("serviceWorkers").checked,
      downloads: document.getElementById("downloads").checked,
      formData: document.getElementById("formdata").checked,
      passwords: document.getElementById("passwords").checked,
      pluginData: document.getElementById("pluginData").checked,
    };

    chrome.runtime.sendMessage({ action: "clearData", options: options });
    updateStatusMessage();
    document.getElementById("statusMessage").style.color = "red";
    var checkedItems = document.querySelectorAll(
      '#dataOptions input[type="checkbox"]:checked:not(#selectAll)'
    );

    checkboxes.forEach((checkbox) => {
      checkbox.parentElement.classList.remove("cleared");
    });

    checkedItems.forEach((item) => {
      item.parentElement.classList.add("cleared");
    });
  });
  displayEdgeVersion();
});

function updateStatusMessage() {
  var now = new Date();
  var options = {
    year: "numeric",
    month: "numeric",
    day: "numeric",
    hour: "numeric",
    minute: "numeric",
    second: "numeric",
    timeZoneName: "short",
  };
  var dateString = new Intl.DateTimeFormat("en-US", options).format(now);

  var message = "Selected data cleared from your browser<br>" + dateString;
  document.getElementById("statusMessage").innerHTML = message;
}

function displayEdgeVersion() {
  var userAgent = navigator.userAgent;
  var edgeVersionMatch = userAgent.match(/Edg\/([\d\.]+)/); // Find Edge version
  // var edgeVersionMatch = userAgent.split('Edge/')[1];
  var edgeVersion = edgeVersionMatch
    ? "Your Edge Version:" + edgeVersionMatch[1]
    : "Edge version not detected";

  // Displaying version info
  document.getElementById("browserVersionInfo").textContent = edgeVersion;
}

chrome.runtime.onMessage.addListener(function (message, sender, sendResponse) {
  if (message.action === "captured") {
    downloadImage(message.image);
  }
});

function downloadImage(imageData) {
  var link = document.createElement("a");
  link.href = imageData;
  link.download = "screenshot.png";
  document.body.appendChild(link);
  link.click();
  document.body.removeChild(link);
}

document.getElementById("captureBtn").addEventListener("click", function () {
  chrome.runtime.sendMessage({ action: "capture" });
});

background.js


chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) {
  if (request.action === "clearData") {
    // Call clearBrowserData and then send response
    clearBrowserData(request.options)
      .then(() => {
        sendResponse({ action: "clearDataResponse" });
      })
      .catch((error) => {
        console.error("Error clearing data:", error);
        sendResponse({ action: "clearDataResponse", error: error.message });
      });

    // Return true to keep the messaging channel open for the response
    return true;
  }
});

function clearBrowserData(options) {
  return new Promise((resolve, reject) => {
    var dataToRemove = {};
    // Existing options
    if (options.cache) dataToRemove.cache = true;
    if (options.cookies) dataToRemove.cookies = true;
    if (options.history) dataToRemove.history = true;
    if (options.fileSystems) dataToRemove.fileSystems = true;
    if (options.indexedDB) dataToRemove.indexedDB = true;
    if (options.localStorage) dataToRemove.localStorage = true;
    if (options.serviceWorkers) dataToRemove.serviceWorkers = true;
    if (options.downloads) dataToRemove.downloads = true;
    if (options.formData) dataToRemove.formData = true;
    if (options.passwords) dataToRemove.passwords = true;
    if (options.pluginData) dataToRemove.pluginData = true;
    chrome.browsingData.remove({ since: 0 }, dataToRemove, () => {
      console.log("Selected data cleared.");
      resolve();
    });
  });
}

chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) {
  if (request.action === "capture") {
    chrome.tabs.captureVisibleTab(null, { format: "png" }, function (image) {
      // Send the image data to the popup script
      chrome.runtime.sendMessage({ action: "captured", image: image });
    });
  }
});