Data Subject Rights Implementation

Data Subject Rights Implementation

GDPR grants individuals eight fundamental rights that websites must technically support. Implementing these rights requires both user interfaces and backend processes to handle requests efficiently while maintaining security and verifying identity appropriately.

The right to access (Article 15) requires providing users with confirmation of whether their personal data is being processed, access to that data, and specific information about the processing. Implementation must include identity verification to prevent unauthorized access, data gathering from all systems and databases, and formatting data in an understandable way.

// Data subject rights implementation
class DataSubjectRights {
  constructor() {
    this.requestTypes = ['access', 'rectification', 'erasure', 'portability', 'restriction', 'objection'];
    this.requestQueue = [];
    this.processingTime = {
      access: 30,
      rectification: 30,
      erasure: 30,
      portability: 30,
      restriction: 72,
      objection: 72
    };
  }
  
  // Handle data access requests
  async handleAccessRequest(userId, requestId) {
    try {
      // Verify identity
      const verified = await this.verifyIdentity(userId);
      if (!verified) {
        throw new Error('Identity verification failed');
      }
      
      // Gather all user data
      const userData = await this.gatherUserData(userId);
      
      // Format for delivery
      const report = this.generateAccessReport(userData);
      
      // Log the request
      await this.logRequest(userId, 'access', requestId);
      
      // Deliver securely
      await this.secureDelivery(userId, report, requestId);
      
      return { success: true, requestId };
    } catch (error) {
      await this.logError(requestId, error);
      throw error;
    }
  }
  
  // Gather all user data from different sources
  async gatherUserData(userId) {
    const dataSources = [
      { name: 'profile', fetch: () => this.getProfileData(userId) },
      { name: 'activity', fetch: () => this.getActivityData(userId) },
      { name: 'preferences', fetch: () => this.getPreferences(userId) },
      { name: 'communications', fetch: () => this.getCommunications(userId) },
      { name: 'consents', fetch: () => this.getConsentHistory(userId) },
      { name: 'thirdParties', fetch: () => this.getThirdPartySharing(userId) }
    ];
    
    const userData = {};
    
    for (const source of dataSources) {
      try {
        userData[source.name] = await source.fetch();
      } catch (error) {
        console.error(`Failed to fetch ${source.name} data:`, error);
        userData[source.name] = { error: 'Unable to retrieve this data category' };
      }
    }
    
    return userData;
  }
  
  // Generate human-readable report
  generateAccessReport(userData) {
    return {
      metadata: {
        generatedAt: new Date().toISOString(),
        requestId: this.generateRequestId(),
        dataController: 'Company Name Ltd.',
        purpose: 'GDPR Article 15 - Right of Access'
      },
      personalData: {
        profile: this.formatProfileData(userData.profile),
        activitySummary: this.summarizeActivity(userData.activity),
        preferences: userData.preferences,
        communications: this.formatCommunications(userData.communications),
        consentHistory: userData.consents,
        dataSharing: userData.thirdParties
      },
      processingInformation: {
        purposes: this.getProcessingPurposes(),
        legalBases: this.getLegalBases(),
        recipients: this.getDataRecipients(),
        retentionPeriods: this.getRetentionPeriods(),
        rights: this.getUserRights()
      }
    };
  }
  
  // Handle erasure requests with validation
  async handleErasureRequest(userId, requestId) {
    try {
      // Verify identity
      const verified = await this.verifyIdentity(userId);
      if (!verified) {
        throw new Error('Identity verification failed');
      }
      
      // Check for legal obligations to retain data
      const retentionObligations = await this.checkRetentionObligations(userId);
      if (retentionObligations.length > 0) {
        return {
          success: false,
          reason: 'Legal retention requirements',
          details: retentionObligations
        };
      }
      
      // Perform erasure
      const erasureResult = await this.performErasure(userId);
      
      // Log the erasure
      await this.logErasure(userId, erasureResult);
      
      // Notify third parties
      await this.notifyThirdParties(userId, 'erasure');
      
      return {
        success: true,
        requestId,
        erasedCategories: erasureResult.categories,
        retainedData: erasureResult.retained
      };
    } catch (error) {
      await this.logError(requestId, error);
      throw error;
    }
  }
  
  // Implement data portability
  async handlePortabilityRequest(userId, requestId) {
    try {
      // Verify identity
      const verified = await this.verifyIdentity(userId);
      if (!verified) {
        throw new Error('Identity verification failed');
      }
      
      // Get portable data (only data provided by user or observed)
      const portableData = await this.getPortableData(userId);
      
      // Format in machine-readable format
      const formats = {
        json: () => JSON.stringify(portableData, null, 2),
        csv: () => this.convertToCSV(portableData),
        xml: () => this.convertToXML(portableData)
      };
      
      // Allow user to choose format
      const format = await this.getUserFormatPreference(userId);
      const formattedData = formats[format]();
      
      // Deliver securely
      await this.secureDelivery(userId, formattedData, requestId, format);
      
      return { success: true, requestId, format };
    } catch (error) {
      await this.logError(requestId, error);
      throw error;
    }
  }
}