Skip to content

Commit

Permalink
fix(filters): IN_CONTAINS should be sanitized when used with html
Browse files Browse the repository at this point in the history
- when using `useFormatterOuputToFilter` from column `params`, we need to make sure that it's sanitized without html tags when filtering
- also remove spaces from the regex check since we want to split only on comma not spaces, the extra spaces are removed by the trim after the split is executed
  • Loading branch information
ghiscoding committed Jul 26, 2021
1 parent 3ca8895 commit 961d8fd
Show file tree
Hide file tree
Showing 4 changed files with 12 additions and 7 deletions.
Expand Up @@ -188,8 +188,11 @@ describe('filterUtilities', () => {
});

it('should return True when value1 is "IN_CONTAINS" value2 collection even if there is extra spaces in the string', () => {
const output = testFilterCondition('IN_CONTAINS', 'Task2, Task3 ', ['Task2', 'Task3']);
expect(output).toBeTruthy();
const output1 = testFilterCondition('IN_CONTAINS', 'Task2, Task3 , Task4', ['Task3']);
const output2 = testFilterCondition('IN_CONTAINS', 'Task2, Task3 , Task4', ['Task4']);

expect(output1).toBeTruthy();
expect(output2).toBeTruthy();
});

it('should return False when value1 is not "IN_CONTAINS" value2 collection', () => {
Expand Down
4 changes: 2 additions & 2 deletions packages/common/src/filter-conditions/filterUtilities.ts
Expand Up @@ -75,13 +75,13 @@ export const testFilterCondition = (operator: OperatorString, value1: any, value
return ((value2 && Array.isArray(value2 as string[])) ? (!value2.includes(value1)) : false);
case 'IN_CONTAINS':
if (value2 && Array.isArray(value2) && typeof value1 === 'string') {
return value2.some(item => value1.split(/[\s,]+/).map(val => (val.trim())).includes(item));
return value2.some(item => value1.split(/[,]+/).map(val => (val.trim())).includes(item));
}
return false;
case 'NIN_CONTAINS':
case 'NOT_IN_CONTAINS':
if (value2 && Array.isArray(value2) && typeof value1 === 'string') {
return !value2.some(item => value1.split(/[\s,]+/).map(val => (val.trim())).includes(item));
return !value2.some(item => value1.split(/[,]+/).map(val => (val.trim())).includes(item));
}
return false;
case 'IN_COLLECTION':
Expand Down
3 changes: 2 additions & 1 deletion packages/common/src/formatters/arrayObjectToCsvFormatter.ts
Expand Up @@ -9,6 +9,7 @@ import { Formatter } from './../interfaces/index';
export const arrayObjectToCsvFormatter: Formatter = (_row, _cell, value, columnDef, dataContext) => {
const columnParams = columnDef && columnDef.params || {};
const propertyNames = columnParams.propertyNames;
const isIncludingTitle = columnParams?.includeTitle ?? true;
let parentObjectKeyName: string = columnParams.dataContextProperty;
if (!parentObjectKeyName) {
parentObjectKeyName = columnDef && columnDef.field && columnDef.field.split('.')[0]; // e.g. "users.roles" would be "users"
Expand Down Expand Up @@ -39,7 +40,7 @@ export const arrayObjectToCsvFormatter: Formatter = (_row, _cell, value, columnD

// finally join all the output strings by CSV (e.g.: 'John Doe, Jane Doe')
const output = outputStrings.join(', ');
return `<span title="${output}">${output}</span>`;
return isIncludingTitle ? `<span title="${output}">${output}</span>` : output;
}
}
return value;
Expand Down
5 changes: 3 additions & 2 deletions packages/common/src/services/filter.service.ts
Expand Up @@ -30,7 +30,7 @@ import {
SlickNamespace,
} from './../interfaces/index';
import { BackendUtilityService } from './backendUtility.service';
import { deepCopy, getDescendantProperty, mapOperatorByFieldType } from './utilities';
import { deepCopy, getDescendantProperty, mapOperatorByFieldType, sanitizeHtmlToText } from './utilities';
import { PubSubService } from '../services/pubSub.service';
import { SharedService } from './shared.service';
import { RxJsFacade, Subject } from './rxjsFacade';
Expand Down Expand Up @@ -495,7 +495,8 @@ export class FilterService {
const dataView = grid.getData() as SlickDataView;
const idPropName = this._gridOptions.datasetIdPropertyName || 'id';
const rowIndex = (dataView && typeof dataView.getIdxById === 'function') ? dataView.getIdxById(item[idPropName]) : 0;
cellValue = (columnDef && typeof columnDef.formatter === 'function') ? columnDef.formatter(rowIndex || 0, columnIndex, cellValue, columnDef, item, this._grid) : '';
const formattedCellValue = (columnDef && typeof columnDef.formatter === 'function') ? columnDef.formatter(rowIndex || 0, columnIndex, cellValue, columnDef, item, this._grid) : '';
cellValue = sanitizeHtmlToText(formattedCellValue as string);
}

// make sure cell value is always a string
Expand Down

0 comments on commit 961d8fd

Please sign in to comment.