From cd76b0dd824c6ac3c39f31aae5729a914d87d0a8 Mon Sep 17 00:00:00 2001 From: Mike Dean Date: Mon, 30 Sep 2024 13:03:44 +0100 Subject: [PATCH] feat(TA-1034): add partitioned cookie configuration --- lib/web-service/nginx-util.ts | 37 +++++++++++++++ .../__snapshots__/nginx-util.test.ts.snap | 47 +++++++++++++++++++ test/web-service/nginx-util.test.ts | 18 +++++++ 3 files changed, 102 insertions(+) diff --git a/lib/web-service/nginx-util.ts b/lib/web-service/nginx-util.ts index f43b93f..1af0239 100644 --- a/lib/web-service/nginx-util.ts +++ b/lib/web-service/nginx-util.ts @@ -29,6 +29,15 @@ interface NginxConfigMapProps { * @default false */ readonly includeSameSiteCookiesConfig?: boolean; + + /** + * Whether to include a config that patches Set-Cookies header to include `Partitioned` + * For further details on partitioned cookies visit: + * + * https://developer.mozilla.org/en-US/docs/Web/Privacy/Privacy_sandbox/Partitioned_cookies + * @default undefined + */ + readonly usePartionedCookiesLocations?: string[]; } /** @@ -47,6 +56,15 @@ function createConfigMap( data["samesite.conf"] = getSameSiteCookiesConfig(); } + if ( + props.usePartionedCookiesLocations && + props.usePartionedCookiesLocations.length > 0 + ) { + data["partitioned.conf"] = getPartitionedCookiesConfig( + props.usePartionedCookiesLocations, + ); + } + const configMap = new ConfigMap(scope, "nginx-config", { data }); return configMap; } @@ -88,6 +106,25 @@ function getSameSiteCookiesConfig(): string { return fs.readFileSync(resolvePath("nginx/samesite.conf"), "utf8"); } + +/** + * Return the contents of an Nginx configuration file that patches + * `Set-Cookie` headers to use the `Partitioned` flag + * + * The output of this function is used with `createConfigMap` with `usePartionedCookiesLocations` provided. + */ +function getPartitionedCookiesConfig(locations: string[]): string { + const configs = locations.map( + (location) => `location ${location} { + proxy_cookie_path / "/; Partitioned"; + }`, + ); + + return `server { + ${configs.join("\n")} + }`; +} + export const nginxUtil = { createConfigMap, getDefaultConfig, diff --git a/test/web-service/__snapshots__/nginx-util.test.ts.snap b/test/web-service/__snapshots__/nginx-util.test.ts.snap index 738ade4..eb24cfb 100644 --- a/test/web-service/__snapshots__/nginx-util.test.ts.snap +++ b/test/web-service/__snapshots__/nginx-util.test.ts.snap @@ -164,6 +164,53 @@ exports[`nginx-util > createConfigMap > Empty 1`] = ` ] `; +exports[`nginx-util > createConfigMap > Partitioned cookies config 1`] = ` +[ + { + "apiVersion": "v1", + "data": { + "partitioned.conf": "server { + location /api/oidclogin { + proxy_cookie_path / "/; Partitioned"; + } + }", + }, + "kind": "ConfigMap", + "metadata": { + "labels": { + "prunable": "true", + }, + "name": "test-nginx-config-c88fe926-m8bk7f665d", + }, + }, +] +`; + +exports[`nginx-util > createConfigMap > Partitioned cookies config with multiple locations 1`] = ` +[ + { + "apiVersion": "v1", + "data": { + "partitioned.conf": "server { + location /api/oidclogin { + proxy_cookie_path / "/; Partitioned"; + } +location /api/auth/login { + proxy_cookie_path / "/; Partitioned"; + } + }", + }, + "kind": "ConfigMap", + "metadata": { + "labels": { + "prunable": "true", + }, + "name": "test-nginx-config-c88fe926-5gf9f48485", + }, + }, +] +`; + exports[`nginx-util > createConfigMap > Same site cookies config 1`] = ` [ { diff --git a/test/web-service/nginx-util.test.ts b/test/web-service/nginx-util.test.ts index 6ce65bf..18b3eff 100644 --- a/test/web-service/nginx-util.test.ts +++ b/test/web-service/nginx-util.test.ts @@ -95,5 +95,23 @@ describe("nginx-util", () => { const results = Testing.synth(chart); expect(results).toMatchSnapshot(); }); + + test("Partitioned cookies config", () => { + const chart = Testing.chart(); + nginxUtil.createConfigMap(chart, { + usePartionedCookiesLocations: ["/api/oidclogin"], + }); + const results = Testing.synth(chart); + expect(results).toMatchSnapshot(); + }); + + test("Partitioned cookies config with multiple locations", () => { + const chart = Testing.chart(); + nginxUtil.createConfigMap(chart, { + usePartionedCookiesLocations: ["/api/oidclogin", "/api/auth/login"], + }); + const results = Testing.synth(chart); + expect(results).toMatchSnapshot(); + }); }); });