mirror of
https://github.com/ghostersk/gowebmail.git
synced 2026-04-17 16:46:01 +01:00
first commit
This commit is contained in:
39
web/templates/admin.html
Normal file
39
web/templates/admin.html
Normal file
@@ -0,0 +1,39 @@
|
||||
{{template "base" .}}
|
||||
{{define "title"}}GoMail Admin{{end}}
|
||||
{{define "body_class"}}admin-page{{end}}
|
||||
{{define "body"}}
|
||||
<div class="admin-layout">
|
||||
<nav class="admin-sidebar">
|
||||
<div class="logo-area">
|
||||
<a href="/">
|
||||
<div class="logo-icon"><svg viewBox="0 0 24 24"><path d="M20 4H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm0 4l-8 5-8-5V6l8 5 8-5v2z"/></svg></div>
|
||||
<span class="logo-text">GoMail</span>
|
||||
</a>
|
||||
</div>
|
||||
<div class="admin-nav">
|
||||
<a href="/admin" id="nav-users" class="active">
|
||||
<svg viewBox="0 0 24 24"><path d="M16 11c1.66 0 2.99-1.34 2.99-3S17.66 5 16 5c-1.66 0-3 1.34-3 3s1.34 3 3 3zm-8 0c1.66 0 2.99-1.34 2.99-3S9.66 5 8 5C6.34 5 5 6.34 5 8s1.34 3 3 3zm0 2c-2.33 0-7 1.17-7 3.5V19h14v-2.5c0-2.33-4.67-3.5-7-3.5zm8 0c-.29 0-.62.02-.97.05 1.16.84 1.97 1.97 1.97 3.45V19h6v-2.5c0-2.33-4.67-3.5-7-3.5z"/></svg>
|
||||
Users
|
||||
</a>
|
||||
<a href="/admin/settings" id="nav-settings">
|
||||
<svg viewBox="0 0 24 24"><path d="M19.14 12.94c.04-.3.06-.61.06-.94 0-.32-.02-.64-.07-.94l2.03-1.58c.18-.14.23-.41.12-.61l-1.92-3.32c-.12-.22-.37-.29-.59-.22l-2.39.96c-.5-.38-1.03-.7-1.62-.94l-.36-2.54c-.04-.24-.24-.41-.48-.41h-3.84c-.24 0-.43.17-.47.41l-.36 2.54c-.59.24-1.13.57-1.62.94l-2.39-.96c-.22-.08-.47 0-.59.22L2.74 8.87c-.12.21-.08.47.12.61l2.03 1.58c-.05.3-.09.63-.09.94s.02.64.07.94l-2.03 1.58c-.18.14-.23.41-.12.61l1.92 3.32c.12.22.37.29.59.22l2.39-.96c.5.38 1.03.7 1.62.94l.36 2.54c.05.24.24.41.48.41h3.84c.24 0 .44-.17.47-.41l.36-2.54c.59-.24 1.13-.56 1.62-.94l2.39.96c.22.08.47 0 .59-.22l1.92-3.32c.12-.22.07-.47-.12-.61l-2.01-1.58zM12 15.6c-1.98 0-3.6-1.62-3.6-3.6s1.62-3.6 3.6-3.6 3.6 1.62 3.6 3.6-1.62 3.6-3.6 3.6z"/></svg>
|
||||
Settings
|
||||
</a>
|
||||
<a href="/admin/audit" id="nav-audit">
|
||||
<svg viewBox="0 0 24 24"><path d="M14 2H6c-1.1 0-1.99.9-1.99 2L4 20c0 1.1.89 2 1.99 2H18c1.1 0 2-.9 2-2V8l-6-6zm2 16H8v-2h8v2zm0-4H8v-2h8v2zm-3-5V3.5L18.5 9H13z"/></svg>
|
||||
Audit Log
|
||||
</a>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<div class="admin-main" id="admin-content">
|
||||
<div class="spinner" style="margin-top:80px"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="toast-container" id="toast-container"></div>
|
||||
<div class="ctx-menu" id="ctx-menu"></div>
|
||||
{{end}}
|
||||
|
||||
{{define "scripts"}}
|
||||
<script src="/static/js/admin.js"></script>
|
||||
{{end}}
|
||||
251
web/templates/app.html
Normal file
251
web/templates/app.html
Normal file
@@ -0,0 +1,251 @@
|
||||
{{template "base" .}}
|
||||
{{define "title"}}GoMail{{end}}
|
||||
{{define "body_class"}}app-page{{end}}
|
||||
|
||||
{{define "body"}}
|
||||
<div class="app">
|
||||
<!-- Sidebar -->
|
||||
<aside class="sidebar">
|
||||
<div class="sidebar-header">
|
||||
<div class="logo">
|
||||
<div class="logo-icon"><svg viewBox="0 0 24 24"><path d="M20 4H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm0 4l-8 5-8-5V6l8 5 8-5v2z"/></svg></div>
|
||||
<span class="logo-text">GoMail</span>
|
||||
</div>
|
||||
<button class="compose-btn" onclick="openCompose()">+ Compose</button>
|
||||
</div>
|
||||
|
||||
<div class="accounts-section">
|
||||
<div class="section-label">Accounts</div>
|
||||
<div id="accounts-list"></div>
|
||||
<div class="add-account-btn" onclick="openModal('add-account-modal')">
|
||||
<svg width="12" height="12" viewBox="0 0 24 24" fill="currentColor"><path d="M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"/></svg>
|
||||
Connect account
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="nav-section">
|
||||
<div class="nav-item active" id="nav-unified" onclick="selectFolder('unified','Unified Inbox')">
|
||||
<svg viewBox="0 0 24 24" fill="currentColor"><path d="M20 4H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm0 4l-8 5-8-5V6l8 5 8-5v2z"/></svg>
|
||||
Unified Inbox
|
||||
<span class="unread-badge" id="unread-total" style="display:none"></span>
|
||||
</div>
|
||||
<div class="nav-item" id="nav-starred" onclick="selectFolder('starred','Starred')">
|
||||
<svg viewBox="0 0 24 24" fill="currentColor"><path d="M12 17.27L18.18 21l-1.64-7.03L22 9.24l-7.19-.61L12 2 9.19 8.63 2 9.24l5.46 4.73L5.82 21z"/></svg>
|
||||
Starred
|
||||
</div>
|
||||
<div id="folders-by-account"></div>
|
||||
</div>
|
||||
|
||||
<div class="sidebar-footer">
|
||||
<div class="user-info">
|
||||
<span class="user-name" id="user-display">...</span>
|
||||
<a href="/admin" id="admin-link" style="display:none;font-size:11px;color:var(--accent);text-decoration:none">Admin</a>
|
||||
</div>
|
||||
<div class="footer-actions">
|
||||
<button class="icon-btn" onclick="openSettings()" title="Settings">
|
||||
<svg viewBox="0 0 24 24"><path d="M19.14 12.94c.04-.3.06-.61.06-.94 0-.32-.02-.64-.07-.94l2.03-1.58c.18-.14.23-.41.12-.61l-1.92-3.32c-.12-.22-.37-.29-.59-.22l-2.39.96c-.5-.38-1.03-.7-1.62-.94l-.36-2.54c-.04-.24-.24-.41-.48-.41h-3.84c-.24 0-.43.17-.47.41l-.36 2.54c-.59.24-1.13.57-1.62.94l-2.39-.96c-.22-.08-.47 0-.59.22L2.74 8.87c-.12.21-.08.47.12.61l2.03 1.58c-.05.3-.09.63-.09.94s.02.64.07.94l-2.03 1.58c-.18.14-.23.41-.12.61l1.92 3.32c.12.22.37.29.59.22l2.39-.96c.5.38 1.03.7 1.62.94l.36 2.54c.05.24.24.41.48.41h3.84c.24 0 .44-.17.47-.41l.36-2.54c.59-.24 1.13-.56 1.62-.94l2.39.96c.22.08.47 0 .59-.22l1.92-3.32c.12-.22.07-.47-.12-.61l-2.01-1.58zM12 15.6c-1.98 0-3.6-1.62-3.6-3.6s1.62-3.6 3.6-3.6 3.6 1.62 3.6 3.6-1.62 3.6-3.6 3.6z"/></svg>
|
||||
</button>
|
||||
<button class="icon-btn" onclick="doLogout()" title="Sign out">
|
||||
<svg viewBox="0 0 24 24"><path d="M17 7l-1.41 1.41L18.17 11H8v2h10.17l-2.58 2.58L17 17l5-5zM4 5h8V3H4c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h8v-2H4V5z"/></svg>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<!-- Message list -->
|
||||
<div class="message-list-panel">
|
||||
<div class="panel-header">
|
||||
<span class="panel-title" id="panel-title">Unified Inbox</span>
|
||||
<span class="panel-count" id="panel-count"></span>
|
||||
</div>
|
||||
<div class="search-bar">
|
||||
<div class="search-wrap">
|
||||
<svg viewBox="0 0 24 24"><path d="M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z"/></svg>
|
||||
<input class="search-input" type="text" id="search-input" placeholder="Search emails..." oninput="handleSearch(this.value)">
|
||||
</div>
|
||||
</div>
|
||||
<div class="message-list" id="message-list">
|
||||
<div class="spinner" style="margin-top:60px"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Message detail -->
|
||||
<main class="message-detail" id="message-detail">
|
||||
<div class="no-message">
|
||||
<svg viewBox="0 0 24 24"><path d="M20 4H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm0 4l-8 5-8-5V6l8 5 8-5v2z"/></svg>
|
||||
<h3>Select a message</h3>
|
||||
<p>Choose a message from the list to read it</p>
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
|
||||
<!-- Compose window -->
|
||||
<div class="compose-overlay" id="compose-overlay">
|
||||
<div class="compose-window" id="compose-window">
|
||||
<div id="compose-resize-handle"></div>
|
||||
<div class="compose-header">
|
||||
<span class="compose-title" id="compose-title">New Message</span>
|
||||
<button class="compose-close" onclick="closeCompose()">×</button>
|
||||
</div>
|
||||
<div class="compose-field"><label>From</label><select id="compose-from"></select></div>
|
||||
<div class="compose-field compose-tag-field"><label>To</label><div id="compose-to" class="tag-container"></div></div>
|
||||
<div class="compose-field compose-tag-field" id="cc-row" style="display:none"><label>CC</label><div id="compose-cc-tags" class="tag-container"></div></div>
|
||||
<div class="compose-field compose-tag-field" id="bcc-row" style="display:none"><label>BCC</label><div id="compose-bcc-tags" class="tag-container"></div></div>
|
||||
<div class="compose-field"><label>Subject</label><input type="text" id="compose-subject" oninput="S.draftDirty=true"></div>
|
||||
<div class="compose-toolbar">
|
||||
<button class="fmt-btn" title="Bold" onclick="execFmt('bold')"><b>B</b></button>
|
||||
<button class="fmt-btn" title="Italic" onclick="execFmt('italic')"><i>I</i></button>
|
||||
<button class="fmt-btn" title="Underline" onclick="execFmt('underline')"><u>U</u></button>
|
||||
<span class="fmt-sep"></span>
|
||||
<button class="fmt-btn" title="Bullets" onclick="execFmt('insertUnorderedList')">•—</button>
|
||||
<button class="fmt-btn" title="Numbers" onclick="execFmt('insertOrderedList')">1—</button>
|
||||
<span class="fmt-sep"></span>
|
||||
<button class="fmt-btn" title="Link" onclick="insertLink()">🔗</button>
|
||||
<button class="fmt-btn" title="Clear format" onclick="execFmt('removeFormat')">T⃗</button>
|
||||
</div>
|
||||
<div id="compose-editor" contenteditable="true" class="compose-editor" placeholder="Write your message..."></div>
|
||||
<div id="compose-attach-list" class="compose-attach-list"></div>
|
||||
<div class="compose-footer">
|
||||
<button class="send-btn" id="send-btn" onclick="sendMessage()">Send</button>
|
||||
<div style="display:flex;gap:6px;margin-left:4px">
|
||||
<button class="btn-secondary" style="font-size:12px" onclick="document.getElementById('cc-row').style.display='flex'">+CC</button>
|
||||
<button class="btn-secondary" style="font-size:12px" onclick="document.getElementById('bcc-row').style.display='flex'">+BCC</button>
|
||||
<button class="btn-secondary" style="font-size:12px" onclick="triggerAttach()">📎 Attach</button>
|
||||
<button class="btn-secondary" style="font-size:12px" onclick="saveDraft()">✎ Draft</button>
|
||||
</div>
|
||||
<input type="file" id="compose-attach-input" multiple style="display:none" onchange="handleAttachFiles(this)">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Add Account Modal -->
|
||||
<div class="modal-overlay" id="add-account-modal">
|
||||
<div class="modal">
|
||||
<h2>Connect an account</h2>
|
||||
<p>Connect Gmail or Outlook via OAuth, or any email via IMAP/SMTP.</p>
|
||||
<div class="provider-btns">
|
||||
<button class="provider-btn" id="btn-gmail" onclick="connectOAuth('gmail')">
|
||||
<svg viewBox="0 0 24 24" width="18" height="18"><path fill="#EA4335" d="M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92c-.26 1.37-1.04 2.53-2.21 3.31v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.09z"/><path fill="#4285F4" d="M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z"/><path fill="#FBBC05" d="M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22.81-.62z"/><path fill="#EA4335" d="M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z"/></svg>
|
||||
Gmail
|
||||
</button>
|
||||
<button class="provider-btn" id="btn-outlook" onclick="connectOAuth('outlook')">
|
||||
<svg viewBox="0 0 24 24" width="18" height="18" fill="#0078D4"><path d="M21.179 4.781H11.25V12h9.929V4.781zM11.25 19.219h9.929V12H11.25v7.219zM2.821 12H11.25V4.781H2.821V12zm0 7.219H11.25V12H2.821v7.219z"/></svg>
|
||||
Outlook
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-divider"><span>or add IMAP account</span></div>
|
||||
<div class="modal-field"><label>Email Address</label><input type="email" id="imap-email" placeholder="you@example.com"></div>
|
||||
<div class="modal-field"><label>Display Name</label><input type="text" id="imap-name" placeholder="Your Name"></div>
|
||||
<div class="modal-field"><label>Password / App Password</label><input type="password" id="imap-password"></div>
|
||||
<div class="modal-row">
|
||||
<div class="modal-field"><label>IMAP Host</label><input type="text" id="imap-host" placeholder="imap.example.com"></div>
|
||||
<div class="modal-field"><label>IMAP Port</label><input type="number" id="imap-port" value="993"></div>
|
||||
</div>
|
||||
<div class="modal-row">
|
||||
<div class="modal-field"><label>SMTP Host</label><input type="text" id="smtp-host" placeholder="smtp.example.com"></div>
|
||||
<div class="modal-field"><label>SMTP Port</label><input type="number" id="smtp-port" value="587"></div>
|
||||
</div>
|
||||
<div class="test-result" id="test-result"></div>
|
||||
<div class="modal-actions">
|
||||
<button class="modal-cancel" onclick="closeModal('add-account-modal')">Cancel</button>
|
||||
<button class="btn-secondary" onclick="testNewConnection()" id="test-btn">Test Connection</button>
|
||||
<button class="modal-submit" onclick="addIMAPAccount()" id="save-acct-btn">Connect</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Edit Account Modal -->
|
||||
<div class="modal-overlay" id="edit-account-modal">
|
||||
<div class="modal">
|
||||
<h2>Account Settings</h2>
|
||||
<p id="edit-account-email" style="font-weight:500;color:var(--text);margin-bottom:16px"></p>
|
||||
<input type="hidden" id="edit-account-id">
|
||||
<div class="modal-field"><label>Display Name</label><input type="text" id="edit-name"></div>
|
||||
<div class="modal-field"><label>New Password (leave blank to keep current)</label><input type="password" id="edit-password"></div>
|
||||
<div class="modal-row">
|
||||
<div class="modal-field"><label>IMAP Host</label><input type="text" id="edit-imap-host"></div>
|
||||
<div class="modal-field"><label>IMAP Port</label><input type="number" id="edit-imap-port"></div>
|
||||
</div>
|
||||
<div class="modal-row">
|
||||
<div class="modal-field"><label>SMTP Host</label><input type="text" id="edit-smtp-host"></div>
|
||||
<div class="modal-field"><label>SMTP Port</label><input type="number" id="edit-smtp-port"></div>
|
||||
</div>
|
||||
<div class="settings-group-title" style="margin:16px 0 8px">Sync Settings</div>
|
||||
<div class="modal-field">
|
||||
<label>Import mode</label>
|
||||
<select id="edit-sync-mode" onchange="toggleSyncDaysField()" style="padding:8px 10px;background:var(--bg);border:1px solid var(--border);border-radius:6px;color:var(--text);font-size:13px;outline:none">
|
||||
<option value="days">Last N days</option>
|
||||
<option value="all">Full mailbox (all email)</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="modal-row" id="edit-sync-days-row">
|
||||
<div class="modal-field"><label>Days to fetch</label><input type="number" id="edit-sync-days" value="30" min="1" max="3650"></div>
|
||||
</div>
|
||||
<div id="edit-conn-result" class="test-result" style="display:none"></div>
|
||||
<div id="edit-last-error" style="display:none" class="alert error"></div>
|
||||
<div class="modal-actions">
|
||||
<button class="modal-cancel" onclick="closeModal('edit-account-modal')">Cancel</button>
|
||||
<button class="btn-secondary" id="edit-test-btn" onclick="testEditConnection()">Test Connection</button>
|
||||
<button class="modal-submit" onclick="saveAccountEdit()">Save</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Settings Modal -->
|
||||
<div class="modal-overlay" id="settings-modal">
|
||||
<div class="modal" style="width:520px">
|
||||
<div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:22px">
|
||||
<h2 style="margin-bottom:0">Settings</h2>
|
||||
<button onclick="closeModal('settings-modal')" class="icon-btn"><svg viewBox="0 0 24 24"><path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/></svg></button>
|
||||
</div>
|
||||
|
||||
<div class="settings-group">
|
||||
<div class="settings-group-title">Email Sync</div>
|
||||
<div style="font-size:13px;color:var(--muted);margin-bottom:12px">How often to automatically check all your accounts for new mail.</div>
|
||||
<div style="display:flex;gap:10px;align-items:center">
|
||||
<select id="sync-interval-select" style="flex:1;padding:8px 10px;background:var(--bg);border:1px solid var(--border);border-radius:6px;color:var(--text);font-family:'DM Sans',sans-serif;font-size:13px;outline:none">
|
||||
<option value="0">Manual only</option>
|
||||
<option value="1">Every 1 minute</option>
|
||||
<option value="5">Every 5 minutes</option>
|
||||
<option value="10">Every 10 minutes</option>
|
||||
<option value="15">Every 15 minutes (default)</option>
|
||||
<option value="30">Every 30 minutes</option>
|
||||
<option value="60">Every 60 minutes</option>
|
||||
</select>
|
||||
<button class="btn-primary" onclick="saveSyncInterval()">Save</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="settings-group">
|
||||
<div class="settings-group-title">Compose Window</div>
|
||||
<div style="font-size:13px;color:var(--muted);margin-bottom:12px">Open new message as an in-page panel (default) or a separate popup window.</div>
|
||||
<label style="display:flex;align-items:center;gap:10px;font-size:13px;cursor:pointer">
|
||||
<input type="checkbox" id="compose-popup-toggle" onchange="saveComposePopupPref()">
|
||||
Open compose in new popup window
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="settings-group">
|
||||
<div class="settings-group-title">Change Password</div>
|
||||
<div class="modal-field"><label>Current Password</label><input type="password" id="cur-pw"></div>
|
||||
<div class="modal-field"><label>New Password</label><input type="password" id="new-pw" placeholder="Min. 8 characters"></div>
|
||||
<button class="btn-primary" onclick="changePassword()">Update Password</button>
|
||||
</div>
|
||||
|
||||
<div class="settings-group">
|
||||
<div class="settings-group-title" style="display:flex;align-items:center;gap:10px">
|
||||
Two-Factor Authentication <span id="mfa-badge"></span>
|
||||
</div>
|
||||
<div id="mfa-panel">Loading...</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Context menu -->
|
||||
<div class="ctx-menu" id="ctx-menu"></div>
|
||||
<div class="toast-container" id="toast-container"></div>
|
||||
{{end}}
|
||||
|
||||
{{define "scripts"}}
|
||||
<script src="/static/js/app.js"></script>
|
||||
{{end}}
|
||||
17
web/templates/base.html
Normal file
17
web/templates/base.html
Normal file
@@ -0,0 +1,17 @@
|
||||
{{define "base"}}<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>{{block "title" .}}GoMail{{end}}</title>
|
||||
<link href="https://fonts.googleapis.com/css2?family=DM+Serif+Display&family=DM+Sans:ital,wght@0,300;0,400;0,500;1,400&display=swap" rel="stylesheet">
|
||||
<link rel="stylesheet" href="/static/css/gomail.css">
|
||||
{{block "head_extra" .}}{{end}}
|
||||
</head>
|
||||
<body class="{{block "body_class" .}}{{end}}">
|
||||
{{block "body" .}}{{end}}
|
||||
<script src="/static/js/gomail.js"></script>
|
||||
{{block "scripts" .}}{{end}}
|
||||
</body>
|
||||
</html>
|
||||
{{end}}
|
||||
27
web/templates/login.html
Normal file
27
web/templates/login.html
Normal file
@@ -0,0 +1,27 @@
|
||||
{{template "base" .}}
|
||||
{{define "title"}}GoMail — Sign In{{end}}
|
||||
{{define "body_class"}}auth-page{{end}}
|
||||
{{define "body"}}
|
||||
<div class="auth-card">
|
||||
<div class="logo">
|
||||
<div class="logo-icon"><svg viewBox="0 0 24 24"><path d="M20 4H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm0 4l-8 5-8-5V6l8 5 8-5v2z"/></svg></div>
|
||||
<span class="logo-text">GoMail</span>
|
||||
</div>
|
||||
<h1>Welcome back</h1>
|
||||
<p class="subtitle">Sign in to your GoMail account</p>
|
||||
<div id="err" class="alert error" style="display:none"></div>
|
||||
<form method="POST" action="/auth/login">
|
||||
<div class="field"><label>Username or Email</label><input type="text" name="username" placeholder="admin" required autocomplete="username"></div>
|
||||
<div class="field"><label>Password</label><input type="password" name="password" placeholder="••••••••" required autocomplete="current-password"></div>
|
||||
<button class="btn-primary" type="submit" style="width:100%;padding:13px;font-size:15px;margin-top:8px">Sign In</button>
|
||||
</form>
|
||||
<p style="font-size:12px;color:var(--muted);margin-top:16px;text-align:center">Default credentials: <strong>admin</strong> / <strong>admin</strong></p>
|
||||
</div>
|
||||
{{end}}
|
||||
{{define "scripts"}}
|
||||
<script>
|
||||
const msgs={invalid_credentials:'Invalid username or password.',missing_fields:'Please fill in all fields.'};
|
||||
const k=new URLSearchParams(location.search).get('error');
|
||||
if(k){const b=document.getElementById('err');b.textContent=msgs[k]||'An error occurred.';b.style.display='block';}
|
||||
</script>
|
||||
{{end}}
|
||||
27
web/templates/mfa.html
Normal file
27
web/templates/mfa.html
Normal file
@@ -0,0 +1,27 @@
|
||||
{{template "base" .}}
|
||||
{{define "title"}}GoMail — Two-Factor Auth{{end}}
|
||||
{{define "body_class"}}auth-page{{end}}
|
||||
{{define "body"}}
|
||||
<div class="auth-card">
|
||||
<div class="logo">
|
||||
<div class="logo-icon"><svg viewBox="0 0 24 24"><path d="M20 4H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm0 4l-8 5-8-5V6l8 5 8-5v2z"/></svg></div>
|
||||
<span class="logo-text">GoMail</span>
|
||||
</div>
|
||||
<h1>Two-Factor Auth</h1>
|
||||
<p class="subtitle">Enter the 6-digit code from your authenticator app</p>
|
||||
<div id="err" class="alert error" style="display:none"></div>
|
||||
<form method="POST" action="/auth/mfa/verify">
|
||||
<div class="field"><label>Verification Code</label>
|
||||
<input type="text" name="code" placeholder="000000" maxlength="6" inputmode="numeric" autocomplete="one-time-code" autofocus required
|
||||
style="font-size:22px;letter-spacing:.3em;text-align:center">
|
||||
</div>
|
||||
<button class="btn-primary" type="submit" style="width:100%;padding:13px;font-size:15px;margin-top:8px">Verify</button>
|
||||
</form>
|
||||
</div>
|
||||
{{end}}
|
||||
{{define "scripts"}}
|
||||
<script>
|
||||
const k=new URLSearchParams(location.search).get('error');
|
||||
if(k){const b=document.getElementById('err');b.textContent='Invalid code. Please try again.';b.style.display='block';}
|
||||
</script>
|
||||
{{end}}
|
||||
Reference in New Issue
Block a user