Focus&go · ${t.checked}
${escape(c.h1)}
${escape(c.summary)}
${sections}diff --git a/apps/web/focus-go-api/routes/anonymousCounts.js b/apps/web/focus-go-api/routes/anonymousCounts.js index 87f77ca..88b7912 100644 --- a/apps/web/focus-go-api/routes/anonymousCounts.js +++ b/apps/web/focus-go-api/routes/anonymousCounts.js @@ -1,6 +1,6 @@ import { Router, json } from 'express' -export const PUBLIC_PAGES = ['/', '/zh/', '/features/pomodoro/', '/zh/features/pomodoro/', '/features/local-first/', '/zh/features/local-first/', '/guides/task-to-focus/', '/zh/guides/task-to-focus/', '/privacy/', '/zh/privacy/', '/terms/', '/zh/terms/'] +export const PUBLIC_PAGES = ['/', '/zh/', '/features/pomodoro/', '/zh/features/pomodoro/', '/features/local-first/', '/zh/features/local-first/', '/guides/task-to-focus/', '/zh/guides/task-to-focus/', '/about/', '/zh/about/', '/privacy/', '/zh/privacy/', '/terms/', '/zh/terms/'] const WEBSITE = 'https://nestflow.art' const APPLICATION = 'https://app.nestflow.art' const RETENTION_DAYS = 90 diff --git a/apps/web/focus-go-api/routes/anonymousCounts.test.js b/apps/web/focus-go-api/routes/anonymousCounts.test.js index 9add7ee..d35efee 100644 --- a/apps/web/focus-go-api/routes/anonymousCounts.test.js +++ b/apps/web/focus-go-api/routes/anonymousCounts.test.js @@ -65,3 +65,16 @@ test('prunes aggregates older than ninety UTC days and bounds report window', as assert.equal(readAnonymousCounts(f.database, 10000, clock).days, 90) } finally { await f.close() } }) + + +test('counts public identity pages but rejects nested or query-bearing variants', async () => { + const f = await fixture() + try { + for (const [page, language] of [['/about/', 'en'], ['/zh/about/', 'zh-CN']]) { + assert.equal((await f.post({ event: 'website_view', page, language })).status, 204) + } + assert.equal((await f.post({ event: 'website_view', page: '/about/private', language: 'en' })).status, 400) + assert.equal((await f.post({ event: 'website_view', page: '/about/?token=excluded', language: 'en' })).status, 400) + assert.equal(readAnonymousCounts(f.database, 28, clock).rows.reduce((sum, row) => sum + row.count, 0), 2) + } finally { await f.close() } +}) diff --git a/apps/web/src/shared/metrics/anonymousCounts.test.ts b/apps/web/src/shared/metrics/anonymousCounts.test.ts index d4c5afa..8e64818 100644 --- a/apps/web/src/shared/metrics/anonymousCounts.test.ts +++ b/apps/web/src/shared/metrics/anonymousCounts.test.ts @@ -34,6 +34,8 @@ describe('anonymous browser counter', () => { it('rejects dev hosts and private/query paths rather than transmit them', async () => { const dev = fixture('http://localhost:5173'); await dev.counter.firstSuccess('en'); await dev.counter.website('website_view','/'); expect(dev.sent).toEqual([]) const site = fixture('https://nestflow.art'); await site.counter.website('website_view','/tasks/private'); await site.counter.website('app_open','/?q=private'); expect(site.sent).toEqual([]) - await site.counter.website('app_open','/zh/features/pomodoro/'); expect(site.sent).toEqual([{ event: 'app_open', page: '/zh/features/pomodoro/', language: 'zh-CN' }]) + await site.counter.website('app_open','/zh/features/pomodoro/'); + await site.counter.website('website_view','/about/'); await site.counter.website('website_view','/zh/about/'); + expect(site.sent).toEqual([{ event: 'app_open', page: '/zh/features/pomodoro/', language: 'zh-CN' }, { event: 'website_view', page: '/about/', language: 'en' }, { event: 'website_view', page: '/zh/about/', language: 'zh-CN' }]) }) }) diff --git a/apps/web/src/shared/metrics/anonymousCounts.ts b/apps/web/src/shared/metrics/anonymousCounts.ts index 319dff1..706c0f6 100644 --- a/apps/web/src/shared/metrics/anonymousCounts.ts +++ b/apps/web/src/shared/metrics/anonymousCounts.ts @@ -2,7 +2,7 @@ const PREFERENCE = 'focusgo.anonymous-counts.enabled' const FIRST_SUCCESS = 'focusgo.anonymous-counts.first-success' const ENDPOINT = 'https://api.nestflow.art/api/public-counts' const CHANGE_EVENT = 'focusgo-anonymous-counts-change' -const PAGES = ['/', '/zh/', '/features/pomodoro/', '/zh/features/pomodoro/', '/features/local-first/', '/zh/features/local-first/', '/guides/task-to-focus/', '/zh/guides/task-to-focus/', '/privacy/', '/zh/privacy/', '/terms/', '/zh/terms/'] +const PAGES = ['/', '/zh/', '/features/pomodoro/', '/zh/features/pomodoro/', '/features/local-first/', '/zh/features/local-first/', '/guides/task-to-focus/', '/zh/guides/task-to-focus/', '/about/', '/zh/about/', '/privacy/', '/zh/privacy/', '/terms/', '/zh/terms/'] type CounterRuntime = { origin: string diff --git a/apps/web/website/index.html b/apps/web/website/index.html index 4a59391..120ad7a 100644 --- a/apps/web/website/index.html +++ b/apps/web/website/index.html @@ -561,6 +561,7 @@
${escape(p)}
`).join('')}${escape(item.a)}
Focus&go · ${t.checked}
${escape(c.summary)}
${sections}Focus&go · ${checked}
${escape(c.summary)}
${sections}${links}