Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 2 additions & 2 deletions messages/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -1160,7 +1160,7 @@
"admin_cf_setup_lede": "Your in-app counters miss anything Cloudflare serves from cache. Connect a read-only token and this page gains an edge-traffic panel: cached hits, bandwidth, threats blocked. It's optional, and it never reads any account but yours.",
"admin_cf_setup_s1_title": "Create a scoped, read-only token",
"admin_cf_setup_s1_text": "In the Cloudflare dashboard, open My Profile, then API Tokens, Create Token, Custom token. Add exactly one permission. Nothing can write:",
"admin_cf_setup_s1_scope": "Zone · Analytics · Read",
"admin_cf_setup_s1_scope": "Zone Analytics: Read",
"admin_cf_setup_s1_zone": "Then set Zone Resources to include your custom domain's zone, or the query returns nothing.",
"admin_cf_setup_s2_title": "Store the token, account id and zone id as secrets",
"admin_cf_setup_s2_ci": "Fastest path — store all three as GitHub repository secrets. From the fork's directory (so gh reads the repo from your origin remote), run:",
Expand All @@ -1169,7 +1169,7 @@
"admin_cf_setup_s3_title": "Redeploy to load the secrets",
"admin_cf_setup_s3_text": "Cloudflare Pages binds secrets at deploy time. The GitHub Actions path redeploys for you; if you set the secrets by hand, redeploy now. The edge panel then appears next to your in-app metrics — it reads zone analytics, so your custom domain must be connected (a bare pages.dev URL has no zone data).",
"admin_cf_setup_callout_strong": "Read-only, and only your account.",
"admin_cf_setup_callout": " Give the token Zone Analytics Read and nothing else, so a leaked token can't change anything. It only ever reads your own zone's numbers, so it never becomes the boundary between two forks.",
"admin_cf_setup_callout": " Give the token Zone Analytics: Read and nothing else, so a leaked token can't change anything. It only ever reads your own zone's numbers, so it never becomes the boundary between two forks.",
"admin_cf_setup_unlocks_label": "Unlocks:",
"admin_cf_setup_unlocks": " a Cloudflare edge panel: cached versus origin requests, total bandwidth, threats blocked. Disconnect anytime by deleting the secret; nothing else on this page depends on it.",
"admin_settings_supporter_early_eyebrow": "early access",
Expand Down
4 changes: 2 additions & 2 deletions messages/ja.json
Original file line number Diff line number Diff line change
Expand Up @@ -1124,7 +1124,7 @@
"admin_cf_setup_lede": "アプリ内カウンターは、Cloudflareがキャッシュから配信したものを計測できません。読み取り専用のトークンを接続すると、このページにエッジトラフィックのパネル(キャッシュヒット、帯域、ブロックした脅威)が追加されます。任意であり、あなた以外のアカウントを読み取ることはありません。",
"admin_cf_setup_s1_title": "範囲を限定した読み取り専用トークンを作成する",
"admin_cf_setup_s1_text": "Cloudflareダッシュボードで、マイプロフィール → APIトークン → トークンを作成 → カスタムトークン を開きます。権限をちょうど1つだけ追加します。書き込みは一切できません:",
"admin_cf_setup_s1_scope": "Zone · Analytics · Read",
"admin_cf_setup_s1_scope": "Zone Analytics: Read",
"admin_cf_setup_s1_zone": "次に、ゾーンリソースにカスタムドメインのゾーンを含めてください。含めないとクエリは何も返しません。",
"admin_cf_setup_s2_title": "トークン・アカウントID・ゾーンIDをシークレットとして保存する",
"admin_cf_setup_s2_ci": "最も簡単な方法 — 3つすべてをGitHubのリポジトリシークレットとして保存します。フォークのディレクトリで(ghがoriginリモートからリポジトリを判別します)、次を実行してください:",
Expand All @@ -1133,7 +1133,7 @@
"admin_cf_setup_s3_title": "再デプロイしてシークレットを読み込む",
"admin_cf_setup_s3_text": "Cloudflare Pagesはデプロイ時にシークレットを読み込みます。GitHub Actions経由なら自動的に再デプロイされます。手動で設定した場合は、ここで再デプロイしてください。その後、Cloudflareエッジパネルがアプリ内メトリクスの隣に表示されます。ゾーン分析を読み取るため、カスタムドメインの接続が必要です(素のpages.dev URLにはゾーンデータがありません)。",
"admin_cf_setup_callout_strong": "読み取り専用で、あなたのアカウントのみ。",
"admin_cf_setup_callout": " トークンにはZone Analytics Readだけを与え、それ以外は与えないでください。万一漏れても何も変更できません。読み取るのは常に自分のゾーンの数値だけなので、2つのフォークの境界になることはありません。",
"admin_cf_setup_callout": " トークンにはZone Analytics: Readだけを与え、それ以外は与えないでください。万一漏れても何も変更できません。読み取るのは常に自分のゾーンの数値だけなので、2つのフォークの境界になることはありません。",
"admin_cf_setup_unlocks_label": "追加される機能:",
"admin_cf_setup_unlocks": " Cloudflareエッジパネル(キャッシュとオリジンのリクエスト、総帯域、ブロックした脅威)。シークレットを削除すればいつでも接続を解除できます。このページの他の機能はこれに依存しません。",
"admin_settings_supporter_early_eyebrow": "早期アクセス",
Expand Down
2 changes: 1 addition & 1 deletion src/app.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ declare global {
* Optional Cloudflare edge-analytics enrichment (issue #6, Observability).
* All three must be present for the "Cloudflare edge" panel to appear;
* absence just hides it. The token needs exactly one scope —
* Zone · Analytics · Read, with Zone Resources scoped to your zone. The
* Zone Analytics: Read, with Zone Resources scoped to your zone. The
* query below is zone-scoped (viewer.zones), so Account Analytics · Read
* authenticates but is refused with a `zone.analytics.read` authz error. Set
* via `wrangler pages secret put CLOUDFLARE_ANALYTICS_TOKEN` (+ CLOUDFLARE_ACCOUNT_ID,
Expand Down
8 changes: 4 additions & 4 deletions src/lib/server/cf-analytics-scope.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { fileURLToPath } from 'node:url';
// Guards the bug class where the setup instructions name a Cloudflare permission
// that cannot run the query we actually send. getCloudflareEdge() queries
// `viewer { zones { httpRequests1dGroups } }` — a ZONE-scoped dataset, which needs
// `Zone · Analytics · Read`. The modal used to say `Account · Account Analytics ·
// `Zone Analytics: Read`. The modal used to say `Account · Account Analytics ·
// Read`; that token authenticates fine and is then refused:
//
// Actor '…' does not have permission 'com.cloudflare.api.account.zone.analytics.read'
Expand All @@ -30,7 +30,7 @@ const settingsPage = read('../../routes/admin/settings/+page.svelte');
const deployWorkflow = read('../../../.github/workflows/deploy.yml');

describe('Cloudflare edge analytics — documented scope matches the query', () => {
it('the query is zone-scoped, which is what makes Zone · Analytics · Read the right permission', () => {
it('the query is zone-scoped, which is what makes Zone Analytics: Read the right permission', () => {
expect(source).toMatch(/viewer\s*\{\s*zones\(/);
expect(source).toContain('httpRequests1dGroups');
});
Expand All @@ -39,8 +39,8 @@ describe('Cloudflare edge analytics — documented scope matches the query', ()
['en', en],
['ja', ja]
])('%s setup copy names the zone permission, never the account one', (_locale, messages) => {
expect(messages.admin_cf_setup_s1_scope).toBe('Zone · Analytics · Read');
expect(messages.admin_cf_setup_callout).toContain('Zone Analytics Read');
expect(messages.admin_cf_setup_s1_scope).toBe('Zone Analytics: Read');
expect(messages.admin_cf_setup_callout).toContain('Zone Analytics: Read');

// The account-scoped permission cannot satisfy a zone-scoped query. If this
// string reappears anywhere in the setup flow, the instructions are wrong.
Expand Down
Loading