Files
DMARC-Sentinel/app/templates/report.html
T
2026-05-16 12:05:36 -03:00

85 lines
4.1 KiB
HTML

{% extends "base.html" %}
{% block content %}
<header class="mb-stack-lg">
<h1 class="text-headline-xl-mobile font-bold text-on-background md:text-headline-xl">Report {{ report.id }}</h1>
<p class="mt-1 text-body-base text-on-surface-variant">{{ report.domain }} · {{ report.org_name or "unknown organization" }}</p>
</header>
<section class="mb-stack-lg grid grid-cols-1 gap-gutter md:grid-cols-2 xl:grid-cols-4">
<div class="metric-card">
<span class="label-caps">Report Org</span>
<span class="text-body-base font-bold">{{ report.org_name or "unknown" }}</span>
</div>
<div class="metric-card">
<span class="label-caps">Report ID</span>
<span class="break-all font-mono text-data-mono">{{ report.report_id or report.id }}</span>
</div>
<div class="metric-card">
<span class="label-caps">Date Range</span>
<span class="font-mono text-data-mono">{{ report.date_begin | fmt_dt }}<br>{{ report.date_end | fmt_dt }}</span>
</div>
<div class="metric-card">
<span class="label-caps">Published Policy</span>
<span class="font-mono text-data-mono">p={{ report.policy_p }}, sp={{ report.policy_sp }}, pct={{ report.policy_pct }}</span>
</div>
</section>
<section class="mb-stack-lg">
<h2 class="mb-stack-md text-headline-md font-semibold">Alerts From This Report</h2>
<div class="dw-alert-feed">
{% for alert in alerts %}
<a class="dw-alert-item is-{{ alert.severity_class }}" href="/alerts?domain={{ report.domain }}&alert_type={{ alert.type }}">
<span class="dw-alert-row">
<span>{{ alert.severity }}</span>
<time>{{ alert.status }}</time>
</span>
<strong>{{ alert.title }}</strong>
<p>{{ alert.llm_summary or alert.summary }}</p>
</a>
{% else %}
<div class="dw-alert-empty">No alerts are linked to this report.</div>
{% endfor %}
</div>
</section>
<section>
<h2 class="mb-stack-md text-headline-md font-semibold">Records</h2>
<div class="surface-card overflow-hidden">
<div class="data-table-wrap">
<table class="data-table">
<thead>
<tr>
<th title="DMARC aggregate source_ip: the IP observed by the reporting receiver. It may be a relay, forwarder, gateway, or direct sender.">Observed IP</th>
<th>Count</th>
<th>SPF</th>
<th>DKIM</th>
<th>DMARC</th>
<th>Known Sender</th>
<th>Applied Policy</th>
<th>Policy Override</th>
</tr>
</thead>
<tbody>
{% for row in report.records %}
<tr>
<td class="font-mono text-data-mono">{{ row.source_ip }}</td>
<td>{{ row.count }}</td>
<td title="{{ row.spf_auth_tooltip }}"><span class="status-chip {{ 'chip-pass' if row.policy_spf == 'pass' else 'chip-fail' }}">{{ row.policy_spf or "none" }}</span></td>
<td title="{{ row.dkim_auth_tooltip }}"><span class="status-chip {{ 'chip-pass' if row.policy_dkim == 'pass' else 'chip-fail' }}">{{ row.policy_dkim or "none" }}</span></td>
<td><span class="status-chip {{ 'chip-pass' if row.dmarc_pass else 'chip-fail' }}">{{ "pass" if row.dmarc_pass else "fail" }}</span></td>
<td><span class="status-chip {{ 'chip-pass' if row.known_sender_name else 'chip-info' }}" title="{{ row.known_sender_name or 'No configured sender matched this observed IP/authentication evidence.' }}">{{ row.known_sender_name or "unknown" }}</span></td>
<td><span class="status-chip {{ 'chip-pass' if not row.disposition or row.disposition == 'none' else ('chip-warning' if row.disposition == 'quarantine' else 'chip-fail') }}">{{ row.disposition or "none" }}</span></td>
<td><span class="status-chip {{ 'chip-info' if row.reason_type else 'chip-pass' }}" title="{{ row.reason_comment or 'No policy override reason reported.' }}">{{ row.reason_type or "none" }}</span></td>
</tr>
{% else %}
<tr>
<td colspan="8" class="text-on-surface-variant">No records found in this report.</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</section>
{% endblock %}