Files
breakpilot-core/pitch-deck/lib/email.ts
T
Sharang Parnerkar 1bf1411c66
Build pitch-deck / build-push-deploy (push) Successful in 1m19s
CI / go-lint (push) Has been skipped
CI / python-lint (push) Has been skipped
CI / nodejs-lint (push) Has been skipped
CI / test-go-consent (push) Successful in 29s
CI / test-python-voice (push) Successful in 29s
CI / test-bqas (push) Successful in 29s
fix(pitch-deck): update email privacy notice to match GDPR changes
72 Stunden → 30 Tage, expand scope to include personal contact data,
add Art. 15–21 rights, LfDI BW supervisory authority. Both DE + EN.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-01 15:20:46 +02:00

183 lines
11 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import 'server-only'
import nodemailer from 'nodemailer'
import {
DEFAULT_MESSAGE,
DEFAULT_CLOSING,
getDefaultGreeting,
} from '@/lib/email-templates'
export { DEFAULT_GREETING, DEFAULT_MESSAGE, DEFAULT_CLOSING, getDefaultGreeting } from '@/lib/email-templates'
const transporter = nodemailer.createTransport({
host: process.env.SMTP_HOST,
port: parseInt(process.env.SMTP_PORT || '587'),
secure: process.env.SMTP_PORT === '465',
auth: {
user: process.env.SMTP_USERNAME,
pass: process.env.SMTP_PASSWORD,
},
})
const fromName = process.env.SMTP_FROM_NAME || 'BreakPilot'
const fromAddr = process.env.SMTP_FROM_ADDR || 'noreply@breakpilot.ai'
export async function sendMagicLinkEmail(
to: string,
investorName: string | null,
magicLinkUrl: string,
greeting?: string,
message?: string,
closing?: string,
): Promise<void> {
const effectiveGreeting = greeting || getDefaultGreeting(investorName)
const effectiveMessage = message || DEFAULT_MESSAGE
const effectiveClosing = closing || DEFAULT_CLOSING
const closingHtml = effectiveClosing.replace(/\n/g, '<br>')
const ttl = process.env.MAGIC_LINK_TTL_HOURS || '72'
await transporter.sendMail({
from: `"${fromName}" <${fromAddr}>`,
to,
subject: 'BreakPilot ComplAI — Ihr persönlicher Pitch-Deck-Zugang',
html: `
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body style="margin:0;padding:0;background:#0a0a1a;font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;">
<table width="100%" cellpadding="0" cellspacing="0" style="background:#0a0a1a;padding:40px 20px;">
<tr>
<td align="center">
<table width="560" cellpadding="0" cellspacing="0" style="background:#111127;border-radius:12px;border:1px solid rgba(99,102,241,0.2);">
<!-- Header -->
<tr>
<td style="padding:40px 40px 20px;">
<h1 style="margin:0;font-size:24px;color:#e0e0ff;font-weight:600;">
BreakPilot ComplAI
</h1>
<p style="margin:8px 0 0;font-size:13px;color:rgba(255,255,255,0.4);">
Investor Pitch Deck
</p>
</td>
</tr>
<!-- Greeting + Message -->
<tr>
<td style="padding:20px 40px 0;">
<p style="margin:0 0 16px;font-size:16px;color:rgba(255,255,255,0.8);line-height:1.6;">
${effectiveGreeting},
</p>
<p style="margin:0 0 24px;font-size:15px;color:rgba(255,255,255,0.7);line-height:1.7;">
${effectiveMessage}
</p>
</td>
</tr>
<!-- Magic Link Explanation -->
<tr>
<td style="padding:0 40px 20px;">
<div style="background:rgba(99,102,241,0.08);border:1px solid rgba(99,102,241,0.15);border-radius:8px;padding:16px;">
<p style="margin:0 0 4px;font-size:11px;font-weight:600;color:rgba(99,102,241,0.8);text-transform:uppercase;letter-spacing:0.5px;">
Ihr persönlicher Zugang
</p>
<p style="margin:0;font-size:13px;color:rgba(255,255,255,0.5);line-height:1.5;">
Der folgende Link ist individuell für Sie generiert, einmalig nutzbar und aus Sicherheitsgründen für ${ttl} Stunden gültig. Er gewährt Ihnen Zugang zu unserem interaktiven Pitch Deck — inklusive integriertem KI-Assistenten für weiterführende Fragen.
</p>
</div>
</td>
</tr>
<!-- Button -->
<tr>
<td style="padding:0 40px 16px;" align="center">
<table cellpadding="0" cellspacing="0">
<tr>
<td style="background:linear-gradient(135deg,#6366f1,#8b5cf6);border-radius:8px;padding:14px 40px;">
<a href="${magicLinkUrl}" style="color:#ffffff;font-size:16px;font-weight:600;text-decoration:none;display:inline-block;">
Pitch Deck öffnen
</a>
</td>
</tr>
</table>
</td>
</tr>
<!-- Raw link -->
<tr>
<td style="padding:0 40px 24px;">
<p style="margin:0;font-size:11px;color:rgba(255,255,255,0.25);line-height:1.5;word-break:break-all;">
Falls der Button nicht funktioniert: ${magicLinkUrl}
</p>
</td>
</tr>
<!-- Closing -->
<tr>
<td style="padding:0 40px 24px;">
<p style="margin:0;font-size:15px;color:rgba(255,255,255,0.7);line-height:1.7;">
${closingHtml}
</p>
</td>
</tr>
<!-- Legal Footer DE -->
<tr>
<td style="padding:20px 40px 12px;border-top:1px solid rgba(255,255,255,0.05);">
<p style="margin:0 0 8px;font-size:10px;font-weight:600;color:rgba(255,255,255,0.3);text-transform:uppercase;letter-spacing:0.5px;">
Vertraulichkeit &amp; Haftungsausschluss
</p>
<p style="margin:0 0 6px;font-size:10px;color:rgba(255,255,255,0.18);line-height:1.5;">
Dieses Pitch Deck wurde im Zusammenhang mit einer geplanten Unternehmung erstellt und dient ausschließlich Informationszwecken. Es ist vertraulich und wurde ausschließlich für den namentlich eingeladenen Empfänger bereitgestellt. Durch das Öffnen des Links erklärt sich der Empfänger einverstanden: (a) Der Inhalt ist vertraulich zu behandeln und darf nicht an Dritte weitergegeben, kopiert oder zugänglich gemacht werden. Ausgenommen sind Berater (Rechtsanwälte, Steuerberater), die berufsrechtlich zur Verschwiegenheit verpflichtet sind. (b) Die Informationen dürfen ausschließlich zur Bewertung einer möglichen zukünftigen Beteiligung verwendet werden. (c) Diese Vertraulichkeitsverpflichtung gilt für drei (3) Jahre ab Übermittlung, unabhängig davon, ob eine Beteiligung zustande kommt.
</p>
<p style="margin:0 0 12px;font-size:10px;color:rgba(255,255,255,0.18);line-height:1.5;">
Dieses Dokument stellt weder ein Angebot zum Verkauf noch eine Aufforderung zur Abgabe eines Angebots zum Erwerb von Wertpapieren dar. Es handelt sich nicht um einen Wertpapierprospekt. Alle dargestellten Inhalte beziehen sich auf eine geplante Unternehmung und können sich im weiteren Verlauf ändern. Finanzangaben sind Planzahlen und stellen keine Garantie für zukünftige Ergebnisse dar. Eine Beteiligung an einem jungen Vorhaben ist mit erheblichen Risiken verbunden, einschließlich des Risikos eines Totalverlusts. Es gilt deutsches Recht. Gerichtsstand ist Konstanz, Deutschland.
</p>
</td>
</tr>
<!-- Legal Footer EN -->
<tr>
<td style="padding:0 40px 40px;">
<p style="margin:0 0 8px;font-size:10px;font-weight:600;color:rgba(255,255,255,0.2);text-transform:uppercase;letter-spacing:0.5px;">
Confidentiality &amp; Disclaimer
</p>
<p style="margin:0 0 6px;font-size:10px;color:rgba(255,255,255,0.13);line-height:1.5;">
This pitch deck has been prepared in the context of a planned venture and is provided for informational purposes only. It is confidential and has been shared exclusively with the personally invited recipient. By opening this link, the recipient agrees: (a) The content must be treated confidentially and may not be disclosed, copied or made accessible to third parties. Excluded are advisors (lawyers, tax advisors) professionally bound to secrecy. (b) The information may only be used for evaluating a potential future investment. (c) This confidentiality obligation applies for three (3) years from transmission, regardless of whether a participation materializes.
</p>
<p style="margin:0;font-size:10px;color:rgba(255,255,255,0.13);line-height:1.5;">
This document constitutes neither an offer to sell nor a solicitation of an offer to acquire securities. It is not a securities prospectus. All information relates to a planned venture and may be subject to change. Financial figures are projections and do not constitute a guarantee of future results. An investment in an early-stage venture involves significant risks, including the risk of total loss. German law applies. Place of jurisdiction is Konstanz, Germany.
</p>
</td>
</tr>
<!-- Privacy Notice -->
<tr>
<td style="padding:12px 40px 40px;border-top:1px solid rgba(255,255,255,0.05);">
<p style="margin:0 0 8px;font-size:10px;font-weight:600;color:rgba(255,255,255,0.2);text-transform:uppercase;letter-spacing:0.5px;">
Datenschutzhinweis / Privacy Notice
</p>
<p style="margin:0 0 6px;font-size:10px;color:rgba(255,255,255,0.15);line-height:1.5;">
Beim Aufruf des obenstehenden Links werden technische Zugriffsdaten (IP-Adresse, Zeitpunkt, Browser) sowie Ihre personenbezogenen Kontaktdaten (E-Mail, Name, Unternehmen) verarbeitet. Zweck: Zugangsverwaltung und Missbrauchsprävention. Speicherdauer: max. 30 Tage nach letztem Zugriff, danach automatische Anonymisierung. Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO. Ihre Rechte gem. Art. 1521 DSGVO (Auskunft, Berichtigung, Löschung, Widerspruch): pitch@breakpilot.ai. Aufsichtsbehörde: LfDI Baden-Württemberg (www.baden-wuerttemberg.datenschutz.de).
</p>
<p style="margin:0;font-size:10px;color:rgba(255,255,255,0.12);line-height:1.5;">
When you access the link above, technical access data (IP address, timestamp, browser) and your personal contact data (email, name, company) are processed. Purpose: access management and misuse prevention. Retention: max. 30 days after last access, then automatic anonymisation. Legal basis: Art. 6(1)(f) GDPR. Your rights under Art. 1521 GDPR (access, rectification, erasure, objection): pitch@breakpilot.ai. Supervisory authority: LfDI Baden-Württemberg (www.baden-wuerttemberg.datenschutz.de).
</p>
<p style="margin:8px 0 0;font-size:10px;color:rgba(255,255,255,0.15);line-height:1.5;">
Verantwortlich / Controller: Benjamin Bönisch &amp; Sharang Parnerkar · Kontakt / Contact: info@breakpilot.com
</p>
</td>
</tr>
</table>
</td>
</tr>
</table>
</body>
</html>
`,
})
}