@decocms/start 5.4.1 → 5.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/sdk/workerEntry.test.ts +106 -0
- package/src/sdk/workerEntry.ts +21 -1
package/package.json
CHANGED
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import { injectGeoCookies } from "./workerEntry";
|
|
3
|
+
|
|
4
|
+
function parseCookies(header: string): Record<string, string> {
|
|
5
|
+
return Object.fromEntries(
|
|
6
|
+
header.split("; ").map((c) => {
|
|
7
|
+
const [k, ...v] = c.split("=");
|
|
8
|
+
return [k, v.join("=")];
|
|
9
|
+
}),
|
|
10
|
+
);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function makeRequest(
|
|
14
|
+
cf: Record<string, string> | undefined,
|
|
15
|
+
headers: Record<string, string> = {},
|
|
16
|
+
): Request {
|
|
17
|
+
const req = new Request("https://example.com/", { headers });
|
|
18
|
+
if (cf) {
|
|
19
|
+
Object.defineProperty(req, "cf", { value: cf, configurable: true });
|
|
20
|
+
}
|
|
21
|
+
return req;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
describe("injectGeoCookies", () => {
|
|
25
|
+
it("strips cf-region from the outgoing Request headers while preserving the value in __cf_geo_region cookie", () => {
|
|
26
|
+
const req = makeRequest(
|
|
27
|
+
{ region: "São Paulo", country: "BR" },
|
|
28
|
+
{ "cf-region": "São Paulo", "cf-ipcountry": "BR" },
|
|
29
|
+
);
|
|
30
|
+
|
|
31
|
+
const out = injectGeoCookies(req);
|
|
32
|
+
|
|
33
|
+
expect(out.headers.get("cf-region")).toBeNull();
|
|
34
|
+
// ASCII CF headers (cf-ipcountry) are still forwarded
|
|
35
|
+
expect(out.headers.get("cf-ipcountry")).toBe("BR");
|
|
36
|
+
// Geo data is preserved as cookies for matchers
|
|
37
|
+
const cookies = parseCookies(out.headers.get("cookie") ?? "");
|
|
38
|
+
expect(cookies.__cf_geo_region).toBe(encodeURIComponent("São Paulo"));
|
|
39
|
+
expect(cookies.__cf_geo_country).toBe("BR");
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
it("strips cf-ipcity from the outgoing Request headers while preserving the value in __cf_geo_city cookie", () => {
|
|
43
|
+
const req = makeRequest(
|
|
44
|
+
{ city: "Brasília", country: "BR" },
|
|
45
|
+
{ "cf-ipcity": "Brasília" },
|
|
46
|
+
);
|
|
47
|
+
|
|
48
|
+
const out = injectGeoCookies(req);
|
|
49
|
+
|
|
50
|
+
expect(out.headers.get("cf-ipcity")).toBeNull();
|
|
51
|
+
const cookies = parseCookies(out.headers.get("cookie") ?? "");
|
|
52
|
+
expect(cookies.__cf_geo_city).toBe(encodeURIComponent("Brasília"));
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
it("returns the original request unchanged when there is no cf object", () => {
|
|
56
|
+
const req = makeRequest(undefined, { "cf-region": "São Paulo" });
|
|
57
|
+
|
|
58
|
+
const out = injectGeoCookies(req);
|
|
59
|
+
|
|
60
|
+
// Without cf, we don't build cookies, and we return the original request
|
|
61
|
+
// untouched (so the cf-region header is still present — but that's the
|
|
62
|
+
// caller's pre-existing state, not something we re-introduced).
|
|
63
|
+
expect(out).toBe(req);
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
it("returns the original request unchanged when cf has no relevant geo fields", () => {
|
|
67
|
+
const req = makeRequest({ asn: "12345" }, { "cf-region": "São Paulo" });
|
|
68
|
+
|
|
69
|
+
const out = injectGeoCookies(req);
|
|
70
|
+
|
|
71
|
+
expect(out).toBe(req);
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
it("preserves a pre-existing cookie header", () => {
|
|
75
|
+
const req = makeRequest(
|
|
76
|
+
{ region: "São Paulo" },
|
|
77
|
+
{ cookie: "vtex_segment=abc; another=xyz" },
|
|
78
|
+
);
|
|
79
|
+
|
|
80
|
+
const out = injectGeoCookies(req);
|
|
81
|
+
|
|
82
|
+
const raw = out.headers.get("cookie") ?? "";
|
|
83
|
+
expect(raw).toContain("vtex_segment=abc");
|
|
84
|
+
expect(raw).toContain("another=xyz");
|
|
85
|
+
expect(raw).toContain("__cf_geo_region=");
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
it("forwards non-geo headers untouched", () => {
|
|
89
|
+
const req = makeRequest(
|
|
90
|
+
{ region: "Paraná" },
|
|
91
|
+
{
|
|
92
|
+
"user-agent": "test-agent",
|
|
93
|
+
accept: "*/*",
|
|
94
|
+
"x-custom": "value",
|
|
95
|
+
"cf-ray": "9ff5b26cf9bc067a",
|
|
96
|
+
},
|
|
97
|
+
);
|
|
98
|
+
|
|
99
|
+
const out = injectGeoCookies(req);
|
|
100
|
+
|
|
101
|
+
expect(out.headers.get("user-agent")).toBe("test-agent");
|
|
102
|
+
expect(out.headers.get("accept")).toBe("*/*");
|
|
103
|
+
expect(out.headers.get("x-custom")).toBe("value");
|
|
104
|
+
expect(out.headers.get("cf-ray")).toBe("9ff5b26cf9bc067a");
|
|
105
|
+
});
|
|
106
|
+
});
|
package/src/sdk/workerEntry.ts
CHANGED
|
@@ -443,7 +443,27 @@ export function injectGeoCookies(request: Request): Request {
|
|
|
443
443
|
|
|
444
444
|
const existing = request.headers.get("cookie") ?? "";
|
|
445
445
|
const combined = existing ? `${existing}; ${parts.join("; ")}` : parts.join("; ");
|
|
446
|
-
|
|
446
|
+
|
|
447
|
+
// Strip CF geo headers that carry non-ASCII values (cf-region: "São Paulo",
|
|
448
|
+
// cf-ipcity: "Brasília", etc.) before building the new Request. The geo
|
|
449
|
+
// data is preserved in the __cf_geo_* cookies we just built, so callers
|
|
450
|
+
// downstream lose no information.
|
|
451
|
+
//
|
|
452
|
+
// Without this strip, the Workers runtime emits a warning on every
|
|
453
|
+
// request because the new Request inherits these UTF-8 headers from the
|
|
454
|
+
// inbound request:
|
|
455
|
+
//
|
|
456
|
+
// "A header value for "cf-region" contains non-ASCII characters: "..."
|
|
457
|
+
//
|
|
458
|
+
// and the warning is logged once per non-ASCII header — for a Brazilian
|
|
459
|
+
// storefront with cities/states full of accents that means ~2 warns per
|
|
460
|
+
// request × every request that hits the worker.
|
|
461
|
+
const headers = new Headers();
|
|
462
|
+
for (const [key, value] of request.headers.entries()) {
|
|
463
|
+
const lk = key.toLowerCase();
|
|
464
|
+
if (lk === "cf-region" || lk === "cf-ipcity") continue;
|
|
465
|
+
headers.set(key, value);
|
|
466
|
+
}
|
|
447
467
|
headers.set("cookie", combined);
|
|
448
468
|
|
|
449
469
|
return new Request(request, { headers });
|