From 74cf7828029f3b01e632c1da7bb0f1f942fe0f8a Mon Sep 17 00:00:00 2001 From: Sokratis Vidros Date: Fri, 18 Oct 2024 00:05:34 +0300 Subject: [PATCH] fix(application-generic): Allow self-signed certifications in development Reject self-signed and invalid certificates in Production environments but allow them in Development as it's common for developers to use self-signed certificates in local environments. --- .prettierignore | 2 +- .../execute-bridge-request.usecase.ts | 29 +++++++++++++++++++ libs/application-generic/src/utils/bridge.ts | 10 +++++++ 3 files changed, 40 insertions(+), 1 deletion(-) diff --git a/.prettierignore b/.prettierignore index 3e1abfa9bb3..3e794ada57b 100644 --- a/.prettierignore +++ b/.prettierignore @@ -3,4 +3,4 @@ package.json apps/api/src/metadata.ts /.nx/cache -/.nx/workspace-data \ No newline at end of file +/.nx/workspace-data diff --git a/libs/application-generic/src/usecases/execute-bridge-request/execute-bridge-request.usecase.ts b/libs/application-generic/src/usecases/execute-bridge-request/execute-bridge-request.usecase.ts index a43a78afa17..fa34647e3d2 100644 --- a/libs/application-generic/src/usecases/execute-bridge-request/execute-bridge-request.usecase.ts +++ b/libs/application-generic/src/usecases/execute-bridge-request/execute-bridge-request.usecase.ts @@ -11,6 +11,7 @@ import got, { HTTPError, MaxRedirectsError, OptionsOfTextResponseBody, + ParseError, ReadError, RequestError, TimeoutError, @@ -130,6 +131,11 @@ export class ExecuteBridgeRequest { afterResponse: command.afterResponse !== undefined ? [command.afterResponse] : [], }, + /* + * Reject self-signed and invalid certificates in Production environments but allow them in Development + * as it's common for developers to use self-signed certificates in local environments. + */ + rejectUnauthorized: true, }; const request = [PostActionEnum.EXECUTE, PostActionEnum.PREVIEW].includes( @@ -315,6 +321,18 @@ export class ExecuteBridgeRequest { }); } + if (error instanceof ParseError) { + Logger.error( + `Bridge URL response code is 2xx, but parsing body fails. \`${url}\``, + LOG_CONTEXT, + ); + throw new BadRequestException({ + message: + BRIDGE_EXECUTION_ERROR.MAXIMUM_REDIRECTS_EXCEEDED.message(url), + code: BRIDGE_EXECUTION_ERROR.MAXIMUM_REDIRECTS_EXCEEDED.code, + }); + } + if (body.code === TUNNEL_ERROR_CODE) { // Handle known tunnel errors const tunnelBody = body as TunnelResponseError; @@ -328,6 +346,17 @@ export class ExecuteBridgeRequest { }); } + if (error.code === 'DEPTH_ZERO_SELF_SIGNED_CERT') { + Logger.error( + `Bridge URL is uing a self-signed certificate that is not allowed for production environments. \`${url}\``, + LOG_CONTEXT, + ); + throw new BadRequestException({ + message: BRIDGE_EXECUTION_ERROR.SELF_SIGNED_CERTIFICATE.message(url), + code: BRIDGE_EXECUTION_ERROR.SELF_SIGNED_CERTIFICATE.code, + }); + } + if (error.response?.statusCode === 502) { /* * Tunnel was live, but the Bridge endpoint was down. diff --git a/libs/application-generic/src/utils/bridge.ts b/libs/application-generic/src/utils/bridge.ts index 4ea92066398..bdc745aba6f 100644 --- a/libs/application-generic/src/utils/bridge.ts +++ b/libs/application-generic/src/utils/bridge.ts @@ -68,6 +68,11 @@ export const BRIDGE_EXECUTION_ERROR = { code: 'BRIDGE_REQUEST_TIMEOUT', message: (url: string) => `Bridge request timeout for \`${url}\``, }, + BRIDGE_PARSE_ERROR: { + code: 'BRIDGE_PARSE_ERROR', + message: (url: string) => + `Bridge response for \`${url}\` is not valid JSON`, + }, UNSUPPORTED_PROTOCOL: { code: 'UNSUPPORTED_PROTOCOL', message: (url: string) => `Unsupported protocol for \`${url}\``, @@ -88,4 +93,9 @@ export const BRIDGE_EXECUTION_ERROR = { code: 'MAXIMUM_REDIRECTS_EXCEEDED', message: (url: string) => `Maximum redirects exceeded for \`${url}\``, }, + SELF_SIGNED_CERTIFICATE: { + code: 'SELF_SIGNED_CERTIFICATE', + message: (url: string) => + `Bridge Endpoint can't use a self signed certificate in production environments.`, + }, } satisfies Record string }>;