Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
183 commits
Select commit Hold shift + click to select a range
c0c0f30
fix: tighten IP address validation
jason5ng32 Apr 14, 2026
70b458b
chore: move dev tools out of production deps
jason5ng32 Apr 14, 2026
134668e
chore: align Docker image with Node 24
jason5ng32 Apr 14, 2026
fd7284c
test: add API smoke coverage
jason5ng32 Apr 14, 2026
0a5b0c1
refactor: bootstrap → tailwind/shadcn-vue infra + sonner toast
jason5ng32 Apr 14, 2026
7f27fae
Update .gitignore
jason5ng32 Apr 14, 2026
45a0325
refactor: offcanvas → shadcn-vue Sheet (5 components + router + Patch)
jason5ng32 Apr 15, 2026
f3efd54
refactor: tooltip directive rewrite + 4 modals → shadcn-vue Dialog
jason5ng32 Apr 15, 2026
4cb1769
refactor: tooltip rewrite — drop custom directive, adopt shadcn-vue T…
jason5ng32 Apr 15, 2026
2e489c0
refactor: extract store.js hardcoded data to frontend/data/
jason5ng32 Apr 15, 2026
7320cb4
refactor: bootstrap collapse/accordion → shadcn-vue Collapsible/Accor…
jason5ng32 Apr 15, 2026
7bc3e3d
refactor: bootstrap dropdown/tab/scrollspy → shadcn-vue (+ scrollspy …
jason5ng32 Apr 15, 2026
4f1405f
refactor: remove bootstrap package + bootstrap CSS via @apply compat …
jason5ng32 Apr 15, 2026
0607606
Revert "refactor: remove bootstrap package + bootstrap CSS via @apply…
jason5ng32 Apr 17, 2026
373e4c1
refactor: drop dead bootstrap JS import; keep bootstrap CSS; realign …
jason5ng32 Apr 17, 2026
57a1306
refactor: rewrite InfoMask with shadcn Button icon variant (1/N for C.2)
jason5ng32 Apr 17, 2026
6c200c3
docs: add "transient-state interference" principle to AGENTS.md
jason5ng32 Apr 17, 2026
05fcf4b
refactor: rewrite Footer template to Tailwind + shadcn-vue (2/N for C.2)
jason5ng32 Apr 17, 2026
a812a08
refactor: rewrite Additional template to Tailwind (3/N for C.2)
jason5ng32 Apr 17, 2026
52ff171
refactor: rewrite Help template to Tailwind (4/N for C.2)
jason5ng32 Apr 17, 2026
daf49b8
refactor: rewrite QueryIP template to Tailwind + shadcn (5/N for C.2)
jason5ng32 Apr 17, 2026
f579474
refactor: rewrite User template to Tailwind (6/N for C.2)
jason5ng32 Apr 17, 2026
8c2ad21
refactor: rewrite ConnectivityTest template to Tailwind (7/N for C.2)
jason5ng32 Apr 17, 2026
8492b02
refactor: rewrite DnsLeaksTest template to Tailwind (8/N for C.2)
jason5ng32 Apr 17, 2026
9fd65bc
refactor: rewrite WebRtcTest template to Tailwind (9/N for C.2)
jason5ng32 Apr 17, 2026
bf9e3b4
refactor: rewrite BrowserInfo template + add Switch (10/N for C.2)
jason5ng32 Apr 17, 2026
3f1a2fa
refactor: rewrite MacChecker to Tailwind + shadcn (11/N for C.2)
jason5ng32 Apr 17, 2026
e1c89aa
refactor: rewrite RuleTest to Tailwind (12/N for C.2)
jason5ng32 Apr 17, 2026
4fa6b78
refactor: rewrite DnsResolver to Tailwind + shadcn (13/N for C.2)
jason5ng32 Apr 17, 2026
64d69de
refactor: rewrite Whois to Tailwind + shadcn (14/N for C.2)
jason5ng32 Apr 17, 2026
4a38fae
refactor: rewrite GlobalLatencyTest + add Select (15/N for C.2)
jason5ng32 Apr 17, 2026
de1133a
refactor: rewrite CensorshipCheck to Tailwind (16/N for C.2)
jason5ng32 Apr 17, 2026
0da4da3
refactor: rewrite MtrTest to Tailwind + shadcn (17/N for C.2)
jason5ng32 Apr 17, 2026
1fcceb0
refactor: rewrite SecurityChecklist to Tailwind + shadcn (18/N for C.2)
jason5ng32 Apr 17, 2026
a0aa481
refactor: rewrite InvisibilityTest to Tailwind + shadcn (19/N for C.2)
jason5ng32 Apr 17, 2026
8b79afb
refactor: rewrite Advanced template to Tailwind (20/N for C.2)
jason5ng32 Apr 17, 2026
09f26a1
refactor: rewrite DataPairBar + ASNInfo to Tailwind (21/N for C.2)
jason5ng32 Apr 17, 2026
51152ad
refactor: rewrite IPCard to Tailwind + shadcn (22/N for C.2)
jason5ng32 Apr 17, 2026
d00909b
refactor: rewrite IpInfos template to Tailwind (23/N for C.2)
jason5ng32 Apr 17, 2026
aa1a3a1
refactor: rewrite SpeedTest template to Tailwind (24/N for C.2)
jason5ng32 Apr 17, 2026
097e8bd
refactor: rewrite Nav template to Tailwind (25/N for C.2)
jason5ng32 Apr 17, 2026
aba5be5
refactor: rewrite Achievements template to Tailwind (26/N for C.2)
jason5ng32 Apr 17, 2026
3f01058
refactor: rewrite Preferences to Tailwind + shadcn (27/N for C.2)
jason5ng32 Apr 17, 2026
22e3b3c
refactor: rewrite App.vue template to Tailwind (28/N for C.2)
jason5ng32 Apr 17, 2026
5bd3ef9
refactor: uninstall bootstrap + remove CSS import — phase 01 C+E DONE
jason5ng32 Apr 17, 2026
b4501da
fix: restore base heading/paragraph spacing + IPCard dashed connector
jason5ng32 Apr 17, 2026
fb2aab2
refactor: bootstrap-icons → lucide-vue-next — phase 01 D DONE
jason5ng32 Apr 17, 2026
ac72d2e
refactor: split App.vue into composables — refactor/02 DONE
jason5ng32 Apr 17, 2026
cd534ed
test: fill in utils coverage — refactor/03 stage A DONE
jason5ng32 Apr 17, 2026
c638a6f
test: complete refactor/03 stages B–E
jason5ng32 Apr 17, 2026
1c4acd7
refactor(ui): modernize Nav.vue — sticky header + shadcn-vue
jason5ng32 Apr 17, 2026
ac9648d
refactor(ui): three Nav tweaks — GitHub stars / left align / dropdown…
jason5ng32 Apr 17, 2026
d41e125
refactor(ui): \u7b80\u5316 Nav \u4e0b\u62c9\u81f3 shadcn \u539f\u751f…
jason5ng32 Apr 17, 2026
74073c5
refactor(ui): restore the profile card in the Nav dropdown
jason5ng32 Apr 17, 2026
9ad2161
fix(nav): switch scroll-to-top to explicit smooth scroll
jason5ng32 Apr 17, 2026
9959202
refactor(ui): Network Connectivity rebuilt as shadcn Card + status dot
jason5ng32 Apr 17, 2026
ad91dc5
fix(css): root patch for Tailwind v4's naked-border color fallback
jason5ng32 Apr 17, 2026
e1393aa
refactor(ui): align Card default shadow + hover animation to jn-card …
jason5ng32 Apr 17, 2026
3a674e7
tweak(ui): ConnectivityTest user tweaks — font sizes bumped + keep jn…
jason5ng32 Apr 17, 2026
6762c3a
refactor(ui): DnsLeak / WebRTC / SpeedTest aligned to Connectivity mo…
jason5ng32 Apr 17, 2026
f54e5a7
fix(ui): long text inside WebRTC / DnsLeak cards no longer breaks car…
jason5ng32 Apr 17, 2026
5890c2b
fix(webrtc): split "Awaiting Test" and "Connection Error" into two st…
jason5ng32 Apr 17, 2026
9724bc8
ui(webrtc/dnsleak): reduce redundant copy in the wait tier
jason5ng32 Apr 17, 2026
a4c2e44
ui(webrtc/dnsleak): restore dl field icons + round country flags
jason5ng32 Apr 17, 2026
7b5efd7
ui(webrtc): switch flags to iconify circle-flags (pilot)
jason5ng32 Apr 17, 2026
9bf407e
ui(dnsleak/speedtest): migrate flags to iconify circle-flags
jason5ng32 Apr 17, 2026
56524e2
refactor(speedtest): size picker → ToggleGroup + unify run-tier color…
jason5ng32 Apr 17, 2026
5fa34fe
refactor(ui): establish semantic color tokens + migrate 4 modules + S…
jason5ng32 Apr 17, 2026
ada6934
fix(ui): SelectTrigger uses focus-visible, aligning with Input
jason5ng32 Apr 17, 2026
22a4392
fix(speedtest): reserve Progress / Colo space to avoid page shift whe…
jason5ng32 Apr 17, 2026
8438697
refactor(ui): Advanced rebuilt with shadcn Card + Sheet → vaul Drawer
jason5ng32 Apr 17, 2026
4ff6913
fix(ui): WebRTC/DnsLeak long IPv6 uses font-size degradation instead …
jason5ng32 Apr 17, 2026
d3838a5
fix(ui): remove Badge default hover effect
jason5ng32 Apr 17, 2026
abaf87d
refactor(ui): full IP Infos overhaul — shadcn Card + semantic colors …
jason5ng32 Apr 17, 2026
dda19a0
i18n(ipInfos): add advancedUnlockCta copy
jason5ng32 Apr 17, 2026
39d7394
refactor(footer): everything on shadcn primitives + Sheet/Tabs rebuil…
jason5ng32 Apr 17, 2026
1b06c52
tweak(ui): user adjustments on IP Infos / WebRTC / DnsLeak
jason5ng32 Apr 17, 2026
5ff2d3d
refactor(preferences): full shadcn primitive pass + flat container un…
jason5ng32 Apr 17, 2026
b86e0db
refactor(achievements): switch to shadcn Sheet/Tabs template + semant…
jason5ng32 Apr 17, 2026
9c5c4d9
refactor(ui): new DialogHeader primitive
jason5ng32 Apr 17, 2026
7b2b3c6
refactor(queryip): fully align visuals with IPCard + switch to circle…
jason5ng32 Apr 17, 2026
9f5c801
refactor(ui): Help / User / Additional — 3 dialogs switch to DialogHe…
jason5ng32 Apr 17, 2026
590a4aa
refactor(ui): new InputGroup primitive + QueryIP switches to it
jason5ng32 Apr 17, 2026
40bced9
feat(ui): add --action semantic color token + Button action variant
jason5ng32 Apr 17, 2026
9fad04f
feat(ui): new Spinner primitive + QueryIP querying state
jason5ng32 Apr 17, 2026
a4bbdbf
style(infomask): floating button rounded, unified with QueryIP trigger
jason5ng32 Apr 17, 2026
33367cf
fix(ui): remove Bootstrap-era ::after keyboard-hover leftover — cures…
jason5ng32 Apr 17, 2026
75a8e8c
fix(ui): keyboard nav green frame switches to outline instead of ::after
jason5ng32 Apr 17, 2026
449e03a
refactor(browserinfo): switch to shadcn Card + semantic colors + data…
jason5ng32 Apr 17, 2026
c7c5434
refactor(ruletest): switch to shadcn Card + useStatusTone + semantic …
jason5ng32 Apr 17, 2026
d214614
refactor(macchecker): switch to InputGroup + Card + semantic colors +…
jason5ng32 Apr 17, 2026
1c62cc5
refactor(dnsresolver): switch to InputGroup + ToggleGroup type picker…
jason5ng32 Apr 17, 2026
428e721
refactor(whois): switch to InputGroup + Card + semantic-color Accordion
jason5ng32 Apr 17, 2026
bb46182
fix(drawer): let text inside drawer be selectable
jason5ng32 Apr 17, 2026
109c3ba
refactor(mtrtest): switch to InputGroup + Accordion card-style + sema…
jason5ng32 Apr 17, 2026
e57d15f
refactor(pingtest): switch to InputGroup + Card table + latency 3-tie…
jason5ng32 Apr 17, 2026
9c800c8
refactor(censorshipcheck): dual-table functional component + 3-state …
jason5ng32 Apr 17, 2026
9ceb0a9
refactor(invisibilitytest): table → divide-y list + 14 items data-ize…
jason5ng32 Apr 17, 2026
77c4229
refactor(securitychecklist): switch to shadcn Card + divide-y list + …
jason5ng32 Apr 17, 2026
8649f76
fix(ui): service-status-card IP row gets min-h-6 to prevent tier-swit…
jason5ng32 Apr 17, 2026
a6d5819
style(ui): various small component visual tweaks
jason5ng32 Apr 17, 2026
d0465de
feat(connectivity): migrate bi-emoji-{frown,smile,expressionless} fac…
jason5ng32 Apr 17, 2026
f8381e0
chore: uninstall flag-icons, drop CSS import along with it
jason5ng32 Apr 17, 2026
c722f00
refactor(app): Patch.vue (empty-template component) → useSectionTrack…
jason5ng32 Apr 17, 2026
fad0095
refactor(nav): migrate neutral-* hard colors + dark: pairs to semanti…
jason5ng32 Apr 17, 2026
7cc3164
refactor(speedtest): success panel switches to success semantic color
jason5ng32 Apr 17, 2026
f1ca458
refactor: zero out bi-* strings — icon map switches from bi-xxx strin…
jason5ng32 Apr 17, 2026
46f02cb
docs: rewrite AGENTS.md to reflect current project state + new CLAUDE…
jason5ng32 Apr 17, 2026
69322ad
fix(pingtest): svgmap CSS moved to static import, fixes runtime error…
jason5ng32 Apr 17, 2026
5843a91
tweak: Advanced Drawer goes rounded-none when fullscreen + RuleTest n…
jason5ng32 Apr 17, 2026
c195f23
style(additional): curl comment-area semantic markers switch to Badge…
jason5ng32 Apr 17, 2026
3f28180
style(ui): 3 service-status modules' refresh button gets cursor-pointer
jason5ng32 Apr 17, 2026
bc43636
style(ipcard): Hero IP font sizes tier down + add min-h-5 anti-jitter
jason5ng32 Apr 17, 2026
e973315
i18n(changelog): add v6.0 release notes (en / zh / fr / tr)
jason5ng32 Apr 17, 2026
b063967
Merge branch 'claude/dreamy-ritchie-6c9993' into dev
jason5ng32 Apr 17, 2026
37021fa
Fix tr.json
jason5ng32 Apr 17, 2026
e61ddc6
docs: rewrite AGENTS.md with cleaner structure + new rules
jason5ng32 Apr 18, 2026
9794177
refactor(ui): drop unnecessary cn() on 4 Sheet/Drawer wrappers
jason5ng32 Apr 18, 2026
5ddda23
chore(maxmind): refresh GeoLite2-ASN / GeoLite2-City databases
jason5ng32 Apr 18, 2026
ffda6fb
fix(ui): DialogContent gives mobile a horizontal margin
jason5ng32 Apr 18, 2026
93a1f2e
chore(api): bump Google Static Maps size for the Dialog-size view
jason5ng32 Apr 18, 2026
8d3fad9
feat(ip-infos): on-demand Map Dialog + 2-up card grid + shared IpDeta…
jason5ng32 Apr 18, 2026
46a23f7
feat(getips): 5s fetch timeout so IPv6/v4 failures surface quickly
jason5ng32 Apr 18, 2026
1977f3e
style(ipcard): error state text uses primary instead of destructive
jason5ng32 Apr 18, 2026
33b96ca
refactor(changelog): split changelog out of locale packs into shared …
jason5ng32 Apr 18, 2026
1b7c1b9
tweak(hero-ip): raise small-tier threshold from 15 to 25 chars
jason5ng32 Apr 18, 2026
c992d5d
ci: run tests + build on push and PR (main / dev)
jason5ng32 Apr 18, 2026
a9d5734
chore: bump package.json version 5.0.0 → 6.0.0 to match changelog
jason5ng32 Apr 18, 2026
b7d782b
feat(common): fetchUpstream helper with 8s timeout
jason5ng32 Apr 18, 2026
9ca7cb5
feat(common): guards.js — requireReferer + requireValidIP middleware
jason5ng32 Apr 18, 2026
75d6248
chore(backend): misc cleanups
jason5ng32 Apr 18, 2026
49e5572
refactor(backend): mount requireReferer globally; strip per-handler c…
jason5ng32 Apr 18, 2026
4ae0783
refactor(backend): mount requireValidIP; strip per-handler IP checks
jason5ng32 Apr 18, 2026
d51d575
refactor(backend): unify upstream HTTP via fetchUpstream; kill https.get
jason5ng32 Apr 18, 2026
9e80e80
docs(changelog): append today's work to v6.0
jason5ng32 Apr 18, 2026
ca4db70
Remove unnecessary files
jason5ng32 Apr 18, 2026
57f03e6
Improvements
jason5ng32 Apr 18, 2026
2792185
refactor(common): unify fetch-with-timeout + fetch-upstream into one …
jason5ng32 Apr 18, 2026
9f1dafb
test: consolidate api-smoke into api-handlers; drop stale refactor notes
jason5ng32 Apr 18, 2026
f8c5851
Improve comments
jason5ng32 Apr 19, 2026
51dcf44
Change defaults
jason5ng32 Apr 19, 2026
552cb7b
Remove Invalid IP testing source
jason5ng32 Apr 19, 2026
8a80724
Improvements
jason5ng32 Apr 19, 2026
c7ef2cb
Docs: split AGENTS.md into root + frontend + api; slim CLAUDE.md
jason5ng32 Apr 19, 2026
1f5b188
Test: align default-preferences expected ipCardsToShow with source (4)
jason5ng32 Apr 19, 2026
973e87b
Update package.json
jason5ng32 Apr 19, 2026
cb543dd
Update Shadcn Vue
jason5ng32 Apr 19, 2026
5efab61
Improvements of UI
jason5ng32 Apr 19, 2026
e214663
Chore(macchecker): residual cleanup after input-group migration
jason5ng32 Apr 19, 2026
e366150
Docs: align AGENTS.md with shadcn-vue input-group refresh
jason5ng32 Apr 19, 2026
d77055f
UI Improvements
jason5ng32 Apr 19, 2026
3d83a8b
Update Footer.vue
jason5ng32 Apr 19, 2026
6bd281f
Update changelog.json
jason5ng32 Apr 19, 2026
dcfec52
Update en.json
jason5ng32 Apr 19, 2026
c23f4a7
Feat(shortcuts): extend J/K navigation to advanced tool cards with `o…
jason5ng32 Apr 19, 2026
c85a12f
Docs(changelog): fill en / fr / tr for v6.0 entries
jason5ng32 Apr 19, 2026
bf50fc8
Refactor(index.html): modernize boot screen and prevent FOUC shake on…
jason5ng32 Apr 19, 2026
64c6c5e
Improvements
jason5ng32 Apr 19, 2026
015ac4e
UI Improvements
jason5ng32 Apr 19, 2026
19153ca
UI Improved
jason5ng32 Apr 19, 2026
282c389
Fix(ci): drop `cache: npm` that required a lockfile we don't commit
jason5ng32 Apr 19, 2026
6c22850
Docs(readme): add Turkish to the language-support bullet
jason5ng32 Apr 19, 2026
c3e79fa
Update sync.yml
jason5ng32 Apr 19, 2026
c3e69b1
Fix(ci): opt workflows into the Node 24 actions runner
jason5ng32 Apr 19, 2026
b5284c4
Chore(ci): bump actions/checkout + actions/setup-node to v6
jason5ng32 Apr 19, 2026
f06e6ff
Chore: stop tracking GeoLite2 mmdb databases
jason5ng32 Apr 19, 2026
5e9e2b6
UI Improvements
jason5ng32 Apr 19, 2026
d7c984e
UI Improvements
jason5ng32 Apr 19, 2026
c496acf
UI Improvements
jason5ng32 Apr 19, 2026
736b6e6
Fix(ci): scope GITHUB_TOKEN permissions to least-privilege
jason5ng32 Apr 19, 2026
3243751
Merge pull request #321 from jason5ng32/dev
jason5ng32 Apr 19, 2026
64657cd
Fix(theme): dark/light mode no longer splits when system scheme diffe…
jason5ng32 Apr 19, 2026
dcec13c
Docs(readme): mark MaxMind vars as required, add setup guide
jason5ng32 Apr 19, 2026
2e5557f
Chore(ci): bump docker/* actions to Node 24 native majors
jason5ng32 Apr 19, 2026
5160f02
Update README_FR.md
jason5ng32 Apr 19, 2026
f6b921d
Merge pull request #322 from jason5ng32/dev
jason5ng32 Apr 19, 2026
38e8a5e
Update Readme
jason5ng32 Apr 19, 2026
16d3860
Merge pull request #323 from jason5ng32/dev
jason5ng32 Apr 19, 2026
826a2e7
Feat(ci): auto-sync README.md to Docker Hub on every push
jason5ng32 Apr 19, 2026
b29be59
Merge pull request #324 from jason5ng32/dev
jason5ng32 Apr 19, 2026
0ca9602
Fix(ci): declare `environment: production` so dockerhub-readme job ca…
jason5ng32 Apr 19, 2026
b50e809
Update dockerhub-readme.yml
jason5ng32 Apr 19, 2026
96b7feb
Merge pull request #325 from jason5ng32/dev
jason5ng32 Apr 19, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
.git
.github
.VSCodeCounter
.claude
.vscode

node_modules
dist
logs
localtest
package-lock.json

.DS_Store
.env
*.log
npm-debug.log*
yarn-debug.log*
pnpm-debug.log*

common/maxmind-db/.maxmind-update-*.json
common/maxmind-db/.maxmind-update.lock
common/maxmind-db/*.bak
common/maxmind-db/*.next
38 changes: 38 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
name: CI

on:
push:
branches: [main, dev]
pull_request:
branches: [main, dev]

# Least-privilege GITHUB_TOKEN: tests + build only need to read the repo.
permissions:
contents: read

jobs:
check:
name: Test + Build
runs-on: ubuntu-latest

steps:
- name: Checkout
uses: actions/checkout@v6

- name: Setup Node
uses: actions/setup-node@v6
with:
node-version: 24
# Intentionally no `cache: npm` — that requires a package-lock.json, and this
# repo gitignores the lockfile by design. `npm install` below runs cold every
# run; dependency install on this project takes ~30s, which is acceptable
# versus the drift risk of committing a lockfile we don't otherwise use.

- name: Install dependencies
run: npm install --no-audit --no-fund

- name: Run tests
run: npm test

- name: Build
run: npm run build
19 changes: 14 additions & 5 deletions .github/workflows/docker-image.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,26 +9,35 @@ on:
description: 'Version tag'
required: true

# Least-privilege GITHUB_TOKEN:
# - contents: read → checkout the source
# - packages: write → push the built image to ghcr.io/${owner}/myip
# Docker Hub push uses DOCKER_HUB_ACCESS_TOKEN (a repo secret), not GITHUB_TOKEN,
# so no extra scopes are needed for that half of the job.
permissions:
contents: read
packages: write

jobs:
build-and-push:
runs-on: ubuntu-latest
environment: production

steps:
- name: Check Out Repo
uses: actions/checkout@v4
uses: actions/checkout@v6

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
uses: docker/setup-buildx-action@v4

- name: Login to Docker Hub
uses: docker/login-action@v3
uses: docker/login-action@v4
with:
username: ${{ secrets.DOCKER_HUB_USERNAME }}
password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }}

- name: Login to GitHub Packages
uses: docker/login-action@v3
uses: docker/login-action@v4
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
Expand All @@ -47,7 +56,7 @@ jobs:
echo "RELEASE_NOTES=Manually triggered build" >> $GITHUB_ENV

- name: Build and Push Docker Image
uses: docker/build-push-action@v5
uses: docker/build-push-action@v7
with:
push: true
tags: |
Expand Down
37 changes: 37 additions & 0 deletions .github/workflows/dockerhub-readme.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
name: Sync README to Docker Hub

# Keeps the Docker Hub overview page in sync with README.md in this repo.
# Triggers on any push to main that touches README.md (or this workflow file
# itself), so documentation edits propagate without waiting for the next
# release or a manual step. Also exposes `workflow_dispatch` for a manual
# one-shot push (useful the first time this workflow is enabled, or to force
# a resync after rotating the Docker Hub token).

on:
push:
branches: [main]
paths:
- 'README.md'
- '.github/workflows/dockerhub-readme.yml'
workflow_dispatch:

permissions:
contents: read

jobs:
sync:
name: Push README to Docker Hub
runs-on: ubuntu-latest
environment: production

steps:
- name: Checkout
uses: actions/checkout@v6

- name: Update Docker Hub description
uses: peter-evans/dockerhub-description@v5
with:
username: ${{ secrets.DOCKER_HUB_USERNAME }}
password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }}
repository: jason5ng32/myip
readme-filepath: ./README.md
17 changes: 8 additions & 9 deletions .github/workflows/sync.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ permissions:

on:
schedule:
- cron: "0 0 * * *" # 每天 UTC 时间 0 点
- cron: "0 0 * * *" # every day at 00:00 UTC
workflow_dispatch:

jobs:
Expand All @@ -15,27 +15,26 @@ jobs:
if: ${{ github.event.repository.fork }}

steps:
# 步骤 1: 运行标准的签出动作
# step 1: checkout target repo
- name: Checkout target repo
uses: actions/checkout@v3
uses: actions/checkout@v6

# 步骤 2: 运行同步动作
# step 2: sync upstream changes
- name: Sync upstream changes
id: sync
uses: aormsby/Fork-Sync-With-Upstream-action@v3.4
with:
upstream_sync_repo: jason5ng32/MyIP
upstream_sync_branch: main
target_sync_branch: main
target_repo_token: ${{ secrets.GITHUB_TOKEN }} # 自动生成,无需设置
target_repo_token: ${{ secrets.GITHUB_TOKEN }} # auto-generated, no need to set

# test_mode 设置为 true 来运行测试而不是真正的动作!
# set test_mode to true to run tests instead of the real action!
test_mode: false

# 出错检查
# error check
- name: Sync check
if: failure()
run: |
echo "[Error] 由于上游仓库的 workflow 文件变更,导致 GitHub 自动暂停了本次自动更新,你需要手动 Sync Fork 一次。"
echo "[Error] Due to a change in the workflow file of the upstream repository, GitHub has automatically suspended the scheduled automatic update. You need to manually sync your fork."
echo "[Error] Due to a change in the workflow file of the upstream repository, GitHub has automatically suspended the scheduled automatic update. You need to manually sync your fork again."
exit 1
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
.claude

node_modules
dist
Expand Down Expand Up @@ -34,3 +35,5 @@ common/maxmind-db/.maxmind-update-*.json
common/maxmind-db/.maxmind-update.lock
common/maxmind-db/*.bak
common/maxmind-db/*.next
common/maxmind-db/*.mmdb
.learnings/
111 changes: 111 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
# AGENTS.md

Single source of truth for anyone — human or AI — contributing to MyIP.

For area-specific details, see:

- Frontend (Vue 3 SPA): @frontend/AGENTS.md
- Backend API (Express): @api/AGENTS.md

## Overview

**MyIP** (IPCheck.ing) is an open-source IP toolbox: IP lookup, connectivity tests, WebRTC / DNS-leak detection, speed test, MTR, Whois, security checklist, browser fingerprint, anonymity checks, and more.

Single repo, two halves: a Vue 3 SPA front-end and an Express 5 back-end API, served side by side.

## Stack

| Layer | Technology |
|---|---|
| Framework | Vue 3 (`<script setup>`, Composition API) |
| State | Pinia |
| Router | vue-router (hash mode) |
| i18n | vue-i18n — `en` / `zh` / `fr` / `tr` |
| Build | Vite + `@vitejs/plugin-vue` |
| CSS | Tailwind CSS v4 (`@tailwindcss/vite`) + `tw-animate-css` |
| UI primitives | shadcn-vue copy-in style, built on `reka-ui` |
| Icons | `lucide-vue-next` (inline SVG components) |
| Flags | `@iconify-json/circle-flags` via `@iconify/vue` |
| Bottom drawer | `vaul-vue` |
| Toast | `vue-sonner` |
| Backend | Express 5 |
| Auth | Firebase Auth (optional, env-gated) |
| PWA | Serwist |
| Tests | Node built-in test runner (`node --test`) |
| Runtime libs | chart.js · svgmap · @cloudflare/speedtest · maxmind · whoiser · thumbmarkjs · ua-parser-js · detect-gpu · circle-progress.vue · @vueuse/core (used by shadcn-vue primitives) |

## Commands

| Command | What it does |
|---|---|
| `npm run dev` | Vite + backend (nodemon) together — front-end 5173, back-end 11966 |
| `npm run build` | Front-end production build |
| `npm run preview` | Vite preview of the build output |
| `npm run start` | Built front-end + backend (static file server) |
| `npm test` | Run all `tests/*.test.js` specs |
| `npm run check` | `test` + `build`, the pre-commit self-check |

## Project layout

```
.
├── AGENTS.md ← this file
├── CLAUDE.md ← Claude-specific pointer to AGENTS.md
├── frontend/ ← Vue 3 SPA (see frontend/AGENTS.md)
├── api/ ← Express handlers (see api/AGENTS.md)
├── common/ ← code shared between front- and back-end
│ (valid-ip / fetch-with-timeout / guards /
│ referer-check / maxmind-service / …)
├── tests/ ← Node test runner specs
├── backend-server.js ← Express app (default port 11966)
├── frontend-server.js ← static file server for `npm start`
├── index.html ← Vite entry; #app mounts vaul-drawer-wrapper
├── vite.config.js
├── jsconfig.json ← JS project, alias @ → frontend/
└── package.json
```

## Conventions

### Language

- **JavaScript only.** New files are `.js` / `.vue`; `<script setup>` has no `lang="ts"`. Do not rename `jsconfig.json` to `tsconfig.json` or otherwise introduce TypeScript.
- **English by default** for source-code comments , commit messages and AGENTS.md files. Planning docs can be in other languages. Locale packs are obviously the exception — they contain user-facing copy in their respective language.

### Comments

- **Every new file opens with a header comment** stating its purpose. One or two lines is usually enough; enough that a reader opening the file cold understands what it is.
- **Large templates or functions carry block comments** on each meaningful section — enough for a maintainer six months later to orient quickly. Not every line, but every region / branch / step.

### i18n coverage

- Any feature that surfaces copy must land in **all four locales** (`en` / `zh` / `fr` / `tr`) in the same change. No English-only or Chinese-only keys slipping through.
- Same rule applies to `frontend/data/changelog.json` — every entry's `change` object must have all four languages. `tests/changelog.test.js` enforces this.

## Testing

- **Test runner:** Node built-in (`node --test`), no third-party framework. Specs live in `tests/*.test.js`.
- **Coverage expectation:** any non-visual logic that can be exercised without a network call — pure functions, composables with mockable inputs, transform utilities, validators — ships with a test in `tests/` and is wired into `npm test`. UI rendering, real network behavior, and browser-API-dependent code are out of scope.
- **Big new features:** write the tests in the same change. Don't defer.
- **Modifying a tested feature:** check the related tests; update them in the same change if behavior shifts.
- **Tests must pass locally before you hand off.** If `npm run check` is red, don't ask the user to review.

## Security & Boundaries

The backend enforces access control and timeouts through shared middleware rather than per-handler code. Full details live in @api/AGENTS.md; the rules that matter at the project level:

- `requireReferer` is mounted globally on `/api/*` — handlers must not repeat the referer check.
- `requireValidIP()` is attached per-route where `?ip` is a required param — handlers must not repeat the IP check.
- Every upstream HTTP call goes through `fetchUpstream` (`common/fetch-with-timeout.js`) with an 8s timeout. Never add a bare `fetch()` to an `api/` handler.

## Workflow

- **Do not commit without explicit user approval.** The flow is: AI edits → user reviews → user tests → user says "commit" → AI commits. Silent commits are a breach of trust.
- **One concern per commit.** Don't mix unrelated changes into a single commit. Split at the right seam.
- **Self-test before handing off.** Run `npm run check` (or at least `npm test`) for every change. If the change is visual (UI layout, styling, interactions) and can't be verified headless, say so explicitly so the user can test it in `npm run dev`.
- **Every commit is gated on user testing.** Even with tests green, a visual change needs the user to have looked at it before it lands.
- **Add yourself as a co-author to the commit.** If you are an AI.
- **Commit message style** follows recent `git log` — `Refactor(xxx): …` / `Fix(ui): …` / `Feat(xxx): …` / `Style: …` / `Chore: …` prefix.
- **On every commit, scan AGENTS.md (root + relevant sub-file) for staleness** — if the change adds a convention, renames a shared module, flips a rule, or invalidates an example, update the doc in the same commit. AGENTS.md drifting from reality is the main failure mode of this kind of document.
11 changes: 11 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# CLAUDE.md

Authoritative project instructions: @AGENTS.md

Claude-specific additions below; on conflict, AGENTS.md wins.

## Claude-specific

None at the moment. This file exists so Claude Code auto-loads AGENTS.md at
session start; additional Claude-only guidance goes here if it ever diverges
from what all contributors should follow.
10 changes: 5 additions & 5 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
# 第一阶段:构建
FROM node:20-alpine as build-stage
# Build stage
FROM node:24-alpine AS build-stage
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build

# 第二阶段:运行
FROM node:20-alpine as production-stage
# Production stage
FROM node:24-alpine AS production-stage
WORKDIR /app
COPY --from=build-stage /app/node_modules ./node_modules
COPY --from=build-stage /app/package.json ./
Expand All @@ -19,5 +19,5 @@ COPY --from=build-stage /app/common ./common

EXPOSE 18966

# 启动应用
# Start application
CMD ["npm", "start"]
Loading
Loading