Skip to content

Commit 178ff0b

Browse files
feat: Add Dynatrace (#236)
1 parent f454384 commit 178ff0b

File tree

3 files changed

+53
-2
lines changed

3 files changed

+53
-2
lines changed

.env.template

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ SENTRY_PROJECT=
66
VITE_SENTRY_DSN=
77
# BFF:
88
BFF_SENTRY_DSN=
9+
DYNATRACE_SCRIPT_URL=
910

1011

1112
# OpenID Connect Configuration for Onboarding API

server.ts

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,15 @@ import proxy from './server/app.js';
88
import envPlugin from './server/config/env.js';
99
import { copyFileSync } from 'node:fs';
1010
import * as Sentry from '@sentry/node';
11+
import { injectDynatraceTag } from './server/config/dynatrace.js';
1112

1213
dotenv.config();
1314

15+
const { DYNATRACE_SCRIPT_URL } = process.env;
16+
if (DYNATRACE_SCRIPT_URL) {
17+
injectDynatraceTag(DYNATRACE_SCRIPT_URL);
18+
}
19+
1420
if (!process.env.BFF_SENTRY_DSN || process.env.BFF_SENTRY_DSN.trim() === '') {
1521
console.error('Error: Sentry DSN is not provided. Sentry will not be initialized.');
1622
} else {
@@ -70,11 +76,21 @@ if (fastify.config.VITE_SENTRY_DSN && fastify.config.VITE_SENTRY_DSN.length > 0)
7076
}
7177
}
7278

79+
let dynatraceOrigin = '';
80+
if (DYNATRACE_SCRIPT_URL) {
81+
try {
82+
dynatraceOrigin = new URL(DYNATRACE_SCRIPT_URL).origin;
83+
} catch {
84+
console.error('DYNATRACE_SCRIPT_URL is not a valid URL');
85+
}
86+
}
87+
88+
7389
fastify.register(helmet, {
7490
contentSecurityPolicy: {
7591
directives: {
76-
'connect-src': ["'self'", 'sdk.openui5.org', sentryHost],
77-
'script-src': isLocalDev ? ["'self'", "'unsafe-inline'"] : ["'self'"],
92+
'connect-src': ["'self'", 'sdk.openui5.org', sentryHost, dynatraceOrigin],
93+
'script-src': isLocalDev ? ["'self'", "'unsafe-inline'", dynatraceOrigin] : ["'self'", dynatraceOrigin],
7894
// @ts-ignore
7995
'frame-ancestors': [fastify.config.FRAME_ANCESTORS],
8096
},

server/config/dynatrace.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import { readFileSync, writeFileSync } from "node:fs";
2+
import { join } from 'node:path';
3+
4+
export function injectDynatraceTag(scriptUrl: string): void {
5+
const indexPath = join(process.cwd(), 'dist/client/index.html');
6+
console.log(`[Dynatrace] Injecting "${scriptUrl}" into "${indexPath}".`);
7+
8+
let html: string;
9+
try {
10+
html = readFileSync(indexPath, 'utf-8');
11+
} catch (err) {
12+
console.error(`[Dynatrace] Failed to read ${indexPath}.`, err);
13+
return;
14+
}
15+
16+
if (html.includes(scriptUrl)) {
17+
console.log('[Dynatrace] Script already present, skipping.');
18+
return;
19+
}
20+
21+
const scriptTag =
22+
`<script type="text/javascript" src="${scriptUrl}" crossorigin="anonymous"></script>`;
23+
24+
// Inject right before closing </head> tag (case-insensitive)
25+
const headClose = /<\/head>/i;
26+
if (!headClose.test(html)) {
27+
console.error('[Dynatrace] </head> tag not found, aborting.');
28+
return;
29+
}
30+
html = html.replace(headClose, ` ${scriptTag}\n</head>`);
31+
32+
writeFileSync(indexPath, html, 'utf-8');
33+
console.log('[Dynatrace] Script injected successfully.');
34+
}

0 commit comments

Comments
 (0)