Browse Source

fix(issues): Encode release version in urls (#58263)

Encode the release version in a few urls. we allow releases starting
with `#` which if not escaped is a different url completely.


the component was loading a list of releases since the url didn't encode
the version
Scott Cooper 1 year ago
parent
commit
45cbab87b1

+ 6 - 6
static/app/components/avatar/avatarList.tsx

@@ -9,7 +9,6 @@ import {AvatarUser, Team} from 'sentry/types';
 type UserAvatarProps = React.ComponentProps<typeof UserAvatar>;
 
 type Props = {
-  users: AvatarUser[];
   avatarSize?: number;
   className?: string;
   maxVisibleAvatars?: number;
@@ -17,6 +16,7 @@ type Props = {
   teams?: Team[];
   tooltipOptions?: UserAvatarProps['tooltipOptions'];
   typeAvatars?: string;
+  users?: AvatarUser[];
 };
 
 function AvatarList({
@@ -25,16 +25,16 @@ function AvatarList({
   typeAvatars = 'users',
   tooltipOptions = {},
   className,
-  users,
-  teams,
+  users = [],
+  teams = [],
   renderTooltip,
 }: Props) {
-  const numTeams = teams ? teams.length : 0;
+  const numTeams = teams.length;
   const numVisibleTeams = maxVisibleAvatars - numTeams > 0 ? numTeams : maxVisibleAvatars;
   const maxVisibleUsers =
     maxVisibleAvatars - numVisibleTeams > 0 ? maxVisibleAvatars - numVisibleTeams : 0;
   // Reverse the order since css flex-reverse is used to display the avatars
-  const visibleTeamAvatars = teams?.slice(0, numVisibleTeams).reverse();
+  const visibleTeamAvatars = teams.slice(0, numVisibleTeams).reverse();
   const visibleUserAvatars = users.slice(0, maxVisibleUsers).reverse();
   const numCollapsedAvatars = users.length - visibleUserAvatars.length;
 
@@ -62,7 +62,7 @@ function AvatarList({
           hasTooltip
         />
       ))}
-      {visibleTeamAvatars?.map(team => (
+      {visibleTeamAvatars.map(team => (
         <StyledTeamAvatar
           key={`${team.id}-${team.name}`}
           team={team}

+ 9 - 4
static/app/components/charts/releaseSeries.tsx

@@ -17,6 +17,7 @@ import {getFormattedDate, getUtcDateString} from 'sentry/utils/dates';
 import {formatVersion} from 'sentry/utils/formatters';
 import parseLinkHeader from 'sentry/utils/parseLinkHeader';
 import withApi from 'sentry/utils/withApi';
+import {normalizeUrl} from 'sentry/utils/withDomainRequired';
 import withOrganization from 'sentry/utils/withOrganization';
 // eslint-disable-next-line no-restricted-imports
 import withSentryRouter from 'sentry/utils/withSentryRouter';
@@ -254,10 +255,14 @@ class ReleaseSeries extends Component<ReleaseSeriesProps, State> {
         name: formatVersion(release.version, true),
         value: formatVersion(release.version, true),
         onClick: () => {
-          router.push({
-            pathname: `/organizations/${organization.slug}/releases/${release.version}/`,
-            query,
-          });
+          router.push(
+            normalizeUrl({
+              pathname: `/organizations/${
+                organization.slug
+              }/releases/${encodeURIComponent(release.version)}/`,
+              query,
+            })
+          );
         },
         label: {
           formatter: () => formatVersion(release.version, true),

+ 3 - 1
static/app/views/discover/table/quickContext/quickContextHovercard.spec.tsx

@@ -136,7 +136,9 @@ describe('Quick Context', function () {
 
     it('Renders release header with copy button', async () => {
       MockApiClient.addMockResponse({
-        url: '/organizations/org-slug/releases/backend@22.10.0+aaf33944f93dc8fa4234ca046a8d88fb1dccfb76/',
+        url: `/organizations/org-slug/releases/${encodeURIComponent(
+          'backend@22.10.0+aaf33944f93dc8fa4234ca046a8d88fb1dccfb76'
+        )}/`,
         body: TestStubs.Release({
           id: '1',
           shortVersion: 'sentry-android-shop@1.2.0',

+ 3 - 1
static/app/views/discover/table/quickContext/releaseContext.spec.tsx

@@ -36,7 +36,9 @@ const renderReleaseContext = () => {
 describe('Quick Context Content Release Column', function () {
   beforeEach(() => {
     MockApiClient.addMockResponse({
-      url: '/organizations/org-slug/releases/backend@22.10.0+aaf33944f93dc8fa4234ca046a8d88fb1dccfb76/',
+      url: `/organizations/org-slug/releases/${encodeURIComponent(
+        'backend@22.10.0+aaf33944f93dc8fa4234ca046a8d88fb1dccfb76'
+      )}/`,
       body: mockedReleaseWithHealth,
     });
   });

+ 5 - 1
static/app/views/discover/table/quickContext/releaseContext.tsx

@@ -28,7 +28,11 @@ import {BaseContextProps, ContextType, tenSecondInMs} from './utils';
 function ReleaseContext(props: BaseContextProps) {
   const {dataRow, organization} = props;
   const {isLoading, isError, data} = useApiQuery<ReleaseWithHealth>(
-    [`/organizations/${organization.slug}/releases/${dataRow.release}/`],
+    [
+      `/organizations/${organization.slug}/releases/${encodeURIComponent(
+        dataRow.release
+      )}/`,
+    ],
     {
       staleTime: tenSecondInMs,
     }