cheburcheck/website/templates/result.html.tera
senya xdearboy :) 58d9e7b68e
Some checks failed
Build Rust Application / Linux amd64 (.deb) (push) Has been cancelled
Build Rust Application / Linux arm64 (.deb via cross) (push) Has been cancelled
Build Rust Application / Windows amd64 (push) Has been cancelled
feat: asn support
* add asn and cidr subnet support

- parse AS numbers (AS13335 format)
- fetch prefixes from ripe stat api
- cache asn data for 24h, check results for 1h
- sample ips across subnets for checking
- show asn stats and prefix lists in ui
- link asn in results for quick lookup
- collapsible lists for long prefix/network lists
- trim whitespace from search input

* refactor: improve code structure and add enhanced error messages

* refactor: replace match with if let for single branch pattern

* fix: don't store ASN in database

* chore: bump version

---------

Co-authored-by: Lowder <me@lowderplay.dev>
2026-03-03 23:39:45 +05:00

315 lines
14 KiB
Text
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{% extends 'base' %}
{% block content %}
{% include 'search-form' %}
{% set warning = whitelist and not domain %}
<div class="result-panel {% if warning %}whitelist-theme{% elif found %}blocked-theme{% else %}clean-theme{% endif %}">
<div class="result-header">
<div class="icon-box status-icon">
{% if whitelist %}
<i data-lucide="shield-alert" width="32" height="32"></i>
{% elif blocked %}
<i data-lucide="shield-x" width="32" height="32"></i>
{% else %}
<i data-lucide="shield-check" width="32" height="32"></i>
{% endif %}
</div>
{% if warning %}
<div>
<h2>Белый список</h2>
<p class="subheading text-sm">
Ресурс находится в белом списке
</p>
</div>
{% elif found %}
<div>
<h2>Заблокирован</h2>
<p class="subheading text-sm">Ресурс был найден в списках блокировок</p>
</div>
{% else %}
<div>
<h2>Доступен</h2>
<p class="subheading text-sm">Ограничений не обнаружено</p>
</div>
{% endif %}
</div>
<div class="target-info">
<div class="target-info-label">{{ target_type }}:</div>
<div class="target-value target-display">{{ target }}</div>
</div>
{% if asn_info %}
<div class="asn-summary">
<div class="asn-stat">
<span class="asn-stat-label">Всего подсетей:</span>
<span class="asn-stat-value">{{ asn_info.prefixes | length }}</span>
</div>
{% if asn_info.blocked_prefixes | length > 0 %}
<div class="asn-stat">
<span class="asn-stat-label">Заблокировано:</span>
<span class="asn-stat-value alert">{{ asn_info.blocked_prefixes | length }}</span>
</div>
{% endif %}
</div>
{% endif %}
<div class="details-grid">
<div class="detail-section">
<h3 class="section-title">Сетевые данные</h3>
{% if not asn_info %}
<div class="detail-row">
<span class="row-label">IP-адреса</span>
<div class="ip-list-container">
{% if ips | length == 1 %}
<span class="ip-item">{{ ips | first }}</span>
{% if subnet_size %}
<span class="ip-count">({{ subnet_size }} всего)</span>
{% endif %}
{% elif ips | length <= 5 %}
{% for ip in ips %}
<span class="ip-item">{{ ip }}</span>
{% endfor %}
{% if subnet_size %}
<span class="ip-count">({{ subnet_size }} всего)</span>
{% endif %}
{% else %}
<div class="ip-summary">
<span class="ip-range">{{ ips | first }} — {{ ips | last }}</span>
{% if subnet_size %}
<span class="ip-count">({{ subnet_size }} всего, проверено {{ ips | length }})</span>
{% else %}
<span class="ip-count">({{ ips | length }} адресов)</span>
{% endif %}
</div>
<details class="ip-list-details">
<summary class="ip-list-toggle">
Показать все
</summary>
<div class="ip-list-expanded">
{% for ip in ips %}
<span class="ip-item">{{ ip }}</span>
{% endfor %}
</div>
</details>
{% endif %}
</div>
</div>
{% endif %}
<div class="detail-row">
<span class="row-label">Хостинг / ISP</span>
<span class="row-value">{% if geo.organisation %}{{ geo.organisation }}{% else %}-{% endif %}</span>
</div>
<div class="detail-row">
<span class="row-label">Локация</span>
<span class="row-value">{{ geo.location }}</span>
</div>
<div class="detail-row">
<span class="row-label">ASN</span>
<span class="row-value">
{% if geo.asn %}
<a href="/check?target={{ geo.asn }}" class="asn-link">{{ geo.asn }}</a>
{% else %}
-
{% endif %}
</span>
</div>
{% if asn_info %}
<div class="detail-row">
<span class="row-label">Подсети ASN</span>
<div class="prefix-list-container">
{% set ipv4_list = [] %}
{% set ipv6_list = [] %}
{% for prefix in asn_info.prefixes %}
{% if ":" in prefix %}
{% set_global ipv6_list = ipv6_list | concat(with=prefix) %}
{% else %}
{% set_global ipv4_list = ipv4_list | concat(with=prefix) %}
{% endif %}
{% endfor %}
{% set all_prefixes = ipv4_list | concat(with=ipv6_list) %}
{% if all_prefixes | length <= 10 %}
<div>
{% for prefix in all_prefixes %}
<p class="row-value">{{ prefix }}</p>
{% endfor %}
</div>
{% else %}
<div>
{% for prefix in all_prefixes | slice(end=10) %}
<p class="row-value">{{ prefix }}</p>
{% endfor %}
</div>
<details class="prefix-list-details">
<summary class="prefix-list-toggle">
Показать все ({{ all_prefixes | length }})
</summary>
<div class="prefix-list-expanded">
{% for prefix in all_prefixes %}
<p class="row-value">{{ prefix }}</p>
{% endfor %}
</div>
</details>
{% endif %}
</div>
</div>
{% endif %}
</div>
<div class="detail-section">
<h3 class="reason-header">Нахождение в списках</h3>
<div class="detail-row">
<span class="row-label">CDN</span>
{% if providers %}
<p class="row-value alert">НАЙДЕН</p>
{% else %}
<span class="row-value">Не найден</span>
{% endif %}
</div>
{% if providers %}
{% for provider, networks in providers %}
<div class="detail-row">
<span class="row-label">{{ provider }}</span>
<div class="cdn-networks-container">
{% if networks | length <= 5 %}
{% for network in networks %}
<p class="row-value">{{ network.cidr }}</p>
{% endfor %}
{% else %}
<div>
{% for network in networks | slice(end=5) %}
<p class="row-value">{{ network.cidr }}</p>
{% endfor %}
</div>
<details class="cdn-networks-details">
<summary class="cdn-networks-toggle">
Показать все ({{ networks | length }})
</summary>
<div class="cdn-networks-expanded">
{% for network in networks %}
<p class="row-value">{{ network.cidr }}</p>
{% endfor %}
</div>
</details>
{% endif %}
</div>
</div>
{% endfor %}
{% endif %}
{% if whitelist %}
<div class="detail-row">
<a href="/kb/whitelist" class="row-label">Белый список (?)</a>
<span class="row-value success">
НАЙДЕН - <span class="hint"
title="Дата последнего сканирования, когда данный домен был найден в белом списке">
<script>
document.write(new Date("{{ whitelist.last_ok }}").toLocaleDateString());
</script>
</span>
</span>
</div>
{% endif %}
<div class="detail-row">
<span class="row-label">Реестр РКН</span>
{% if domain %}
<span class="row-value alert">ОГРАНИЧЕН</span>
{% elif blocked_subnets %}
<span class="row-value alert hint"
title="Адреса пересекаются с подсетями заблокированных доменов (не гарантирует блокировку)">
IP-АДРЕСА
</span>
{% else %}
<span class="row-value">Не найден</span>
{% endif %}
</div>
{% if domain %}
<div class="detail-row">
<span class="row-label">Заблокированный домен</span>
<span class="row-value">{{ domain }}</span>
</div>
{% endif %}
{% if blocked_subnets and not asn_info %}
<div class="detail-row">
<span class="row-label">Заблокированные подсети</span>
<div>
{% for network in blocked_subnets %}
<p class="row-value">{{ network }}</p>
{% endfor %}
</div>
</div>
{% endif %}
{% if asn_info and asn_info.blocked_prefixes | length > 0 %}
<div class="detail-row">
<span class="row-label">Заблокированные подсети ASN</span>
<div class="blocked-prefix-list-container">
{% if asn_info.blocked_prefixes | length <= 10 %}
<div>
{% for prefix in asn_info.blocked_prefixes %}
<p class="row-value alert">{{ prefix }}</p>
{% endfor %}
</div>
{% else %}
<div>
{% for prefix in asn_info.blocked_prefixes | slice(end=10) %}
<p class="row-value alert">{{ prefix }}</p>
{% endfor %}
</div>
<details class="blocked-prefix-list-details">
<summary class="blocked-prefix-list-toggle">
Показать все ({{ asn_info.blocked_prefixes | length }})
</summary>
<div class="blocked-prefix-list-expanded">
{% for prefix in asn_info.blocked_prefixes %}
<p class="row-value alert">{{ prefix }}</p>
{% endfor %}
</div>
</details>
{% endif %}
</div>
</div>
{% endif %}
</div>
</div>
<div class="user-feedback-section">
<p class="feedback-prompt">У вас работает этот ресурс?</p>
<div class="feedback-buttons">
<button class="feedback-btn feedback-works" onclick="sendFeedback(true)">
<i data-lucide="thumbs-up" width="16" height="16"></i>
Работает
</button>
<button class="feedback-btn feedback-not-works" onclick="sendFeedback(false)">
<i data-lucide="thumbs-down" width="16" height="16"></i>
Не работает
</button>
</div>
<div class="feedback-status hidden">
<i data-lucide="thumbs-up" width="16" height="16"></i>
<span>Спасибо за ваш отзыв!</span>
</div>
</div>
</div>
<script>
function sendFeedback(works) {
document.querySelector('.feedback-buttons').classList.add('hidden');
document.querySelector('.feedback-prompt').classList.add('hidden');
document.querySelector('.feedback-status').classList.remove('hidden');
fetch(`/feedback/{{ id }}/${works}`, {
method: 'POST',
});
}
</script>
{% endblock content %}