Skip to content

Commit 18b8c34

Browse files
set cookies properties and CSP settings to enable emedding
1 parent 6cf174f commit 18b8c34

File tree

8 files changed

+66
-17
lines changed

8 files changed

+66
-17
lines changed

.env.template

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,6 @@ SESSION_SECRET=
2020

2121
FEEDBACK_SLACK_URL=
2222
FEEDBACK_URL_LINK=
23+
24+
# frame-ancestors attribute of CSP. Separate multiple values with a space
25+
FRAME_ANCHESTORS=

index.html

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,9 @@
88
<title>MCP</title>
99
</head>
1010

11-
<script>
12-
window.global ||= window;
13-
</script>
14-
1511
<body>
1612
<div id="root"></div>
1713
<script type="module" src="/src/mount.ts"></script>
1814
</body>
1915

20-
</html>
16+
</html>

package-lock.json

Lines changed: 30 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
"npm": "^11.0.0"
88
},
99
"scripts": {
10-
"dev": "node server.js --dev",
10+
"dev": "node server.js --local-dev",
1111
"start": "node server.js",
1212
"build": "tsc && vite build",
1313
"lint": "eslint ./src --report-unused-disable-directives --max-warnings 0",
@@ -23,9 +23,10 @@
2323
"@fastify/autoload": "^6.3.0",
2424
"@fastify/cookie": "^11.0.2",
2525
"@fastify/env": "^5.0.2",
26+
"@fastify/helmet": "^13.0.1",
2627
"@fastify/http-proxy": "^11.1.2",
27-
"@fastify/sensible": "^6.0.3",
2828
"@fastify/secure-session": "^8.2.0",
29+
"@fastify/sensible": "^6.0.3",
2930
"@fastify/session": "^11.1.0",
3031
"@fastify/static": "^8.1.1",
3132
"@fastify/vite": "^8.1.3",

server.js

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,20 @@
11
import Fastify from 'fastify';
22
import FastifyVite from '@fastify/vite';
3+
import helmet from '@fastify/helmet';
34
import { fileURLToPath } from 'node:url';
45
import path from 'node:path';
56
import dotenv from 'dotenv';
67
import proxy from './server/app.js';
8+
import envPlugin from "./server/config/env.js";
79
import { copyFileSync } from 'node:fs';
810

911
dotenv.config();
1012

11-
const isDev = process.argv.includes('--dev');
13+
const isLocalDev = process.argv.includes('--local-dev');
1214

1315
const __filename = fileURLToPath(import.meta.url);
1416
const __dirname = path.dirname(__filename);
15-
const frontendConfigLocation = isDev
17+
const frontendConfigLocation = isLocalDev
1618
? 'public/frontend-config.json'
1719
: 'dist/client/frontend-config.json';
1820

@@ -33,13 +35,28 @@ const fastify = Fastify({
3335
logger: true,
3436
});
3537

38+
await fastify.register(envPlugin);
39+
40+
fastify.register(
41+
helmet,
42+
{
43+
contentSecurityPolicy: {
44+
directives: {
45+
"connect-src": ["'self'", "sdk.openui5.org"],
46+
"script-src": isLocalDev ? ["'self'", "'unsafe-inline'"] : ["'self'"],
47+
"frame-ancestors": [fastify.config.FRAME_ANCHESTORS]
48+
},
49+
}
50+
}
51+
)
52+
3653
fastify.register(proxy, {
3754
prefix: '/api',
3855
});
3956

4057
await fastify.register(FastifyVite, {
4158
root: __dirname,
42-
dev: isDev,
59+
dev: isLocalDev,
4360
spa: true,
4461
});
4562

server/app.js

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import path, { join, dirname } from "node:path";
22
import { fileURLToPath } from "node:url";
33
import AutoLoad from "@fastify/autoload";
4-
import envPlugin from "./config/env.js";
54
import encryptedSession from "./encrypted-session.js";
65

76
export const options = {};
@@ -10,7 +9,6 @@ const __filename = fileURLToPath(import.meta.url);
109
const __dirname = dirname(__filename);
1110

1211
export default async function (fastify, opts) {
13-
await fastify.register(envPlugin);
1412
fastify.register(encryptedSession, {
1513
...opts,
1614
});

server/config/env.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ const schema = {
1313
'COOKIE_SECRET',
1414
'SESSION_SECRET',
1515
'API_BACKEND_URL',
16+
'FRAME_ANCHESTORS',
1617
],
1718
properties: {
1819
// Application variables (.env)
@@ -27,6 +28,7 @@ const schema = {
2728
API_BACKEND_URL: { type: 'string' },
2829
FEEDBACK_SLACK_URL: { type: 'string' },
2930
FEEDBACK_URL_LINK: { type: 'string' },
31+
FRAME_ANCHESTORS: { type: 'string' },
3032

3133
// System variables
3234
NODE_ENV: { type: 'string', enum: ['development', 'production'] },

server/encrypted-session.js

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ export const ENCRYPTED_COOKIE_KEY_ENCRYPTION_KEY = "encryptionKey";
2121
export const SESSION_COOKIE_NAME = "session-cookie";
2222

2323
async function encryptedSession(fastify) {
24-
const { COOKIE_SECRET, SESSION_SECRET, NODE_ENV } = fastify.config;
24+
const { COOKIE_SECRET, SESSION_SECRET } = fastify.config;
2525

2626
await fastify.register(fastifyCookie);
2727

@@ -32,8 +32,9 @@ async function encryptedSession(fastify) {
3232
cookie: {
3333
path: "/",
3434
httpOnly: true,
35-
sameSite: "lax",
36-
secure: NODE_ENV === "production",
35+
sameSite: "None", // cross-site cookies are needed for the session to work when embedded. By setting CORS to None and CSP.frame-anchestors we restrict the api calls from the browser that contain the cookies to originating from our site only.
36+
partioned: true, // use for modern isolation of third party cookies when embedded, every embedded iframe (or not embedded) gets its own cookie partition
37+
secure: true,
3738
maxAge: 60 * 60 * 24 * 7, // 7 days
3839
},
3940
});
@@ -44,8 +45,9 @@ async function encryptedSession(fastify) {
4445
cookie: {
4546
path: "/",
4647
httpOnly: true,
47-
sameSite: "lax",
48-
secure: NODE_ENV === "production",
48+
sameSite: "None", // see secureSession cookie for explanation
49+
partioned: true, // see secureSession cookie for explanation
50+
secure: true,
4951
maxAge: 60 * 60 * 24 * 7, // 7 days
5052
},
5153
});

0 commit comments

Comments
 (0)