Skip to content

Commit 48e84cc

Browse files
committed
fix: ensure correct encoding of tag filters
This makes sure the global tag filters are correctly URI encoded, only a single encode pass. Previously they could be double encoded which made the API always return no systems.
1 parent a48b45b commit 48e84cc

2 files changed

Lines changed: 31 additions & 7 deletions

File tree

src/Utilities/Helpers.js

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -703,18 +703,40 @@ export const isRHAdvisory = (name) => /^(RHEA|RHBA|RHSA)/.test(name);
703703
export const buildTagString = (tag) =>
704704
`${tag.category}/${tag.values?.tagKey}=${tag.value?.tagValue}`;
705705

706+
/**
707+
* Build one `tags=…` query fragment with a single URI encode pass. Inventory / insights-chrome
708+
* sometimes passes tag strings that are already `tags=` segments or percent-encoded and encoding
709+
* again turns `%2F` into `%252F` and breaks the patch API.
710+
*/
711+
const buildTagsQuerySegment = (rawTagInput) => {
712+
if (rawTagInput === undefined || rawTagInput === null) {
713+
return '';
714+
}
715+
let inner = String(rawTagInput).trim();
716+
if (inner.startsWith('tags=')) {
717+
inner = inner.slice(5);
718+
}
719+
let decoded = inner;
720+
try {
721+
decoded = decodeURIComponent(inner);
722+
} catch {
723+
decoded = inner;
724+
}
725+
return `tags=${encodeURIComponent(decoded)}`;
726+
};
727+
706728
export const mapGlobalFilters = (tags, workloads = {}) => {
707729
let tagsInUrlFormat = [];
708730
tags &&
709731
tags.forEach((tag, index) => {
710732
let tagGruop = tag;
711-
if (typeof tag === 'object') {
712-
tagGruop = tag?.values.map(
713-
(value) => `tags=${encodeURIComponent(`${tag.category}/${value.tagKey}=${value.value}`)}`,
733+
if (typeof tag === 'object' && tag !== null) {
734+
tagGruop = tag?.values.map((value) =>
735+
buildTagsQuerySegment(`${tag.category}/${value.tagKey}=${value.value}`),
714736
);
715737
tagsInUrlFormat[index] = (Array.isArray(tagGruop) && flatten(tagGruop)) || tagGruop;
716-
} else {
717-
tagsInUrlFormat[index] = `tags=${encodeURIComponent(tagGruop)}`;
738+
} else if (typeof tag === 'string') {
739+
tagsInUrlFormat[index] = buildTagsQuerySegment(tagGruop);
718740
}
719741
});
720742

@@ -730,7 +752,9 @@ export const mapGlobalFilters = (tags, workloads = {}) => {
730752
}),
731753
};
732754

733-
tagsInUrlFormat && (globalFilterConfig.selectedTags = tagsInUrlFormat);
755+
if (tagsInUrlFormat?.length) {
756+
globalFilterConfig.selectedTags = flatten(tagsInUrlFormat).filter(Boolean);
757+
}
734758

735759
return globalFilterConfig;
736760
};

src/Utilities/hooks/Hooks.test.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ describe('Custom hooks tests', () => {
215215
os: 'RHEL 8.8',
216216
},
217217
filters: params.filters,
218-
selectedTags: ['tags=owner%2Fteam%3Dplatform', ['tags=env%2Fstage%3Dprod']],
218+
selectedTags: ['tags=owner%2Fteam%3Dplatform', 'tags=env%2Fstage%3Dprod'],
219219
systemProfile: { ansible: { controller_version: 'not_nil' } },
220220
});
221221
expect(applyInventorySnapshot.mock.invocationCallOrder[0]).toBeLessThan(

0 commit comments

Comments
 (0)