Skip to content

Commit 438a270

Browse files
committed
fix: add versioning to umami script to enable manual CF cache invalidation
Know-Code-Verified: 23a3c5e5d43133a9bb8d391011ece2ace4273ae904c97bf83fcc2b5599a7b478
1 parent ca307e1 commit 438a270

4 files changed

Lines changed: 27 additions & 7 deletions

File tree

‎infra/umami-proxy/README.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ so the browser never talks to a third-party analytics host (ad-blocker bypass).
66

77
| Public (docs domain) | Upstream |
88
|----------------------|----------|
9-
| `GET /s/x.js` | `{UMAMI_ORIGIN}/script.js` |
9+
| `GET /s/x.js` | `{UMAMI_ORIGIN}/script.js` (collector rewritten to `/s/e`) |
1010
| `POST /s/e` | `{UMAMI_ORIGIN}/api/send` |
1111

1212
Neutral path names (`/s/x.js`, `/s/e`) avoid EasyPrivacy hits on `umami`,

‎infra/umami-proxy/src/index.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
* Same-origin proxy for self-hosted Umami.
33
*
44
* Public paths on kc.chtnnhfoundation.org (neutral names — not on blocklists):
5-
* GET /s/x.js → {UMAMI_ORIGIN}/script.js (rewrites /api/send → /s/e)
5+
* GET /s/x.js → {UMAMI_ORIGIN}/script.js (rewrites its collector to /s/e)
66
* POST /s/e → {UMAMI_ORIGIN}/api/send
77
*
88
* Dashboard and other Umami routes are not exposed. Deploy the Worker first,

‎infra/umami-proxy/src/paths.test.ts‎

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ import { describe, it } from "node:test";
33
import {
44
COLLECT_PATH,
55
ORIGIN_COLLECT,
6+
SCRIPT_PATH,
7+
TRACKER_COLLECT_SUFFIX,
68
matchProxyPath,
79
originBase,
810
rewriteTrackerScript,
@@ -21,14 +23,29 @@ describe("originBase", () => {
2123
});
2224

2325
describe("rewriteTrackerScript", () => {
24-
it("points collect calls at the same-origin path", () => {
26+
it("points collect calls at the same-origin collector suffix", () => {
2527
const src = `fetch("${ORIGIN_COLLECT}",{method:"POST"})`;
26-
assert.equal(rewriteTrackerScript(src), `fetch("${COLLECT_PATH}",{method:"POST"})`);
28+
assert.equal(
29+
rewriteTrackerScript(src),
30+
`fetch("${TRACKER_COLLECT_SUFFIX}",{method:"POST"})`,
31+
);
2732
});
2833

2934
it("rewrites every occurrence", () => {
3035
const src = `${ORIGIN_COLLECT} ${ORIGIN_COLLECT}`;
31-
assert.equal(rewriteTrackerScript(src), `${COLLECT_PATH} ${COLLECT_PATH}`);
36+
assert.equal(
37+
rewriteTrackerScript(src),
38+
`${TRACKER_COLLECT_SUFFIX} ${TRACKER_COLLECT_SUFFIX}`,
39+
);
40+
});
41+
42+
it("makes the tracker's script-relative collector resolve to the public endpoint", () => {
43+
const trackerBase = new URL(SCRIPT_PATH, "https://kc.chtnnhfoundation.org").href
44+
.split("/")
45+
.slice(0, -1)
46+
.join("/");
47+
assert.equal(`${trackerBase}${TRACKER_COLLECT_SUFFIX}`, "https://kc.chtnnhfoundation.org/s/e");
48+
assert.equal(`${trackerBase}${COLLECT_PATH}`, "https://kc.chtnnhfoundation.org/s/s/e");
3249
});
3350

3451
it("does not rewrite other Umami routes", () => {

‎infra/umami-proxy/src/paths.ts‎

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,14 @@ export const SCRIPT_PATH = "/s/x.js";
44
export const COLLECT_PATH = "/s/e";
55
export const ORIGIN_SCRIPT = "/script.js";
66
export const ORIGIN_COLLECT = "/api/send";
7+
// Umami appends this suffix to the directory containing its tracker script.
8+
// With /s/x.js, /e produces the public collector endpoint /s/e.
9+
export const TRACKER_COLLECT_SUFFIX = "/e";
710

811
// Bump this whenever the Worker changes the transformed tracker response.
912
// Cache API entries outlive Worker deployments, so this avoids serving a
1013
// response produced by an older transform.
11-
export const TRACKER_CACHE_VERSION = "v1";
14+
export const TRACKER_CACHE_VERSION = "v2";
1215

1316
export type ProxyRoute = "script" | "collect";
1417

@@ -17,7 +20,7 @@ export function originBase(origin: string): string {
1720
}
1821

1922
export function rewriteTrackerScript(body: string): string {
20-
return body.replaceAll(ORIGIN_COLLECT, COLLECT_PATH);
23+
return body.replaceAll(ORIGIN_COLLECT, TRACKER_COLLECT_SUFFIX);
2124
}
2225

2326
/** Versioned Cache API key; never use this URL for the upstream fetch. */

0 commit comments

Comments
 (0)