From c7c05f0e8df8d6c4361bef34f0e9ba20af0b62c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89mile=20R=C3=A9?= Date: Thu, 9 Jul 2026 09:31:29 -0400 Subject: [PATCH] Harden subprocessor filters per review feedback MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Address the review comments on the subprocessors work: - Reject invalid category/country filter values in the Subprocessors resolver with an INVALID error instead of relying solely on transport coercion, so a malformed request fails fast and explicitly. - Use pgx.StrictNamedArgs in the new distinct facet queries so missing or extra SQL placeholders stay detectable, matching sibling queries. - Default a nil ThirdPartyFilter at the service boundary to avoid a nil dereference in the coredata list/count paths. - Expose the category group label as an aria heading for assistive tech. - Add the missing space in the Select "Selected:" story label. Signed-off-by: Émile Ré --- .../_components/SubprocessorCategorySection.tsx | 2 +- packages/ui/src/v2/Select/Select.stories.tsx | 1 + pkg/coredata/third_party.go | 4 ++-- pkg/server/api/trust/v1/trust_center_resolvers.go | 8 ++++++++ pkg/trust/third_party_service.go | 4 ++++ 5 files changed, 16 insertions(+), 3 deletions(-) diff --git a/apps/compliance-portal/src/pages/subprocessors/_components/SubprocessorCategorySection.tsx b/apps/compliance-portal/src/pages/subprocessors/_components/SubprocessorCategorySection.tsx index c7c7faa19..19da6c7f4 100644 --- a/apps/compliance-portal/src/pages/subprocessors/_components/SubprocessorCategorySection.tsx +++ b/apps/compliance-portal/src/pages/subprocessors/_components/SubprocessorCategorySection.tsx @@ -38,7 +38,7 @@ export function SubprocessorCategorySection({ category, subprocessors }: Subproc return (
- + {t(`categories.${category}.label`)} diff --git a/packages/ui/src/v2/Select/Select.stories.tsx b/packages/ui/src/v2/Select/Select.stories.tsx index 8dfb25476..3884aa54c 100644 --- a/packages/ui/src/v2/Select/Select.stories.tsx +++ b/packages/ui/src/v2/Select/Select.stories.tsx @@ -87,6 +87,7 @@ export function Controlled() {
Selected: + {" "} {value ?? "none"} diff --git a/pkg/coredata/third_party.go b/pkg/coredata/third_party.go index 8a333350b..4dd58a9a0 100644 --- a/pkg/coredata/third_party.go +++ b/pkg/coredata/third_party.go @@ -800,7 +800,7 @@ ORDER BY ` q = fmt.Sprintf(q, scope.SQLFragment()) - args := pgx.NamedArgs{"organization_id": organizationID} + args := pgx.StrictNamedArgs{"organization_id": organizationID} maps.Copy(args, scope.SQLArguments()) rows, err := conn.Query(ctx, q, args) @@ -836,7 +836,7 @@ ORDER BY ` q = fmt.Sprintf(q, scope.SQLFragment()) - args := pgx.NamedArgs{"organization_id": organizationID} + args := pgx.StrictNamedArgs{"organization_id": organizationID} maps.Copy(args, scope.SQLArguments()) rows, err := conn.Query(ctx, q, args) diff --git a/pkg/server/api/trust/v1/trust_center_resolvers.go b/pkg/server/api/trust/v1/trust_center_resolvers.go index 349333071..391a8c83f 100644 --- a/pkg/server/api/trust/v1/trust_center_resolvers.go +++ b/pkg/server/api/trust/v1/trust_center_resolvers.go @@ -819,6 +819,14 @@ func (r *trustCenterResolver) Subprocessors(ctx context.Context, obj *types.Trus country = filter.Country } + if category != nil && !category.IsValid() { + return nil, gqlutils.Invalidf(ctx, "invalid subprocessor category filter: %q", string(*category)) + } + + if country != nil && !country.IsValid() { + return nil, gqlutils.Invalidf(ctx, "invalid subprocessor country filter: %q", string(*country)) + } + showOnTrustCenter := true thirdPartyFilter := coredata.NewThirdPartyFilter(&showOnTrustCenter, nil, query, category, country) diff --git a/pkg/trust/third_party_service.go b/pkg/trust/third_party_service.go index 016eeb3b0..2c272d7b8 100644 --- a/pkg/trust/third_party_service.go +++ b/pkg/trust/third_party_service.go @@ -60,6 +60,10 @@ func (s ThirdPartyService) ListForOrganizationId( cursor *page.Cursor[coredata.ThirdPartyOrderField], filter *coredata.ThirdPartyFilter, ) (*page.Page[*coredata.ThirdParty, coredata.ThirdPartyOrderField], error) { + if filter == nil { + filter = coredata.NewThirdPartyFilter(nil, nil, nil, nil, nil) + } + var thirdParties coredata.ThirdParties err := s.svc.pg.WithConn(