Commit Graph
172 Commits
Author SHA1 Message Date
NetworkCats 0ee38b44df fix: ensure city label is available for JS-rendered alt IP rows
When the primary IP lacks city data, the conditional <tr data-label="city">
row is absent from the DOM, so readLabels() cannot scrape the translated
label. Embed translated labels as data-l-* attributes on the <table> element
so they are always available regardless of which rows are rendered.
2026-03-23 18:23:42 +08:00
NetworkCats c2247fc4a6 fix: add explicit line-height to ensure consistent layout across languages 2026-03-22 19:28:50 +08:00
NetworkCats ead6ee47be fix: reduce spacing between info table labels and values 2026-03-22 19:01:12 +08:00
NetworkCats c15d7ad36a fix: apply rustfmt and replace map_or with is_some_and per clippy 2026-03-22 18:23:22 +08:00
NetworkCats 991fd289a2 fix: improve accessibility to meet WCAG 2.2 AA/AAA standards
- Remove disruptive alert() on error pages, rely on role="alert" banner
- Add skip navigation link for keyboard users (WCAG 2.4.1)
- Fix heading hierarchy on error page (sr-only status text in h1)
- Add "opens in a new tab" screen reader hint on external links
- Wrap language selector in form with noscript submit button (WCAG 3.2.2)
- Add aria-label to copy-to-clipboard buttons and footer landmarks
- Use h2 for alt-IP section to maintain single h1 per page
- Add persistent underline on links for non-color identification (WCAG 1.4.1)
- Fix footer attribution contrast ratio to ~5.5:1 (WCAG 1.4.3)
- Add aria-busy/role=status loading announcements for skeleton state
- Add translations for new accessibility strings across all 14 locales
- Update integration tests to assert role="alert" instead of alert()
2026-03-22 18:21:29 +08:00
NetworkCats b76410abf4 modernize JS to ES2022+ module and fix CSS logical property consistency
Rewrite script.js from ES5 (IIFEs, var, .then() chains) to modern ES2022+:
const/let, arrow functions, template literals, async/await, optional
chaining, for...of, .includes(), AbortSignal.timeout(), and DOM APIs
for dynamic HTML construction. Fix unhandled clipboard rejection, abort
timeout leak, and global scope pollution. Update script tag to
type="module" and fix CSS: top -> inset-block-start, flex-start -> start,
and indentation in media query block.
2026-03-22 18:01:05 +08:00
NetworkCats 5af03bf9b9 fix: PO parser escape order, proxy endpoint consistency, and accessibility bugs 2026-03-22 17:52:25 +08:00
NetworkCats ab7fb7c3c6 refactor: migrate templates to Askama custom i18n filter syntax
Replace all {{ t_field_name }} template variables with {{ "msgid"|t(locale) }}
filter calls across all 6 template files. This works with the #[askama::filter_fn]
defined in handlers/html.rs, which calls i18n::translate() directly.

Templates updated: index.html, error_alert.html, error_page.html,
_footer.html, _footer_lang.html, _search_form.html
2026-03-22 17:33:55 +08:00
NetworkCats 8fba47afd1 refactor: split models.rs into mmdb/api sub-modules with pub(crate) visibility
Split the 865-line models.rs into 3 focused files:
- models/mod.rs: conversion logic, helpers, re-exports, tests
- models/mmdb.rs: MMDB deserialization types (internal, pub(crate))
- models/api.rs: API serialization types (public) with From<MmdbProxy> impl

Mmdb types are now pub(crate) since they are internal deserialization details
that should not be part of the public API surface.
2026-03-22 17:33:40 +08:00
NetworkCats ee6ec1a28b refactor: split handlers.rs into focused sub-modules with DRY improvements
Split the 957-line handlers.rs into 4 focused files:
- handlers/mod.rs: shared state, IP resolution, non-browser request helper
- handlers/html.rs: HTML template rendering with Askama custom i18n filter,
  eliminating the Translations struct and ~250 lines of boilerplate
- handlers/api.rs: JSON/plain-text API endpoints with generic field_handler
  and proxy_field_handler helpers (consolidates 8 near-identical handlers)
- handlers/seo.rs: robots.txt, sitemap, OpenAPI, manifest

DRY improvements included:
- extract_ip_from_header() parameterized helper (deduplicates CF/IPv4 extraction)
- handle_non_browser_request() helper (deduplicates CLI/JSON early-return)
- append_ip_query() helper (deduplicates ?ip= redirect construction)
- field_handler/proxy_field_handler generics (consolidates 8 handlers)
- Askama #[filter_fn] custom filter for i18n (eliminates Translations struct)
2026-03-22 17:33:26 +08:00
NetworkCats 77410593f2 refactor: consolidate DB lookup boilerplate, UA detection, and polish error/module docs
Phase 1 (DRY):
- db.rs: extract with_reader() helper to eliminate repeated load-guard-lookup
  boilerplate across 6 lookup functions; use From<MmdbProxy> for ProxyInfo
- ua_detect.rs: extract matches_any_prefix() shared by both prefix-matching fns

Phase 4 (Quality polish):
- error.rs: implement Debug, Display, and std::error::Error on AppError
- Add module-level //! docs to all source modules
2026-03-22 17:33:09 +08:00
NetworkCats ccfa7decda feat: schedule DB updates at fixed daily UTC time instead of interval
Replace DB_UPDATE_INTERVAL_HOURS with DB_UPDATE_TIME_UTC (HH:MM format,
default 01:20) so the database update runs at a predictable time each day.
This ensures the update happens 20 minutes after the upstream Merged IP
Data release at 01:00 UTC.
2026-03-22 16:43:02 +08:00
NetworkCats cefdceab2c feat: add dismissible noscript notification banner
Show a fixed bottom banner for users with JavaScript disabled,
using CSS checkbox hack for dismissal without requiring JS.
2026-03-22 16:30:30 +08:00
NetworkCats bf3d96ac9c fix: use semantic data-label keys for alt-IP table row labels
The JS used fragile numeric indices to look up localized labels from the
server-rendered table. When optional rows (ASN, Org, Country, City) were
missing for the primary IP, the indices shifted, causing 'Proxy' to appear
as the City label. Add data-label attributes to each <tr> in the template
and key the label map by name instead of position.
2026-03-22 16:23:14 +08:00
NetworkCats d078859c5c relax rate limits: 100/50/30 RPM tiers at 0/300/500 RPS thresholds 2026-03-22 14:13:12 +08:00
NetworkCats 4877724408 fix: dynamically scale down IPv6 address font size based on length 2026-03-22 12:34:26 +08:00
NetworkCats 66a3db8901 style: restore import order to satisfy cargo fmt 2026-03-22 12:20:27 +08:00
NetworkCats 41016891eb fix: update proxy test assertions to match current MMDB data
45.77.77.77 no longer has is_hosting=true in the upstream database;
it now reports is_anonymous=true instead.
2026-03-22 12:17:20 +08:00
NetworkCats da8434662f feat: add skeleton loading state for alt-IP section when primary IP is IPv6
Show a shimmer skeleton placeholder while fetching the local IPv4
address via the IPv4-only domain. When the primary IP is already IPv4,
no loading state is displayed and the alt section fades in directly.
2026-03-22 12:06:56 +08:00
NetworkCats d236302b09 fix: skip alt-IP detection when querying another IP address
The detectAltIp() function was unconditionally fetching the viewer's own
IPv6/IPv4 address and displaying it alongside queried IP results. Pass
the is_query flag to the client via a data attribute and guard the
alt-IP detection so it only runs when viewing your own IP.
2026-03-22 11:58:44 +08:00
NetworkCats fb661933e8 fix(deploy): replace SIGHUP reload with container recreate to fix bind mount staleness
Docker file-level bind mounts track inodes, not paths. Ansible template
writes create new inodes, leaving the container reading orphaned files.
Replacing SIGHUP with force-recreate ensures fresh mounts every time,
eliminating the admin socket dependency entirely.
2026-03-20 09:40:56 +08:00
NetworkCats bd71dae443 fix(deploy): preserve bind mount inode with unsafe_writes for HAProxy config 2026-03-20 08:56:06 +08:00
NetworkCats 09f3b6bd72 fix(deploy): move HAProxy admin socket to /tmp for correct permissions
The named Docker volume created /var/run/haproxy owned by root:root,
preventing the haproxy user (uid 99) from creating the socket file.
2026-03-20 08:17:36 +08:00
NetworkCats f72cf8190b fix(deploy): retry admin socket command after HAProxy reload 2026-03-20 07:36:52 +08:00
NetworkCats 1c8f274453 refactor(deploy): use HAProxy admin socket instead of stats HTTP API 2026-03-20 07:01:09 +08:00
NetworkCats 258f68af5d fix(deploy): force server out of maintenance after HAProxy SIGHUP reload 2026-03-20 06:49:29 +08:00
NetworkCats ec91cd7738 refactor: remove FAQPage JSON-LD structured data block 2026-03-20 06:20:50 +08:00
NetworkCats f2a6678bf5 Fix live demo link to use HTTPS
Updated the live demo link to use HTTPS.
2026-03-16 11:42:08 +08:00
NetworkCats c2fc9d00f4 fix(ci): disable codecov auto-search to prevent false file detection 2026-03-11 05:58:55 +08:00
NetworkCats 797bb7c76a fix Fmt 2026-03-10 21:44:29 +00:00
NetworkCats 60e4f08fd3 docs: update installation guides for IPv4 domain configuration 2026-03-11 05:06:58 +08:00
NetworkCats d7f24cc0ab feat: update Ansible and deploy workflow for IPv4 domain support 2026-03-11 05:03:43 +08:00
NetworkCats 3f11d2161f fix: use localized names in JS-rendered secondary IP info table 2026-03-11 04:43:12 +08:00
NetworkCats bcb06e0e82 test: add integration tests for IPv4 domain routing and dual-stack detection 2026-03-11 04:41:41 +08:00
NetworkCats 1872142bbb feat: add JS dual-stack IP detection with full info display 2026-03-11 04:40:05 +08:00
NetworkCats 8567630f7a feat: add host-based routing and IPv4 domain handler with CORS 2026-03-11 04:38:10 +08:00
NetworkCats dfdfda0e81 feat: add HAProxy dual-domain routing with separate IPv4 headers 2026-03-11 04:33:47 +08:00
NetworkCats c876d17e8c feat: add IPV4_DOMAIN config for dual-stack IP detection 2026-03-11 04:33:01 +08:00
NetworkCats 5565f4a0a5 feat: add HTTP port 80 support with Cloudflare-only firewall rules 2026-03-08 05:52:42 +08:00
NetworkCats 801ed1f45e fix: verify backend is UP in HAProxy before removing old container 2026-03-08 04:40:53 +08:00
NetworkCats 21249e1717 fix: use window.URL to avoid document.URL shadowing in inline handler 2026-03-08 04:16:32 +08:00
NetworkCats bc282c4279 fix: allow HAProxy to start with unresolved inactive backend 2026-03-08 03:02:10 +08:00
NetworkCats f0b6a18083 fix: relax TLS cert permissions for HAProxy container access 2026-03-08 02:23:22 +08:00
NetworkCats 609c71920b fix: replace docker inspect with docker exec health probe in deploy verification 2026-03-08 01:44:05 +08:00
NetworkCats f1b89e5a64 fix: remove extra quotes from docker inspect format in health check 2026-03-08 01:04:37 +08:00
NetworkCats 9ff0649c02 fix: prevent docker inspect SSH exit from aborting health check loop 2026-03-08 00:36:18 +08:00
NetworkCats 0b90e5b3cd fix: prevent ssh-keyscan non-zero exit from aborting deploy under bash -e 2026-03-08 00:03:33 +08:00
NetworkCats ff9f024950 fix: add SSH options to deploy health check to prevent host key failure 2026-03-07 23:35:30 +08:00
NetworkCats e7fe02a3ea fix: correct HAProxy 3.3.4 config syntax in prod template 2026-03-07 22:49:36 +08:00
NetworkCats b4a9750dbd fix: correct Dockerfile volume permissions and HAProxy 3.3.4 config syntax 2026-03-07 22:48:36 +08:00