domainapi/templates/dns_records.html
2025-04-08 23:41:24 +02:00

316 lines
No EOL
11 KiB
HTML

<!DOCTYPE html>
<html>
<head>
<title>DNS Records Viewer</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
body {
font-family: Arial, sans-serif;
margin: 0;
padding: 20px;
line-height: 1.6;
}
.container {
max-width: 1200px;
margin: 0 auto;
}
h1 {
color: #333;
border-bottom: 1px solid #eee;
padding-bottom: 10px;
margin-bottom: 20px;
}
.nav {
margin: 20px 0;
}
.nav-link {
display: inline-block;
padding: 8px 16px;
background-color: #4CAF50;
color: white;
text-decoration: none;
border-radius: 4px;
font-weight: bold;
margin-right: 10px;
}
.nav-link:hover {
opacity: 0.9;
}
.filter-section {
display: flex;
flex-wrap: wrap;
gap: 15px;
background-color: #f9f9f9;
padding: 15px;
border-radius: 5px;
margin-bottom: 20px;
}
.filter-group {
display: flex;
flex-direction: column;
}
.filter-group label {
font-weight: bold;
margin-bottom: 5px;
font-size: 0.9em;
}
.filter-group select, .filter-group input {
padding: 8px;
border: 1px solid #ddd;
border-radius: 4px;
min-width: 150px;
}
.filter-buttons {
display: flex;
align-items: flex-end;
gap: 10px;
}
button {
padding: 8px 16px;
background-color: #4CAF50;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
font-weight: bold;
}
button.reset {
background-color: #f44336;
}
button:hover {
opacity: 0.9;
}
table {
width: 100%;
border-collapse: collapse;
margin-top: 20px;
table-layout: fixed;
}
th, td {
padding: 12px 15px;
text-align: left;
border-bottom: 1px solid #ddd;
word-break: break-word;
}
th {
background-color: #f2f2f2;
font-weight: bold;
position: sticky;
top: 0;
z-index: 1;
}
tr:hover {
background-color: #f5f5f5;
}
/* History elements removed */
.badge {
display: inline-block;
padding: 3px 7px;
border-radius: 4px;
font-size: 0.9em;
font-weight: normal;
}
.record-type-badge {
background-color: #e0e0e0;
color: #333;
}
.sld-badge {
background-color: #d1e7dd;
color: #0f5132;
}
.tld-badge {
background-color: #cfe2ff;
color: #0a58ca;
}
.service-badge {
background-color: #fff3cd;
color: #664d03;
}
.api-section {
margin-top: 30px;
padding: 15px;
background-color: #f9f9f9;
border-radius: 5px;
}
code {
background: #f0f0f0;
padding: 2px 4px;
border-radius: 3px;
font-family: monospace;
}
.count-badge {
display: inline-block;
padding: 3px 8px;
background-color: #6c757d;
color: white;
border-radius: 10px;
font-size: 0.8em;
margin-left: 10px;
font-weight: normal;
}
.tooltip {
position: relative;
display: inline-block;
}
.tooltip .tooltiptext {
visibility: hidden;
width: 200px;
background-color: #555;
color: #fff;
text-align: center;
border-radius: 6px;
padding: 5px;
position: absolute;
z-index: 1;
bottom: 125%;
left: 50%;
margin-left: -100px;
opacity: 0;
transition: opacity 0.3s;
}
.tooltip:hover .tooltiptext {
visibility: visible;
opacity: 1;
}
@media (max-width: 768px) {
.filter-section {
flex-direction: column;
}
.filter-group {
width: 100%;
}
}
</style>
</head>
<body>
<div class="container">
<h1>DNS Entry Viewer</h1>
<div class="nav">
<a href="/" class="nav-link">SLD View</a>
<a href="/dns-records" class="nav-link">DNS Records</a>
</div>
<form class="filter-section" method="get" action="/dns-records">
<div class="filter-group">
<label for="upload-filter">Upload:</label>
<select id="upload-filter" name="upload_id">
<option value="">All Uploads</option>
{% for upload in uploads %}
<option value="{{ upload.id }}" {% if request.query_params.get('upload_id') == upload.id %}selected{% endif %}>
{{ upload.filename }} - {{ upload.timestamp.replace('T', ' ').split('.')[0] }}
</option>
{% endfor %}
</select>
</div>
<div class="filter-group">
<label for="record-type">Record Type:</label>
<select id="record-type" name="record_type">
<option value="">All Types</option>
{% for type in unique_values.record_type %}
<option value="{{ type }}" {% if request.query_params.get('record_type') == type %}selected{% endif %}>{{ type }}</option>
{% endfor %}
</select>
</div>
<div class="filter-group">
<label for="record-class">Record Class:</label>
<select id="record-class" name="record_class">
<option value="">All Classes</option>
{% for class in unique_values.record_class %}
<option value="{{ class }}" {% if request.query_params.get('record_class') == class %}selected{% endif %}>{{ class }}</option>
{% endfor %}
</select>
</div>
<div class="filter-group">
<label for="tld">TLD:</label>
<select id="tld" name="tld">
<option value="">All TLDs</option>
{% for tld in unique_values.tld %}
<option value="{{ tld }}" {% if request.query_params.get('tld') == tld %}selected{% endif %}>{{ tld }}</option>
{% endfor %}
</select>
</div>
<div class="filter-group">
<label for="sld">SLD:</label>
<select id="sld" name="sld">
<option value="">All SLDs</option>
{% for sld in unique_values.sld %}
<option value="{{ sld }}" {% if request.query_params.get('sld') == sld %}selected{% endif %}>{{ sld }}</option>
{% endfor %}
</select>
</div>
<div class="filter-group">
<label for="domain-search">Domain Search:</label>
<input type="text" id="domain-search" name="domain" placeholder="Enter domain name..." value="{{ request.query_params.get('domain', '') }}">
</div>
<div class="filter-buttons">
<button type="submit">Apply Filters</button>
<a href="/dns-records" class="reset-button" style="padding: 8px 16px; background-color: #f44336; color: white; text-decoration: none; border-radius: 4px; font-weight: bold; display: inline-block;">Reset</a>
</div>
</form>
<h2>DNS Records <span class="count-badge">{{ entries|length }}</span></h2>
{% if entries %}
<table id="dns-table">
<thead>
<tr>
<th style="width: 20%;">Domain</th>
<th style="width: 8%;">TTL</th>
<th style="width: 7%;">Class</th>
<th style="width: 8%;">Type</th>
<th style="width: 40%;">Data</th>
<th style="width: 17%;">Last Updated</th>
</tr>
</thead>
<tbody>
{% for entry in entries %}
<tr>
<td>
{% if entry.get('service') %}
<span class="badge service-badge">{{ entry.service }}</span>
{% endif %}
{% if entry.get('subdomain') %}
{{ entry.subdomain }}.
{% endif %}
<span class="badge sld-badge">{{ entry.sld }}</span>.
<span class="badge tld-badge">{{ entry.tld }}</span>
</td>
<td>{{ entry.ttl }}</td>
<td>{{ entry.record_class }}</td>
<td><span class="badge record-type-badge">{{ entry.record_type }}</span></td>
<td class="tooltip">
{{ entry.record_data }}
{% if entry.record_type == "SOA" or entry.record_data|length > 50 %}
<span class="tooltiptext">{{ entry.record_data }}</span>
{% endif %}
<!-- History elements removed -->
</td>
<td>
{{ entry.timestamp.replace('T', ' ').split('.')[0] }}
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% else %}
<p>No DNS entries found. Please upload a CSV file to get started.</p>
{% endif %}
<div class="api-section">
<h2>API Endpoints</h2>
<p>Get all DNS entries: <code>/api/dns</code></p>
<p>Get filtered DNS entries: <code>/api/dns?record_type=A&tld=de</code></p>
<p>Filter by upload: <code>/api/dns?upload_id={upload_id}</code></p>
<p>Get unique filter values: <code>/api/dns/types</code></p>
</div>
</div>
<!-- All JavaScript removed, using server-side FastAPI for filtering -->
<script>
// No JavaScript needed - all filtering handled by FastAPI
</script>
</body>
</html>