Uncaught (in promise) ReferenceError: defaultConfig is not defined.
---
// manifest.json
{
  "manifest_version": 3,
  "name": "Advanced CORS Handler",
  "version": "1.1",
  "description": "Powerful CORS handling with full customization for development",
  "permissions": [
    "declarativeNetRequest",
    "activeTab",
    "storage"
  ],
  "host_permissions": [
    "<all_urls>"
  ],
  "action": {
    "default_popup": "popup.html",
    "default_icon": {
      "16": "icons/icon16-off.png",
      "48": "icons/icon48-off.png",
      "128": "icons/icon128-off.png"
    }
  },
  "background": {
    "service_worker": "background.js"
  },
  "icons": {
    "16": "icons/icon16-off.png",
    "48": "icons/icon48-off.png",
    "128": "icons/icon128-off.png"
  }
}

// popup.html
<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>CORS Handler Settings</title>
  <link rel="stylesheet" href="popup.css">
</head>
<body>
  <div class="container">
    <div class="header">
      <h2>CORS Handler</h2>
      <div class="toggle-container">
        <label class="switch">
          <input type="checkbox" id="globalToggle">
          <span class="slider"></span>
        </label>
        <span id="statusText">Disabled</span>
      </div>
    </div>

    <div class="settings-container">
      <div class="tab-container">
        <button class="tab-button active" data-tab="response">Response Headers</button>
        <button class="tab-button" data-tab="request">Request Headers</button>
        <button class="tab-button" data-tab="rules">URL Rules</button>
      </div>

      <div class="tab-content active" id="response">
        <div class="header-list" id="responseHeaders">
          <!-- Dynamically populated -->
        </div>
        <button class="add-header" id="addResponseHeader">+ Add Response Header</button>
      </div>

      <div class="tab-content" id="request">
        <div class="header-list" id="requestHeaders">
          <!-- Dynamically populated -->
        </div>
        <button class="add-header" id="addRequestHeader">+ Add Request Header</button>
      </div>

      <div class="tab-content" id="rules">
        <div class="url-rules" id="urlRules">
          <!-- Dynamically populated -->
        </div>
        <button class="add-rule" id="addUrlRule">+ Add URL Rule</button>
      </div>
    </div>

    <div class="footer">
      <button id="saveButton">Save Changes</button>
      <button id="resetDefault">Reset to Default</button>
    </div>
  </div>
  <script src="popup.js"></script>
</body>
</html>

// popup.css
.container {
  width: 400px;
  padding: 16px;
  font-family: -apple-system, system-ui, BlinkMacSystemFont, "Segoe UI", Roboto;
}

.header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20px;
}

.toggle-container {
  display: flex;
  align-items: center;
  gap: 8px;
}

.switch {
  position: relative;
  display: inline-block;
  width: 48px;
  height: 24px;
}

.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: .4s;
  border-radius: 24px;
}

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

input:checked + .slider {
  background-color: #2196F3;
}

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

.tab-container {
  display: flex;
  gap: 8px;
  margin-bottom: 16px;
}

.tab-button {
  padding: 8px 16px;
  border: none;
  background: #f0f0f0;
  cursor: pointer;
  border-radius: 4px;
}

.tab-button.active {
  background: #2196F3;
  color: white;
}

.tab-content {
  display: none;
  padding: 16px;
  background: #f8f8f8;
  border-radius: 4px;
}

.tab-content.active {
  display: block;
}

.header-item {
  display: flex;
  gap: 8px;
  margin-bottom: 12px;
  align-items: center;
}

.header-item input[type="text"] {
  padding: 6px;
  border: 1px solid #ddd;
  border-radius: 4px;
}

.header-item select {
  padding: 6px;
  border: 1px solid #ddd;
  border-radius: 4px;
}

.remove-button {
  padding: 4px 8px;
  background: #ff4444;
  color: white;
  border: none;
  border-radius: 4px;
  cursor: pointer;
}

.add-header, .add-rule {
  width: 100%;
  padding: 8px;
  margin-top: 12px;
  background: #2196F3;
  color: white;
  border: none;
  border-radius: 4px;
  cursor: pointer;
}

.footer {
  margin-top: 20px;
  display: flex;
  justify-content: space-between;
}

.footer button {
  padding: 8px 16px;
  border: none;
  border-radius: 4px;
  cursor: pointer;
}

#saveButton {
  background: #4CAF50;
  color: white;
}

#resetDefault {
  background: #f0f0f0;
}

// popup.js
let defaultConfig = {
  enabled: false,
  responseHeaders: [
    { name: "Access-Control-Allow-Origin", value: "*", enabled: true },
    { name: "Access-Control-Allow-Methods", value: "GET, PUT, POST, DELETE, HEAD, OPTIONS, PATCH", enabled: true },
    { name: "Access-Control-Allow-Headers", value: "*", enabled: true },
    { name: "Access-Control-Allow-Credentials", value: "true", enabled: true },
    { name: "Access-Control-Expose-Headers", value: "*", enabled: true },
    { name: "Access-Control-Max-Age", value: "1728000", enabled: true },
    { name: "Cross-Origin-Resource-Policy", value: "cross-origin", enabled: true },
    { name: "Cross-Origin-Embedder-Policy", value: "credentialless", enabled: true }
  ],
  requestHeaders: [
    { name: "Origin", value: "https://allowed-origin.com", enabled: true },
    { name: "Access-Control-Request-Method", value: "*", enabled: true },
    { name: "Access-Control-Request-Headers", value: "*", enabled: true }
  ],
  urlRules: [
    { pattern: "*", enabled: true }
  ]
};

let currentConfig = null;

// Load configuration
async function loadConfig() {
  try {
    const result = await chrome.storage.local.get('corsConfig');
    currentConfig = result.corsConfig || JSON.parse(JSON.stringify(defaultConfig));
    renderUI();
  } catch (error) {
    console.error('Error loading configuration:', error);
    currentConfig = JSON.parse(JSON.stringify(defaultConfig));
  }
}

// Save configuration
async function saveConfig() {
  try {
    await chrome.storage.local.set({ corsConfig: currentConfig });
    await updateExtensionRules();
    showSaveSuccess();
  } catch (error) {
    console.error('Error saving configuration:', error);
    showSaveError();
  }
}

// Update extension rules
async function updateExtensionRules() {
  const message = {
    type: 'updateRules',
    config: currentConfig
  };
  await chrome.runtime.sendMessage(message);
}

// UI Rendering
function renderUI() {
  const globalToggle = document.getElementById('globalToggle');
  globalToggle.checked = currentConfig.enabled;
  document.getElementById('statusText').textContent = currentConfig.enabled ? 'Enabled' : 'Disabled';

  renderHeaderList('responseHeaders');
  renderHeaderList('requestHeaders');
  renderUrlRules();
}

function renderHeaderList(type) {
  const container = document.getElementById(type);
  container.innerHTML = '';

  currentConfig[type].forEach((header, index) => {
    const headerItem = createHeaderItem(header, index, type);
    container.appendChild(headerItem);
  });
}

function createHeaderItem(header, index, type) {
  const div = document.createElement('div');
  div.className = 'header-item';

  const enabledCheckbox = document.createElement('input');
  enabledCheckbox.type = 'checkbox';
  enabledCheckbox.checked = header.enabled;
  enabledCheckbox.onchange = () => {
    currentConfig[type][index].enabled = enabledCheckbox.checked;
  };

  const nameInput = document.createElement('input');
  nameInput.type = 'text';
  nameInput.value = header.name;
  nameInput.placeholder = 'Header Name';
  nameInput.onchange = () => {
    currentConfig[type][index].name = nameInput.value;
  };

  const valueInput = document.createElement('input');
  valueInput.type = 'text';
  valueInput.value = header.value;
  valueInput.placeholder = 'Header Value';
  valueInput.onchange = () => {
    currentConfig[type][index].value = valueInput.value;
  };

  const removeButton = document.createElement('button');
  removeButton.textContent = '×';
  removeButton.className = 'remove-button';
  removeButton.onclick = () => {
    currentConfig[type].splice(index, 1);
    renderHeaderList(type);
  };

  div.appendChild(enabledCheckbox);
  div.appendChild(nameInput);
  div.appendChild(valueInput);
  div.appendChild(removeButton);

  return div;
}

function renderUrlRules() {
  const container = document.getElementById('urlRules');
  container.innerHTML = '';

  currentConfig.urlRules.forEach((rule, index) => {
    const ruleItem = createUrlRuleItem(rule, index);
    container.appendChild(ruleItem);
  });
}

function createUrlRuleItem(rule, index) {
  const div = document.createElement('div');
  div.className = 'header-item';

  const enabledCheckbox = document.createElement('input');
  enabledCheckbox.type = 'checkbox';
  enabledCheckbox.checked = rule.enabled;
  enabledCheckbox.onchange = () => {
    currentConfig.urlRules[index].enabled = enabledCheckbox.checked;
  };

  const patternInput = document.createElement('input');
  patternInput.type = 'text';
  patternInput.value = rule.pattern;
  patternInput.placeholder = 'URL Pattern (e.g., *://*.example.com/*)';
  patternInput.onchange = () => {
    currentConfig.urlRules[index].pattern = patternInput.value;
  };

  const removeButton = document.createElement('button');
  removeButton.textContent = '×';
  removeButton.className = 'remove-button';
  removeButton.onclick = () => {
    currentConfig.urlRules.splice(index, 1);
    renderUrlRules();
  };

  div.appendChild(enabledCheckbox);
  div.appendChild(patternInput);
  div.appendChild(removeButton);

  return div;
}

// Event Handlers
document.getElementById('globalToggle').addEventListener('change', async (e) => {
  currentConfig.enabled = e.target.checked;
  document.getElementById('statusText').textContent = currentConfig.enabled ? 'Enabled' : 'Disabled';
  await saveConfig();
});

document.getElementById('addResponseHeader').addEventListener('click', () => {
  currentConfig.responseHeaders.push({ name: '', value: '', enabled: true });
  renderHeaderList('responseHeaders');
});

document.getElementById('addRequestHeader').addEventListener('click', () => {
  currentConfig.requestHeaders.push({ name: '', value: '', enabled: true });
  renderHeaderList('requestHeaders');
});

document.getElementById('addUrlRule').addEventListener('click', () => {
  currentConfig.urlRules.push({ pattern: '*', enabled: true });
  renderUrlRules();
});

document.getElementById('saveButton').addEventListener('click', saveConfig);

document.getElementById('resetDefault').addEventListener('click', () => {
  currentConfig = JSON.parse(JSON.stringify(defaultConfig));
  renderUI();
  saveConfig();
});

// Tab Handling
document.querySelectorAll('.tab-button').forEach(button => {
  button.addEventListener('click', () => {
    document.querySelectorAll('.tab-button').forEach(b => b.classList.remove('active'));
    document.querySelectorAll('.tab-content').forEach(c => c.classList.remove('active'));
    button.classList.add('active');
    document.getElementById(button.dataset.tab).classList.add('active');
  });
});

// Initialize
document.addEventListener('DOMContentLoaded', loadConfig);

// background.js
let currentRules = [];
const RULE_ID_START = 1;

chrome.runtime.onMessage.addListener(async (message, sender, sendResponse) => {
  if (message.type === 'updateRules') {
    await updateRules(message.config);
  }
});

async function updateRules(config) {
  try {
    // Remove existing rules
    const existingRules = await chrome.declarativeNetRequest.getDynamicRules();
    const ruleIdsToRemove = existingRules.map(rule => rule.id);
    await chrome.declarativeNetRequest.updateDynamicRules({
      removeRuleIds: ruleIdsToRemove,
      addRules: []
    });

    if (!config.enabled) {
      await updateIcon(false);
      return;
    }

    // Create new rules
    const newRules = createRulesFromConfig(config);
    await chrome.declarativeNetRequest.updateDynamicRules({
      addRules: newRules
    });

    await updateIcon(true);
  } catch (error) {
    console.error('Error updating rules:', error);
  }
}

// background.js (continued)
function createRulesFromConfig(config) {
  const rules = [];
  let ruleId = RULE_ID_START;

  config.urlRules.forEach(urlRule => {
    if (!urlRule.enabled) return;

    const responseHeadersToModify = config.responseHeaders
      .filter(header => header.enabled)
      .map(header => ({
        header: header.name,
        operation: "set",
        value: header.value
      }));

    const requestHeadersToModify = config.requestHeaders
      .filter(header => header.enabled)
      .map(header => ({
        header: header.name,
        operation: "set",
        value: header.value
      }));

    rules.push({
      id: ruleId++,
      priority: 1,
      action: {
        type: "modifyHeaders",
        responseHeaders: responseHeadersToModify,
        requestHeaders: requestHeadersToModify
      },
      condition: {
        urlFilter: urlRule.pattern,
        resourceTypes: [
          "xmlhttprequest",
          "fetch",
          "websocket",
          "other",
          "main_frame",
          "sub_frame",
          "script",
          "image",
          "stylesheet",
          "font"
        ]
      }
    });
  });

  return rules;
}

async function updateIcon(enabled) {
  const iconState = enabled ? "-on" : "-off";
  await chrome.action.setIcon({
    path: {
      "16": `icons/icon16${iconState}.png`,
      "48": `icons/icon48${iconState}.png`,
      "128": `icons/icon128${iconState}.png`
    }
  });
}

// Initialize extension state
chrome.runtime.onInstalled.addListener(async () => {
  // Load or create default configuration
  const result = await chrome.storage.local.get('corsConfig');
  const config = result.corsConfig || defaultConfig;
  await chrome.storage.local.set({ corsConfig: config });
  await updateRules(config);
});

// utils.js
function showSaveSuccess() {
  const saveButton = document.getElementById('saveButton');
  const originalText = saveButton.textContent;
  saveButton.textContent = '✓ Saved';
  saveButton.style.backgroundColor = '#4CAF50';
  
  setTimeout(() => {
    saveButton.textContent = originalText;
    saveButton.style.backgroundColor = '';
  }, 2000);
}

function showSaveError() {
  const saveButton = document.getElementById('saveButton');
  const originalText = saveButton.textContent;
  saveButton.textContent = '× Error';
  saveButton.style.backgroundColor = '#ff4444';
  
  setTimeout(() => {
    saveButton.textContent = originalText;
    saveButton.style.backgroundColor = '';
  }, 2000);
}

// Add these helper functions to handle complex header scenarios
function validateHeaderValue(headerName, value) {
  // Special handling for certain headers
  const specialHeaders = {
    'Access-Control-Allow-Origin': ['*', 'null', ...customOriginValidation],
    'Access-Control-Allow-Methods': ['*', 'GET', 'POST', 'PUT', 'DELETE', 'OPTIONS', 'PATCH', 'HEAD'],
    'Access-Control-Allow-Headers': ['*'],
    'Access-Control-Allow-Credentials': ['true', 'false'],
    'Access-Control-Max-Age': (value) => !isNaN(value) && parseInt(value) >= 0
  };

  if (specialHeaders[headerName]) {
    if (Array.isArray(specialHeaders[headerName])) {
      return specialHeaders[headerName].includes(value) || isValidCustomValue(headerName, value);
    } else {
      return specialHeaders[headerName](value);
    }
  }
  
  return true; // Allow custom headers by default
}

function customOriginValidation(value) {
  try {
    if (value === '*' || value === 'null') return true;
    new URL(value);
    return true;
  } catch {
    return false;
  }
}

function isValidCustomValue(headerName, value) {
  // Additional validation for custom values
  if (headerName === 'Access-Control-Allow-Methods') {
    const validMethods = ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS', 'PATCH', 'HEAD'];
    const methods = value.split(',').map(m => m.trim().toUpperCase());
    return methods.every(m => validMethods.includes(m));
  }
  
  if (headerName === 'Access-Control-Allow-Headers') {
    return value.split(',').every(h => /^[a-zA-Z0-9-]+$/.test(h.trim()));
  }
  
  return true;
}
---
fix it and send the fully working full fixed code.