- Move repo to project root to include both public/ and api/ - Add .gitignore excluding node_modules and .env - Include API routes (erase, gmail_oauth), services (mailer), and config Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
117 lines
6.7 KiB
JavaScript
117 lines
6.7 KiB
JavaScript
'use strict';
|
|
|
|
const nodemailer = require('nodemailer');
|
|
|
|
const transporter = nodemailer.createTransport({
|
|
sendmail: true,
|
|
newline: 'unix',
|
|
path: '/usr/sbin/sendmail'
|
|
});
|
|
|
|
/* ============================================================
|
|
DATOS DE PROVEEDORES
|
|
Actualizar si cambian los contactos de privacidad.
|
|
============================================================ */
|
|
const PROVIDER_DATA = {
|
|
instagram: { name: 'Instagram (Meta)', email: 'privacidad-dpo@fb.com', company: 'Meta Platforms Ireland Limited', address: '4 Grand Canal Square, Grand Canal Harbour, Dublín 2, Irlanda' },
|
|
facebook: { name: 'Facebook (Meta)', email: 'privacidad-dpo@fb.com', company: 'Meta Platforms Ireland Limited', address: '4 Grand Canal Square, Grand Canal Harbour, Dublín 2, Irlanda' },
|
|
twitter_x: { name: 'X (Twitter)', email: 'gdpr@twitter.com', company: 'Twitter International Unlimited Company', address: 'One Cumberland Place, Fenian Street, Dublín 2, D02 AX07, Irlanda' },
|
|
google: { name: 'Google', email: null, formUrl: 'https://support.google.com/policies/contact/sar_data_protection', company: 'Google Ireland Limited', address: 'Gordon House, Barrow Street, Dublín 4, Irlanda' },
|
|
linkedin: { name: 'LinkedIn', email: 'privacy@linkedin.com', company: 'LinkedIn Ireland Unlimited Company', address: 'Wilton Place, Dublín 2, Irlanda' },
|
|
tiktok: { name: 'TikTok', email: 'privacy@tiktok.com', company: 'TikTok Technology Limited', address: '10 Earlsfort Terrace, Dublín, D02 T380, Irlanda' },
|
|
snapchat: { name: 'Snapchat', email: 'privacy@snap.com', company: 'Snap Group Limited', address: '77 Shaftesbury Avenue, Londres W1D 5DU, Reino Unido' },
|
|
microsoft: { name: 'Microsoft', email: 'msprivacy@microsoft.com', company: 'Microsoft Ireland Operations Limited', address: 'One Microsoft Place, South County Business Park, Leopardstown, Dublín 18, Irlanda' },
|
|
apple: { name: 'Apple', email: 'privacy@apple.com', company: 'Apple Distribution International Ltd.', address: 'Hollyhill Industrial Estate, Hollyhill, Cork, Irlanda' },
|
|
amazon: { name: 'Amazon', email: null, formUrl: 'https://www.amazon.es/hz/contact-us/privacy-disclosure/', company: 'Amazon Europe Core S.à r.l.', address: '38 avenue John F. Kennedy, L-1855 Luxemburgo' },
|
|
reddit: { name: 'Reddit', email: 'gdpr@reddit.com', company: 'Reddit Inc.', address: '548 Market St. #16093, San Francisco, CA 94104, EE.UU.' },
|
|
discord: { name: 'Discord', email: 'privacy@discord.com', company: 'Discord Inc.', address: '444 De Haro Street, Suite 200, San Francisco, CA 94107, EE.UU.' },
|
|
};
|
|
|
|
/* ============================================================
|
|
PLANTILLA DE CARTA — supresión Art. 17 RGPD
|
|
============================================================ */
|
|
function buildLetterText({ providerInfo, senderName, senderEmail, senderNick, senderPhone, senderAddress, extra }) {
|
|
const today = new Date().toLocaleDateString('es-ES', { day: 'numeric', month: 'long', year: 'numeric' });
|
|
const deadline = new Date(Date.now() + 30 * 86400000).toLocaleDateString('es-ES', { day: 'numeric', month: 'long', year: 'numeric' });
|
|
|
|
const identLines = [
|
|
`Nombre: ${senderName}`,
|
|
`Email: ${senderEmail}`,
|
|
senderNick ? `Usuario / alias: ${senderNick}` : null,
|
|
senderPhone ? `Teléfono: ${senderPhone}` : null,
|
|
senderAddress ? `Dirección: ${senderAddress}` : null,
|
|
extra ? `Datos adicionales: ${extra}` : null,
|
|
].filter(Boolean).join('\n');
|
|
|
|
return `${providerInfo.company}
|
|
${providerInfo.address}
|
|
${providerInfo.email ? 'DPO: ' + providerInfo.email : ''}
|
|
|
|
${today}
|
|
|
|
Asunto: Ejercicio del derecho de supresión — artículo 17 RGPD (UE 2016/679)
|
|
|
|
A quien corresponda:
|
|
|
|
Yo, ${senderName}, con los siguientes datos de contacto:
|
|
|
|
${identLines}
|
|
|
|
En ejercicio del derecho de supresión ("derecho al olvido") reconocido en el artículo 17 del Reglamento (UE) 2016/679 (RGPD) y en la Ley Orgánica 3/2018, de Protección de Datos Personales y garantía de los derechos digitales (LOPDGDD), solicito a ${providerInfo.company} la supresión completa de todos mis datos personales, incluyendo sin limitación:
|
|
|
|
· Datos de cuenta e identificadores (nombre, email, teléfono, dirección IP, identificadores de dispositivo).
|
|
· Contenidos publicados, comentarios, mensajes, imágenes y archivos.
|
|
· Datos de comportamiento, historial de actividad y preferencias inferidas.
|
|
· Datos en sistemas de backup y réplicas, en el plazo razonable comprometido.
|
|
· Datos cedidos o compartidos con terceros, con la notificación correspondiente para que también procedan a su supresión.
|
|
|
|
Fundamento mi solicitud en la retirada del consentimiento que en su momento presté y en que el tratamiento de mis datos ya no es necesario para los fines para los que fueron recabados.
|
|
|
|
Solicito confirmación escrita de la supresión una vez completada, con indicación del plazo para la eliminación de backups.
|
|
|
|
De conformidad con el artículo 12.3 RGPD, disponen de un mes desde la recepción para responder (antes del ${deadline}). En caso de denegación o silencio, me reservo el derecho a presentar reclamación ante la Agencia Española de Protección de Datos (sedeagpd.gob.es).
|
|
|
|
Atentamente,
|
|
|
|
${senderName}
|
|
${senderEmail}
|
|
${today}`;
|
|
}
|
|
|
|
/* ============================================================
|
|
EXPORTACIONES
|
|
============================================================ */
|
|
exports.PROVIDER_DATA = PROVIDER_DATA;
|
|
|
|
exports.sendErasureMail = async ({ provider, email, nickname, phone, address, extra }) => {
|
|
const providerInfo = PROVIDER_DATA[provider] || {
|
|
name: provider,
|
|
email: `privacy@${provider}.com`,
|
|
company: provider,
|
|
address: '',
|
|
};
|
|
|
|
// Si el proveedor no tiene email directo, no enviamos (devolvemos aviso)
|
|
if (!providerInfo.email) {
|
|
return { skipped: true, reason: 'use_form', formUrl: providerInfo.formUrl };
|
|
}
|
|
|
|
const letterText = buildLetterText({
|
|
providerInfo,
|
|
senderName: email, // El nombre real viene del campo email por compatibilidad heredada
|
|
senderEmail: email,
|
|
senderNick: nickname || '',
|
|
senderPhone: phone || '',
|
|
senderAddress: address || '',
|
|
extra: extra || '',
|
|
});
|
|
|
|
await transporter.sendMail({
|
|
from: 'privacy@resetea.net',
|
|
to: providerInfo.email,
|
|
subject: `Ejercicio derecho de supresión (RGPD Art. 17) — ${providerInfo.name}`,
|
|
text: letterText,
|
|
});
|
|
|
|
return { skipped: false };
|
|
};
|