diff --git a/app/lib/server/methods/filterBadWords.js b/app/lib/server/methods/filterBadWords.js deleted file mode 100644 index 0e09a31d1777..000000000000 --- a/app/lib/server/methods/filterBadWords.js +++ /dev/null @@ -1,29 +0,0 @@ -import Filter from 'bad-words'; - -import { settings } from '../../../settings'; -import { callbacks } from '../../../callbacks'; - -callbacks.add('beforeSaveMessage', function(message) { - if (settings.get('Message_AllowBadWordsFilter')) { - const badWordsList = settings.get('Message_BadWordsFilterList'); - let whiteList = settings.get('Message_BadWordsWhitelist'); - let options; - - // Add words to the blacklist - if (!!badWordsList && badWordsList.length) { - options = { - list: badWordsList.split(','), - }; - } - const filter = new Filter(options); - - if (whiteList?.length) { - whiteList = whiteList.split(',').map((word) => word.trim()); - filter.removeWords(...whiteList); - } - - message.msg = filter.clean(message.msg); - } - - return message; -}, 1, 'filterBadWords'); diff --git a/app/lib/server/methods/filterBadWords.ts b/app/lib/server/methods/filterBadWords.ts new file mode 100644 index 000000000000..57f89059fc7a --- /dev/null +++ b/app/lib/server/methods/filterBadWords.ts @@ -0,0 +1,56 @@ +import { Meteor } from 'meteor/meteor'; +import { Tracker } from 'meteor/tracker'; +import Filter from 'bad-words'; + +import { settings } from '../../../settings/server'; +import { callbacks } from '../../../callbacks/server'; +import { IMessage } from '../../../../definition/IMessage'; + +const Dep = new Tracker.Dependency(); +Meteor.startup(() => { + settings.get(/Message_AllowBadWordsFilter|Message_BadWordsFilterList|Message_BadWordsWhitelist/, () => { + Dep.changed(); + }); + Tracker.autorun(() => { + Dep.depend(); + const allowBadWordsFilter = settings.get('Message_AllowBadWordsFilter'); + + callbacks.remove('beforeSaveMessage', 'filterBadWords'); + + if (!allowBadWordsFilter) { + return; + } + + const badWordsList = settings.get('Message_BadWordsFilterList') as string | undefined; + const whiteList = settings.get('Message_BadWordsWhitelist') as string | undefined; + + const options = { + list: badWordsList?.split(',').map((word) => word.trim()).filter(Boolean) || [], + // library definition does not allow optional definition + exclude: undefined, + splitRegex: undefined, + placeHolder: undefined, + regex: undefined, + replaceRegex: undefined, + emptyList: undefined, + }; + + const filter = new Filter(options); + + if (whiteList?.length) { + filter.removeWords(...whiteList.split(',').map((word) => word.trim())); + } + + callbacks.add('beforeSaveMessage', function(message: IMessage) { + if (!message.msg) { + return message; + } + try { + message.msg = filter.clean(message.msg); + } finally { + // eslint-disable-next-line no-unsafe-finally + return message; + } + }, callbacks.priority.HIGH, 'filterBadWords'); + }); +}); diff --git a/package-lock.json b/package-lock.json index 581f0f917c3b..5509ccc66f76 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9247,6 +9247,11 @@ "@types/node": "*" } }, + "@types/bad-words": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/bad-words/-/bad-words-3.0.1.tgz", + "integrity": "sha512-7la3ZDJG1tlRqySO+pnXycZpacaMEw/iLEm8kc4l+I+jN8KjBfoQVwO6jm98xzXVLrxV8vDrB5TaMoop8sKclQ==" + }, "@types/bcrypt": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/@types/bcrypt/-/bcrypt-5.0.0.tgz", diff --git a/package.json b/package.json index ea69dace3934..22a9168495d0 100644 --- a/package.json +++ b/package.json @@ -60,6 +60,7 @@ "@storybook/addons": "^6.3.6", "@storybook/react": "^6.3.6", "@types/agenda": "^2.0.9", + "@types/bad-words": "^3.0.1", "@types/bcrypt": "^5.0.0", "@types/body-parser": "^1.19.0", "@types/chai": "^4.2.19",