added relay
This commit is contained in:
@@ -29,6 +29,7 @@
|
||||
.badge-red{background:#7f1d1d;color:#fca5a5}
|
||||
.badge-yellow{background:#78350f;color:#fcd34d}
|
||||
.badge-gray{background:#374151;color:#9ca3af}
|
||||
.badge-blue{background:#1e3a5f;color:#93c5fd}
|
||||
.flash-ok{background:#064e3b;border:1px solid #065f46;color:#6ee7b7;padding:.75rem 1rem;border-radius:.375rem;margin-bottom:1rem;font-size:.875rem}
|
||||
.flash-err{background:#7f1d1d;border:1px solid #991b1b;color:#fca5a5;padding:.75rem 1rem;border-radius:.375rem;margin-bottom:1rem;font-size:.875rem}
|
||||
</style>
|
||||
|
||||
@@ -163,6 +163,65 @@
|
||||
<!-- DNS check results injected here -->
|
||||
<div id="dns-check-{{.Domain.ID}}" style="display:none;margin-top:1.25rem;padding-top:1rem;border-top:1px solid #374151"></div>
|
||||
</div>
|
||||
|
||||
<!-- IP Relay Rules -->
|
||||
<div class="card">
|
||||
<div class="text-sm font-semibold text-gray-300 mb-2">IP Relay Rules</div>
|
||||
<div class="text-xs text-gray-400 mb-3">
|
||||
Allow specific IP addresses (or CIDR ranges) to submit email for this domain
|
||||
without SMTP authentication. Optionally restrict to specific sender addresses.
|
||||
</div>
|
||||
{{if .RelayIPRules}}
|
||||
<div style="margin-bottom:.75rem;overflow:auto">
|
||||
<table style="font-size:.7rem;width:100%;border-collapse:collapse">
|
||||
<thead>
|
||||
<tr style="color:#6b7280;text-align:left;border-bottom:1px solid #374151">
|
||||
<th style="padding:.25rem .5rem">IP / CIDR</th>
|
||||
<th style="padding:.25rem .5rem">Sender pattern</th>
|
||||
<th style="padding:.25rem .5rem">Description</th>
|
||||
<th style="padding:.25rem .5rem"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{range .RelayIPRules}}
|
||||
<tr style="border-bottom:1px solid #1f2937">
|
||||
<td style="padding:.25rem .5rem;font-family:monospace;color:#93c5fd">{{.CIDR}}</td>
|
||||
<td style="padding:.25rem .5rem;font-family:monospace;color:#a78bfa">{{.SenderPattern}}</td>
|
||||
<td style="padding:.25rem .5rem;color:#9ca3af">{{.Description}}</td>
|
||||
<td style="padding:.25rem .5rem;text-align:right">
|
||||
<form method="POST" action="/admin/domains/{{$.Domain.ID}}/relay/{{.ID}}/delete" style="margin:0"
|
||||
onsubmit="return confirm('Remove this IP relay rule?')">
|
||||
<input type="hidden" name="_csrf" value="{{$.CSRF}}">
|
||||
<button type="submit" class="btn btn-danger btn-sm" style="padding:.125rem .5rem;font-size:.7rem">Remove</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
{{end}}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{{else}}
|
||||
<div class="text-xs text-gray-500 mb-3">No IP relay rules configured.</div>
|
||||
{{end}}
|
||||
<form method="POST" action="/admin/domains/{{.Domain.ID}}/relay/add">
|
||||
<input type="hidden" name="_csrf" value="{{.CSRF}}">
|
||||
<div style="display:grid;grid-template-columns:1fr 1fr;gap:.5rem">
|
||||
<div class="field" style="margin:0">
|
||||
<label style="font-size:.7rem">IP or CIDR</label>
|
||||
<input type="text" name="cidr" required placeholder="10.0.0.1 or 10.0.0.0/24" maxlength="50">
|
||||
</div>
|
||||
<div class="field" style="margin:0">
|
||||
<label style="font-size:.7rem">Sender pattern</label>
|
||||
<input type="text" name="sender_pattern" required placeholder="*@{{.Domain.Name}}" maxlength="255">
|
||||
</div>
|
||||
</div>
|
||||
<div class="field" style="margin:.5rem 0 .75rem">
|
||||
<label style="font-size:.7rem">Description (optional)</label>
|
||||
<input type="text" name="description" placeholder="Internal mail server" maxlength="255">
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary btn-sm">Add rule</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -6,11 +6,12 @@
|
||||
<h1 class="text-xl font-bold text-white">{{.U.Email}}</h1>
|
||||
{{if .U.Enabled}}<span class="badge badge-green">active</span>{{else}}<span class="badge badge-red">disabled</span>{{end}}
|
||||
{{if .U.Admin}}<span class="badge badge-yellow">admin</span>{{else if .U.DomainAdmin}}<span class="badge badge-gray">domain admin</span>{{end}}
|
||||
{{if .U.IsRelay}}<span class="badge badge-blue">relay</span>{{end}}
|
||||
</div>
|
||||
|
||||
<div style="display:grid;grid-template-columns:1fr 1fr;gap:1.5rem">
|
||||
|
||||
<!-- Edit user -->
|
||||
<!-- Left column -->
|
||||
<div>
|
||||
<div class="card">
|
||||
<div class="text-sm font-semibold text-gray-300 mb-3">User settings</div>
|
||||
@@ -20,11 +21,13 @@
|
||||
<label>Display name</label>
|
||||
<input type="text" name="display_name" value="{{.U.DisplayName}}" maxlength="255">
|
||||
</div>
|
||||
{{if not .U.IsRelay}}
|
||||
<div class="field">
|
||||
<label>Quota (MB)</label>
|
||||
<input type="number" name="quota_mb" value="{{mb .U.QuotaBytes}}" min="0" max="1048576">
|
||||
</div>
|
||||
<div style="display:flex;gap:1.5rem;margin-bottom:.875rem">
|
||||
{{end}}
|
||||
<div style="display:flex;gap:1.5rem;margin-bottom:.875rem;flex-wrap:wrap">
|
||||
<label style="display:flex;align-items:center;gap:.375rem;cursor:pointer;margin:0">
|
||||
<input type="checkbox" name="enabled" value="1" {{if .U.Enabled}}checked{{end}} style="width:auto">
|
||||
<span class="text-sm">Enabled</span>
|
||||
@@ -54,26 +57,83 @@
|
||||
<button type="submit" class="btn btn-primary btn-sm">Set password</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<!-- Relay mode toggle -->
|
||||
<div class="card">
|
||||
<div class="text-sm font-semibold text-gray-300 mb-2">Relay account mode</div>
|
||||
<div class="text-xs text-gray-400 mb-3">
|
||||
Relay accounts authenticate via SMTP only — no IMAP mailboxes, no webmail.
|
||||
They can send email as their own address or any permitted send-as pattern below.
|
||||
</div>
|
||||
<form method="POST" action="/admin/users/{{.U.ID}}/relay/toggle">
|
||||
<input type="hidden" name="_csrf" value="{{.CSRF}}">
|
||||
{{if .U.IsRelay}}
|
||||
<input type="hidden" name="relay" value="0">
|
||||
<button type="submit" class="btn btn-danger btn-sm">Disable relay mode</button>
|
||||
{{else}}
|
||||
<input type="hidden" name="relay" value="1">
|
||||
<button type="submit" class="btn btn-primary btn-sm">Enable relay mode</button>
|
||||
{{end}}
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Info + danger -->
|
||||
<!-- Right column -->
|
||||
<div>
|
||||
<div class="card">
|
||||
<div class="text-sm font-semibold text-gray-300 mb-3">Account info</div>
|
||||
<div class="text-xs space-y-1.5 text-gray-400">
|
||||
<div>Email: <span class="text-white">{{.U.Email}}</span></div>
|
||||
<div>Domain: <span class="text-white">{{.U.DomainName}}</span></div>
|
||||
{{if not .U.IsRelay}}
|
||||
<div>Used: <span class="text-white">{{humanBytes .U.UsedBytes}}</span>
|
||||
of <span class="text-white">{{if .U.QuotaBytes}}{{humanBytes .U.QuotaBytes}}{{else}}unlimited{{end}}</span></div>
|
||||
{{end}}
|
||||
<div>Created: <span class="text-white">{{shortTime .U.CreatedAt}}</span></div>
|
||||
<div>Last login: <span class="text-white">{{if isZero .U.LastLogin}}never{{else}}{{shortTime .U.LastLogin}}{{end}}</span></div>
|
||||
<div>MFA: <span class="text-white">{{if .U.MFAEnabled}}enabled{{else}}disabled{{end}}</span></div>
|
||||
<div>Type: <span class="text-white">{{if .U.IsRelay}}relay (SMTP only){{else}}mailbox{{end}}</span></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{if .U.IsRelay}}
|
||||
<!-- Send-as patterns -->
|
||||
<div class="card">
|
||||
<div class="text-sm font-semibold text-gray-300 mb-2">Permitted sender addresses</div>
|
||||
<div class="text-xs text-gray-400 mb-3">
|
||||
This account can always send as its own address. Add patterns to allow additional
|
||||
sender addresses. Use <span style="font-family:monospace;color:#93c5fd">*@domain.com</span>
|
||||
to allow any address at a domain.
|
||||
</div>
|
||||
{{if .SendAs}}
|
||||
<div style="margin-bottom:.75rem">
|
||||
{{range .SendAs}}
|
||||
<div style="display:flex;align-items:center;justify-content:space-between;padding:.375rem .5rem;background:#111827;border-radius:.25rem;margin-bottom:.375rem">
|
||||
<span style="font-family:monospace;font-size:.75rem;color:#93c5fd">{{.Pattern}}</span>
|
||||
<form method="POST" action="/admin/users/{{$.U.ID}}/relay/{{.ID}}/delete" style="margin:0">
|
||||
<input type="hidden" name="_csrf" value="{{$.CSRF}}">
|
||||
<button type="submit" class="btn btn-danger btn-sm" style="padding:.125rem .5rem;font-size:.7rem">Remove</button>
|
||||
</form>
|
||||
</div>
|
||||
{{end}}
|
||||
</div>
|
||||
{{else}}
|
||||
<div class="text-xs text-gray-500 mb-3">No additional patterns configured. Only own address allowed.</div>
|
||||
{{end}}
|
||||
<form method="POST" action="/admin/users/{{.U.ID}}/relay/sendas" style="display:flex;gap:.5rem;align-items:flex-end">
|
||||
<input type="hidden" name="_csrf" value="{{.CSRF}}">
|
||||
<div class="field" style="margin:0;flex:1">
|
||||
<label style="font-size:.7rem">Pattern (email or *@domain.com)</label>
|
||||
<input type="text" name="pattern" required placeholder="newsletter@example.com or *@example.com" maxlength="255">
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary btn-sm">Add</button>
|
||||
</form>
|
||||
</div>
|
||||
{{end}}
|
||||
|
||||
<div class="card" style="border:1px solid #7f1d1d">
|
||||
<div class="text-sm font-semibold text-red-400 mb-2">Delete user</div>
|
||||
<div class="text-xs text-gray-400 mb-3">Permanently deletes the user account, all mailboxes, and all messages. Cannot be undone.</div>
|
||||
<div class="text-xs text-gray-400 mb-3">Permanently deletes this account and all associated data. Cannot be undone.</div>
|
||||
<form method="POST" action="/admin/users/{{.U.ID}}/delete"
|
||||
onsubmit="return confirm('Delete user {{.U.Email}} and all their data?')">
|
||||
<input type="hidden" name="_csrf" value="{{.CSRF}}">
|
||||
|
||||
@@ -40,6 +40,10 @@
|
||||
<input type="checkbox" name="domain_admin" value="1" id="da" style="width:auto">
|
||||
<label for="da" style="margin:0;cursor:pointer">Domain admin</label>
|
||||
</div>
|
||||
<div class="field" style="margin:0;display:flex;align-items:center;gap:.5rem;padding-top:1.25rem">
|
||||
<input type="checkbox" name="relay" value="1" id="relay" style="width:auto">
|
||||
<label for="relay" style="margin:0;cursor:pointer">Relay account (SMTP only)</label>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
@@ -72,6 +76,7 @@
|
||||
<td>
|
||||
{{if .Admin}}<span class="badge badge-yellow">admin</span>
|
||||
{{else if .DomainAdmin}}<span class="badge badge-gray">domain admin</span>
|
||||
{{else if .IsRelay}}<span class="badge badge-blue">relay</span>
|
||||
{{else}}<span class="badge badge-gray">user</span>{{end}}
|
||||
</td>
|
||||
<td class="text-gray-400 text-xs">{{humanBytes .UsedBytes}} / {{if .QuotaBytes}}{{humanBytes .QuotaBytes}}{{else}}unlimited{{end}}</td>
|
||||
|
||||
Reference in New Issue
Block a user