[pull] main from jason5ng32:main#107
Merged
Merged
Conversation
…tatic assets
Service-worker offline caching had no real value (every detection in this
app needs the network) and conflicted with Cloudflare challenge pages —
the SW would NetworkFirst-timeout and serve a stale index.html, then the
hashed chunk requests came back as a wall of 403s from CF.
Replace with conventional HTTP cache headers in frontend-server.js:
- dist/assets/** + dist/fonts/** → 1y immutable (content-addressed)
- top-level images → 24h
- index.html + manifest.webmanifest → no-store (so deploys propagate
cleanly to hashed chunks)
- everything else → 1h
Existing prod clients still have the old SW + ~5 MB precache installed,
so unregister-service-worker.js does a one-shot cleanup on first load
after this deploy: unregister all SW registrations, drop every cache.
Safe to delete the file and its main.js call after a few release cycles.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Most /api endpoints are caller-specific (e.g. /api/ipinfo without ?ip reads the *caller's* IP, /api/getuserinfo returns the authenticated user's profile). Without explicit headers, a stray Cloudflare cache rule could serve user A's response to user B. Add a one-line middleware on /api/* that defaults every response to no-store, mounted before requireReferer so even rejected 403/404/429 responses carry the header. Pure-function handlers (whois / macchecker / cfradar / map / configs) can override later with public, max-age=… if edge caching is desired. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Rename pref connectivityAutoRefresh → connectivityMultipleTests across defaults, tests, locales (en/zh/fr/tr), Preferences, and ConnectivityTest. - Defer the Congrats/OhNo toast until every round finishes; aggregate the verdict via "ever-succeeded across all rounds" (mintime > 0) so a target reachable in any later round still counts as connected. Sticky alertToShow latch prevents interval ticks from suppressing it. - Preserve best-of-N face/text/ms — a later failed round no longer downgrades a card that already succeeded. - Add per-card progress dots: one slot per round, bootstrap-only writer so manual operations leave the historical snapshot alone. Head-of-queue pulses; pulse suppressed once the user takes over. - Trim verbose comments throughout the component. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
New /api/asn-history handler queries RIPEstat routing-history for an IP and enriches each historical ASN with its holder name via as-overview (parallel, best-effort — org=null on timeout, ASN timeline still ships). Filters out leak-grade prefixes (< /8 v4, < /19 v6) and low-visibility announcements (< 30 full-feed peers) before fetching org names. UI: ASN row in IpDetailPanel now has two view-toggles (Info / History) sharing one Collapsible; at most one open at a time. Session-cached per IP. Locale keys added in en/zh/fr/tr; bumps version to 6.2.0. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Introduce a cacheable(maxAge) middleware factory in backend-server.js that hooks res.json to attach Cache-Control: public, max-age=N — but only on 2xx responses, so Cloudflare's edge never caches 4xx/5xx. Wire it on the routes whose upstreams refresh slowly: cfradar / asn-history / whois / maxmind / macchecker plus the third-party IP geolocation handlers (ipinfo / ipapicom / ipsb / ipapiis / ip2location). Auth-context handlers (ipchecking, invisibility, dns-leak-test/session, getuserinfo, updateuserachievement) remain on the global no-store default — their caching belongs at the upstream that owns the auth. Also trim stale "what" comments throughout backend-server.js and document the new pattern in api/AGENTS.md. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
/api/asn-history previously took ?ip=, producing a unique CF cache key per IP — wasteful since BGP routes are announced at /24 (v4) and /48 (v6) at minimum, so every IP in the same prefix has identical routing history. Frontend now quantizes the user's IP to its DFZ-floor prefix via toBgpPrefix() and hits /api/asn-history?prefix=...; CF can dedupe 256 v4 addresses (or a /48's worth of v6) onto one edge cache entry. Backend swaps requireValidIP() for a new requireValidPrefix() guard that validates any well-formed CIDR. RIPEstat returns identical results whether queried by IP or its covering prefix (verified empirically), so the upstream call is unchanged in shape. Shared via common/bgp-prefix.js with a frontend re-export at frontend/utils/bgp-prefix.js, matching the valid-ip.js pattern. 50 new tests cover v4/v6 quantization (including various IPv6 shorthand forms, mixed case, leading-zero normalization) and the prefix guard. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
A dozen components already statically import @iconify/vue, so wrapping addCollection in a dynamic import() achieved nothing — Rollup couldn't split it into a separate chunk. Promote @iconify/vue to a static import and keep only the heavy circle-flags JSON (~500 kB) lazy, which is the actual first-paint optimization. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The fallback loop in QueryIP's fetchIPForModal silently relied on a JS truthy-check bug — `if (sourceID && source.id !== sourceID)` only falls through to other sources when sourceID is 0 (which happens to be IPCheck.ing). For any other preferred source (ipinfo, ip-api, etc.), the filter activates and the loop tries exactly one source, so a 5xx from that source left the spinner running forever with no visible error. Replace with the same cyclic walk IpInfos.fetchIPDetails uses: findIndex by id, walk (currentIdx + 1) % sources.length on failure, attempts < sources.length termination. 200 responses with all-"N/A" fields are treated as valid output (upstream is healthy, just no data for this IP) rather than triggering fallback. When every source genuinely fails, surface a new ipcheck.NoData error string across en/zh/fr/tr. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Keep the selected ASN panel content mounted separately from the Collapsible open state so the close height animation can complete without a late layout jump. Co-authored-by: Codex <codex@openai.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
See Commits and Changes for more details.
Created by
pull[bot] (v2.0.0-alpha.4)
Can you help keep this open source service alive? 💖 Please sponsor : )