Project Content
+This is the base template. Add your project content here.
+diff --git a/BCT-Base/Logo.png b/BCT-Base/Logo.png new file mode 100644 index 0000000..22e4ac3 Binary files /dev/null and b/BCT-Base/Logo.png differ diff --git a/BCT-Base/index.html b/BCT-Base/index.html new file mode 100644 index 0000000..aded436 --- /dev/null +++ b/BCT-Base/index.html @@ -0,0 +1,55 @@ + + + +
+ + + +
+ Beyond Cloud Technology - Project Title
+ Project Description Goes Here
+ + + Watch on YouTube @beyondcloudtechnology + +This is the base template. Add your project content here.
+Advanced SMTP Configuration & Delivery Testing Utility
+ + + Watch on YouTube @beyondcloudtechnology + @@ -73,6 +86,7 @@ @@ -134,6 +148,10 @@ Test Configuration & Send Email + diff --git a/public/script.js b/public/script.js index 7229373..a17a29a 100644 --- a/public/script.js +++ b/public/script.js @@ -65,3 +65,96 @@ document.getElementById('smtpForm').addEventListener('submit', async function(e) btnText.textContent = 'Test Configuration & Send Email'; } }); + +// Auto Discovery Test Handler +document.getElementById('autoTestBtn').addEventListener('click', async function() { + const btn = document.getElementById('autoTestBtn'); + const spinner = btn.querySelector('.loading-spinner'); + const btnText = btn.querySelector('.btn-text'); + const resultsDiv = document.getElementById('results'); + const statusDiv = document.getElementById('statusMessage'); + const logOutput = document.getElementById('logOutput'); + + // Get form data + const form = document.getElementById('smtpForm'); + const formData = new FormData(form); + const data = Object.fromEntries(formData.entries()); + + // Only need host, user, pass, from, to for auto test + const autoTestData = { + host: data.host, + user: data.user, + pass: data.pass, + from: data.from, + to: data.to + }; + + // Reset UI + resultsDiv.classList.add('hidden'); + statusDiv.className = 'status-message'; + statusDiv.textContent = ''; + logOutput.textContent = ''; + + // Set Loading State + btn.disabled = true; + spinner.classList.remove('hidden'); + btnText.textContent = 'Testing All Configurations...'; + + try { + const response = await fetch('/api/auto-test-smtp', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify(autoTestData), + }); + + const result = await response.json(); + + // Show Results + resultsDiv.classList.remove('hidden'); + + if (result.success) { + statusDiv.classList.add('status-success'); + statusDiv.textContent = `✅ ${result.message}`; + + // Format detailed results + let detailedOutput = `Total Tests: ${result.totalTests}\n`; + detailedOutput += `Successful: ${result.successfulConfigs}\n`; + detailedOutput += `Failed: ${result.totalTests - result.successfulConfigs}\n\n`; + detailedOutput += '─'.repeat(50) + '\n\n'; + + result.results.forEach((test, index) => { + detailedOutput += `Test ${index + 1}: ${test.config}\n`; + detailedOutput += ` Port: ${test.port}\n`; + detailedOutput += ` Encryption: ${test.secure ? 'SSL/TLS' : 'STARTTLS'}\n`; + detailedOutput += ` Status: ${test.status === 'success' ? '✅ SUCCESS' : '❌ FAILED'}\n`; + + if (test.status === 'success') { + detailedOutput += ` Email Sent: ${test.messageId}\n`; + } else { + detailedOutput += ` Error: ${test.error}\n`; + } + + detailedOutput += '\n'; + }); + + logOutput.textContent = detailedOutput; + } else { + statusDiv.classList.add('status-error'); + statusDiv.textContent = '❌ Error: ' + result.message; + logOutput.textContent = result.error || 'Unknown error occurred.'; + } + + } catch (error) { + resultsDiv.classList.remove('hidden'); + statusDiv.classList.add('status-error'); + statusDiv.textContent = '❌ Network Error'; + logOutput.textContent = error.toString(); + } finally { + // Reset Button + btn.disabled = false; + spinner.classList.add('hidden'); + btnText.textContent = '🔍 Auto Discovery Test'; + } +}); diff --git a/public/styles.css b/public/styles.css index 2c24b32..07b5238 100644 --- a/public/styles.css +++ b/public/styles.css @@ -88,6 +88,7 @@ body { gap: 1rem; background: linear-gradient(135deg, #fff 0%, #cbd5e1 100%); -webkit-background-clip: text; + background-clip: text; -webkit-text-fill-color: transparent; } @@ -104,9 +105,38 @@ body { font-weight: 400; } +.youtube-link { + display: inline-flex; + align-items: center; + gap: 0.5rem; + margin-top: 1rem; + padding: 0.6rem 1.2rem; + background: rgba(255, 0, 0, 0.1); + border: 1px solid rgba(255, 0, 0, 0.3); + border-radius: var(--radius-md); + color: #ff6b6b; + text-decoration: none; + font-size: 0.9rem; + font-weight: 500; + transition: all 0.3s ease; +} + +.youtube-link:hover { + background: rgba(255, 0, 0, 0.2); + border-color: rgba(255, 0, 0, 0.5); + transform: translateY(-2px); + box-shadow: 0 4px 12px rgba(255, 0, 0, 0.3); +} + +.youtube-icon { + width: 20px; + height: 20px; +} + /* Panel */ .panel { background: var(--bg-glass); + -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px); border: 1px solid rgba(255, 255, 255, 0.1); border-radius: var(--radius-lg); @@ -238,6 +268,28 @@ select:focus { transform: translateY(0); } +.btn-secondary { + background: linear-gradient(135deg, #10b981, #059669); + color: white; + box-shadow: 0 4px 12px rgba(16, 185, 129, 0.4); +} + +.btn-secondary:hover { + transform: translateY(-2px); + box-shadow: 0 6px 16px rgba(16, 185, 129, 0.5); +} + +.btn-secondary:active { + transform: translateY(0); +} + +.form-actions { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); + gap: 1rem; + margin-bottom: var(--spacing-md); +} + .btn:disabled { opacity: 0.7; cursor: not-allowed; diff --git a/server.js b/server.js index 2b8d8b0..d5b87c4 100644 --- a/server.js +++ b/server.js @@ -29,7 +29,7 @@ app.post('/api/test-smtp', async (req, res) => { ); // Create Transporter - const transporter = nodemailer.createTransport({ + const transporterConfig = { host: host, port: parseInt(port), secure: secure === true || secure === "true", // true for 465, false for other ports @@ -37,10 +37,16 @@ app.post('/api/test-smtp', async (req, res) => { user: user, pass: pass, }, - tls: { + }; + + // Only add TLS settings if secure is not explicitly "none" + if (secure !== "none") { + transporterConfig.tls = { rejectUnauthorized: false, // Allow self-signed certs for testing flexibility - }, - }); + }; + } + + const transporter = nodemailer.createTransport(transporterConfig); try { // 1. Verify Connection @@ -53,22 +59,128 @@ app.post('/api/test-smtp', async (req, res) => { to: to, subject: "SMTP Test - Advanced SMTP Tester", html: ` -This email confirms that your SMTP settings are correct.
-Generated by Advanced SMTP Tester
-| + + | +
| + + | +