useCompliance

GDPR, CCPA, and privacy compliance tools for consent management and data protection.

Regulations: GDPR (EU), CCPA (California), LGPD (Brazil), PIPEDA (Canada)

Import

import { useCompliance } from '@heliorim/sdk-react';

Type Signature

interface ComplianceState {
  consents: ConsentRecord[];
  dataRequests: DataRequest[];
  policies: PrivacyPolicy[];
  breaches: DataBreach[];
  isProcessing: boolean;
  error: Error | null;
}

interface ComplianceActions {
  // Consent Management
  getConsent: (userId: string, purpose: ConsentPurpose) => Promise<ConsentRecord>;
  recordConsent: (consent: ConsentInput) => Promise<ConsentRecord>;
  withdrawConsent: (userId: string, purpose: ConsentPurpose) => Promise<void>;
  getConsentHistory: (userId: string) => Promise<ConsentRecord[]>;

  // Data Subject Rights
  handleDataRequest: (request: DataRequestInput) => Promise<DataRequest>;
  exportUserData: (userId: string) => Promise<UserDataExport>;
  deleteUserData: (userId: string, options: DeletionOptions) => Promise<void>;
  rectifyData: (userId: string, corrections: DataCorrections) => Promise<void>;

  // Privacy Management
  updatePrivacyPolicy: (policy: PrivacyPolicy) => Promise<void>;
  acceptPrivacyPolicy: (userId: string, version: string) => Promise<void>;
  getCookieConsent: () => CookieConsent;
  updateCookieConsent: (consent: CookieConsent) => void;

  // Breach Management
  reportBreach: (breach: DataBreachInput) => Promise<DataBreach>;
  getBreachNotifications: () => Promise<BreachNotification[]>;
}

interface ConsentRecord {
  id: string;
  userId: string;
  purpose: ConsentPurpose;
  granted: boolean;
  timestamp: number;
  expiresAt?: number;
  withdrawnAt?: number;
  ipAddress: string;
  method: 'explicit' | 'implicit' | 'opt-out';
  version: string;
}

interface DataRequest {
  id: string;
  userId: string;
  type: 'access' | 'deletion' | 'portability' | 'rectification' | 'restriction';
  status: 'pending' | 'processing' | 'completed' | 'rejected';
  submittedAt: number;
  completedAt?: number;
  response?: string;
  verificationMethod: string;
}

interface UserDataExport {
  userId: string;
  exportDate: number;
  format: 'json' | 'csv' | 'xml';
  data: {
    profile: any;
    consents: ConsentRecord[];
    activities: any[];
    preferences: any;
  };
  signature: string;
}

type ConsentPurpose =
  | 'marketing'
  | 'analytics'
  | 'personalization'
  | 'necessary'
  | 'performance'
  | 'functional';

type UseComplianceReturn = ComplianceState & ComplianceActions;

Basic Usage

function PrivacyCenter() {
  const {
    consents,
    recordConsent,
    withdrawConsent,
    exportUserData,
    deleteUserData,
    getCookieConsent,
    updateCookieConsent
  } = useCompliance();

  const { user } = useAuth();

  // Cookie consent banner
  const [showCookieBanner, setShowCookieBanner] = useState(false);

  useEffect(() => {
    const consent = getCookieConsent();
    if (!consent.decided) {
      setShowCookieBanner(true);
    }
  }, []);

  const handleCookieConsent = (accepted: boolean) => {
    updateCookieConsent({
      necessary: true, // Always true
      analytics: accepted,
      marketing: accepted,
      functional: accepted,
      decided: true,
      timestamp: Date.now()
    });
    setShowCookieBanner(false);
  };

  // Manage marketing consent
  const updateMarketingConsent = async (granted: boolean) => {
    if (!user) return;

    if (granted) {
      await recordConsent({
        userId: user.id,
        purpose: 'marketing',
        granted: true,
        method: 'explicit'
      });
    } else {
      await withdrawConsent(user.id, 'marketing');
    }
  };

  // Data export request
  const requestDataExport = async () => {
    if (!user) return;

    const exportData = await exportUserData(user.id);

    // Download the export
    const blob = new Blob([JSON.stringify(exportData, null, 2)], {
      type: 'application/json'
    });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = `my-data-${Date.now()}.json`;
    a.click();
  };

  // Account deletion
  const requestAccountDeletion = async () => {
    if (!user) return;

    if (confirm('Are you sure you want to delete your account? This cannot be undone.')) {
      await deleteUserData(user.id, {
        immediate: false, // Schedule for deletion
        retentionPeriod: 30, // Keep for 30 days
        reason: 'User requested',
        notifyUser: true
      });
    }
  };

  return (
    <div className="privacy-center">
      <h2>Privacy Center</h2>

      {showCookieBanner && (
        <div className="cookie-banner">
          <p>We use cookies to improve your experience.</p>
          <button onClick={() => handleCookieConsent(true)}>
            Accept All
          </button>
          <button onClick={() => handleCookieConsent(false)}>
            Necessary Only
          </button>
        </div>
      )}

      <div className="consent-management">
        <h3>Your Consent Preferences</h3>

        <label>
          <input
            type="checkbox"
            checked={consents.some(c =>
              c.purpose === 'marketing' && c.granted && !c.withdrawnAt
            )}
            onChange={(e) => updateMarketingConsent(e.target.checked)}
          />
          Marketing Communications
        </label>

        <label>
          <input
            type="checkbox"
            checked={consents.some(c =>
              c.purpose === 'analytics' && c.granted && !c.withdrawnAt
            )}
            onChange={(e) => recordConsent({
              userId: user!.id,
              purpose: 'analytics',
              granted: e.target.checked,
              method: 'explicit'
            })}
          />
          Analytics & Performance
        </label>

        <label>
          <input
            type="checkbox"
            checked={consents.some(c =>
              c.purpose === 'personalization' && c.granted && !c.withdrawnAt
            )}
            onChange={(e) => recordConsent({
              userId: user!.id,
              purpose: 'personalization',
              granted: e.target.checked,
              method: 'explicit'
            })}
          />
          Personalization
        </label>
      </div>

      <div className="data-rights">
        <h3>Your Data Rights</h3>

        <button onClick={requestDataExport}>
          Download My Data
        </button>

        <button onClick={requestAccountDeletion}>
          Delete My Account
        </button>
      </div>
    </div>
  );
}

GDPR Compliance

Consent Management

function GDPRConsent() {
  const {
    recordConsent,
    withdrawConsent,
    getConsentHistory
  } = useCompliance();

  const collectGDPRConsent = async (userId: string) => {
    // Record multiple consents with proper legal basis
    const consents = [
      {
        userId,
        purpose: 'necessary' as ConsentPurpose,
        granted: true,
        method: 'explicit' as const,
        legalBasis: 'contract',
        description: 'Essential cookies for site functionality'
      },
      {
        userId,
        purpose: 'analytics' as ConsentPurpose,
        granted: false,
        method: 'explicit' as const,
        legalBasis: 'consent',
        description: 'Analytics to improve our services'
      },
      {
        userId,
        purpose: 'marketing' as ConsentPurpose,
        granted: false,
        method: 'explicit' as const,
        legalBasis: 'consent',
        description: 'Marketing and promotional communications'
      }
    ];

    for (const consent of consents) {
      await recordConsent(consent);
    }
  };

  const showConsentHistory = async (userId: string) => {
    const history = await getConsentHistory(userId);

    return (
      <div className="consent-history">
        <h4>Consent History</h4>
        <table>
          <thead>
            <tr>
              <th>Purpose</th>
              <th>Status</th>
              <th>Date</th>
              <th>Method</th>
            </tr>
          </thead>
          <tbody>
            {history.map(record => (
              <tr key={record.id}>
                <td>{record.purpose}</td>
                <td>{record.withdrawnAt ? 'Withdrawn' : record.granted ? 'Granted' : 'Denied'}</td>
                <td>{new Date(record.timestamp).toLocaleDateString()}</td>
                <td>{record.method}</td>
              </tr>
            ))}
          </tbody>
        </table>
      </div>
    );
  };

  const granularConsentControl = () => {
    return (
      <div className="granular-consent">
        <h4>Granular Consent Control</h4>

        <div className="consent-category">
          <h5>Strictly Necessary</h5>
          <p>Required for basic site functionality</p>
          <input type="checkbox" checked disabled />
        </div>

        <div className="consent-category">
          <h5>Performance Cookies</h5>
          <p>Help us understand how visitors use our site</p>
          <input
            type="checkbox"
            onChange={(e) => {
              if (e.target.checked) {
                recordConsent({
                  userId: getCurrentUserId(),
                  purpose: 'performance',
                  granted: true,
                  method: 'explicit'
                });
              } else {
                withdrawConsent(getCurrentUserId(), 'performance');
              }
            }}
          />
        </div>

        <div className="consent-category">
          <h5>Functional Cookies</h5>
          <p>Remember your preferences and settings</p>
          <input
            type="checkbox"
            onChange={(e) => {
              recordConsent({
                userId: getCurrentUserId(),
                purpose: 'functional',
                granted: e.target.checked,
                method: 'explicit'
              });
            }}
          />
        </div>
      </div>
    );
  };

  return { collectGDPRConsent, showConsentHistory, granularConsentControl };
}

Data Subject Requests

function DataSubjectRights() {
  const {
    handleDataRequest,
    exportUserData,
    deleteUserData,
    rectifyData
  } = useCompliance();

  // Right to Access (Article 15)
  const handleAccessRequest = async (userId: string) => {
    const request = await handleDataRequest({
      userId,
      type: 'access',
      verificationMethod: 'email',
      details: 'User requested copy of personal data'
    });

    // Generate comprehensive data export
    const exportData = await exportUserData(userId);

    // Send to user
    await sendSecureEmail(userId, {
      subject: 'Your Data Access Request',
      attachments: [{
        filename: 'personal-data.json',
        content: JSON.stringify(exportData)
      }]
    });

    return request;
  };

  // Right to Erasure (Article 17)
  const handleDeletionRequest = async (userId: string, reason: string) => {
    const request = await handleDataRequest({
      userId,
      type: 'deletion',
      verificationMethod: 'passkey',
      details: reason
    });

    // Check if deletion can proceed
    const canDelete = await checkDeletionEligibility(userId);

    if (canDelete) {
      await deleteUserData(userId, {
        immediate: false,
        retentionPeriod: 30,
        reason,
        notifyUser: true,
        cascade: true, // Delete related data
        exceptions: ['legal_holds', 'financial_records']
      });
    } else {
      // Explain why deletion cannot proceed
      await notifyUser(userId, {
        subject: 'Deletion Request Status',
        message: 'Some data must be retained for legal compliance'
      });
    }

    return request;
  };

  // Right to Rectification (Article 16)
  const handleRectificationRequest = async (
    userId: string,
    corrections: DataCorrections
  ) => {
    const request = await handleDataRequest({
      userId,
      type: 'rectification',
      verificationMethod: 'passkey',
      details: JSON.stringify(corrections)
    });

    await rectifyData(userId, corrections);

    // Notify third parties of corrections
    await notifyThirdParties(userId, corrections);

    return request;
  };

  // Right to Data Portability (Article 20)
  const handlePortabilityRequest = async (userId: string, format: 'json' | 'csv' | 'xml') => {
    const request = await handleDataRequest({
      userId,
      type: 'portability',
      verificationMethod: 'email',
      details: `Requested format: ${format}`
    });

    const exportData = await exportUserData(userId);

    // Convert to requested format
    let formatted: string;
    switch (format) {
      case 'csv':
        formatted = convertToCSV(exportData);
        break;
      case 'xml':
        formatted = convertToXML(exportData);
        break;
      default:
        formatted = JSON.stringify(exportData);
    }

    return {
      request,
      data: formatted,
      format
    };
  };

  return {
    handleAccessRequest,
    handleDeletionRequest,
    handleRectificationRequest,
    handlePortabilityRequest
  };
}

CCPA Compliance

California Privacy Rights

function CCPACompliance() {
  const {
    recordConsent,
    exportUserData,
    deleteUserData
  } = useCompliance();

  // "Do Not Sell My Personal Information" opt-out
  const handleDoNotSell = async (userId: string, optOut: boolean) => {
    await recordConsent({
      userId,
      purpose: 'data_sale',
      granted: !optOut,
      method: 'opt-out',
      jurisdiction: 'california',
      metadata: {
        ccpa: true,
        timestamp: Date.now(),
        ipAddress: getClientIP()
      }
    });

    // Update user preferences
    await updateUserPreferences(userId, {
      doNotSell: optOut,
      ccpaOptOut: optOut
    });

    // Notify partners
    if (optOut) {
      await notifyDataPartners(userId, 'opt-out');
    }
  };

  // Categories of personal information
  const getInformationCategories = async (userId: string) => {
    const data = await exportUserData(userId);

    return {
      identifiers: {
        collected: true,
        examples: ['email', 'name', 'user_id'],
        sources: ['direct', 'automatic'],
        purposes: ['authentication', 'communication'],
        shared: false
      },
      commercial: {
        collected: true,
        examples: ['purchase_history', 'preferences'],
        sources: ['direct'],
        purposes: ['service_improvement'],
        shared: false
      },
      biometric: {
        collected: true,
        examples: ['passkey_credentials'],
        sources: ['direct'],
        purposes: ['authentication'],
        shared: false
      },
      internet_activity: {
        collected: true,
        examples: ['browsing_history', 'interaction_data'],
        sources: ['automatic'],
        purposes: ['analytics', 'personalization'],
        shared: false
      },
      geolocation: {
        collected: true,
        examples: ['ip_location'],
        sources: ['automatic'],
        purposes: ['security', 'compliance'],
        shared: false
      }
    };
  };

  // Disclosure requirements
  const generatePrivacyDisclosure = () => {
    return {
      businessPurposes: [
        'Providing authentication services',
        'Detecting security incidents',
        'Debugging and error resolution',
        'Internal research and development'
      ],
      categoriesCollected: [
        'Identifiers',
        'Commercial information',
        'Biometric information',
        'Internet activity',
        'Geolocation data'
      ],
      categoriesSold: [],
      categoriesDisclosed: [
        'Identifiers (to service providers only)'
      ],
      rightsAvailable: [
        'Right to know',
        'Right to delete',
        'Right to opt-out',
        'Right to non-discrimination'
      ]
    };
  };

  return { handleDoNotSell, getInformationCategories, generatePrivacyDisclosure };
}

Cookie Management

Cookie Consent Banner

function CookieConsentManager() {
  const { getCookieConsent, updateCookieConsent } = useCompliance();
  const [showSettings, setShowSettings] = useState(false);
  const [consent, setConsent] = useState(getCookieConsent());

  const cookieCategories = {
    necessary: {
      name: 'Strictly Necessary',
      description: 'Essential for the website to function properly',
      required: true,
      cookies: ['heliorim_session', 'heliorim_csrf', 'heliorim_auth_token']
    },
    functional: {
      name: 'Functional',
      description: 'Enable personalized features',
      required: false,
      cookies: ['language_preference', 'timezone', 'theme']
    },
    analytics: {
      name: 'Analytics',
      description: 'Help us understand how you use our site',
      required: false,
      cookies: ['_ga', '_gid', 'amplitude_id']
    },
    marketing: {
      name: 'Marketing',
      description: 'Used for targeted advertising',
      required: false,
      cookies: ['fbp', 'gcl_au']
    }
  };

  const savePreferences = () => {
    updateCookieConsent({
      ...consent,
      decided: true,
      timestamp: Date.now()
    });

    // Apply consent choices
    if (!consent.analytics) {
      disableAnalytics();
    }
    if (!consent.marketing) {
      disableMarketing();
    }

    setShowSettings(false);
  };

  return (
    <div className="cookie-consent-banner">
      <div className="banner-content">
        <h3>Cookie Preferences</h3>
        <p>We use cookies to enhance your experience.</p>

        {!showSettings ? (
          <div className="quick-options">
            <button onClick={() => {
              updateCookieConsent({
                necessary: true,
                functional: true,
                analytics: true,
                marketing: true,
                decided: true,
                timestamp: Date.now()
              });
            }}>
              Accept All
            </button>

            <button onClick={() => setShowSettings(true)}>
              Customize
            </button>

            <button onClick={() => {
              updateCookieConsent({
                necessary: true,
                functional: false,
                analytics: false,
                marketing: false,
                decided: true,
                timestamp: Date.now()
              });
            }}>
              Reject Non-Essential
            </button>
          </div>
        ) : (
          <div className="detailed-settings">
            {Object.entries(cookieCategories).map(([key, category]) => (
              <div key={key} className="cookie-category">
                <h4>{category.name}</h4>
                <p>{category.description}</p>
                <p className="cookies-list">Cookies: {category.cookies.join(', ')}</p>
                <input
                  type="checkbox"
                  checked={consent[key as keyof CookieConsent]}
                  disabled={category.required}
                  onChange={(e) => setConsent({
                    ...consent,
                    [key]: e.target.checked
                  })}
                />
              </div>
            ))}

            <button onClick={savePreferences}>
              Save Preferences
            </button>
          </div>
        )}
      </div>
    </div>
  );
}

Data Breach Management

Breach Response

function DataBreachResponse() {
  const { reportBreach, getBreachNotifications } = useCompliance();

  const handleDataBreach = async (breach: DataBreachInput) => {
    // Report the breach
    const breachReport = await reportBreach({
      ...breach,
      detectedAt: Date.now(),
      severity: assessSeverity(breach),
      affectedDataCategories: identifyAffectedData(breach),
      estimatedAffectedUsers: estimateImpact(breach)
    });

    // 72-hour GDPR notification requirement
    if (breach.severity === 'high') {
      await notifyAuthorities(breachReport, {
        deadline: Date.now() + 72 * 60 * 60 * 1000
      });
    }

    // Notify affected users
    const notifications = await prepareUserNotifications(breachReport);
    await sendBreachNotifications(notifications);

    // Implement containment measures
    await implementContainment(breach);

    return breachReport;
  };

  const breachAssessment = async () => {
    return {
      checklistItems: [
        { item: 'Identify breach scope', completed: false },
        { item: 'Contain the breach', completed: false },
        { item: 'Assess risk to individuals', completed: false },
        { item: 'Determine notification requirements', completed: false },
        { item: 'Notify supervisory authority (if required)', completed: false },
        { item: 'Notify affected individuals', completed: false },
        { item: 'Document breach and response', completed: false },
        { item: 'Review and update security measures', completed: false }
      ],
      timeline: {
        detection: null,
        containment: null,
        assessment: null,
        authorityNotification: null,
        userNotification: null,
        resolution: null
      },
      documentation: {
        breachDescription: '',
        dataCategories: [],
        affectedUsers: 0,
        riskAssessment: '',
        mitigationMeasures: [],
        preventiveMeasures: []
      }
    };
  };

  return { handleDataBreach, breachAssessment };
}

Privacy Policy Management

Policy Updates & Acceptance

function PrivacyPolicyManager() {
  const { updatePrivacyPolicy, acceptPrivacyPolicy } = useCompliance();

  const [currentPolicy, setCurrentPolicy] = useState<PrivacyPolicy | null>(null);
  const [userAcceptance, setUserAcceptance] = useState(false);

  const deployNewPolicy = async (policy: PrivacyPolicy) => {
    // Update policy
    await updatePrivacyPolicy({
      ...policy,
      version: incrementVersion(currentPolicy?.version),
      effectiveDate: Date.now() + 30 * 24 * 60 * 60 * 1000, // 30 days notice
      changes: summarizeChanges(currentPolicy, policy)
    });

    // Notify all users
    await notifyAllUsers({
      subject: 'Privacy Policy Update',
      message: 'Our privacy policy will be updated in 30 days',
      actionRequired: true
    });
  };

  const requirePolicyAcceptance = async (userId: string) => {
    const latestPolicy = await getLatestPolicy();

    const hasAccepted = await checkUserAcceptance(userId, latestPolicy.version);

    if (!hasAccepted) {
      return (
        <div className="policy-acceptance-required">
          <h3>Privacy Policy Update</h3>
          <div className="policy-content">
            {latestPolicy.content}
          </div>
          <div className="policy-changes">
            <h4>Key Changes:</h4>
            <ul>
              {latestPolicy.changes.map((change, i) => (
                <li key={i}>{change}</li>
              ))}
            </ul>
          </div>
          <button onClick={async () => {
            await acceptPrivacyPolicy(userId, latestPolicy.version);
            setUserAcceptance(true);
          }}>
            I Accept the Updated Privacy Policy
          </button>
        </div>
      );
    }

    return null;
  };

  return { deployNewPolicy, requirePolicyAcceptance };
}

International Compliance

Supported Regulations:

  • GDPR (European Union)
  • CCPA/CPRA (California)
  • LGPD (Brazil)
  • PIPEDA (Canada)
  • POPI (South Africa)
  • APP (Australia)

Best Practices

✓ Recommended

  • Obtain explicit consent before data collection
  • Provide granular consent options
  • Maintain comprehensive consent records
  • Respond to data requests within legal timeframes
  • Implement privacy by design
  • Regular privacy impact assessments
  • Document all data processing activities
  • Train staff on privacy requirements

⚠️ Avoid

  • Pre-checked consent boxes
  • Bundled consent for different purposes
  • Making consent a precondition for service
  • Ignoring withdrawal of consent
  • Delaying breach notifications
  • Insufficient data security measures

Related Hooks