2025-06-07 10:48:03 +01:00
{% extends "base.html" %}
{% block title %}Domains - Email Server Management{% endblock %}
{% block page_title %}Domain Management{% endblock %}
{% block content %}
< div class = "d-flex justify-content-between align-items-center mb-4" >
< h2 >
< i class = "bi bi-globe me-2" > < / i >
Domains
< / h2 >
< a href = "{{ url_for('email.add_domain') }}" class = "btn btn-primary" >
< i class = "bi bi-plus-circle me-2" > < / i >
Add Domain
< / a >
< / div >
< div class = "card" >
< div class = "card-header" >
< h5 class = "mb-0" >
< i class = "bi bi-list-ul me-2" > < / i >
All Domains
< / h5 >
< / div >
< div class = "card-body p-0" >
{% if domains %}
< div class = "table-responsive" >
< table class = "table table-dark table-hover mb-0" >
< thead >
< tr >
< th > Domain Name< / th >
< th > Status< / th >
< th > Created< / th >
2025-06-08 22:51:07 +01:00
< th > Senders< / th >
2025-06-07 10:48:03 +01:00
< th > DKIM< / th >
< th > Actions< / th >
< / tr >
< / thead >
< tbody >
{% for domain in domains %}
< tr >
< td >
< div class = "fw-bold" > {{ domain.domain_name }}< / div >
< / td >
< td >
{% if domain.is_active %}
< 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 >
{% endif %}
< / td >
< td >
< small class = "text-muted" >
{{ domain.created_at.strftime('%Y-%m-%d %H:%M') }}
< / small >
< / td >
< td >
< span class = "badge bg-info" >
2025-06-08 22:51:07 +01:00
{{ domain.users|length }} senders
2025-06-07 10:48:03 +01:00
< / span >
< / td >
< td >
2025-06-08 22:51:07 +01:00
{% set active_dkim_keys = domain.dkim_keys|selectattr('is_active')|list %}
{% if active_dkim_keys %}
< span class = "dns-status" id = "dkim-status-{{ domain.domain_name.replace('.', '-') }}" >
< span class = "status-indicator status-warning" > < / span >
< i class = "bi bi-shield-check" title = "DKIM Active (DNS not checked)" > < / i >
2025-06-07 10:48:03 +01:00
< / span >
{% else %}
2025-06-08 22:51:07 +01:00
{% if domain.dkim_keys|length > 0 %}
< span class = "text-secondary" >
< i class = "bi bi-shield" title = "DKIM Disabled" > < / i >
< / span >
{% else %}
< span class = "text-danger" >
< i class = "bi bi-shield-exclamation" title = "No DKIM Key" > < / i >
< / span >
{% endif %}
2025-06-07 10:48:03 +01:00
{% endif %}
< / td >
< td >
< div class = "btn-group btn-group-sm" role = "group" >
2025-06-07 11:57:21 +01:00
<!-- Edit Button -->
< a href = "{{ url_for('email.edit_domain', domain_id=domain.id) }}"
class="btn btn-outline-primary"
title="Edit Domain">
< i class = "bi bi-pencil" > < / i >
2025-06-07 10:48:03 +01:00
< / a >
2025-06-07 11:57:21 +01:00
<!-- Toggle Enable/Disable Button -->
< form method = "post" action = "{{ url_for('email.toggle_domain', domain_id=domain.id) }}" class = "d-inline" >
{% if domain.is_active %}
2025-06-07 10:48:03 +01:00
< button type = "submit"
2025-06-07 11:57:21 +01:00
class="btn btn-outline-warning"
onclick="return confirm('Are you sure you want to disable domain \'{{ domain.domain_name }}\'?')"
title="Disable Domain">
< i class = "bi bi-pause-circle" > < / i >
2025-06-07 10:48:03 +01:00
< / button >
2025-06-07 11:57:21 +01:00
{% else %}
< button type = "submit"
class="btn btn-outline-success"
onclick="return confirm('Are you sure you want to enable domain \'{{ domain.domain_name }}\'?')"
title="Enable Domain">
< i class = "bi bi-play-circle" > < / i >
< / button >
{% endif %}
< / form >
<!-- Remove Button -->
< form method = "post" action = "{{ url_for('email.remove_domain', domain_id=domain.id) }}" class = "d-inline" >
< button type = "submit"
class="btn btn-outline-danger"
onclick="return confirm('WARNING: This will permanently delete domain \'{{ domain.domain_name }}\' and ALL associated data (users, IPs, DKIM keys). This action cannot be undone. Are you sure you want to continue?')"
title="Permanently Remove Domain">
< i class = "bi bi-trash" > < / i >
< / button >
< / form >
2025-06-07 10:48:03 +01:00
< / div >
< / td >
< / tr >
{% endfor %}
< / tbody >
< / table >
< / div >
{% else %}
< div class = "text-center py-5" >
< i class = "bi bi-globe text-muted" style = "font-size: 4rem;" > < / i >
< h4 class = "text-muted mt-3" > No domains configured< / h4 >
< p class = "text-muted" > Get started by adding your first domain< / p >
< a href = "{{ url_for('email.add_domain') }}" class = "btn btn-primary" >
< i class = "bi bi-plus-circle me-2" > < / i >
Add Your First Domain
< / a >
< / div >
{% endif %}
< / div >
< / div >
{% if domains %}
< div class = "row mt-4" >
< div class = "col-md-6" >
< div class = "card" >
< div class = "card-header" >
< h6 class = "mb-0" >
< i class = "bi bi-info-circle me-2" > < / i >
Domain Information
< / h6 >
< / div >
< div class = "card-body" >
< ul class = "list-unstyled mb-0" >
< li class = "mb-2" >
< i class = "bi bi-check-circle text-success me-2" > < / i >
< strong > Active domains:< / strong > {{ domains|selectattr('is_active')|list|length }}
< / li >
< li class = "mb-2" >
< i class = "bi bi-shield-check text-warning me-2" > < / i >
2025-06-08 22:51:07 +01:00
< strong > DKIM configured:< / strong >
{% set dkim_count = namespace(active=0) %}
{% for domain in domains %}
{% set active_dkim_keys = domain.dkim_keys|selectattr('is_active')|list %}
{% if active_dkim_keys %}
{% set dkim_count.active = dkim_count.active + 1 %}
{% endif %}
{% endfor %}
{{ dkim_count.active }}
2025-06-07 10:48:03 +01:00
< / li >
< / ul >
< / div >
< / div >
< / div >
< div class = "col-md-6" >
< div class = "card" >
< div class = "card-header" >
< h6 class = "mb-0" >
< i class = "bi bi-lightbulb me-2" > < / i >
Quick Tips
< / h6 >
< / div >
< div class = "card-body" >
< ul class = "list-unstyled mb-0" >
< li class = "mb-2" >
< i class = "bi bi-arrow-right text-primary me-2" > < / i >
DKIM keys are automatically generated for new domains
< / li >
< li class = "mb-2" >
< i class = "bi bi-arrow-right text-primary me-2" > < / i >
Configure DNS records after adding domains
< / li >
< li >
< i class = "bi bi-arrow-right text-primary me-2" > < / i >
2025-06-08 22:51:07 +01:00
Add senders or whitelist IPs for authentication
2025-06-07 10:48:03 +01:00
< / li >
< / ul >
< / div >
< / div >
< / div >
< / div >
{% endif %}
{% endblock %}
2025-06-08 22:51:07 +01:00
{% block extra_js %}
< script >
async function checkDomainDKIM(domain, selector) {
const dkimStatus = document.getElementById(`dkim-status-${domain.replace('.', '-')}`);
if (!dkimStatus) return;
try {
// Check DKIM DNS
const response = await fetch("{{ url_for('email.check_dkim_dns') }}", {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
body: new URLSearchParams({
domain: domain,
selector: selector
})
});
const result = await response.json();
if (result.success) {
dkimStatus.innerHTML = `
< span class = "status-indicator status-success" > < / span >
< i class = "bi bi-shield-check" title = "DKIM Active & DNS Configured" > < / i >
`;
} else {
dkimStatus.innerHTML = `
< span class = "status-indicator" style = "background-color: #fd7e14;" > < / span >
< i class = "bi bi-shield-exclamation" title = "DKIM Active but DNS not found" > < / i >
`;
}
} catch (error) {
console.error('DKIM DNS check error:', error);
dkimStatus.innerHTML = `
< span class = "status-indicator status-danger" > < / span >
< i class = "bi bi-shield-x" title = "Error checking DKIM DNS" > < / i >
`;
}
}
// Check DKIM DNS for all domains when page loads
document.addEventListener('DOMContentLoaded', async function() {
{% for domain in domains %}
{% set active_dkim_keys = domain.dkim_keys|selectattr('is_active')|list %}
{% if active_dkim_keys %}
{% set active_key = active_dkim_keys|first %}
await checkDomainDKIM('{{ domain.domain_name }}', '{{ active_key.selector }}');
{% endif %}
{% endfor %}
});
< / script >
< style >
.status-indicator {
width: 8px;
height: 8px;
border-radius: 50%;
display: inline-block;
margin-right: 0.5rem;
}
.status-success { background-color: #28a745; }
.status-warning { background-color: #ffc107; }
.status-danger { background-color: #dc3545; }
.dns-status {
display: inline-flex;
align-items: center;
}
< / style >
{% endblock %}