diff --git a/CHANGELOG.md b/CHANGELOG.md index b2728c58c..eada6e4b7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ * Correctly handle optional `X-Okapi-token` request header. Refs UIU-2977. * Fix bug with Edit form Expand/collapse all shortcuts not working. Refs UIU-2959. * Update patron groups retrieval in user search to hold `maxUnpagedResourceCount`. Refs UIU-2973. +* Update resourceData and queryParams in `UserSearchContainer.js` to escape special characters in tags filter. Refs. UIU-2995. ## [10.0.3](https://github.com/folio-org/ui-users/tree/v10.0.3) (2023-10-23) [Full Changelog](https://github.com/folio-org/ui-users/compare/v10.0.1...v10.0.3) diff --git a/src/routes/UserSearchContainer.js b/src/routes/UserSearchContainer.js index c167a6b29..2019a33e4 100644 --- a/src/routes/UserSearchContainer.js +++ b/src/routes/UserSearchContainer.js @@ -1,6 +1,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import { + cloneDeep, get, template, } from 'lodash'; @@ -34,8 +35,39 @@ const searchFields = [ ]; const compileQuery = template(`(${searchFields.join(' or ')})`, { interpolate: /%{([\s\S]+?)}/g }); +/* + Some of the special characters that are allowed while creating a tag are "", \, *, ? + These special characters cause CQL exceptions while searching the user records, which are + assigned with such tags. + This function "escapeSpecialCharactersInTagFilters" intends to escape the special characters + in filters of type "Tags" + Ref: https://issues.folio.org/browse/UIU-2995 +*/ + +const escapeSpecialCharactersInTagFilters = (queryParams, resourceData) => { + const newResourceData = cloneDeep(resourceData); + let escapedFilters; + + if (resourceData.query.filters) { + const filterArr = resourceData.query.filters.split(','); + escapedFilters = filterArr.map(f => { + let newF = f; + if (f.startsWith('tags.')) { + newF = f.replace(/["^*?\\]/g, c => '\\' + c); + } + return newF; + }); + escapedFilters = escapedFilters.join(','); + + newResourceData.query.filters = escapedFilters; + queryParams.filters = escapedFilters; + } + return newResourceData; +}; + export function buildQuery(queryParams, pathComponents, resourceData, logger, props) { const customFilterConfig = buildFilterConfig(queryParams.filters); + const newResourceData = escapeSpecialCharactersInTagFilters(queryParams, resourceData); return makeQueryFunction( 'cql.allRecords=1', @@ -53,7 +85,7 @@ export function buildQuery(queryParams, pathComponents, resourceData, logger, pr }, [...filterConfig, ...customFilterConfig], 2, - )(queryParams, pathComponents, resourceData, logger, props); + )(queryParams, pathComponents, newResourceData, logger, props); } class UserSearchContainer extends React.Component {