\section{Email Küldés Backend-ből}

\begin{frame}{Miért kell email küldés a backend-ből?}
  \begin{block}{Gyakori felhasználási esetek}
    \begin{itemize}
      \item \textbf{Regisztráció megerősítés} - Verification email
      \item \textbf{Jelszó visszaállítás} - Password reset link
      \item \textbf{Értesítések} - Rendelés visszaigazolás, státusz változás
      \item \textbf{Marketing emailek} - Newsletter, promóciók
      \item \textbf{Rendszer értesítések/ Jelentések} - Hibák, figyelmeztetések - Napi/heti összesítők
    \end{itemize}
  \end{block}
  
  \begin{alertblock}{Miért backend-ből?}
    \begin{itemize}
      \item Biztonság: SMTP hitelesítési adatok nem kerülnek a kliens oldalra
      \item Megbízhatóság: szerver oldali retry logika
      \item Komplexitás: template renderelés, csatolmányok
      \item Skálázhatóság: külön email queue kezelés
    \end{itemize}
  \end{alertblock}
\end{frame}

\begin{frame}{Email protokollok}
  \begin{block}{SMTP - Simple Mail Transfer Protocol}
    \begin{itemize}
      \item Email \textbf{küldésére} használt standard protokoll
      \item Port: 25 (alap), 587 (TLS), 465 (SSL)
      \item Autentikáció: username + password vagy API key
    \end{itemize}
  \end{block}
  
  \begin{block}{Egyéb protokollok}
    \begin{description}
      \item[IMAP] Email fogadás és szinkronizálás (Port 143/993)
      \item[POP3] Email letöltés (Port 110/995)
      \item[HTTP API] Modern email szolgáltatók (SendGrid, Mailgun)
    \end{description}
  \end{block}
\end{frame}

\begin{frame}{Email protokollok - Backend használat}
  \begin{exampleblock}{Backend használat}
    Backend fejlesztésben jellemzően csak \textbf{SMTP}-t vagy \textbf{HTTP API}-t használunk email küldésre
  \end{exampleblock}
\end{frame}

\begin{frame}[fragile]{Nodemailer - A legnépszerűbb Node.js email könyvtár}
  \begin{block}{Telepítés}
\small
\begin{lstlisting}[language=bash]
npm install nodemailer
\end{lstlisting}
  \end{block}
  
  \begin{block}{Jellemzők}
    \begin{itemize}
      \item SMTP támogatás
      \item HTML és plain text emailek
      \item Csatolmányok (attachments)
      \item Beágyazott képek (inline images)
      \item Unicode támogatás
      \item Stream támogatás nagyméretű csatolmányokhoz
      \item OAuth2 autentikáció
    \end{itemize}
  \end{block}
\end{frame}

\begin{frame}[fragile]{Nodemailer alapok - Transporter létrehozása (1/3)}
  \begin{exampleblock}{Import és konfiguráció Object}
\small
\begin{lstlisting}[language=JavaScript]
const nodemailer = require('nodemailer');

const config = {
  host: 'smtp.example.com',
  port: 587,
  secure: false,
  auth: {
\end{lstlisting}
  \end{exampleblock}
\end{frame}

\begin{frame}[fragile]{Nodemailer alapok - Transporter létrehozása (2/4)}
  \begin{exampleblock}{Auth és zárás}
\small
\begin{lstlisting}[language=JavaScript]
    user: 'your-email@example.com',
    pass: 'your-password'
  }
};
\end{lstlisting}
  \end{exampleblock}
\end{frame}

\begin{frame}[fragile]{Nodemailer alapok - Transporter létrehozása (3/4)}
  \begin{exampleblock}{Transporter létrehozása}
\small
\begin{lstlisting}[language=JavaScript]
// Transporter létrehozása SMTP-vel
const transporter = nodemailer.createTransport(config);
\end{lstlisting}
  \end{exampleblock}
\end{frame}

\begin{frame}[fragile]{Nodemailer alapok - Transporter létrehozása (4/4)}
  \begin{exampleblock}{Transporter ellenőrzés}
\small
\begin{lstlisting}[language=JavaScript]
// Ellenőrzés
transporter.verify((error, success) => {
  if (error) {
    console.log('SMTP connection error:', error);
  } else {
    console.log('Server is ready to send emails');
  }
});
\end{lstlisting}
  \end{exampleblock}
\end{frame}

\begin{frame}[fragile]{Egyszerű email küldés (1/3)}
  \begin{exampleblock}{Mail options megadása}
\small
\begin{lstlisting}[language=JavaScript]
const mailOptions = {
  from: '"Sender Name" <sender@example.com>',
  to: 'recipient@example.com',
  subject: 'Test Email',
  text: 'This is a plain text email message.'
};
\end{lstlisting}
  \end{exampleblock}
\end{frame}

\begin{frame}[fragile]{Egyszerű email küldés (2/3)}
  \begin{exampleblock}{Email küldés callback-kel}
\small
\begin{lstlisting}[language=JavaScript]
transporter.sendMail(mailOptions, (error, info) => {
  if (error) {
    console.log('Error sending email:', error);
  } else {
    console.log('Email sent:', info.messageId);
  }
});
\end{lstlisting}
  \end{exampleblock}
\end{frame}

\begin{frame}[fragile]{Egyszerű email küldés (3/3)}
  \begin{exampleblock}{Async/await használattal}
\small
\begin{lstlisting}[language=JavaScript]
async function sendEmail() {
  try {
    const info = await transporter.sendMail(mailOptions);
    console.log('Email sent:', info.messageId);
    return info;
  } catch (error) {
    console.error('Error sending email:', error);
    throw error;
  }
}
\end{lstlisting}
  \end{exampleblock}
\end{frame}

\begin{frame}[fragile]{HTML email küldés (1/3)}
  \begin{exampleblock}{HTML mail options - Alapadatok}
\small
\begin{lstlisting}[language=JavaScript]
const mailOptions = {
  from: '"Company Name" <noreply@company.com>',
  to: 'user@example.com',
  subject: 'Welcome to Our Service!',
  html: `
    <h1>Welcome!</h1>
    <p>Thank you for registering.</p>
    <p>Click below to verify your email:</p>
\end{lstlisting}
  \end{exampleblock}
\end{frame}

\begin{frame}[fragile]{HTML email küldés (2/4)}
  \begin{exampleblock}{HTML mail options - Gomb stílusok}
\small
\begin{lstlisting}[language=JavaScript]
    <a href="https://example.com/verify?token=abc123"
       style="background-color: #4CAF50; 
              color: white; padding: 10px 20px; 
              text-decoration: none;
              display: inline-block; 
              border-radius: 4px;">
      Verify Email
    </a>
\end{lstlisting}
  \end{exampleblock}
\end{frame}

\begin{frame}[fragile]{HTML email küldés (3/4)}
  \begin{exampleblock}{HTML mail options - Lezárás}
\small
\begin{lstlisting}[language=JavaScript]
    <p>Best regards,<br>The Team</p>
  `,
\end{lstlisting}
  \end{exampleblock}
\end{frame}

\begin{frame}[fragile]{HTML email küldés (4/5)}
  \begin{exampleblock}{Plain text alternatíva}
\small
\begin{lstlisting}[language=JavaScript]
  text: 'Welcome! Verify your email: \n
    https://example.com/verify?token=abc123'
};
\end{lstlisting}
  \end{exampleblock}
\end{frame}

\begin{frame}[fragile]{HTML email küldés (5/5)}
  \begin{exampleblock}{Email küldés}
\small
\begin{lstlisting}[language=JavaScript]
await transporter.sendMail(mailOptions);
\end{lstlisting}
  \end{exampleblock}
  
  \begin{alertblock}{Fontos}
    Mindig adj meg \texttt{text} alternatívát a \texttt{html} mellett!
  \end{alertblock}
\end{frame}

\begin{frame}[fragile]{Több címzett és CC/BCC (1/3)}
  \begin{exampleblock}{Több címzett kezelése}
\small
\begin{lstlisting}[language=JavaScript]
const mailOptions = {
  from: 'sender@example.com',
  // Több címzett vesszővel
  to: 'user1@example.com, user2@example.com',
  // Vagy tömbként
  to: ['user1@example.com', 'user2@example.com'],
\end{lstlisting}
  \end{exampleblock}
\end{frame}

\begin{frame}[fragile]{Több címzett és CC/BCC (2/3)}
  \begin{exampleblock}{CC és BCC}
\small
\begin{lstlisting}[language=JavaScript]
  // CC - Carbon Copy (látható másolat)
  cc: 'manager@example.com',
  // BCC - Blind Carbon Copy (rejtett másolat)
  bcc: ['admin@example.com', 'audit@example.com'],
\end{lstlisting}
  \end{exampleblock}
\end{frame}

\begin{frame}[fragile]{Több címzett és CC/BCC (3/3)}
  \begin{exampleblock}{Email küldés}
\small
\begin{lstlisting}[language=JavaScript]
  subject: 'Team Notification',
  text: 'This message is sent to multiple \n
    recipients'
};

await transporter.sendMail(mailOptions);
\end{lstlisting}
  \end{exampleblock}
  
  \begin{alertblock}{Tömeges email küldés}
    Sok címzetthez NE egy emailben küld! Használj email service provider-t vagy queue-t!
  \end{alertblock}
\end{frame}

\begin{frame}[fragile]{Csatolmányok (Attachments) (1/3)}
  \begin{exampleblock}{Fájl csatolása - Mail options}
\small
\begin{lstlisting}[language=JavaScript]
const mailOptions = {
  from: 'sender@example.com',
  to: 'recipient@example.com',
  subject: 'Invoice',
  text: 'Please find your invoice attached.',
  attachments: [
\end{lstlisting}
  \end{exampleblock}
\end{frame}

\begin{frame}[fragile]{Csatolmányok (Attachments) (2/3)}
  \begin{exampleblock}{Fájl csatolása - Fájlok}
\small
\begin{lstlisting}[language=JavaScript]
    {
      filename: 'invoice.pdf',
      path: '/path/to/invoice.pdf'
    },
    {
      filename: 'report.xlsx',
\end{lstlisting}
  \end{exampleblock}
\end{frame}

\begin{frame}[fragile]{Csatolmányok (Attachments) (3/4)}
  \begin{exampleblock}{Buffer és String csatolmányok}
\small
\begin{lstlisting}[language=JavaScript]
      path: '/path/to/report.xlsx'
    },
    {
      // Buffer-ből
      filename: 'data.txt',
      content: Buffer.from('File content here')
    },
\end{lstlisting}
  \end{exampleblock}
\end{frame}

\begin{frame}[fragile]{Csatolmányok (Attachments) (4/4)}
  \begin{exampleblock}{String tartalom és küldés}
\small
\begin{lstlisting}[language=JavaScript]
    {
      // String-ből
      filename: 'info.txt',
      content: 'Text content'
    }
  ]
};

await transporter.sendMail(mailOptions);
\end{lstlisting}
  \end{exampleblock}
\end{frame}

\begin{frame}[fragile]{Beágyazott képek (Inline Images) (1/3)}
  \begin{exampleblock}{HTML struktúra CID-vel}
\small
\begin{lstlisting}[language=JavaScript]
const mailOptions = {
  from: 'sender@example.com',
  to: 'recipient@example.com',
  subject: 'Email with Image',
  html: `
    <h1>Company Logo</h1>
    <img src="cid:logo" alt="Logo" style="width: 200px;"/>
    <p>Email content here...</p>
\end{lstlisting}
  \end{exampleblock}
\end{frame}

\begin{frame}[fragile]{Beágyazott képek (Inline Images) (2/3)}
  \begin{exampleblock}{HTML és attachments}
\small
\begin{lstlisting}[language=JavaScript]
    <img src="cid:banner" alt="Banner"/>
  `,
\end{lstlisting}
  \end{exampleblock}
   \begin{exampleblock}{Attachments list}
\small
\begin{lstlisting}[language=JavaScript]
  attachments: [
    {
      filename: 'logo.png',
      path: '/path/to/logo.png',
      cid: 'logo'  // Content-ID referencia
    },
\end{lstlisting}
  \end{exampleblock}
\end{frame}


\begin{frame}[fragile]{Beágyazott képek (Inline Images) (3/3)}
  \begin{exampleblock}{Banner és küldés}
\small
\begin{lstlisting}[language=JavaScript]
    {
      filename: 'banner.jpg',
      path: '/path/to/banner.jpg',
      cid: 'banner'
    }
  ]
};

await transporter.sendMail(mailOptions);
\end{lstlisting}
  \end{exampleblock}
\end{frame}

\begin{frame}[fragile]{Gmail használata SMTP-vel}
  \begin{exampleblock}{Gmail konfiguráció}
\small
\begin{lstlisting}[language=JavaScript]
const transporter = nodemailer.createTransport({
  service: 'gmail',  // Előre konfigurált service
  auth: {
    user: 'your-email@gmail.com',
    pass: 'your-app-password'  // NEM a normál jelszó!}
  });
\end{lstlisting}
  \end{exampleblock}
  
  \begin{alertblock}{App Password szükséges!}
    \begin{enumerate}
      \item Gmail Account Settings $\rightarrow$ Security
      \item 2-Step Verification bekapcsolása
      \item App passwords létrehozása
      \item Az generált app password használata
    \end{enumerate}
  \end{alertblock}
\end{frame}

\begin{frame}{Gmail korlátozások}
  \begin{alertblock}{Korlátozások}
    \begin{itemize}
      \item Gmail: max 500 email/nap
      \item Production környezetben NE használj Gmail-t!
    \end{itemize}
  \end{alertblock}
\end{frame}

\begin{frame}[fragile]{Email Service Provider - SendGrid példa}
  \begin{block}{Miért használj ESP-t?}
    \begin{itemize}
      \item Magas kézbesítési arány (deliverability)
      \item Spam szűrők elkerülése
      \item Analytics és tracking
      \item Skálázhatóság
      \item Email validáció és bounce kezelés
    \end{itemize}
  \end{block}
  
  \begin{exampleblock}{SendGrid telepítés}
\small
\begin{lstlisting}[language=bash]
npm install @sendgrid/mail
\end{lstlisting}
  \end{exampleblock}
\end{frame}

\begin{frame}[fragile]{SendGrid használat (1/2)}
  \begin{exampleblock}{SendGrid inicializálás}
\small
\begin{lstlisting}[language=JavaScript]
const sgMail = require('@sendgrid/mail');
sgMail.setApiKey(process.env.SENDGRID_API_KEY);

const msg = {
  to: 'recipient@example.com',
  from: 'sender@verified-domain.com',
  subject: 'Hello from SendGrid',
\end{lstlisting}
  \end{exampleblock}
\end{frame}

\begin{frame}[fragile]{SendGrid használat (2/2)}
  \begin{exampleblock}{SendGrid email küldés}
\small
\begin{lstlisting}[language=JavaScript]
  text: 'Plain text content',
  html: '<strong>HTML content</strong>'
};

await sgMail.send(msg);
\end{lstlisting}
  \end{exampleblock}
\end{frame}

\begin{frame}[fragile]{Nodemailer SendGrid-del (1/2)}
  \begin{exampleblock}{SendGrid SMTP-n keresztül Nodemailer-rel}
\small
\begin{lstlisting}[language=JavaScript]
const nodemailer = require('nodemailer');

const transporter = nodemailer.createTransport({
  host: 'smtp.sendgrid.net',
  port: 587,
  auth: {
    user: 'apikey',
\end{lstlisting}
  \end{exampleblock}
\end{frame}

\begin{frame}[fragile]{Nodemailer SendGrid-del (2/4)}
  \begin{exampleblock}{Auth konfiguráció}
\small
\begin{lstlisting}[language=JavaScript]
    pass: process.env.SENDGRID_API_KEY
  }
});
\end{lstlisting}
  \end{exampleblock}
\end{frame}

\begin{frame}[fragile]{Nodemailer SendGrid-del (3/4)}
  \begin{exampleblock}{Mail options}
\small
\begin{lstlisting}[language=JavaScript]
const mailOptions = {
  from: 'verified-sender@yourdomain.com',
  to: 'recipient@example.com',
  subject: 'Email via SendGrid SMTP',
  html: '<h1>Hello from SendGrid!</h1>'
};
\end{lstlisting}
  \end{exampleblock}
\end{frame}

\begin{frame}[fragile]{Nodemailer SendGrid-del (4/4)}
  \begin{exampleblock}{Email küldés}
\small
\begin{lstlisting}[language=JavaScript]
try {
  const info = await transporter.sendMail(mailOptions);
  console.log('Email sent:', info.messageId);
} catch (error) {
  console.error('Error:', error);
}
\end{lstlisting}
  \end{exampleblock}
\end{frame}

\begin{frame}{Email Service Providers összehasonlítás}
  \begin{table}
    \small
    \begin{tabular}{l|l|l|l}
      \textbf{Szolgáltató} & \textbf{Ingyenes limit} & \textbf{Jellemzők} & \textbf{Ár} \\
      \hline
      SendGrid & 100/nap & Kiváló docs, sablonok & \$19.95/hó \\
      Mailgun & 5000/hó & Fejlesztő-barát API & \$35/hó \\
      Amazon SES & 62000/hó & AWS integráció & \$0.10/1000 \\
      Postmark & 100/hó & Transactional spec. & \$15/hó \\
      Resend & 3000/hó & Modern, egyszerű & \$20/hó \\
    \end{tabular}
  \end{table}
  
  \begin{block}{Választási szempontok}
    \begin{itemize}
      \item \textbf{Mennyiség}: hány email/hó szükséges?
      \item \textbf{Típus}: transactional vs marketing?
      \item \textbf{Funkciók}: analytics, webhooks, sablonok?
      \item \textbf{Ár}: költségvetés
      \item \textbf{Kézbesíthetőség}: deliverability rate
    \end{itemize}
  \end{block}
\end{frame}

\begin{frame}[fragile]{Email küldés Express route-ban (1/4)}
  \begin{exampleblock}{Express setup}
\small
\begin{lstlisting}[language=JavaScript]
const express = require('express');
const nodemailer = require('nodemailer');
const app = express();

app.use(express.json());
\end{lstlisting}
  \end{exampleblock}
\end{frame}

\begin{frame}[fragile]{Email küldés Express route-ban (2/4)}
  \begin{exampleblock}{Transporter konfiguráció}
\small
\begin{lstlisting}[language=JavaScript]
const transporter = nodemailer.createTransport({
  host: process.env.SMTP_HOST,
  port: process.env.SMTP_PORT,
  auth: {
    user: process.env.SMTP_USER,
\end{lstlisting}
  \end{exampleblock}
\end{frame}

\begin{frame}[fragile]{Email küldés Express route-ban (3/4)}
  \begin{exampleblock}{Auth és route}
\small
\begin{lstlisting}[language=JavaScript]
    pass: process.env.SMTP_PASS
  }
});

app.post('/api/register', async (req, res) => {
  const { email, username } = req.body;
  
  try {
\end{lstlisting}
  \end{exampleblock}
\end{frame}

\begin{frame}[fragile]{Email küldés Express route-ban (4/5)}
  \begin{exampleblock}{User mentés és token}
\small
\begin{lstlisting}[language=JavaScript]
    // User mentése adatbázisba (példa)
    // const user = await saveUser({ email, username });
    const verificationToken = generateToken();
    
\end{lstlisting}
  \end{exampleblock}
\end{frame}

\begin{frame}[fragile]{Email küldés Express route-ban (5/6)}
  \begin{exampleblock}{Email küldés - sendMail}
\small
\begin{lstlisting}[language=JavaScript]
    // Email küldés
    await transporter.sendMail({
      from: '"MyApp" <noreply@myapp.com>',
      to: email,
      subject: 'Verify your email',
      html: `<h1>Welcome ${username}!</h1>
        <p>Click to verify: 
\end{lstlisting}
  \end{exampleblock}
\end{frame}

\begin{frame}[fragile]{Email küldés Express route-ban (6/6)}
  \begin{exampleblock}{Email küldés - zárás és válasz}
\small
\begin{lstlisting}[language=JavaScript]
           <a href="https://myapp.com/verify?token=${verificationToken}">
             Verify Email</a></p>`
    });
    res.json({ message: 'Registration successful, check email' });
  } catch (error) {
    res.status(500).json({ error: 'Registration failed' });
  }
});
\end{lstlisting}
  \end{exampleblock}
\end{frame}

\begin{frame}[fragile]{Email Service osztály - Clean Architecture (1/4)}
  \begin{exampleblock}{EmailService class}
\small
\begin{lstlisting}[language=JavaScript]
class EmailService {
  constructor(transporter) {
    this.transporter = transporter;
  }
  
  async sendWelcomeEmail(user) {
    const mailOptions = {
      from: '"MyApp" <noreply@myapp.com>',
      to: user.email,
\end{lstlisting}
  \end{exampleblock}
\end{frame}

\begin{frame}[fragile]{Email Service osztály - Clean Architecture (2/4)}
  \begin{exampleblock}{EmailService sendWelcomeEmail}
\small
\begin{lstlisting}[language=JavaScript]
      subject: 'Welcome to MyApp!',
      html: `<h1>Welcome ${user.username}!</h1>`
    };
    return await this.transporter.sendMail(mailOptions);
  }
\end{lstlisting}
  \end{exampleblock}
\end{frame}

\begin{frame}[fragile]{Email Service osztály - Clean Architecture (3/4)}
  \begin{exampleblock}{EmailService sendPasswordReset}
\small
\begin{lstlisting}[language=JavaScript]
  async sendPasswordReset(email, resetToken) {
    const resetUrl = `${process.env.APP_URL}/reset?token=${resetToken}`;
    return await this.transporter.sendMail({
      from: '"MyApp" <noreply@myapp.com>',
      to: email,
\end{lstlisting}
  \end{exampleblock}
\end{frame}

\begin{frame}[fragile]{Email Service osztály - Clean Architecture (4/5)}
  \begin{exampleblock}{sendPasswordReset (folytatás)}
\small
\begin{lstlisting}[language=JavaScript]
      subject: 'Password Reset Request',
      html: `<h2>Password Reset</h2>
        <p>Click here to reset your password:</p>
        <a href="${resetUrl}">Reset Password</a>
        <p>This link expires in 1 hour.</p>`
    });
  }
\end{lstlisting}
  \end{exampleblock}
\end{frame}

\begin{frame}[fragile]{Email Service osztály - Clean Architecture (5/5)}
  \begin{exampleblock}{EmailService sendOrderConfirmation}
\small
\begin{lstlisting}[language=JavaScript]
  async sendOrderConfirmation(order) {
    return await this.transporter.sendMail({
      from: '"Shop" <orders@shop.com>',
      to: order.customerEmail,
      subject: `Order Confirmation #${order.id}`,
      html: this.renderOrderTemplate(order) });
  }
}
module.exports = EmailService;
\end{lstlisting}
  \end{exampleblock}
\end{frame}

\begin{frame}[fragile]{EmailService használata DI-val (1/4)}
  \begin{exampleblock}{Transporter setup}
\small
\begin{lstlisting}[language=JavaScript]
// app.js - Setup
const nodemailer = require('nodemailer');
const EmailService = require('./services/EmailService');

const transporter = nodemailer.createTransport({
  host: process.env.SMTP_HOST,
  port: process.env.SMTP_PORT,
\end{lstlisting}
  \end{exampleblock}
\end{frame}

\begin{frame}[fragile]{EmailService használata DI-val (2/5)}
  \begin{exampleblock}{Auth}
\small
\begin{lstlisting}[language=JavaScript]
  auth: {
    user: process.env.SMTP_USER,
    pass: process.env.SMTP_PASS
  }
});
\end{lstlisting}
  \end{exampleblock}
\end{frame}

\begin{frame}[fragile]{EmailService használata DI-val (3/5)}
  \begin{exampleblock}{EmailService inicializálás}
\small
\begin{lstlisting}[language=JavaScript]
const emailService = new EmailService(transporter);
\end{lstlisting}
  \end{exampleblock}
\end{frame}

\begin{frame}[fragile]{EmailService használata DI-val (4/5)}
  \begin{exampleblock}{Route használat}
\small
\begin{lstlisting}[language=JavaScript]
// Route-okban használat
app.post('/api/register', async (req, res) => {
  try {
    const user = await userService.createUser(req.body);
    await emailService.sendWelcomeEmail(user);
    
\end{lstlisting}
  \end{exampleblock}
\end{frame}

\begin{frame}[fragile]{EmailService használata DI-val (5/5)}
  \begin{exampleblock}{Register route - válasz}
\small
\begin{lstlisting}[language=JavaScript]
    res.json({ message: 'Registration successful' });
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});
\end{lstlisting}
  \end{exampleblock}
\end{frame}

\begin{frame}[fragile]{EmailService használata DI-val (6/6)}
  \begin{exampleblock}{Forgot password route}
\small
\begin{lstlisting}[language=JavaScript]
app.post('/api/forgot-password', async (req, res) => {
  try {
    const resetToken = await userService.generateResetToken(req.body.email);
    await emailService.sendPasswordReset(req.body.email, resetToken);
    res.json({ message: 'Password reset email sent' });
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});
\end{lstlisting}
  \end{exampleblock}
\end{frame}

\begin{frame}[fragile]{Hibakezelés és retry logika (1/4)}
  \begin{exampleblock}{Retry mechanizmus - Setup}
\small
\begin{lstlisting}[language=JavaScript]
class EmailService {
  async sendEmailWithRetry(mailOptions, maxRetries = 3) {
    for (let attempt = 1; attempt <= maxRetries; attempt++) {
      try {
        const info = await this.transporter.sendMail(mailOptions);
        console.log(`Email sent on attempt ${attempt}:`, info.messageId);
\end{lstlisting}
  \end{exampleblock}
\end{frame}

\begin{frame}[fragile]{Hibakezelés és retry logika (2/4)}
  \begin{exampleblock}{Retry mechanizmus - Return és error}
\small
\begin{lstlisting}[language=JavaScript]
        return info;
      } catch (error) {
\end{lstlisting}
  \end{exampleblock}
\end{frame}

\begin{frame}[fragile]{Hibakezelés és retry logika (3/4)}
  \begin{exampleblock}{Error handling és backoff}
\small
\begin{lstlisting}[language=JavaScript]
        console.error(`Attempt ${attempt} failed:`, error.message);
        if (attempt === maxRetries) {
          // Utolsó próbálkozás sikertelen
          throw new Error(`Failed to send email after ${maxRetries} attempts`);
        }
        
        // Exponential backoff: 1s, 2s, 4s...
        const delay = Math.pow(2, attempt - 1) * 1000;
\end{lstlisting}
  \end{exampleblock}
\end{frame}

\begin{frame}[fragile]{Hibakezelés és retry logika (4/5)}
  \begin{exampleblock}{Exponential backoff}
\small
\begin{lstlisting}[language=JavaScript]
        await new Promise(resolve => setTimeout(resolve, delay));
      }
    }
  }
\end{lstlisting}
  \end{exampleblock}
\end{frame}

\begin{frame}[fragile]{Hibakezelés és retry logika (5/6)}
  \begin{exampleblock}{sendWelcomeEmail setup}
\small
\begin{lstlisting}[language=JavaScript]
  async sendWelcomeEmail(user) {
    const mailOptions = {
      from: '"MyApp" <noreply@myapp.com>',
      to: user.email,
      subject: 'Welcome!',
      html: `<h1>Welcome ${user.username}!</h1>`
    };
    
\end{lstlisting}
  \end{exampleblock}
\end{frame}

\begin{frame}[fragile]{Hibakezelés és retry logika (6/6)}
  \begin{exampleblock}{sendEmailWithRetry call}
\small
\begin{lstlisting}[language=JavaScript]
    return await this.sendEmailWithRetry(mailOptions);
  }
}
\end{lstlisting}
  \end{exampleblock}
\end{frame}

\begin{frame}[fragile]{Email queue - Bull használatával}
  \begin{block}{Miért kell queue?}
    \begin{itemize}
      \item Email küldés lassú (network I/O)
      \item User ne várjon a válaszra
      \item Megbízhatóság: retry failed jobs
      \item Rate limiting kezelése
    \end{itemize}
  \end{block}
  
  \begin{exampleblock}{Bull telepítés}
\small
\begin{lstlisting}[language=bash]
npm install bull redis
\end{lstlisting}
  \end{exampleblock}
\end{frame}

\begin{frame}[fragile]{Email queue - Queue létrehozás}
  \begin{exampleblock}{Queue létrehozás}
\small
\begin{lstlisting}[language=JavaScript]
const Queue = require('bull');

const emailQueue = new Queue('email', {
  redis: {
    host: process.env.REDIS_HOST || 'localhost',
    port: process.env.REDIS_PORT || 6379
  }
});

module.exports = emailQueue;
\end{lstlisting}
  \end{exampleblock}
\end{frame}

\begin{frame}[fragile]{Email queue - Job feldolgozás (1/3)}
  \begin{exampleblock}{Worker létrehozása}
\small
\begin{lstlisting}[language=JavaScript]
const emailQueue = require('./emailQueue');
const EmailService = require('./services/EmailService');

const emailService = new EmailService(transporter);

// Job processor
emailQueue.process(async (job) => {
  const { type, data } = job.data;
  console.log(`Processing email job: ${type}`);
\end{lstlisting}
  \end{exampleblock}
\end{frame}

\begin{frame}[fragile]{Email queue - Job feldolgozás (2/3)}
  \begin{exampleblock}{Switch case processing}
\small
\begin{lstlisting}[language=JavaScript]
  switch (type) {
    case 'welcome':
      return await emailService.sendWelcomeEmail(data.user);
    case 'order-confirmation':
      return await emailService.sendOrderConfirmation(data.order);
    default:
      throw new Error(`Unknown email type: ${type}`);
  }
});
\end{lstlisting}
  \end{exampleblock}
\end{frame}

\begin{frame}[fragile]{Email queue - Job feldolgozás (3/3)}
  \begin{exampleblock}{Event handlers}
\small
\begin{lstlisting}[language=JavaScript]
// Event handlers
emailQueue.on('completed', (job, result) => {
  console.log(`Job ${job.id} completed:`, result.messageId);
});
emailQueue.on('failed', (job, err) => {
  console.error(`Job ${job.id} failed:`, err.message);
});
\end{lstlisting}
  \end{exampleblock}
\end{frame}

\begin{frame}[fragile]{Email queue - Job hozzáadása (1/4)}
  \begin{exampleblock}{Register route setup}
\small
\begin{lstlisting}[language=JavaScript]
const emailQueue = require('./emailQueue');

app.post('/api/register', async (req, res) => {
  try {
    const user = await userService.createUser(req.body);
    // Email job hozzáadása a queue-hoz
    await emailQueue.add('welcome', {
\end{lstlisting}
  \end{exampleblock}
\end{frame}

\begin{frame}[fragile]{Email queue - Job hozzáadása (2/4)}
  \begin{exampleblock}{Job type és data}
\small
\begin{lstlisting}[language=JavaScript]
      type: 'welcome',
      data: { user }
    }, {
      removeOnComplete: true,
      removeOnFail: false
    });      
\end{lstlisting}
  \end{exampleblock}
\end{frame}

\begin{frame}[fragile]{Email queue - Job hozzáadása (3/4)}
  \begin{exampleblock}{Job configuration és response}
\small
\begin{lstlisting}[language=JavaScript]
    // Azonnal válaszolunk, email küldés háttérben történik
    res.json({ 
      message: 'Registration successful',
      userId: user.id
    });
    } catch (error) {
    res.status(500).json({ error: error.message });
  }
});
\end{lstlisting}
  \end{exampleblock}
\end{frame}

\begin{frame}[fragile]{Email queue - Job hozzáadása (4/4)}
  \begin{exampleblock}{Forgot password route}
\small
\begin{lstlisting}[language=JavaScript]
app.post('/api/forgot-password', async (req, res) => {
  const resetToken = await userService.generateResetToken(req.body.email);
  await emailQueue.add('password-reset', {
    type: 'password-reset',
    data: { email: req.body.email, token: resetToken } });
  res.json({ message: 'If email exists, reset link was sent' });
});
\end{lstlisting}
  \end{exampleblock}
\end{frame}

\begin{frame}[fragile]{Környezeti változók kezelése (1/3)}
  \begin{exampleblock}{.env fájl - SMTP}
\small
\begin{lstlisting}[language=bash]
# SMTP Configuration
SMTP_HOST=smtp.example.com
SMTP_PORT=587
SMTP_USER=your-email@example.com
SMTP_PASS=your-password
\end{lstlisting}
  \end{exampleblock}
\end{frame}

\begin{frame}[fragile]{Környezeti változók kezelése (2/3)}
  \begin{exampleblock}{.env fájl - Email settings}
\small
\begin{lstlisting}[language=bash]
# Email settings
EMAIL_FROM_NAME=MyApp
EMAIL_FROM_ADDRESS=noreply@myapp.com
\end{lstlisting}
  \end{exampleblock}
\end{frame}

\begin{frame}[fragile]{Környezeti változók kezelése (3/4)}
  \begin{exampleblock}{.env fájl (folytatás)}
\small
\begin{lstlisting}[language=bash]
# SendGrid (alternatíva)
SENDGRID_API_KEY=SG.xxxxxx

# Application
APP_URL=https://myapp.com
\end{lstlisting}
  \end{exampleblock}
\end{frame}

\begin{frame}[fragile]{Környezeti változók kezelése (4/5)}
  \begin{exampleblock}{Config betöltése}
\small
\begin{lstlisting}[language=JavaScript]
require('dotenv').config();

const emailConfig = {
  host: process.env.SMTP_HOST,
  port: parseInt(process.env.SMTP_PORT),
\end{lstlisting}
  \end{exampleblock}
\end{frame}

\begin{frame}[fragile]{Környezeti változók kezelése (5/5)}
  \begin{exampleblock}{Auth és transporter}
\small
\begin{lstlisting}[language=JavaScript]
  auth: {
    user: process.env.SMTP_USER,
\end{lstlisting}
  \end{exampleblock}
\end{frame}

\begin{frame}[fragile]{Környezeti változók kezelése (6/6)}
  \begin{exampleblock}{Transporter létrehozás}
\small
\begin{lstlisting}[language=JavaScript]
    pass: process.env.SMTP_PASS
  }
};

const transporter = nodemailer.createTransport(emailConfig);
\end{lstlisting}
  \end{exampleblock}
\end{frame}

\begin{frame}{Best Practices}
  \begin{block}{Biztonsági és fejlesztési ajánlások}
    \footnotesize
    \begin{enumerate}
      \item \textbf{Soha ne hard-code-old credentials}-t - használj környezeti változókat
      \item \textbf{Használj queue-t} production környezetben - ne blokkolj HTTP requesteket
      \item \textbf{Rate limiting} - védd meg magad spam-től
      \item \textbf{Email validáció} - ellenőrizd az email formátumot
      \item \textbf{Unsubscribe link} - marketing emailekhez kötelező
      \item \textbf{SPF, DKIM, DMARC} - domain autentikáció
      \item \textbf{Teszt környezet} - használj Mailtrap/Ethereal development-hez
      \item \textbf{Template-ek} - külön fájlokban tartsd az email template-eket
      \item \textbf{Error logging} - monitorozd a sikertelen küldéseket
      \item \textbf{Bounce handling} - kezeld a visszapattanó email-eket
    \end{enumerate}
  \end{block}
\end{frame}

\begin{frame}[fragile]{Development email teszt - Ethereal Email (1/3)}
  \begin{block}{Ethereal Email}
    Fake SMTP service teszteléshez - https://ethereal.email
  \end{block}
  
  \begin{exampleblock}{Teszt account és config}
\small
\begin{lstlisting}[language=JavaScript]
const nodemailer = require('nodemailer');

// Teszt account létrehozása
const testAccount = await nodemailer.createTestAccount();
\end{lstlisting}
  \end{exampleblock}
\end{frame}

\begin{frame}[fragile]{Development email teszt - Ethereal Email (2/4)}
  \begin{exampleblock}{Transporter létrehozása}
\small
\begin{lstlisting}[language=JavaScript]
const transporter = nodemailer.createTransport({
  host: 'smtp.ethereal.email',
  port: 587,
\end{lstlisting}
  \end{exampleblock}
\end{frame}

\begin{frame}[fragile]{Development email teszt - Ethereal Email (3/4)}
  \begin{exampleblock}{Transporter konfiguráció}
\small
\begin{lstlisting}[language=JavaScript]
  secure: false,
  auth: {
    user: testAccount.user,
    pass: testAccount.pass
  }
});
\end{lstlisting}
  \end{exampleblock}
\end{frame}

\begin{frame}[fragile]{Development email teszt - Ethereal Email (4/4)}
  \begin{exampleblock}{Email küldés és preview}
\small
\begin{lstlisting}[language=JavaScript]
const info = await transporter.sendMail({
  from: '"Test" <test@example.com>',
  to: 'recipient@example.com',
  subject: 'Test Email',
  html: '<h1>This is a test</h1>'
});
// Preview URL - böngészőben megnézhető
console.log('Preview URL:', nodemailer.getTestMessageUrl(info));
\end{lstlisting}
  \end{exampleblock}
\end{frame}

\begin{frame}{Összefoglalás (1/2)}
  \begin{block}{Email küldés backend-ből}
    \begin{itemize}
      \item SMTP protokoll használata
      \item Nodemailer - de facto standard Node.js-hez
      \item HTML, plain text, attachments támogatása
      \item Email Service Providers (SendGrid, Mailgun, SES)
    \end{itemize}
  \end{block}
  
  \begin{block}{Production best practices}
    \begin{itemize}
      \item Queue használata (Bull + Redis)
      \item Retry logika hibák kezelésére
      \item EmailService osztály clean architecture-höz
      \item Környezeti változók biztonságos kezelése
      \item Error logging és monitoring
    \end{itemize}
  \end{block}
\end{frame}

\begin{frame}{Összefoglalás (2/2)}
  \begin{block}{Development}
    \begin{itemize}
      \item Ethereal Email vagy Mailtrap teszteléshez
      \item Ne használj production SMTP-t development-ben
      \item Template-ek külön kezelése (következő téma)
    \end{itemize}
  \end{block}
\end{frame}


