Skip to content

Commit

Permalink
feat(TA-1034): add partitioned cookie configuration (#94)
Browse files Browse the repository at this point in the history
## Problem

* [TA-1034](https://techfromsage.atlassian.net/browse/TA-1034)

On analysing Elevate's use of LTI.js, we identified that it requires
third party cookies. The library has not yet been updated to change this
particular feature.

In order for LTI launches to continue to work in Elevate (at least for
Chrome-based browsers), we require a solution that allows these cookies
to be processed in a PKCE workflow.

The current solution to this issue is [partioned
cookies](https://developer.mozilla.org/en-US/docs/Web/Privacy/Privacy_sandbox/Partitioned_cookies).

Elevate cannot support this at an LTI.js level, nor at the Express.js
level so we must resort to a supporting configuration in nginx.

This new property will load a supporting nginx configuration. 

[TA-1034]:
https://techfromsage.atlassian.net/browse/TA-1034?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ
  • Loading branch information
mike-dean-talis authored Oct 3, 2024
1 parent b0a6c15 commit e9f2962
Show file tree
Hide file tree
Showing 5 changed files with 362 additions and 90 deletions.
134 changes: 77 additions & 57 deletions examples/advanced-web-service/__snapshots__/chart.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -82,15 +82,17 @@ server {
gzip_types text/html text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;
location / {
proxy_pass http://application;
proxy_http_version 1.1;
proxy_set_header Connection $connection_upgrade;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
proxy_pass http://application;
proxy_http_version 1.1;
proxy_set_header Connection $connection_upgrade;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location /livez {
access_log off;
Expand All @@ -106,6 +108,8 @@ server {
allow 172.16.0.0/12;
deny all;
}
}
",
"samesite.conf": "# Implements SameSite cookie flags to ensure that our Login Server cookies are flagged as \`SameSite=None\` and \`Secure\`.
Expand Down Expand Up @@ -185,7 +189,7 @@ proxy_cookie_path / "/$cookie_path_patches";
"region": "local",
"service": "advanced-development-local",
},
"name": "nginx-config-82htd5f6t7",
"name": "nginx-config-g87b2gc9mg",
"namespace": "advanced-test",
},
},
Expand Down Expand Up @@ -617,7 +621,7 @@ proxy_cookie_path / "/$cookie_path_patches";
{
"configMap": {
"defaultMode": 292,
"name": "nginx-config-82htd5f6t7",
"name": "nginx-config-g87b2gc9mg",
},
"name": "nginx-config",
},
Expand Down Expand Up @@ -711,15 +715,17 @@ server {
gzip_types text/html text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;
location / {
proxy_pass http://application;
proxy_http_version 1.1;
proxy_set_header Connection $connection_upgrade;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
proxy_pass http://application;
proxy_http_version 1.1;
proxy_set_header Connection $connection_upgrade;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location /livez {
access_log off;
Expand All @@ -735,6 +741,8 @@ server {
allow 172.16.0.0/12;
deny all;
}
}
",
"samesite.conf": "# Implements SameSite cookie flags to ensure that our Login Server cookies are flagged as \`SameSite=None\` and \`Secure\`.
Expand Down Expand Up @@ -814,7 +822,7 @@ proxy_cookie_path / "/$cookie_path_patches";
"region": "local",
"service": "advanced-development-local",
},
"name": "nginx-config-82htd5f6t7",
"name": "nginx-config-g87b2gc9mg",
"namespace": "advanced-test",
},
},
Expand Down Expand Up @@ -1103,7 +1111,7 @@ proxy_cookie_path / "/$cookie_path_patches";
{
"configMap": {
"defaultMode": 292,
"name": "nginx-config-82htd5f6t7",
"name": "nginx-config-g87b2gc9mg",
},
"name": "nginx-config",
},
Expand Down Expand Up @@ -1466,7 +1474,7 @@ proxy_cookie_path / "/$cookie_path_patches";
{
"configMap": {
"defaultMode": 292,
"name": "nginx-config-82htd5f6t7",
"name": "nginx-config-g87b2gc9mg",
},
"name": "nginx-config",
},
Expand Down Expand Up @@ -1560,15 +1568,17 @@ server {
gzip_types text/html text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;
location / {
proxy_pass http://application;
proxy_http_version 1.1;
proxy_set_header Connection $connection_upgrade;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
proxy_pass http://application;
proxy_http_version 1.1;
proxy_set_header Connection $connection_upgrade;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location /livez {
access_log off;
Expand All @@ -1584,6 +1594,8 @@ server {
allow 172.16.0.0/12;
deny all;
}
}
",
"samesite.conf": "# Implements SameSite cookie flags to ensure that our Login Server cookies are flagged as \`SameSite=None\` and \`Secure\`.
Expand Down Expand Up @@ -1663,7 +1675,7 @@ proxy_cookie_path / "/$cookie_path_patches";
"region": "local",
"service": "advanced-development-local",
},
"name": "nginx-config-82htd5f6t7",
"name": "nginx-config-g87b2gc9mg",
"namespace": "advanced-test",
},
},
Expand Down Expand Up @@ -2095,7 +2107,7 @@ proxy_cookie_path / "/$cookie_path_patches";
{
"configMap": {
"defaultMode": 292,
"name": "nginx-config-82htd5f6t7",
"name": "nginx-config-g87b2gc9mg",
},
"name": "nginx-config",
},
Expand Down Expand Up @@ -2189,15 +2201,17 @@ server {
gzip_types text/html text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;
location / {
proxy_pass http://application;
proxy_http_version 1.1;
proxy_set_header Connection $connection_upgrade;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
proxy_pass http://application;
proxy_http_version 1.1;
proxy_set_header Connection $connection_upgrade;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location /livez {
access_log off;
Expand All @@ -2213,6 +2227,8 @@ server {
allow 172.16.0.0/12;
deny all;
}
}
",
"samesite.conf": "# Implements SameSite cookie flags to ensure that our Login Server cookies are flagged as \`SameSite=None\` and \`Secure\`.
Expand Down Expand Up @@ -2292,7 +2308,7 @@ proxy_cookie_path / "/$cookie_path_patches";
"region": "local",
"service": "advanced-development-local",
},
"name": "nginx-config-82htd5f6t7",
"name": "nginx-config-g87b2gc9mg",
"namespace": "advanced-test",
},
},
Expand Down Expand Up @@ -2580,7 +2596,7 @@ proxy_cookie_path / "/$cookie_path_patches";
{
"configMap": {
"defaultMode": 292,
"name": "nginx-config-82htd5f6t7",
"name": "nginx-config-g87b2gc9mg",
},
"name": "nginx-config",
},
Expand Down Expand Up @@ -2943,7 +2959,7 @@ proxy_cookie_path / "/$cookie_path_patches";
{
"configMap": {
"defaultMode": 292,
"name": "nginx-config-82htd5f6t7",
"name": "nginx-config-g87b2gc9mg",
},
"name": "nginx-config",
},
Expand Down Expand Up @@ -3037,15 +3053,17 @@ server {
gzip_types text/html text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;
location / {
proxy_pass http://application;
proxy_http_version 1.1;
proxy_set_header Connection $connection_upgrade;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
proxy_pass http://application;
proxy_http_version 1.1;
proxy_set_header Connection $connection_upgrade;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location /livez {
access_log off;
Expand All @@ -3061,6 +3079,8 @@ server {
allow 172.16.0.0/12;
deny all;
}
}
",
"samesite.conf": "# Implements SameSite cookie flags to ensure that our Login Server cookies are flagged as \`SameSite=None\` and \`Secure\`.
Expand Down Expand Up @@ -3140,7 +3160,7 @@ proxy_cookie_path / "/$cookie_path_patches";
"region": "local",
"service": "advanced-development-local",
},
"name": "nginx-config-82htd5f6t7",
"name": "nginx-config-g87b2gc9mg",
"namespace": "advanced-test",
},
},
Expand Down Expand Up @@ -3571,7 +3591,7 @@ proxy_cookie_path / "/$cookie_path_patches";
{
"configMap": {
"defaultMode": 292,
"name": "nginx-config-82htd5f6t7",
"name": "nginx-config-g87b2gc9mg",
},
"name": "nginx-config",
},
Expand Down
68 changes: 65 additions & 3 deletions lib/web-service/nginx-util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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[];
}

/**
Expand All @@ -39,7 +48,11 @@ function createConfigMap(
props: NginxConfigMapProps,
data: { [key: string]: string } = {},
): ConfigMap {
if (props.includeDefaultConfig) {
const usePartitionedCookies =
props.usePartionedCookiesLocations &&
props.usePartionedCookiesLocations.length > 0;

if (props.includeDefaultConfig || usePartitionedCookies) {
data["default.conf"] = getDefaultConfig(props);
}

Expand All @@ -60,7 +73,10 @@ function createConfigMap(
* The output of this function is used with `createConfigMap` with `includeDefaultConfig` enabled.
*/
function getDefaultConfig(
props: Pick<NginxConfigMapProps, "applicationPort" | "nginxPort">,
props: Pick<
NginxConfigMapProps,
"applicationPort" | "nginxPort" | "usePartionedCookiesLocations"
>,
): string {
const { applicationPort, nginxPort } = props;

Expand All @@ -72,10 +88,21 @@ function getDefaultConfig(
throw new Error("Application and nginx ports must be different");
}

const defaultRouteLocation = createProxyRouteConfig(
"/",
"http://application",
);

const partitionedCookieLocations = getPartitionedCookiesConfig(
props.usePartionedCookiesLocations,
);

return fs
.readFileSync(resolvePath("nginx/default.conf"), "utf8")
.replaceAll("{{applicationPort}}", applicationPort.toString())
.replaceAll("{{nginxPort}}", nginxPort.toString());
.replaceAll("{{nginxPort}}", nginxPort.toString())
.replaceAll("{{defaultRouteLocation}}", defaultRouteLocation)
.replaceAll("{{partitionedCookieLocations}}", partitionedCookieLocations);
}

/**
Expand All @@ -88,6 +115,41 @@ function getSameSiteCookiesConfig(): string {
return fs.readFileSync(resolvePath("nginx/samesite.conf"), "utf8");
}

function getPartitionedCookiesConfig(locations?: string[]): string {
if (!locations) {
return "";
}

return locations
.map((location) =>
createProxyRouteConfig(location, "http://application", [
`proxy_cookie_path / "/; Partitioned";`,
]),
)
.join("\n\n");
}

function createProxyRouteConfig(
location: string,
proxyPath: string,
additionalSettings?: string[],
): string {
const additional = additionalSettings ? additionalSettings.join("\n") : "";

return `location ${location} {
proxy_pass ${proxyPath};
proxy_http_version 1.1;
proxy_set_header Connection $connection_upgrade;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
${additional}
}`;
}

export const nginxUtil = {
createConfigMap,
getDefaultConfig,
Expand Down
Loading

0 comments on commit e9f2962

Please sign in to comment.