From 1917c17cf9efcf17c806a28986bc66346c9471c8 Mon Sep 17 00:00:00 2001 From: Ken Tandrian <60643640+KenTandrian@users.noreply.github.com> Date: Sat, 15 Mar 2025 17:57:01 +0700 Subject: [PATCH] Bugfix/fix issue with serving Storybook related to contentSecurityPolicy (#4437) * Fix issue with serving Storybook related to contentSecurityPolicy * Update changelog --- CHANGELOG.md | 4 +++ apps/api/src/main.ts | 35 +++++++++++-------- .../middlewares/html-template.middleware.ts | 3 +- libs/common/src/lib/config.ts | 2 ++ 4 files changed, 29 insertions(+), 15 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a71397b2c..70fb91984 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Upgraded `angular` from version `19.0.5` to `19.2.1` - Upgraded `Nx` from version `20.3.2` to `20.5.0` +### Fixed + +- Fixed an issue with serving _Storybook_ related to the `contentSecurityPolicy` + ## 2.145.1 - 2025-03-10 ### Added diff --git a/apps/api/src/main.ts b/apps/api/src/main.ts index fdd6c1d99..7cd5953b0 100644 --- a/apps/api/src/main.ts +++ b/apps/api/src/main.ts @@ -1,3 +1,5 @@ +import { STORYBOOK_PATH } from '@ghostfolio/common/config'; + import { Logger, LogLevel, @@ -7,6 +9,7 @@ import { import { ConfigService } from '@nestjs/config'; import { NestFactory } from '@nestjs/core'; import type { NestExpressApplication } from '@nestjs/platform-express'; +import { NextFunction, Request, Response } from 'express'; import helmet from 'helmet'; import { AppModule } from './app/app.module'; @@ -50,20 +53,24 @@ async function bootstrap() { app.useBodyParser('json', { limit: '10mb' }); if (configService.get('ENABLE_FEATURE_SUBSCRIPTION') === 'true') { - app.use( - helmet({ - contentSecurityPolicy: { - directives: { - connectSrc: ["'self'", 'https://js.stripe.com'], // Allow connections to Stripe - frameSrc: ["'self'", 'https://js.stripe.com'], // Allow loading frames from Stripe - scriptSrc: ["'self'", "'unsafe-inline'", 'https://js.stripe.com'], // Allow inline scripts and scripts from Stripe - scriptSrcAttr: ["'self'", "'unsafe-inline'"], // Allow inline event handlers - styleSrc: ["'self'", "'unsafe-inline'"] // Allow inline styles - } - }, - crossOriginOpenerPolicy: false // Disable Cross-Origin-Opener-Policy header (for Internet Identity) - }) - ); + app.use((req: Request, res: Response, next: NextFunction) => { + if (req.path.startsWith(STORYBOOK_PATH)) { + next(); + } else { + helmet({ + contentSecurityPolicy: { + directives: { + connectSrc: ["'self'", 'https://js.stripe.com'], // Allow connections to Stripe + frameSrc: ["'self'", 'https://js.stripe.com'], // Allow loading frames from Stripe + scriptSrc: ["'self'", "'unsafe-inline'", 'https://js.stripe.com'], // Allow inline scripts and scripts from Stripe + scriptSrcAttr: ["'self'", "'unsafe-inline'"], // Allow inline event handlers + styleSrc: ["'self'", "'unsafe-inline'"] // Allow inline styles + } + }, + crossOriginOpenerPolicy: false // Disable Cross-Origin-Opener-Policy header (for Internet Identity) + })(req, res, next); + } + }); } app.use(HtmlTemplateMiddleware); diff --git a/apps/api/src/middlewares/html-template.middleware.ts b/apps/api/src/middlewares/html-template.middleware.ts index b6c8f2e54..256876952 100644 --- a/apps/api/src/middlewares/html-template.middleware.ts +++ b/apps/api/src/middlewares/html-template.middleware.ts @@ -3,6 +3,7 @@ import { I18nService } from '@ghostfolio/api/services/i18n/i18n.service'; import { DEFAULT_LANGUAGE_CODE, DEFAULT_ROOT_URL, + STORYBOOK_PATH, SUPPORTED_LANGUAGE_CODES } from '@ghostfolio/common/config'; import { DATE_FORMAT, interpolate } from '@ghostfolio/common/helper'; @@ -129,7 +130,7 @@ export const HtmlTemplateMiddleware = async ( if ( path.startsWith('/api/') || - path.startsWith('/development/storybook') || + path.startsWith(STORYBOOK_PATH) || isFileRequest(path) || !environment.production ) { diff --git a/libs/common/src/lib/config.ts b/libs/common/src/lib/config.ts index edfe7fa69..696ca86d2 100644 --- a/libs/common/src/lib/config.ts +++ b/libs/common/src/lib/config.ts @@ -153,6 +153,8 @@ export const REPLACE_NAME_PARTS = [ 'Xtrackers (IE) Plc -' ]; +export const STORYBOOK_PATH = '/development/storybook'; + export const SUPPORTED_LANGUAGE_CODES = [ 'ca', 'de',