fix(dashboard): honor portal endpoint filters without widening scope - #2770
Conversation
keep query endpointId as an allowlist intersection on portal list/count/retry paths, return typed empty pages when the intersection is empty, and cover the contract in unit plus portal integration tests. also clear unused-var lint in event deliveries filters.
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Want higher recall? High effort reviews run extra passes and find more bugs. A team admin can switch effort levels in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 2814dc0. Configure here.
| } | ||
|
|
||
| endpointIDs, innerErr := h.getEndpoints(r, portalLink) | ||
| endpointIDs, innerErr := h.portalScopedEndpointIDs(r, portalLink, data.Filter.EndpointIDs) |
There was a problem hiding this comment.
Batch replay ownership filter coupling
Medium Severity
portalScopedEndpointIDs is correctly used for the query filter, but the same intersected result is also assigned to ownedEndpointIDs. Ownership checks need the full portal allowlist, so a portal batch replay filtered to one owned endpoint can skip fan-out events that also target other owned endpoints and count them as failures.
Reviewed by Cursor Bugbot for commit 2814dc0. Configure here.
* redesign dashboard * update convoy clean design * finish Clean UI cleanup across dashboard surfaces Align remaining shared components, billing, auth, filters, and dialogs with Clean tokens and native pill CTAs. Co-authored-by: Cursor <cursoragent@cursor.com> * honor portal endpoint filters within allowed scope Intersect requested endpoint IDs with the portal link allowlist so delivery list and count queries can filter without widening token access. Co-authored-by: Cursor <cursoragent@cursor.com> * update billing session * fix(dashboard): honor portal endpoint filters without widening scope (#2770) keep query endpointId as an allowlist intersection on portal list/count/retry paths, return typed empty pages when the intersection is empty, and cover the contract in unit plus portal integration tests. also clear unused-var lint in event deliveries filters. * feat(controlplane): forward optional referral_code on sh checkout and trial (#2769) * feat(billing): forward optional referral_code on sh checkout and trial pass the trimmed referral_code through to overwatch guest checkout and self-hosted trial start so attribution can stick at signup. * feat(billing): wire referral share ui and fix portal batch replay ownership show the sh refer block from organisation share_url, accept optional referral_code on checkout and trial, and keep OwnedEndpointIDs on the full portal allowlist when filtering batch replay by endpointId. * fix(billing): reload referral share after activation and harden portal list errors call loadReferralShare from pollUntilBillingActive with a stale-response token, and clear portal subscription loading failures without showing stale rows or a false empty state. --------- Co-authored-by: Smart Mekiliuwa <st.nonso@gmail.com> Co-authored-by: Cursor <cursoragent@cursor.com>


Summary
endpointIdfilters now intersect with the portal allowlist on event delivery list/count/batch-retry and event list/count/batch-replay paths (sharedportalScopedEndpointIDshelper).[]stringcontent payload.Test plan
go test ./api/handlers/ -run TestFilterAllowedEndpointIDsgo test ./api/ -run 'TestPortalEventIntegrationTestSuite/(Test_GetEventDeliveriesPaged|Test_GetEventsPaged|Test_BatchRetry|Test_CountAffected)'eslintonevent-deliveries.component.tsNote
Medium Risk
Changes portal authorization scoping for list/count/batch APIs; incorrect intersection logic could leak or hide data, though behavior is fail-closed with new integration coverage.
Overview
Portal API list/count/batch paths now resolve endpoints through
portalScopedEndpointIDs, which intersects queryendpointIdfilters with the portal allowlist instead of ignoring or inconsistently applying filters.Events (paged list, batch-replay count, batch replay) and event deliveries (paged list, count, batch retry) all use this helper. When nothing matches, responses return typed empty payloads (e.g. empty event/delivery arrays) rather than mis-typed
[]stringcontent.Unit tests cover
filterAllowedEndpointIDs; portal integration tests assert unfiltered owner scope, narrowing to an allowed endpoint, and empty results for out-of-scope endpoint filters. The dashboard event-deliveries screen sharesqueryParamsForCountso totals and group batch-retry use the same filter surface as list queries (lint fix included).Reviewed by Cursor Bugbot for commit 2814dc0. Bugbot is set up for automated code reviews on this repo. Configure here.