Files
EonaCat.LogStack/EonaCat.LogStack.Status/Pages/Certificates.cshtml
EonaCat 977374ce02 Added EonaCat.LogStack.Status
Updated EonaCat.LogStack.LogClient to support EonaCat.LogStack.Status
2026-03-12 21:15:33 +01:00

73 lines
3.5 KiB
Plaintext

@page
@model Status.Pages.CertificatesModel
@{
ViewData["Title"] = "Certificates";
ViewData["Page"] = "certs";
}
<div class="section-header">
<span class="section-title">SSL/TLS Certificates</span>
@if (Model.IsAdmin) { <a href="/admin/certificates" class="btn btn-outline btn-sm">Manage →</a> }
</div>
@if (!Model.Certificates.Any())
{
<div class="empty-state">
<div class="empty-state-icon">◧</div>
<div class="empty-state-text">No certificates tracked</div>
</div>
}
else
{
<div class="stats-grid">
@{
var now = DateTime.UtcNow;
var valid = Model.Certificates.Count(c => c.ExpiresAt.HasValue && (c.ExpiresAt.Value - now).TotalDays > 30);
var expiringSoon = Model.Certificates.Count(c => c.ExpiresAt.HasValue && (c.ExpiresAt.Value - now).TotalDays is > 0 and <= 30);
var expired = Model.Certificates.Count(c => c.ExpiresAt.HasValue && c.ExpiresAt.Value <= now);
}
<div class="stat-card up"><div class="stat-label">Valid</div><div class="stat-value">@valid</div></div>
<div class="stat-card warn"><div class="stat-label">Expiring &lt;30d</div><div class="stat-value">@expiringSoon</div></div>
<div class="stat-card down"><div class="stat-label">Expired</div><div class="stat-value">@expired</div></div>
</div>
<div class="card">
<table class="data-table">
<thead><tr>
<th>Name</th>
<th>Domain</th>
<th>Issuer</th>
<th>Valid From</th>
<th>Expires</th>
<th>Days Left</th>
<th>Fingerprint</th>
<th>Status</th>
</tr></thead>
<tbody>
@foreach (var certificate in Model.Certificates)
{
var days = certificate.ExpiresAt.HasValue ? (int)(certificate.ExpiresAt.Value - now).TotalDays : (int?)null;
var cls = days == null ? "" : days <= 0 ? "cert-expiry-expired" : days <= 7 ? "cert-expiry-critical" : days <= 30 ? "cert-expiry-warn" : "cert-expiry-ok";
<tr>
<td style="font-weight:500;color:var(--text-primary)">@certificate.Name</td>
<td class="mono" style="font-size:11px">@certificate.Domain</td>
<td style="font-size:11px;color:var(--text-muted);max-width:160px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap">@(certificate.Issuer?.Split(',').FirstOrDefault()?.Replace("CN=","") ?? "—")</td>
<td class="mono" style="font-size:11px">@(certificate.IssuedAt?.ToString("yyyy-MM-dd") ?? "—")</td>
<td class="mono @cls" style="font-size:11px">@(certificate.ExpiresAt?.ToString("yyyy-MM-dd") ?? "—")</td>
<td class="mono @cls" style="font-weight:700">@(days.HasValue ? days + "d" : "—")</td>
<td class="mono" style="font-size:10px;color:var(--text-muted)">@(certificate.Thumbprint?[..16] ?? "—")…</td>
<td>
@if (!string.IsNullOrEmpty(certificate.LastError)) { <span class="badge badge-down" title="@certificate.LastError">ERROR</span> }
else if (days == null) { <span class="badge badge-unknown">Unchecked</span> }
else if (days <= 0) { <span class="badge badge-down">EXPIRED</span> }
else if (days <= 7) { <span class="badge badge-down">CRITICAL</span> }
else if (days <= 30) { <span class="badge badge-warn">EXPIRING</span> }
else { <span class="badge badge-up">VALID</span> }
</td>
</tr>
}
</tbody>
</table>
</div>
}