Make this chrome extension 10 times better than before.

Don't over complex it.

Keep it straightforward but extremely powerful and customisable.

Increase the UX 10 times better than before.

Send the fully working production-ready chrome extension's full codes.

// background.js

let ruleIdCounter = 1000; // Start from 1000 to avoid conflicts

// Initialize storage with default settings if not present
chrome.runtime.onInstalled.addListener(() => {
  chrome.storage.sync.get(["corsSettings"], (result) => {
    if (!result.corsSettings) {
      const defaultSettings = getDefaultSettings();
      chrome.storage.sync.set({ corsSettings: defaultSettings }, () => {
        applyCORSRules(defaultSettings);
      });
    } else {
      applyCORSRules(result.corsSettings);
    }
  });
});

// Listen for changes in storage and update rules accordingly
chrome.storage.onChanged.addListener((changes, area) => {
  if (area === "sync" && changes.corsSettings) {
    applyCORSRules(changes.corsSettings.newValue);
  }
});

// Function to apply CORS rules based on settings
async function applyCORSRules(settings) {
  // Remove all existing rules added by this extension (rule IDs >= 1000)
  const existingRules = await chrome.declarativeNetRequest.getDynamicRules();
  const ruleIdsToRemove = existingRules
    .filter(rule => rule.ruleId >= 1000)
    .map(rule => rule.ruleId);

  if (ruleIdsToRemove.length > 0) {
    await chrome.declarativeNetRequest.updateDynamicRules({
      removeRuleIds: ruleIdsToRemove,
      addRules: []
    });
  }

  if (!settings.enabled) {
    return; // If extension is disabled, do not add new rules
  }

  const newRules = [];

  // Iterate over each custom header to create rules
  for (const [header, value] of Object.entries(settings.headers)) {
    // Validate header names and values if necessary

    const rule = {
      id: ruleIdCounter,
      priority: 1,
      action: {
        type: "modifyHeaders",
        responseHeaders: [
          { header: header, operation: "set", value: value }
        ]
      },
      condition: {
        urlFilter: "*", // Applies to all URLs
        resourceTypes: settings.applyTo.resourceTypes
      }
    };
    newRules.push(rule);
    ruleIdCounter++;
  }

  // Add new rules if any
  if (newRules.length > 0) {
    await chrome.declarativeNetRequest.updateDynamicRules({
      removeRuleIds: [],
      addRules: newRules
    });
  }
}

// Function to get default settings
function getDefaultSettings() {
  return {
    enabled: true,
    headers: {
      "Access-Control-Allow-Origin": "*",
      "Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, OPTIONS",
      "Access-Control-Allow-Headers": "Content-Type, Authorization",
      "Access-Control-Allow-Credentials": "true",
      "Access-Control-Expose-Headers": "Content-Length,Content-Range",
      "Access-Control-Max-Age": "86400"
    },
    applyTo: {
      domains: ["<all_urls>"],
      resourceTypes: [
        "main_frame",
        "sub_frame",
        "script",
        "xmlhttprequest",
        "image",
        "stylesheet",
        "font",
        "object",
        "media",
        "websocket"
      ]
      // Note: Removed "methods" as DNR does not support it
    }
  };
}

{
  "manifest_version": 3,
  "name": "CORS Modifier",
  "version": "1.0.4",
  "description": "Modify CORS headers to prevent CORS policy errors with extensive customization options.",
  "permissions": [
    "declarativeNetRequest",
    "declarativeNetRequestWithHostAccess",
    "storage",
    "activeTab",
    "scripting"
  ],
  "host_permissions": [
    "<all_urls>"
  ],
  "action": {
    "default_popup": "popup.html",
    "default_icon": {
      "16": "icons/icon16.png",
      "48": "icons/icon48.png",
      "128": "icons/icon128.png"
    }
  },
  "background": {
    "service_worker": "background.js"
  },
  "icons": {
    "16": "icons/icon16.png",
    "48": "icons/icon48.png",
    "128": "icons/icon128.png"
  }
}

/* popup.css */

body {
  font-family: Arial, sans-serif;
  width: 400px;
  margin: 0;
  padding: 10px;
  background-color: #f4f4f4;
}

.container {
  display: flex;
  flex-direction: column;
}

h1 {
  text-align: center;
}

.switch-container {
  display: flex;
  align-items: center;
  margin-bottom: 20px;
}

.switch {
  position: relative;
  display: inline-block;
  width: 50px;
  height: 24px;
  margin-right: 10px;
}

.switch input {
  opacity: 0;
  width: 0;
  height: 0;
}

.slider {
  position: absolute;
  cursor: pointer;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: #ccc;
  transition: 0.4s;
  border-radius: 24px;
}

.slider:before {
  position: absolute;
  content: "";
  height: 18px;
  width: 18px;
  left: 3px;
  bottom: 3px;
  background-color: white;
  transition: 0.4s;
  border-radius: 50%;
}

input:checked + .slider {
  background-color: #4caf50;
}

input:checked + .slider:before {
  transform: translateX(26px);
}

.section {
  margin-bottom: 20px;
}

.section h2 {
  margin-bottom: 10px;
}

.sub-section {
  margin-bottom: 10px;
}

#currentDomain {
  font-weight: bold;
}

textarea {
  width: 100%;
  height: 60px;
  resize: vertical;
}

select {
  width: 100%;
  height: 100px;
}

button {
  padding: 10px;
  background-color: #007bff;
  color: white;
  border: none;
  cursor: pointer;
  border-radius: 4px;
}

button:hover {
  background-color: #0056b3;
}

.header-row {
  display: flex;
  align-items: center;
  margin-bottom: 5px;
}

.header-row input {
  flex: 1;
  padding: 5px;
  margin-right: 5px;
}

.header-row button {
  padding: 5px 10px;
  background-color: #dc3545;
}

#addHeaderBtn {
  margin-top: 10px;
  background-color: #28a745;
}

<!-- popup.html -->
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>CORS Modifier</title>
  <link rel="stylesheet" href="popup.css">
</head>
<body>
  <div class="container">
    <h1>CORS Modifier</h1>
    
    <div class="switch-container">
      <label class="switch">
        <input type="checkbox" id="enableToggle">
        <span class="slider round"></span>
      </label>
      <span id="enableLabel">Enable</span>
    </div>

    <div class="section">
      <h2>Current Domain</h2>
      <p id="currentDomain">Loading...</p>
    </div>

    <div class="section">
      <h2>Custom Headers</h2>
      <div id="headersContainer">
        <!-- Dynamic Header Inputs -->
      </div>
      <button id="addHeaderBtn">Add Header</button>
    </div>

    <div class="section">
      <h2>Apply To</h2>
      <div class="sub-section">
        <h3>Domains</h3>
        <textarea id="domainsInput" placeholder="e.g., https://example.com/*"></textarea>
      </div>
      <div class="sub-section">
        <h3>Resource Types</h3>
        <select id="resourceTypesSelect" multiple>
          <option value="main_frame">Main Frame</option>
          <option value="sub_frame">Sub Frame</option>
          <option value="script">Script</option>
          <option value="xmlhttprequest">XMLHttpRequest</option>
          <option value="image">Image</option>
          <option value="stylesheet">Stylesheet</option>
          <option value="font">Font</option>
          <option value="object">Object</option>
          <option value="media">Media</option>
          <option value="websocket">WebSocket</option>
        </select>
      </div>
    </div>

    <button id="saveBtn">Save Settings</button>
  </div>

  <script src="popup.js"></script>
</body>
</html>

// popup.js

document.addEventListener('DOMContentLoaded', initializePopup);

async function initializePopup() {
  const enableToggle = document.getElementById('enableToggle');
  const saveBtn = document.getElementById('saveBtn');
  const currentDomainEl = document.getElementById('currentDomain');
  const headersContainer = document.getElementById('headersContainer');
  const addHeaderBtn = document.getElementById('addHeaderBtn');
  const domainsInput = document.getElementById('domainsInput');
  const resourceTypesSelect = document.getElementById('resourceTypesSelect');

  // Load settings
  chrome.storage.sync.get(['corsSettings'], (result) => {
    const settings = result.corsSettings || getDefaultSettings();
    enableToggle.checked = settings.enabled;

    // Populate headers
    headersContainer.innerHTML = '';
    for (const [header, value] of Object.entries(settings.headers)) {
      addHeaderRow(header, value);
    }

    // Populate applyTo settings
    domainsInput.value = settings.applyTo.domains.join('\n');
    setSelectOptions(resourceTypesSelect, settings.applyTo.resourceTypes);
  });

  // Get current active tab's domain
  chrome.tabs.query({ active: true, currentWindow: true }, (tabs) => {
    if (tabs.length > 0) {
      const tab = tabs[0];
      try {
        const url = new URL(tab.url);
        currentDomainEl.textContent = url.origin;
      } catch (e) {
        currentDomainEl.textContent = "N/A";
      }
    } else {
      currentDomainEl.textContent = "N/A";
    }
  });

  // Toggle switch handler
  enableToggle.addEventListener('change', () => {
    saveSettings();
  });

  // Add header button handler
  addHeaderBtn.addEventListener('click', () => {
    addHeaderRow('', '');
  });

  // Save button handler
  saveBtn.addEventListener('click', () => {
    saveSettings();
  });

  // Function to add a header row
  function addHeaderRow(header, value) {
    const row = document.createElement('div');
    row.className = 'header-row';

    const headerInput = document.createElement('input');
    headerInput.type = 'text';
    headerInput.placeholder = 'Header';
    headerInput.value = header;

    const valueInput = document.createElement('input');
    valueInput.type = 'text';
    valueInput.placeholder = 'Value';
    valueInput.value = value;

    const removeBtn = document.createElement('button');
    removeBtn.textContent = 'Remove';
    removeBtn.addEventListener('click', () => {
      headersContainer.removeChild(row);
    });

    row.appendChild(headerInput);
    row.appendChild(valueInput);
    row.appendChild(removeBtn);

    headersContainer.appendChild(row);
  }

  // Function to set selected options in multi-select
  function setSelectOptions(selectElement, selectedValues) {
    for (let option of selectElement.options) {
      option.selected = selectedValues.includes(option.value);
    }
  }

  // Function to save settings
  function saveSettings() {
    const enabled = enableToggle.checked;

    // Gather headers
    const headers = {};
    const headerRows = headersContainer.querySelectorAll('.header-row');
    headerRows.forEach(row => {
      const inputs = row.querySelectorAll('input');
      const header = inputs[0].value.trim();
      const value = inputs[1].value.trim();
      if (header && value) {
        headers[header] = value;
      }
    });

    // Gather applyTo settings
    const domainsRaw = domainsInput.value.trim();
    const domains = domainsRaw ? domainsRaw.split('\n').map(d => d.trim()).filter(d => d !== '') : ["<all_urls>"];
    const resourceTypes = Array.from(resourceTypesSelect.selectedOptions).map(opt => opt.value);

    // Validate resource types
    const allowedResourceTypes = [
      "csp_report",
      "font",
      "image",
      "main_frame",
      "media",
      "object",
      "ping",
      "script",
      "stylesheet",
      "sub_frame",
      "webbundle",
      "websocket",
      "webtransport",
      "xmlhttprequest"
    ];
    const invalidResourceTypes = resourceTypes.filter(rt => !allowedResourceTypes.includes(rt));
    if (invalidResourceTypes.length > 0) {
      alert(`Invalid resource types detected: ${invalidResourceTypes.join(', ')}. Please remove or correct them.`);
      return;
    }

    const newSettings = {
      enabled: enabled,
      headers: headers,
      applyTo: {
        domains: domains.length > 0 ? domains : ["<all_urls>"],
        resourceTypes: resourceTypes.length > 0 ? resourceTypes : ["main_frame", "sub_frame", "script", "xmlhttprequest", "image", "stylesheet", "font", "object", "media", "websocket"]
      }
    };

    chrome.storage.sync.set({ corsSettings: newSettings }, () => {
      alert("Settings saved successfully!");
    });
  }

  // Function to get default settings
  function getDefaultSettings() {
    return {
      enabled: true,
      headers: {
        "Access-Control-Allow-Origin": "*",
        "Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, OPTIONS",
        "Access-Control-Allow-Headers": "Content-Type, Authorization",
        "Access-Control-Allow-Credentials": "true",
        "Access-Control-Expose-Headers": "Content-Length,Content-Range",
        "Access-Control-Max-Age": "86400"
      },
      applyTo: {
        domains: ["<all_urls>"],
        resourceTypes: [
          "main_frame",
          "sub_frame",
          "script",
          "xmlhttprequest",
          "image",
          "stylesheet",
          "font",
          "object",
          "media",
          "websocket"
        ]
      }
    };
  }
}