SSL Certificate Checker Tool

SSL Certificate Checker Tool

Lookup Host

Lookup History

Your lookup history will appear here.

${escapeHTML(log.host)}: ${log.status}, expires in ${log.days_left} days.

`).join(''); } function logEntry(data) { const timestamp = new Date().toLocaleString('en-US'); const logItem = { timestamp, host: data.host, status: data.valid ? 'Valid' : 'Invalid', days_left: data.days_left, fullData: data }; lookupLog.unshift(logItem); if (lookupLog.length > 50) lookupLog.pop(); // Limit log size saveState(); renderLog(); } function formatDate(dateStr) { if (!dateStr) return "N/A"; try { return new Date(dateStr).toLocaleString('en-US', { year: 'numeric', month: 'long', day: 'numeric', hour: 'numeric', minute: 'numeric' }); } catch (e) { return dateStr; } } function renderResults(data) { currentResult = data; ui.summaryHost.textContent = escapeHTML(data.host); if (data.valid) { ui.summaryStatus.textContent = "Valid"; ui.summaryStatus.className = "value status-valid"; } else { ui.summaryStatus.textContent = "Invalid / Expired"; ui.summaryStatus.className = "value status-invalid"; } ui.summaryExpires.textContent = `${data.days_left} days`; if (data.days_left <= 0) { ui.summaryExpires.className = "value status-invalid"; } else if (data.days_left < 14) { ui.summaryExpires.className = "value status-warn"; } else { ui.summaryExpires.className = "value status-valid"; } ui.summaryIssuer.textContent = escapeHTML(data.issuer?.O || data.issuer?.CN || 'N/A'); ui.resSubject.textContent = escapeHTML(data.valid_for[0] || 'N/A'); ui.resAlgo.textContent = escapeHTML(data.signature_algorithm || 'N/A'); ui.resValidFrom.textContent = formatDate(data.valid_from); ui.resValidTo.textContent = formatDate(data.valid_to); ui.loader.style.display = 'none'; ui.resultsContainer.style.display = 'block'; } function showMessage(message, isError = true) { ui.errorMsg.textContent = message; ui.errorMsg.style.display = 'block'; } // --- API LOGIC --- function sanitizeHost(host) { return host.trim().replace(/^(https?:\/\/)/, '').replace(/\/.*$/, ''); } async function fetchSslData(host) { ui.loader.style.display = 'block'; ui.resultsContainer.style.display = 'none'; ui.errorMsg.style.display = 'none'; const sanitizedHost = sanitizeHost(host); if (!sanitizedHost) { showMessage("Please enter a valid host name."); ui.loader.style.display = 'none'; return; } try { const response = await fetch(`https://api.ssl.lol/api/check?host=${encodeURIComponent(sanitizedHost)}`); if (!response.ok) { throw new Error(`API returned status ${response.status}`); } const data = await response.json(); if (data.status === 'error' || !data.valid_to) { throw new Error(data.message || 'Invalid or unreachable host.'); } renderResults(data); logEntry(data); } catch (error) { console.error("SSL Fetch Error:", error); showMessage(error.message); } finally { ui.loader.style.display = 'none'; } } // --- PDF LOGIC --- function downloadPDF(type) { const { jsPDF } = window.jspdf; if (!jsPDF || !window.jspdf.autoTable) { alert("PDF library not loaded!"); return; } const doc = new jsPDF(); if (type === 'current') { if (!currentResult.host) { alert("Please run a lookup before downloading."); return; } doc.setFontSize(18); doc.text(`SSL Certificate Report: ${currentResult.host}`, 14, 22); doc.autoTable({ startY: 30, theme: 'grid', body: [ ['Host', currentResult.host], ['Status', currentResult.valid ? 'Valid' : 'Invalid/Expired'], ['Expires In', `${currentResult.days_left} days`], ['Subject', currentResult.valid_for[0] || 'N/A'], ['Issuer', currentResult.issuer?.O || currentResult.issuer?.CN || 'N/A'], ['Valid From', formatDate(currentResult.valid_from)], ['Valid To', formatDate(currentResult.valid_to)], ['Algorithm', currentResult.signature_algorithm], ] }); doc.save(`SSL_Report_${currentResult.host}.pdf`); } else if (type === 'log') { if (lookupLog.length === 0) { alert("Log is empty. Please perform a lookup first."); return; } doc.setFontSize(18); doc.text("SSL Lookup Log", 14, 22); doc.autoTable({ startY: 30, head: [['Timestamp', 'Host', 'Status', 'Days Left']], body: lookupLog.map(log => [log.timestamp, log.host, log.status, log.days_left]), theme: 'striped', headStyles: { fillColor: [55, 48, 163] } // var(--primary-color) }); doc.save("SSL_Lookup_Log.pdf"); } } // --- EVENT LISTENERS --- ui.form.addEventListener('submit', e => { e.preventDefault(); const host = ui.input.value; fetchSslData(host); }); ui.downloadReportBtn.addEventListener('click', () => downloadPDF('current')); ui.downloadLogBtn.addEventListener('click', () => downloadPDF('log')); ui.clearLogBtn.addEventListener('click', () => { lookupLog = []; saveState(); renderLog(); }); // --- TABBING LOGIC --- function switchTab(targetTabId) { ui.tabContents.forEach(c => c.classList.remove('active')); ui.tabButtons.forEach(b => b.classList.remove('active')); document.getElementById(`ssl-tab-${targetTabId}`).classList.add('active'); document.querySelector(`.ssl-tab-button[data-tab="${targetTabId}"]`).classList.add('active'); } function navigateTabs(dir) { const tabs = Array.from(ui.tabButtons); const active = tabs.find(t => t.classList.contains('active')); let index = tabs.indexOf(active) + dir; if (index < 0) index = 0; if (index >= tabs.length) index = tabs.length - 1; switchTab(tabs[index].dataset.tab); } ui.tabButtons.forEach(button => button.addEventListener('click', () => switchTab(button.dataset.tab))); ui.nextTabBtn.addEventListener('click', () => navigateTabs(1)); ui.prevTabBtn.addEventListener('click', () => navigateTabs(-1)); // --- UTILITY --- function escapeHTML(str) { if (typeof str !== 'string') return ''; const p = document.createElement('p'); p.textContent = str; return p.innerHTML; } // --- INITIALIZATION --- loadState(); renderLog(); });
Scroll to Top