286 lines
12 KiB
HTML
286 lines
12 KiB
HTML
{% extends "base.html" %}
|
|
|
|
{% block title %}Dashboard - Email Server Management{% endblock %}
|
|
{% block page_title %}Dashboard{% endblock %}
|
|
|
|
{% block content %}
|
|
<div class="row">
|
|
<!-- Statistics Cards -->
|
|
<div class="col-lg-3 col-md-6 mb-4">
|
|
<div class="card border-primary">
|
|
<div class="card-body">
|
|
<div class="d-flex align-items-center">
|
|
<div class="flex-grow-1">
|
|
<h5 class="card-title text-primary mb-1">
|
|
<i class="bi bi-globe me-2"></i>
|
|
Domains
|
|
</h5>
|
|
<h3 class="mb-0">{{ domain_count }}</h3>
|
|
<small class="text-muted">Active domains</small>
|
|
</div>
|
|
<div class="fs-2 text-primary opacity-50">
|
|
<i class="bi bi-globe"></i>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="col-lg-3 col-md-6 mb-4">
|
|
<div class="card border-success">
|
|
<div class="card-body">
|
|
<div class="d-flex align-items-center">
|
|
<div class="flex-grow-1">
|
|
<h5 class="card-title text-success mb-1">
|
|
<i class="bi bi-people me-2"></i>
|
|
Users
|
|
</h5>
|
|
<h3 class="mb-0">{{ user_count }}</h3>
|
|
<small class="text-muted">Authenticated users</small>
|
|
</div>
|
|
<div class="fs-2 text-success opacity-50">
|
|
<i class="bi bi-people"></i>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="col-lg-3 col-md-6 mb-4">
|
|
<div class="card border-warning">
|
|
<div class="card-body">
|
|
<div class="d-flex align-items-center">
|
|
<div class="flex-grow-1">
|
|
<h5 class="card-title text-warning mb-1">
|
|
<i class="bi bi-shield-check me-2"></i>
|
|
DKIM Keys
|
|
</h5>
|
|
<h3 class="mb-0">{{ dkim_count }}</h3>
|
|
<small class="text-muted">Active DKIM keys</small>
|
|
</div>
|
|
<div class="fs-2 text-warning opacity-50">
|
|
<i class="bi bi-shield-check"></i>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="col-lg-3 col-md-6 mb-4">
|
|
<div class="card border-info">
|
|
<div class="card-body">
|
|
<div class="d-flex align-items-center">
|
|
<div class="flex-grow-1">
|
|
<h5 class="card-title text-info mb-1">
|
|
<i class="bi bi-activity me-2"></i>
|
|
Status
|
|
</h5>
|
|
<h6 class="text-success mb-0">
|
|
<i class="bi bi-circle-fill me-1" style="font-size: 0.5rem;"></i>
|
|
Online
|
|
</h6>
|
|
<small class="text-muted">Server running</small>
|
|
</div>
|
|
<div class="fs-2 text-info opacity-50">
|
|
<i class="bi bi-activity"></i>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row">
|
|
<!-- Recent Email Activity -->
|
|
<div class="col-lg-8 mb-4">
|
|
<div class="card">
|
|
<div class="card-header d-flex justify-content-between align-items-center">
|
|
<h5 class="mb-0">
|
|
<i class="bi bi-envelope me-2"></i>
|
|
Recent Email Activity
|
|
</h5>
|
|
<a href="{{ url_for('email.logs', type='emails') }}" class="btn btn-outline-light btn-sm">
|
|
View All
|
|
</a>
|
|
</div>
|
|
<div class="card-body p-0">
|
|
{% if recent_emails %}
|
|
<div class="table-responsive">
|
|
<table class="table table-dark table-hover mb-0">
|
|
<thead>
|
|
<tr>
|
|
<th>Time</th>
|
|
<th>From</th>
|
|
<th>To</th>
|
|
<th>Status</th>
|
|
<th>DKIM</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{% for email in recent_emails %}
|
|
<tr>
|
|
<td>
|
|
<small class="text-muted">
|
|
{{ email.created_at.strftime('%H:%M:%S') }}
|
|
</small>
|
|
</td>
|
|
<td>
|
|
<span class="text-truncate d-inline-block" style="max-width: 150px;" title="{{ email.mail_from }}">
|
|
{{ email.mail_from }}
|
|
</span>
|
|
</td>
|
|
<td>
|
|
<span class="text-truncate d-inline-block" style="max-width: 150px;" title="{{ email.to_address }}">
|
|
{{ email.to_address }}
|
|
</span>
|
|
</td>
|
|
<td>
|
|
{% if email.status == 'relayed' %}
|
|
<span class="badge bg-success">
|
|
<i class="bi bi-check-circle me-1"></i>
|
|
Sent
|
|
</span>
|
|
{% else %}
|
|
<span class="badge bg-danger">
|
|
<i class="bi bi-x-circle me-1"></i>
|
|
Failed
|
|
</span>
|
|
{% endif %}
|
|
</td>
|
|
<td>
|
|
{% if email.dkim_signed %}
|
|
<span class="text-success">
|
|
<i class="bi bi-shield-check" title="DKIM Signed"></i>
|
|
</span>
|
|
{% else %}
|
|
<span class="text-muted">
|
|
<i class="bi bi-shield-x" title="Not DKIM Signed"></i>
|
|
</span>
|
|
{% endif %}
|
|
</td>
|
|
</tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
{% else %}
|
|
<div class="text-center py-4">
|
|
<i class="bi bi-envelope text-muted fs-1"></i>
|
|
<p class="text-muted mt-2">No email activity yet</p>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Recent Authentication Activity -->
|
|
<div class="col-lg-4 mb-4">
|
|
<div class="card">
|
|
<div class="card-header d-flex justify-content-between align-items-center">
|
|
<h5 class="mb-0">
|
|
<i class="bi bi-shield-lock me-2"></i>
|
|
Recent Auth Activity
|
|
</h5>
|
|
<a href="{{ url_for('email.logs', type='auth') }}" class="btn btn-outline-light btn-sm">
|
|
View All
|
|
</a>
|
|
</div>
|
|
<div class="card-body p-0">
|
|
{% if recent_auths %}
|
|
<div class="list-group list-group-flush">
|
|
{% for auth in recent_auths %}
|
|
<div class="list-group-item list-group-item-dark d-flex justify-content-between align-items-start">
|
|
<div class="ms-2 me-auto">
|
|
<div class="fw-bold">
|
|
{% if auth.success %}
|
|
<i class="bi bi-check-circle text-success me-1"></i>
|
|
{% else %}
|
|
<i class="bi bi-x-circle text-danger me-1"></i>
|
|
{% endif %}
|
|
{{ auth.auth_type|title }}
|
|
</div>
|
|
<small class="text-muted">
|
|
{{ auth.identifier }}
|
|
</small>
|
|
<br>
|
|
<small class="text-muted">
|
|
{{ auth.created_at.strftime('%H:%M:%S') }}
|
|
</small>
|
|
</div>
|
|
<small class="text-muted">
|
|
{{ auth.ip_address }}
|
|
</small>
|
|
</div>
|
|
{% endfor %}
|
|
</div>
|
|
{% else %}
|
|
<div class="text-center py-4">
|
|
<i class="bi bi-shield-lock text-muted fs-1"></i>
|
|
<p class="text-muted mt-2">No authentication activity yet</p>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Quick Actions -->
|
|
<div class="row">
|
|
<div class="col-12">
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<h5 class="mb-0">
|
|
<i class="bi bi-lightning me-2"></i>
|
|
Quick Actions
|
|
</h5>
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="row">
|
|
<div class="col-md-3 mb-3">
|
|
<div class="d-grid">
|
|
<a href="{{ url_for('email.add_domain') }}" class="btn btn-outline-primary">
|
|
<i class="bi bi-plus-circle me-2"></i>
|
|
Add Domain
|
|
</a>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-3 mb-3">
|
|
<div class="d-grid">
|
|
<a href="{{ url_for('email.add_user') }}" class="btn btn-outline-success">
|
|
<i class="bi bi-person-plus me-2"></i>
|
|
Add User
|
|
</a>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-3 mb-3">
|
|
<div class="d-grid">
|
|
<a href="{{ url_for('email.add_ip') }}" class="btn btn-outline-warning">
|
|
<i class="bi bi-shield-plus me-2"></i>
|
|
Whitelist IP
|
|
</a>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-3 mb-3">
|
|
<div class="d-grid">
|
|
<a href="{{ url_for('email.settings') }}" class="btn btn-outline-info">
|
|
<i class="bi bi-gear me-2"></i>
|
|
Settings
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endblock %}
|
|
|
|
{% block extra_js %}
|
|
<script>
|
|
// Auto-refresh dashboard every 30 seconds
|
|
setTimeout(function() {
|
|
location.reload();
|
|
}, 30000);
|
|
</script>
|
|
{% endblock %}
|