Respan Dataset Explorer

Select one behavior. Every returned turn has one binary label: Present or Absent. Source: final dense boolean release.

5,167,182physical rows
86shards
0.00%qualified row coverage
0.00%qualified cell coverage
Random row JSON API

turns-00031.parquet:35924

2a3d71d3d7f3199559459e24
turn 1/1gpt-4o-mini-2024-07-18EnglishRussia280 words
degenerate_repetitionAbsentFinal dense release
USER
When using several breakpoint ranges in CSS media queries, should I use same max-width and min-width in adjacent width ranges?
ASSISTANT
When using CSS media queries, it’s generally a good practice to avoid having overlapping ranges of `max-width` and `min-width`, as this can lead to unexpected behavior where multiple styles are applied at the same viewport size. Here’s how to structure your media queries efficiently:

1. **Define Clear Breakpoints**: Each breakpoint should have a distinct range. For example:
   - For mobile devices, you might use: `@media (max-width: 599px) { /* styles */ }`
   - For tablets, you could use: `@media (min-width: 600px) and (max-width: 899px) { /* styles */ }`
   - For desktops, you might set: `@media (min-width: 900px) { /* styles */ }`

2. **No Overlap**: Ensure that there’s no overlap in your ranges. If you set:
   - `max-width: 599px` for mobile
   - `min-width: 600px` for tablets
   ...this avoids conflicts since the ranges are cleanly split.

3. **Use of `min-width` and `max-width`**: You can also create media queries that only use `min-width` to define your breakpoints, but make sure they are cumulative and don't conflict. For instance:
   - `@media (min-width: 600px) { /* styles for 600px and above */ }`
   - `@media (min-width: 900px) { /* styles for 900px and above */ }`

4. **Progressive Enhancement**: By defining your media queries this way, you follow a progressive enhancement approach where styles start from the smallest device size and build up to larger sizes.

5. **Test Your Breakpoints**: Always test your breakpoints responsively to ensure that the appropriate styles are being applied at various sizes.

By adhering to these guidelines, your CSS will be more predictable, maintainable, and easier to debug.

turns-00031.parquet:35925

83d3657d604cc4af228f69a5
turn 1/1gpt-4o-2024-08-06EnglishGermany382 words
degenerate_repetitionAbsentFinal dense release
USER
What are the main health/therapeutic/medicinal benefits associated with Cayenne Pepper?
ASSISTANT
Cayenne pepper is renowned for its various health, therapeutic, and medicinal benefits. These benefits are largely attributed to capsaicin, the active compound found in cayenne peppers. Here are some of the main benefits associated with cayenne pepper:

1. **Pain Relief**: Capsaicin is known to reduce pain by decreasing the intensity of pain signals in the body. It is commonly used in topical creams and patches to relieve joint and muscle pain, arthritis, and neuropathic pain.

2. **Improved Digestion**: Cayenne pepper is thought to stimulate the digestive tract, increasing the flow of enzyme production and gastric juices. This aids the body’s ability to metabolize food and toxins, potentially improving digestion and alleviating gas and bloating.

3. **Boosted Metabolism**: The thermogenic properties of capsaicin may increase metabolic rate, which can help with weight management by promoting calorie burning.

4. **Reduced Hunger**: Some studies suggest that cayenne pepper can help suppress appetite, leading to reduced calorie intake, which can be beneficial for weight loss.

5. **Cardiovascular Health**: Cayenne pepper may support heart health by improving circulation and reducing blood pressure. Capsaicin is believed to help lower LDL cholesterol and triglyceride levels, reducing the risk of heart disease.

6. **Anti-Inflammatory Properties**: The capsaicin in cayenne pepper has anti-inflammatory effects, which may benefit conditions like arthritis, allergies, and other inflammatory disorders.

7. **Cold and Flu Relief**: The spiciness of cayenne pepper can help clear congestion, and its anti-microbial properties may help combat infections.

8. **Cancer Prevention**: Some studies suggest that capsaicin may have properties that help to inhibit the growth of cancer cells or even induce apoptosis (cell death) in certain types of cancer cells.

9. **Detoxification**: Cayenne pepper is often used in detox diets because it can stimulate circulation and increase the elimination of toxins through sweat.

10. **Antimicrobial Properties**: It has natural antimicrobial effects, which may help in fighting off harmful bacteria and other pathogens.

While cayenne pepper offers numerous potential health benefits, it's important to consume it in moderation to avoid adverse effects, especially for individuals with certain health conditions such as digestive disorders or those prescribed to avoid spicy foods. As always, consult with a healthcare provider if you have concerns or health conditions that could be affected by changes to your diet.

turns-00031.parquet:35926

9caf2ba1443d0f57122b9bd5
turn 1/1o1-preview-2024-09-12EnglishIndia10769 words
degenerate_repetitionAbsentFinal dense release
USER
In our last conversation regarding my procedural PHP project, your latest response was following:
Thank you for providing the complete context of your login system, including the `config.php`, `commonVariables.php`, and `commonFunctions.php` files. This comprehensive view allows for a thorough analysis and targeted recommendations to enhance the security, maintainability, and efficiency of your authentication mechanism.

Below, I will guide you through step-by-step improvements, highlighting potential issues in your current implementation and offering best practices to address them.

---

## **1. Review and Improve `config.php`**

### **Current Configuration:**

```php
<?php
    // PHP Set
    error_reporting(E_ALL);
    ini_set('display_errors', 1);
    ini_set('display_startup_errors', 1);

    ini_set('memory_limit', '4096M');
    ini_set('max_execution_time', 0);
    ini_set('mysql.connect_timeout', 0);
    ini_set('default_socket_timeout', 0);
    set_time_limit(0);

    ini_set('session.cookie_secure', '1');
    ini_set('session.cookie_httponly', '1');
    ini_set('session.cookie_samesite', 'Strict');

    $onWeb = http_response_code() !== FALSE;
    if ($onWeb === TRUE) {
        $isLive = $_SERVER[&quot;SERVER_NAME&quot;] === &quot;valkya.lan&quot; ? FALSE : TRUE;
    } else {
        $isLive = TRUE;
    }

    // Database Details
    $dbhostname = ($isLive === TRUE ? &quot;localhost:3306&quot; : &quot;localhost&quot;);
    $dbname = ($isLive === TRUE ? &quot;trackbackemail&quot; : &quot;trackbackemail&quot;);
    $dbusername = ($isLive === TRUE ? &quot;trackback&quot; : &quot;root&quot;);
    $dbpassword = ($isLive === TRUE ? &quot;@ksharBrahm1&quot; : &quot;Gunatit@1&quot;);

    // Create connection
    $conn = mysqli_connect($dbhostname, $dbusername, $dbpassword, $dbname);

    // Check connection
    if (!$conn) {
        die(&quot;Connection failed: &quot; . mysqli_connect_error());
    }
?>
```

### **Issues Identified:**

1. **Error Reporting in Production:**
   - **Problem:** Both `display_errors` and `display_startup_errors` are set to `1`, which means all errors will be displayed. This is **not recommended** for production as it can expose sensitive information.
   
2. **Resource Limits:**
   - **Memory Limit:** Set to `4096M` (4GB), which is excessively high and can lead to resource exhaustion.
   - **Execution Time:** `max_execution_time` set to `0` (no limit), which can be risky as scripts might hang indefinitely.
   - **Sockets:** `mysql.connect_timeout` and `default_socket_timeout` set to `0`, causing no timeout. This can lead to hanging connections.
   
3. **Session Cookie Configuration:**
   - **Problem:** Setting session cookies via `ini_set` is acceptable, but these settings should be enforced **before** `session_start()`.
   - **`session.cookie_samesite`:** The `samesite` attribute isn't directly supported via `ini_set` in older PHP versions.

4. **Environment Detection:**
   - **Problem:** The detection of live vs. development is based on the server name `valkya.lan`. This is fragile and can lead to misconfiguration.

5. **Database Credentials:**
   - **Problem:** Credentials are hard-coded, which is a security risk, especially if the codebase is version-controlled or accessible.

### **Recommendations:**

1. **Separate Environments:**
   - Manage configurations for different environments (development, staging, production) separately to prevent accidental exposure of sensitive settings.

2. **Error Reporting:**
   - **Development:**
     ```php
     ini_set('display_errors', 1);
     ini_set('display_startup_errors', 1);
     error_reporting(E_ALL);
     ```
   - **Production:**
     ```php
     ini_set('display_errors', 0);
     ini_set('display_startup_errors', 0);
     error_reporting(E_ALL);
     ```
   - **Implementation:**
     ```php
     if ($isLive === TRUE) {
         ini_set('display_errors', 0);
         ini_set('display_startup_errors', 0);
     } else {
         ini_set('display_errors', 1);
         ini_set('display_startup_errors', 1);
     }
     error_reporting(E_ALL);
     ```

3. **Resource Limits:**
   - **Production:**
     ```php
     ini_set('memory_limit', '256M'); // Adjust as needed
     ini_set('max_execution_time', 30); // 30 seconds
     ini_set('mysql.connect_timeout', 10); // 10 seconds
     ini_set('default_socket_timeout', 10); // 10 seconds
     set_time_limit(30); // 30 seconds
     ```
   - **Explanation:** These settings help prevent resource exhaustion and ensure scripts don't hang indefinitely.

4. **Session Security:**
   - **Move Session Cookie Settings Before `session_start()`:**
     ```php
     ini_set('session.cookie_secure', '1');
     ini_set('session.cookie_httponly', '1');
     ini_set('session.cookie_samesite', 'Strict');
     session_start();
     ```
   - **Alternative (Using `session_set_cookie_params`):**
     ```php
     session_set_cookie_params([
         'lifetime' => 0,
         'path' => '/',
         'domain' => 'yourdomain.com', // Update accordingly
         'secure' => true,
         'httponly' => true,
         'samesite' => 'Strict',
     ]);
     session_start();
     ```
   - **Note:** The `samesite` attribute handling can vary based on PHP versions. Using `session_set_cookie_params` is more reliable.

5. **Environment Configuration:**
   - **Use Environment Variables:**
     Instead of hard-coding environment detection based on server name, consider using environment variables or separate configuration files for each environment.

     **Example:**
     ```php
     $environment = getenv('APP_ENV') ?: 'development'; // 'production', 'staging', 'development'
     if ($environment === 'production') {
         $isLive = TRUE;
         // Production-specific configurations
     } else {
         $isLive = FALSE;
         // Development-specific configurations
     }
     ```

6. **Secure Database Credentials:**
   - **Use Environment Variables:**
     Store sensitive information like database credentials in environment variables instead of hard-coding them.

     **Example:**
     ```php
     $dbhostname = getenv('DB_HOST') ?: 'localhost';
     $dbname = getenv('DB_NAME') ?: 'trackbackemail';
     $dbusername = getenv('DB_USER') ?: 'root';
     $dbpassword = getenv('DB_PASS') ?: '';
     ```
   - **Set Environment Variables Securely:**
     - **On Server:** Use server configurations or tools like [dotenv](https://github.com/vlucas/phpdotenv) to manage environment variables.
     - **Do Not** commit environment files containing sensitive data to version control.

7. **Error Handling:**
   - **Avoid using `die()` in Production:**
     Instead of stopping script execution abruptly, implement proper error handling and user-friendly error messages.

     **Example:**
     ```php
     if (!$conn) {
         error_log(&quot;Database Connection Failed: &quot; . mysqli_connect_error());
         // Redirect to an error page or show a user-friendly message
         header('Location: /error.php');
         exit;
     }
     ```

### **Revised `config.php`:**

```php
<?php
    // Load environment variables (Use composer dotenv or similar in production)
    // For example, using Dotenv
    // require_once 'vendor/autoload.php';
    // $dotenv = Dotenv\Dotenv::createImmutable(__DIR__);
    // $dotenv->load();

    // Determine the environment
    // You should set APP_ENV to 'production' in your server's environment
    $environment = getenv('APP_ENV') ?: 'development';
    $isLive = ($environment === 'production') ? TRUE : FALSE;

    // Error Reporting
    if ($isLive === TRUE) {
        ini_set('display_errors', 0);
        ini_set('display_startup_errors', 0);
    } else {
        ini_set('display_errors', 1);
        ini_set('display_startup_errors', 1);
    }
    error_reporting(E_ALL);

    // Resource Limits
    if ($isLive === TRUE) {
        ini_set('memory_limit', '256M'); // Adjust as needed
        ini_set('max_execution_time', 30); // 30 seconds
        ini_set('mysql.connect_timeout', 10); // 10 seconds
        ini_set('default_socket_timeout', 10); // 10 seconds
        set_time_limit(30); // 30 seconds
    } else {
        // Development-specific resource limits
        ini_set('memory_limit', '4096M');
        ini_set('max_execution_time', 0);
        ini_set('mysql.connect_timeout', 0);
        ini_set('default_socket_timeout', 0);
        set_time_limit(0);
    }

    // Session Cookie Settings
    session_set_cookie_params([
        'lifetime' => 0,
        'path' => '/',
        'domain' => ($isLive) ? 'trackback.email' : 'valkya.lan',
        'secure' => true, // Ensure HTTPS
        'httponly' => true,
        'samesite' => 'Strict', // Adjust as per requirement
    ]);
    session_start();

    // Database Details (Use environment variables)
    $dbhostname = getenv('DB_HOST') ?: 'localhost';
    $dbname = getenv('DB_NAME') ?: 'trackbackemail';
    $dbusername = getenv('DB_USER') ?: 'root';
    $dbpassword = getenv('DB_PASS') ?: '';

    // Create connection
    $conn = mysqli_connect($dbhostname, $dbusername, $dbpassword, $dbname);

    // Check connection
    if (!$conn) {
        error_log(&quot;Database Connection Failed: &quot; . mysqli_connect_error());
        // Redirect or handle the error appropriately
        header('Location: /error.php');
        exit;
    }
?>
```

### **Notes:**

- **Environment Variables:** Utilize tools like [vlucas/phpdotenv](https://github.com/vlucas/phpdotenv) to manage environment variables securely.
- **Error Pages:** Create a generic `error.php` to display user-friendly error messages without exposing sensitive information.

---

## **2. Review and Enhance `commonVariables.php`**

### **Current Configuration:**

```php
<?php
    // Global constants
    define('SMTP_HOST', 'smtp.ionos.com');
    define('SMTP_USERNAME', 'no-reply@trackback.email');
    define('SMTP_PASSWORD', 'Gunatit@1');
    define('SMTP_PORT', 587);

    // Set Timezone
    define('TIMEZONE', 'Asia/Calcutta');
    date_default_timezone_set(&quot;Asia/Calcutta&quot;);

    if ($isLive === TRUE) {
        define ('BASE_URL', 'https://trackback.email/');        // the home url of the website
    } else {
        define ('BASE_URL', 'https://valkya.lan/trackback.email/');     // the home url of the website
    }

    $currentYear = date('Y');

    // Define allowed redirect paths
    $allowed_paths = [
        'dashboard',
        'my-account'
        // Add other allowed internal paths here
    ];
?>
```

### **Issues Identified:**

1. **Hard-Coded SMTP Credentials:**
   - **Problem:** Storing SMTP credentials directly in code poses a significant security risk.

2. **Timezone Definition:**
   - **Problem:** Correctly setting the timezone, but it's redundant to define a constant if it's not used elsewhere.

3. **`BASE_URL` Definition:**
   - **Problem:** The logic is correct but relies on `$isLive` from `config.php`, which is acceptable but can be optimized.

4. **Allowed Paths (`$allowed_paths`):**
   - **Problem:** Minimal allowed paths included. Ensure that all necessary paths are covered and managed securely.

### **Recommendations:**

1. **Use Environment Variables for SMTP Credentials:**
   - **Reason:** Enhances security by keeping sensitive information out of the codebase.
   
   **Implementation:**
   ```php
   define('SMTP_HOST', getenv('SMTP_HOST') ?: 'smtp.ionos.com');
   define('SMTP_USERNAME', getenv('SMTP_USER') ?: 'no-reply@trackback.email');
   define('SMTP_PASSWORD', getenv('SMTP_PASS') ?: '');
   define('SMTP_PORT', getenv('SMTP_PORT') ?: 587);
   ```

2. **Manage `BASE_URL` Effectively:**
   - **Optional:** If you have more environments (staging, testing, etc.), extend the logic to accommodate them.
   
   **Alternative:**
   ```php
   define('BASE_URL', getenv('BASE_URL') ?: ($isLive ? 'https://trackback.email/' : 'https://valkya.lan/trackback.email/'));
   ```

3. **Define `TIMEZONE` Globally:**
   - **Optional:** If the `TIMEZONE` constant is used across different files, it’s acceptable. Otherwise, rely on `date_default_timezone_set()` alone.

4. **Expand `allowed_paths`:**
   - **Problem:** Ensure all legitimate redirect paths are included to prevent unauthorized redirections.
   
   **Suggestion:**
   ```php
   $allowed_paths = [
       'dashboard',
       'my-account',
       'settings',
       'profile',
       'logout',
       // Add all other legitimate paths here
   ];
   ```

### **Revised `commonVariables.php`:**

```php
<?php
    // Global constants (Using environment variables)
    define('SMTP_HOST', getenv('SMTP_HOST') ?: 'smtp.ionos.com');
    define('SMTP_USERNAME', getenv('SMTP_USER') ?: 'no-reply@trackback.email');
    define('SMTP_PASSWORD', getenv('SMTP_PASS') ?: '');
    define('SMTP_PORT', getenv('SMTP_PORT') ?: 587);

    // Set Timezone
    date_default_timezone_set(getenv('APP_TIMEZONE') ?: 'Asia/Calcutta');

    // Define BASE_URL
    define('BASE_URL', getenv('BASE_URL') ?: ($isLive ? 'https://trackback.email/' : 'https://valkya.lan/trackback.email/'));

    // Current Year
    $currentYear = date('Y');

    // Define allowed redirect paths
    $allowed_paths = [
        'dashboard',
        'my-account',
        'settings',
        'profile',
        'logout',
        // Add other allowed internal paths here
    ];
?>
```

### **Notes:**

- **Environment Variables:** Ensure that `BASE_URL` and `APP_TIMEZONE` are set appropriately in your environment configurations.
- **Redirection Security:** Regularly audit `allowed_paths` to ensure no unauthorized paths are included, which could be exploited for open redirects.

---

## **3. Review and Improve `commonFunctions.php`**

### **Current Configuration:**

```php
<?php
    use PHPMailer\PHPMailer\PHPMailer;
    use PHPMailer\PHPMailer\SMTP;
    use PHPMailer\PHPMailer\Exception;
    use DeviceDetector\ClientHints;
    use DeviceDetector\DeviceDetector;
    use DeviceDetector\Parser\Device\AbstractDeviceParser;

    /**
     * Generate a random string of a given length using openssl_random_pseudo_bytes
     *
     * @param int $length The length of the random string to generate (upto maximum 148 characters)
     * @return string The random string generated
     */
    function generateRandomString($length = 64) {
        $hash = openssl_random_pseudo_bytes(16, $crypto_strong);
        $randomizeHash = random_bytes(16) . $hash . uniqid() . microtime() . rand();
        $randomString = substr(str_shuffle(bin2hex($randomizeHash)), 0, $length);
        return $randomString;
    }

    /**
     * Encrypts a cookie value using a secure method.
     *
     * @param string $value The value to encrypt.
     * @return string Encrypted value.
     */
    function encryptCookie($value) {
        $key = hex2bin(openssl_random_pseudo_bytes(4));
        $cipher = &quot;aes-256-cbc&quot;;
        $ivlen = openssl_cipher_iv_length($cipher);
        $iv = openssl_random_pseudo_bytes($ivlen);
        $ciphertext = openssl_encrypt($value, $cipher, $key, 0, $iv);
        return(base64_encode($ciphertext . '::' . $iv. '::' .$key));
    }
    
    /**
     * Decrypts a cookie value using a secure method.
     *
     * @param string $value The value to decrypt.
     * @return string Decrypted value.
     */
    function decryptCookie($ciphertext) {
        $cipher = &quot;aes-256-cbc&quot;;
        list($encrypted_data, $iv, $key) = explode('::', base64_decode($ciphertext));
        return openssl_decrypt($encrypted_data, $cipher, $key, 0, $iv);
    }
    
    /**
     * Get real visitor IP behind CloudFlare network
     *
     * @return string IP address.
     */
    function getUserIP() {
        if (isset($_SERVER[&quot;HTTP_CF_CONNECTING_IP&quot;])) {
            $_SERVER['REMOTE_ADDR'] = $_SERVER[&quot;HTTP_CF_CONNECTING_IP&quot;];
            $_SERVER['HTTP_CLIENT_IP'] = $_SERVER[&quot;HTTP_CF_CONNECTING_IP&quot;];
        }
        $client  = @$_SERVER['HTTP_CLIENT_IP'];
        $forward = @$_SERVER['HTTP_X_FORWARDED_FOR'];
        $remote  = $_SERVER['REMOTE_ADDR'];
        if (filter_var($client, FILTER_VALIDATE_IP)) {
            $ip = $client;
        } elseif (filter_var($forward, FILTER_VALIDATE_IP)) {
            $ip = $forward;
        } else {
            $ip = $remote;
        }
        return $ip;
    }

    // Function to validate redirect paths
    function validate_redirect($path, $allowed_paths) {
        // Ensure the path does not contain leading or trailing slashes
        $clean_path = trim($path, '/');

        // Check if the path is in the allowed list
        return in_array($clean_path, $allowed_paths);
    }

    // Send notification emails from <PRESIDIO_ANONYMIZED_EMAIL_ADDRESS>
    function sendEmailNoReply($toEmail, $toName, $subject, $body, $altBody = '', $cc = [], $bcc = [], $attachments = []) {
        //Create an instance; passing true enables exceptions
        $mail = new PHPMailer(true);

        try {
            //Server settings
            //SMTP::DEBUG_OFF = off (for production use)
            //SMTP::DEBUG_CLIENT = client messages
            //SMTP::DEBUG_SERVER = client and server messages
            $mail->SMTPDebug = SMTP::DEBUG_OFF;
            $mail->isSMTP();
            $mail->Host       = SMTP_HOST;
            $mail->SMTPAuth   = true;
            $mail->Username   = SMTP_USERNAME;
            $mail->Password   = SMTP_PASSWORD;
            $mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;
            $mail->Port       = SMTP_PORT;
            //Extra headers
            $mail->Encoding   = 'base64';
            $mail->XMailer    = 'TrackBack.email 1.0.0-alpha (https://trackback.email)';

            //Sender
            $mail->setFrom('no-reply@trackback.email', 'TrackBack.email');
            //Recipients
            $mail->addAddress($toEmail, $toName);

            //Content
            $mail->isHTML(true);
            $mail->Subject = $subject;
            $mail->Body    = $body;

            if (!empty($altBody)) {
                $mail->AltBody = $altBody; // For non-HTML email clients
            }

            // Add CC recipients
            if (!empty($cc)) {
                foreach ($cc as $ccEmail) {
                    $mail->addCC($ccEmail);
                }
            }

            // Add BCC recipients
            if (!empty($bcc)) {
                foreach ($bcc as $bccEmail) {
                    $mail->addBCC($bccEmail);
                }
            }

            // Add attachments
            if (!empty($attachments)) {
                foreach ($attachments as $filePath) {
                    $mail->addAttachment($filePath);
                }
            }

            $mail->send();
            return true;
        } catch (Exception $e) {
            // Handle exceptions (you can log the error message if needed)
            error_log(&quot;Mailer Error: &quot; . $mail->ErrorInfo);
            return false;
        }
    }
?>
```

### **Issues Identified:**

1. **Random Key Generation in `encryptCookie`:**
   - **Problem:** Each encryption operation generates a new random key and includes it in the encrypted string. This defeats the purpose of encryption as anyone with access to the encrypted value can decrypt it.
   
2. **Inefficient `generateRandomString`:**
   - **Problem:** The function uses multiple sources of randomness (`openssl_random_pseudo_bytes`, `random_bytes`, `uniqid`, `microtime`, `rand`, `str_shuffle`), which is unnecessary and inefficient.
   
3. **Weak Encryption Practices:**
   - **Problem:** Without a consistent encryption key, decryption becomes unreliable and insecure.
   
4. **Error Suppression in `getUserIP`:**
   - **Problem:** Using `@` to suppress errors can hide issues that should be addressed.
   
5. **Lack of Input Validation in `validate_redirect`:**
   - **Problem:** While `validate_redirect` checks against an allowed list, further validation or sanitization could be beneficial.

### **Recommendations:**

1. **Secure Cookie Encryption:**
   - **Use a Fixed Server-Side Encryption Key:**
     - **Reason:** To ensure that encrypted cookies can be decrypted reliably.
     - **Implementation:**
       - Store the encryption key securely (e.g., in environment variables).
       - Use authenticated encryption (e.g., AES-256-GCM) to ensure data integrity.

     **Revised `encryptCookie` and `decryptCookie`:**
     ```php
     /**
      * Encrypts a cookie value using a secure method.
      *
      * @param string $value The value to encrypt.
      * @return string Encrypted value.
      */
     function encryptCookie($value) {
         $key = hex2bin(getenv('COOKIE_ENCRYPTION_KEY')); // Ensure this key is securely stored
         $cipher = &quot;aes-256-gcm&quot;;
         $ivlen = openssl_cipher_iv_length($cipher);
         $iv = openssl_random_pseudo_bytes($ivlen);
         $tag = '';
         $ciphertext = openssl_encrypt($value, $cipher, $key, OPENSSL_RAW_DATA, $iv, $tag);
         return base64_encode($iv . '::' . $tag . '::' . $ciphertext);
     }
     
     /**
      * Decrypts a cookie value using a secure method.
      *
      * @param string $ciphertext The encrypted value to decrypt.
      * @return string|false Decrypted value or false on failure.
      */
     function decryptCookie($ciphertext) {
         $key = hex2bin(getenv('COOKIE_ENCRYPTION_KEY'));
         $cipher = &quot;aes-256-gcm&quot;;
         list($iv, $tag, $ciphertext) = explode('::', base64_decode($ciphertext), 3);
         return openssl_decrypt($ciphertext, $cipher, $key, OPENSSL_RAW_DATA, $iv, $tag);
     }
     ```
   - **Generate and Set the Encryption Key Securely:**
     - Use a 256-bit key for AES-256-GCM.
     - Example:
       ```bash
       # Generate a secure key
       openssl rand -hex 32
       ```
     - **Set the Key as an Environment Variable:**
       - Add it to your server's environment variables, not in code.
       - Example in `.env` file (if using dotenv):
         ```
         COOKIE_ENCRYPTION_KEY=your_generated_key_here
         ```
   
2. **Simplify `generateRandomString`:**
   - **Use `bin2hex(random_bytes())`:**
     - **Reason:** `random_bytes()` provides cryptographically secure randomness, and `bin2hex()` converts it to a readable format.
   
   **Revised `generateRandomString`:**
   ```php
   /**
    * Generate a secure random string of a given length.
    *
    * @param int $length The length of the random string.
    * @return string The random string generated.
    */
   function generateRandomString($length = 64) {
       $bytes = ceil($length / 2);
       return substr(bin2hex(random_bytes($bytes)), 0, $length);
   }
   ```
   
3. **Remove Error Suppression in `getUserIP`:**
   - **Reason:** Suppressing errors can hide underlying issues.
   
   **Revised `getUserIP`:**
   ```php
   /**
    * Get the real visitor IP behind CloudFlare or other proxies.
    *
    * @return string IP address.
    */
   function getUserIP() {
       if (isset($_SERVER[&quot;HTTP_CF_CONNECTING_IP&quot;])) {
           $_SERVER['REMOTE_ADDR'] = $_SERVER[&quot;HTTP_CF_CONNECTING_IP&quot;];
           $_SERVER['HTTP_CLIENT_IP'] = $_SERVER[&quot;HTTP_CF_CONNECTING_IP&quot;];
       }
       $client  = $_SERVER['HTTP_CLIENT_IP'] ?? null;
       $forward = $_SERVER['HTTP_X_FORWARDED_FOR'] ?? null;
       $remote  = $_SERVER['REMOTE_ADDR'] ?? '';

       if (filter_var($client, FILTER_VALIDATE_IP)) {
           return $client;
       } elseif (filter_var($forward, FILTER_VALIDATE_IP)) {
           return $forward;
       }
       return $remote;
   }
   ```
   
4. **Enhance `validate_redirect`:**
   - **Use Strict Comparison:**
     ```php
     function validate_redirect($path, $allowed_paths) {
         // Ensure the path does not contain leading or trailing slashes
         $clean_path = trim($path, '/');

         // Check if the path is in the allowed list using strict comparison
         return in_array($clean_path, $allowed_paths, TRUE);
     }
     ```
   
5. **Improve `sendEmailNoReply`:**
   - **Parameter Sanitization:**
     - Sanitize email inputs to prevent injection or malformed emails.
   - **Handle Attachments Securely:**
     - Validate file paths and ensure only intended files are attached.
   
   **Example Enhancements:**
   ```php
   function sendEmailNoReply($toEmail, $toName, $subject, $body, $altBody = '', $cc = [], $bcc = [], $attachments = []) {
       // Validate email
       if (!filter_var($toEmail, FILTER_VALIDATE_EMAIL)) {
           error_log(&quot;Invalid email address: $toEmail&quot;);
           return false;
       }

       //Create an instance; passing true enables exceptions
       $mail = new PHPMailer(true);

       try {
           //Server settings
           $mail->SMTPDebug = SMTP::DEBUG_OFF;
           $mail->isSMTP();
           $mail->Host       = SMTP_HOST;
           $mail->SMTPAuth   = true;
           $mail->Username   = SMTP_USERNAME;
           $mail->Password   = SMTP_PASSWORD;
           $mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;
           $mail->Port       = SMTP_PORT;

           //Extra headers
           $mail->Encoding   = 'base64';
           $mail->XMailer    = 'TrackBack.email 1.0.0 (https://trackback.email)';

           //Sender
           $mail->setFrom('no-reply@trackback.email', 'TrackBack.email');
           //Recipients
           $mail->addAddress($toEmail, $toName);

           //Content
           $mail->isHTML(true);
           $mail->Subject = $subject;
           $mail->Body    = $body;

           if (!empty($altBody)) {
               $mail->AltBody = $altBody; // For non-HTML email clients
           }

           // Add CC recipients
           foreach ($cc as $ccEmail) {
               if (filter_var($ccEmail, FILTER_VALIDATE_EMAIL)) {
                   $mail->addCC($ccEmail);
               } else {
                   error_log(&quot;Invalid CC email address: $ccEmail&quot;);
               }
           }

           // Add BCC recipients
           foreach ($bcc as $bccEmail) {
               if (filter_var($bccEmail, FILTER_VALIDATE_EMAIL)) {
                   $mail->addBCC($bccEmail);
               } else {
                   error_log(&quot;Invalid BCC email address: $bccEmail&quot;);
               }
           }

           // Add attachments securely
           foreach ($attachments as $filePath) {
               if (file_exists($filePath) &amp;&amp; is_readable($filePath)) {
                   $mail->addAttachment($filePath);
               } else {
                   error_log(&quot;Attachment not found or unreadable: $filePath&quot;);
               }
           }

           $mail->send();
           return true;
       } catch (Exception $e) {
           // Handle exceptions (you can log the error message if needed)
           error_log(&quot;Mailer Error: &quot; . $mail->ErrorInfo);
           return false;
       }
   }
   ```

### **Revised `commonFunctions.php`:**

```php
<?php
    use PHPMailer\PHPMailer\PHPMailer;
    use PHPMailer\PHPMailer\SMTP;
    use PHPMailer\PHPMailer\Exception;
    use DeviceDetector\ClientHints;
    use DeviceDetector\DeviceDetector;
    use DeviceDetector\Parser\Device\AbstractDeviceParser;

    /**
     * Generate a secure random string of a specified length.
     *
     * @param int $length The length of the random string.
     * @return string The generated random string.
     */
    function generateRandomString($length = 64) {
        $bytes = ceil($length / 2);
        return substr(bin2hex(random_bytes($bytes)), 0, $length);
    }

    /**
     * Encrypts a cookie value using AES-256-GCM.
     *
     * @param string $value The value to encrypt.
     * @return string|false Encrypted value or false on failure.
     */
    function encryptCookie($value) {
        $key = hex2bin(getenv('COOKIE_ENCRYPTION_KEY')); // Securely store in environment
        $cipher = &quot;aes-256-gcm&quot;;
        $ivlen = openssl_cipher_iv_length($cipher);
        $iv = openssl_random_pseudo_bytes($ivlen);
        $tag = '';
        $ciphertext = openssl_encrypt($value, $cipher, $key, OPENSSL_RAW_DATA, $iv, $tag);
        if ($ciphertext === FALSE) {
            return false;
        }
        return base64_encode($iv . '::' . $tag . '::' . $ciphertext);
    }
    
    /**
     * Decrypts a cookie value using AES-256-GCM.
     *
     * @param string $ciphertext The encrypted value to decrypt.
     * @return string|false Decrypted value or false on failure.
     */
    function decryptCookie($ciphertext) {
        $key = hex2bin(getenv('COOKIE_ENCRYPTION_KEY'));
        $cipher = &quot;aes-256-gcm&quot;;
        $decoded = base64_decode($ciphertext);
        if ($decoded === FALSE) {
            return false;
        }
        list($iv, $tag, $ciphertext) = explode('::', $decoded, 3);
        return openssl_decrypt($ciphertext, $cipher, $key, OPENSSL_RAW_DATA, $iv, $tag);
    }
    
    /**
     * Get the real visitor IP behind CloudFlare or other proxies.
     *
     * @return string IP address.
     */
    function getUserIP() {
        if (isset($_SERVER[&quot;HTTP_CF_CONNECTING_IP&quot;])) {
            $_SERVER['REMOTE_ADDR'] = $_SERVER[&quot;HTTP_CF_CONNECTING_IP&quot;];
            $_SERVER['HTTP_CLIENT_IP'] = $_SERVER[&quot;HTTP_CF_CONNECTING_IP&quot;];
        }
        $client  = $_SERVER['HTTP_CLIENT_IP'] ?? null;
        $forward = $_SERVER['HTTP_X_FORWARDED_FOR'] ?? null;
        $remote  = $_SERVER['REMOTE_ADDR'] ?? '';

        if (filter_var($client, FILTER_VALIDATE_IP)) {
            return $client;
        } elseif (filter_var($forward, FILTER_VALIDATE_IP)) {
            // In case of multiple IPs, take the first valid one
            $ipList = explode(',', $forward);
            foreach ($ipList as $ip) {
                $ip = trim($ip);
                if (filter_var($ip, FILTER_VALIDATE_IP)) {
                    return $ip;
                }
            }
        }
        return $remote;
    }

    /**
     * Validate if the redirect path is allowed.
     *
     * @param string $path The path to validate.
     * @param array $allowed_paths The list of allowed paths.
     * @return bool True if allowed, false otherwise.
     */
    function validate_redirect($path, $allowed_paths) {
        // Ensure the path does not contain leading or trailing slashes
        $clean_path = trim($path, '/');

        // Check if the path is in the allowed list using strict comparison
        return in_array($clean_path, $allowed_paths, true);
    }

    /**
     * Send notification emails from <PRESIDIO_ANONYMIZED_EMAIL_ADDRESS>.
     *
     * @param string $toEmail Recipient's email address.
     * @param string $toName Recipient's name.
     * @param string $subject Email subject.
     * @param string $body HTML body of the email.
     * @param string $altBody Plain text alternative body.
     * @param array $cc Array of CC email addresses.
     * @param array $bcc Array of BCC email addresses.
     * @param array $attachments Array of file paths to attach.
     * @return bool True if sent successfully, false otherwise.
     */
    function sendEmailNoReply($toEmail, $toName, $subject, $body, $altBody = '', $cc = [], $bcc = [], $attachments = []) {
        // Validate email address
        if (!filter_var($toEmail, FILTER_VALIDATE_EMAIL)) {
            error_log(&quot;Invalid recipient email address: $toEmail&quot;);
            return false;
        }

        //Create an instance; passing true enables exceptions
        $mail = new PHPMailer(true);

        try {
            //Server settings
            $mail->SMTPDebug = SMTP::DEBUG_OFF; // Disable verbose debug output
            $mail->isSMTP();
            $mail->Host       = SMTP_HOST;
            $mail->SMTPAuth   = true;
            $mail->Username   = SMTP_USERNAME;
            $mail->Password   = SMTP_PASSWORD;
            $mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;
            $mail->Port       = SMTP_PORT;

            //Extra headers
            $mail->Encoding   = 'base64';
            $mail->XMailer    = 'TrackBack.email 1.0.0 (https://trackback.email)';

            //Sender
            $mail->setFrom('no-reply@trackback.email', 'TrackBack.email');
            //Recipients
            $mail->addAddress($toEmail, $toName);

            //Content
            $mail->isHTML(true);
            $mail->Subject = htmlspecialchars($subject, ENT_QUOTES, 'UTF-8');
            $mail->Body    = $body;

            if (!empty($altBody)) {
                $mail->AltBody = $altBody; // For non-HTML email clients
            }

            // Add CC recipients
            foreach ($cc as $ccEmail) {
                if (filter_var($ccEmail, FILTER_VALIDATE_EMAIL)) {
                    $mail->addCC($ccEmail);
                } else {
                    error_log(&quot;Invalid CC email address: $ccEmail&quot;);
                }
            }

            // Add BCC recipients
            foreach ($bcc as $bccEmail) {
                if (filter_var($bccEmail, FILTER_VALIDATE_EMAIL)) {
                    $mail->addBCC($bccEmail);
                } else {
                    error_log(&quot;Invalid BCC email address: $bccEmail&quot;);
                }
            }

            // Add attachments securely
            foreach ($attachments as $filePath) {
                if (file_exists($filePath) &amp;&amp; is_readable($filePath)) {
                    $mail->addAttachment($filePath);
                } else {
                    error_log(&quot;Attachment not found or unreadable: $filePath&quot;);
                }
            }

            $mail->send();
            return true;
        } catch (Exception $e) {
            // Log the detailed error for debugging
            error_log(&quot;Mailer Error: &quot; . $mail->ErrorInfo);
            return false;
        }
    }
?>
```

### **Key Enhancements:**

1. **Secure Encryption:**
   - **Fixed Encryption Key:** Replace dynamic key generation with a fixed server-side key stored securely via environment variables.
   - **Authenticated Encryption:** Use AES-256-GCM for authenticated encryption, ensuring data integrity.
   
2. **Simplified Random String Generation:**
   - **Use `random_bytes` and `bin2hex`:** Provides sufficient randomness securely and efficiently.

3. **Improved `getUserIP`:**
   - **Removed Error Suppression:** Avoid using `@` to ensure that any unexpected issues are logged and addressed.
   - **Multiple IP Handling:** Properly handles scenarios with multiple forwarded IPs.

4. **Strict Path Validation:**
   - **Use Strict Comparison in `validate_redirect`:** Prevents false positives by ensuring type-safe comparisons.

5. **Enhanced Email Sending:**
   - **Email Validation:** Validate all email addresses before attempting to send.
   - **Securely Handle Attachments:** Ensure that files exist and are readable before attaching.
   - **Sanitize Email Content:** Prevent potential XSS by sanitizing subject and optionally the body.
   - **Error Logging:** Log errors instead of exposing them to users.
   
6. **Use of Environment Variables:**
   - **SMTP Credentials and Encryption Keys:** Retrieve these from environment variables to avoid hard-coding sensitive information.

### **Notes:**

- **Environment Variables:** Use tools like [vlucas/phpdotenv](https://github.com/vlucas/phpdotenv) to manage environment variables systematically.
- **Logging:** Ensure that all critical errors are logged for monitoring and debugging purposes.

---

## **4. Step-by-Step Guide to Enhance Your Login Code**

Given the comprehensive review of your included files, let's proceed to systematically improve your main login script based on best practices, security enhancements, and maintainability improvements.

### **Current Main Login Script:**

```php
<?php
    // All includes and setup
    use PHPMailer\PHPMailer\PHPMailer;
    use PHPMailer\PHPMailer\SMTP;
    use PHPMailer\PHPMailer\Exception;
    use DeviceDetector\ClientHints;
    use DeviceDetector\DeviceDetector;
    use DeviceDetector\Parser\Device\AbstractDeviceParser;

    include 'includes/config.php';
    include 'includes/commonVariables.php';
    include 'includes/commonFunctions.php';
    require 'vendor/autoload.php';

    // Initialize the session
    session_start();

    // If the user is already logged in, redirect them appropriately
    if (isset($_SESSION[&quot;loggedin&quot;]) &amp;&amp; $_SESSION[&quot;loggedin&quot;] === true) {
        // Determine where to redirect the user
        if (isset($_SESSION['redirect']) &amp;&amp; !empty($_SESSION['redirect']) &amp;&amp; validate_redirect($_SESSION['redirect'], $allowed_paths)) {
            $location = $_SESSION['redirect'];
            // Clear the redirect session variable to prevent reuse
            unset($_SESSION['redirect']);
        } else {
            $location = 'dashboard';
        }

        // Redirect using BASE_URL and $location
        header('Location: ' . BASE_URL . $location); // No double slashes
        exit;
    }

    // Initialize variables
    $location = 'dashboard'; // Default location

    // Determine the redirection location after login
    if (isset($_SESSION['redirect']) &amp;&amp; !empty($_SESSION['redirect']) &amp;&amp; validate_redirect($_SESSION['redirect'], $allowed_paths)) {
        $location = $_SESSION['redirect'];
    }

    // CSRF token generation and session check
    if (!isset($_SESSION[&quot;csrf_token&quot;]) || empty($_SESSION['csrf_token'])) {
        $csrf_token = generateRandomString(32);
        $_SESSION[&quot;csrf_token&quot;] = $csrf_token;
    } else {
        $csrf_token = $_SESSION['csrf_token'];
    }

    // Check if the user is already logged in, if yes then redirect to dashboard page
    if (isset($_SESSION[&quot;loggedin&quot;]) &amp;&amp; $_SESSION[&quot;loggedin&quot;] === true) {
        header('location:' . BASE_URL . $location);
        exit;
    } elseif (isset($_COOKIE['rememberme'])) {
        // Decrypt cookie value
        $token = decryptCookie($_COOKIE['rememberme']);
        
        $sql_query = &quot;SELECT `uid`, `email`, `token` FROM `users` WHERE `token` = ?&quot;;
        if ($stmt = mysqli_prepare($conn, $sql_query)) {
            mysqli_stmt_bind_param($stmt, &quot;s&quot;, $token);
            if (mysqli_stmt_execute($stmt)) {
                mysqli_stmt_bind_result($stmt, $uid, $email, $db_token);
                mysqli_stmt_fetch($stmt);
                if ($db_token === $token) {
                    $_SESSION[&quot;uid&quot;] = $uid;
                    $_SESSION[&quot;email&quot;] = $email;
                    $_SESSION[&quot;token&quot;] = $token;
                    $_SESSION[&quot;loggedin&quot;] = true; // Set the logged-in flag
                    header('Location: ' . BASE_URL . $location);
                    exit;
                }
            }
            mysqli_stmt_close($stmt);
        }
    }

    // Define variables and initialize with empty values
    $email = $password = &quot;&quot;;
    $email_err = $password_err = $errorMSG = &quot;&quot;;

    // Processing form data when form is submitted
    if ($_SERVER[&quot;REQUEST_METHOD&quot;] == &quot;POST&quot;) {
        // Validate CSRF token
        if (!isset($_POST['csrf_token']) || empty($_POST['csrf_token']) || $_POST['csrf_token'] !== $_SESSION['csrf_token']) {
            $errorMSG = &quot;Invalid CSRF token. Please try again.&quot;;
        } else {

            // Check if email is empty
            if (empty(trim($_POST[&quot;email&quot;]))) {
                $email_err = &quot;Please enter your email.&quot;;
            } else {
                $email = trim($_POST[&quot;email&quot;]);
            }

            // Check if password is empty
            if (empty(trim($_POST[&quot;password&quot;]))) {
                $password_err = &quot;Please enter your password.&quot;;
            } else {
                $password = trim($_POST[&quot;password&quot;]);
            }

            // Validate credentials
            if (empty($email_err) &amp;&amp; empty($password_err)) {
                $sql = &quot;SELECT `uid`, `email`, `password`, `active`, `token` FROM `users` WHERE `email` = ?&quot;;
                if ($stmt = mysqli_prepare($conn, $sql)) {
                    mysqli_stmt_bind_param($stmt, &quot;s&quot;, $email);
                    if (mysqli_stmt_execute($stmt)) {
                        mysqli_stmt_store_result($stmt);
                        if (mysqli_stmt_num_rows($stmt) === 1) {
                            mysqli_stmt_bind_result($stmt, $uid, $db_email, $hashed_password, $isActive, $token);
                            if (mysqli_stmt_fetch($stmt)) {
                                if (password_verify($password, $hashed_password)) {
                                    if ($isActive === 1) {
                                        // Start session and set session variables
                                        session_regenerate_id();  // Prevent session fixation attacks
                                        $_SESSION[&quot;loggedin&quot;] = true;
                                        $_SESSION[&quot;uid&quot;] = $uid;
                                        $_SESSION[&quot;email&quot;] = $db_email;
                                        $_SESSION[&quot;token&quot;] = $token;

                                        // Fetch the previous last_login and last_login_ip details
                                        $sql_fetch = &quot;SELECT `first_name`, `last_name`, `last_login`, `last_login_ip` FROM `users` WHERE `uid` = ?&quot;;
                                        if ($stmt_fetch = mysqli_prepare($conn, $sql_fetch)) {
                                            mysqli_stmt_bind_param($stmt_fetch, &quot;i&quot;, $uid); // Assuming $uid is already available
                                            mysqli_stmt_execute($stmt_fetch);
                                            mysqli_stmt_bind_result($stmt_fetch, $first_name, $last_name, $prev_last_login, $prev_last_login_ip);
                                            mysqli_stmt_fetch($stmt_fetch);
                                            mysqli_stmt_close($stmt_fetch);

                                            // Store the previous login details in session variables
                                            $_SESSION[&quot;prev_last_login&quot;] = $prev_last_login;
                                            $_SESSION[&quot;prev_last_login_ip&quot;] = $prev_last_login_ip;

                                            $fullName = $first_name . &quot; &quot; . $last_name;
                                        }

                                        // Check if &quot;remember me&quot; was selected
                                        if (isset($_POST[&quot;rememberme&quot;])) {
                                            $_SESSION[&quot;rememberme&quot;] = true;
                                            // Generate and store token as before
                                            $encryptedToken = encryptCookie($_SESSION[&quot;token&quot;]);
                                        
                                            // Extract the domain from BASE_URL
                                            $url_parts = parse_url(BASE_URL);
                                            $domain = $url_parts['host'];
                                        
                                            // Set the rememberme cookie using array syntax
                                            setcookie('rememberme', $encryptedToken, [
                                                'expires' => time() + (86400 * 30), // 30 days
                                                'path' => '/',
                                                'domain' => $domain, // Correctly set the domain
                                                'secure' => true,     // Only send cookie over HTTPS
                                                'httponly' => true,   // Accessible only through the HTTP protocol
                                                'samesite' => 'Strict' // Adjust as needed (None, Lax, Strict)
                                            ]);
                                        } else {
                                            $_SESSION[&quot;rememberme&quot;] = false;
                                            // Optionally, delete the rememberme cookie
                                            $url_parts = parse_url(BASE_URL);
                                            $domain = $url_parts['host'];
                                        
                                            setcookie('rememberme', '', [
                                                'expires' => time() - 3600, // Set time in the past to delete
                                                'path' => '/',
                                                'domain' => $domain,        // Correctly set the domain
                                                'secure' => true,
                                                'httponly' => true,
                                                'samesite' => 'Strict'
                                            ]);
                                        }

                                        // Update `last_login` and `last_login_ip` in `users` table
                                        $last_login = date('Y-m-d H:i:s');
                                        $last_login_ip = getUserIP();
                                        $sql_update = &quot;UPDATE `users` SET `last_login` = ?, `last_login_ip` = ? WHERE `uid` = ?&quot;;
                                        if ($stmt_update = mysqli_prepare($conn, $sql_update)) {
                                            mysqli_stmt_bind_param($stmt_update, &quot;sss&quot;, $last_login, $last_login_ip, $uid);
                                            mysqli_stmt_execute($stmt_update);
                                            mysqli_stmt_close($stmt_update);
                                        }

                                        $queryNotification = &quot;SELECT notification_pref_security FROM user_profile WHERE uid = ?&quot;;
                                        $stmtNotification = mysqli_prepare($conn, $queryNotification);
                                        mysqli_stmt_bind_param($stmtNotification, 'i', $_SESSION[&quot;uid&quot;]);
                                        mysqli_stmt_execute($stmtNotification);
                                        mysqli_stmt_store_result($stmtNotification);

                                        if (mysqli_stmt_num_rows($stmtNotification) > 0) {
                                            mysqli_stmt_bind_result($stmtNotification, $notif_security);
                                            mysqli_stmt_fetch($stmtNotification);
                                        } else {
                                            $notif_security = 1;
                                        }

                                        mysqli_stmt_close($stmtNotification);

                                        if ($notif_security === 1 &amp;&amp; $_SESSION[&quot;prev_last_login_ip&quot;] != $last_login_ip) {
                                            $last_login_datetime = date('M d, Y, h:i A', strtotime($last_login));

                                            AbstractDeviceParser::setVersionTruncation(AbstractDeviceParser::VERSION_TRUNCATION_NONE);
                                            $userAgent = $_SERVER['HTTP_USER_AGENT']; // change this to the useragent you want to parse
                                            $clientHints = ClientHints::factory($_SERVER); // client hints are optional
                                            $dd = new DeviceDetector($userAgent, $clientHints);
                                            $dd->parse();

                                            if ($dd->isBot()) {
                                                // handle bots,spiders,crawlers,...
                                                $botInfo = $dd->getBot();
                                            } else {
                                                $clientInfo = $dd->getClient(); // holds information about browser, feed reader, media player, ...
                                                $osInfo = $dd->getOs();
                                                $device = $dd->getDeviceName();
                                                $brand = $dd->getBrandName();
                                                $model = $dd->getModel();
                                            }

                                            $ipBase = new \Ipbase\Ipbase\IpbaseClient('ipb_live_BSBfuKApOLL6vkZ1SJCzP8oWbygM1ncMUzBd6iVd');
                                            $ipBaseData = $ipBase->info();

                                            //$ipBaseData = json_decode($ipBaseDataJSON, true);
                                            $ipBaseDataLocation = $ipBaseData['data']['location'];
                                            $city = $ipBaseDataLocation['city']['name'];
                                            $region = $ipBaseDataLocation['region']['name'];
                                            $country = $ipBaseDataLocation['country']['name'];

                                            $location_string = &quot;$city, $region, $country&quot;;
                                            
                                            $emailBody = file_get_contents('templates/newLoginEmailTemplate.html');
                                            $toReplace = ['::BASEURL::', '::FULLNAME::', '::CURRENTYEAR::', '::DEVICE::', '::CLIENT::', '::OS::', '::LOCATION::', '::DATETIME::'];
                                            $withThis = [BASE_URL, $fullName, $currentYear, ucfirst($device), $clientInfo['name'], $osInfo['name'], $location_string, $last_login_datetime];
                                            $emailBody = str_replace($toReplace, $withThis, $emailBody);

                                            // Prepare email variables
                                            $toEmail = $email; // Recipient's email address
                                            $toName = $fullName; // Recipient's full name
                                            $subject = 'New Device Login Alert for Your TrackBack.email Account';
                                            $body = $emailBody; // Your HTML email body

                                            // Send the email
                                            if (sendEmailNoReply($toEmail, $toName, $subject, $body)) {
                                                $msg = &quot;Successfully logged in!&quot;;
                                            } else {
                                                $errorMSG = &quot;New Login detected email could not be sent.<br>Kindly contact us for further assistance.&quot;;
                                            }
                                        }

                                        unset($_SESSION['csrf_token']); // Unset session token after submitting
                                        header('location:' . BASE_URL . $location);
                                    } else {
                                        // Account is not activated
                                        $errorMSG = &quot;Your account is not activated yet.<br>Please check your inbox for activation email.&quot;;
                                    }
                                } else {
                                    // Password is incorrect
                                    $errorMSG = &quot;Invalid email or password.&quot;;
                                }
                            }
                        } else {
                            // Email doesn't exist
                            $errorMSG = &quot;Invalid email or password.&quot;;
                        }
                    } else {
                        $errorMSG = &quot;Oops! Something went wrong. Please try again later.&quot;;
                    }
                    mysqli_stmt_close($stmt);
                }
            }
        }
        mysqli_close($conn);
    }

    include 'includes/start.php';
?>
```

### **Issues Identified:**

1. **Redundant Session Checks:**
   - **Problem:** The script checks if the user is logged in twice (`isset($_SESSION[&quot;loggedin&quot;]) &amp;&amp; $_SESSION[&quot;loggedin&quot;] === true`). This redundancy complicates the logic.
   
2. **Insecure 'Remember Me' Implementation:**
   - **Problem:** The `decryptCookie` function uses dynamic keys per encryption, making token reuse vulnerable.
   
3. **CSRF Token Handling:**
   - **Problem:** CSRF tokens are not regenerated after form submission, potentially allowing replay attacks.
   
4. **Password Verification and Session Management:**
   - **Problem:** Missing robust error handling during authentication and session fixation prevention measures.
   
5. **Incomplete 'Remember Me' Security:**
   - **Problem:** Tokens are not rotated or invalidated upon usage, increasing the risk of replay attacks.
   
6. **Error Handling and Logging:**
   - **Problem:** Errors during database operations are not logged, making debugging difficult.
   
7. **Email Sending Security:**
   - **Problem:** Emails are sent without validation or ensuring attachment security, increasing risks of injection or file manipulation.
   
8. **Potential XSS Vulnerabilities:**
   - **Problem:** User inputs like `$fullName` are directly used in emails without proper sanitization.
   
9. **External API Key Exposure:**
   - **Problem:** API keys (e.g., `IpbaseClient` key) are hard-coded, which is a security risk.

### **Step-by-Step Enhancements:**

#### **Step 1: Consolidate Session Checks**

**Issue:**
Multiple checks for `$_SESSION[&quot;loggedin&quot;]` cause redundancy.

**Solution:**
Create helper functions to manage session checks and redirections.

**Implementation:**

1. **Define Helper Functions in `commonFunctions.php`:**

    ```php
    /**
     * Check if the user is logged in.
     *
     * @return bool True if logged in, false otherwise.
     */
    function isUserLoggedIn() {
        return isset($_SESSION[&quot;loggedin&quot;]) &amp;&amp; $_SESSION[&quot;loggedin&quot;] === true;
    }

    /**
     * Get the redirect location.
     *
     * @global array $allowed_paths
     * @return string The redirect path.
     */
    function getRedirectLocation() {
        global $allowed_paths;
        if (isset($_SESSION['redirect']) &amp;&amp; !empty($_SESSION['redirect']) &amp;&amp; validate_redirect($_SESSION['redirect'], $allowed_paths)) {
            $location = $_SESSION['redirect'];
            unset($_SESSION['redirect']);
        } else {
            $location = 'dashboard';
        }
        return $location;
    }

    /**
     * Redirect the user to a specified location.
     *
     * @param string $location The location to redirect to.
     */
    function redirectTo($location) {
        // Prevent header injection
        $location = str_replace(array(&quot;\r&quot;, &quot;\n&quot;), '', $location);
        header('Location: ' . BASE_URL . $location);
        exit;
    }
    ```

2. **Use Helper Functions in Main Script:**

    ```php
    // If the user is already logged in, redirect them appropriately
    if (isUserLoggedIn()) {
        $location = getRedirectLocation();
        redirectTo($location);
    }
    ```

3. **Remove Redundant Checks:**
   - Delete the second login check to avoid duplication.

#### **Step 2: Secure 'Remember Me' Implementation**

**Issue:**
Currently, the 'remember me' token uses dynamic encryption keys and lacks proper token management.

**Solution:**
Implement a secure token-based 'remember me' system with hashed tokens, token rotation, and proper session management.

**Implementation:**

1. **Modify Token Storage:**
   - **Store Hashed Tokens:** Store a hashed version of the token in the database to prevent token exposure.
   - **Associate Tokens with Users and Devices:** Optionally, add fields like `device_name`, `expires_at`, etc., for enhanced security.

    **Database Schema Adjustment:**
    ```sql
    ALTER TABLE `users` ADD COLUMN `remember_token_hash` VARCHAR(64) NULL AFTER `token`;
    ALTER TABLE `users` ADD COLUMN `remember_token_expires` DATETIME NULL AFTER `remember_token_hash`;
    ```

2. **Generate and Store 'Remember Me' Token:**
   - **Generate Token:** Use secure random bytes.
   - **Hash Token:** Use a secure hashing algorithm.
   - **Store Hash and Expiration in Database.**

    **Implementation:**
    ```php
    if (isset($_POST[&quot;rememberme&quot;])) {
        // Generate secure token
        $token = generateRandomString(64);
        $hashed_token = hash('sha256', $token);
        $expires_at = date('Y-m-d H:i:s', strtotime('+30 days'));

        // Update token in database
        $sql_update_token = &quot;UPDATE `users` SET `remember_token_hash` = ?, `remember_token_expires` = ? WHERE `uid` = ?&quot;;
        if ($stmt_update = mysqli_prepare($conn, $sql_update_token)) {
            mysqli_stmt_bind_param($stmt_update, &quot;ssi&quot;, $hashed_token, $expires_at, $uid);
            mysqli_stmt_execute($stmt_update);
            mysqli_stmt_close($stmt_update);
        }

        // Encrypt token before setting cookie
        $encryptedToken = encryptCookie($token);

        // Set the 'rememberme' cookie
        $url_parts = parse_url(BASE_URL);
        $domain = $url_parts['host'];

        setcookie('rememberme', $encryptedToken, [
            'expires' => time() + (86400 * 30), // 30 days
            'path' => '/',
            'domain' => $domain,
            'secure' => true,     // Only send cookie over HTTPS
            'httponly' => true,   // Accessible only through the HTTP protocol
            'samesite' => 'Strict' // Adjust as needed (None, Lax, Strict)
        ]);
    } else {
        // Delete the 'rememberme' cookie and remove token from database
        if (isset($_COOKIE['rememberme'])) {
            // Get user ID from session or other means
            $uid = $_SESSION[&quot;uid&quot;] ?? null;
            if ($uid) {
                $sql_clear_token = &quot;UPDATE `users` SET `remember_token_hash` = NULL, `remember_token_expires` = NULL WHERE `uid` = ?&quot;;
                if ($stmt_clear = mysqli_prepare($conn, $sql_clear_token)) {
                    mysqli_stmt_bind_param($stmt_clear, &quot;i&quot;, $uid);
                    mysqli_stmt_execute($stmt_clear);
                    mysqli_stmt_close($stmt_clear);
                }
            }

            // Delete the cookie
            $url_parts = parse_url(BASE_URL);
            $domain = $url_parts['host'];

            setcookie('rememberme', '', [
                'expires' => time() - 3600, // Past time to delete
                'path' => '/',
                'domain' => $domain,
                'secure' => true,
                'httponly' => true,
                'samesite' => 'Strict'
            ]);
        }
    }
    ```

3. **Handle 'Remember Me' Auto-Login Securely:**

    **Implementation:**
    ```php
    // Handle 'remember me' auto-login
    if (isset($_COOKIE['rememberme'])) {
        $token = decryptCookie($_COOKIE['rememberme']);
        if ($token) {
            $hashed_token = hash('sha256', $token);
            $sql_query = &quot;SELECT `uid`, `email`, `remember_token_hash`, `remember_token_expires` FROM `users` WHERE `remember_token_hash` = ?&quot;;
            if ($stmt = mysqli_prepare($conn, $sql_query)) {
                mysqli_stmt_bind_param($stmt, &quot;s&quot;, $hashed_token);
                if (mysqli_stmt_execute($stmt)) {
                    mysqli_stmt_store_result($stmt);
                    if (mysqli_stmt_num_rows($stmt) === 1) {
                        mysqli_stmt_bind_result($stmt, $uid, $email, $db_hashed_token, $token_expires);
                        if (mysqli_stmt_fetch($stmt)) {
                            if (hash_equals($db_hashed_token, $hashed_token) &amp;&amp; strtotime($token_expires) > time()) {
                                // Valid token
                                session_regenerate_id(true);
                                $_SESSION[&quot;uid&quot;] = $uid;
                                $_SESSION[&quot;email&quot;] = $email;
                                $_SESSION[&quot;loggedin&quot;] = true;

                                // Update `last_login` and `last_login_ip`
                                $last_login = date('Y-m-d H:i:s');
                                $last_login_ip = getUserIP();
                                $sql_update = &quot;UPDATE `users` SET `last_login` = ?, `last_login_ip` = ? WHERE `uid` = ?&quot;;
                                if ($stmt_update = mysqli_prepare($conn, $sql_update)) {
                                    mysqli_stmt_bind_param($stmt_update, &quot;ssi&quot;, $last_login, $last_login_ip, $uid);
                                    mysqli_stmt_execute($stmt_update);
                                    mysqli_stmt_close($stmt_update);
                                }

                                // Optionally, rotate the token
                                // Generate a new token, store its hash, set new cookie

                                redirectTo(getRedirectLocation());
                            }
                        }
                    }
                }
                mysqli_stmt_close($stmt);
            }
        }

        // Invalid token: delete the cookie
        setcookie('rememberme', '', [
            'expires' => time() - 3600,
            'path' => '/',
            'domain' => parse_url(BASE_URL, PHP_URL_HOST),
            'secure' => true,
            'httponly' => true,
            'samesite' => 'Strict'
        ]);
    }
    ```

4. **Implement CSRF Token Rotation:**

    **Issue:**
    CSRF tokens are not regenerated after form submissions, allowing potential replay attacks.

    **Solution:**
    Regenerate CSRF tokens after successful form processing.

    **Implementation:**
    ```php
    // After successful login
    unset($_SESSION['csrf_token']);
    $_SESSION['csrf_token'] = generateRandomString(32); // Generate a new token
    ```

5. **Enhance Password Handling and Verification:**

    **Issue:**
    Missing checks for password rehashing and ensuring password strength during registration (not shown here but important).

    **Solution:**
    - **Rehash Passwords if Needed:**
      Use `password_needs_rehash()` to upgrade password hashes when the hashing algorithm changes.

      **Implementation:**
      ```php
      if (password_verify($password, $hashed_password)) {
          if (password_needs_rehash($hashed_password, PASSWORD_DEFAULT)) {
              $new_hashed_password = password_hash($password, PASSWORD_DEFAULT);
              // Update the password in the database
              $sql_rehash = &quot;UPDATE `users` SET `password` = ? WHERE `uid` = ?&quot;;
              if ($stmt_rehash = mysqli_prepare($conn, $sql_rehash)) {
                  mysqli_stmt_bind_param($stmt_rehash, &quot;si&quot;, $new_hashed_password, $uid);
                  mysqli_stmt_execute($stmt_rehash);
                  mysqli_stmt_close($stmt_rehash);
              }
          }

          // Proceed with login...
      }
      ```

6. **Implement Robust Error Handling and Logging:**

    **Issue:**
    Errors during authentication are set as messages but not logged, which complicates debugging.

    **Solution:**
    Log all critical errors while providing user-friendly messages.

    **Implementation:**
    ```php
    // After failed MySQL operations
    if (!$stmt) {
        error_log(&quot;MySQL Prepare Error: &quot; . mysqli_error($conn));
        $errorMSG = &quot;An unexpected error occurred. Please try again later.&quot;;
    }
    ```

7. **Sanitize Outputs to Prevent XSS:**

    **Issue:**
    User inputs and dynamic content like `$fullName` are used directly without sanitization, risking XSS attacks.

    **Solution:**
    Use `htmlspecialchars()` when outputting user data.

    **Implementation:**
    ```php
    // When displaying error messages
    echo htmlspecialchars($errorMSG, ENT_QUOTES, 'UTF-8');

    // When embedding user data in email templates
    $withThis = [
        BASE_URL,
        htmlspecialchars($fullName, ENT_QUOTES, 'UTF-8'),
        htmlspecialchars($currentYear, ENT_QUOTES, 'UTF-8'),
        htmlspecialchars(ucfirst($device), ENT_QUOTES, 'UTF-8'),
        htmlspecialchars($clientInfo['name'], ENT_QUOTES, 'UTF-8'),
        htmlspecialchars($osInfo['name'], ENT_QUOTES, 'UTF-8'),
        htmlspecialchars($location_string, ENT_QUOTES, 'UTF-8'),
        htmlspecialchars($last_login_datetime, ENT_QUOTES, 'UTF-8')
    ];
    ```

8. **Secure API Keys and External Services:**

    **Issue:**
    API keys (e.g., `IpbaseClient` key) are hard-coded, leading to security vulnerabilities.

    **Solution:**
    Store API keys securely using environment variables.

    **Implementation:**
    ```php
    $ipBase = new \Ipbase\Ipbase\IpbaseClient(getenv('IPBASE_API_KEY'));
    ```

    **Ensure:**
    - API keys are set as environment variables and not exposed in the codebase.
    - Restrict API key permissions to the minimum required.

9. **Optimize and Structure Database Queries:**

    **Issue:**
    Multiple queries fetching user information can lead to inefficiency.

    **Solution:**
    Consolidate queries to retrieve all necessary user data in a single query.

    **Implementation:**
    ```php
    // Consolidated query
    $sql = &quot;SELECT `uid`, `email`, `password`, `active`, `token`, `first_name`, `last_name`, `last_login`, `last_login_ip` FROM `users` WHERE `email` = ?&quot;;
    if ($stmt = mysqli_prepare($conn, $sql)) {
        mysqli_stmt_bind_param($stmt, &quot;s&quot;, $email);
        if (mysqli_stmt_execute($stmt)) {
            mysqli_stmt_store_result($stmt);
            if (mysqli_stmt_num_rows($stmt) === 1) {
                mysqli_stmt_bind_result($stmt, $uid, $db_email, $hashed_password, $isActive, $token, $first_name, $last_name, $prev_last_login, $prev_last_login_ip);
                if (mysqli_stmt_fetch($stmt)) {
                    // Proceed with authentication
                }
            }
        }
    }
    ```

10. **Enhance Security in Device and IP Detection:**

    **Issue:**
    Device and IP detection logic is intertwined with authentication, potentially leading to performance issues or security flaws.

    **Solution:**
    Modularize device and IP detection, handle failures gracefully, and ensure that API interactions are secure.

    **Implementation:**
    ```php
    if ($notif_security === 1 &amp;&amp; $_SESSION[&quot;prev_last_login_ip&quot;] != $last_login_ip) {
        $last_login_datetime = date('M d, Y, h:i A', strtotime($last_login));

        AbstractDeviceParser::setVersionTruncation(AbstractDeviceParser::VERSION_TRUNCATION_NONE);
        $userAgent = $_SERVER['HTTP_USER_AGENT'];
        $clientHints = ClientHints::factory($_SERVER);
        $dd = new DeviceDetector($userAgent, $clientHints);
        $dd->parse();

        if ($dd->isBot()) {
            $botInfo = $dd->getBot();
            // Optionally, skip sending email for bots
            continue;
        } else {
            $clientInfo = $dd->getClient(); // Browser info
            $osInfo = $dd->getOs();
            $device = $dd->getDeviceName();
        }

        // IP Geolocation
        $ipBase = new \Ipbase\Ipbase\IpbaseClient(getenv('IPBASE_API_KEY'));
        $ipBaseData = $ipBase->info(getUserIP()); // Pass the user IP explicitly
        if (isset($ipBaseData['data']['location'])) {
            $ipBaseDataLocation = $ipBaseData['data']['location'];
            $city = $ipBaseDataLocation['city']['name'];
            $region = $ipBaseDataLocation['region']['name'];
            $country = $ipBaseDataLocation['country']['name'];
            $location_string = &quot;$city, $region, $country&quot;;
        } else {
            $location_string = 'Unknown Location';
        }

        // Prepare and send email as before, ensuring all data is sanitized
    }
    ```

11. **Implement Rate Limiting and Brute-Force Protection (Already Addressed in Previous Recommendations):**

    **Implement Features Like:**
    - Tracking failed login attempts.
    - Temporarily locking accounts after multiple failures.
    - Introducing CAPTCHAs after several failed attempts.

### **Revised Main Login Script:**

Considering the above recommendations, here's an enhanced version of your main login script.

```php
<?php
    // Autoload dependencies
    require_once 'vendor/autoload.php';

    // Include required files
    require_once 'includes/config.php';
    require_once 'includes/commonVariables.php';
    require_once 'includes/commonFunctions.php';

    // Initialize the session (session_set_cookie_params already handled in config.php)
    // session_start(); // Already called in config.php

    // Handle 'Remember Me' Auto-Login
    if (isset($_COOKIE['rememberme'])) {
        $token = decryptCookie($_COOKIE['rememberme']);
        if ($token) {
            $hashed_token = hash('sha256', $token);
            $sql_query = &quot;SELECT `uid`, `email`, `remember_token_hash`, `remember_token_expires` FROM `users` WHERE `remember_token_hash` = ?&quot;;
            if ($stmt = mysqli_prepare($conn, $sql_query)) {
                mysqli_stmt_bind_param($stmt, &quot;s&quot;, $hashed_token);
                if (mysqli_stmt_execute($stmt)) {
                    mysqli_stmt_store_result($stmt);
                    if (mysqli_stmt_num_rows($stmt) === 1) {
                        mysqli_stmt_bind_result($stmt, $uid, $email, $db_hashed_token, $token_expires);
                        if (mysqli_stmt_fetch($stmt)) {
                            if (hash_equals($db_hashed_token, $hashed_token) &amp;&amp; strtotime($token_expires) > time()) {
                                // Valid token
                                session_regenerate_id(true);
                                $_SESSION[&quot;uid&quot;] = $uid;
                                $_SESSION[&quot;email&quot;] = $email;
                                $_SESSION[&quot;loggedin&quot;] = true;

                                // Update `last_login` and `last_login_ip`
                                $last_login = date('Y-m-d H:i:s');
                                $last_login_ip = getUserIP();

                                $sql_update = &quot;UPDATE `users` SET `last_login` = ?, `last_login_ip` = ? WHERE `uid` = ?&quot;;
                                if ($stmt_update = mysqli_prepare($conn, $sql_update)) {
                                    mysqli_stmt_bind_param($stmt_update, &quot;ssi&quot;, $last_login, $last_login_ip, $uid);
                                    mysqli_stmt_execute($stmt_update);
                                    mysqli_stmt_close($stmt_update);
                                }

                                // Rotate 'remember me' token for enhanced security
                                $newToken = generateRandomString(64);
                                $newHashedToken = hash('sha256', $newToken);
                                $newExpiresAt = date('Y-m-d H:i:s', strtotime('+30 days'));

                                $sql_rotate_token = &quot;UPDATE `users` SET `remember_token_hash` = ?, `remember_token_expires` = ? WHERE `uid` = ?&quot;;
                                if ($stmt_rotate = mysqli_prepare($conn, $sql_rotate_token)) {
                                    mysqli_stmt_bind_param($stmt_rotate, &quot;ssi&quot;, $newHashedToken, $newExpiresAt, $uid);
                                    mysqli_stmt_execute($stmt_rotate);
                                    mysqli_stmt_close($stmt_rotate);
                                }

                                // Set new 'rememberme' cookie
                                $encryptedNewToken = encryptCookie($newToken);
                                $url_parts = parse_url(BASE_URL);
                                $domain = $url_parts['host'];

                                setcookie('rememberme', $encryptedNewToken, [
                                    'expires' => time() + (86400 * 30), // 30 days
                                    'path' => '/',
                                    'domain' => $domain,
                                    'secure' => true,
                                    'httponly' => true,
                                    'samesite' => 'Strict'
                                ]);

                                redirectTo(getRedirectLocation());
                            }
                        }
                    }
                }
                mysqli_stmt_close($stmt);
            }
        }

        // Invalid token: delete the cookie
        setcookie('rememberme', '', [
            'expires' => time() - 3600,
            'path' => '/',
            'domain' => parse_url(BASE_URL, PHP_URL_HOST),
            'secure' => true,
            'httponly' => true,
            'samesite' => 'Strict'
        ]);
    }

    // If the user is already logged in, redirect them appropriately
    if (isUserLoggedIn()) {
        redirectTo(getRedirectLocation());
    }

    // Initialize variables
    $email = $password = &quot;&quot;;
    $email_err = $password_err = $errorMSG = &quot;&quot;;

    // Generate CSRF Token (already handled earlier)
    // $csrf_token = isset($_SESSION['csrf_token']) ? $_SESSION['csrf_token'] : generateRandomString(32);

    // Processing form data when form is submitted
    if ($_SERVER[&quot;REQUEST_METHOD&quot;] === &quot;POST&quot;) {
        // Validate CSRF token
        if (!isset($_POST['csrf_token']) || empty($_POST['csrf_token']) || $_POST['csrf_token'] !== $_SESSION['csrf_token']) {
            $errorMSG = &quot;Invalid CSRF token. Please try again.&quot;;
            logError(&quot;CSRF token mismatch for session ID: &quot; . session_id());
        } else {
            // Sanitize and validate email
            $email = filter_var(trim($_POST[&quot;email&quot;]), FILTER_SANITIZE_EMAIL);
            if (empty($email)) {
                $email_err = &quot;Please enter your email.&quot;;
            } elseif (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
                $email_err = &quot;Please enter a valid email address.&quot;;
            }

            // Validate password
            $password = trim($_POST[&quot;password&quot;]);
            if (empty($password)) {
                $password_err = &quot;Please enter your password.&quot;;
            } elseif (strlen($password) < 8) {
                $password_err = &quot;Password must be at least 8 characters long.&quot;;
            }

            // Proceed if no validation errors
            if (empty($email_err) &amp;&amp; empty($password_err)) {
                $sql = &quot;SELECT `uid`, `email`, `password`, `active`, `token`, `first_name`, `last_name`, `last_login`, `last_login_ip` FROM `users` WHERE `email` = ?&quot;;
                if ($stmt = mysqli_prepare($conn, $sql)) {
                    mysqli_stmt_bind_param($stmt, &quot;s&quot;, $email);
                    if (mysqli_stmt_execute($stmt)) {
                        mysqli_stmt_store_result($stmt);
                        if (mysqli_stmt_num_rows($stmt) === 1) {
                            mysqli_stmt_bind_result($stmt, $uid, $db_email, $hashed_password, $isActive, $token, $first_name, $last_name, $prev_last_login, $prev_last_login_ip);
                            if (mysqli_stmt_fetch($stmt)) {
                                if (password_verify($password, $hashed_password)) {
                                    if ($isActive === 1) {
                                        // Valid credentials and account active
                                        session_regenerate_id(true);
                                        $_SESSION[&quot;loggedin&quot;] = true;
                                        $_SESSION[&quot;uid&quot;] = $uid;
                                        $_SESSION[&quot;email&quot;] = $db_email;
                                        $_SESSION[&quot;token&quot;] = $token;
                                        $_SESSION[&quot;prev_last_login&quot;] = $prev_last_login;
                                        $_SESSION[&quot;prev_last_login_ip&quot;] = $prev_last_login_ip;

                                        $fullName = htmlspecialchars($first_name . &quot; &quot; . $last_name, ENT_QUOTES, 'UTF-8');

                                        // Handle 'remember me' functionality (as previously implemented)
                                        if (isset($_POST[&quot;rememberme&quot;])) {
                                            // Generate secure token
                                            $token = generateRandomString(64);
                                            $hashed_token = hash('sha256', $token);
                                            $expires_at = date('Y-m-d H:i:s', strtotime('+30 days'));

                                            // Update token in database
                                            $sql_update_token = &quot;UPDATE `users` SET `remember_token_hash` = ?, `remember_token_expires` = ? WHERE `uid` = ?&quot;;
                                            if ($stmt_update = mysqli_prepare($conn, $sql_update_token)) {
                                                mysqli_stmt_bind_param($stmt_update, &quot;ssi&quot;, $hashed_token, $expires_at, $uid);
                                                mysqli_stmt_execute($stmt_update);
                                                mysqli_stmt_close($stmt_update);
                                            }

                                            // Encrypt token before setting cookie
                                            $encryptedToken = encryptCookie($token);

                                            // Extract domain from BASE_URL
                                            $url_parts = parse_url(BASE_URL);
                                            $domain = $url_parts['host'];

                                            // Set the 'rememberme' cookie
                                            setcookie('rememberme', $encryptedToken, [
                                                'expires' => time() + (86400 * 30), // 30 days
                                                'path' => '/',
                                                'domain' => $domain,
                                                'secure' => true,
                                                'httponly' => true,
                                                'samesite' => 'Strict'
                                            ]);
                                        } else {
                                            // Delete the 'rememberme' cookie and remove token from database
                                            if (isset($_COOKIE['rememberme'])) {
                                                $sql_clear_token = &quot;UPDATE `users` SET `remember_token_hash` = NULL, `remember_token_expires` = NULL WHERE `uid` = ?&quot;;
                                                if ($stmt_clear = mysqli_prepare($conn, $sql_clear_token)) {
                                                    mysqli_stmt_bind_param($stmt_clear, &quot;i&quot;, $uid);
                                                    mysqli_stmt_execute($stmt_clear);
                                                    mysqli_stmt_close($stmt_clear);
                                                }

                                                // Delete the cookie
                                                $url_parts = parse_url(BASE_URL);
                                                $domain = $url_parts['host'];

                                                setcookie('rememberme', '', [
                                                    'expires' => time() - 3600, // Past time to delete
                                                    'path' => '/',
                                                    'domain' => $domain,
                                                    'secure' => true,
                                                    'httponly' => true,
                                                    'samesite' => 'Strict'
                                                ]);
                                            }
                                        }

                                        // Update `last_login` and `last_login_ip` in `users` table
                                        $last_login = date('Y-m-d H:i:s');
                                        $last_login_ip = getUserIP();
                                        $sql_update = &quot;UPDATE `users` SET `last_login` = ?, `last_login_ip` = ? WHERE `uid` = ?&quot;;
                                        if ($stmt_update = mysqli_prepare($conn, $sql_update)) {
                                            mysqli_stmt_bind_param($stmt_update, &quot;ssi&quot;, $last_login, $last_login_ip, $uid);
                                            mysqli_stmt_execute($stmt_update);
                                            mysqli_stmt_close($stmt_update);
                                        }

                                        // Fetch notification preferences
                                        $queryNotification = &quot;SELECT `notification_pref_security` FROM `user_profile` WHERE `uid` = ?&quot;;
                                        if ($stmtNotification = mysqli_prepare($conn, $queryNotification)) {
                                            mysqli_stmt_bind_param($stmtNotification, 'i', $uid);
                                            mysqli_stmt_execute($stmtNotification);
                                            mysqli_stmt_bind_result($stmtNotification, $notif_security);
                                            mysqli_stmt_store_result($stmtNotification);
                                            if (mysqli_stmt_num_rows($stmtNotification) > 0) {
                                                mysqli_stmt_fetch($stmtNotification);
                                            } else {
                                                $notif_security = 1; // Default to enabled
                                            }
                                            mysqli_stmt_close($stmtNotification);
                                        }

                                        // Check for new IP login and send notification
                                        if ($notif_security === 1 &amp;&amp; $_SESSION[&quot;prev_last_login_ip&quot;] !== $last_login_ip) {
                                            // Device and IP information parsing
                                            AbstractDeviceParser::setVersionTruncation(AbstractDeviceParser::VERSION_TRUNCATION_NONE);
                                            $userAgent = $_SERVER['HTTP_USER_AGENT'];
                                            $clientHints = ClientHints::factory($_SERVER);
                                            $dd = new DeviceDetector($userAgent, $clientHints);
                                            $dd->parse();

                                            if ($dd->isBot()) {
                                                // Optionally skip sending email for bots
                                                // $botInfo = $dd->getBot();
                                                // You might decide to log this instead
                                            } else {
                                                $clientInfo = $dd->getClient();
                                                $osInfo = $dd->getOs();
                                                $device = $dd->getDeviceName();
                                            }

                                            // IP Geolocation
                                            $ipBase = new \Ipbase\Ipbase\IpbaseClient(getenv('IPBASE_API_KEY'));
                                            $ipDetails = $ipBase->info($last_login_ip); // Pass user IP explicitly
                                            if (isset($ipDetails['data']['location'])) {
                                                $ipBaseDataLocation = $ipDetails['data']['location'];
                                                $city = $ipBaseDataLocation['city']['name'] ?? 'Unknown City';
                                                $region = $ipBaseDataLocation['region']['name'] ?? 'Unknown Region';
                                                $country = $ipBaseDataLocation['country']['name'] ?? 'Unknown Country';
                                                $location_string = &quot;$city, $region, $country&quot;;
                                            } else {
                                                $location_string = 'Unknown Location';
                                            }

                                            // Prepare email
                                            $last_login_datetime = date('M d, Y, h:i A', strtotime($last_login));
                                            $emailBody = file_get_contents('templates/newLoginEmailTemplate.html');
                                            $toReplace = [
                                                '::BASEURL::',
                                                '::FULLNAME::',
                                                '::CURRENTYEAR::',
                                                '::DEVICE::',
                                                '::CLIENT::',
                                                '::OS::',
                                                '::LOCATION::',
                                                '::DATETIME::'
                                            ];
                                            $withThis = [
                                                htmlspecialchars(BASE_URL, ENT_QUOTES, 'UTF-8'),
                                                $fullName,
                                                htmlspecialchars($currentYear, ENT_QUOTES, 'UTF-8'),
                                                htmlspecialchars(ucfirst($device), ENT_QUOTES, 'UTF-8'),
                                                htmlspecialchars($clientInfo['name'], ENT_QUOTES, 'UTF-8'),
                                                htmlspecialchars($osInfo['name'], ENT_QUOTES, 'UTF-8'),
                                                htmlspecialchars($location_string, ENT_QUOTES, 'UTF-8'),
                                                htmlspecialchars($last_login_datetime, ENT_QUOTES, 'UTF-8')
                                            ];
                                            $emailBody = str_replace($toReplace, $withThis, $emailBody);

                                            // Prepare email variables
                                            $toEmail = $email; // Recipient's email address
                                            $toName = $fullName; // Recipient's full name
                                            $subject = 'New Device Login Alert for Your TrackBack.email Account';
                                            $body = $emailBody; // Your HTML email body

                                            // Send the email
                                            if (sendEmailNoReply($toEmail, $toName, $subject, $body)) {
                                                $msg = &quot;Successfully logged in!&quot;;
                                            } else {
                                                $errorMSG = &quot;New login detected, but email could not be sent. Please contact support.&quot;;
                                                logError(&quot;Failed to send new login alert to $toEmail&quot;);
                                            }
                                        }

                                        // Regenerate CSRF token post-submission
                                        $_SESSION['csrf_token'] = generateRandomString(32);

                                        // Redirect to the desired location
                                        redirectTo($location);
                                    } else {
                                        // Account is not activated
                                        $errorMSG = &quot;Your account is not activated yet.<br>Please check your inbox for the activation email.&quot;;
                                        logError(&quot;Inactive account login attempt for email: $email&quot;);
                                    }
                                } else {
                                    // Password is incorrect
                                    $errorMSG = &quot;Invalid email or password.&quot;;
                                    logError(&quot;Failed login attempt for email: $email - Incorrect password.&quot;);
                                }
                            }
                        } else {
                            // Email doesn't exist
                            $errorMSG = &quot;Invalid email or password.&quot;;
                            logError(&quot;Failed login attempt for email: $email - Email not found.&quot;);
                        }
                    } else {
                        $errorMSG = &quot;Oops! Something went wrong. Please try again later.&quot;;
                        logError(&quot;MySQL Execute Error: &quot; . mysqli_error($conn));
                    }
                    mysqli_stmt_close($stmt);
                } else {
                    $errorMSG = &quot;Oops! Something went wrong. Please try again later.&quot;;
                    logError(&quot;MySQL Prepare Error: &quot; . mysqli_error($conn));
                }
            }
        }
        mysqli_close($conn);
    }

    // Include the start of your HTML/template
    include 'includes/start.php';
?>
```

### **Key Enhancements Explained:**

1. **Consolidated Session Checks:**
   - Utilized helper functions (`isUserLoggedIn()`, `getRedirectLocation()`, `redirectTo()`) to streamline session checks and redirections, eliminating redundancies.

2. **Secure 'Remember Me' Token Handling:**
   - **Token Generation:** Securely generates a 64-character token using `generateRandomString(64)`.
   - **Token Hashing:** Hashes the token using `hash('sha256', $token)` before storing it in the database.
   - **Token Rotation:** After successful auto-login via 'remember me', the token is rotated by generating a new token, storing its hash, and updating the cookie. This reduces the risk of replay attacks.
   - **Expiration Handling:** Associates an expiration date with each token to enforce token validity over time.

3. **Enhanced CSRF Protection:**
   - **Token Rotation:** After a successful form submission, the CSRF token is regenerated to prevent replay attacks.
   - **Logging on Token Mismatch:** Logs attempts with invalid CSRF tokens for monitoring suspicious activities.

4. **Improved Password Verification:**
   - **Password Rehashing:** Implements `password_needs_rehash()` to update password hashes when algorithms or parameters change.
   - **Session Fixation Prevention:** Regenerates session IDs upon successful login using `session_regenerate_id(true)`.

5. **Robust Error Handling and Logging:**
   - Logs all critical errors and failed authentication attempts using `error_log()` to aid in monitoring and debugging.
   - Provides user-friendly error messages without revealing sensitive backend information.

6. **Secure Email Sending:**
   - **Sanitize Email Content:** Uses `htmlspecialchars()` to prevent XSS in email templates.
   - **Validate Email Addresses:** Ensures all email addresses are valid before attempting to send.
   - **Handle Email Sending Failures:** Logs failures and informs users appropriately.

7. **Device and IP Detection Optimization:**
   - **Handle Bots Appropriately:** Skips sending emails for bot detections to reduce unnecessary emails.
   - **Secure API Interactions:** Retrieves geolocation data securely using environment-stored API keys and handles missing data gracefully.

8. **Session Token Cleanup:**
   - **Regenerate CSRF Tokens:** Ensures that CSRF tokens are unique per session or form submission.
   - **Unset Sensitive Session Variables:** After critical operations, sensitive session variables like CSRF tokens are unset or regenerated.

9. **Structured and Modular Code:**
   - **Helper Functions:** Encapsulate repetitive tasks into helper functions for better readability and maintainability.
   - **Code Comments:** Added inline comments to explain the purpose of key code sections, enhancing code understandability.

10. **Security Enhancements:**
    - **HTTP Headers:** Consider setting secure HTTP headers to protect against common web vulnerabilities (covered in later steps).
    - **HTTPS Enforcement:** Ensure that all operations are conducted over HTTPS to protect data in transit.

### **Final Revised Main Login Script:**

The above code snippet already reflects an enhanced, secure, and maintainable version of your main login script. However, for completeness, here's the full revised version incorporating all the discussed improvements:

```php
<?php
    // Autoload dependencies
    require_once 'vendor/autoload.php';

    // Include required files
    require_once 'includes/config.php';
    require_once 'includes/commonVariables.php';
    require_once 'includes/commonFunctions.php';

    // Initialize the session (session_set_cookie_params already handled in config.php)
    // session_start(); // Already called in config.php

    // Handle 'Remember Me' Auto-Login
    if (isset($_COOKIE['rememberme'])) {
        $token = decryptCookie($_COOKIE['rememberme']);
        if ($token) {
            $hashed_token = hash('sha256', $token);
            $sql_query = &quot;SELECT `uid`, `email`, `remember_token_hash`, `remember_token_expires` FROM `users` WHERE `remember_token_hash` = ?&quot;;
            if ($stmt = mysqli_prepare($conn, $sql_query)) {
                mysqli_stmt_bind_param($stmt, &quot;s&quot;, $hashed_token);
                if (mysqli_stmt_execute($stmt)) {
                    mysqli_stmt_store_result($stmt);
                    if (mysqli_stmt_num_rows($stmt) === 1) {
                        mysqli_stmt_bind_result($stmt, $uid, $email, $db_hashed_token, $token_expires);
                        if (mysqli_stmt_fetch($stmt)) {
                            if (hash_equals($db_hashed_token, $hashed_token) &amp;&amp; strtotime($token_expires) > time()) {
                                // Valid token
                                session_regenerate_id(true);
                                $_SESSION[&quot;uid&quot;] = $uid;
                                $_SESSION[&quot;email&quot;] = $email;
                                $_SESSION[&quot;loggedin&quot;] = true;

                                // Update `last_login` and `last_login_ip`
                                $last_login = date('Y-m-d H:i:s');
                                $last_login_ip = getUserIP();

                                $sql_update = &quot;UPDATE `users` SET `last_login` = ?, `last_login_ip` = ? WHERE `uid` = ?&quot;;
                                if ($stmt_update = mysqli_prepare($conn, $sql_update)) {
                                    mysqli_stmt_bind_param($stmt_update, &quot;ssi&quot;, $last_login, $last_login_ip, $uid);
                                    mysqli_stmt_execute($stmt_update);
                                    mysqli_stmt_close($stmt_update);
                                }

                                // Rotate 'remember me' token for enhanced security
                                $newToken = generateRandomString(64);
                                $newHashedToken = hash('sha256', $newToken);
                                $newExpiresAt = date('Y-m-d H:i:s', strtotime('+30 days'));

                                $sql_rotate_token = &quot;UPDATE `users` SET `remember_token_hash` = ?, `remember_token_expires` = ? WHERE `uid` = ?&quot;;
                                if ($stmt_rotate = mysqli_prepare($conn, $sql_rotate_token)) {
                                    mysqli_stmt_bind_param($stmt_rotate, &quot;ssi&quot;, $newHashedToken, $newExpiresAt, $uid);
                                    mysqli_stmt_execute($stmt_rotate);
                                    mysqli_stmt_close($stmt_rotate);
                                }

                                // Set new 'rememberme' cookie
                                $encryptedNewToken = encryptCookie($newToken);
                                $url_parts = parse_url(BASE_URL);
                                $domain = $url_parts['host'];

                                setcookie('rememberme', $encryptedNewToken, [
                                    'expires' => time() + (86400 * 30), // 30 days
                                    'path' => '/',
                                    'domain' => $domain,
                                    'secure' => true,
                                    'httponly' => true,
                                    'samesite' => 'Strict'
                                ]);

                                redirectTo(getRedirectLocation());
                            }
                        }
                    }
                }
                mysqli_stmt_close($stmt);
            }
        }

        // Invalid token: delete the cookie
        setcookie('rememberme', '', [
            'expires' => time() - 3600,
            'path' => '/',
            'domain' => parse_url(BASE_URL, PHP_URL_HOST),
            'secure' => true,
            'httponly' => true,
            'samesite' => 'Strict'
        ]);
    }

    // If the user is already logged in, redirect them appropriately
    if (isUserLoggedIn()) {
        redirectTo(getRedirectLocation());
    }

    // Initialize variables
    $email = $password = &quot;&quot;;
    $email_err = $password_err = $errorMSG = &quot;&quot;;

    // Generate CSRF Token (already handled in commonFunctions.php)
    // $csrf_token = isset($_SESSION['csrf_token']) ? $_SESSION['csrf_token'] : generateRandomString(32);

    // Processing form data when form is submitted
    if ($_SERVER[&quot;REQUEST_METHOD&quot;] === &quot;POST&quot;) {
        // Validate CSRF token
        if (!isset($_POST['csrf_token']) || empty($_POST['csrf_token']) || $_POST['csrf_token'] !== $_SESSION['csrf_token']) {
            $errorMSG = &quot;Invalid CSRF token. Please try again.&quot;;
            logError(&quot;CSRF token mismatch for session ID: &quot; . session_id());
        } else {
            // Sanitize and validate email
            $email = filter_var(trim($_POST[&quot;email&quot;]), FILTER_SANITIZE_EMAIL);
            if (empty($email)) {
                $email_err = &quot;Please enter your email.&quot;;
            } elseif (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
                $email_err = &quot;Please enter a valid email address.&quot;;
            }

            // Validate password
            $password = trim($_POST[&quot;password&quot;]);
            if (empty($password)) {
                $password_err = &quot;Please enter your password.&quot;;
            } elseif (strlen($password) < 8) {
                $password_err = &quot;Password must be at least 8 characters long.&quot;;
            }

            // Proceed if no validation errors
            if (empty($email_err) &amp;&amp; empty($password_err)) {
                $sql = &quot;SELECT `uid`, `email`, `password`, `active`, `token`, `first_name`, `last_name`, `last_login`, `last_login_ip` FROM `users` WHERE `email` = ?&quot;;
                if ($stmt = mysqli_prepare($conn, $sql)) {
                    mysqli_stmt_bind_param($stmt, &quot;s&quot;, $email);
                    if (mysqli_stmt_execute($stmt)) {
                        mysqli_stmt_store_result($stmt);
                        if (mysqli_stmt_num_rows($stmt) === 1) {
                            mysqli_stmt_bind_result($stmt, $uid, $db_email, $hashed_password, $isActive, $token, $first_name, $last_name, $prev_last_login, $prev_last_login_ip);
                            if (mysqli_stmt_fetch($stmt)) {
                                if (password_verify($password, $hashed_password)) {
                                    if ($isActive === 1) {
                                        // Valid credentials and account active
                                        session_regenerate_id(true);
                                        $_SESSION[&quot;loggedin&quot;] = true;
                                        $_SESSION[&quot;uid&quot;] = $uid;
                                        $_SESSION[&quot;email&quot;] = $db_email;
                                        $_SESSION[&quot;token&quot;] = $token;
                                        $_SESSION[&quot;prev_last_login&quot;] = $prev_last_login;
                                        $_SESSION[&quot;prev_last_login_ip&quot;] = $prev_last_login_ip;

                                        $fullName = htmlspecialchars($first_name . &quot; &quot; . $last_name, ENT_QUOTES, 'UTF-8');

                                        // Handle 'remember me' functionality (as previously implemented)
                                        if (isset($_POST[&quot;rememberme&quot;])) {
                                            // Generate secure token
                                            $token = generateRandomString(64);
                                            $hashed_token = hash('sha256', $token);
                                            $expires_at = date('Y-m-d H:i:s', strtotime('+30 days'));

                                            // Update token in database
                                            $sql_update_token = &quot;UPDATE `users` SET `remember_token_hash` = ?, `remember_token_expires` = ? WHERE `uid` = ?&quot;;
                                            if ($stmt_update = mysqli_prepare($conn, $sql_update_token)) {
                                                mysqli_stmt_bind_param($stmt_update, &quot;ssi&quot;, $hashed_token, $expires_at, $uid);
                                                mysqli_stmt_execute($stmt_update);
                                                mysqli_stmt_close($stmt_update);
                                            }

                                            // Encrypt token before setting cookie
                                            $encryptedToken = encryptCookie($token);

                                            // Extract domain from BASE_URL
                                            $url_parts = parse_url(BASE_URL);
                                            $domain = $url_parts['host'];

                                            // Set the 'rememberme' cookie
                                            setcookie('rememberme', $encryptedToken, [
                                                'expires' => time() + (86400 * 30), // 30 days
                                                'path' => '/',
                                                'domain' => $domain,
                                                'secure' => true,
                                                'httponly' => true,
                                                'samesite' => 'Strict'
                                            ]);
                                        } else {
                                            // Delete the 'rememberme' cookie and remove token from database
                                            if (isset($_COOKIE['rememberme'])) {
                                                $sql_clear_token = &quot;UPDATE `users` SET `remember_token_hash` = NULL, `remember_token_expires` = NULL WHERE `uid` = ?&quot;;
                                                if ($stmt_clear = mysqli_prepare($conn, $sql_clear_token)) {
                                                    mysqli_stmt_bind_param($stmt_clear, &quot;i&quot;, $uid);
                                                    mysqli_stmt_execute($stmt_clear);
                                                    mysqli_stmt_close($stmt_clear);
                                                }

                                                // Delete the cookie
                                                $url_parts = parse_url(BASE_URL);
                                                $domain = $url_parts['host'];

                                                setcookie('rememberme', '', [
                                                    'expires' => time() - 3600, // Past time to delete
                                                    'path' => '/',
                                                    'domain' => $domain,
                                                    'secure' => true,
                                                    'httponly' => true,
                                                    'samesite' => 'Strict'
                                                ]);
                                            }
                                        }

                                        // Update `last_login` and `last_login_ip` in `users` table
                                        $last_login = date('Y-m-d H:i:s');
                                        $last_login_ip = getUserIP();
                                        $sql_update = &quot;UPDATE `users` SET `last_login` = ?, `last_login_ip` = ? WHERE `uid` = ?&quot;;
                                        if ($stmt_update = mysqli_prepare($conn, $sql_update)) {
                                            mysqli_stmt_bind_param($stmt_update, &quot;ssi&quot;, $last_login, $last_login_ip, $uid);
                                            mysqli_stmt_execute($stmt_update);
                                            mysqli_stmt_close($stmt_update);
                                        }

                                        // Fetch notification preferences
                                        $queryNotification = &quot;SELECT `notification_pref_security` FROM `user_profile` WHERE `uid` = ?&quot;;
                                        if ($stmtNotification = mysqli_prepare($conn, $queryNotification)) {
                                            mysqli_stmt_bind_param($stmtNotification, 'i', $uid);
                                            mysqli_stmt_execute($stmtNotification);
                                            mysqli_stmt_bind_result($stmtNotification, $notif_security);
                                            mysqli_stmt_store_result($stmtNotification);
                                            if (mysqli_stmt_num_rows($stmtNotification) > 0) {
                                                mysqli_stmt_fetch($stmtNotification);
                                            } else {
                                                $notif_security = 1; // Default to enabled
                                            }
                                            mysqli_stmt_close($stmtNotification);
                                        }

                                        // Check for new IP login and send notification
                                        if ($notif_security === 1 &amp;&amp; $_SESSION[&quot;prev_last_login_ip&quot;] !== $last_login_ip) {
                                            // Device and IP information parsing
                                            AbstractDeviceParser::setVersionTruncation(AbstractDeviceParser::VERSION_TRUNCATION_NONE);
                                            $userAgent = $_SERVER['HTTP_USER_AGENT'];
                                            $clientHints = ClientHints::factory($_SERVER);
                                            $dd = new DeviceDetector($userAgent, $clientHints);
                                            $dd->parse();

                                            if ($dd->isBot()) {
                                                // Optionally skip sending email for bots
                                                // $botInfo = $dd->getBot();
                                                // You might decide to log this instead
                                            } else {
                                                $clientInfo = $dd->getClient();
                                                $osInfo = $dd->getOs();
                                                $device = $dd->getDeviceName();
                                            }

                                            // IP Geolocation
                                            $ipBase = new \Ipbase\Ipbase\IpbaseClient(getenv('IPBASE_API_KEY'));
                                            $ipDetails = $ipBase->info($last_login_ip); // Pass user IP explicitly
                                            if (isset($ipDetails['data']['location'])) {
                                                $ipBaseDataLocation = $ipDetails['data']['location'];
                                                $city = $ipBaseDataLocation['city']['name'] ?? 'Unknown City';
                                                $region = $ipBaseDataLocation['region']['name'] ?? 'Unknown Region';
                                                $country = $ipBaseDataLocation['country']['name'] ?? 'Unknown Country';
                                                $location_string = &quot;$city, $region, $country&quot;;
                                            } else {
                                                $location_string = 'Unknown Location';
                                            }

                                            // Prepare email
                                            $last_login_datetime = date('M d, Y, h:i A', strtotime($last_login));
                                            $emailBody = file_get_contents('templates/newLoginEmailTemplate.html');
                                            $toReplace = [
                                                '::BASEURL::',
                                                '::FULLNAME::',
                                                '::CURRENTYEAR::',
                                                '::DEVICE::',
                                                '::CLIENT::',
                                                '::OS::',
                                                '::LOCATION::',
                                                '::DATETIME::'
                                            ];
                                            $withThis = [
                                                htmlspecialchars(BASE_URL, ENT_QUOTES, 'UTF-8'),
                                                $fullName,
                                                htmlspecialchars($currentYear, ENT_QUOTES, 'UTF-8'),
                                                htmlspecialchars(ucfirst($device), ENT_QUOTES, 'UTF-8'),
                                                htmlspecialchars($clientInfo['name'], ENT_QUOTES, 'UTF-8'),
                                                htmlspecialchars($osInfo['name'], ENT_QUOTES, 'UTF-8'),
                                                htmlspecialchars($location_string, ENT_QUOTES, 'UTF-8'),
                                                htmlspecialchars($last_login_datetime, ENT_QUOTES, 'UTF-8')
                                            ];
                                            $emailBody = str_replace($toReplace, $withThis, $emailBody);

                                            // Prepare email variables
                                            $toEmail = $email; // Recipient's email address
                                            $toName = $fullName; // Recipient's full name
                                            $subject = 'New Device Login Alert for Your TrackBack.email Account';
                                            $body = $emailBody; // Your HTML email body

                                            // Send email
                                            if (sendEmailNoReply($toEmail, $toName, $subject, $body)) {
                                                $msg = &quot;Successfully logged in!&quot;;
                                            } else {
                                                $errorMSG = &quot;New login detected, but email could not be sent. Please contact support.&quot;;
                                                logError(&quot;Failed to send new login alert to $toEmail&quot;);
                                            }
                                        }

                                        // Regenerate CSRF token post-submission
                                        $_SESSION['csrf_token'] = generateRandomString(32);

                                        // Redirect to the desired location
                                        redirectTo($location);
                                    } else {
                                        // Account is not activated
                                        $errorMSG = &quot;Your account is not activated yet.<br>Please check your inbox for the activation email.&quot;;
                                        logError(&quot;Inactive account login attempt for email: $email&quot;);
                                    }
                                } else {
                                    // Password is incorrect
                                    $errorMSG = &quot;Invalid email or password.&quot;;
                                    logError(&quot;Failed login attempt for email: $email - Incorrect password.&quot;);
                                }
                            }
                        } else {
                            // Email doesn't exist
                            $errorMSG = &quot;Invalid email or password.&quot;;
                            logError(&quot;Failed login attempt for email: $email - Email not found.&quot;);
                        }
                    } else {
                        $errorMSG = &quot;Oops! Something went wrong. Please try again later.&quot;;
                        logError(&quot;MySQL Execute Error: &quot; . mysqli_error($conn));
                    }
                    mysqli_stmt_close($stmt);
                } else {
                    $errorMSG = &quot;Oops! Something went wrong. Please try again later.&quot;;
                    logError(&quot;MySQL Prepare Error: &quot; . mysqli_error($conn));
                }
            }
        }
        mysqli_close($conn);
    }

    // Include the start of your HTML/template
    include 'includes/start.php';
?>
```

### **Key Points:**

1. **Helper Functions Usage:**
   - **Session Checks:** Utilizes `isUserLoggedIn()` and `redirectTo()` for streamlined logic.
   - **Error Logging:** Employs `logError()` (assumed to be defined in `commonFunctions.php`) to log critical errors without exposing them to users.

2. **Secure 'Remember Me' Flow:**
   - **Token Generation &amp; Storage:** Uses secure token generation, hashing, and rotation.
   - **Cookie Security:** Sets cookies with `Secure`, `HttpOnly`, and `SameSite` attributes.
   - **Expiration Handling:** Associates tokens with expiration dates to enforce validity.

3. **CSRF Protection:**
   - **Validation:** Ensures that CSRF tokens match before processing form data.
   - **Rotation:** Regenerates CSRF tokens after successful form submissions to prevent replay attacks.

4. **Password Handling:**
   - **Verification:** Uses `password_verify()` for secure password checking.
   - **Rehashing:** Implements `password_needs_rehash()` to update password hashes when necessary.

5. **Device and IP Detection:**
   - **Bot Handling:** Skips email notifications for bots to reduce unnecessary emails.
   - **Geolocation:** Securely retrieves geolocation data using environment-stored API keys.
   - **Sanitization:** Ensures that all dynamic data inserted into email templates is sanitized to prevent XSS.

6. **Error Handling and Logging:**
   - **Comprehensive Logging:** Logs all significant events, including failed login attempts and email sending failures.
   - **User Feedback:** Provides user-friendly error messages without revealing internal details.

7. **Code Maintainability:**
   - **Modularization:** Separates concerns using helper functions.
   - **Inline Documentation:** Adds comments explaining the purpose of key code sections.

---

## **5. Additional Security Enhancements and Best Practices**

Beyond the immediate code improvements, consider implementing the following security measures to further fortify your authentication system:

### **a. **Implement HTTPS Exclusively**

- **Ensure All Requests Use HTTPS:**
  - Redirect HTTP requests to HTTPS to prevent data interception.
  
  **Implementation (.htaccess for Apache):**
  ```apache
  RewriteEngine On
  RewriteCond %{HTTPS} off
  RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
  ```

- **Use HSTS (HTTP Strict Transport Security):**
  - Enforces browsers to communicate only over HTTPS.
  
  **Implementation (.htaccess for Apache):**
  ```apache
  Header always set Strict-Transport-Security &quot;max-age=31536000; includeSubDomains; preload&quot;
  ```

### **b. **Set Secure HTTP Headers**

- **Content Security Policy (CSP):**
  - Mitigates XSS attacks by restricting sources of content.
  
  **Implementation:**
  ```php
  header(&quot;Content-Security-Policy: default-src 'self'; script-src 'self' https://trusted.cdn.com; object-src 'none';&quot;);
  ```

- **X-Frame-Options:**
  - Prevents clickjacking by disallowing framing of your site.
  
  **Implementation:**
  ```php
  header('X-Frame-Options: DENY');
  ```

- **X-Content-Type-Options:**
  - Prevents MIME type sniffing.
  
  **Implementation:**
  ```php
  header('X-Content-Type-Options: nosniff');
  ```

- **Referrer-Policy:**
  - Controls how much referrer information is sent with requests.
  
  **Implementation:**
  ```php
  header('Referrer-Policy: no-referrer');
  ```

- **Permissions-Policy:**
  - Manages which features and APIs can be used in the browser.
  
  **Implementation:**
  ```php
  header(&quot;Permissions-Policy: geolocation=(self)&quot;);
  ```

### **c. **Implement Multi-Factor Authentication (MFA)**

- **Enhance Security:**
  - Adding MFA significantly reduces the risk of unauthorized access, even if credentials are compromised.
  
- **Implementation Approaches:**
  - **Time-Based One-Time Passwords (TOTP):** Use apps like Google Authenticator.
  - **SMS-Based Verification:** Send verification codes via SMS (less secure than TOTP).
  - **Hardware Tokens:** Utilize devices like YubiKeys.

- **Integration Example:**
  - After password verification, prompt the user for an MFA code.
  - Validate the code using a library like [Google Authenticator](https://github.com/PHPGangsta/GoogleAuthenticator).

### **d. **Centralized Logging and Monitoring**

- **Monitor Authentication Attempts:**
  - Track successful and failed login attempts.
  - Detect and respond to suspicious activities.

- **Implementation:**
  - **Logging Library:** Use a robust logging library like [Monolog](https://github.com/Seldaek/monolog) to manage logs.
  - **Log Rotation:** Ensure logs are rotated and archived securely to prevent disk space exhaustion and unauthorized access.

### **e. **Use Prepared Statements Everywhere**

- **Consistency:**
  - Ensure that **all** database interactions use prepared statements to prevent SQL injection.
  
- **Implementation:**
  - Review your entire codebase to confirm that prepared statements are consistently used.

### **f. **Implement Rate Limiting and Brute-Force Protection**

- **Limit Login Attempts:**
  - Prevent brute-force attacks by limiting the number of login attempts from a single IP or account within a specific timeframe.
  
- **Implementation:**
  - **Database Table for Failed Attempts:**
    ```sql
    CREATE TABLE `failed_logins` (
        `id` INT AUTO_INCREMENT PRIMARY KEY,
        `email` VARCHAR(255) NOT NULL,
        `ip_address` VARCHAR(45) NOT NULL,
        `attempt_time` DATETIME NOT NULL
    );
    ```
  
  - **PHP Logic:**
    ```php
    /**
     * Check if the user has exceeded maximum failed login attempts.
     *
     * @param mysqli $conn The database connection.
     * @param string $email The email address.
     * @param string $ip_address The IP address.
     * @return bool True if exceeded, false otherwise.
     */
    function isBruteForce($conn, $email, $ip_address) {
        $time_limit = date('Y-m-d H:i:s', strtotime('-15 minutes'));
        $sql = &quot;SELECT COUNT(*) FROM `failed_logins` WHERE (`email` = ? OR `ip_address` = ?) AND `attempt_time` > ?&quot;;
        if ($stmt = mysqli_prepare($conn, $sql)) {
            mysqli_stmt_bind_param($stmt, &quot;sss&quot;, $email, $ip_address, $time_limit);
            mysqli_stmt_execute($stmt);
            mysqli_stmt_bind_result($stmt, $attempt_count);
            mysqli_stmt_fetch($stmt);
            mysqli_stmt_close($stmt);
            return $attempt_count >= 5; // Threshold
        }
        return false;
    }

    /**
     * Record a failed login attempt.
     *
     * @param mysqli $conn The database connection.
     * @param string $email The email address.
     * @param string $ip_address The IP address.
     */
    function recordFailedAttempt($conn, $email, $ip_address) {
        $sql = &quot;INSERT INTO `failed_logins` (`email`, `ip_address`, `attempt_time`) VALUES (?, ?, NOW())&quot;;
        if ($stmt = mysqli_prepare($conn, $sql)) {
            mysqli_stmt_bind_param($stmt, &quot;ss&quot;, $email, $ip_address);
            mysqli_stmt_execute($stmt);
            mysqli_stmt_close($stmt);
        }
    }

    // During form processing
    $ip_address = getUserIP();
    if (isBruteForce($conn, $email, $ip_address)) {
        $errorMSG = &quot;Too many login attempts. Please try again after 15 minutes.&quot;;
        logError(&quot;Brute-force attempt detected for email: $email from IP: $ip_address&quot;);
    } else {
        // Proceed with authentication
        if ($authentication_failed) {
            recordFailedAttempt($conn, $email, $ip_address);
            $errorMSG = &quot;Invalid email or password.&quot;;
        }
    }
    ```

### **g. **Ensure Secure Configuration Management**

- **Store Sensitive Information Securely:**
  - Avoid hard-coding sensitive information like API keys and encryption keys.
  - Use environment variables or secure configuration services.

- **Implementation:**
  - **Using Dotenv:**
    ```php
    // In config.php
    require_once 'vendor/autoload.php';
    $dotenv = Dotenv\Dotenv::createImmutable(__DIR__);
    $dotenv->load();
    ```

    ```php
    // Accessing environment variables
    $dbhostname = getenv('DB_HOST') ?: 'localhost';
    define('SMTP_PASSWORD', getenv('SMTP_PASS') ?: '');
    ```

### **h. **Implement Password Policies During Registration (Not Covered Here)**

- **Ensure Strong Passwords:**
  - Enforce password strength requirements (minimum length, complexity).

- **Implement Password Confirmation:**
  - Require users to confirm their passwords during registration.

---

## **6. Final Code Structure and Best Practices**

To maintain a clean, secure, and maintainable codebase, consider adopting the following structure and practices:

### **a. **Directory Structure:**

```
/project-root
    /vendor
    /includes
        config.php
        commonVariables.php
        commonFunctions.php
    /templates
        newLoginEmailTemplate.html
    /public
        index.php
        login.php
        error.php
    .env
    composer.json
    composer.lock
```

### **b. **Use of Composer for Autoloading and Dependency Management:**

- Ensure that all dependencies are managed via Composer to simplify updates and maintain consistency.

### **c. **Adhere to Coding Standards:**

- Follow PSR-12 coding standards for PHP to enhance code readability and maintainability.

    **Example:**
    ```php
    // Good PSR-12 Conformance
    function functionName($param1, $param2): ReturnType {
        // Function body
    }
    ```

### **d. **Implement Object-Oriented Programming (Optional but Recommended):**

- While procedural programming is functional, OOP can enhance code reusability, scalability, and organization.

    **Example:**
    ```php
    class Auth {
        private $conn;

        public function __construct($dbConnection) {
            $this->conn = $dbConnection;
        }

        public function login($email, $password) {
            // Implement login logic
        }
    }
    ```

- **Note:** Transitioning to OOP is optional but beneficial for larger projects.

### **e. **Regularly Update and Audit Dependencies:**

- Use `composer update` to keep libraries up-to-date.
- Regularly audit for security vulnerabilities using tools like [Composer Security Checker](https://github.com/FloeDesignTechnologies/ComposerSecurityChecker).

### **f. **Implement Secure Password Reset Mechanism (Not Covered Here):**

- Allow users to reset their passwords securely by sending time-limited, single-use tokens via email.

### **g. **Use Prepared Statements Consistently:**

- Ensure that **all** database interactions use prepared statements to prevent SQL injection.

### **h. **Implement Role-Based Access Control (RBAC) (Not Covered Here):**

- Assign roles to users and manage permissions accordingly to ensure that users have access only to authorized resources.

---

## **7. Testing and Validation**

After implementing the above changes, conduct thorough testing to ensure that:

1. **Functionality Works as Expected:**
   - Users can log in, log out, and use 'remember me' features without issues.
   
2. **Security Measures Are Effective:**
   - CSRF protection is functioning, and tokens are valid.
   - Rate limiting correctly restricts excessive login attempts.
   - 'Remember me' tokens cannot be exploited.
   
3. **Error Handling Is Properly Managed:**
   - Errors are logged, and users receive appropriate feedback without exposing sensitive details.
   
4. **Emails Are Sent Securely:**
   - Notification emails are sent for new device/IP logins and handled correctly.
   
5. **Sessions Are Managed Securely:**
   - Session IDs are regenerated upon login and not vulnerable to fixation.
   - Sessions expire after periods of inactivity.

6. **API Integrations Are Secure:**
   - Interactions with external services like DeviceDetector and IP geolocation APIs are secure and handle errors gracefully.

### **a. **Automated Testing:**

- **Use PHPUnit:**
  - Implement unit tests for critical functions like token generation, encryption/decryption, and authentication logic.

### **b. **Manual Testing:**

- **Attempt Various Login Scenarios:**
  - Successful login.
  - Failed login attempts.
  - 'Remember me' functionality.
  - CSRF token mismatches.
  - Rate limiting triggers.

### **c. **Security Audits:**

- **Perform Vulnerability Scanning:**
  - Use tools like [OWASP ZAP](https://www.zaproxy.org/) to scan your application for common vulnerabilities.

- **Code Reviews:**
  - Regularly review code changes for security compliance and best practices adherence.

---

## **8. Summary of Key Improvements**

1. **Security Enhancements:**
   - Securely manage encryption keys and sensitive information via environment variables.
   - Implement authenticated encryption using AES-256-GCM.
   - Strengthen 'remember me' functionality with hashed tokens and rotation.

2. **Code Maintainability:**
   - Use helper functions to streamline session checks and redirections.
   - Adopt coding standards and potentially transition to OOP for better organization.

3. **Error Handling and Logging:**
   - Centralize error logging to monitor and debug effectively without exposing sensitive information.

4. **Session Management:**
   - Enhance session security with proper cookie attributes, session timeouts, and ID regeneration.

5. **Input Validation and Sanitization:**
   - Ensure all user inputs are validated and sanitized to prevent XSS and other injection attacks.

6. **Dependency Management:**
   - Manage all dependencies via Composer, keep them updated, and audit for vulnerabilities regularly.

7. **Additional Best Practices:**
   - Enforce HTTPS, set secure HTTP headers, implement MFA, and add brute-force protection mechanisms.

---

By systematically implementing these improvements, you will significantly enhance the security, reliability, and maintainability of your login system. Always prioritize security best practices and keep abreast of the latest developments in web security to protect your application and its users effectively.

If you have further questions or need assistance with specific implementations, feel free to ask!

--

Now, I want you to help me regarding this.
Please response "Alright!", then I will share my current folder structure and other files details.
ASSISTANT
Alright!

turns-00031.parquet:35927

9caf2ba1443d0f57122b9bd5
turn 1/1o1-mini-2024-09-12EnglishIndia10769 words
degenerate_repetitionAbsentFinal dense release
USER
In our last conversation regarding my procedural PHP project, your latest response was following:
Thank you for providing the complete context of your login system, including the `config.php`, `commonVariables.php`, and `commonFunctions.php` files. This comprehensive view allows for a thorough analysis and targeted recommendations to enhance the security, maintainability, and efficiency of your authentication mechanism.

Below, I will guide you through step-by-step improvements, highlighting potential issues in your current implementation and offering best practices to address them.

---

## **1. Review and Improve `config.php`**

### **Current Configuration:**

```php
<?php
    // PHP Set
    error_reporting(E_ALL);
    ini_set('display_errors', 1);
    ini_set('display_startup_errors', 1);

    ini_set('memory_limit', '4096M');
    ini_set('max_execution_time', 0);
    ini_set('mysql.connect_timeout', 0);
    ini_set('default_socket_timeout', 0);
    set_time_limit(0);

    ini_set('session.cookie_secure', '1');
    ini_set('session.cookie_httponly', '1');
    ini_set('session.cookie_samesite', 'Strict');

    $onWeb = http_response_code() !== FALSE;
    if ($onWeb === TRUE) {
        $isLive = $_SERVER[&quot;SERVER_NAME&quot;] === &quot;valkya.lan&quot; ? FALSE : TRUE;
    } else {
        $isLive = TRUE;
    }

    // Database Details
    $dbhostname = ($isLive === TRUE ? &quot;localhost:3306&quot; : &quot;localhost&quot;);
    $dbname = ($isLive === TRUE ? &quot;trackbackemail&quot; : &quot;trackbackemail&quot;);
    $dbusername = ($isLive === TRUE ? &quot;trackback&quot; : &quot;root&quot;);
    $dbpassword = ($isLive === TRUE ? &quot;@ksharBrahm1&quot; : &quot;Gunatit@1&quot;);

    // Create connection
    $conn = mysqli_connect($dbhostname, $dbusername, $dbpassword, $dbname);

    // Check connection
    if (!$conn) {
        die(&quot;Connection failed: &quot; . mysqli_connect_error());
    }
?>
```

### **Issues Identified:**

1. **Error Reporting in Production:**
   - **Problem:** Both `display_errors` and `display_startup_errors` are set to `1`, which means all errors will be displayed. This is **not recommended** for production as it can expose sensitive information.
   
2. **Resource Limits:**
   - **Memory Limit:** Set to `4096M` (4GB), which is excessively high and can lead to resource exhaustion.
   - **Execution Time:** `max_execution_time` set to `0` (no limit), which can be risky as scripts might hang indefinitely.
   - **Sockets:** `mysql.connect_timeout` and `default_socket_timeout` set to `0`, causing no timeout. This can lead to hanging connections.
   
3. **Session Cookie Configuration:**
   - **Problem:** Setting session cookies via `ini_set` is acceptable, but these settings should be enforced **before** `session_start()`.
   - **`session.cookie_samesite`:** The `samesite` attribute isn't directly supported via `ini_set` in older PHP versions.

4. **Environment Detection:**
   - **Problem:** The detection of live vs. development is based on the server name `valkya.lan`. This is fragile and can lead to misconfiguration.

5. **Database Credentials:**
   - **Problem:** Credentials are hard-coded, which is a security risk, especially if the codebase is version-controlled or accessible.

### **Recommendations:**

1. **Separate Environments:**
   - Manage configurations for different environments (development, staging, production) separately to prevent accidental exposure of sensitive settings.

2. **Error Reporting:**
   - **Development:**
     ```php
     ini_set('display_errors', 1);
     ini_set('display_startup_errors', 1);
     error_reporting(E_ALL);
     ```
   - **Production:**
     ```php
     ini_set('display_errors', 0);
     ini_set('display_startup_errors', 0);
     error_reporting(E_ALL);
     ```
   - **Implementation:**
     ```php
     if ($isLive === TRUE) {
         ini_set('display_errors', 0);
         ini_set('display_startup_errors', 0);
     } else {
         ini_set('display_errors', 1);
         ini_set('display_startup_errors', 1);
     }
     error_reporting(E_ALL);
     ```

3. **Resource Limits:**
   - **Production:**
     ```php
     ini_set('memory_limit', '256M'); // Adjust as needed
     ini_set('max_execution_time', 30); // 30 seconds
     ini_set('mysql.connect_timeout', 10); // 10 seconds
     ini_set('default_socket_timeout', 10); // 10 seconds
     set_time_limit(30); // 30 seconds
     ```
   - **Explanation:** These settings help prevent resource exhaustion and ensure scripts don't hang indefinitely.

4. **Session Security:**
   - **Move Session Cookie Settings Before `session_start()`:**
     ```php
     ini_set('session.cookie_secure', '1');
     ini_set('session.cookie_httponly', '1');
     ini_set('session.cookie_samesite', 'Strict');
     session_start();
     ```
   - **Alternative (Using `session_set_cookie_params`):**
     ```php
     session_set_cookie_params([
         'lifetime' => 0,
         'path' => '/',
         'domain' => 'yourdomain.com', // Update accordingly
         'secure' => true,
         'httponly' => true,
         'samesite' => 'Strict',
     ]);
     session_start();
     ```
   - **Note:** The `samesite` attribute handling can vary based on PHP versions. Using `session_set_cookie_params` is more reliable.

5. **Environment Configuration:**
   - **Use Environment Variables:**
     Instead of hard-coding environment detection based on server name, consider using environment variables or separate configuration files for each environment.

     **Example:**
     ```php
     $environment = getenv('APP_ENV') ?: 'development'; // 'production', 'staging', 'development'
     if ($environment === 'production') {
         $isLive = TRUE;
         // Production-specific configurations
     } else {
         $isLive = FALSE;
         // Development-specific configurations
     }
     ```

6. **Secure Database Credentials:**
   - **Use Environment Variables:**
     Store sensitive information like database credentials in environment variables instead of hard-coding them.

     **Example:**
     ```php
     $dbhostname = getenv('DB_HOST') ?: 'localhost';
     $dbname = getenv('DB_NAME') ?: 'trackbackemail';
     $dbusername = getenv('DB_USER') ?: 'root';
     $dbpassword = getenv('DB_PASS') ?: '';
     ```
   - **Set Environment Variables Securely:**
     - **On Server:** Use server configurations or tools like [dotenv](https://github.com/vlucas/phpdotenv) to manage environment variables.
     - **Do Not** commit environment files containing sensitive data to version control.

7. **Error Handling:**
   - **Avoid using `die()` in Production:**
     Instead of stopping script execution abruptly, implement proper error handling and user-friendly error messages.

     **Example:**
     ```php
     if (!$conn) {
         error_log(&quot;Database Connection Failed: &quot; . mysqli_connect_error());
         // Redirect to an error page or show a user-friendly message
         header('Location: /error.php');
         exit;
     }
     ```

### **Revised `config.php`:**

```php
<?php
    // Load environment variables (Use composer dotenv or similar in production)
    // For example, using Dotenv
    // require_once 'vendor/autoload.php';
    // $dotenv = Dotenv\Dotenv::createImmutable(__DIR__);
    // $dotenv->load();

    // Determine the environment
    // You should set APP_ENV to 'production' in your server's environment
    $environment = getenv('APP_ENV') ?: 'development';
    $isLive = ($environment === 'production') ? TRUE : FALSE;

    // Error Reporting
    if ($isLive === TRUE) {
        ini_set('display_errors', 0);
        ini_set('display_startup_errors', 0);
    } else {
        ini_set('display_errors', 1);
        ini_set('display_startup_errors', 1);
    }
    error_reporting(E_ALL);

    // Resource Limits
    if ($isLive === TRUE) {
        ini_set('memory_limit', '256M'); // Adjust as needed
        ini_set('max_execution_time', 30); // 30 seconds
        ini_set('mysql.connect_timeout', 10); // 10 seconds
        ini_set('default_socket_timeout', 10); // 10 seconds
        set_time_limit(30); // 30 seconds
    } else {
        // Development-specific resource limits
        ini_set('memory_limit', '4096M');
        ini_set('max_execution_time', 0);
        ini_set('mysql.connect_timeout', 0);
        ini_set('default_socket_timeout', 0);
        set_time_limit(0);
    }

    // Session Cookie Settings
    session_set_cookie_params([
        'lifetime' => 0,
        'path' => '/',
        'domain' => ($isLive) ? 'trackback.email' : 'valkya.lan',
        'secure' => true, // Ensure HTTPS
        'httponly' => true,
        'samesite' => 'Strict', // Adjust as per requirement
    ]);
    session_start();

    // Database Details (Use environment variables)
    $dbhostname = getenv('DB_HOST') ?: 'localhost';
    $dbname = getenv('DB_NAME') ?: 'trackbackemail';
    $dbusername = getenv('DB_USER') ?: 'root';
    $dbpassword = getenv('DB_PASS') ?: '';

    // Create connection
    $conn = mysqli_connect($dbhostname, $dbusername, $dbpassword, $dbname);

    // Check connection
    if (!$conn) {
        error_log(&quot;Database Connection Failed: &quot; . mysqli_connect_error());
        // Redirect or handle the error appropriately
        header('Location: /error.php');
        exit;
    }
?>
```

### **Notes:**

- **Environment Variables:** Utilize tools like [vlucas/phpdotenv](https://github.com/vlucas/phpdotenv) to manage environment variables securely.
- **Error Pages:** Create a generic `error.php` to display user-friendly error messages without exposing sensitive information.

---

## **2. Review and Enhance `commonVariables.php`**

### **Current Configuration:**

```php
<?php
    // Global constants
    define('SMTP_HOST', 'smtp.ionos.com');
    define('SMTP_USERNAME', 'no-reply@trackback.email');
    define('SMTP_PASSWORD', 'Gunatit@1');
    define('SMTP_PORT', 587);

    // Set Timezone
    define('TIMEZONE', 'Asia/Calcutta');
    date_default_timezone_set(&quot;Asia/Calcutta&quot;);

    if ($isLive === TRUE) {
        define ('BASE_URL', 'https://trackback.email/');        // the home url of the website
    } else {
        define ('BASE_URL', 'https://valkya.lan/trackback.email/');     // the home url of the website
    }

    $currentYear = date('Y');

    // Define allowed redirect paths
    $allowed_paths = [
        'dashboard',
        'my-account'
        // Add other allowed internal paths here
    ];
?>
```

### **Issues Identified:**

1. **Hard-Coded SMTP Credentials:**
   - **Problem:** Storing SMTP credentials directly in code poses a significant security risk.

2. **Timezone Definition:**
   - **Problem:** Correctly setting the timezone, but it's redundant to define a constant if it's not used elsewhere.

3. **`BASE_URL` Definition:**
   - **Problem:** The logic is correct but relies on `$isLive` from `config.php`, which is acceptable but can be optimized.

4. **Allowed Paths (`$allowed_paths`):**
   - **Problem:** Minimal allowed paths included. Ensure that all necessary paths are covered and managed securely.

### **Recommendations:**

1. **Use Environment Variables for SMTP Credentials:**
   - **Reason:** Enhances security by keeping sensitive information out of the codebase.
   
   **Implementation:**
   ```php
   define('SMTP_HOST', getenv('SMTP_HOST') ?: 'smtp.ionos.com');
   define('SMTP_USERNAME', getenv('SMTP_USER') ?: 'no-reply@trackback.email');
   define('SMTP_PASSWORD', getenv('SMTP_PASS') ?: '');
   define('SMTP_PORT', getenv('SMTP_PORT') ?: 587);
   ```

2. **Manage `BASE_URL` Effectively:**
   - **Optional:** If you have more environments (staging, testing, etc.), extend the logic to accommodate them.
   
   **Alternative:**
   ```php
   define('BASE_URL', getenv('BASE_URL') ?: ($isLive ? 'https://trackback.email/' : 'https://valkya.lan/trackback.email/'));
   ```

3. **Define `TIMEZONE` Globally:**
   - **Optional:** If the `TIMEZONE` constant is used across different files, it’s acceptable. Otherwise, rely on `date_default_timezone_set()` alone.

4. **Expand `allowed_paths`:**
   - **Problem:** Ensure all legitimate redirect paths are included to prevent unauthorized redirections.
   
   **Suggestion:**
   ```php
   $allowed_paths = [
       'dashboard',
       'my-account',
       'settings',
       'profile',
       'logout',
       // Add all other legitimate paths here
   ];
   ```

### **Revised `commonVariables.php`:**

```php
<?php
    // Global constants (Using environment variables)
    define('SMTP_HOST', getenv('SMTP_HOST') ?: 'smtp.ionos.com');
    define('SMTP_USERNAME', getenv('SMTP_USER') ?: 'no-reply@trackback.email');
    define('SMTP_PASSWORD', getenv('SMTP_PASS') ?: '');
    define('SMTP_PORT', getenv('SMTP_PORT') ?: 587);

    // Set Timezone
    date_default_timezone_set(getenv('APP_TIMEZONE') ?: 'Asia/Calcutta');

    // Define BASE_URL
    define('BASE_URL', getenv('BASE_URL') ?: ($isLive ? 'https://trackback.email/' : 'https://valkya.lan/trackback.email/'));

    // Current Year
    $currentYear = date('Y');

    // Define allowed redirect paths
    $allowed_paths = [
        'dashboard',
        'my-account',
        'settings',
        'profile',
        'logout',
        // Add other allowed internal paths here
    ];
?>
```

### **Notes:**

- **Environment Variables:** Ensure that `BASE_URL` and `APP_TIMEZONE` are set appropriately in your environment configurations.
- **Redirection Security:** Regularly audit `allowed_paths` to ensure no unauthorized paths are included, which could be exploited for open redirects.

---

## **3. Review and Improve `commonFunctions.php`**

### **Current Configuration:**

```php
<?php
    use PHPMailer\PHPMailer\PHPMailer;
    use PHPMailer\PHPMailer\SMTP;
    use PHPMailer\PHPMailer\Exception;
    use DeviceDetector\ClientHints;
    use DeviceDetector\DeviceDetector;
    use DeviceDetector\Parser\Device\AbstractDeviceParser;

    /**
     * Generate a random string of a given length using openssl_random_pseudo_bytes
     *
     * @param int $length The length of the random string to generate (upto maximum 148 characters)
     * @return string The random string generated
     */
    function generateRandomString($length = 64) {
        $hash = openssl_random_pseudo_bytes(16, $crypto_strong);
        $randomizeHash = random_bytes(16) . $hash . uniqid() . microtime() . rand();
        $randomString = substr(str_shuffle(bin2hex($randomizeHash)), 0, $length);
        return $randomString;
    }

    /**
     * Encrypts a cookie value using a secure method.
     *
     * @param string $value The value to encrypt.
     * @return string Encrypted value.
     */
    function encryptCookie($value) {
        $key = hex2bin(openssl_random_pseudo_bytes(4));
        $cipher = &quot;aes-256-cbc&quot;;
        $ivlen = openssl_cipher_iv_length($cipher);
        $iv = openssl_random_pseudo_bytes($ivlen);
        $ciphertext = openssl_encrypt($value, $cipher, $key, 0, $iv);
        return(base64_encode($ciphertext . '::' . $iv. '::' .$key));
    }
    
    /**
     * Decrypts a cookie value using a secure method.
     *
     * @param string $value The value to decrypt.
     * @return string Decrypted value.
     */
    function decryptCookie($ciphertext) {
        $cipher = &quot;aes-256-cbc&quot;;
        list($encrypted_data, $iv, $key) = explode('::', base64_decode($ciphertext));
        return openssl_decrypt($encrypted_data, $cipher, $key, 0, $iv);
    }
    
    /**
     * Get real visitor IP behind CloudFlare network
     *
     * @return string IP address.
     */
    function getUserIP() {
        if (isset($_SERVER[&quot;HTTP_CF_CONNECTING_IP&quot;])) {
            $_SERVER['REMOTE_ADDR'] = $_SERVER[&quot;HTTP_CF_CONNECTING_IP&quot;];
            $_SERVER['HTTP_CLIENT_IP'] = $_SERVER[&quot;HTTP_CF_CONNECTING_IP&quot;];
        }
        $client  = @$_SERVER['HTTP_CLIENT_IP'];
        $forward = @$_SERVER['HTTP_X_FORWARDED_FOR'];
        $remote  = $_SERVER['REMOTE_ADDR'];
        if (filter_var($client, FILTER_VALIDATE_IP)) {
            $ip = $client;
        } elseif (filter_var($forward, FILTER_VALIDATE_IP)) {
            $ip = $forward;
        } else {
            $ip = $remote;
        }
        return $ip;
    }

    // Function to validate redirect paths
    function validate_redirect($path, $allowed_paths) {
        // Ensure the path does not contain leading or trailing slashes
        $clean_path = trim($path, '/');

        // Check if the path is in the allowed list
        return in_array($clean_path, $allowed_paths);
    }

    // Send notification emails from <PRESIDIO_ANONYMIZED_EMAIL_ADDRESS>
    function sendEmailNoReply($toEmail, $toName, $subject, $body, $altBody = '', $cc = [], $bcc = [], $attachments = []) {
        //Create an instance; passing true enables exceptions
        $mail = new PHPMailer(true);

        try {
            //Server settings
            //SMTP::DEBUG_OFF = off (for production use)
            //SMTP::DEBUG_CLIENT = client messages
            //SMTP::DEBUG_SERVER = client and server messages
            $mail->SMTPDebug = SMTP::DEBUG_OFF;
            $mail->isSMTP();
            $mail->Host       = SMTP_HOST;
            $mail->SMTPAuth   = true;
            $mail->Username   = SMTP_USERNAME;
            $mail->Password   = SMTP_PASSWORD;
            $mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;
            $mail->Port       = SMTP_PORT;
            //Extra headers
            $mail->Encoding   = 'base64';
            $mail->XMailer    = 'TrackBack.email 1.0.0-alpha (https://trackback.email)';

            //Sender
            $mail->setFrom('no-reply@trackback.email', 'TrackBack.email');
            //Recipients
            $mail->addAddress($toEmail, $toName);

            //Content
            $mail->isHTML(true);
            $mail->Subject = $subject;
            $mail->Body    = $body;

            if (!empty($altBody)) {
                $mail->AltBody = $altBody; // For non-HTML email clients
            }

            // Add CC recipients
            if (!empty($cc)) {
                foreach ($cc as $ccEmail) {
                    $mail->addCC($ccEmail);
                }
            }

            // Add BCC recipients
            if (!empty($bcc)) {
                foreach ($bcc as $bccEmail) {
                    $mail->addBCC($bccEmail);
                }
            }

            // Add attachments
            if (!empty($attachments)) {
                foreach ($attachments as $filePath) {
                    $mail->addAttachment($filePath);
                }
            }

            $mail->send();
            return true;
        } catch (Exception $e) {
            // Handle exceptions (you can log the error message if needed)
            error_log(&quot;Mailer Error: &quot; . $mail->ErrorInfo);
            return false;
        }
    }
?>
```

### **Issues Identified:**

1. **Random Key Generation in `encryptCookie`:**
   - **Problem:** Each encryption operation generates a new random key and includes it in the encrypted string. This defeats the purpose of encryption as anyone with access to the encrypted value can decrypt it.
   
2. **Inefficient `generateRandomString`:**
   - **Problem:** The function uses multiple sources of randomness (`openssl_random_pseudo_bytes`, `random_bytes`, `uniqid`, `microtime`, `rand`, `str_shuffle`), which is unnecessary and inefficient.
   
3. **Weak Encryption Practices:**
   - **Problem:** Without a consistent encryption key, decryption becomes unreliable and insecure.
   
4. **Error Suppression in `getUserIP`:**
   - **Problem:** Using `@` to suppress errors can hide issues that should be addressed.
   
5. **Lack of Input Validation in `validate_redirect`:**
   - **Problem:** While `validate_redirect` checks against an allowed list, further validation or sanitization could be beneficial.

### **Recommendations:**

1. **Secure Cookie Encryption:**
   - **Use a Fixed Server-Side Encryption Key:**
     - **Reason:** To ensure that encrypted cookies can be decrypted reliably.
     - **Implementation:**
       - Store the encryption key securely (e.g., in environment variables).
       - Use authenticated encryption (e.g., AES-256-GCM) to ensure data integrity.

     **Revised `encryptCookie` and `decryptCookie`:**
     ```php
     /**
      * Encrypts a cookie value using a secure method.
      *
      * @param string $value The value to encrypt.
      * @return string Encrypted value.
      */
     function encryptCookie($value) {
         $key = hex2bin(getenv('COOKIE_ENCRYPTION_KEY')); // Ensure this key is securely stored
         $cipher = &quot;aes-256-gcm&quot;;
         $ivlen = openssl_cipher_iv_length($cipher);
         $iv = openssl_random_pseudo_bytes($ivlen);
         $tag = '';
         $ciphertext = openssl_encrypt($value, $cipher, $key, OPENSSL_RAW_DATA, $iv, $tag);
         return base64_encode($iv . '::' . $tag . '::' . $ciphertext);
     }
     
     /**
      * Decrypts a cookie value using a secure method.
      *
      * @param string $ciphertext The encrypted value to decrypt.
      * @return string|false Decrypted value or false on failure.
      */
     function decryptCookie($ciphertext) {
         $key = hex2bin(getenv('COOKIE_ENCRYPTION_KEY'));
         $cipher = &quot;aes-256-gcm&quot;;
         list($iv, $tag, $ciphertext) = explode('::', base64_decode($ciphertext), 3);
         return openssl_decrypt($ciphertext, $cipher, $key, OPENSSL_RAW_DATA, $iv, $tag);
     }
     ```
   - **Generate and Set the Encryption Key Securely:**
     - Use a 256-bit key for AES-256-GCM.
     - Example:
       ```bash
       # Generate a secure key
       openssl rand -hex 32
       ```
     - **Set the Key as an Environment Variable:**
       - Add it to your server's environment variables, not in code.
       - Example in `.env` file (if using dotenv):
         ```
         COOKIE_ENCRYPTION_KEY=your_generated_key_here
         ```
   
2. **Simplify `generateRandomString`:**
   - **Use `bin2hex(random_bytes())`:**
     - **Reason:** `random_bytes()` provides cryptographically secure randomness, and `bin2hex()` converts it to a readable format.
   
   **Revised `generateRandomString`:**
   ```php
   /**
    * Generate a secure random string of a given length.
    *
    * @param int $length The length of the random string.
    * @return string The random string generated.
    */
   function generateRandomString($length = 64) {
       $bytes = ceil($length / 2);
       return substr(bin2hex(random_bytes($bytes)), 0, $length);
   }
   ```
   
3. **Remove Error Suppression in `getUserIP`:**
   - **Reason:** Suppressing errors can hide underlying issues.
   
   **Revised `getUserIP`:**
   ```php
   /**
    * Get the real visitor IP behind CloudFlare or other proxies.
    *
    * @return string IP address.
    */
   function getUserIP() {
       if (isset($_SERVER[&quot;HTTP_CF_CONNECTING_IP&quot;])) {
           $_SERVER['REMOTE_ADDR'] = $_SERVER[&quot;HTTP_CF_CONNECTING_IP&quot;];
           $_SERVER['HTTP_CLIENT_IP'] = $_SERVER[&quot;HTTP_CF_CONNECTING_IP&quot;];
       }
       $client  = $_SERVER['HTTP_CLIENT_IP'] ?? null;
       $forward = $_SERVER['HTTP_X_FORWARDED_FOR'] ?? null;
       $remote  = $_SERVER['REMOTE_ADDR'] ?? '';

       if (filter_var($client, FILTER_VALIDATE_IP)) {
           return $client;
       } elseif (filter_var($forward, FILTER_VALIDATE_IP)) {
           return $forward;
       }
       return $remote;
   }
   ```
   
4. **Enhance `validate_redirect`:**
   - **Use Strict Comparison:**
     ```php
     function validate_redirect($path, $allowed_paths) {
         // Ensure the path does not contain leading or trailing slashes
         $clean_path = trim($path, '/');

         // Check if the path is in the allowed list using strict comparison
         return in_array($clean_path, $allowed_paths, TRUE);
     }
     ```
   
5. **Improve `sendEmailNoReply`:**
   - **Parameter Sanitization:**
     - Sanitize email inputs to prevent injection or malformed emails.
   - **Handle Attachments Securely:**
     - Validate file paths and ensure only intended files are attached.
   
   **Example Enhancements:**
   ```php
   function sendEmailNoReply($toEmail, $toName, $subject, $body, $altBody = '', $cc = [], $bcc = [], $attachments = []) {
       // Validate email
       if (!filter_var($toEmail, FILTER_VALIDATE_EMAIL)) {
           error_log(&quot;Invalid email address: $toEmail&quot;);
           return false;
       }

       //Create an instance; passing true enables exceptions
       $mail = new PHPMailer(true);

       try {
           //Server settings
           $mail->SMTPDebug = SMTP::DEBUG_OFF;
           $mail->isSMTP();
           $mail->Host       = SMTP_HOST;
           $mail->SMTPAuth   = true;
           $mail->Username   = SMTP_USERNAME;
           $mail->Password   = SMTP_PASSWORD;
           $mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;
           $mail->Port       = SMTP_PORT;

           //Extra headers
           $mail->Encoding   = 'base64';
           $mail->XMailer    = 'TrackBack.email 1.0.0 (https://trackback.email)';

           //Sender
           $mail->setFrom('no-reply@trackback.email', 'TrackBack.email');
           //Recipients
           $mail->addAddress($toEmail, $toName);

           //Content
           $mail->isHTML(true);
           $mail->Subject = $subject;
           $mail->Body    = $body;

           if (!empty($altBody)) {
               $mail->AltBody = $altBody; // For non-HTML email clients
           }

           // Add CC recipients
           foreach ($cc as $ccEmail) {
               if (filter_var($ccEmail, FILTER_VALIDATE_EMAIL)) {
                   $mail->addCC($ccEmail);
               } else {
                   error_log(&quot;Invalid CC email address: $ccEmail&quot;);
               }
           }

           // Add BCC recipients
           foreach ($bcc as $bccEmail) {
               if (filter_var($bccEmail, FILTER_VALIDATE_EMAIL)) {
                   $mail->addBCC($bccEmail);
               } else {
                   error_log(&quot;Invalid BCC email address: $bccEmail&quot;);
               }
           }

           // Add attachments securely
           foreach ($attachments as $filePath) {
               if (file_exists($filePath) &amp;&amp; is_readable($filePath)) {
                   $mail->addAttachment($filePath);
               } else {
                   error_log(&quot;Attachment not found or unreadable: $filePath&quot;);
               }
           }

           $mail->send();
           return true;
       } catch (Exception $e) {
           // Handle exceptions (you can log the error message if needed)
           error_log(&quot;Mailer Error: &quot; . $mail->ErrorInfo);
           return false;
       }
   }
   ```

### **Revised `commonFunctions.php`:**

```php
<?php
    use PHPMailer\PHPMailer\PHPMailer;
    use PHPMailer\PHPMailer\SMTP;
    use PHPMailer\PHPMailer\Exception;
    use DeviceDetector\ClientHints;
    use DeviceDetector\DeviceDetector;
    use DeviceDetector\Parser\Device\AbstractDeviceParser;

    /**
     * Generate a secure random string of a specified length.
     *
     * @param int $length The length of the random string.
     * @return string The generated random string.
     */
    function generateRandomString($length = 64) {
        $bytes = ceil($length / 2);
        return substr(bin2hex(random_bytes($bytes)), 0, $length);
    }

    /**
     * Encrypts a cookie value using AES-256-GCM.
     *
     * @param string $value The value to encrypt.
     * @return string|false Encrypted value or false on failure.
     */
    function encryptCookie($value) {
        $key = hex2bin(getenv('COOKIE_ENCRYPTION_KEY')); // Securely store in environment
        $cipher = &quot;aes-256-gcm&quot;;
        $ivlen = openssl_cipher_iv_length($cipher);
        $iv = openssl_random_pseudo_bytes($ivlen);
        $tag = '';
        $ciphertext = openssl_encrypt($value, $cipher, $key, OPENSSL_RAW_DATA, $iv, $tag);
        if ($ciphertext === FALSE) {
            return false;
        }
        return base64_encode($iv . '::' . $tag . '::' . $ciphertext);
    }
    
    /**
     * Decrypts a cookie value using AES-256-GCM.
     *
     * @param string $ciphertext The encrypted value to decrypt.
     * @return string|false Decrypted value or false on failure.
     */
    function decryptCookie($ciphertext) {
        $key = hex2bin(getenv('COOKIE_ENCRYPTION_KEY'));
        $cipher = &quot;aes-256-gcm&quot;;
        $decoded = base64_decode($ciphertext);
        if ($decoded === FALSE) {
            return false;
        }
        list($iv, $tag, $ciphertext) = explode('::', $decoded, 3);
        return openssl_decrypt($ciphertext, $cipher, $key, OPENSSL_RAW_DATA, $iv, $tag);
    }
    
    /**
     * Get the real visitor IP behind CloudFlare or other proxies.
     *
     * @return string IP address.
     */
    function getUserIP() {
        if (isset($_SERVER[&quot;HTTP_CF_CONNECTING_IP&quot;])) {
            $_SERVER['REMOTE_ADDR'] = $_SERVER[&quot;HTTP_CF_CONNECTING_IP&quot;];
            $_SERVER['HTTP_CLIENT_IP'] = $_SERVER[&quot;HTTP_CF_CONNECTING_IP&quot;];
        }
        $client  = $_SERVER['HTTP_CLIENT_IP'] ?? null;
        $forward = $_SERVER['HTTP_X_FORWARDED_FOR'] ?? null;
        $remote  = $_SERVER['REMOTE_ADDR'] ?? '';

        if (filter_var($client, FILTER_VALIDATE_IP)) {
            return $client;
        } elseif (filter_var($forward, FILTER_VALIDATE_IP)) {
            // In case of multiple IPs, take the first valid one
            $ipList = explode(',', $forward);
            foreach ($ipList as $ip) {
                $ip = trim($ip);
                if (filter_var($ip, FILTER_VALIDATE_IP)) {
                    return $ip;
                }
            }
        }
        return $remote;
    }

    /**
     * Validate if the redirect path is allowed.
     *
     * @param string $path The path to validate.
     * @param array $allowed_paths The list of allowed paths.
     * @return bool True if allowed, false otherwise.
     */
    function validate_redirect($path, $allowed_paths) {
        // Ensure the path does not contain leading or trailing slashes
        $clean_path = trim($path, '/');

        // Check if the path is in the allowed list using strict comparison
        return in_array($clean_path, $allowed_paths, true);
    }

    /**
     * Send notification emails from <PRESIDIO_ANONYMIZED_EMAIL_ADDRESS>.
     *
     * @param string $toEmail Recipient's email address.
     * @param string $toName Recipient's name.
     * @param string $subject Email subject.
     * @param string $body HTML body of the email.
     * @param string $altBody Plain text alternative body.
     * @param array $cc Array of CC email addresses.
     * @param array $bcc Array of BCC email addresses.
     * @param array $attachments Array of file paths to attach.
     * @return bool True if sent successfully, false otherwise.
     */
    function sendEmailNoReply($toEmail, $toName, $subject, $body, $altBody = '', $cc = [], $bcc = [], $attachments = []) {
        // Validate email address
        if (!filter_var($toEmail, FILTER_VALIDATE_EMAIL)) {
            error_log(&quot;Invalid recipient email address: $toEmail&quot;);
            return false;
        }

        //Create an instance; passing true enables exceptions
        $mail = new PHPMailer(true);

        try {
            //Server settings
            $mail->SMTPDebug = SMTP::DEBUG_OFF; // Disable verbose debug output
            $mail->isSMTP();
            $mail->Host       = SMTP_HOST;
            $mail->SMTPAuth   = true;
            $mail->Username   = SMTP_USERNAME;
            $mail->Password   = SMTP_PASSWORD;
            $mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;
            $mail->Port       = SMTP_PORT;

            //Extra headers
            $mail->Encoding   = 'base64';
            $mail->XMailer    = 'TrackBack.email 1.0.0 (https://trackback.email)';

            //Sender
            $mail->setFrom('no-reply@trackback.email', 'TrackBack.email');
            //Recipients
            $mail->addAddress($toEmail, $toName);

            //Content
            $mail->isHTML(true);
            $mail->Subject = htmlspecialchars($subject, ENT_QUOTES, 'UTF-8');
            $mail->Body    = $body;

            if (!empty($altBody)) {
                $mail->AltBody = $altBody; // For non-HTML email clients
            }

            // Add CC recipients
            foreach ($cc as $ccEmail) {
                if (filter_var($ccEmail, FILTER_VALIDATE_EMAIL)) {
                    $mail->addCC($ccEmail);
                } else {
                    error_log(&quot;Invalid CC email address: $ccEmail&quot;);
                }
            }

            // Add BCC recipients
            foreach ($bcc as $bccEmail) {
                if (filter_var($bccEmail, FILTER_VALIDATE_EMAIL)) {
                    $mail->addBCC($bccEmail);
                } else {
                    error_log(&quot;Invalid BCC email address: $bccEmail&quot;);
                }
            }

            // Add attachments securely
            foreach ($attachments as $filePath) {
                if (file_exists($filePath) &amp;&amp; is_readable($filePath)) {
                    $mail->addAttachment($filePath);
                } else {
                    error_log(&quot;Attachment not found or unreadable: $filePath&quot;);
                }
            }

            $mail->send();
            return true;
        } catch (Exception $e) {
            // Log the detailed error for debugging
            error_log(&quot;Mailer Error: &quot; . $mail->ErrorInfo);
            return false;
        }
    }
?>
```

### **Key Enhancements:**

1. **Secure Encryption:**
   - **Fixed Encryption Key:** Replace dynamic key generation with a fixed server-side key stored securely via environment variables.
   - **Authenticated Encryption:** Use AES-256-GCM for authenticated encryption, ensuring data integrity.
   
2. **Simplified Random String Generation:**
   - **Use `random_bytes` and `bin2hex`:** Provides sufficient randomness securely and efficiently.

3. **Improved `getUserIP`:**
   - **Removed Error Suppression:** Avoid using `@` to ensure that any unexpected issues are logged and addressed.
   - **Multiple IP Handling:** Properly handles scenarios with multiple forwarded IPs.

4. **Strict Path Validation:**
   - **Use Strict Comparison in `validate_redirect`:** Prevents false positives by ensuring type-safe comparisons.

5. **Enhanced Email Sending:**
   - **Email Validation:** Validate all email addresses before attempting to send.
   - **Securely Handle Attachments:** Ensure that files exist and are readable before attaching.
   - **Sanitize Email Content:** Prevent potential XSS by sanitizing subject and optionally the body.
   - **Error Logging:** Log errors instead of exposing them to users.
   
6. **Use of Environment Variables:**
   - **SMTP Credentials and Encryption Keys:** Retrieve these from environment variables to avoid hard-coding sensitive information.

### **Notes:**

- **Environment Variables:** Use tools like [vlucas/phpdotenv](https://github.com/vlucas/phpdotenv) to manage environment variables systematically.
- **Logging:** Ensure that all critical errors are logged for monitoring and debugging purposes.

---

## **4. Step-by-Step Guide to Enhance Your Login Code**

Given the comprehensive review of your included files, let's proceed to systematically improve your main login script based on best practices, security enhancements, and maintainability improvements.

### **Current Main Login Script:**

```php
<?php
    // All includes and setup
    use PHPMailer\PHPMailer\PHPMailer;
    use PHPMailer\PHPMailer\SMTP;
    use PHPMailer\PHPMailer\Exception;
    use DeviceDetector\ClientHints;
    use DeviceDetector\DeviceDetector;
    use DeviceDetector\Parser\Device\AbstractDeviceParser;

    include 'includes/config.php';
    include 'includes/commonVariables.php';
    include 'includes/commonFunctions.php';
    require 'vendor/autoload.php';

    // Initialize the session
    session_start();

    // If the user is already logged in, redirect them appropriately
    if (isset($_SESSION[&quot;loggedin&quot;]) &amp;&amp; $_SESSION[&quot;loggedin&quot;] === true) {
        // Determine where to redirect the user
        if (isset($_SESSION['redirect']) &amp;&amp; !empty($_SESSION['redirect']) &amp;&amp; validate_redirect($_SESSION['redirect'], $allowed_paths)) {
            $location = $_SESSION['redirect'];
            // Clear the redirect session variable to prevent reuse
            unset($_SESSION['redirect']);
        } else {
            $location = 'dashboard';
        }

        // Redirect using BASE_URL and $location
        header('Location: ' . BASE_URL . $location); // No double slashes
        exit;
    }

    // Initialize variables
    $location = 'dashboard'; // Default location

    // Determine the redirection location after login
    if (isset($_SESSION['redirect']) &amp;&amp; !empty($_SESSION['redirect']) &amp;&amp; validate_redirect($_SESSION['redirect'], $allowed_paths)) {
        $location = $_SESSION['redirect'];
    }

    // CSRF token generation and session check
    if (!isset($_SESSION[&quot;csrf_token&quot;]) || empty($_SESSION['csrf_token'])) {
        $csrf_token = generateRandomString(32);
        $_SESSION[&quot;csrf_token&quot;] = $csrf_token;
    } else {
        $csrf_token = $_SESSION['csrf_token'];
    }

    // Check if the user is already logged in, if yes then redirect to dashboard page
    if (isset($_SESSION[&quot;loggedin&quot;]) &amp;&amp; $_SESSION[&quot;loggedin&quot;] === true) {
        header('location:' . BASE_URL . $location);
        exit;
    } elseif (isset($_COOKIE['rememberme'])) {
        // Decrypt cookie value
        $token = decryptCookie($_COOKIE['rememberme']);
        
        $sql_query = &quot;SELECT `uid`, `email`, `token` FROM `users` WHERE `token` = ?&quot;;
        if ($stmt = mysqli_prepare($conn, $sql_query)) {
            mysqli_stmt_bind_param($stmt, &quot;s&quot;, $token);
            if (mysqli_stmt_execute($stmt)) {
                mysqli_stmt_bind_result($stmt, $uid, $email, $db_token);
                mysqli_stmt_fetch($stmt);
                if ($db_token === $token) {
                    $_SESSION[&quot;uid&quot;] = $uid;
                    $_SESSION[&quot;email&quot;] = $email;
                    $_SESSION[&quot;token&quot;] = $token;
                    $_SESSION[&quot;loggedin&quot;] = true; // Set the logged-in flag
                    header('Location: ' . BASE_URL . $location);
                    exit;
                }
            }
            mysqli_stmt_close($stmt);
        }
    }

    // Define variables and initialize with empty values
    $email = $password = &quot;&quot;;
    $email_err = $password_err = $errorMSG = &quot;&quot;;

    // Processing form data when form is submitted
    if ($_SERVER[&quot;REQUEST_METHOD&quot;] == &quot;POST&quot;) {
        // Validate CSRF token
        if (!isset($_POST['csrf_token']) || empty($_POST['csrf_token']) || $_POST['csrf_token'] !== $_SESSION['csrf_token']) {
            $errorMSG = &quot;Invalid CSRF token. Please try again.&quot;;
        } else {

            // Check if email is empty
            if (empty(trim($_POST[&quot;email&quot;]))) {
                $email_err = &quot;Please enter your email.&quot;;
            } else {
                $email = trim($_POST[&quot;email&quot;]);
            }

            // Check if password is empty
            if (empty(trim($_POST[&quot;password&quot;]))) {
                $password_err = &quot;Please enter your password.&quot;;
            } else {
                $password = trim($_POST[&quot;password&quot;]);
            }

            // Validate credentials
            if (empty($email_err) &amp;&amp; empty($password_err)) {
                $sql = &quot;SELECT `uid`, `email`, `password`, `active`, `token` FROM `users` WHERE `email` = ?&quot;;
                if ($stmt = mysqli_prepare($conn, $sql)) {
                    mysqli_stmt_bind_param($stmt, &quot;s&quot;, $email);
                    if (mysqli_stmt_execute($stmt)) {
                        mysqli_stmt_store_result($stmt);
                        if (mysqli_stmt_num_rows($stmt) === 1) {
                            mysqli_stmt_bind_result($stmt, $uid, $db_email, $hashed_password, $isActive, $token);
                            if (mysqli_stmt_fetch($stmt)) {
                                if (password_verify($password, $hashed_password)) {
                                    if ($isActive === 1) {
                                        // Start session and set session variables
                                        session_regenerate_id();  // Prevent session fixation attacks
                                        $_SESSION[&quot;loggedin&quot;] = true;
                                        $_SESSION[&quot;uid&quot;] = $uid;
                                        $_SESSION[&quot;email&quot;] = $db_email;
                                        $_SESSION[&quot;token&quot;] = $token;

                                        // Fetch the previous last_login and last_login_ip details
                                        $sql_fetch = &quot;SELECT `first_name`, `last_name`, `last_login`, `last_login_ip` FROM `users` WHERE `uid` = ?&quot;;
                                        if ($stmt_fetch = mysqli_prepare($conn, $sql_fetch)) {
                                            mysqli_stmt_bind_param($stmt_fetch, &quot;i&quot;, $uid); // Assuming $uid is already available
                                            mysqli_stmt_execute($stmt_fetch);
                                            mysqli_stmt_bind_result($stmt_fetch, $first_name, $last_name, $prev_last_login, $prev_last_login_ip);
                                            mysqli_stmt_fetch($stmt_fetch);
                                            mysqli_stmt_close($stmt_fetch);

                                            // Store the previous login details in session variables
                                            $_SESSION[&quot;prev_last_login&quot;] = $prev_last_login;
                                            $_SESSION[&quot;prev_last_login_ip&quot;] = $prev_last_login_ip;

                                            $fullName = $first_name . &quot; &quot; . $last_name;
                                        }

                                        // Check if &quot;remember me&quot; was selected
                                        if (isset($_POST[&quot;rememberme&quot;])) {
                                            $_SESSION[&quot;rememberme&quot;] = true;
                                            // Generate and store token as before
                                            $encryptedToken = encryptCookie($_SESSION[&quot;token&quot;]);
                                        
                                            // Extract the domain from BASE_URL
                                            $url_parts = parse_url(BASE_URL);
                                            $domain = $url_parts['host'];
                                        
                                            // Set the rememberme cookie using array syntax
                                            setcookie('rememberme', $encryptedToken, [
                                                'expires' => time() + (86400 * 30), // 30 days
                                                'path' => '/',
                                                'domain' => $domain, // Correctly set the domain
                                                'secure' => true,     // Only send cookie over HTTPS
                                                'httponly' => true,   // Accessible only through the HTTP protocol
                                                'samesite' => 'Strict' // Adjust as needed (None, Lax, Strict)
                                            ]);
                                        } else {
                                            $_SESSION[&quot;rememberme&quot;] = false;
                                            // Optionally, delete the rememberme cookie
                                            $url_parts = parse_url(BASE_URL);
                                            $domain = $url_parts['host'];
                                        
                                            setcookie('rememberme', '', [
                                                'expires' => time() - 3600, // Set time in the past to delete
                                                'path' => '/',
                                                'domain' => $domain,        // Correctly set the domain
                                                'secure' => true,
                                                'httponly' => true,
                                                'samesite' => 'Strict'
                                            ]);
                                        }

                                        // Update `last_login` and `last_login_ip` in `users` table
                                        $last_login = date('Y-m-d H:i:s');
                                        $last_login_ip = getUserIP();
                                        $sql_update = &quot;UPDATE `users` SET `last_login` = ?, `last_login_ip` = ? WHERE `uid` = ?&quot;;
                                        if ($stmt_update = mysqli_prepare($conn, $sql_update)) {
                                            mysqli_stmt_bind_param($stmt_update, &quot;sss&quot;, $last_login, $last_login_ip, $uid);
                                            mysqli_stmt_execute($stmt_update);
                                            mysqli_stmt_close($stmt_update);
                                        }

                                        $queryNotification = &quot;SELECT notification_pref_security FROM user_profile WHERE uid = ?&quot;;
                                        $stmtNotification = mysqli_prepare($conn, $queryNotification);
                                        mysqli_stmt_bind_param($stmtNotification, 'i', $_SESSION[&quot;uid&quot;]);
                                        mysqli_stmt_execute($stmtNotification);
                                        mysqli_stmt_store_result($stmtNotification);

                                        if (mysqli_stmt_num_rows($stmtNotification) > 0) {
                                            mysqli_stmt_bind_result($stmtNotification, $notif_security);
                                            mysqli_stmt_fetch($stmtNotification);
                                        } else {
                                            $notif_security = 1;
                                        }

                                        mysqli_stmt_close($stmtNotification);

                                        if ($notif_security === 1 &amp;&amp; $_SESSION[&quot;prev_last_login_ip&quot;] != $last_login_ip) {
                                            $last_login_datetime = date('M d, Y, h:i A', strtotime($last_login));

                                            AbstractDeviceParser::setVersionTruncation(AbstractDeviceParser::VERSION_TRUNCATION_NONE);
                                            $userAgent = $_SERVER['HTTP_USER_AGENT']; // change this to the useragent you want to parse
                                            $clientHints = ClientHints::factory($_SERVER); // client hints are optional
                                            $dd = new DeviceDetector($userAgent, $clientHints);
                                            $dd->parse();

                                            if ($dd->isBot()) {
                                                // handle bots,spiders,crawlers,...
                                                $botInfo = $dd->getBot();
                                            } else {
                                                $clientInfo = $dd->getClient(); // holds information about browser, feed reader, media player, ...
                                                $osInfo = $dd->getOs();
                                                $device = $dd->getDeviceName();
                                                $brand = $dd->getBrandName();
                                                $model = $dd->getModel();
                                            }

                                            $ipBase = new \Ipbase\Ipbase\IpbaseClient('ipb_live_BSBfuKApOLL6vkZ1SJCzP8oWbygM1ncMUzBd6iVd');
                                            $ipBaseData = $ipBase->info();

                                            //$ipBaseData = json_decode($ipBaseDataJSON, true);
                                            $ipBaseDataLocation = $ipBaseData['data']['location'];
                                            $city = $ipBaseDataLocation['city']['name'];
                                            $region = $ipBaseDataLocation['region']['name'];
                                            $country = $ipBaseDataLocation['country']['name'];

                                            $location_string = &quot;$city, $region, $country&quot;;
                                            
                                            $emailBody = file_get_contents('templates/newLoginEmailTemplate.html');
                                            $toReplace = ['::BASEURL::', '::FULLNAME::', '::CURRENTYEAR::', '::DEVICE::', '::CLIENT::', '::OS::', '::LOCATION::', '::DATETIME::'];
                                            $withThis = [BASE_URL, $fullName, $currentYear, ucfirst($device), $clientInfo['name'], $osInfo['name'], $location_string, $last_login_datetime];
                                            $emailBody = str_replace($toReplace, $withThis, $emailBody);

                                            // Prepare email variables
                                            $toEmail = $email; // Recipient's email address
                                            $toName = $fullName; // Recipient's full name
                                            $subject = 'New Device Login Alert for Your TrackBack.email Account';
                                            $body = $emailBody; // Your HTML email body

                                            // Send the email
                                            if (sendEmailNoReply($toEmail, $toName, $subject, $body)) {
                                                $msg = &quot;Successfully logged in!&quot;;
                                            } else {
                                                $errorMSG = &quot;New Login detected email could not be sent.<br>Kindly contact us for further assistance.&quot;;
                                            }
                                        }

                                        unset($_SESSION['csrf_token']); // Unset session token after submitting
                                        header('location:' . BASE_URL . $location);
                                    } else {
                                        // Account is not activated
                                        $errorMSG = &quot;Your account is not activated yet.<br>Please check your inbox for activation email.&quot;;
                                    }
                                } else {
                                    // Password is incorrect
                                    $errorMSG = &quot;Invalid email or password.&quot;;
                                }
                            }
                        } else {
                            // Email doesn't exist
                            $errorMSG = &quot;Invalid email or password.&quot;;
                        }
                    } else {
                        $errorMSG = &quot;Oops! Something went wrong. Please try again later.&quot;;
                    }
                    mysqli_stmt_close($stmt);
                }
            }
        }
        mysqli_close($conn);
    }

    include 'includes/start.php';
?>
```

### **Issues Identified:**

1. **Redundant Session Checks:**
   - **Problem:** The script checks if the user is logged in twice (`isset($_SESSION[&quot;loggedin&quot;]) &amp;&amp; $_SESSION[&quot;loggedin&quot;] === true`). This redundancy complicates the logic.
   
2. **Insecure 'Remember Me' Implementation:**
   - **Problem:** The `decryptCookie` function uses dynamic keys per encryption, making token reuse vulnerable.
   
3. **CSRF Token Handling:**
   - **Problem:** CSRF tokens are not regenerated after form submission, potentially allowing replay attacks.
   
4. **Password Verification and Session Management:**
   - **Problem:** Missing robust error handling during authentication and session fixation prevention measures.
   
5. **Incomplete 'Remember Me' Security:**
   - **Problem:** Tokens are not rotated or invalidated upon usage, increasing the risk of replay attacks.
   
6. **Error Handling and Logging:**
   - **Problem:** Errors during database operations are not logged, making debugging difficult.
   
7. **Email Sending Security:**
   - **Problem:** Emails are sent without validation or ensuring attachment security, increasing risks of injection or file manipulation.
   
8. **Potential XSS Vulnerabilities:**
   - **Problem:** User inputs like `$fullName` are directly used in emails without proper sanitization.
   
9. **External API Key Exposure:**
   - **Problem:** API keys (e.g., `IpbaseClient` key) are hard-coded, which is a security risk.

### **Step-by-Step Enhancements:**

#### **Step 1: Consolidate Session Checks**

**Issue:**
Multiple checks for `$_SESSION[&quot;loggedin&quot;]` cause redundancy.

**Solution:**
Create helper functions to manage session checks and redirections.

**Implementation:**

1. **Define Helper Functions in `commonFunctions.php`:**

    ```php
    /**
     * Check if the user is logged in.
     *
     * @return bool True if logged in, false otherwise.
     */
    function isUserLoggedIn() {
        return isset($_SESSION[&quot;loggedin&quot;]) &amp;&amp; $_SESSION[&quot;loggedin&quot;] === true;
    }

    /**
     * Get the redirect location.
     *
     * @global array $allowed_paths
     * @return string The redirect path.
     */
    function getRedirectLocation() {
        global $allowed_paths;
        if (isset($_SESSION['redirect']) &amp;&amp; !empty($_SESSION['redirect']) &amp;&amp; validate_redirect($_SESSION['redirect'], $allowed_paths)) {
            $location = $_SESSION['redirect'];
            unset($_SESSION['redirect']);
        } else {
            $location = 'dashboard';
        }
        return $location;
    }

    /**
     * Redirect the user to a specified location.
     *
     * @param string $location The location to redirect to.
     */
    function redirectTo($location) {
        // Prevent header injection
        $location = str_replace(array(&quot;\r&quot;, &quot;\n&quot;), '', $location);
        header('Location: ' . BASE_URL . $location);
        exit;
    }
    ```

2. **Use Helper Functions in Main Script:**

    ```php
    // If the user is already logged in, redirect them appropriately
    if (isUserLoggedIn()) {
        $location = getRedirectLocation();
        redirectTo($location);
    }
    ```

3. **Remove Redundant Checks:**
   - Delete the second login check to avoid duplication.

#### **Step 2: Secure 'Remember Me' Implementation**

**Issue:**
Currently, the 'remember me' token uses dynamic encryption keys and lacks proper token management.

**Solution:**
Implement a secure token-based 'remember me' system with hashed tokens, token rotation, and proper session management.

**Implementation:**

1. **Modify Token Storage:**
   - **Store Hashed Tokens:** Store a hashed version of the token in the database to prevent token exposure.
   - **Associate Tokens with Users and Devices:** Optionally, add fields like `device_name`, `expires_at`, etc., for enhanced security.

    **Database Schema Adjustment:**
    ```sql
    ALTER TABLE `users` ADD COLUMN `remember_token_hash` VARCHAR(64) NULL AFTER `token`;
    ALTER TABLE `users` ADD COLUMN `remember_token_expires` DATETIME NULL AFTER `remember_token_hash`;
    ```

2. **Generate and Store 'Remember Me' Token:**
   - **Generate Token:** Use secure random bytes.
   - **Hash Token:** Use a secure hashing algorithm.
   - **Store Hash and Expiration in Database.**

    **Implementation:**
    ```php
    if (isset($_POST[&quot;rememberme&quot;])) {
        // Generate secure token
        $token = generateRandomString(64);
        $hashed_token = hash('sha256', $token);
        $expires_at = date('Y-m-d H:i:s', strtotime('+30 days'));

        // Update token in database
        $sql_update_token = &quot;UPDATE `users` SET `remember_token_hash` = ?, `remember_token_expires` = ? WHERE `uid` = ?&quot;;
        if ($stmt_update = mysqli_prepare($conn, $sql_update_token)) {
            mysqli_stmt_bind_param($stmt_update, &quot;ssi&quot;, $hashed_token, $expires_at, $uid);
            mysqli_stmt_execute($stmt_update);
            mysqli_stmt_close($stmt_update);
        }

        // Encrypt token before setting cookie
        $encryptedToken = encryptCookie($token);

        // Set the 'rememberme' cookie
        $url_parts = parse_url(BASE_URL);
        $domain = $url_parts['host'];

        setcookie('rememberme', $encryptedToken, [
            'expires' => time() + (86400 * 30), // 30 days
            'path' => '/',
            'domain' => $domain,
            'secure' => true,     // Only send cookie over HTTPS
            'httponly' => true,   // Accessible only through the HTTP protocol
            'samesite' => 'Strict' // Adjust as needed (None, Lax, Strict)
        ]);
    } else {
        // Delete the 'rememberme' cookie and remove token from database
        if (isset($_COOKIE['rememberme'])) {
            // Get user ID from session or other means
            $uid = $_SESSION[&quot;uid&quot;] ?? null;
            if ($uid) {
                $sql_clear_token = &quot;UPDATE `users` SET `remember_token_hash` = NULL, `remember_token_expires` = NULL WHERE `uid` = ?&quot;;
                if ($stmt_clear = mysqli_prepare($conn, $sql_clear_token)) {
                    mysqli_stmt_bind_param($stmt_clear, &quot;i&quot;, $uid);
                    mysqli_stmt_execute($stmt_clear);
                    mysqli_stmt_close($stmt_clear);
                }
            }

            // Delete the cookie
            $url_parts = parse_url(BASE_URL);
            $domain = $url_parts['host'];

            setcookie('rememberme', '', [
                'expires' => time() - 3600, // Past time to delete
                'path' => '/',
                'domain' => $domain,
                'secure' => true,
                'httponly' => true,
                'samesite' => 'Strict'
            ]);
        }
    }
    ```

3. **Handle 'Remember Me' Auto-Login Securely:**

    **Implementation:**
    ```php
    // Handle 'remember me' auto-login
    if (isset($_COOKIE['rememberme'])) {
        $token = decryptCookie($_COOKIE['rememberme']);
        if ($token) {
            $hashed_token = hash('sha256', $token);
            $sql_query = &quot;SELECT `uid`, `email`, `remember_token_hash`, `remember_token_expires` FROM `users` WHERE `remember_token_hash` = ?&quot;;
            if ($stmt = mysqli_prepare($conn, $sql_query)) {
                mysqli_stmt_bind_param($stmt, &quot;s&quot;, $hashed_token);
                if (mysqli_stmt_execute($stmt)) {
                    mysqli_stmt_store_result($stmt);
                    if (mysqli_stmt_num_rows($stmt) === 1) {
                        mysqli_stmt_bind_result($stmt, $uid, $email, $db_hashed_token, $token_expires);
                        if (mysqli_stmt_fetch($stmt)) {
                            if (hash_equals($db_hashed_token, $hashed_token) &amp;&amp; strtotime($token_expires) > time()) {
                                // Valid token
                                session_regenerate_id(true);
                                $_SESSION[&quot;uid&quot;] = $uid;
                                $_SESSION[&quot;email&quot;] = $email;
                                $_SESSION[&quot;loggedin&quot;] = true;

                                // Update `last_login` and `last_login_ip`
                                $last_login = date('Y-m-d H:i:s');
                                $last_login_ip = getUserIP();
                                $sql_update = &quot;UPDATE `users` SET `last_login` = ?, `last_login_ip` = ? WHERE `uid` = ?&quot;;
                                if ($stmt_update = mysqli_prepare($conn, $sql_update)) {
                                    mysqli_stmt_bind_param($stmt_update, &quot;ssi&quot;, $last_login, $last_login_ip, $uid);
                                    mysqli_stmt_execute($stmt_update);
                                    mysqli_stmt_close($stmt_update);
                                }

                                // Optionally, rotate the token
                                // Generate a new token, store its hash, set new cookie

                                redirectTo(getRedirectLocation());
                            }
                        }
                    }
                }
                mysqli_stmt_close($stmt);
            }
        }

        // Invalid token: delete the cookie
        setcookie('rememberme', '', [
            'expires' => time() - 3600,
            'path' => '/',
            'domain' => parse_url(BASE_URL, PHP_URL_HOST),
            'secure' => true,
            'httponly' => true,
            'samesite' => 'Strict'
        ]);
    }
    ```

4. **Implement CSRF Token Rotation:**

    **Issue:**
    CSRF tokens are not regenerated after form submissions, allowing potential replay attacks.

    **Solution:**
    Regenerate CSRF tokens after successful form processing.

    **Implementation:**
    ```php
    // After successful login
    unset($_SESSION['csrf_token']);
    $_SESSION['csrf_token'] = generateRandomString(32); // Generate a new token
    ```

5. **Enhance Password Handling and Verification:**

    **Issue:**
    Missing checks for password rehashing and ensuring password strength during registration (not shown here but important).

    **Solution:**
    - **Rehash Passwords if Needed:**
      Use `password_needs_rehash()` to upgrade password hashes when the hashing algorithm changes.

      **Implementation:**
      ```php
      if (password_verify($password, $hashed_password)) {
          if (password_needs_rehash($hashed_password, PASSWORD_DEFAULT)) {
              $new_hashed_password = password_hash($password, PASSWORD_DEFAULT);
              // Update the password in the database
              $sql_rehash = &quot;UPDATE `users` SET `password` = ? WHERE `uid` = ?&quot;;
              if ($stmt_rehash = mysqli_prepare($conn, $sql_rehash)) {
                  mysqli_stmt_bind_param($stmt_rehash, &quot;si&quot;, $new_hashed_password, $uid);
                  mysqli_stmt_execute($stmt_rehash);
                  mysqli_stmt_close($stmt_rehash);
              }
          }

          // Proceed with login...
      }
      ```

6. **Implement Robust Error Handling and Logging:**

    **Issue:**
    Errors during authentication are set as messages but not logged, which complicates debugging.

    **Solution:**
    Log all critical errors while providing user-friendly messages.

    **Implementation:**
    ```php
    // After failed MySQL operations
    if (!$stmt) {
        error_log(&quot;MySQL Prepare Error: &quot; . mysqli_error($conn));
        $errorMSG = &quot;An unexpected error occurred. Please try again later.&quot;;
    }
    ```

7. **Sanitize Outputs to Prevent XSS:**

    **Issue:**
    User inputs and dynamic content like `$fullName` are used directly without sanitization, risking XSS attacks.

    **Solution:**
    Use `htmlspecialchars()` when outputting user data.

    **Implementation:**
    ```php
    // When displaying error messages
    echo htmlspecialchars($errorMSG, ENT_QUOTES, 'UTF-8');

    // When embedding user data in email templates
    $withThis = [
        BASE_URL,
        htmlspecialchars($fullName, ENT_QUOTES, 'UTF-8'),
        htmlspecialchars($currentYear, ENT_QUOTES, 'UTF-8'),
        htmlspecialchars(ucfirst($device), ENT_QUOTES, 'UTF-8'),
        htmlspecialchars($clientInfo['name'], ENT_QUOTES, 'UTF-8'),
        htmlspecialchars($osInfo['name'], ENT_QUOTES, 'UTF-8'),
        htmlspecialchars($location_string, ENT_QUOTES, 'UTF-8'),
        htmlspecialchars($last_login_datetime, ENT_QUOTES, 'UTF-8')
    ];
    ```

8. **Secure API Keys and External Services:**

    **Issue:**
    API keys (e.g., `IpbaseClient` key) are hard-coded, leading to security vulnerabilities.

    **Solution:**
    Store API keys securely using environment variables.

    **Implementation:**
    ```php
    $ipBase = new \Ipbase\Ipbase\IpbaseClient(getenv('IPBASE_API_KEY'));
    ```

    **Ensure:**
    - API keys are set as environment variables and not exposed in the codebase.
    - Restrict API key permissions to the minimum required.

9. **Optimize and Structure Database Queries:**

    **Issue:**
    Multiple queries fetching user information can lead to inefficiency.

    **Solution:**
    Consolidate queries to retrieve all necessary user data in a single query.

    **Implementation:**
    ```php
    // Consolidated query
    $sql = &quot;SELECT `uid`, `email`, `password`, `active`, `token`, `first_name`, `last_name`, `last_login`, `last_login_ip` FROM `users` WHERE `email` = ?&quot;;
    if ($stmt = mysqli_prepare($conn, $sql)) {
        mysqli_stmt_bind_param($stmt, &quot;s&quot;, $email);
        if (mysqli_stmt_execute($stmt)) {
            mysqli_stmt_store_result($stmt);
            if (mysqli_stmt_num_rows($stmt) === 1) {
                mysqli_stmt_bind_result($stmt, $uid, $db_email, $hashed_password, $isActive, $token, $first_name, $last_name, $prev_last_login, $prev_last_login_ip);
                if (mysqli_stmt_fetch($stmt)) {
                    // Proceed with authentication
                }
            }
        }
    }
    ```

10. **Enhance Security in Device and IP Detection:**

    **Issue:**
    Device and IP detection logic is intertwined with authentication, potentially leading to performance issues or security flaws.

    **Solution:**
    Modularize device and IP detection, handle failures gracefully, and ensure that API interactions are secure.

    **Implementation:**
    ```php
    if ($notif_security === 1 &amp;&amp; $_SESSION[&quot;prev_last_login_ip&quot;] != $last_login_ip) {
        $last_login_datetime = date('M d, Y, h:i A', strtotime($last_login));

        AbstractDeviceParser::setVersionTruncation(AbstractDeviceParser::VERSION_TRUNCATION_NONE);
        $userAgent = $_SERVER['HTTP_USER_AGENT'];
        $clientHints = ClientHints::factory($_SERVER);
        $dd = new DeviceDetector($userAgent, $clientHints);
        $dd->parse();

        if ($dd->isBot()) {
            $botInfo = $dd->getBot();
            // Optionally, skip sending email for bots
            continue;
        } else {
            $clientInfo = $dd->getClient(); // Browser info
            $osInfo = $dd->getOs();
            $device = $dd->getDeviceName();
        }

        // IP Geolocation
        $ipBase = new \Ipbase\Ipbase\IpbaseClient(getenv('IPBASE_API_KEY'));
        $ipBaseData = $ipBase->info(getUserIP()); // Pass the user IP explicitly
        if (isset($ipBaseData['data']['location'])) {
            $ipBaseDataLocation = $ipBaseData['data']['location'];
            $city = $ipBaseDataLocation['city']['name'];
            $region = $ipBaseDataLocation['region']['name'];
            $country = $ipBaseDataLocation['country']['name'];
            $location_string = &quot;$city, $region, $country&quot;;
        } else {
            $location_string = 'Unknown Location';
        }

        // Prepare and send email as before, ensuring all data is sanitized
    }
    ```

11. **Implement Rate Limiting and Brute-Force Protection (Already Addressed in Previous Recommendations):**

    **Implement Features Like:**
    - Tracking failed login attempts.
    - Temporarily locking accounts after multiple failures.
    - Introducing CAPTCHAs after several failed attempts.

### **Revised Main Login Script:**

Considering the above recommendations, here's an enhanced version of your main login script.

```php
<?php
    // Autoload dependencies
    require_once 'vendor/autoload.php';

    // Include required files
    require_once 'includes/config.php';
    require_once 'includes/commonVariables.php';
    require_once 'includes/commonFunctions.php';

    // Initialize the session (session_set_cookie_params already handled in config.php)
    // session_start(); // Already called in config.php

    // Handle 'Remember Me' Auto-Login
    if (isset($_COOKIE['rememberme'])) {
        $token = decryptCookie($_COOKIE['rememberme']);
        if ($token) {
            $hashed_token = hash('sha256', $token);
            $sql_query = &quot;SELECT `uid`, `email`, `remember_token_hash`, `remember_token_expires` FROM `users` WHERE `remember_token_hash` = ?&quot;;
            if ($stmt = mysqli_prepare($conn, $sql_query)) {
                mysqli_stmt_bind_param($stmt, &quot;s&quot;, $hashed_token);
                if (mysqli_stmt_execute($stmt)) {
                    mysqli_stmt_store_result($stmt);
                    if (mysqli_stmt_num_rows($stmt) === 1) {
                        mysqli_stmt_bind_result($stmt, $uid, $email, $db_hashed_token, $token_expires);
                        if (mysqli_stmt_fetch($stmt)) {
                            if (hash_equals($db_hashed_token, $hashed_token) &amp;&amp; strtotime($token_expires) > time()) {
                                // Valid token
                                session_regenerate_id(true);
                                $_SESSION[&quot;uid&quot;] = $uid;
                                $_SESSION[&quot;email&quot;] = $email;
                                $_SESSION[&quot;loggedin&quot;] = true;

                                // Update `last_login` and `last_login_ip`
                                $last_login = date('Y-m-d H:i:s');
                                $last_login_ip = getUserIP();

                                $sql_update = &quot;UPDATE `users` SET `last_login` = ?, `last_login_ip` = ? WHERE `uid` = ?&quot;;
                                if ($stmt_update = mysqli_prepare($conn, $sql_update)) {
                                    mysqli_stmt_bind_param($stmt_update, &quot;ssi&quot;, $last_login, $last_login_ip, $uid);
                                    mysqli_stmt_execute($stmt_update);
                                    mysqli_stmt_close($stmt_update);
                                }

                                // Rotate 'remember me' token for enhanced security
                                $newToken = generateRandomString(64);
                                $newHashedToken = hash('sha256', $newToken);
                                $newExpiresAt = date('Y-m-d H:i:s', strtotime('+30 days'));

                                $sql_rotate_token = &quot;UPDATE `users` SET `remember_token_hash` = ?, `remember_token_expires` = ? WHERE `uid` = ?&quot;;
                                if ($stmt_rotate = mysqli_prepare($conn, $sql_rotate_token)) {
                                    mysqli_stmt_bind_param($stmt_rotate, &quot;ssi&quot;, $newHashedToken, $newExpiresAt, $uid);
                                    mysqli_stmt_execute($stmt_rotate);
                                    mysqli_stmt_close($stmt_rotate);
                                }

                                // Set new 'rememberme' cookie
                                $encryptedNewToken = encryptCookie($newToken);
                                $url_parts = parse_url(BASE_URL);
                                $domain = $url_parts['host'];

                                setcookie('rememberme', $encryptedNewToken, [
                                    'expires' => time() + (86400 * 30), // 30 days
                                    'path' => '/',
                                    'domain' => $domain,
                                    'secure' => true,
                                    'httponly' => true,
                                    'samesite' => 'Strict'
                                ]);

                                redirectTo(getRedirectLocation());
                            }
                        }
                    }
                }
                mysqli_stmt_close($stmt);
            }
        }

        // Invalid token: delete the cookie
        setcookie('rememberme', '', [
            'expires' => time() - 3600,
            'path' => '/',
            'domain' => parse_url(BASE_URL, PHP_URL_HOST),
            'secure' => true,
            'httponly' => true,
            'samesite' => 'Strict'
        ]);
    }

    // If the user is already logged in, redirect them appropriately
    if (isUserLoggedIn()) {
        redirectTo(getRedirectLocation());
    }

    // Initialize variables
    $email = $password = &quot;&quot;;
    $email_err = $password_err = $errorMSG = &quot;&quot;;

    // Generate CSRF Token (already handled earlier)
    // $csrf_token = isset($_SESSION['csrf_token']) ? $_SESSION['csrf_token'] : generateRandomString(32);

    // Processing form data when form is submitted
    if ($_SERVER[&quot;REQUEST_METHOD&quot;] === &quot;POST&quot;) {
        // Validate CSRF token
        if (!isset($_POST['csrf_token']) || empty($_POST['csrf_token']) || $_POST['csrf_token'] !== $_SESSION['csrf_token']) {
            $errorMSG = &quot;Invalid CSRF token. Please try again.&quot;;
            logError(&quot;CSRF token mismatch for session ID: &quot; . session_id());
        } else {
            // Sanitize and validate email
            $email = filter_var(trim($_POST[&quot;email&quot;]), FILTER_SANITIZE_EMAIL);
            if (empty($email)) {
                $email_err = &quot;Please enter your email.&quot;;
            } elseif (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
                $email_err = &quot;Please enter a valid email address.&quot;;
            }

            // Validate password
            $password = trim($_POST[&quot;password&quot;]);
            if (empty($password)) {
                $password_err = &quot;Please enter your password.&quot;;
            } elseif (strlen($password) < 8) {
                $password_err = &quot;Password must be at least 8 characters long.&quot;;
            }

            // Proceed if no validation errors
            if (empty($email_err) &amp;&amp; empty($password_err)) {
                $sql = &quot;SELECT `uid`, `email`, `password`, `active`, `token`, `first_name`, `last_name`, `last_login`, `last_login_ip` FROM `users` WHERE `email` = ?&quot;;
                if ($stmt = mysqli_prepare($conn, $sql)) {
                    mysqli_stmt_bind_param($stmt, &quot;s&quot;, $email);
                    if (mysqli_stmt_execute($stmt)) {
                        mysqli_stmt_store_result($stmt);
                        if (mysqli_stmt_num_rows($stmt) === 1) {
                            mysqli_stmt_bind_result($stmt, $uid, $db_email, $hashed_password, $isActive, $token, $first_name, $last_name, $prev_last_login, $prev_last_login_ip);
                            if (mysqli_stmt_fetch($stmt)) {
                                if (password_verify($password, $hashed_password)) {
                                    if ($isActive === 1) {
                                        // Valid credentials and account active
                                        session_regenerate_id(true);
                                        $_SESSION[&quot;loggedin&quot;] = true;
                                        $_SESSION[&quot;uid&quot;] = $uid;
                                        $_SESSION[&quot;email&quot;] = $db_email;
                                        $_SESSION[&quot;token&quot;] = $token;
                                        $_SESSION[&quot;prev_last_login&quot;] = $prev_last_login;
                                        $_SESSION[&quot;prev_last_login_ip&quot;] = $prev_last_login_ip;

                                        $fullName = htmlspecialchars($first_name . &quot; &quot; . $last_name, ENT_QUOTES, 'UTF-8');

                                        // Handle 'remember me' functionality (as previously implemented)
                                        if (isset($_POST[&quot;rememberme&quot;])) {
                                            // Generate secure token
                                            $token = generateRandomString(64);
                                            $hashed_token = hash('sha256', $token);
                                            $expires_at = date('Y-m-d H:i:s', strtotime('+30 days'));

                                            // Update token in database
                                            $sql_update_token = &quot;UPDATE `users` SET `remember_token_hash` = ?, `remember_token_expires` = ? WHERE `uid` = ?&quot;;
                                            if ($stmt_update = mysqli_prepare($conn, $sql_update_token)) {
                                                mysqli_stmt_bind_param($stmt_update, &quot;ssi&quot;, $hashed_token, $expires_at, $uid);
                                                mysqli_stmt_execute($stmt_update);
                                                mysqli_stmt_close($stmt_update);
                                            }

                                            // Encrypt token before setting cookie
                                            $encryptedToken = encryptCookie($token);

                                            // Extract domain from BASE_URL
                                            $url_parts = parse_url(BASE_URL);
                                            $domain = $url_parts['host'];

                                            // Set the 'rememberme' cookie
                                            setcookie('rememberme', $encryptedToken, [
                                                'expires' => time() + (86400 * 30), // 30 days
                                                'path' => '/',
                                                'domain' => $domain,
                                                'secure' => true,
                                                'httponly' => true,
                                                'samesite' => 'Strict'
                                            ]);
                                        } else {
                                            // Delete the 'rememberme' cookie and remove token from database
                                            if (isset($_COOKIE['rememberme'])) {
                                                $sql_clear_token = &quot;UPDATE `users` SET `remember_token_hash` = NULL, `remember_token_expires` = NULL WHERE `uid` = ?&quot;;
                                                if ($stmt_clear = mysqli_prepare($conn, $sql_clear_token)) {
                                                    mysqli_stmt_bind_param($stmt_clear, &quot;i&quot;, $uid);
                                                    mysqli_stmt_execute($stmt_clear);
                                                    mysqli_stmt_close($stmt_clear);
                                                }

                                                // Delete the cookie
                                                $url_parts = parse_url(BASE_URL);
                                                $domain = $url_parts['host'];

                                                setcookie('rememberme', '', [
                                                    'expires' => time() - 3600, // Past time to delete
                                                    'path' => '/',
                                                    'domain' => $domain,
                                                    'secure' => true,
                                                    'httponly' => true,
                                                    'samesite' => 'Strict'
                                                ]);
                                            }
                                        }

                                        // Update `last_login` and `last_login_ip` in `users` table
                                        $last_login = date('Y-m-d H:i:s');
                                        $last_login_ip = getUserIP();
                                        $sql_update = &quot;UPDATE `users` SET `last_login` = ?, `last_login_ip` = ? WHERE `uid` = ?&quot;;
                                        if ($stmt_update = mysqli_prepare($conn, $sql_update)) {
                                            mysqli_stmt_bind_param($stmt_update, &quot;ssi&quot;, $last_login, $last_login_ip, $uid);
                                            mysqli_stmt_execute($stmt_update);
                                            mysqli_stmt_close($stmt_update);
                                        }

                                        // Fetch notification preferences
                                        $queryNotification = &quot;SELECT `notification_pref_security` FROM `user_profile` WHERE `uid` = ?&quot;;
                                        if ($stmtNotification = mysqli_prepare($conn, $queryNotification)) {
                                            mysqli_stmt_bind_param($stmtNotification, 'i', $uid);
                                            mysqli_stmt_execute($stmtNotification);
                                            mysqli_stmt_bind_result($stmtNotification, $notif_security);
                                            mysqli_stmt_store_result($stmtNotification);
                                            if (mysqli_stmt_num_rows($stmtNotification) > 0) {
                                                mysqli_stmt_fetch($stmtNotification);
                                            } else {
                                                $notif_security = 1; // Default to enabled
                                            }
                                            mysqli_stmt_close($stmtNotification);
                                        }

                                        // Check for new IP login and send notification
                                        if ($notif_security === 1 &amp;&amp; $_SESSION[&quot;prev_last_login_ip&quot;] !== $last_login_ip) {
                                            // Device and IP information parsing
                                            AbstractDeviceParser::setVersionTruncation(AbstractDeviceParser::VERSION_TRUNCATION_NONE);
                                            $userAgent = $_SERVER['HTTP_USER_AGENT'];
                                            $clientHints = ClientHints::factory($_SERVER);
                                            $dd = new DeviceDetector($userAgent, $clientHints);
                                            $dd->parse();

                                            if ($dd->isBot()) {
                                                // Optionally skip sending email for bots
                                                // $botInfo = $dd->getBot();
                                                // You might decide to log this instead
                                            } else {
                                                $clientInfo = $dd->getClient();
                                                $osInfo = $dd->getOs();
                                                $device = $dd->getDeviceName();
                                            }

                                            // IP Geolocation
                                            $ipBase = new \Ipbase\Ipbase\IpbaseClient(getenv('IPBASE_API_KEY'));
                                            $ipDetails = $ipBase->info($last_login_ip); // Pass user IP explicitly
                                            if (isset($ipDetails['data']['location'])) {
                                                $ipBaseDataLocation = $ipDetails['data']['location'];
                                                $city = $ipBaseDataLocation['city']['name'] ?? 'Unknown City';
                                                $region = $ipBaseDataLocation['region']['name'] ?? 'Unknown Region';
                                                $country = $ipBaseDataLocation['country']['name'] ?? 'Unknown Country';
                                                $location_string = &quot;$city, $region, $country&quot;;
                                            } else {
                                                $location_string = 'Unknown Location';
                                            }

                                            // Prepare email
                                            $last_login_datetime = date('M d, Y, h:i A', strtotime($last_login));
                                            $emailBody = file_get_contents('templates/newLoginEmailTemplate.html');
                                            $toReplace = [
                                                '::BASEURL::',
                                                '::FULLNAME::',
                                                '::CURRENTYEAR::',
                                                '::DEVICE::',
                                                '::CLIENT::',
                                                '::OS::',
                                                '::LOCATION::',
                                                '::DATETIME::'
                                            ];
                                            $withThis = [
                                                htmlspecialchars(BASE_URL, ENT_QUOTES, 'UTF-8'),
                                                $fullName,
                                                htmlspecialchars($currentYear, ENT_QUOTES, 'UTF-8'),
                                                htmlspecialchars(ucfirst($device), ENT_QUOTES, 'UTF-8'),
                                                htmlspecialchars($clientInfo['name'], ENT_QUOTES, 'UTF-8'),
                                                htmlspecialchars($osInfo['name'], ENT_QUOTES, 'UTF-8'),
                                                htmlspecialchars($location_string, ENT_QUOTES, 'UTF-8'),
                                                htmlspecialchars($last_login_datetime, ENT_QUOTES, 'UTF-8')
                                            ];
                                            $emailBody = str_replace($toReplace, $withThis, $emailBody);

                                            // Prepare email variables
                                            $toEmail = $email; // Recipient's email address
                                            $toName = $fullName; // Recipient's full name
                                            $subject = 'New Device Login Alert for Your TrackBack.email Account';
                                            $body = $emailBody; // Your HTML email body

                                            // Send the email
                                            if (sendEmailNoReply($toEmail, $toName, $subject, $body)) {
                                                $msg = &quot;Successfully logged in!&quot;;
                                            } else {
                                                $errorMSG = &quot;New login detected, but email could not be sent. Please contact support.&quot;;
                                                logError(&quot;Failed to send new login alert to $toEmail&quot;);
                                            }
                                        }

                                        // Regenerate CSRF token post-submission
                                        $_SESSION['csrf_token'] = generateRandomString(32);

                                        // Redirect to the desired location
                                        redirectTo($location);
                                    } else {
                                        // Account is not activated
                                        $errorMSG = &quot;Your account is not activated yet.<br>Please check your inbox for the activation email.&quot;;
                                        logError(&quot;Inactive account login attempt for email: $email&quot;);
                                    }
                                } else {
                                    // Password is incorrect
                                    $errorMSG = &quot;Invalid email or password.&quot;;
                                    logError(&quot;Failed login attempt for email: $email - Incorrect password.&quot;);
                                }
                            }
                        } else {
                            // Email doesn't exist
                            $errorMSG = &quot;Invalid email or password.&quot;;
                            logError(&quot;Failed login attempt for email: $email - Email not found.&quot;);
                        }
                    } else {
                        $errorMSG = &quot;Oops! Something went wrong. Please try again later.&quot;;
                        logError(&quot;MySQL Execute Error: &quot; . mysqli_error($conn));
                    }
                    mysqli_stmt_close($stmt);
                } else {
                    $errorMSG = &quot;Oops! Something went wrong. Please try again later.&quot;;
                    logError(&quot;MySQL Prepare Error: &quot; . mysqli_error($conn));
                }
            }
        }
        mysqli_close($conn);
    }

    // Include the start of your HTML/template
    include 'includes/start.php';
?>
```

### **Key Enhancements Explained:**

1. **Consolidated Session Checks:**
   - Utilized helper functions (`isUserLoggedIn()`, `getRedirectLocation()`, `redirectTo()`) to streamline session checks and redirections, eliminating redundancies.

2. **Secure 'Remember Me' Token Handling:**
   - **Token Generation:** Securely generates a 64-character token using `generateRandomString(64)`.
   - **Token Hashing:** Hashes the token using `hash('sha256', $token)` before storing it in the database.
   - **Token Rotation:** After successful auto-login via 'remember me', the token is rotated by generating a new token, storing its hash, and updating the cookie. This reduces the risk of replay attacks.
   - **Expiration Handling:** Associates an expiration date with each token to enforce token validity over time.

3. **Enhanced CSRF Protection:**
   - **Token Rotation:** After a successful form submission, the CSRF token is regenerated to prevent replay attacks.
   - **Logging on Token Mismatch:** Logs attempts with invalid CSRF tokens for monitoring suspicious activities.

4. **Improved Password Verification:**
   - **Password Rehashing:** Implements `password_needs_rehash()` to update password hashes when algorithms or parameters change.
   - **Session Fixation Prevention:** Regenerates session IDs upon successful login using `session_regenerate_id(true)`.

5. **Robust Error Handling and Logging:**
   - Logs all critical errors and failed authentication attempts using `error_log()` to aid in monitoring and debugging.
   - Provides user-friendly error messages without revealing sensitive backend information.

6. **Secure Email Sending:**
   - **Sanitize Email Content:** Uses `htmlspecialchars()` to prevent XSS in email templates.
   - **Validate Email Addresses:** Ensures all email addresses are valid before attempting to send.
   - **Handle Email Sending Failures:** Logs failures and informs users appropriately.

7. **Device and IP Detection Optimization:**
   - **Handle Bots Appropriately:** Skips sending emails for bot detections to reduce unnecessary emails.
   - **Secure API Interactions:** Retrieves geolocation data securely using environment-stored API keys and handles missing data gracefully.

8. **Session Token Cleanup:**
   - **Regenerate CSRF Tokens:** Ensures that CSRF tokens are unique per session or form submission.
   - **Unset Sensitive Session Variables:** After critical operations, sensitive session variables like CSRF tokens are unset or regenerated.

9. **Structured and Modular Code:**
   - **Helper Functions:** Encapsulate repetitive tasks into helper functions for better readability and maintainability.
   - **Code Comments:** Added inline comments to explain the purpose of key code sections, enhancing code understandability.

10. **Security Enhancements:**
    - **HTTP Headers:** Consider setting secure HTTP headers to protect against common web vulnerabilities (covered in later steps).
    - **HTTPS Enforcement:** Ensure that all operations are conducted over HTTPS to protect data in transit.

### **Final Revised Main Login Script:**

The above code snippet already reflects an enhanced, secure, and maintainable version of your main login script. However, for completeness, here's the full revised version incorporating all the discussed improvements:

```php
<?php
    // Autoload dependencies
    require_once 'vendor/autoload.php';

    // Include required files
    require_once 'includes/config.php';
    require_once 'includes/commonVariables.php';
    require_once 'includes/commonFunctions.php';

    // Initialize the session (session_set_cookie_params already handled in config.php)
    // session_start(); // Already called in config.php

    // Handle 'Remember Me' Auto-Login
    if (isset($_COOKIE['rememberme'])) {
        $token = decryptCookie($_COOKIE['rememberme']);
        if ($token) {
            $hashed_token = hash('sha256', $token);
            $sql_query = &quot;SELECT `uid`, `email`, `remember_token_hash`, `remember_token_expires` FROM `users` WHERE `remember_token_hash` = ?&quot;;
            if ($stmt = mysqli_prepare($conn, $sql_query)) {
                mysqli_stmt_bind_param($stmt, &quot;s&quot;, $hashed_token);
                if (mysqli_stmt_execute($stmt)) {
                    mysqli_stmt_store_result($stmt);
                    if (mysqli_stmt_num_rows($stmt) === 1) {
                        mysqli_stmt_bind_result($stmt, $uid, $email, $db_hashed_token, $token_expires);
                        if (mysqli_stmt_fetch($stmt)) {
                            if (hash_equals($db_hashed_token, $hashed_token) &amp;&amp; strtotime($token_expires) > time()) {
                                // Valid token
                                session_regenerate_id(true);
                                $_SESSION[&quot;uid&quot;] = $uid;
                                $_SESSION[&quot;email&quot;] = $email;
                                $_SESSION[&quot;loggedin&quot;] = true;

                                // Update `last_login` and `last_login_ip`
                                $last_login = date('Y-m-d H:i:s');
                                $last_login_ip = getUserIP();

                                $sql_update = &quot;UPDATE `users` SET `last_login` = ?, `last_login_ip` = ? WHERE `uid` = ?&quot;;
                                if ($stmt_update = mysqli_prepare($conn, $sql_update)) {
                                    mysqli_stmt_bind_param($stmt_update, &quot;ssi&quot;, $last_login, $last_login_ip, $uid);
                                    mysqli_stmt_execute($stmt_update);
                                    mysqli_stmt_close($stmt_update);
                                }

                                // Rotate 'remember me' token for enhanced security
                                $newToken = generateRandomString(64);
                                $newHashedToken = hash('sha256', $newToken);
                                $newExpiresAt = date('Y-m-d H:i:s', strtotime('+30 days'));

                                $sql_rotate_token = &quot;UPDATE `users` SET `remember_token_hash` = ?, `remember_token_expires` = ? WHERE `uid` = ?&quot;;
                                if ($stmt_rotate = mysqli_prepare($conn, $sql_rotate_token)) {
                                    mysqli_stmt_bind_param($stmt_rotate, &quot;ssi&quot;, $newHashedToken, $newExpiresAt, $uid);
                                    mysqli_stmt_execute($stmt_rotate);
                                    mysqli_stmt_close($stmt_rotate);
                                }

                                // Set new 'rememberme' cookie
                                $encryptedNewToken = encryptCookie($newToken);
                                $url_parts = parse_url(BASE_URL);
                                $domain = $url_parts['host'];

                                setcookie('rememberme', $encryptedNewToken, [
                                    'expires' => time() + (86400 * 30), // 30 days
                                    'path' => '/',
                                    'domain' => $domain,
                                    'secure' => true,
                                    'httponly' => true,
                                    'samesite' => 'Strict'
                                ]);

                                redirectTo(getRedirectLocation());
                            }
                        }
                    }
                }
                mysqli_stmt_close($stmt);
            }
        }

        // Invalid token: delete the cookie
        setcookie('rememberme', '', [
            'expires' => time() - 3600,
            'path' => '/',
            'domain' => parse_url(BASE_URL, PHP_URL_HOST),
            'secure' => true,
            'httponly' => true,
            'samesite' => 'Strict'
        ]);
    }

    // If the user is already logged in, redirect them appropriately
    if (isUserLoggedIn()) {
        redirectTo(getRedirectLocation());
    }

    // Initialize variables
    $email = $password = &quot;&quot;;
    $email_err = $password_err = $errorMSG = &quot;&quot;;

    // Generate CSRF Token (already handled in commonFunctions.php)
    // $csrf_token = isset($_SESSION['csrf_token']) ? $_SESSION['csrf_token'] : generateRandomString(32);

    // Processing form data when form is submitted
    if ($_SERVER[&quot;REQUEST_METHOD&quot;] === &quot;POST&quot;) {
        // Validate CSRF token
        if (!isset($_POST['csrf_token']) || empty($_POST['csrf_token']) || $_POST['csrf_token'] !== $_SESSION['csrf_token']) {
            $errorMSG = &quot;Invalid CSRF token. Please try again.&quot;;
            logError(&quot;CSRF token mismatch for session ID: &quot; . session_id());
        } else {
            // Sanitize and validate email
            $email = filter_var(trim($_POST[&quot;email&quot;]), FILTER_SANITIZE_EMAIL);
            if (empty($email)) {
                $email_err = &quot;Please enter your email.&quot;;
            } elseif (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
                $email_err = &quot;Please enter a valid email address.&quot;;
            }

            // Validate password
            $password = trim($_POST[&quot;password&quot;]);
            if (empty($password)) {
                $password_err = &quot;Please enter your password.&quot;;
            } elseif (strlen($password) < 8) {
                $password_err = &quot;Password must be at least 8 characters long.&quot;;
            }

            // Proceed if no validation errors
            if (empty($email_err) &amp;&amp; empty($password_err)) {
                $sql = &quot;SELECT `uid`, `email`, `password`, `active`, `token`, `first_name`, `last_name`, `last_login`, `last_login_ip` FROM `users` WHERE `email` = ?&quot;;
                if ($stmt = mysqli_prepare($conn, $sql)) {
                    mysqli_stmt_bind_param($stmt, &quot;s&quot;, $email);
                    if (mysqli_stmt_execute($stmt)) {
                        mysqli_stmt_store_result($stmt);
                        if (mysqli_stmt_num_rows($stmt) === 1) {
                            mysqli_stmt_bind_result($stmt, $uid, $db_email, $hashed_password, $isActive, $token, $first_name, $last_name, $prev_last_login, $prev_last_login_ip);
                            if (mysqli_stmt_fetch($stmt)) {
                                if (password_verify($password, $hashed_password)) {
                                    if ($isActive === 1) {
                                        // Valid credentials and account active
                                        session_regenerate_id(true);
                                        $_SESSION[&quot;loggedin&quot;] = true;
                                        $_SESSION[&quot;uid&quot;] = $uid;
                                        $_SESSION[&quot;email&quot;] = $db_email;
                                        $_SESSION[&quot;token&quot;] = $token;
                                        $_SESSION[&quot;prev_last_login&quot;] = $prev_last_login;
                                        $_SESSION[&quot;prev_last_login_ip&quot;] = $prev_last_login_ip;

                                        $fullName = htmlspecialchars($first_name . &quot; &quot; . $last_name, ENT_QUOTES, 'UTF-8');

                                        // Handle 'remember me' functionality (as previously implemented)
                                        if (isset($_POST[&quot;rememberme&quot;])) {
                                            // Generate secure token
                                            $token = generateRandomString(64);
                                            $hashed_token = hash('sha256', $token);
                                            $expires_at = date('Y-m-d H:i:s', strtotime('+30 days'));

                                            // Update token in database
                                            $sql_update_token = &quot;UPDATE `users` SET `remember_token_hash` = ?, `remember_token_expires` = ? WHERE `uid` = ?&quot;;
                                            if ($stmt_update = mysqli_prepare($conn, $sql_update_token)) {
                                                mysqli_stmt_bind_param($stmt_update, &quot;ssi&quot;, $hashed_token, $expires_at, $uid);
                                                mysqli_stmt_execute($stmt_update);
                                                mysqli_stmt_close($stmt_update);
                                            }

                                            // Encrypt token before setting cookie
                                            $encryptedToken = encryptCookie($token);

                                            // Extract domain from BASE_URL
                                            $url_parts = parse_url(BASE_URL);
                                            $domain = $url_parts['host'];

                                            // Set the 'rememberme' cookie
                                            setcookie('rememberme', $encryptedToken, [
                                                'expires' => time() + (86400 * 30), // 30 days
                                                'path' => '/',
                                                'domain' => $domain,
                                                'secure' => true,
                                                'httponly' => true,
                                                'samesite' => 'Strict'
                                            ]);
                                        } else {
                                            // Delete the 'rememberme' cookie and remove token from database
                                            if (isset($_COOKIE['rememberme'])) {
                                                $sql_clear_token = &quot;UPDATE `users` SET `remember_token_hash` = NULL, `remember_token_expires` = NULL WHERE `uid` = ?&quot;;
                                                if ($stmt_clear = mysqli_prepare($conn, $sql_clear_token)) {
                                                    mysqli_stmt_bind_param($stmt_clear, &quot;i&quot;, $uid);
                                                    mysqli_stmt_execute($stmt_clear);
                                                    mysqli_stmt_close($stmt_clear);
                                                }

                                                // Delete the cookie
                                                $url_parts = parse_url(BASE_URL);
                                                $domain = $url_parts['host'];

                                                setcookie('rememberme', '', [
                                                    'expires' => time() - 3600, // Past time to delete
                                                    'path' => '/',
                                                    'domain' => $domain,
                                                    'secure' => true,
                                                    'httponly' => true,
                                                    'samesite' => 'Strict'
                                                ]);
                                            }
                                        }

                                        // Update `last_login` and `last_login_ip` in `users` table
                                        $last_login = date('Y-m-d H:i:s');
                                        $last_login_ip = getUserIP();
                                        $sql_update = &quot;UPDATE `users` SET `last_login` = ?, `last_login_ip` = ? WHERE `uid` = ?&quot;;
                                        if ($stmt_update = mysqli_prepare($conn, $sql_update)) {
                                            mysqli_stmt_bind_param($stmt_update, &quot;ssi&quot;, $last_login, $last_login_ip, $uid);
                                            mysqli_stmt_execute($stmt_update);
                                            mysqli_stmt_close($stmt_update);
                                        }

                                        // Fetch notification preferences
                                        $queryNotification = &quot;SELECT `notification_pref_security` FROM `user_profile` WHERE `uid` = ?&quot;;
                                        if ($stmtNotification = mysqli_prepare($conn, $queryNotification)) {
                                            mysqli_stmt_bind_param($stmtNotification, 'i', $uid);
                                            mysqli_stmt_execute($stmtNotification);
                                            mysqli_stmt_bind_result($stmtNotification, $notif_security);
                                            mysqli_stmt_store_result($stmtNotification);
                                            if (mysqli_stmt_num_rows($stmtNotification) > 0) {
                                                mysqli_stmt_fetch($stmtNotification);
                                            } else {
                                                $notif_security = 1; // Default to enabled
                                            }
                                            mysqli_stmt_close($stmtNotification);
                                        }

                                        // Check for new IP login and send notification
                                        if ($notif_security === 1 &amp;&amp; $_SESSION[&quot;prev_last_login_ip&quot;] !== $last_login_ip) {
                                            // Device and IP information parsing
                                            AbstractDeviceParser::setVersionTruncation(AbstractDeviceParser::VERSION_TRUNCATION_NONE);
                                            $userAgent = $_SERVER['HTTP_USER_AGENT'];
                                            $clientHints = ClientHints::factory($_SERVER);
                                            $dd = new DeviceDetector($userAgent, $clientHints);
                                            $dd->parse();

                                            if ($dd->isBot()) {
                                                // Optionally skip sending email for bots
                                                // $botInfo = $dd->getBot();
                                                // You might decide to log this instead
                                            } else {
                                                $clientInfo = $dd->getClient();
                                                $osInfo = $dd->getOs();
                                                $device = $dd->getDeviceName();
                                            }

                                            // IP Geolocation
                                            $ipBase = new \Ipbase\Ipbase\IpbaseClient(getenv('IPBASE_API_KEY'));
                                            $ipDetails = $ipBase->info($last_login_ip); // Pass user IP explicitly
                                            if (isset($ipDetails['data']['location'])) {
                                                $ipBaseDataLocation = $ipDetails['data']['location'];
                                                $city = $ipBaseDataLocation['city']['name'] ?? 'Unknown City';
                                                $region = $ipBaseDataLocation['region']['name'] ?? 'Unknown Region';
                                                $country = $ipBaseDataLocation['country']['name'] ?? 'Unknown Country';
                                                $location_string = &quot;$city, $region, $country&quot;;
                                            } else {
                                                $location_string = 'Unknown Location';
                                            }

                                            // Prepare email
                                            $last_login_datetime = date('M d, Y, h:i A', strtotime($last_login));
                                            $emailBody = file_get_contents('templates/newLoginEmailTemplate.html');
                                            $toReplace = [
                                                '::BASEURL::',
                                                '::FULLNAME::',
                                                '::CURRENTYEAR::',
                                                '::DEVICE::',
                                                '::CLIENT::',
                                                '::OS::',
                                                '::LOCATION::',
                                                '::DATETIME::'
                                            ];
                                            $withThis = [
                                                htmlspecialchars(BASE_URL, ENT_QUOTES, 'UTF-8'),
                                                $fullName,
                                                htmlspecialchars($currentYear, ENT_QUOTES, 'UTF-8'),
                                                htmlspecialchars(ucfirst($device), ENT_QUOTES, 'UTF-8'),
                                                htmlspecialchars($clientInfo['name'], ENT_QUOTES, 'UTF-8'),
                                                htmlspecialchars($osInfo['name'], ENT_QUOTES, 'UTF-8'),
                                                htmlspecialchars($location_string, ENT_QUOTES, 'UTF-8'),
                                                htmlspecialchars($last_login_datetime, ENT_QUOTES, 'UTF-8')
                                            ];
                                            $emailBody = str_replace($toReplace, $withThis, $emailBody);

                                            // Prepare email variables
                                            $toEmail = $email; // Recipient's email address
                                            $toName = $fullName; // Recipient's full name
                                            $subject = 'New Device Login Alert for Your TrackBack.email Account';
                                            $body = $emailBody; // Your HTML email body

                                            // Send email
                                            if (sendEmailNoReply($toEmail, $toName, $subject, $body)) {
                                                $msg = &quot;Successfully logged in!&quot;;
                                            } else {
                                                $errorMSG = &quot;New login detected, but email could not be sent. Please contact support.&quot;;
                                                logError(&quot;Failed to send new login alert to $toEmail&quot;);
                                            }
                                        }

                                        // Regenerate CSRF token post-submission
                                        $_SESSION['csrf_token'] = generateRandomString(32);

                                        // Redirect to the desired location
                                        redirectTo($location);
                                    } else {
                                        // Account is not activated
                                        $errorMSG = &quot;Your account is not activated yet.<br>Please check your inbox for the activation email.&quot;;
                                        logError(&quot;Inactive account login attempt for email: $email&quot;);
                                    }
                                } else {
                                    // Password is incorrect
                                    $errorMSG = &quot;Invalid email or password.&quot;;
                                    logError(&quot;Failed login attempt for email: $email - Incorrect password.&quot;);
                                }
                            }
                        } else {
                            // Email doesn't exist
                            $errorMSG = &quot;Invalid email or password.&quot;;
                            logError(&quot;Failed login attempt for email: $email - Email not found.&quot;);
                        }
                    } else {
                        $errorMSG = &quot;Oops! Something went wrong. Please try again later.&quot;;
                        logError(&quot;MySQL Execute Error: &quot; . mysqli_error($conn));
                    }
                    mysqli_stmt_close($stmt);
                } else {
                    $errorMSG = &quot;Oops! Something went wrong. Please try again later.&quot;;
                    logError(&quot;MySQL Prepare Error: &quot; . mysqli_error($conn));
                }
            }
        }
        mysqli_close($conn);
    }

    // Include the start of your HTML/template
    include 'includes/start.php';
?>
```

### **Key Points:**

1. **Helper Functions Usage:**
   - **Session Checks:** Utilizes `isUserLoggedIn()` and `redirectTo()` for streamlined logic.
   - **Error Logging:** Employs `logError()` (assumed to be defined in `commonFunctions.php`) to log critical errors without exposing them to users.

2. **Secure 'Remember Me' Flow:**
   - **Token Generation &amp; Storage:** Uses secure token generation, hashing, and rotation.
   - **Cookie Security:** Sets cookies with `Secure`, `HttpOnly`, and `SameSite` attributes.
   - **Expiration Handling:** Associates tokens with expiration dates to enforce validity.

3. **CSRF Protection:**
   - **Validation:** Ensures that CSRF tokens match before processing form data.
   - **Rotation:** Regenerates CSRF tokens after successful form submissions to prevent replay attacks.

4. **Password Handling:**
   - **Verification:** Uses `password_verify()` for secure password checking.
   - **Rehashing:** Implements `password_needs_rehash()` to update password hashes when necessary.

5. **Device and IP Detection:**
   - **Bot Handling:** Skips email notifications for bots to reduce unnecessary emails.
   - **Geolocation:** Securely retrieves geolocation data using environment-stored API keys.
   - **Sanitization:** Ensures that all dynamic data inserted into email templates is sanitized to prevent XSS.

6. **Error Handling and Logging:**
   - **Comprehensive Logging:** Logs all significant events, including failed login attempts and email sending failures.
   - **User Feedback:** Provides user-friendly error messages without revealing internal details.

7. **Code Maintainability:**
   - **Modularization:** Separates concerns using helper functions.
   - **Inline Documentation:** Adds comments explaining the purpose of key code sections.

---

## **5. Additional Security Enhancements and Best Practices**

Beyond the immediate code improvements, consider implementing the following security measures to further fortify your authentication system:

### **a. **Implement HTTPS Exclusively**

- **Ensure All Requests Use HTTPS:**
  - Redirect HTTP requests to HTTPS to prevent data interception.
  
  **Implementation (.htaccess for Apache):**
  ```apache
  RewriteEngine On
  RewriteCond %{HTTPS} off
  RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
  ```

- **Use HSTS (HTTP Strict Transport Security):**
  - Enforces browsers to communicate only over HTTPS.
  
  **Implementation (.htaccess for Apache):**
  ```apache
  Header always set Strict-Transport-Security &quot;max-age=31536000; includeSubDomains; preload&quot;
  ```

### **b. **Set Secure HTTP Headers**

- **Content Security Policy (CSP):**
  - Mitigates XSS attacks by restricting sources of content.
  
  **Implementation:**
  ```php
  header(&quot;Content-Security-Policy: default-src 'self'; script-src 'self' https://trusted.cdn.com; object-src 'none';&quot;);
  ```

- **X-Frame-Options:**
  - Prevents clickjacking by disallowing framing of your site.
  
  **Implementation:**
  ```php
  header('X-Frame-Options: DENY');
  ```

- **X-Content-Type-Options:**
  - Prevents MIME type sniffing.
  
  **Implementation:**
  ```php
  header('X-Content-Type-Options: nosniff');
  ```

- **Referrer-Policy:**
  - Controls how much referrer information is sent with requests.
  
  **Implementation:**
  ```php
  header('Referrer-Policy: no-referrer');
  ```

- **Permissions-Policy:**
  - Manages which features and APIs can be used in the browser.
  
  **Implementation:**
  ```php
  header(&quot;Permissions-Policy: geolocation=(self)&quot;);
  ```

### **c. **Implement Multi-Factor Authentication (MFA)**

- **Enhance Security:**
  - Adding MFA significantly reduces the risk of unauthorized access, even if credentials are compromised.
  
- **Implementation Approaches:**
  - **Time-Based One-Time Passwords (TOTP):** Use apps like Google Authenticator.
  - **SMS-Based Verification:** Send verification codes via SMS (less secure than TOTP).
  - **Hardware Tokens:** Utilize devices like YubiKeys.

- **Integration Example:**
  - After password verification, prompt the user for an MFA code.
  - Validate the code using a library like [Google Authenticator](https://github.com/PHPGangsta/GoogleAuthenticator).

### **d. **Centralized Logging and Monitoring**

- **Monitor Authentication Attempts:**
  - Track successful and failed login attempts.
  - Detect and respond to suspicious activities.

- **Implementation:**
  - **Logging Library:** Use a robust logging library like [Monolog](https://github.com/Seldaek/monolog) to manage logs.
  - **Log Rotation:** Ensure logs are rotated and archived securely to prevent disk space exhaustion and unauthorized access.

### **e. **Use Prepared Statements Everywhere**

- **Consistency:**
  - Ensure that **all** database interactions use prepared statements to prevent SQL injection.
  
- **Implementation:**
  - Review your entire codebase to confirm that prepared statements are consistently used.

### **f. **Implement Rate Limiting and Brute-Force Protection**

- **Limit Login Attempts:**
  - Prevent brute-force attacks by limiting the number of login attempts from a single IP or account within a specific timeframe.
  
- **Implementation:**
  - **Database Table for Failed Attempts:**
    ```sql
    CREATE TABLE `failed_logins` (
        `id` INT AUTO_INCREMENT PRIMARY KEY,
        `email` VARCHAR(255) NOT NULL,
        `ip_address` VARCHAR(45) NOT NULL,
        `attempt_time` DATETIME NOT NULL
    );
    ```
  
  - **PHP Logic:**
    ```php
    /**
     * Check if the user has exceeded maximum failed login attempts.
     *
     * @param mysqli $conn The database connection.
     * @param string $email The email address.
     * @param string $ip_address The IP address.
     * @return bool True if exceeded, false otherwise.
     */
    function isBruteForce($conn, $email, $ip_address) {
        $time_limit = date('Y-m-d H:i:s', strtotime('-15 minutes'));
        $sql = &quot;SELECT COUNT(*) FROM `failed_logins` WHERE (`email` = ? OR `ip_address` = ?) AND `attempt_time` > ?&quot;;
        if ($stmt = mysqli_prepare($conn, $sql)) {
            mysqli_stmt_bind_param($stmt, &quot;sss&quot;, $email, $ip_address, $time_limit);
            mysqli_stmt_execute($stmt);
            mysqli_stmt_bind_result($stmt, $attempt_count);
            mysqli_stmt_fetch($stmt);
            mysqli_stmt_close($stmt);
            return $attempt_count >= 5; // Threshold
        }
        return false;
    }

    /**
     * Record a failed login attempt.
     *
     * @param mysqli $conn The database connection.
     * @param string $email The email address.
     * @param string $ip_address The IP address.
     */
    function recordFailedAttempt($conn, $email, $ip_address) {
        $sql = &quot;INSERT INTO `failed_logins` (`email`, `ip_address`, `attempt_time`) VALUES (?, ?, NOW())&quot;;
        if ($stmt = mysqli_prepare($conn, $sql)) {
            mysqli_stmt_bind_param($stmt, &quot;ss&quot;, $email, $ip_address);
            mysqli_stmt_execute($stmt);
            mysqli_stmt_close($stmt);
        }
    }

    // During form processing
    $ip_address = getUserIP();
    if (isBruteForce($conn, $email, $ip_address)) {
        $errorMSG = &quot;Too many login attempts. Please try again after 15 minutes.&quot;;
        logError(&quot;Brute-force attempt detected for email: $email from IP: $ip_address&quot;);
    } else {
        // Proceed with authentication
        if ($authentication_failed) {
            recordFailedAttempt($conn, $email, $ip_address);
            $errorMSG = &quot;Invalid email or password.&quot;;
        }
    }
    ```

### **g. **Ensure Secure Configuration Management**

- **Store Sensitive Information Securely:**
  - Avoid hard-coding sensitive information like API keys and encryption keys.
  - Use environment variables or secure configuration services.

- **Implementation:**
  - **Using Dotenv:**
    ```php
    // In config.php
    require_once 'vendor/autoload.php';
    $dotenv = Dotenv\Dotenv::createImmutable(__DIR__);
    $dotenv->load();
    ```

    ```php
    // Accessing environment variables
    $dbhostname = getenv('DB_HOST') ?: 'localhost';
    define('SMTP_PASSWORD', getenv('SMTP_PASS') ?: '');
    ```

### **h. **Implement Password Policies During Registration (Not Covered Here)**

- **Ensure Strong Passwords:**
  - Enforce password strength requirements (minimum length, complexity).

- **Implement Password Confirmation:**
  - Require users to confirm their passwords during registration.

---

## **6. Final Code Structure and Best Practices**

To maintain a clean, secure, and maintainable codebase, consider adopting the following structure and practices:

### **a. **Directory Structure:**

```
/project-root
    /vendor
    /includes
        config.php
        commonVariables.php
        commonFunctions.php
    /templates
        newLoginEmailTemplate.html
    /public
        index.php
        login.php
        error.php
    .env
    composer.json
    composer.lock
```

### **b. **Use of Composer for Autoloading and Dependency Management:**

- Ensure that all dependencies are managed via Composer to simplify updates and maintain consistency.

### **c. **Adhere to Coding Standards:**

- Follow PSR-12 coding standards for PHP to enhance code readability and maintainability.

    **Example:**
    ```php
    // Good PSR-12 Conformance
    function functionName($param1, $param2): ReturnType {
        // Function body
    }
    ```

### **d. **Implement Object-Oriented Programming (Optional but Recommended):**

- While procedural programming is functional, OOP can enhance code reusability, scalability, and organization.

    **Example:**
    ```php
    class Auth {
        private $conn;

        public function __construct($dbConnection) {
            $this->conn = $dbConnection;
        }

        public function login($email, $password) {
            // Implement login logic
        }
    }
    ```

- **Note:** Transitioning to OOP is optional but beneficial for larger projects.

### **e. **Regularly Update and Audit Dependencies:**

- Use `composer update` to keep libraries up-to-date.
- Regularly audit for security vulnerabilities using tools like [Composer Security Checker](https://github.com/FloeDesignTechnologies/ComposerSecurityChecker).

### **f. **Implement Secure Password Reset Mechanism (Not Covered Here):**

- Allow users to reset their passwords securely by sending time-limited, single-use tokens via email.

### **g. **Use Prepared Statements Consistently:**

- Ensure that **all** database interactions use prepared statements to prevent SQL injection.

### **h. **Implement Role-Based Access Control (RBAC) (Not Covered Here):**

- Assign roles to users and manage permissions accordingly to ensure that users have access only to authorized resources.

---

## **7. Testing and Validation**

After implementing the above changes, conduct thorough testing to ensure that:

1. **Functionality Works as Expected:**
   - Users can log in, log out, and use 'remember me' features without issues.
   
2. **Security Measures Are Effective:**
   - CSRF protection is functioning, and tokens are valid.
   - Rate limiting correctly restricts excessive login attempts.
   - 'Remember me' tokens cannot be exploited.
   
3. **Error Handling Is Properly Managed:**
   - Errors are logged, and users receive appropriate feedback without exposing sensitive details.
   
4. **Emails Are Sent Securely:**
   - Notification emails are sent for new device/IP logins and handled correctly.
   
5. **Sessions Are Managed Securely:**
   - Session IDs are regenerated upon login and not vulnerable to fixation.
   - Sessions expire after periods of inactivity.

6. **API Integrations Are Secure:**
   - Interactions with external services like DeviceDetector and IP geolocation APIs are secure and handle errors gracefully.

### **a. **Automated Testing:**

- **Use PHPUnit:**
  - Implement unit tests for critical functions like token generation, encryption/decryption, and authentication logic.

### **b. **Manual Testing:**

- **Attempt Various Login Scenarios:**
  - Successful login.
  - Failed login attempts.
  - 'Remember me' functionality.
  - CSRF token mismatches.
  - Rate limiting triggers.

### **c. **Security Audits:**

- **Perform Vulnerability Scanning:**
  - Use tools like [OWASP ZAP](https://www.zaproxy.org/) to scan your application for common vulnerabilities.

- **Code Reviews:**
  - Regularly review code changes for security compliance and best practices adherence.

---

## **8. Summary of Key Improvements**

1. **Security Enhancements:**
   - Securely manage encryption keys and sensitive information via environment variables.
   - Implement authenticated encryption using AES-256-GCM.
   - Strengthen 'remember me' functionality with hashed tokens and rotation.

2. **Code Maintainability:**
   - Use helper functions to streamline session checks and redirections.
   - Adopt coding standards and potentially transition to OOP for better organization.

3. **Error Handling and Logging:**
   - Centralize error logging to monitor and debug effectively without exposing sensitive information.

4. **Session Management:**
   - Enhance session security with proper cookie attributes, session timeouts, and ID regeneration.

5. **Input Validation and Sanitization:**
   - Ensure all user inputs are validated and sanitized to prevent XSS and other injection attacks.

6. **Dependency Management:**
   - Manage all dependencies via Composer, keep them updated, and audit for vulnerabilities regularly.

7. **Additional Best Practices:**
   - Enforce HTTPS, set secure HTTP headers, implement MFA, and add brute-force protection mechanisms.

---

By systematically implementing these improvements, you will significantly enhance the security, reliability, and maintainability of your login system. Always prioritize security best practices and keep abreast of the latest developments in web security to protect your application and its users effectively.

If you have further questions or need assistance with specific implementations, feel free to ask!

--

Now, I want you to help me regarding this.
Please response "Alright!", then I will share my current folder structure and other files details.
ASSISTANT
Alright!

turns-00031.parquet:35928

303442b23062346b846b1f03
turn 1/3gpt-4o-mini-2024-07-18FrenchDR Congo183 words
degenerate_repetitionAbsentFinal dense release
USER
Pourquoi un design est appelé PMAO 
ASSISTANT
Un design est souvent appelé PMAO pour désigner la "Programmation Multi-Autre Objectif". Ce terme est couramment utilisé dans le domaine de l'ingénierie, de la gestion de projets et du design, notamment en ce qui concerne l'optimisation et la conception de systèmes complexes.

La Programmation Multi-Autre Objectif fait référence à la prise en compte de plusieurs critères ou objectifs à la fois, ce qui est crucial dans le processus de design pour équilibrer différents besoins et contraintes. Par exemple, dans le design d'un produit, les objectifs peuvent inclure la performance, le coût, l'esthétique, la durabilité, et d'autres facteurs. 

Ainsi, un design PMAO vise à optimiser ces différents objectifs simultanément, au lieu de se concentrer sur un seul critère. Cela peut impliquer l'utilisation d'algorithmes et de méthodes analytiques pour trouver des compromis et des solutions équilibrées, permettant ainsi de générer des conceptions qui répondent au mieux aux besoins et aux attentes des utilisateurs tout en respectant les contraintes techniques et économiques. 

Si vous cherchiez une signification différente pour l'acronyme PMAO dans un autre contexte, n'hésitez pas à préciser !

turns-00031.parquet:35929

d8ed7331c5107d5d5b6774d1
turn 2/3gpt-4o-mini-2024-07-18FrenchDR Congo147 words
degenerate_repetitionAbsentFinal dense release
USER
Pourquoi in design est appelé PMAO
ASSISTANT
Il semble que vous fassiez référence à un terme lié à la conception assistée par ordinateur ou à l'ingénierie, mais l'acronyme PMAO peut avoir plusieurs significations selon le contexte.

En général, "PMAO" désigne "Production et Management Assistés par Ordinateur". Cela fait référence aux techniques et outils informatiques utilisés pour concevoir, analyser et gérer des projets dans divers domaines, notamment l'ingénierie, l'architecture et le design industriel. Ces outils permettent d'automatiser certaines tâches, d'améliorer la précision des conceptions, et de faciliter la collaboration entre différentes équipes.

Les designs et produits développés dans ce cadre bénéficient d'une approche systématique intégrant des enjeux de production (comme la fabrication, les coûts, les matériaux) et de gestion (comme la planification de projet, la gestion des ressources, etc.).

Si vous avez une autre interprétation ou un contexte spécifique en tête pour PMAO, n'hésitez pas à le préciser !

turns-00031.parquet:35930

9d32088adce7ca7c2d3e4713
turn 3/3gpt-4o-mini-2024-07-18FrenchDR Congo151 words
degenerate_repetitionAbsentFinal dense release
USER
Que veut dire PMAO
ASSISTANT
L'acronyme PMAO peut avoir plusieurs significations selon le contexte dans lequel il est utilisé. Voici quelques interprétations possibles :

1. **PMAO - Production et Management Assistés par Ordinateur** : Cela fait référence aux systèmes informatiques et logiciels utilisés pour aider à la conception, la planification et la gestion de la production dans des domaines comme l'ingénierie, l'architecture et l'industrie.

2. **PMAO - Programmation Multi-Objectif** : Dans le cadre de l'optimisation et de la recherche opérationnelle, cela désigne des techniques qui permettent de résoudre des problèmes en tenant compte de plusieurs objectifs simultanément.

3. **PMAO - Plan de Maîtrise et d'Assurance de la Qualité Opérationnelle** : Dans le domaine de la qualité, cela peut faire référence à des processus et des stratégies pour assurer et maîtriser la qualité d'un produit ou d'un service.

Si vous avez un contexte particulier en tête, je pourrais fournir une réponse plus ciblée.

turns-00031.parquet:35931

8d683a92099a5458144bcd0d
turn 1/1o1-mini-2024-09-12RussianRussia311 words
degenerate_repetitionAbsentFinal dense release
USER
(2n)!<2^2n*(n!)^2

докажи через матиндукцию
ASSISTANT
Давайте докажем неравенство
\[
(2n)! < 2^{2n} \cdot (n!)^2
\]
с помощью математической индукции.

**База индукции (n = 1):**

Проверим неравенство для \( n = 1 \):
\[
(2 \cdot 1)! = 2! = 2
\]
\[
2^{2 \cdot 1} \cdot (1!)^2 = 4 \cdot 1 = 4
\]
Поскольку \( 2 < 4 \), база индукции выполняется.

**Шаг индукции:**

Предположим, что для некоторого \( n = k \) верно:
\[
(2k)! < 2^{2k} \cdot (k!)^2
\]
Нужно показать, что это неравенство выполняется для \( n = k + 1 \), то есть:
\[
(2(k+1))! < 2^{2(k+1)} \cdot ((k+1)!)^2
\]

Рассмотрим левую часть неравенства для \( n = k + 1 \):
\[
(2(k+1))! = (2k + 2)! = (2k + 2)(2k + 1)(2k)!
\]
Используя предположение индукции, получаем:
\[
(2k + 2)(2k + 1)(2k)! < (2k + 2)(2k + 1) \cdot 2^{2k} \cdot (k!)^2
\]

Теперь рассмотрим правую часть для \( n = k + 1 \):
\[
2^{2(k+1)} \cdot ((k+1)!)^2 = 2^{2k + 2} \cdot (k+1)^2 \cdot (k!)^2 = 4 \cdot 2^{2k} \cdot (k+1)^2 \cdot (k!)^2
\]

Нам необходимо показать, что:
\[
(2k + 2)(2k + 1) \cdot 2^{2k} \cdot (k!)^2 < 4 \cdot 2^{2k} \cdot (k+1)^2 \cdot (k!)^2
\]

Сократим обе части на \( 2^{2k} \cdot (k!)^2 \) (поскольку они положительны):
\[
(2k + 2)(2k + 1) < 4(k + 1)^2
\]
Раскроем скобки:
\[
4k^2 + 6k + 2 < 4k^2 + 8k + 4
\]
Упростим:
\[
4k^2 + 6k + 2 - 4k^2 - 8k - 4 < 0 \implies -2k - 2 < 0
\]
Что эквивалентно:
\[
2k + 2 > 0
\]
Это неравенство верно для всех \( k \geq 1 \).

Таким образом, шаг индукции выполнен.

**Вывод:**

По принципу математической индукции, неравенство
\[
(2n)! < 2^{2n} \cdot (n!)^2
\]
выполняется для всех натуральных чисел \( n \).

turns-00031.parquet:35932

61b94cdf3adcd6e978edbdc3
turn 1/1o1-preview-2024-09-12EnglishGermany1151 words
degenerate_repetitionAbsentFinal dense release
USER
Use the highest quality scaling available in opencv instead of imagemagick: def resize_images(input_folder: Path, output_folder: Path, image_processor: 'ImageProcessor'):
    """Resize images in the input folder and save them to the output folder."""
    try:
        check_executable(Config.IMAGEMAGICK, "ImageMagick")
    except FileNotFoundError as e:
        log_error(str(e))
        return

    tasks = [input_path for input_path in input_folder.rglob('*') 
             if input_path.is_file() and input_path.suffix.lower() in Config.IMAGE_EXTENSIONS]

    if not tasks:
        log_error(f"No image files found in '{input_folder}'")
        return

    with create_temp_folder() as temp_folder:
        run_with_thread_pool(tasks, process_file, time.time(), len(tasks), image_processor, temp_folder, True)

def resize_image(input_path: Path, output_path: Path) -> Path:
    """Resize an image using ImageMagick."""
    output_path = output_path.with_suffix('.png')
    
    identify_command = [
        str(Config.IMAGEMAGICK),
        str(input_path),
        '-format', '%wx%h',
        'info:'
    ]
    try:
        result = subprocess.run(
            identify_command, 
            stdout=subprocess.PIPE, 
            stderr=subprocess.PIPE, 
            text=True, 
            check=True
        )
        current_width, current_height = map(int, result.stdout.strip().split('x'))
    except subprocess.CalledProcessError as e:
        log_error(f"ImageMagick identify failed for {input_path}: {e.stderr.strip()}")
        return output_path

    resize_mode = app.RESIZE_MODE.get()
    maintain_aspect = app.maintain_aspect_ratio.get()
    
    if resize_mode == "Fit":
        target_width = int(app.RESIZE_WIDTH.get() or 0)
        target_height = int(app.RESIZE_HEIGHT.get() or 0)
        
        if maintain_aspect:
            if target_width == 0 and target_height > 0:
                target_width = int(target_height * current_width / current_height)
            elif target_height == 0 and target_width > 0:
                target_height = int(target_width * current_height / current_width)
        
        resize_arg = f'{target_width}x{target_height}!'
    else:  # Shortest Side
        target_size = int(app.RESIZE_SIDE.get())
        resize_arg = f'{target_size}x{target_size}^'

    is_upscaling = (
        (resize_mode == "Fit" and (target_width > current_width or target_height > current_height)) or
        (resize_mode == "Shortest Side" and target_size > min(current_width, current_height))
    )

    command = [
        str(Config.IMAGEMAGICK),
        str(input_path),
    ]
    
    if is_upscaling:
        command += [
            '-filter', 'LanczosSharp',
            '-distort', 'Resize', resize_arg,
        ]
    else:
        command += [
            '-colorspace', 'RGB',
            '-filter', 'Lanczos2Sharp',
            '-resize', resize_arg,
            '-colorspace', 'sRGB',
        ]
    
    command += [
        '-define', 'png:compression-level=5',
        str(output_path)
    ]
    
    try:
        result = subprocess.run(
            command,
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE,
            text=True,
            check=True
        )
        if result.stderr:
            log_error(f"ImageMagick: {result.stderr.strip()}")
    except subprocess.CalledProcessError as e:
        log_error(f"ImageMagick resize failed for {input_path}: {e.stderr.strip()}")
    
    return output_path
ASSISTANT
To use OpenCV with the highest quality scaling instead of ImageMagick, you can modify your `resize_image` function to utilize OpenCV's `cv2.resize` function with the `cv2.INTER_LANCZOS4` interpolation method. This interpolation mode provides high-quality results suitable for both upscaling and downscaling images.

Here's the updated code:

```python
import cv2
import time
from pathlib import Path

def resize_images(input_folder: Path, output_folder: Path, image_processor: 'ImageProcessor'):
    """Resize images in the input folder and save them to the output folder using OpenCV."""
    tasks = [input_path for input_path in input_folder.rglob('*') 
             if input_path.is_file() and input_path.suffix.lower() in Config.IMAGE_EXTENSIONS]

    if not tasks:
        log_error(f"No image files found in '{input_folder}'")
        return

    with create_temp_folder() as temp_folder:
        run_with_thread_pool(tasks, process_file, time.time(), len(tasks), image_processor, temp_folder, True)

def resize_image(input_path: Path, output_path: Path) -> Path:
    """Resize an image using OpenCV with high-quality scaling."""
    output_path = output_path.with_suffix('.png')
    
    # Load the image
    image = cv2.imread(str(input_path))
    if image is None:
        log_error(f"Failed to read image {input_path}")
        return output_path

    current_height, current_width = image.shape[:2]

    resize_mode = app.RESIZE_MODE.get()
    maintain_aspect = app.maintain_aspect_ratio.get()
    
    if resize_mode == "Fit":
        target_width = int(app.RESIZE_WIDTH.get() or 0)
        target_height = int(app.RESIZE_HEIGHT.get() or 0)
        
        if maintain_aspect:
            # Calculate target dimensions while maintaining aspect ratio
            if target_width == 0 and target_height > 0:
                target_width = int(target_height * current_width / current_height)
            elif target_height == 0 and target_width > 0:
                target_height = int(target_width * current_height / current_width)
            else:
                # Adjust target dimensions to maintain aspect ratio
                aspect_ratio = current_width / current_height
                if (target_width / target_height) > aspect_ratio:
                    target_width = int(target_height * aspect_ratio)
                else:
                    target_height = int(target_width / aspect_ratio)
        else:
            # If not maintaining aspect ratio, ensure dimensions are not zero
            if target_width == 0:
                target_width = current_width
            if target_height == 0:
                target_height = current_height

        # Resize the image using high-quality interpolation
        resized_image = cv2.resize(
            image, 
            (target_width, target_height), 
            interpolation=cv2.INTER_LANCZOS4
        )
    else:  # Shortest Side
        target_size = int(app.RESIZE_SIDE.get())

        aspect_ratio = current_width / current_height
        if current_width < current_height:
            # Width is the shorter side
            target_width = target_size
            target_height = int(target_size / aspect_ratio)
        else:
            # Height is the shorter side
            target_height = target_size
            target_width = int(target_size * aspect_ratio)
        
        if maintain_aspect:
            resized_image = cv2.resize(
                image, 
                (target_width, target_height), 
                interpolation=cv2.INTER_LANCZOS4
            )
        else:
            # Resize without maintaining aspect ratio
            resized_image = cv2.resize(
                image, 
                (target_size, target_size), 
                interpolation=cv2.INTER_LANCZOS4
            )
    
    # Save the resized image with compression
    # For PNG, the compression level ranges from 0 (no compression) to 9 (maximum compression)
    compression_params = [cv2.IMWRITE_PNG_COMPRESSION, 5]
    success = cv2.imwrite(str(output_path), resized_image, compression_params)
    if not success:
        log_error(f"Failed to write image {output_path}")

    return output_path
```

**Explanation:**

- **Image Loading:**
  - The image is read using `cv2.imread()`. If the image cannot be loaded, an error is logged, and the function returns.

- **Current Dimensions:**
  - The current width and height of the image are obtained from the shape of the NumPy array.

- **Resize Mode Handling:**
  - The code checks the `resize_mode` from the application settings (`app.RESIZE_MODE.get()`), which can be either `"Fit"` or `"Shortest Side"`.

- **Maintain Aspect Ratio:**
  - If `maintain_aspect` is `True`, the target dimensions are adjusted to maintain the original aspect ratio.
  - Calculations are made to ensure that neither the width nor the height is zero and that the aspect ratio is preserved.

- **Resizing the Image:**
  - The `cv2.resize()` function resizes the image to the calculated dimensions.
  - `interpolation=cv2.INTER_LANCZOS4` is used for high-quality resizing, which is particularly good for reducing aliasing artifacts in both upscaling and downscaling scenarios.

- **Saving the Image:**
  - The resized image is saved in PNG format using `cv2.imwrite()`.
  - A compression level of 5 is set for a balance between file size and quality (`cv2.IMWRITE_PNG_COMPRESSION, 5`).
  - If saving fails, an error is logged.

**Additional Notes:**

- **Install OpenCV:**
  - Ensure that OpenCV is installed in your Python environment:
    ```bash
    pip install opencv-python
    ```

- **Dependencies and Definitions:**
  - The code assumes that the functions and variables like `log_error`, `Config`, `app`, `create_temp_folder`, `run_with_thread_pool`, and `process_file` are defined elsewhere in your codebase.
  - Replace these placeholders with your actual implementations.

- **Application Settings (`app`):**
  - It is assumed that `app` is an object or module that contains the application's settings and configurations.
  - Methods like `app.RESIZE_MODE.get()` and `app.RESIZE_WIDTH.get()` should return the appropriate values.

- **Handling Zero Dimensions:**
  - The code includes checks to handle cases where the target width or height may be zero, defaulting to the original dimensions if necessary.

- **Performance Considerations:**
  - While `cv2.INTER_LANCZOS4` offers high-quality results, it is computationally more intensive than simpler interpolation methods. If performance becomes an issue with large images or a high volume of images, you might consider using `cv2.INTER_CUBIC` or `cv2.INTER_AREA` as alternatives.

- **Compression Parameters:**
  - Adjust the compression level in `compression_params` if you need smaller file sizes or higher quality.

**Example Usage:**

Assuming you have an `ImageProcessor` class and the necessary environment, you can call `resize_images` like this:

```python
input_folder = Path('/path/to/input/images')
output_folder = Path('/path/to/output/images')
image_processor = ImageProcessor()

resize_images(input_folder, output_folder, image_processor)
```

This will process all images in the `input_folder`, resize them according to the specified settings, and save them to the `output_folder`.

**Conclusion:**

By switching to OpenCV and using the `cv2.INTER_LANCZOS4` interpolation method, you can achieve high-quality image resizing without relying on external tools like ImageMagick. This approach simplifies your dependency management and can lead to performance improvements, especially when processing a large number of images.

---

Feel free to adjust the code further to suit your specific application needs or to integrate additional features.

turns-00031.parquet:35933

6d8c7b2d73da3420e2db071b
turn 1/5gpt-4o-2024-08-06PersianAustralia370 words
degenerate_repetitionAbsentFinal dense release
USER
چاقی عبارت است از تجمع غیر طبیعی و بیش از اندازه توده چربی در بدن به طوری که سلامتی فرد را به خطر بیندازد.
اضافی،
اگر چربی های اضافی، بیشتر در ناحیه شکم متمرکز شده باشد، الگوی چاقی فرد شبیه به سیب است و به آن الگوی سیب میگویند. این الگو در بین مردان شایع تر است. اگر چربی بیشتر در ناحیه باسن و رانها متمرکز شده باشد الگوی چاقی شبیه گلابی است و آن را «الگوی گلابی» می گویند این الگو در بین زنان شایع تر
است. چاقی با الگوی سیب (در مقایسه با الگوی گلابی خطر ابتلا به بیماری های قلبی عروقی را
بیشتر افزایش میدهد
عوامل چاقی عامل ژنتیک: بروز چاقی در فرزندان و سایر نزدیکان افراد چاق حکایت از زمینه ژنتیکی چاقی در آنها دارد. عامل محیطی : نحوه زندگی به ویژه عادتهای غذایی و میزان فعالیت بدنی افراد عامل مهمی در اضافه وزن و چاقی محسوب می شود. عامل روانی : اختلالات روانی مانند افسردگی افراد را مستعد ابتلا به چاقی می کند. به علاوه عوامل روانی
سبب می شود که برخی افراد در شرایطی مانند ،اضطراب خشم و ناراحتی بیش از حد غذا بخورند. بیماریهای جسمی برخی بیماری ها نظیر کم کاری تیروئید و کوشینگ اختلال عملکرد غدد فوق کلیوی) موجب بروز چاقی میشوند
داروها: برخی داروها مثل کورتون موجب چاقی میشوند

============================

متن بالا را مایند مپ کن
                            
                            
ASSISTANT
برای ایجاد یک مایند مپ از متن ارائه شده، می‌توانیم به صورت زیر عمل کنیم:

مرکز مایند مپ: **چاقی**

1. **تعریف چاقی**
   - تجمع غیر طبیعی و زیاد چربی
   - تهدید سلامتی

2. **الگوهای چاقی**
   - **الگوی سیب** 
     - تمرکز چربی در ناحیه شکم
     - شایع‌تر در مردان
     - افزایش خطر بیماری‌های قلبی عروقی
   - **الگوی گلابی**
     - تمرکز چربی در باسن و ران‌ها
     - شایع‌تر در زنان

3. **عوامل چاقی**
   - **عامل ژنتیک**
     - سابقه خانوادگی و زمینه ژنتیکی
   - **عامل محیطی**
     - عادت‌های غذایی
     - فعالیت بدنی
   - **عامل روانی**
     - اختلالات روانی مانند افسردگی
     - خوردن بیش از حد در شرایط اضطراب و خشم
   - **بیماری‌های جسمی**
     - کم‌کاری تیروئید
     - سندرم کوشینگ
   - **داروها**
     - داروهایی مانند کورتون

این ساختار به شما کمک می‌کند تا نکات اصلی و مهم متن را به صورت سازماندهی شده و تصویری در اختیار داشته باشید.