Commit Graph
15 Commits
Author SHA1 Message Date
Claude 96525d2fc7 Chore: trim the branch — leftovers, redundancy, comments
A pass over every file the branch touched, after the iOS animation hunt
left tries and reverts behind it. Removed what nothing reaches: the
view-transition rule for a transition no code starts, an unreachable
guard in the transition hook, a no-op KeepAlive key branch, a sign-in
guard the menu already enforces, usage-dialog wrappers that only
forwarded to the store, a duplicated modifier-click check and card
filter (isPlainClick / listedTools), a test that hand-rolled
listedTools, a drawer-era fixture parameter. auth-flow.js folded into
auth-redirect.js. Comments cut to what the code cannot say itself —
file headers of a few lines, the measured iOS reasons, non-obvious
orderings — and stale ones fixed (Nav under KeepAlive, Home.vue
reusing DEFAULT_META, "from Nav", enabledCards). AGENTS.md sections
tightened to the code as it is now.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013GbLTGMZ45MV78qd2tHoco
2026-10-05 16:50:16 +00:00
Claude 1c7e7c68cd Fix(auth): give the installed PWA its own auth domain
VITE_FIREBASE_AUTH_DOMAIN stays the shared sign-in domain every browser
uses; the new optional VITE_FIREBASE_PWA_AUTH_DOMAIN is the domain the
installed PWA initialises Firebase with — the site's own host, served
by the /__/auth proxy, so the redirect handler runs inside the PWA
(utils/auth-domain.js). GitHub's OAuth app has one callback, on the
shared domain, so when the PWA domain differs the account menu offers
Google only. .env.example documents both and the console-side steps.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013GbLTGMZ45MV78qd2tHoco
2026-10-05 15:28:57 +00:00
Claude 1c3a36d253 Fix(auth): serve Firebase's auth handler from the site's own origin
The installed iOS PWA opens an out-of-scope authDomain in the system's
in-app browser view, whose storage the PWA's own webview cannot read,
so a redirect sign-in completed there never reached the app. The
frontend server and the Vite dev server now proxy /__/auth/* to
https://<project>.firebaseapp.com (common/firebase-auth-proxy.js),
mounted only when VITE_FIREBASE_PROJECT_ID is set, so with
VITE_FIREBASE_AUTH_DOMAIN set to the site's host the handler runs
in-scope, inside the PWA itself. .env.example documents the three keys
and the console-side requirements (authorized domain, OAuth callback at
https://<host>/__/auth/handler).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013GbLTGMZ45MV78qd2tHoco
2026-10-05 15:02:01 +00:00
jason5ng32andClaude Opus 5.5 c29e48687b Refactor(layout): split backend-only code out of common/, group frontend utils
common/ had become the backend's library: 30 of its 41 modules were
imported by nothing in the frontend, so the name no longer said what
belonged there. It now holds only what the frontend or the build imports
too; backend-only code moved to server/, flat except for datasets/ (the
dataset engine and its readers). The *-db/ dataset directories stay in
common/: self-hosting docs and Docker volumes mount those paths.

frontend/utils/ keeps its app-wide modules at the root and gains ip/
(IP / ASN shaping and validation), report/ (the report pipeline) and
features/ (the pure layer of a single feature). Paths only — no logic
changes. The Dockerfile copies server/, and the AGENTS.md files say where
a new module goes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 13:10:02 +08:00
jason5ng32 4c41f2a2bd Improvements 2026-08-14 13:21:12 +08:00
jason5ng32andClaude Fable 5 fe3883fd77 Feat(connectivity): importable curated target lists
The Connectivity grid's add tile now opens a tabbed dialog: import one
of 11 curated lists (Iran / Russia / China country packs + AI, social,
streaming, gaming, developer, cloud, crypto, news themes — 130 sites)
or hand-add a custom test. Imported members materialize into the
customConnectivityTargets preference tagged with their listId, so cards
are individually removable and a list can be removed as a whole from
the dialog; hostname dedupe and a shared 60-target cap apply on import.

Cards (built-in included) now show real site favicons served from
committed 64px PNGs under public/favicons/ — same-origin, so icons
render even when the tested site is blocked for the visitor; a data
test enforces one PNG per member, and the static server caches the
directory for 30 days (a changed icon ships under a new id/filename).

Also, since the section was reworked in the same change:
- multi-round mode now runs on manual/section refreshes too — it was
  boot-only, so visitors with connectivity auto-run off could never
  trigger rounds at all
- shared report caps grow 24 → 72 targets so reports carry every
  tested target instead of a silently truncated subset
- dead ServiceStatusBanner leftovers (logic + locale keys) removed;
  the banner UI itself was retired earlier

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-06 12:17:23 +08:00
jason5ng32 b2eb8806bb Improvements 2026-07-16 16:19:30 +08:00
jason5ng32 7243d5185e Improvements 2026-07-16 00:07:59 +08:00
jason5ng32 7eb90956e7 Improvements 2026-07-15 23:22:12 +08:00
jason5ng32 92a088e82b Improvements 2026-07-15 21:12:09 +08:00
jason5ng32andClaude Opus 4.8 52b3b2a6e5 Feat(advanced-tools): SPA fallback + per-route meta for standalone pages
Make the /tools/:slug pages production-servable and SEO-addressable.

- frontend-server.js: add an SPA history fallback after the static layer — GET
  navigations (Accept: text/html, no file extension) get index.html so a hard
  load / new tab of a client route resolves. Real assets and /api are untouched;
  missing hashed chunks still 404 rather than returning an HTML body.
- New use-document-meta composable: client-side per-route <title> / description
  / canonical / Open Graph. StandaloneTool sets localized per-tool values + a
  self-referential canonical; Home resets to the index.html homepage defaults
  (so SPA-navigating back from a tool page restores the head). No SSR — applied
  at runtime, picked up by the browser tab and JS-rendering crawlers.

Wraps up the standalone-pages work (drawer + standalone now fully co-exist,
dev / preview / prod all serve the routes).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-08 13:06:14 +08:00
jason5ng32andClaude Opus 4.7 9c5b655f4d Refactor(cache): drop service worker, add explicit Cache-Control on static 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>
2026-05-07 09:25:22 +08:00
jason5ng32andClaude Opus 4.7 833f66cc42 Feat(backend): introduce pino logger + pino-http request logs
Replace all backend console.* with a shared pino singleton at
common/logger.js. Startup-style lines get emoji prefixes (🚀 listening,
📦 maxmind ready, 📥 downloading, 🗓️ schedule, ⚠️ warning, ❌ failure);
per-handler / per-request logs stay plain.

Three .env-driven knobs, all without NODE_ENV:
  - LOG_LEVEL (default info) — pino level filter
  - LOG_FORMAT (default pretty) — "json" for log shippers
  - LOG_HTTP (default off) — pino-http on /api/* gated behind this flag
    so pm2 logs don't bloat with 2xx/3xx request lines on every deploy;
    when enabled, 4xx log as warn and 5xx as error

logger.js calls dotenv.config({ quiet: true }) itself because ES module
imports are hoisted above backend-server.js's dotenv call — without that
LOG_LEVEL from .env was silently ignored.

Fixes in common/rdap.js:
  - err: res.status → status: res.status (pino's err serializer expects
    an Error object, not a number)
  - broken single-quoted template literal in "No RDAP endpoint" message
  - demote "No RDAP endpoint" and "Domain not found" from error to warn
    (they're expected outcomes for user input, not server failures)

README (en/zh/fr/tr) + .env.example + AGENTS.md (root and api/) all
updated to document the three new vars and the "no console.* in backend"
convention.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-23 01:29:52 +08:00
jason5ng32 57f03e66ec Improvements 2026-04-18 19:45:11 +08:00
jason5ng32 4e6e5972e8 Structure improvements 2024-05-12 10:34:07 +08:00