| | @@ -31,8 +31,11 @@ |
| 31 | 31 | const env = { PUBLIC_URL: ORIGIN, DB, BOOTSTRAP_ADMINS: "" } as unknown as Env; |
| 32 | 32 | const waits: Promise<unknown>[] = []; |
| 33 | 33 | const ctx = { waitUntil: (p: Promise<unknown>) => void waits.push(p), passThroughOnException() {}, props: {} } as unknown as ExecutionContext; |
| 34 | | - const fetch = async (path: string, init: RequestInit = {}) => { |
| 35 | | - const res = await app.fetch(new Request(`${ORIGIN}${path}`, { redirect: "manual", ...init }), env, ctx); |
| 34 | + // `cf` stands in for the edge's request.cf, which a Worker gets and a client can't set. |
| 35 | + const fetch = async (path: string, { cf, ...init }: RequestInit & { cf?: Record<string, string> } = {}) => { |
| 36 | + const req = new Request(`${ORIGIN}${path}`, { redirect: "manual", ...init }); |
| 37 | + if (cf) Object.defineProperty(req, "cf", { value: cf }); |
| 38 | + const res = await app.fetch(req, env, ctx); |
| 36 | 39 | await Promise.allSettled(waits); |
| 37 | 40 | return res; |
| 38 | 41 | }; |
| | @@ -265,19 +268,21 @@ |
| 265 | 268 | |
| 266 | 269 | it("warns when the device code came from another network or country", async () => { |
| 267 | 270 | const t = setup(); |
| 268 | | - const r = await t.fetch("/-/cli/device", { method: "POST", headers: { "content-type": "application/json", "cf-connecting-ip": "203.0.113.5", "cf-ipcountry": "NG" }, body: JSON.stringify({ client: { host: "far-away" } }) }); |
| 271 | + const r = await t.fetch("/-/cli/device", { method: "POST", cf: { city: "Lagos", country: "NG" }, headers: { "content-type": "application/json", "cf-connecting-ip": "203.0.113.5" }, body: JSON.stringify({ client: { host: "far-away" } }) }); |
| 269 | 272 | const d = (await r.json()) as { user_code: string }; |
| 270 | | - const approve = (ip: string, country?: string) => |
| 273 | + const approve = (ip: string, country?: string, header?: string) => |
| 271 | 274 | t.fetch("/login/device", { |
| 272 | 275 | method: "POST", |
| 273 | | - headers: { cookie: `__Host-dfy_session=ana-fresh-session-0000000000001; dfy_csrf=${CSRF}`, "content-type": "application/x-www-form-urlencoded", "content-length": String(new URLSearchParams({ _csrf: CSRF, code: d.user_code }).toString().length), origin: ORIGIN, "cf-connecting-ip": ip, ...(country ? { "cf-ipcountry": country } : {}) }, |
| 276 | + cf: country ? { country } : undefined, |
| 277 | + headers: { cookie: `__Host-dfy_session=ana-fresh-session-0000000000001; dfy_csrf=${CSRF}`, "content-type": "application/x-www-form-urlencoded", "content-length": String(new URLSearchParams({ _csrf: CSRF, code: d.user_code }).toString().length), origin: ORIGIN, "cf-connecting-ip": ip, ...(header ? { "cf-ipcountry": header } : {}) }, |
| 274 | 278 | body: new URLSearchParams({ _csrf: CSRF, code: d.user_code }).toString(), |
| 275 | 279 | }); |
| 276 | 280 | expect(await (await approve("198.51.100.7")).text()).toContain("from a different network (203.0.113.5)"); |
| 277 | 281 | expect(await (await approve("203.0.113.5")).text()).not.toContain("different network"); |
| 278 | | - // The country comes from request.cf, or from the CF-IPCountry header when cf has none. |
| 279 | | - expect(await (await approve("198.51.100.7", "TR")).text()).toContain("asked for from another country</b> (NG)"); |
| 282 | + // The country comes from the edge's request.cf only; a CF-IPCountry header the client sends is ignored. |
| 283 | + expect(await (await approve("198.51.100.7", "TR")).text()).toContain("asked for from another country</b> (Lagos, NG)"); |
| 280 | 284 | expect(await (await approve("198.51.100.7", "NG")).text()).not.toContain("another country"); |
| 285 | + expect(await (await approve("198.51.100.7", undefined, "TR")).text()).not.toContain("another country"); |
| 281 | 286 | expect(placeMismatch({ ip: "1.1.1.1", location: "Lagos, NG" }, { ip: "2.2.2.2", country: "TR" })).toBe("country"); |
| 282 | 287 | expect(placeMismatch({ ip: "1.1.1.1", location: "TR" }, { ip: "2.2.2.2", country: "TR" })).toBe("network"); |
| 283 | 288 | expect(placeMismatch({ ip: "1.1.1.1", location: "Istanbul, TR" }, { ip: "1.1.1.1", country: "TR" })).toBeNull(); |