From bdb36d6be4dd9c344a7d6a8dcb7124b427db5fd2 Mon Sep 17 00:00:00 2001 From: Maidul Islam Date: Tue, 10 Jun 2025 02:59:31 -0400 Subject: [PATCH 1/6] disable caching for frontend assets This aims to fix the issue where it says ``` TypeError Cannot read properties of undefined (reading 'component') ``` by telling the browser to not cache any chunks --- backend/src/server/plugins/serve-ui.ts | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/backend/src/server/plugins/serve-ui.ts b/backend/src/server/plugins/serve-ui.ts index 22c097726..fc6b85d3d 100644 --- a/backend/src/server/plugins/serve-ui.ts +++ b/backend/src/server/plugins/serve-ui.ts @@ -57,9 +57,12 @@ export const registerServeUI = async ( reply.callNotFound(); return; } - // reference: https://github.com/fastify/fastify-static?tab=readme-ov-file#managing-cache-control-headers - // to avoid ui bundle skew on new deployment - return reply.sendFile("index.html", { maxAge: 0, immutable: false }); + + // This should help avoid caching any chunks (temp) + reply.header('Cache-Control', 'no-cache, no-store, must-revalidate'); + reply.header('Pragma', 'no-cache'); + return reply.sendFile("index.html"); + } }); } From 2d3c63e8b933efca9d1dff82b4998e5e1bf01ed7 Mon Sep 17 00:00:00 2001 From: Maidul Islam Date: Tue, 10 Jun 2025 03:10:16 -0400 Subject: [PATCH 2/6] fix lint --- backend/src/server/plugins/serve-ui.ts | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/backend/src/server/plugins/serve-ui.ts b/backend/src/server/plugins/serve-ui.ts index fc6b85d3d..9904c992f 100644 --- a/backend/src/server/plugins/serve-ui.ts +++ b/backend/src/server/plugins/serve-ui.ts @@ -57,12 +57,11 @@ export const registerServeUI = async ( reply.callNotFound(); return; } - + // This should help avoid caching any chunks (temp) - reply.header('Cache-Control', 'no-cache, no-store, must-revalidate'); - reply.header('Pragma', 'no-cache'); + reply.header("Cache-Control", "no-cache, no-store, must-revalidate"); + reply.header("Pragma", "no-cache"); return reply.sendFile("index.html"); - } }); } From 26bed22b949029778fc5ed8ea1c6a7ba3be4e4dd Mon Sep 17 00:00:00 2001 From: Maidul Islam Date: Tue, 10 Jun 2025 17:05:10 -0400 Subject: [PATCH 3/6] fix lint by adding void --- backend/src/server/plugins/serve-ui.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/backend/src/server/plugins/serve-ui.ts b/backend/src/server/plugins/serve-ui.ts index 9904c992f..b71451b6e 100644 --- a/backend/src/server/plugins/serve-ui.ts +++ b/backend/src/server/plugins/serve-ui.ts @@ -58,9 +58,10 @@ export const registerServeUI = async ( return; } - // This should help avoid caching any chunks (temp) - reply.header("Cache-Control", "no-cache, no-store, must-revalidate"); - reply.header("Pragma", "no-cache"); + // This should help avoid caching any chunks (temp fix) + void reply.header("Cache-Control", "no-cache, no-store, must-revalidate, private, max-age=0"); + void reply.header("Pragma", "no-cache"); + void reply.header("Expires", "0"); return reply.sendFile("index.html"); } }); From a6271a6187513bb97597d82729912aab00bcc9d3 Mon Sep 17 00:00:00 2001 From: Daniel Hougaard Date: Wed, 11 Jun 2025 01:45:38 +0400 Subject: [PATCH 4/6] fix: allow for empty target URLs --- backend/src/lib/gateway/gateway.ts | 47 +++++++++++++------ backend/src/lib/gateway/types.ts | 4 +- .../identity-kubernetes-auth-service.ts | 6 +-- cli/packages/gateway/connection.go | 27 +++++------ 4 files changed, 47 insertions(+), 37 deletions(-) diff --git a/backend/src/lib/gateway/gateway.ts b/backend/src/lib/gateway/gateway.ts index 179c29fc8..46481a049 100644 --- a/backend/src/lib/gateway/gateway.ts +++ b/backend/src/lib/gateway/gateway.ts @@ -149,8 +149,8 @@ const setupProxyServer = async ({ protocol = GatewayProxyProtocol.Tcp, httpsAgent }: { - targetHost: string; - targetPort: number; + targetHost?: string; + targetPort?: number; relayPort: number; relayHost: string; tlsOptions: TGatewayTlsOptions; @@ -183,27 +183,44 @@ const setupProxyServer = async ({ let command: string; if (protocol === GatewayProxyProtocol.Http) { - const targetUrl = `${targetHost}:${targetPort}`; // note(daniel): targetHost MUST include the scheme (https|http) - command = `FORWARD-HTTP ${targetUrl}`; - logger.debug(`Using HTTP proxy mode: ${command.trim()}`); + if (!targetHost && !targetPort) { + command = `FORWARD-HTTP`; + logger.debug(`Using HTTP proxy mode, no target URL provided [command=${command.trim()}]`); + } else { + if (!targetHost || targetPort === undefined) { + throw new BadRequestError({ + message: `Target host and port are required for HTTP proxy mode with custom target` + }); + } - // extract ca certificate from httpsAgent if present - if (httpsAgent && targetHost.startsWith("https://")) { - const agentOptions = httpsAgent.options; - if (agentOptions && agentOptions.ca) { - const caCert = Array.isArray(agentOptions.ca) ? agentOptions.ca.join("\n") : agentOptions.ca; - const caB64 = Buffer.from(caCert as string).toString("base64"); - command += ` ca=${caB64}`; + const targetUrl = `${targetHost}:${targetPort}`; // note(daniel): targetHost MUST include the scheme (https|http) + command = `FORWARD-HTTP ${targetUrl}`; + logger.debug(`Using HTTP proxy mode, custom target URL provided [command=${command.trim()}]`); - const rejectUnauthorized = agentOptions.rejectUnauthorized !== false; - command += ` verify=${rejectUnauthorized}`; + // extract ca certificate from httpsAgent if present + if (httpsAgent && targetHost.startsWith("https://")) { + const agentOptions = httpsAgent.options; + if (agentOptions && agentOptions.ca) { + const caCert = Array.isArray(agentOptions.ca) ? agentOptions.ca.join("\n") : agentOptions.ca; + const caB64 = Buffer.from(caCert as string).toString("base64"); + command += ` ca=${caB64}`; - logger.debug(`Using HTTP proxy mode [command=${command.trim()}]`); + const rejectUnauthorized = agentOptions.rejectUnauthorized !== false; + command += ` verify=${rejectUnauthorized}`; + + logger.debug(`Using HTTP proxy mode, custom target URL provided [command=${command.trim()}]`); + } } } command += "\n"; } else if (protocol === GatewayProxyProtocol.Tcp) { + if (!targetHost || !targetPort) { + throw new BadRequestError({ + message: `Target host and port are required for TCP proxy mode` + }); + } + // For TCP mode, send FORWARD-TCP with host:port command = `FORWARD-TCP ${targetHost}:${targetPort}\n`; logger.debug(`Using TCP proxy mode: ${command.trim()}`); diff --git a/backend/src/lib/gateway/types.ts b/backend/src/lib/gateway/types.ts index fdb13d256..8552fbf54 100644 --- a/backend/src/lib/gateway/types.ts +++ b/backend/src/lib/gateway/types.ts @@ -15,8 +15,8 @@ export enum GatewayHttpProxyActions { } export interface IGatewayProxyOptions { - targetHost: string; - targetPort: number; + targetHost?: string; + targetPort?: number; relayHost: string; relayPort: number; tlsOptions: TGatewayTlsOptions; diff --git a/backend/src/services/identity-kubernetes-auth/identity-kubernetes-auth-service.ts b/backend/src/services/identity-kubernetes-auth/identity-kubernetes-auth-service.ts index b599c4ff9..1f89745a9 100644 --- a/backend/src/services/identity-kubernetes-auth/identity-kubernetes-auth-service.ts +++ b/backend/src/services/identity-kubernetes-auth/identity-kubernetes-auth-service.ts @@ -72,8 +72,8 @@ export const identityKubernetesAuthServiceFactory = ({ const $gatewayProxyWrapper = async ( inputs: { gatewayId: string; - targetHost: string; - targetPort: number; + targetHost?: string; + targetPort?: number; caCert?: string; reviewTokenThroughGateway: boolean; }, @@ -286,8 +286,6 @@ export const identityKubernetesAuthServiceFactory = ({ data = await $gatewayProxyWrapper( { gatewayId: identityKubernetesAuth.gatewayId, - targetHost: `/`, // note(daniel): the targetURL will be constructed as `/:0`, which the gateway will handle as a special case, by replacing the /:0, with the internal kubernetes base URL (only when the action header is set to `GatewayHttpProxyActions.UseGatewayK8sServiceAccount`) - targetPort: 0, reviewTokenThroughGateway: true }, tokenReviewCallbackThroughGateway diff --git a/cli/packages/gateway/connection.go b/cli/packages/gateway/connection.go index 460956d3e..980137374 100644 --- a/cli/packages/gateway/connection.go +++ b/cli/packages/gateway/connection.go @@ -108,19 +108,17 @@ func handleStream(stream quic.Stream, quicConn quic.Connection) { return case "FORWARD-HTTP": + targetURL := "" argParts := bytes.Split(args, []byte(" ")) - if len(argParts) == 0 { - log.Error().Msg("FORWARD-HTTP requires target URL") - return - } - targetURL := string(argParts[0]) - - // ? note(daniel): special case: if the target URL is "/:0", we don't validate it. - // ? the reason for this is because we want to be able to send requests to the gateway without knowing the actual target URL, and instead let the gateway construct the target URL. - if targetURL != "/:0" && !isValidURL(targetURL) { - log.Error().Msgf("Invalid target URL: %s", targetURL) - return + if len(argParts) == 0 || len(argParts[0]) == 0 { + log.Warn().Msg("FORWARD-HTTP used without a target URL.") + } else { + targetURL = string(argParts[0]) + if !isValidURL(targetURL) { + log.Error().Msgf("Invalid target URL: %s", targetURL) + return + } } // Parse optional parameters @@ -208,8 +206,7 @@ func handleHTTPProxy(stream quic.Stream, reader *bufio.Reader, targetURL string, } req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", string(token))) log.Info().Msgf("Injected gateway k8s SA auth token in request to %s", targetURL) - } else if actionHeader == HttpProxyActionUseGatewayK8sServiceAccount { - + } else if actionHeader == HttpProxyActionUseGatewayK8sServiceAccount { // will work without a target URL set // set the ca cert to the pod's k8s service account ca cert: caCert, err := os.ReadFile(KUBERNETES_SERVICE_ACCOUNT_CA_CERT_PATH) if err != nil { @@ -218,9 +215,7 @@ func handleHTTPProxy(stream quic.Stream, reader *bufio.Reader, targetURL string, } caCertPool := x509.NewCertPool() - appendSuccess := caCertPool.AppendCertsFromPEM(caCert) - - if !appendSuccess { + if ok := caCertPool.AppendCertsFromPEM(caCert); !ok { stream.Write([]byte(buildHttpInternalServerError("failed to parse k8s sa ca cert"))) continue } From 160e2b773bfd2cdfc87ffdc53eae5510ca389a21 Mon Sep 17 00:00:00 2001 From: carlosmonastyrski Date: Tue, 10 Jun 2025 19:02:02 -0300 Subject: [PATCH 5/6] feat(pit): improve commit changes condition as some old versions can be zero --- .../folder-commit-changes/folder-commit-changes-dal.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/backend/src/services/folder-commit-changes/folder-commit-changes-dal.ts b/backend/src/services/folder-commit-changes/folder-commit-changes-dal.ts index b2d74c5af..2c30c5bcf 100644 --- a/backend/src/services/folder-commit-changes/folder-commit-changes-dal.ts +++ b/backend/src/services/folder-commit-changes/folder-commit-changes-dal.ts @@ -120,7 +120,7 @@ export const folderCommitChangesDALFactory = (db: TDbClient) => { return docs.map((doc) => { // Determine if this is a secret or folder change based on populated fields - if (doc.secretKey && doc.secretVersion && doc.secretId) { + if (doc.secretKey && doc.secretVersion !== null && doc.secretId) { return { ...doc, resourceType: "secret", @@ -168,7 +168,7 @@ export const folderCommitChangesDALFactory = (db: TDbClient) => { ); return docs - .filter((doc) => doc.secretKey && doc.secretVersion && doc.secretId) + .filter((doc) => doc.secretKey && doc.secretVersion !== null && doc.secretId) .map( (doc): SecretCommitChange => ({ ...doc, @@ -209,7 +209,7 @@ export const folderCommitChangesDALFactory = (db: TDbClient) => { ); return docs - .filter((doc) => doc.folderName && doc.folderVersion && doc.folderChangeId) + .filter((doc) => doc.folderName && doc.folderVersion !== null && doc.folderChangeId) .map( (doc): FolderCommitChange => ({ ...doc, From c363f485eb893f432dd8b12d9960c8b4051f018f Mon Sep 17 00:00:00 2001 From: Akhil Mohan Date: Wed, 11 Jun 2025 08:52:35 +0530 Subject: [PATCH 6/6] Update aws-iam.mdx --- docs/documentation/platform/dynamic-secrets/aws-iam.mdx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/documentation/platform/dynamic-secrets/aws-iam.mdx b/docs/documentation/platform/dynamic-secrets/aws-iam.mdx index aa10e4029..a02d80a5c 100644 --- a/docs/documentation/platform/dynamic-secrets/aws-iam.mdx +++ b/docs/documentation/platform/dynamic-secrets/aws-iam.mdx @@ -32,7 +32,8 @@ Infisical needs an initial AWS IAM user with the required permissions to create "iam:ListUserPolicies", "iam:PutUserPolicy", "iam:AddUserToGroup", - "iam:RemoveUserFromGroup" + "iam:RemoveUserFromGroup", + "iam:TagUser" ], "Resource": ["*"] }