mirror of
https://github.com/formbricks/formbricks.git
synced 2026-05-06 19:35:53 -05:00
fix: harden FeedbackRecords Envoy auth routing
This commit is contained in:
@@ -213,14 +213,17 @@ describe("FeedbackRecords envoy auth route", () => {
|
||||
});
|
||||
|
||||
const response = await GET(
|
||||
createRequest("http://localhost/api/envoy-auth/feedback-records/v1/feedback-records", {
|
||||
createRequest(
|
||||
`http://localhost/api/envoy-auth/feedback-records/v1/feedback-records?tenant_id=${feedbackRecordDirectoryId}`,
|
||||
{
|
||||
headers: {
|
||||
method: "GET",
|
||||
path: `/v1/feedback-records?tenant_id=${feedbackRecordDirectoryId}`,
|
||||
authorization: "Bearer header.payload.signature",
|
||||
cookie: "next-auth.session-token=still-present",
|
||||
},
|
||||
})
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
expect(response.status).toBe(401);
|
||||
@@ -237,13 +240,16 @@ describe("FeedbackRecords envoy auth route", () => {
|
||||
});
|
||||
|
||||
const response = await GET(
|
||||
createRequest("http://localhost/api/envoy-auth/feedback-records/v1/feedback-records", {
|
||||
createRequest(
|
||||
`http://localhost/api/envoy-auth/feedback-records/v1/feedback-records?tenant_id=${feedbackRecordDirectoryId}`,
|
||||
{
|
||||
headers: {
|
||||
method: "GET",
|
||||
path: `/v1/feedback-records?tenant_id=${feedbackRecordDirectoryId}`,
|
||||
authorization: "Bearer header.payload.signature",
|
||||
},
|
||||
})
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
expect(response.status).toBe(403);
|
||||
|
||||
@@ -20,6 +20,7 @@ import { getFeedbackRecordTenant } from "@/modules/hub/service";
|
||||
|
||||
const FEEDBACK_RECORDS_V3_PREFIX = "/api/v3/feedbackRecords";
|
||||
const FEEDBACK_RECORDS_SDK_PREFIX = "/v1/feedback-records";
|
||||
const FEEDBACK_RECORDS_AUTH_PREFIX = "/api/envoy-auth/feedback-records";
|
||||
const ZFeedbackRecordId = z.string().uuid();
|
||||
const HEADERS_TO_REMOVE_ON_ALLOW = "x-api-key,cookie";
|
||||
|
||||
@@ -88,15 +89,23 @@ const parseOriginalRequestMetadata = (
|
||||
request: NextRequest
|
||||
): { method: string; url: URL } | { errorResponse: Response } => {
|
||||
const originalMethod = request.headers.get("method")?.toUpperCase();
|
||||
const originalPath = request.headers.get("path");
|
||||
|
||||
if (!originalMethod || !originalPath) {
|
||||
if (!originalMethod) {
|
||||
return {
|
||||
errorResponse: buildStatusResponse(400, "Missing original request metadata"),
|
||||
};
|
||||
}
|
||||
|
||||
if (!request.nextUrl.pathname.startsWith(FEEDBACK_RECORDS_AUTH_PREFIX)) {
|
||||
return {
|
||||
errorResponse: buildStatusResponse(400, "Invalid FeedbackRecords auth request path"),
|
||||
};
|
||||
}
|
||||
|
||||
try {
|
||||
const originalPathname = request.nextUrl.pathname.slice(FEEDBACK_RECORDS_AUTH_PREFIX.length) || "/";
|
||||
const originalPath = `${originalPathname}${request.nextUrl.search}`;
|
||||
|
||||
return {
|
||||
method: originalMethod,
|
||||
url: new URL(originalPath, "http://feedback-records-gateway.local"),
|
||||
|
||||
@@ -157,7 +157,7 @@ If `namespaceOverride` is provided, it will be used; otherwise, it defaults to `
|
||||
{{- end }}
|
||||
|
||||
{{- define "formbricks.hubApiKey" -}}
|
||||
{{- $secret := (lookup "v1" "Secret" .Release.Namespace (include "formbricks.appSecretName" .)) }}
|
||||
{{- $secret := (lookup "v1" "Secret" .Release.Namespace (include "formbricks.hubSecretName" .)) }}
|
||||
{{- if and $secret (index $secret.data "HUB_API_KEY") }}
|
||||
{{- index $secret.data "HUB_API_KEY" | b64dec -}}
|
||||
{{- else }}
|
||||
|
||||
@@ -7,9 +7,9 @@
|
||||
{{- $gatewayClassName := include "formbricks.envoy.gatewayClassName" . -}}
|
||||
{{- $proxyName := include "formbricks.envoy.proxyName" . -}}
|
||||
{{- $proxyServiceName := include "formbricks.envoy.proxyServiceName" . -}}
|
||||
{{- $appSecretName := include "formbricks.appSecretName" . -}}
|
||||
{{- $appServiceName := include "formbricks.name" . -}}
|
||||
{{- $hubServiceName := include "formbricks.hubname" . -}}
|
||||
{{- $hubSecretName := include "formbricks.hubSecretName" . -}}
|
||||
---
|
||||
apiVersion: gateway.envoyproxy.io/v1alpha1
|
||||
kind: EnvoyProxy
|
||||
@@ -303,7 +303,7 @@ spec:
|
||||
overwrite: true
|
||||
credential:
|
||||
valueRef:
|
||||
name: {{ $hubSecretName }}
|
||||
name: {{ $appSecretName }}
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1
|
||||
kind: HTTPRoute
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
{{- $redisPassword := include "formbricks.redisPassword" . }}
|
||||
{{- $webappUrl := required "formbricks.webappUrl is required. Set it to your Formbricks instance URL (e.g., https://formbricks.example.com)" .Values.formbricks.webappUrl }}
|
||||
{{- $hubApiKey := include "formbricks.hubApiKey" . }}
|
||||
{{- $includeHubApiKeyInAppSecret := or (not .Values.hub.existingSecret) (eq .Values.hub.existingSecret (include "formbricks.appSecretName" .)) }}
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
@@ -30,10 +29,8 @@ data:
|
||||
{{- else }}
|
||||
DATABASE_URL: {{ .Values.postgresql.externalDatabaseUrl | b64enc }}
|
||||
{{- end }}
|
||||
{{- if $includeHubApiKeyInAppSecret }}
|
||||
HUB_API_KEY: {{ $hubApiKey | b64enc }}
|
||||
credential: {{ printf "Bearer %s" $hubApiKey | b64enc }}
|
||||
{{- end }}
|
||||
CRON_SECRET: {{ include "formbricks.cronSecret" . | b64enc }}
|
||||
ENCRYPTION_KEY: {{ include "formbricks.encryptionKey" . | b64enc }}
|
||||
NEXTAUTH_SECRET: {{ include "formbricks.nextAuthSecret" . | b64enc }}
|
||||
|
||||
@@ -573,6 +573,7 @@ hub:
|
||||
# Optional override for the secret Hub reads from.
|
||||
# Defaults to the generated app secret (<release>-app-secrets), which contains DATABASE_URL and HUB_API_KEY.
|
||||
# If you set this, the custom secret must provide DATABASE_URL and HUB_API_KEY.
|
||||
# The app secret still needs HUB_API_KEY as well because the web app talks to Hub directly.
|
||||
existingSecret: ""
|
||||
|
||||
# Optional env vars (non-secret). Use existingSecret for secret values such as DATABASE_URL and HUB_API_KEY.
|
||||
|
||||
Reference in New Issue
Block a user