Implementing the "Do Not Sell" Requirement

Implementing the "Do Not Sell" Requirement

CCPA's signature requirement mandates a clear and conspicuous "Do Not Sell My Personal Information" link on the homepage and any page where personal information is collected. This opt-out mechanism must be easy to use and cannot require account creation. The implementation must respect user choice across sessions and devices, requiring sophisticated tracking and preference management systems.

// Do Not Sell implementation
class DoNotSellManager {
  constructor() {
    this.optOutCookie = 'ccpa_opt_out';
    this.optOutDuration = 365 * 24 * 60 * 60 * 1000; // 1 year
    this.optOutDatabase = new OptOutDatabase();
  }

  // Initialize Do Not Sell functionality
  init() {
    this.renderDoNotSellLink();
    this.checkOptOutStatus();
    this.setupGlobalPrivacyControl();
  }

  // Render Do Not Sell link
  renderDoNotSellLink() {
    const link = document.createElement('a');
    link.href = '/privacy/do-not-sell';
    link.className = 'ccpa-do-not-sell-link';
    link.textContent = 'Do Not Sell My Personal Information';
    link.setAttribute('aria-label', 'Opt out of personal information sales');
    
    // Add to footer and header as required
    const positions = ['.footer-links', '.header-menu', '.privacy-links'];
    positions.forEach(selector => {
      const container = document.querySelector(selector);
      if (container) {
        container.appendChild(link.cloneNode(true));
      }
    });
  }

  // Check current opt-out status
  checkOptOutStatus() {
    // Check cookie
    const cookieOptOut = this.getCookie(this.optOutCookie);
    
    // Check Global Privacy Control signal
    const gpcOptOut = navigator.globalPrivacyControl || navigator.doNotTrack === '1';
    
    // Check database for authenticated users
    const dbOptOut = this.checkDatabaseOptOut();
    
    // Apply most restrictive preference
    if (cookieOptOut || gpcOptOut || dbOptOut) {
      this.applyOptOut();
    }
  }

  // Process opt-out request
  async processOptOut(requestData = {}) {
    const optOutRecord = {
      timestamp: new Date().toISOString(),
      method: requestData.method || 'direct-link',
      ipAddress: await this.getHashedIP(),
      userAgent: navigator.userAgent,
      authenticated: !!requestData.userId
    };

    // Set opt-out cookie
    this.setCookie(this.optOutCookie, 'true', this.optOutDuration);
    
    // Record in database if authenticated
    if (requestData.userId) {
      await this.optOutDatabase.recordOptOut(requestData.userId, optOutRecord);
    }
    
    // Apply opt-out immediately
    this.applyOptOut();
    
    // Notify third parties
    await this.notifyThirdParties();
    
    // Show confirmation
    this.showOptOutConfirmation();
    
    return {
      success: true,
      record: optOutRecord
    };
  }

  // Apply opt-out preferences
  applyOptOut() {
    // Disable advertising cookies
    this.disableAdvertisingCookies();
    
    // Update consent management platform
    if (window.consentManager) {
      window.consentManager.updateConsent({
        advertising: false,
        sale_of_data: false
      });
    }
    
    // Disable third-party scripts
    this.disableThirdPartyTracking();
    
    // Update ad personalization
    this.disableAdPersonalization();
    
    // Signal to backend
    this.signalOptOutToBackend();
  }

  // Handle Global Privacy Control
  setupGlobalPrivacyControl() {
    if (navigator.globalPrivacyControl) {
      console.log('Global Privacy Control detected');
      this.processOptOut({ method: 'gpc-signal' });
      
      // Show GPC acknowledgment
      this.showGPCAcknowledgment();
    }
  }

  // Disable third-party tracking
  disableThirdPartyTracking() {
    // Google Analytics
    window['ga-disable-UA-XXXXX-Y'] = true;
    
    // Facebook Pixel
    if (typeof fbq !== 'undefined') {
      fbq('dataProcessingOptions', ['LDU'], 1, 1000);
    }
    
    // Other third-party scripts
    const trackingScripts = [
      'doubleclick.net',
      'facebook.com/tr',
      'amazon-adsystem.com',
      'googlesyndication.com'
    ];
    
    // Prevent loading of tracking scripts
    const observer = new MutationObserver((mutations) => {
      mutations.forEach((mutation) => {
        mutation.addedNodes.forEach((node) => {
          if (node.tagName === 'SCRIPT' && node.src) {
            if (trackingScripts.some(domain => node.src.includes(domain))) {
              node.remove();
              console.log('Blocked tracking script:', node.src);
            }
          }
        });
      });
    });
    
    observer.observe(document.documentElement, {
      childList: true,
      subtree: true
    });
  }

  // Show opt-out confirmation
  showOptOutConfirmation() {
    const confirmation = document.createElement('div');
    confirmation.className = 'ccpa-opt-out-confirmation';
    confirmation.innerHTML = `
      <div class="confirmation-content">
        <h3>Opt-Out Confirmed</h3>
        <p>Your opt-out preference has been recorded. We will not sell your personal information.</p>
        <p>Note: This opt-out applies only to sales of personal information. You may still see ads, but they won't be based on your personal information sold by us.</p>
        <button onclick="this.parentElement.parentElement.remove()">Close</button>
      </div>
    `;
    document.body.appendChild(confirmation);
  }
}

// Initialize Do Not Sell functionality
document.addEventListener('DOMContentLoaded', () => {
  const doNotSellManager = new DoNotSellManager();
  doNotSellManager.init();
});