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;
}
}
}