117 lines
7.2 KiB
HTML
117 lines
7.2 KiB
HTML
{{define "title"}}Whitelisted IPs - Email Server{{end}}
|
|
|
|
{{define "content"}}
|
|
<div class="container-fluid">
|
|
<div class="d-flex justify-content-between align-items-center mb-4">
|
|
<h2><i class="bi bi-router me-2"></i>Whitelisted IP Addresses</h2>
|
|
<a href="/pymta-manager/ips/add" class="btn btn-success"><i class="bi bi-plus-circle me-2"></i>Add IP Address</a>
|
|
</div>
|
|
|
|
<div class="card mb-4">
|
|
<div class="card-header"><h5 class="mb-0"><i class="bi bi-list me-2"></i>Whitelisted IP Addresses</h5></div>
|
|
<div class="card-body">
|
|
{{if .ips}}
|
|
<div class="table-responsive">
|
|
<table class="table table-striped">
|
|
<thead><tr><th>IP Address</th><th>Domain</th><th>Status</th><th>Storage Type</th><th>Added</th><th>Actions</th></tr></thead>
|
|
<tbody>
|
|
{{range .ips}}
|
|
{{$ip := index . 0}}{{$domain := index . 1}}
|
|
<tr>
|
|
<td><div class="fw-bold font-monospace">{{$ip.IPAddress}}</div></td>
|
|
<td><span class="badge bg-secondary">{{$domain.domain_name}}</span></td>
|
|
<td>{{if $ip.IsActive}}<span class="badge bg-success"><i class="bi bi-check-circle me-1"></i>Active</span>{{else}}<span class="badge bg-danger"><i class="bi bi-x-circle me-1"></i>Inactive</span>{{end}}</td>
|
|
<td>{{if $ip.StoreMessageContent}}<span class="badge bg-info text-dark"><i class="bi bi-file-earmark-text me-1"></i>Stores Full Message</span>{{else}}<span class="badge bg-secondary"><i class="bi bi-file-earmark me-1"></i>Headers Only</span>{{end}}</td>
|
|
<td><small class="text-muted">{{strftime "%Y-%m-%d %H:%M" $ip.CreatedAt}}</small></td>
|
|
<td>
|
|
<div class="btn-group" role="group">
|
|
<a href="/pymta-manager/ips/{{$ip.ID}}/edit" class="btn btn-outline-primary btn-sm" title="Edit IP"><i class="bi bi-pencil"></i></a>
|
|
{{if $ip.IsActive}}
|
|
<form method="post" action="/pymta-manager/ips/{{$ip.ID}}/delete" class="d-inline">
|
|
<button type="submit" class="btn btn-outline-warning btn-sm" title="Disable IP" data-confirm="Disable {{$ip.IPAddress}}?"><i class="bi bi-pause-circle"></i></button>
|
|
</form>
|
|
{{else}}
|
|
<form method="post" action="/pymta-manager/ips/{{$ip.ID}}/enable" class="d-inline">
|
|
<button type="submit" class="btn btn-outline-success btn-sm" title="Enable IP" data-confirm="Enable {{$ip.IPAddress}}?"><i class="bi bi-play-circle"></i></button>
|
|
</form>
|
|
{{end}}
|
|
<form method="post" action="/pymta-manager/ips/{{$ip.ID}}/remove" class="d-inline">
|
|
<button type="submit" class="btn btn-outline-danger btn-sm" title="Permanently Remove IP" data-confirm="Permanently remove {{$ip.IPAddress}}? This cannot be undone!"><i class="bi bi-trash"></i></button>
|
|
</form>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
{{end}}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
{{else}}
|
|
<div class="text-center py-5">
|
|
<i class="bi bi-router text-muted" style="font-size: 4rem;"></i>
|
|
<h4 class="text-muted mt-3">No IP Addresses Whitelisted</h4>
|
|
<p class="text-muted">Add IP addresses to allow authentication without username/password</p>
|
|
<a href="/pymta-manager/ips/add" class="btn btn-primary"><i class="bi bi-plus-circle me-2"></i>Add First IP Address</a>
|
|
</div>
|
|
{{end}}
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row">
|
|
<div class="col-md-8">
|
|
<div class="card">
|
|
<div class="card-header"><h6 class="mb-0"><i class="bi bi-info-circle me-2"></i>IP Whitelist Information</h6></div>
|
|
<div class="card-body">
|
|
<div class="alert alert-info mb-0">
|
|
<h6 class="alert-heading"><i class="bi bi-shield-check me-2"></i>How IP Whitelisting Works</h6>
|
|
<ul class="mb-0 small">
|
|
<li>Whitelisted IPs can send emails without username/password authentication</li>
|
|
<li>Each IP is associated with a specific domain</li>
|
|
<li>IP can only send emails for its authorized domain</li>
|
|
<li>Useful for server-to-server email sending</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="col-md-4">
|
|
<div class="card">
|
|
<div class="card-header"><h6 class="mb-0"><i class="bi bi-geo-alt me-2"></i>Your Current IP</h6></div>
|
|
<div class="card-body">
|
|
<div class="text-center">
|
|
<div class="fw-bold font-monospace fs-5" id="current-ip"><span class="spinner-border spinner-border-sm me-2"></span>Detecting...</div>
|
|
<button class="btn btn-outline-primary btn-sm mt-2" onclick="addCurrentIP()"><i class="bi bi-plus-circle me-1"></i>Add This IP</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{{end}}
|
|
|
|
{{define "extra_js"}}
|
|
<script>
|
|
async function detectCurrentIP() {
|
|
try {
|
|
const response = await fetch('https://ifconfig.me/all.json');
|
|
const data = await response.json();
|
|
document.getElementById('current-ip').innerHTML = `<span class="text-primary">${data.ip_addr}</span>`;
|
|
} catch (error) {
|
|
document.getElementById('current-ip').innerHTML = '<span class="text-muted">Unable to detect</span>';
|
|
}
|
|
}
|
|
function addCurrentIP() {
|
|
const currentIPElement = document.getElementById('current-ip');
|
|
const ip = currentIPElement.textContent.trim();
|
|
if (ip && ip !== 'Detecting...' && ip !== 'Unable to detect') {
|
|
const url = new URL('/pymta-manager/ips/add', window.location.origin);
|
|
url.searchParams.set('ip', ip);
|
|
window.location.href = url.toString();
|
|
} else {
|
|
showToast('Unable to detect current IP address', 'danger');
|
|
}
|
|
}
|
|
detectCurrentIP();
|
|
</script>
|
|
{{end}}
|