From f9536ee19b29cf5812c826a71306bbf867b80b26 Mon Sep 17 00:00:00 2001 From: Flatlogic Bot Date: Sun, 24 May 2026 07:14:49 +0000 Subject: [PATCH] 01 --- assets/css/custom.css | 913 +++++++++++------- assets/js/main.js | 83 +- assets/pasted-20260524-070702-ebe35df4.png | Bin 0 -> 100902 bytes db/config.php | 117 ++- .../20260524_create_mail_accounts.sql | 19 + healthz.php | 30 + includes/app.php | 378 ++++++++ includes/pop3_client.php | 342 +++++++ index.php | 453 ++++++--- mailbox.php | 279 ++++++ xampp-setup.php | 199 ++++ 11 files changed, 2270 insertions(+), 543 deletions(-) create mode 100644 assets/pasted-20260524-070702-ebe35df4.png create mode 100644 db/migrations/20260524_create_mail_accounts.sql create mode 100644 healthz.php create mode 100644 includes/app.php create mode 100644 includes/pop3_client.php create mode 100644 mailbox.php create mode 100644 xampp-setup.php diff --git a/assets/css/custom.css b/assets/css/custom.css index 789132e..8d27e7f 100644 --- a/assets/css/custom.css +++ b/assets/css/custom.css @@ -1,403 +1,598 @@ +:root { + --bg: #f3f5f7; + --surface: #ffffff; + --surface-muted: #f8fafc; + --surface-soft: #eef2f6; + --border: #d6dde6; + --border-strong: #c4ced8; + --text: #0f172a; + --muted: #5b6b7d; + --primary: #0f172a; + --accent: #2563eb; + --accent-soft: #dbe8ff; + --success-bg: #eaf7ee; + --success-text: #17603a; + --warning-bg: #fff5e8; + --warning-text: #a65a00; + --danger-bg: #fdeeee; + --danger-text: #b42318; + --idle-bg: #edf1f5; + --idle-text: #4b5f74; + --shadow-sm: 0 1px 2px rgba(15, 23, 42, 0.05); + --shadow-md: 0 12px 30px rgba(15, 23, 42, 0.06); + --radius-sm: 8px; + --radius-md: 12px; + --radius-lg: 16px; + --container-max: 1320px; +} + +* { + box-sizing: border-box; +} + +html { + scroll-behavior: smooth; +} + body { - background: linear-gradient(-45deg, #ee7752, #e73c7e, #23a6d5, #23d5ab); - background-size: 400% 400%; - animation: gradient 15s ease infinite; - color: #212529; - font-family: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; - font-size: 14px; margin: 0; min-height: 100vh; + background: var(--bg); + color: var(--text); + font-family: 'Inter', ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; + line-height: 1.5; } -.main-wrapper { - display: flex; +a { + color: inherit; + text-decoration: none; +} + +a:hover { + color: inherit; +} + +img { + max-width: 100%; + display: block; +} + +.app-shell { + max-width: var(--container-max); +} + +.app-nav { + border: 1px solid var(--border); + background: rgba(255, 255, 255, 0.92); + backdrop-filter: blur(12px); + border-radius: var(--radius-lg); + box-shadow: var(--shadow-sm); + padding: 0.75rem 1rem; + margin-bottom: 1.5rem; +} + +.brand-mark { + width: 2.25rem; + height: 2.25rem; + border-radius: 10px; + background: var(--primary); + color: #fff; + display: inline-flex; align-items: center; justify-content: center; - min-height: 100vh; - width: 100%; - padding: 20px; - box-sizing: border-box; - position: relative; - z-index: 1; -} - -@keyframes gradient { - 0% { - background-position: 0% 50%; - } - 50% { - background-position: 100% 50%; - } - 100% { - background-position: 0% 50%; - } -} - -.chat-container { - width: 100%; - max-width: 600px; - background: rgba(255, 255, 255, 0.85); - border: 1px solid rgba(255, 255, 255, 0.3); - border-radius: 20px; - display: flex; - flex-direction: column; - height: 85vh; - box-shadow: 0 20px 40px rgba(0,0,0,0.2); - backdrop-filter: blur(15px); - -webkit-backdrop-filter: blur(15px); - overflow: hidden; -} - -.chat-header { - padding: 1.5rem; - border-bottom: 1px solid rgba(0, 0, 0, 0.05); - background: rgba(255, 255, 255, 0.5); + font-size: 0.8rem; font-weight: 700; - font-size: 1.1rem; - display: flex; - justify-content: space-between; - align-items: center; + letter-spacing: 0.06em; } -.chat-messages { - flex: 1; - overflow-y: auto; - padding: 1.5rem; - display: flex; - flex-direction: column; - gap: 1.25rem; +.brand-copy small, +.nav-note, +.helper-text, +.form-text, +.meta-copy, +.section-subtitle, +.page-eyebrow, +.footer-copy, +.overline { + color: var(--muted); } -/* Custom Scrollbar */ -::-webkit-scrollbar { - width: 6px; -} - -::-webkit-scrollbar-track { - background: transparent; -} - -::-webkit-scrollbar-thumb { - background: rgba(255, 255, 255, 0.3); - border-radius: 10px; -} - -::-webkit-scrollbar-thumb:hover { - background: rgba(255, 255, 255, 0.5); -} - -.message { - max-width: 85%; - padding: 0.85rem 1.1rem; - border-radius: 16px; - line-height: 1.5; - font-size: 0.95rem; - box-shadow: 0 4px 15px rgba(0,0,0,0.05); - animation: fadeIn 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.275); -} - -@keyframes fadeIn { - from { opacity: 0; transform: translateY(20px) scale(0.95); } - to { opacity: 1; transform: translateY(0) scale(1); } -} - -.message.visitor { - align-self: flex-end; - background: linear-gradient(135deg, #212529 0%, #343a40 100%); - color: #fff; - border-bottom-right-radius: 4px; -} - -.message.bot { - align-self: flex-start; - background: #ffffff; - color: #212529; - border-bottom-left-radius: 4px; -} - -.chat-input-area { - padding: 1.25rem; - background: rgba(255, 255, 255, 0.5); - border-top: 1px solid rgba(0, 0, 0, 0.05); -} - -.chat-input-area form { - display: flex; - gap: 0.75rem; -} - -.chat-input-area input { - flex: 1; - border: 1px solid rgba(0, 0, 0, 0.1); - border-radius: 12px; - padding: 0.75rem 1rem; - outline: none; - background: rgba(255, 255, 255, 0.9); - transition: all 0.3s ease; -} - -.chat-input-area input:focus { - border-color: #23a6d5; - box-shadow: 0 0 0 3px rgba(35, 166, 213, 0.2); -} - -.chat-input-area button { - background: #212529; - color: #fff; - border: none; - padding: 0.75rem 1.5rem; - border-radius: 12px; - cursor: pointer; - font-weight: 600; - transition: all 0.3s ease; -} - -.chat-input-area button:hover { - background: #000; - transform: translateY(-2px); - box-shadow: 0 5px 15px rgba(0,0,0,0.2); -} - -/* Background Animations */ -.bg-animations { - position: fixed; - top: 0; - left: 0; - width: 100%; - height: 100%; - z-index: 0; - overflow: hidden; - pointer-events: none; -} - -.blob { - position: absolute; - width: 500px; - height: 500px; - background: rgba(255, 255, 255, 0.2); - border-radius: 50%; - filter: blur(80px); - animation: move 20s infinite alternate cubic-bezier(0.45, 0, 0.55, 1); -} - -.blob-1 { - top: -10%; - left: -10%; - background: rgba(238, 119, 82, 0.4); -} - -.blob-2 { - bottom: -10%; - right: -10%; - background: rgba(35, 166, 213, 0.4); - animation-delay: -7s; - width: 600px; - height: 600px; -} - -.blob-3 { - top: 40%; - left: 30%; - background: rgba(231, 60, 126, 0.3); - animation-delay: -14s; - width: 450px; - height: 450px; -} - -@keyframes move { - 0% { transform: translate(0, 0) rotate(0deg) scale(1); } - 33% { transform: translate(150px, 100px) rotate(120deg) scale(1.1); } - 66% { transform: translate(-50px, 200px) rotate(240deg) scale(0.9); } - 100% { transform: translate(0, 0) rotate(360deg) scale(1); } -} - -.header-link { - font-size: 14px; - color: #fff; - text-decoration: none; - background: rgba(0, 0, 0, 0.2); - padding: 0.5rem 1rem; - border-radius: 8px; - transition: all 0.3s ease; -} - -.header-link:hover { - background: rgba(0, 0, 0, 0.4); - text-decoration: none; -} - -/* Admin Styles */ -.admin-container { - max-width: 900px; - margin: 3rem auto; - padding: 2.5rem; - background: rgba(255, 255, 255, 0.85); - backdrop-filter: blur(20px); - -webkit-backdrop-filter: blur(20px); - border-radius: 24px; - box-shadow: 0 20px 50px rgba(0,0,0,0.15); - border: 1px solid rgba(255, 255, 255, 0.4); - position: relative; - z-index: 1; -} - -.admin-container h1 { - margin-top: 0; - color: #212529; - font-weight: 800; -} - -.table { - width: 100%; - border-collapse: separate; - border-spacing: 0 8px; - margin-top: 1.5rem; -} - -.table th { - background: transparent; - border: none; - padding: 1rem; - color: #6c757d; - font-weight: 600; - text-transform: uppercase; - font-size: 0.75rem; - letter-spacing: 1px; -} - -.table td { - background: #fff; - padding: 1rem; - border: none; -} - -.table tr td:first-child { border-radius: 12px 0 0 12px; } -.table tr td:last-child { border-radius: 0 12px 12px 0; } - -.form-group { - margin-bottom: 1.25rem; -} - -.form-group label { +.brand-copy strong { display: block; - margin-bottom: 0.5rem; + font-size: 0.95rem; + line-height: 1.15; +} + +.btn { + border-radius: var(--radius-sm); font-weight: 600; + letter-spacing: 0.01em; +} + +.btn-primary { + background: var(--primary); + border-color: var(--primary); +} + +.btn-primary:hover, +.btn-primary:focus { + background: #020617; + border-color: #020617; +} + +.btn-outline-secondary { + border-color: var(--border-strong); + color: var(--text); +} + +.btn-outline-secondary:hover, +.btn-outline-secondary:focus { + background: #fff; + border-color: var(--primary); + color: var(--primary); +} + +.hero-grid { + display: grid; + grid-template-columns: 1.2fr 0.8fr; + gap: 1rem; + margin-bottom: 1.5rem; +} + +.hero-card, +.section-card, +.metric-card, +.message-item, +.stat-chip, +.detail-block, +.mail-preview, +.quick-step, +.account-row { + background: var(--surface); + border: 1px solid var(--border); + border-radius: var(--radius-lg); + box-shadow: var(--shadow-sm); +} + +.hero-card, +.section-card, +.mail-preview, +.detail-block { + padding: 1.25rem; +} + +.hero-title { + font-size: clamp(1.9rem, 3vw, 2.65rem); + line-height: 1.05; + letter-spacing: -0.04em; + margin: 0 0 0.9rem; +} + +.section-title { + font-size: 1.1rem; + margin: 0; +} + +.page-eyebrow, +.overline { + text-transform: uppercase; + font-size: 0.73rem; + letter-spacing: 0.08em; + font-weight: 700; +} + +.hero-copy p, +.section-subtitle { + max-width: 56rem; + margin-bottom: 0; +} + +.hero-actions { + display: flex; + flex-wrap: wrap; + gap: 0.75rem; + margin-top: 1.1rem; +} + +.metrics-grid { + display: grid; + gap: 0.9rem; +} + +.metric-card { + padding: 1rem; +} + +.metric-label { + color: var(--muted); + font-size: 0.78rem; + text-transform: uppercase; + letter-spacing: 0.06em; + font-weight: 700; +} + +.metric-value { + font-size: 1.55rem; + font-weight: 700; + margin-top: 0.35rem; + letter-spacing: -0.03em; +} + +.metric-hint { + margin-top: 0.35rem; + color: var(--muted); font-size: 0.9rem; } -.form-control { - width: 100%; - padding: 0.75rem 1rem; - border: 1px solid rgba(0, 0, 0, 0.1); - border-radius: 12px; +.surface-muted { + background: var(--surface-muted); +} + +.form-label { + font-size: 0.88rem; + font-weight: 600; + margin-bottom: 0.4rem; +} + +.form-control, +.form-select { + border-radius: var(--radius-sm); + border-color: var(--border-strong); background: #fff; - transition: all 0.3s ease; - box-sizing: border-box; + padding-top: 0.7rem; + padding-bottom: 0.7rem; + font-size: 0.95rem; } -.form-control:focus { - outline: none; - border-color: #23a6d5; - box-shadow: 0 0 0 3px rgba(35, 166, 213, 0.1); +.form-control:focus, +.form-select:focus, +.message-search input:focus, +.btn:focus, +.nav-link:focus, +.list-link:focus { + border-color: var(--accent); + box-shadow: 0 0 0 0.25rem rgba(37, 99, 235, 0.12); } -.header-container { - display: flex; - justify-content: space-between; +.form-check-input:checked { + background-color: var(--primary); + border-color: var(--primary); +} + +.validation-note { + font-size: 0.82rem; + color: var(--danger-text); + margin-top: 0.35rem; +} + +.inline-note { + display: inline-flex; align-items: center; + gap: 0.45rem; + background: var(--surface-soft); + border: 1px solid var(--border); + border-radius: 999px; + padding: 0.35rem 0.7rem; + font-size: 0.84rem; + color: var(--muted); } -.header-links { - display: flex; - gap: 1rem; +.stack-sm > * + * { + margin-top: 0.75rem; } -.admin-card { - background: rgba(255, 255, 255, 0.6); - padding: 2rem; - border-radius: 20px; - border: 1px solid rgba(255, 255, 255, 0.5); - margin-bottom: 2.5rem; - box-shadow: 0 10px 30px rgba(0,0,0,0.05); -} - -.admin-card h3 { - margin-top: 0; - margin-bottom: 1.5rem; - font-weight: 700; -} - -.btn-delete { - background: #dc3545; - color: white; - border: none; - padding: 0.25rem 0.5rem; - border-radius: 4px; - cursor: pointer; -} - -.btn-add { - background: #212529; - color: white; - border: none; - padding: 0.5rem 1rem; - border-radius: 4px; - cursor: pointer; +.stack-md > * + * { margin-top: 1rem; } -.btn-save { - background: #0088cc; - color: white; - border: none; - padding: 0.8rem 1.5rem; - border-radius: 12px; - cursor: pointer; - font-weight: 600; - width: 100%; - transition: all 0.3s ease; +.status-badge, +.soft-badge { + display: inline-flex; + align-items: center; + gap: 0.35rem; + border-radius: 999px; + font-size: 0.78rem; + font-weight: 700; + padding: 0.32rem 0.65rem; + border: 1px solid transparent; } -.webhook-url { - font-size: 0.85em; - color: #555; +.status-success { + background: var(--success-bg); + color: var(--success-text); + border-color: #cce7d4; +} + +.status-warning { + background: var(--warning-bg); + color: var(--warning-text); + border-color: #f3dfbe; +} + +.status-danger { + background: var(--danger-bg); + color: var(--danger-text); + border-color: #f2ceca; +} + +.status-idle { + background: var(--idle-bg); + color: var(--idle-text); + border-color: #d9e2ea; +} + +.soft-badge { + background: var(--surface-soft); + border-color: var(--border); + color: var(--muted); +} + +.table-shell { + border: 1px solid var(--border); + border-radius: var(--radius-lg); + overflow: hidden; +} + +.table { + margin-bottom: 0; +} + +.table thead th { + background: var(--surface-muted); + border-bottom-color: var(--border); + color: var(--muted); + font-size: 0.76rem; + text-transform: uppercase; + letter-spacing: 0.06em; + font-weight: 700; +} + +.table td, +.table th { + padding: 0.95rem 1rem; + vertical-align: middle; +} + +.table tbody tr:hover { + background: rgba(15, 23, 42, 0.025); +} + +.account-meta, +.meta-list { + display: flex; + flex-wrap: wrap; + gap: 0.5rem; +} + +.meta-list { + flex-direction: column; + gap: 0.6rem; +} + +.meta-list strong { + font-size: 0.76rem; + text-transform: uppercase; + letter-spacing: 0.06em; + color: var(--muted); + display: block; + margin-bottom: 0.15rem; +} + +.quick-steps { + display: grid; + gap: 0.75rem; +} + +.quick-step { + padding: 0.95rem 1rem; +} + +.quick-step h3 { + margin: 0 0 0.3rem; + font-size: 0.98rem; +} + +.quick-step p { + margin: 0; + color: var(--muted); + font-size: 0.9rem; +} + +.mailbox-shell { + display: grid; + grid-template-columns: minmax(280px, 360px) minmax(0, 1fr); + gap: 1rem; +} + +.mailbox-list { + display: flex; + flex-direction: column; + gap: 0.8rem; +} + +.message-search { + margin-bottom: 0.85rem; +} + +.message-search input { + width: 100%; + border: 1px solid var(--border-strong); + border-radius: var(--radius-sm); + padding: 0.72rem 0.9rem; + font-size: 0.95rem; +} + +.message-item { + display: block; + padding: 0.9rem 1rem; + transition: border-color 0.18s ease, box-shadow 0.18s ease, transform 0.18s ease; +} + +.message-item:hover { + border-color: var(--primary); + box-shadow: var(--shadow-sm); + transform: translateY(-1px); +} + +.message-item.active { + border-color: var(--primary); + background: #f8fbff; +} + +.message-subject { + font-weight: 700; + margin: 0 0 0.25rem; +} + +.message-from, +.message-date, +.message-preview, +.empty-copy, +.help-list li, +.kicker { + color: var(--muted); +} + +.message-from, +.message-date { + font-size: 0.86rem; +} + +.message-preview { + font-size: 0.88rem; margin-top: 0.5rem; } -.history-table-container { - overflow-x: auto; - background: rgba(255, 255, 255, 0.4); - padding: 1rem; - border-radius: 12px; - border: 1px solid rgba(255, 255, 255, 0.3); +.message-body { + white-space: pre-wrap; + word-break: break-word; + font-size: 0.95rem; + line-height: 1.65; } -.history-table { - width: 100%; +.message-header-grid { + display: grid; + gap: 0.75rem; + grid-template-columns: repeat(3, minmax(0, 1fr)); + margin-bottom: 1rem; } -.history-table-time { - width: 15%; - white-space: nowrap; - font-size: 0.85em; - color: #555; +.detail-block { + padding: 0.95rem 1rem; } -.history-table-user { - width: 35%; - background: rgba(255, 255, 255, 0.3); - border-radius: 8px; - padding: 8px; +.detail-block strong { + display: block; + font-size: 0.76rem; + text-transform: uppercase; + letter-spacing: 0.06em; + color: var(--muted); + margin-bottom: 0.2rem; } -.history-table-ai { - width: 50%; - background: rgba(255, 255, 255, 0.5); - border-radius: 8px; - padding: 8px; -} - -.no-messages { +.empty-panel { text-align: center; - color: #777; -} \ No newline at end of file + padding: 2rem 1.2rem; + border: 1px dashed var(--border-strong); + border-radius: var(--radius-lg); + background: var(--surface-muted); +} + +.nav-pills .nav-link { + border-radius: 999px; + color: var(--muted); + border: 1px solid transparent; + font-weight: 600; +} + +.nav-pills .nav-link.active { + background: var(--primary); + color: #fff; +} + +.nav-pills .nav-link.disabled { + border-color: var(--border); + color: var(--muted); + background: var(--surface-muted); +} + +.toast-shell { + position: fixed; + top: 1rem; + right: 1rem; + z-index: 1080; +} + +.toast { + border-radius: var(--radius-md); + border: 1px solid var(--border); + box-shadow: var(--shadow-md); +} + +.footer-copy { + font-size: 0.9rem; +} + +.help-list { + margin: 0; + padding-left: 1rem; +} + +.help-list li + li { + margin-top: 0.4rem; +} + +@media (max-width: 991.98px) { + .hero-grid, + .mailbox-shell, + .message-header-grid { + grid-template-columns: 1fr; + } + + .app-nav { + padding: 0.85rem 0.95rem; + } +} + +@media (max-width: 767.98px) { + .hero-card, + .section-card, + .mail-preview, + .detail-block { + padding: 1rem; + } + + .table-shell { + border: 0; + overflow: visible; + } + + .table thead { + display: none; + } + + .table, + .table tbody, + .table tr, + .table td { + display: block; + width: 100%; + } + + .table tbody tr { + border: 1px solid var(--border); + border-radius: var(--radius-lg); + background: var(--surface); + box-shadow: var(--shadow-sm); + margin-bottom: 0.85rem; + } + + .table td { + padding: 0.85rem 1rem 0; + border: 0; + } + + .table td:last-child { + padding-bottom: 1rem; + } +} diff --git a/assets/js/main.js b/assets/js/main.js index d349598..d962ab0 100644 --- a/assets/js/main.js +++ b/assets/js/main.js @@ -1,39 +1,54 @@ document.addEventListener('DOMContentLoaded', () => { - const chatForm = document.getElementById('chat-form'); - const chatInput = document.getElementById('chat-input'); - const chatMessages = document.getElementById('chat-messages'); - - const appendMessage = (text, sender) => { - const msgDiv = document.createElement('div'); - msgDiv.classList.add('message', sender); - msgDiv.textContent = text; - chatMessages.appendChild(msgDiv); - chatMessages.scrollTop = chatMessages.scrollHeight; - }; - - chatForm.addEventListener('submit', async (e) => { - e.preventDefault(); - const message = chatInput.value.trim(); - if (!message) return; - - appendMessage(message, 'visitor'); - chatInput.value = ''; - - try { - const response = await fetch('api/chat.php', { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ message }) + if (window.bootstrap) { + document.querySelectorAll('.toast').forEach((toastEl) => { + const toast = new bootstrap.Toast(toastEl, { + delay: 4200, }); - const data = await response.json(); - - // Artificial delay for realism - setTimeout(() => { - appendMessage(data.reply, 'bot'); - }, 500); - } catch (error) { - console.error('Error:', error); - appendMessage("Sorry, something went wrong. Please try again.", 'bot'); + toast.show(); + }); + } + + const searchInput = document.querySelector('[data-mail-search]'); + const messageItems = Array.from(document.querySelectorAll('[data-mail-item]')); + const searchEmpty = document.querySelector('[data-mail-empty]'); + + if (searchInput && messageItems.length) { + const applyFilter = () => { + const term = searchInput.value.trim().toLowerCase(); + let visibleCount = 0; + + messageItems.forEach((item) => { + const haystack = (item.getAttribute('data-search') || '').toLowerCase(); + const matches = term === '' || haystack.includes(term); + item.classList.toggle('d-none', !matches); + if (matches) { + visibleCount += 1; + } + }); + + if (searchEmpty) { + searchEmpty.classList.toggle('d-none', visibleCount > 0); + } + }; + + searchInput.addEventListener('input', applyFilter); + applyFilter(); + } + + document.querySelectorAll('[data-security-select]').forEach((select) => { + const portInput = document.querySelector(select.getAttribute('data-port-target')); + if (!portInput) { + return; } + + select.addEventListener('change', () => { + const currentValue = portInput.value.trim(); + if (select.value === 'ssl' && (currentValue === '' || currentValue === '110')) { + portInput.value = '995'; + } + if (select.value === 'plain' && (currentValue === '' || currentValue === '995')) { + portInput.value = '110'; + } + }); }); }); diff --git a/assets/pasted-20260524-070702-ebe35df4.png b/assets/pasted-20260524-070702-ebe35df4.png new file mode 100644 index 0000000000000000000000000000000000000000..6319fe102651a57298d89f05d0830752cec3bc70 GIT binary patch literal 100902 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 literal 0 HcmV?d00001 diff --git a/db/config.php b/db/config.php index f135f1f..2192d13 100644 --- a/db/config.php +++ b/db/config.php @@ -1,21 +1,108 @@ DB_HOST, + 'port' => DB_PORT, + 'name' => DB_NAME, + 'user' => DB_USER, + 'has_password' => DB_PASS !== '', + ]; } -function db() { - static $pdo; - if (!$pdo) { - $pdo = new PDO('mysql:host='.DB_HOST.';dbname='.DB_NAME.';charset=utf8mb4', DB_USER, DB_PASS, [ - PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, - PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, - ]); - } - return $pdo; +function db_dsn(?string $database = null): string +{ + $dsn = 'mysql:host=' . DB_HOST . ';port=' . DB_PORT . ';charset=utf8mb4'; + + if ($database !== null && $database !== '') { + $dsn .= ';dbname=' . $database; + } + + return $dsn; +} + +function db_options(): array +{ + return [ + PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, + PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, + ]; +} + +function db(): PDO +{ + static $pdo; + + if (!$pdo) { + try { + $pdo = new PDO(db_dsn(DB_NAME), DB_USER, DB_PASS, db_options()); + } catch (Throwable $exception) { + throw new RuntimeException(db_human_error($exception), 0, $exception); + } + } + + return $pdo; +} + +function db_server(): PDO +{ + try { + return new PDO(db_dsn(null), DB_USER, DB_PASS, db_options()); + } catch (Throwable $exception) { + throw new RuntimeException(db_human_error($exception), 0, $exception); + } +} + +function db_initialize(string $migrationFile): void +{ + $server = db_server(); + $databaseName = str_replace('`', '``', DB_NAME); + $server->exec("CREATE DATABASE IF NOT EXISTS `{$databaseName}` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci"); + + $pdo = new PDO(db_dsn(DB_NAME), DB_USER, DB_PASS, db_options()); + $sql = file_get_contents($migrationFile); + + if ($sql === false) { + throw new RuntimeException('Ne mogu pročitati SQL migraciju za mailbox tablicu.'); + } + + $pdo->exec($sql); +} + +function db_human_error(Throwable $exception): string +{ + $message = trim($exception->getMessage()); + $messageLower = strtolower($message); + + if (str_contains($messageLower, 'unknown database')) { + return 'MySQL radi, ali baza `' . DB_NAME . '` još ne postoji. Pokreni `xampp-setup.php` ili je kreiraj u phpMyAdminu. Detalj: ' . $message; + } + + if (str_contains($messageLower, 'access denied')) { + return 'MySQL je dostupan, ali korisničko ime ili lozinka nisu prihvaćeni. Provjeri `db/config.php`. Detalj: ' . $message; + } + + if ( + str_contains($messageLower, 'connection refused') + || str_contains($messageLower, 'no such file or directory') + || str_contains($messageLower, "can't connect") + || str_contains($messageLower, 'sqlstate[hy000] [2002]') + ) { + return 'Ne mogu se spojiti na MySQL na ' . DB_HOST . ':' . DB_PORT . '. Pokreni MySQL u XAMPP-u i pokušaj ponovno. Detalj: ' . $message; + } + + return $message !== '' ? $message : 'Nepoznata greška pri spajanju na bazu.'; } diff --git a/db/migrations/20260524_create_mail_accounts.sql b/db/migrations/20260524_create_mail_accounts.sql new file mode 100644 index 0000000..76d1c98 --- /dev/null +++ b/db/migrations/20260524_create_mail_accounts.sql @@ -0,0 +1,19 @@ +CREATE TABLE IF NOT EXISTS mail_accounts ( + id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY, + label VARCHAR(120) NOT NULL, + email_address VARCHAR(190) DEFAULT NULL, + pop3_host VARCHAR(190) NOT NULL, + pop3_port SMALLINT UNSIGNED NOT NULL DEFAULT 110, + security_mode VARCHAR(20) NOT NULL DEFAULT 'plain', + username VARCHAR(190) NOT NULL, + password_ciphertext TEXT NOT NULL, + sync_limit SMALLINT UNSIGNED NOT NULL DEFAULT 15, + leave_on_server TINYINT(1) NOT NULL DEFAULT 1, + last_status VARCHAR(255) DEFAULT NULL, + last_message_count INT UNSIGNED NOT NULL DEFAULT 0, + last_sync_at DATETIME DEFAULT NULL, + created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + INDEX idx_mail_accounts_created_at (created_at), + INDEX idx_mail_accounts_last_sync_at (last_sync_at) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; diff --git a/healthz.php b/healthz.php new file mode 100644 index 0000000..bccc9a2 --- /dev/null +++ b/healthz.php @@ -0,0 +1,30 @@ + 'ok', + 'db' => false, + 'timestamp' => gmdate(DATE_ATOM), +]; + +try { + $pdo = app_db(); + + if (!$pdo) { + throw new RuntimeException(app_db_error() ?: 'Database connection is not available.'); + } + + $statement = $pdo->prepare('SELECT 1'); + $statement->execute(); + $status['db'] = true; +} catch (Throwable $exception) { + $status['status'] = 'degraded'; +} + +http_response_code($status['status'] === 'ok' ? 200 : 503); +header('Content-Type: application/json; charset=utf-8'); +echo json_encode($status, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES); diff --git a/includes/app.php b/includes/app.php new file mode 100644 index 0000000..2866b31 --- /dev/null +++ b/includes/app.php @@ -0,0 +1,378 @@ +getMessage(); + } + + return $pdo; +} + +function app_db_error(): ?string +{ + return $GLOBALS['APP_DB_ERROR'] ?? null; +} + +function ensure_mail_schema(): bool +{ + static $ensured = false; + + if ($ensured) { + return app_db() instanceof PDO; + } + + $ensured = true; + $pdo = app_db(); + + if (!$pdo) { + return false; + } + + $migrationFile = __DIR__ . '/../db/migrations/20260524_create_mail_accounts.sql'; + + try { + $sql = file_get_contents($migrationFile); + + if ($sql === false) { + throw new RuntimeException('Unable to read the mailbox migration file.'); + } + + $pdo->exec($sql); + + return true; + } catch (Throwable $exception) { + $GLOBALS['APP_DB_ERROR'] = $exception->getMessage(); + + return false; + } +} + +function app_boot(): void +{ + ensure_mail_schema(); +} + +function db_ready(): bool +{ + return app_db() instanceof PDO; +} + +function flash(string $type, string $message): void +{ + $_SESSION['flash'] = [ + 'type' => $type, + 'message' => $message, + ]; +} + +function pull_flash(): ?array +{ + if (empty($_SESSION['flash']) || !is_array($_SESSION['flash'])) { + return null; + } + + $flash = $_SESSION['flash']; + unset($_SESSION['flash']); + + return $flash; +} + +function mail_cipher_key(): string +{ + return hash('sha256', DB_HOST . '|' . DB_NAME . '|' . DB_USER . '|' . DB_PASS, true); +} + +function encrypt_secret(string $plaintext): string +{ + $cipher = 'aes-256-cbc'; + $ivLength = openssl_cipher_iv_length($cipher); + $iv = random_bytes($ivLength); + $encrypted = openssl_encrypt($plaintext, $cipher, mail_cipher_key(), OPENSSL_RAW_DATA, $iv); + + if ($encrypted === false) { + throw new RuntimeException('Unable to securely store the POP3 password.'); + } + + return base64_encode($iv . $encrypted); +} + +function decrypt_secret(string $ciphertext): string +{ + $decoded = base64_decode($ciphertext, true); + + if ($decoded === false) { + return ''; + } + + $cipher = 'aes-256-cbc'; + $ivLength = openssl_cipher_iv_length($cipher); + $iv = substr($decoded, 0, $ivLength); + $payload = substr($decoded, $ivLength); + $decrypted = openssl_decrypt($payload, $cipher, mail_cipher_key(), OPENSSL_RAW_DATA, $iv); + + return $decrypted === false ? '' : $decrypted; +} + +function default_mail_account_input(): array +{ + return [ + 'label' => '', + 'email_address' => '', + 'pop3_host' => '127.0.0.1', + 'pop3_port' => 110, + 'security_mode' => 'plain', + 'username' => '', + 'password' => '', + 'sync_limit' => 15, + 'leave_on_server' => 1, + ]; +} + +function validate_mail_account_input(array $input): array +{ + $clean = [ + 'label' => trim((string) ($input['label'] ?? '')), + 'email_address' => trim((string) ($input['email_address'] ?? '')), + 'pop3_host' => trim((string) ($input['pop3_host'] ?? '')), + 'pop3_port' => (int) ($input['pop3_port'] ?? 110), + 'security_mode' => in_array(($input['security_mode'] ?? 'plain'), ['plain', 'ssl'], true) ? (string) $input['security_mode'] : 'plain', + 'username' => trim((string) ($input['username'] ?? '')), + 'password' => trim((string) ($input['password'] ?? '')), + 'sync_limit' => (int) ($input['sync_limit'] ?? 15), + 'leave_on_server' => isset($input['leave_on_server']) ? 1 : 0, + ]; + + $errors = []; + + if ($clean['label'] === '' || strlen($clean['label']) < 2) { + $errors['label'] = 'Unesite naziv mailboxa (najmanje 2 znaka).'; + } + + if ($clean['email_address'] !== '' && !filter_var($clean['email_address'], FILTER_VALIDATE_EMAIL)) { + $errors['email_address'] = 'Email adresa nije ispravna.'; + } + + if ($clean['pop3_host'] === '' || strlen($clean['pop3_host']) < 2) { + $errors['pop3_host'] = 'POP3 host je obavezan.'; + } + + if ($clean['pop3_port'] < 1 || $clean['pop3_port'] > 65535) { + $errors['pop3_port'] = 'POP3 port mora biti između 1 i 65535.'; + } + + if ($clean['username'] === '') { + $errors['username'] = 'Korisničko ime je obavezno.'; + } + + if ($clean['password'] === '') { + $errors['password'] = 'Lozinka je obavezna.'; + } + + if ($clean['sync_limit'] < 5 || $clean['sync_limit'] > 50) { + $errors['sync_limit'] = 'Prikaži između 5 i 50 poruka po sinkronizaciji.'; + } + + return [$clean, $errors]; +} + +function save_mail_account(array $data): int +{ + $pdo = app_db(); + + if (!$pdo) { + throw new RuntimeException('Baza trenutno nije dostupna.'); + } + + $statement = $pdo->prepare( + 'INSERT INTO mail_accounts (label, email_address, pop3_host, pop3_port, security_mode, username, password_ciphertext, sync_limit, leave_on_server, last_status) + VALUES (:label, :email_address, :pop3_host, :pop3_port, :security_mode, :username, :password_ciphertext, :sync_limit, :leave_on_server, :last_status)' + ); + + $statement->bindValue(':label', $data['label']); + $statement->bindValue(':email_address', $data['email_address'] !== '' ? $data['email_address'] : null, PDO::PARAM_STR); + $statement->bindValue(':pop3_host', $data['pop3_host']); + $statement->bindValue(':pop3_port', (int) $data['pop3_port'], PDO::PARAM_INT); + $statement->bindValue(':security_mode', $data['security_mode']); + $statement->bindValue(':username', $data['username']); + $statement->bindValue(':password_ciphertext', encrypt_secret($data['password'])); + $statement->bindValue(':sync_limit', (int) $data['sync_limit'], PDO::PARAM_INT); + $statement->bindValue(':leave_on_server', (int) $data['leave_on_server'], PDO::PARAM_INT); + $statement->bindValue(':last_status', 'Ready to connect'); + $statement->execute(); + + return (int) $pdo->lastInsertId(); +} + +function get_mail_accounts(): array +{ + $pdo = app_db(); + + if (!$pdo) { + return []; + } + + $statement = $pdo->prepare( + 'SELECT id, label, email_address, pop3_host, pop3_port, security_mode, username, sync_limit, leave_on_server, last_status, last_message_count, last_sync_at, created_at, updated_at + FROM mail_accounts + ORDER BY created_at DESC, id DESC' + ); + $statement->execute(); + + return $statement->fetchAll() ?: []; +} + +function find_mail_account(int $id): ?array +{ + $pdo = app_db(); + + if (!$pdo) { + return null; + } + + $statement = $pdo->prepare( + 'SELECT id, label, email_address, pop3_host, pop3_port, security_mode, username, password_ciphertext, sync_limit, leave_on_server, last_status, last_message_count, last_sync_at, created_at, updated_at + FROM mail_accounts + WHERE id = :id + LIMIT 1' + ); + $statement->bindValue(':id', $id, PDO::PARAM_INT); + $statement->execute(); + + $account = $statement->fetch(); + + return $account ?: null; +} + +function update_mail_account_sync(int $id, string $status, int $messageCount): void +{ + $pdo = app_db(); + + if (!$pdo) { + return; + } + + $statement = $pdo->prepare( + 'UPDATE mail_accounts + SET last_status = :last_status, + last_message_count = :last_message_count, + last_sync_at = NOW() + WHERE id = :id' + ); + $statement->bindValue(':last_status', substr($status, 0, 255)); + $statement->bindValue(':last_message_count', max(0, $messageCount), PDO::PARAM_INT); + $statement->bindValue(':id', $id, PDO::PARAM_INT); + $statement->execute(); +} + +function format_datetime(?string $value, string $fallback = 'Not yet'): string +{ + if (!$value) { + return $fallback; + } + + try { + return (new DateTimeImmutable($value))->format('M j, Y · H:i'); + } catch (Throwable $exception) { + return $fallback; + } +} + +function status_tone(?string $status): string +{ + $value = strtolower(trim((string) $status)); + + if ($value === '') { + return 'status-idle'; + } + + if (str_contains($value, 'fail') || str_contains($value, 'error')) { + return 'status-danger'; + } + + if (str_contains($value, 'empty')) { + return 'status-warning'; + } + + if (str_contains($value, 'connected') || str_contains($value, 'ready')) { + return 'status-success'; + } + + return 'status-idle'; +} + +function security_label(string $mode): string +{ + return $mode === 'ssl' ? 'SSL/TLS' : 'Plain'; +} + +function truncate_text(string $text, int $length = 160): string +{ + $text = trim(preg_replace('/\s+/', ' ', $text) ?? $text); + + if ($text === '') { + return ''; + } + + if (function_exists('iconv_strlen') && function_exists('iconv_substr')) { + $currentLength = iconv_strlen($text, 'UTF-8'); + + if ($currentLength !== false && $currentLength > $length) { + return rtrim((string) iconv_substr($text, 0, $length, 'UTF-8')) . '…'; + } + } + + return strlen($text) > $length ? rtrim(substr($text, 0, $length)) . '…' : $text; +} diff --git a/includes/pop3_client.php b/includes/pop3_client.php new file mode 100644 index 0000000..123031d --- /dev/null +++ b/includes/pop3_client.php @@ -0,0 +1,342 @@ +host = $host; + $this->port = $port; + $this->security = $security; + $this->timeout = $timeout; + } + + public function connect(): void + { + $target = ($this->security === 'ssl' ? 'ssl://' : '') . $this->host; + $errno = 0; + $errstr = ''; + $stream = @fsockopen($target, $this->port, $errno, $errstr, $this->timeout); + + if (!is_resource($stream)) { + throw new RuntimeException(sprintf('Ne mogu otvoriti POP3 vezu prema %s:%d.', $this->host, $this->port)); + } + + stream_set_timeout($stream, $this->timeout); + $this->stream = $stream; + + $greeting = $this->readLine(); + + if (stripos($greeting, '+OK') !== 0) { + throw new RuntimeException('POP3 server je odbio početni pozdrav.'); + } + } + + public function login(string $username, string $password): void + { + $this->simpleCommand('USER ' . $username, 'Korisničko ime nije prihvaćeno na POP3 serveru.'); + $this->simpleCommand('PASS ' . $password, 'Lozinka nije prihvaćena na POP3 serveru.'); + } + + public function stat(): array + { + $response = $this->simpleCommand('STAT', 'Ne mogu očitati stanje inboxa.'); + + if (preg_match('/^\+OK\s+(\d+)\s+(\d+)/', $response, $matches)) { + return [ + 'count' => (int) $matches[1], + 'size' => (int) $matches[2], + ]; + } + + return ['count' => 0, 'size' => 0]; + } + + public function fetchRecent(int $limit = 15): array + { + $stats = $this->stat(); + $count = $stats['count']; + + if ($count <= 0) { + return []; + } + + $messages = []; + $start = max(1, $count - $limit + 1); + + for ($number = $count; $number >= $start; $number--) { + try { + $raw = $this->multilineCommand('TOP ' . $number . ' 18', 'Ne mogu dohvatiti pregled poruke.'); + } catch (Throwable $exception) { + $raw = $this->multilineCommand('RETR ' . $number, 'Ne mogu preuzeti poruku s POP3 servera.'); + } + + $messages[] = $this->parseMessage($number, $raw, false); + } + + return $messages; + } + + public function fetchMessage(int $number): array + { + $raw = $this->multilineCommand('RETR ' . $number, 'Ne mogu otvoriti traženu poruku.'); + + return $this->parseMessage($number, $raw, true); + } + + public function quit(): void + { + if (is_resource($this->stream)) { + try { + $this->simpleCommand('QUIT'); + } catch (Throwable $exception) { + // ignore close failures + } + + fclose($this->stream); + $this->stream = null; + } + } + + public function __destruct() + { + $this->quit(); + } + + private function parseMessage(int $number, string $rawMessage, bool $includeBody): array + { + [$headerText, $bodyText] = self::splitMessage($rawMessage); + $headers = self::parseHeaders($headerText); + $decodedBody = self::extractBodyText($headers, $bodyText); + $normalizedBody = trim(preg_replace("/ +?| /", " +", $decodedBody) ?? $decodedBody); + $preview = truncate_text($normalizedBody !== '' ? $normalizedBody : 'Nema pregleda za ovu poruku.', 180); + + return [ + 'number' => $number, + 'subject' => self::headerValue($headers, 'subject', '(Bez naslova)'), + 'from' => self::headerValue($headers, 'from', 'Nepoznati pošiljatelj'), + 'date' => self::headerValue($headers, 'date', ''), + 'message_id' => self::headerValue($headers, 'message-id', 'POP3-' . $number), + 'preview' => $preview !== '' ? $preview : 'Nema pregleda za ovu poruku.', + 'body_text' => $includeBody ? ($normalizedBody !== '' ? $normalizedBody : 'Poruka nema tekstualni sadržaj za prikaz.') : '', + ]; + } + + private static function splitMessage(string $rawMessage): array + { + $parts = preg_split("/ ? + ? +/", $rawMessage, 2); + + return [ + $parts[0] ?? '', + $parts[1] ?? '', + ]; + } + + public static function parseHeaders(string $headerText): array + { + $headers = []; + $current = null; + $lines = preg_split("/ ? +/", $headerText) ?: []; + + foreach ($lines as $line) { + if ($line === '') { + continue; + } + + if (preg_match('/^[ ]+/', $line) === 1 && $current !== null) { + $headers[$current] .= ' ' . trim($line); + continue; + } + + $parts = explode(':', $line, 2); + + if (count($parts) !== 2) { + continue; + } + + $current = strtolower(trim($parts[0])); + $headers[$current] = trim($parts[1]); + } + + return $headers; + } + + private static function extractBodyText(array $headers, string $body): string + { + $contentType = strtolower((string) ($headers['content-type'] ?? 'text/plain; charset=UTF-8')); + $encoding = strtolower((string) ($headers['content-transfer-encoding'] ?? '')); + $charset = 'UTF-8'; + + if (preg_match('/charset="?([^";]+)"?/i', $contentType, $charsetMatch) === 1) { + $charset = trim($charsetMatch[1]); + } + + if (str_starts_with($contentType, 'multipart/') && preg_match('/boundary="?([^";]+)"?/i', $contentType, $boundaryMatch) === 1) { + $boundary = $boundaryMatch[1]; + $delimiter = '--' . $boundary; + $parts = explode($delimiter, $body); + $plain = ''; + $html = ''; + + foreach ($parts as $part) { + $part = ltrim($part, " +"); + $part = preg_replace('/--\s*$/', '', $part) ?? $part; + + if (trim($part) === '') { + continue; + } + + [$partHeadersText, $partBody] = self::splitMessage($part); + $partHeaders = self::parseHeaders($partHeadersText); + $partText = trim(self::extractBodyText($partHeaders, $partBody)); + $partType = strtolower((string) ($partHeaders['content-type'] ?? 'text/plain')); + + if ($partText === '') { + continue; + } + + if (str_contains($partType, 'text/plain')) { + return $partText; + } + + if ($plain === '') { + $plain = $partText; + } + + if ($html === '' && str_contains($partType, 'text/html')) { + $html = $partText; + } + } + + return $plain !== '' ? $plain : $html; + } + + $decoded = self::decodeBody($body, $encoding); + + if ($charset !== '' && strtoupper($charset) !== 'UTF-8' && function_exists('iconv')) { + $converted = @iconv($charset, 'UTF-8//IGNORE', $decoded); + + if ($converted !== false) { + $decoded = $converted; + } + } + + if (str_contains($contentType, 'text/html')) { + $decoded = html_entity_decode(strip_tags($decoded), ENT_QUOTES | ENT_HTML5, 'UTF-8'); + } + + return trim($decoded); + } + + private static function decodeBody(string $body, string $encoding): string + { + return match ($encoding) { + 'base64' => base64_decode($body, true) ?: $body, + 'quoted-printable' => quoted_printable_decode($body), + default => $body, + }; + } + + private static function headerValue(array $headers, string $key, string $fallback): string + { + $value = trim((string) ($headers[$key] ?? '')); + + if ($value === '') { + return $fallback; + } + + if (function_exists('iconv_mime_decode')) { + $decoded = @iconv_mime_decode($value, ICONV_MIME_DECODE_CONTINUE_ON_ERROR, 'UTF-8'); + + if (is_string($decoded) && $decoded !== '') { + return $decoded; + } + } + + return $value; + } + + private function simpleCommand(string $command, ?string $fallbackMessage = null): string + { + $this->write($command . " +"); + $response = $this->readLine(); + + if (stripos($response, '+OK') !== 0) { + $serverMessage = preg_replace('/^-ERR\s*/i', '', trim($response)) ?: trim($response); + throw new RuntimeException($fallbackMessage ?: ($serverMessage !== '' ? $serverMessage : 'POP3 naredba nije uspjela.')); + } + + return trim($response); + } + + private function multilineCommand(string $command, ?string $fallbackMessage = null): string + { + $this->write($command . " +"); + $response = $this->readLine(); + + if (stripos($response, '+OK') !== 0) { + $serverMessage = preg_replace('/^-ERR\s*/i', '', trim($response)) ?: trim($response); + throw new RuntimeException($fallbackMessage ?: ($serverMessage !== '' ? $serverMessage : 'POP3 naredba nije uspjela.')); + } + + $lines = []; + + while (($line = $this->readLine()) !== '.') { + if (str_starts_with($line, '..')) { + $line = substr($line, 1); + } + + $lines[] = $line; + } + + return implode(" +", $lines); + } + + private function write(string $payload): void + { + if (!is_resource($this->stream)) { + throw new RuntimeException('POP3 veza nije aktivna.'); + } + + fwrite($this->stream, $payload); + } + + private function readLine(): string + { + if (!is_resource($this->stream)) { + throw new RuntimeException('POP3 veza nije aktivna.'); + } + + $line = fgets($this->stream, 8192); + + if ($line === false) { + $meta = stream_get_meta_data($this->stream); + + if (!empty($meta['timed_out'])) { + throw new RuntimeException('POP3 server nije odgovorio na vrijeme.'); + } + + throw new RuntimeException('POP3 server je zatvorio vezu.'); + } + + return rtrim($line, " +"); + } +} diff --git a/index.php b/index.php index 7205f3d..6837311 100644 --- a/index.php +++ b/index.php @@ -1,150 +1,333 @@ strtotime((string) $latestSync)) { + $latestSync = (string) $account['last_sync_at']; + } + } +} + +$pageTitle = project_name() . ' — POP3 mailbox dashboard'; +$projectBaseDescription = trim((string) ($_SERVER['PROJECT_DESCRIPTION'] ?? getenv('PROJECT_DESCRIPTION') ?: '')); +$pageDescription = $projectBaseDescription !== '' + ? $projectBaseDescription . ' — Dashboard for POP3 mailbox setup, MySQL account storage, and live inbox access.' + : 'Configure local POP3 mailboxes, store connection settings in MySQL, and open a clean inbox view from one lightweight PHP interface.'; +$projectDescription = $projectBaseDescription !== '' ? $projectBaseDescription : $pageDescription; +$projectImageUrl = project_image_url(); ?> - + - - - New Style - + + + <?= h($pageTitle) ?> + - - - - - - + + - - - - + + - - - - + + + + + + + -
-
-

Analyzing your requirements and generating your website…

-
- Loading… -
-

AI is collecting your requirements and applying the first changes.

-

This page will update automatically as the plan is implemented.

-

Runtime: PHP — UTC

+ +
+
+
+
+ +
+
-
-
- Page updated: (UTC) -
+ +
+ + +
+
+
Initial MVP slice
+

Dodaj POP3 mailbox i odmah otvori inbox iz preglednika.

+

Ova prva verzija pokriva najbitniji tok: spremi POP3 postavke u MySQL, otvori live pregled inboxa i pročitaj poruku bez izlaska iz aplikacije. Dizajn je namjerno čist i lagan za lokalni XAMPP setup.

+ +
+ POP3 read workflow + MySQL account storage + Inbox detail view +
+
+ +
+ + + + + +
+
+
+
+
+
Create / input
+

Dodaj POP3 račun

+
+ Server-side validation · encrypted password at rest +
+ + + + + +
+ +
+ + > +
+
+
+ + > +
+
+
+ + > +
+
+
+ + > +
+
+
+ + +
+
+ + > +
+
+
+ + > +
+
+
+ + > +
+
+
+
+ > + +
+
+
+ + Savjet za lokalni test: host 127.0.0.1, port 110, bez enkripcije. +
+
+
+
+ + + +
+
+
+
+
List
+

Spremljeni mailbox računi

+
+
+ Last sync: + Accounts: +
+
+ + +
+ + + + + + + + + + + + + + + + + + + + + +
MailboxPOP3StatusZadnja sinkronizacijaAkcija
+
+
+
+
:
+
· limit
+
+ +
poruka
+
+
+
Dodano
+
+ Otvori inbox +
+
+ +
+

Još nema spremljenih mailbox računa.

+

Dodaj prvi POP3 račun kako bi dashboard dobio live inbox i detail prikaz poruka.

+
+ Primjer hosta: 127.0.0.1 + Primjer porta: 110 + Sigurnost: plain +
+
+ +
+
+
+ + +
+ + diff --git a/mailbox.php b/mailbox.php new file mode 100644 index 0000000..686ea61 --- /dev/null +++ b/mailbox.php @@ -0,0 +1,279 @@ + 0 ? find_mail_account($accountId) : null; +$flash = pull_flash(); +$messages = []; +$selectedMessage = null; +$selectedNumber = max(0, (int) ($_GET['message'] ?? 0)); +$syncError = null; +$totalRemoteMessages = 0; +$displayedMessages = 0; +$currentStatus = $account ? (string) ($account['last_status'] ?: 'Ready') : 'Ready'; +$currentLastSync = $account['last_sync_at'] ?? null; + +if ($account) { + $client = null; + + try { + $password = decrypt_secret((string) $account['password_ciphertext']); + + if ($password === '') { + throw new RuntimeException('Spremljena lozinka se ne može dešifrirati. Ponovno spremi mailbox račun.'); + } + + $client = new Pop3Client((string) $account['pop3_host'], (int) $account['pop3_port'], (string) $account['security_mode']); + $client->connect(); + $client->login((string) $account['username'], $password); + + $stats = $client->stat(); + $totalRemoteMessages = (int) $stats['count']; + $messages = $client->fetchRecent((int) $account['sync_limit']); + $displayedMessages = count($messages); + + if ($selectedNumber <= 0 && !empty($messages)) { + $selectedNumber = (int) $messages[0]['number']; + } + + if ($selectedNumber > $totalRemoteMessages && !empty($messages)) { + $selectedNumber = (int) $messages[0]['number']; + } + + if ($selectedNumber > 0 && $totalRemoteMessages > 0) { + $selectedMessage = $client->fetchMessage($selectedNumber); + } + + $status = $totalRemoteMessages > 0 ? 'Connected' : 'Connected — empty mailbox'; + update_mail_account_sync($accountId, $status, $totalRemoteMessages); + $currentStatus = $status; + $currentLastSync = gmdate('Y-m-d H:i:s'); + } catch (Throwable $exception) { + $syncError = $exception->getMessage(); + update_mail_account_sync($accountId, 'Sync failed', 0); + $currentStatus = 'Sync failed'; + $currentLastSync = gmdate('Y-m-d H:i:s'); + } finally { + if ($client instanceof Pop3Client) { + $client->quit(); + } + } +} + +$pageLabel = $account ? ($account['label'] . ' — Inbox') : 'Mailbox not found'; +$pageTitle = project_name() . ' — ' . $pageLabel; +$projectBaseDescription = trim((string) ($_SERVER['PROJECT_DESCRIPTION'] ?? getenv('PROJECT_DESCRIPTION') ?: '')); +$pageDescription = $projectBaseDescription !== '' + ? $projectBaseDescription . ' — Live POP3 inbox detail with message reading and fetched-list search.' + : 'Read the latest POP3 messages in a clean split-view inbox with server-side search helpers and mailbox status.'; +$projectDescription = $projectBaseDescription !== '' ? $projectBaseDescription : $pageDescription; +$projectImageUrl = project_image_url(); +?> + + + + + + <?= h($pageTitle) ?> + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+
+ +
+ + + +
+

Mailbox nije pronađen.

+

Vrati se na dashboard i dodaj POP3 račun da bi otvorio inbox pregled.

+ Idi na dashboard +
+ +
+
+
Detail
+

+

· POP3 : ·

+
+ + Leave on server: + Inbox only in this slice +
+ +
+ +
+ + + + + +
+
+
+
+
List
+

Inbox poruke

+
+ Search in fetched set +
+ + +
+ + + +
+

+ +
+
+
+
+ +
+
+

Nijedna poruka iz dohvaćenog seta ne odgovara trenutnoj pretrazi.

+
+ +
+

Inbox je trenutno prazan.

+

Ako očekuješ poruke, klikni refresh ili provjeri da POP3 server zaista ima mail u sandučiću.

+
+ +
+ +
+
+
+
Read / detail
+

Detalj poruke

+
+ Server-rendered preview +
+ + +
+
+ Subject +
+
+
+ From +
+
+
+ Date / POP3 # +
+
+
+
+
+
+ +
+

Odaberi poruku s lijeve strane.

+

Kad odabereš mail, ovdje ćeš vidjeti subject, sender, datum i tekstualni sadržaj poruke.

+
+ + +
+
Mailbox settings
+
+
+ POP3 endpoint + : · +
+
+ Username + +
+
+ Saved in database + +
+
+
+
+
+ +
+ + + + diff --git a/xampp-setup.php b/xampp-setup.php new file mode 100644 index 0000000..c2b3dcd --- /dev/null +++ b/xampp-setup.php @@ -0,0 +1,199 @@ +getMessage(); + } +} + +app_boot(); + +$dbReady = db_ready(); +$dbError = $setupError ?: app_db_error(); +$pageTitle = project_name() . ' — XAMPP setup'; +$projectBaseDescription = trim((string) ($_SERVER['PROJECT_DESCRIPTION'] ?? getenv('PROJECT_DESCRIPTION') ?: '')); +$pageDescription = $projectBaseDescription !== '' + ? $projectBaseDescription . ' — Local XAMPP setup for the POP3 webmail database and first run.' + : 'Prepare the POP3 webmail app for local XAMPP by initializing the MySQL database and verifying the runtime configuration.'; +$projectDescription = $projectBaseDescription !== '' ? $projectBaseDescription : $pageDescription; +$projectImageUrl = project_image_url(); +?> + + + + + + <?= h($pageTitle) ?> + + + + + + + + + + + + + + + + + + + +
+ + +
+
+
Local install
+

Priprema za XAMPP lokalni rad

+

Otvori ovu stranicu unutar htdocs, pokreni Apache i MySQL u XAMPP-u, pa jednim klikom kreiraj bazu i mailbox tablicu. Nakon toga dashboard na index.php radi lokalno na localhost.

+
+ + Otvori dashboard + +
+ + +
+ + Natrag na aplikaciju +
+
+ Apache + MySQL + phpMyAdmin optional + Local URL ready +
+
+ +
+ + + + + + + +
+
+
+
+
3 steps
+

Kako pokrenuti aplikaciju na XAMPP-u

+
+
+
+

1. Kopiraj projekt u htdocs

+

Primjer: xampp/htdocs/pop3-webmail. Lokalni URL će tada biti sličan /index.php.

+
+
+

2. Pokreni Apache i MySQL

+

U XAMPP Control Panelu uključi oba servisa. Bez aktivnog MySQL-a spremanje mailboxa neće raditi.

+
+
+

3. Inicijaliziraj bazu

+

Klikni gumb Kreiraj bazu i tablicu. To će napraviti bazu i tablicu mail_accounts.

+
+
+
+
+ + +
+
+ + +