diff --git a/packages/api-gateway/bin/server.ts b/packages/api-gateway/bin/server.ts index b8d3fe7f3..a374eece7 100644 --- a/packages/api-gateway/bin/server.ts +++ b/packages/api-gateway/bin/server.ts @@ -83,7 +83,41 @@ void container.load().then((container) => { type: ['text/plain', 'application/x-www-form-urlencoded', 'application/x-www-form-urlencoded; charset=utf-8'], }), ) - app.use(cors()) + const corsAllowedOrigins = env.get('CORS_ALLOWED_ORIGINS', true) + ? env.get('CORS_ALLOWED_ORIGINS', true).split(',') + : [] + app.use( + cors({ + credentials: true, + exposedHeaders: ['x-captcha-required'], + origin: (requestOrigin: string | undefined, callback: (err: Error | null, origin?: string[]) => void) => { + const requstOriginIsNotFilled = !requestOrigin || requestOrigin === 'null' + const requestOriginatesFromTheDesktopApp = requestOrigin?.startsWith('file://') + const requestOriginatesFromClipperForFirefox = requestOrigin?.startsWith('moz-extension://') + const requestOriginatesFromSelfHostedAppOnHttpPort = requestOrigin === 'http://localhost' + const requestOriginatesFromSelfHostedAppOnCustomPort = requestOrigin?.match(/http:\/\/localhost:\d+/) !== null + const requestOriginatesFromSelfHostedApp = + requestOriginatesFromSelfHostedAppOnHttpPort || requestOriginatesFromSelfHostedAppOnCustomPort + + const requestIsWhitelisted = + corsAllowedOrigins.length === 0 || + requstOriginIsNotFilled || + requestOriginatesFromTheDesktopApp || + requestOriginatesFromClipperForFirefox || + requestOriginatesFromSelfHostedApp + + if (requestIsWhitelisted) { + callback(null, [requestOrigin as string]) + } else { + if (corsAllowedOrigins.includes(requestOrigin)) { + callback(null, [requestOrigin]) + } else { + callback(new Error('Not allowed by CORS', { cause: 'origin not allowed' })) + } + } + }, + }), + ) app.use( robots({ UserAgent: '*', diff --git a/packages/files/bin/server.ts b/packages/files/bin/server.ts index b255a656c..eda20a951 100644 --- a/packages/files/bin/server.ts +++ b/packages/files/bin/server.ts @@ -65,9 +65,45 @@ void container.load().then((container) => { app.use(json({ limit: requestPayloadLimit })) app.use(raw({ limit: requestPayloadLimit, type: 'application/octet-stream' })) app.use(urlencoded({ extended: true, limit: requestPayloadLimit })) + + const corsAllowedOrigins = env.get('CORS_ALLOWED_ORIGINS', true) + ? env.get('CORS_ALLOWED_ORIGINS', true).split(',') + : [] app.use( cors({ - exposedHeaders: ['Content-Range', 'Accept-Ranges'], + credentials: true, + exposedHeaders: [ + 'Content-Range', + 'Accept-Ranges', + 'Access-Control-Allow-Credentials', + 'Access-Control-Allow-Origin', + ], + origin: (requestOrigin: string | undefined, callback: (err: Error | null, origin?: string[]) => void) => { + const requstOriginIsNotFilled = !requestOrigin || requestOrigin === 'null' + const requestOriginatesFromTheDesktopApp = requestOrigin?.startsWith('file://') + const requestOriginatesFromClipperForFirefox = requestOrigin?.startsWith('moz-extension://') + const requestOriginatesFromSelfHostedAppOnHttpPort = requestOrigin === 'http://localhost' + const requestOriginatesFromSelfHostedAppOnCustomPort = requestOrigin?.match(/http:\/\/localhost:\d+/) !== null + const requestOriginatesFromSelfHostedApp = + requestOriginatesFromSelfHostedAppOnHttpPort || requestOriginatesFromSelfHostedAppOnCustomPort + + const requestIsWhitelisted = + corsAllowedOrigins.length === 0 || + requstOriginIsNotFilled || + requestOriginatesFromTheDesktopApp || + requestOriginatesFromClipperForFirefox || + requestOriginatesFromSelfHostedApp + + if (requestIsWhitelisted) { + callback(null, [requestOrigin as string]) + } else { + if (corsAllowedOrigins.includes(requestOrigin)) { + callback(null, [requestOrigin]) + } else { + callback(new Error('Not allowed by CORS', { cause: 'origin not allowed' })) + } + } + }, }), ) app.use( diff --git a/packages/home-server/src/Server/HomeServer.ts b/packages/home-server/src/Server/HomeServer.ts index 8c20469c6..312e6b8c9 100644 --- a/packages/home-server/src/Server/HomeServer.ts +++ b/packages/home-server/src/Server/HomeServer.ts @@ -129,9 +129,40 @@ export class HomeServer implements HomeServerInterface { ], }), ) + const corsAllowedOrigins = env.get('CORS_ALLOWED_ORIGINS', true) + ? env.get('CORS_ALLOWED_ORIGINS', true).split(',') + : [] app.use( cors({ - exposedHeaders: ['Content-Range', 'Accept-Ranges'], + credentials: true, + exposedHeaders: ['Content-Range', 'Accept-Ranges', 'x-captcha-required'], + origin: (requestOrigin: string | undefined, callback: (err: Error | null, origin?: string[]) => void) => { + const requstOriginIsNotFilled = !requestOrigin || requestOrigin === 'null' + const requestOriginatesFromTheDesktopApp = requestOrigin?.startsWith('file://') + const requestOriginatesFromClipperForFirefox = requestOrigin?.startsWith('moz-extension://') + const requestOriginatesFromSelfHostedAppOnHttpPort = requestOrigin === 'http://localhost' + const requestOriginatesFromSelfHostedAppOnCustomPort = + requestOrigin?.match(/http:\/\/localhost:\d+/) !== null + const requestOriginatesFromSelfHostedApp = + requestOriginatesFromSelfHostedAppOnHttpPort || requestOriginatesFromSelfHostedAppOnCustomPort + + const requestIsWhitelisted = + corsAllowedOrigins.length === 0 || + requstOriginIsNotFilled || + requestOriginatesFromTheDesktopApp || + requestOriginatesFromClipperForFirefox || + requestOriginatesFromSelfHostedApp + + if (requestIsWhitelisted) { + callback(null, [requestOrigin as string]) + } else { + if (corsAllowedOrigins.includes(requestOrigin)) { + callback(null, [requestOrigin]) + } else { + callback(new Error('Not allowed by CORS', { cause: 'origin not allowed' })) + } + } + }, }), ) app.use(