String helpers (#21988)

pull/21999/head
Tasso Evangelista 4 years ago committed by GitHub
parent 6e9d541d5e
commit 857e21eaa7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 4
      app/2fa/client/TOTPOAuth.js
  2. 3
      app/api/server/lib/users.js
  3. 2
      app/api/server/v1/misc.js
  4. 4
      app/authentication/server/startup/index.js
  5. 3
      app/autolinker/client/client.js
  6. 2
      app/autotranslate/server/autotranslate.js
  7. 6
      app/custom-oauth/client/custom_oauth_client.js
  8. 2
      app/emoji-custom/client/lib/emojiCustom.js
  9. 2
      app/emoji/client/emojiPicker.js
  10. 2
      app/highlight-words/client/helper.js
  11. 3
      app/katex/client/index.js
  12. 4
      app/lib/server/functions/addOAuthService.js
  13. 3
      app/lib/server/functions/checkEmailAvailability.js
  14. 2
      app/lib/server/functions/checkUsernameAvailability.js
  15. 2
      app/lib/server/functions/getFullUserData.js
  16. 2
      app/lib/server/functions/notifications/email.js
  17. 2
      app/lib/server/functions/notifications/index.js
  18. 2
      app/lib/server/functions/saveUser.js
  19. 2
      app/lib/server/functions/setEmail.js
  20. 2
      app/lib/server/lib/notifyUsersOnMessage.js
  21. 4
      app/lib/server/methods/removeOAuthService.js
  22. 3
      app/livechat/server/api/lib/customFields.js
  23. 3
      app/livechat/server/api/lib/departments.js
  24. 3
      app/livechat/server/api/lib/users.js
  25. 2
      app/mail-messages/server/functions/sendMail.js
  26. 2
      app/mailer/server/api.js
  27. 2
      app/markdown/lib/markdown.js
  28. 3
      app/markdown/lib/parser/marked/marked.js
  29. 2
      app/markdown/lib/parser/original/code.js
  30. 3
      app/markdown/tests/client.tests.js
  31. 2
      app/mentions/lib/MentionsParser.js
  32. 2
      app/message-snippet/client/messageType.js
  33. 4
      app/meteor-accounts-saml/server/lib/SAML.ts
  34. 2
      app/models/server/models/LivechatVisitors.js
  35. 2
      app/models/server/models/Rooms.js
  36. 2
      app/models/server/models/Uploads.js
  37. 2
      app/models/server/models/Users.js
  38. 2
      app/models/server/models/_oplogHandle.ts
  39. 3
      app/models/server/raw/LivechatDepartment.js
  40. 3
      app/models/server/raw/LivechatVisitors.js
  41. 3
      app/models/server/raw/Rooms.js
  42. 3
      app/models/server/raw/Users.js
  43. 3
      app/oembed/client/oembedUrlWidget.js
  44. 2
      app/threads/client/lib/normalizeThreadTitle.js
  45. 2
      app/tokenpass/server/functions/saveRoomTokensMinimumBalance.js
  46. 6
      app/ui-login/client/login/services.js
  47. 2
      app/ui-master/server/inject.js
  48. 2
      app/ui-message/client/message.js
  49. 2
      app/ui-message/client/popup/messagePopupConfig.js
  50. 2
      app/ui-utils/client/lib/RoomHistoryManager.js
  51. 2
      app/ui-utils/lib/Message.js
  52. 2
      app/ui/client/lib/chatMessages.js
  53. 3
      app/ui/client/views/app/photoswipe.js
  54. 3
      app/utils/client/lib/handleError.js
  55. 2
      client/components/CustomFieldsForm.js
  56. 3
      client/hooks/useForm.ts
  57. 43
      client/lib/capitalize.spec.ts
  58. 7
      client/lib/capitalize.ts
  59. 3
      client/lib/lists/DiscussionsList.ts
  60. 3
      client/lib/lists/ThreadsList.ts
  61. 3
      client/lib/renderMessageBody.ts
  62. 3
      client/sidebar/RoomList/normalizeSidebarMessage.js
  63. 2
      client/sidebar/search/SearchList.js
  64. 2
      client/startup/messageTypes.ts
  65. 2
      client/views/admin/apps/AppSettingsAssembler.js
  66. 2
      client/views/admin/users/UserRow.js
  67. 3
      client/views/room/contextualBar/Discussions/normalizeThreadMessage.js
  68. 3
      client/views/room/contextualBar/Threads/normalizeThreadMessage.js
  69. 2
      client/views/room/hooks/useUserInfoActions.js
  70. 2
      ee/app/auditing/server/methods.js
  71. 3
      ee/app/livechat-enterprise/server/api/lib/monitors.js
  72. 3
      ee/app/livechat-enterprise/server/api/lib/priorities.js
  73. 3
      ee/app/livechat-enterprise/server/api/lib/tags.js
  74. 3
      ee/app/livechat-enterprise/server/api/lib/units.js
  75. 3
      ee/app/livechat-enterprise/server/business-hour/lib/business-hour.ts
  76. 7
      ee/server/services/.eslintrc.js
  77. 19
      lib/escapeHTML.spec.ts
  78. 27
      lib/escapeHTML.ts
  79. 80
      lib/escapeRegExp.spec.ts
  80. 6
      lib/escapeRegExp.ts
  81. 35
      lib/unescapeHTML.spec.ts
  82. 42
      lib/unescapeHTML.ts
  83. 125
      package-lock.json
  84. 1
      package.json
  85. 2
      server/lib/spotlight.js
  86. 2
      server/methods/browseChannels.js
  87. 2
      server/methods/messageSearch.js
  88. 2
      server/services/team/service.ts
  89. 3
      server/startup/migrations/v055.js
  90. 3
      server/startup/migrations/v064.js

@ -1,3 +1,4 @@
import { capitalize } from '@rocket.chat/string-helpers';
import { Meteor } from 'meteor/meteor';
import { Accounts } from 'meteor/accounts-base';
import { Facebook } from 'meteor/facebook-oauth';
@ -6,7 +7,6 @@ import { Twitter } from 'meteor/twitter-oauth';
import { MeteorDeveloperAccounts } from 'meteor/meteor-developer-oauth';
import { Linkedin } from 'meteor/pauli:linkedin-oauth';
import { OAuth } from 'meteor/oauth';
import s from 'underscore.string';
import { Utils2fa } from './lib/2fa';
import { process2faReturn } from './callWithTwoFactorRequired';
@ -126,7 +126,7 @@ Accounts.onPageLoadLogin((loginAttempt) => {
const oldConfigureLogin = CustomOAuth.prototype.configureLogin;
CustomOAuth.prototype.configureLogin = function(...args) {
const loginWithService = `loginWith${ s.capitalize(this.name) }`;
const loginWithService = `loginWith${ capitalize(String(this.name || '')) }`;
oldConfigureLogin.apply(this, args);

@ -1,6 +1,7 @@
import { escapeRegExp } from '@rocket.chat/string-helpers';
import { Users } from '../../../models/server/raw';
import { hasPermissionAsync } from '../../../authorization/server/functions/hasPermission';
import { escapeRegExp } from '../../../../lib/escapeRegExp';
export async function findUsersToAutocomplete({ uid, selector }) {
if (!await hasPermissionAsync(uid, 'view-outside-room')) {

@ -5,6 +5,7 @@ import { check } from 'meteor/check';
import { TAPi18n } from 'meteor/rocketchat:tap-i18n';
import { EJSON } from 'meteor/ejson';
import { DDPRateLimiter } from 'meteor/ddp-rate-limiter';
import { escapeHTML } from '@rocket.chat/string-helpers';
import { hasRole, hasPermission } from '../../../authorization/server';
import { Info } from '../../../utils/server';
@ -14,7 +15,6 @@ import { API } from '../api';
import { getDefaultUserFields } from '../../../utils/server/functions/getDefaultUserFields';
import { getURL } from '../../../utils/lib/getURL';
import { StdOut } from '../../../logger/server/streamer';
import { escapeHTML } from '../../../../lib/escapeHTML';
// DEPRECATED

@ -3,6 +3,7 @@ import { Match } from 'meteor/check';
import { Accounts } from 'meteor/accounts-base';
import { TAPi18n } from 'meteor/rocketchat:tap-i18n';
import _ from 'underscore';
import { escapeRegExp, escapeHTML } from '@rocket.chat/string-helpers';
import * as Mailer from '../../../mailer/server/api';
import { settings } from '../../../settings/server';
@ -17,8 +18,7 @@ import {
} from '../lib/restrictLoginAttempts';
import './settings';
import { getClientAddress } from '../../../../server/lib/getClientAddress';
import { escapeHTML } from '../../../../lib/escapeHTML';
import { escapeRegExp } from '../../../../lib/escapeRegExp';
Accounts.config({
forbidClientAccountCreation: true,

@ -1,8 +1,7 @@
import { Meteor } from 'meteor/meteor';
import { Random } from 'meteor/random';
import Autolinker from 'autolinker';
import { escapeRegExp } from '../../../lib/escapeRegExp';
import { escapeRegExp } from '@rocket.chat/string-helpers';
export const createAutolinkerMessageRenderer = (config) =>
(message) => {

@ -1,12 +1,12 @@
import { Meteor } from 'meteor/meteor';
import _ from 'underscore';
import { escapeHTML } from '@rocket.chat/string-helpers';
import { settings } from '../../settings';
import { callbacks } from '../../callbacks';
import { Subscriptions, Messages } from '../../models';
import { Markdown } from '../../markdown/server';
import { Logger } from '../../logger';
import { escapeHTML } from '../../../lib/escapeHTML';
const Providers = Symbol('Providers');
const Provider = Symbol('Provider');

@ -1,12 +1,12 @@
import { capitalize } from '@rocket.chat/string-helpers';
import { Meteor } from 'meteor/meteor';
import { Match } from 'meteor/check';
import { Accounts } from 'meteor/accounts-base';
import { Random } from 'meteor/random';
import { ServiceConfiguration } from 'meteor/service-configuration';
import { OAuth } from 'meteor/oauth';
import s from 'underscore.string';
import './swapSessionStorage';
import './swapSessionStorage';
import { isURL } from '../../utils/lib/isURL';
// Request custom OAuth credentials for the user
@ -56,7 +56,7 @@ export class CustomOAuth {
}
configureLogin() {
const loginWithService = `loginWith${ s.capitalize(this.name) }`;
const loginWithService = `loginWith${ capitalize(String(this.name || '')) }`;
Meteor[loginWithService] = (options, callback) => {
// support a callback without options

@ -1,13 +1,13 @@
import { Meteor } from 'meteor/meteor';
import { Blaze } from 'meteor/blaze';
import { Session } from 'meteor/session';
import { escapeRegExp } from '@rocket.chat/string-helpers';
import { isSetNotNull } from './function-isSet';
import { RoomManager } from '../../../ui-utils/client';
import { emoji, EmojiPicker } from '../../../emoji/client';
import { CachedCollectionManager } from '../../../ui-cached-collection/client';
import { APIClient } from '../../../utils/client';
import { escapeRegExp } from '../../../../lib/escapeRegExp';
export const getEmojiUrlFromName = function(name, extension) {
Session.get;

@ -3,8 +3,8 @@ import { ReactiveVar } from 'meteor/reactive-var';
import { ReactiveDict } from 'meteor/reactive-dict';
import { FlowRouter } from 'meteor/kadira:flow-router';
import { Template } from 'meteor/templating';
import { escapeRegExp } from '@rocket.chat/string-helpers';
import { escapeRegExp } from '../../../lib/escapeRegExp';
import '../../theme/client/imports/components/emojiPicker.css';
import { t } from '../../utils/client';
import { EmojiPicker } from './lib/EmojiPicker';

@ -1,4 +1,4 @@
import { escapeRegExp } from '../../../lib/escapeRegExp';
import { escapeRegExp } from '@rocket.chat/string-helpers';
export const checkHighlightedWordsInUrls = (msg, urlRegex) => msg.match(urlRegex);

@ -1,8 +1,7 @@
import { Random } from 'meteor/random';
import katex from 'katex';
import { unescapeHTML, escapeHTML } from '@rocket.chat/string-helpers';
import { escapeHTML } from '../../../lib/escapeHTML';
import { unescapeHTML } from '../../../lib/unescapeHTML';
import 'katex/dist/katex.min.css';
import './style.css';

@ -1,12 +1,12 @@
/* eslint no-multi-spaces: 0 */
/* eslint comma-spacing: 0 */
import s from 'underscore.string';
import { capitalize } from '@rocket.chat/string-helpers';
import { settings } from '../../../settings';
export function addOAuthService(name, values = {}) {
name = name.toLowerCase().replace(/[^a-z0-9_]/g, '');
name = s.capitalize(name);
name = capitalize(name);
settings.add(`Accounts_OAuth_Custom-${ name }` , values.enabled || false , { type: 'boolean', group: 'OAuth', section: `Custom OAuth: ${ name }`, i18nLabel: 'Accounts_OAuth_Custom_Enable', persistent: true });
settings.add(`Accounts_OAuth_Custom-${ name }-url` , values.serverURL || '' , { type: 'string' , group: 'OAuth', section: `Custom OAuth: ${ name }`, i18nLabel: 'URL', persistent: true });
settings.add(`Accounts_OAuth_Custom-${ name }-token_path` , values.tokenPath || '/oauth/token' , { type: 'string' , group: 'OAuth', section: `Custom OAuth: ${ name }`, i18nLabel: 'Accounts_OAuth_Custom_Token_Path', persistent: true });

@ -1,7 +1,6 @@
import { Meteor } from 'meteor/meteor';
import s from 'underscore.string';
import { escapeRegExp } from '../../../../lib/escapeRegExp';
import { escapeRegExp } from '@rocket.chat/string-helpers';
export const checkEmailAvailability = function(email) {
return !Meteor.users.findOne({ 'emails.address': { $regex: new RegExp(`^${ s.trim(escapeRegExp(email)) }$`, 'i') } });

@ -1,7 +1,7 @@
import { Meteor } from 'meteor/meteor';
import s from 'underscore.string';
import { escapeRegExp } from '@rocket.chat/string-helpers';
import { escapeRegExp } from '../../../../lib/escapeRegExp';
import { settings } from '../../../settings';
import { Team } from '../../../../server/sdk';
import { validateName } from './validateName';

@ -1,10 +1,10 @@
import s from 'underscore.string';
import { escapeRegExp } from '@rocket.chat/string-helpers';
import { Logger } from '../../../logger';
import { settings } from '../../../settings';
import { Users } from '../../../models/server';
import { hasPermission } from '../../../authorization';
import { escapeRegExp } from '../../../../lib/escapeRegExp';
const logger = new Logger('getFullUserData');

@ -1,6 +1,7 @@
import { Meteor } from 'meteor/meteor';
import { TAPi18n } from 'meteor/rocketchat:tap-i18n';
import s from 'underscore.string';
import { escapeHTML } from '@rocket.chat/string-helpers';
import * as Mailer from '../../../../mailer';
import { settings } from '../../../../settings';
@ -8,7 +9,6 @@ import { roomTypes } from '../../../../utils';
import { metrics } from '../../../../metrics';
import { callbacks } from '../../../../callbacks';
import { getURL } from '../../../../utils/server';
import { escapeHTML } from '../../../../../lib/escapeHTML';
let advice = '';
let goToMessage = '';

@ -1,7 +1,7 @@
import { Meteor } from 'meteor/meteor';
import { TAPi18n } from 'meteor/rocketchat:tap-i18n';
import { escapeRegExp } from '@rocket.chat/string-helpers';
import { escapeRegExp } from '../../../../../lib/escapeRegExp';
import { callbacks } from '../../../../callbacks';
import { settings } from '../../../../settings';

@ -3,6 +3,7 @@ import { Accounts } from 'meteor/accounts-base';
import _ from 'underscore';
import s from 'underscore.string';
import { Gravatar } from 'meteor/jparker:gravatar';
import { escapeHTML } from '@rocket.chat/string-helpers';
import * as Mailer from '../../../mailer';
import { getRoles, hasPermission } from '../../../authorization';
@ -11,7 +12,6 @@ import { passwordPolicy } from '../lib/passwordPolicy';
import { validateEmailDomain } from '../lib';
import { validateUserRoles } from '../../../../ee/app/authorization/server/validateUserRoles';
import { saveUserIdentity } from './saveUserIdentity';
import { escapeHTML } from '../../../../lib/escapeHTML';
import { checkEmailAvailability, checkUsernameAvailability, setUserAvatar, setEmail, setStatusText } from '.';

@ -1,12 +1,12 @@
import { Meteor } from 'meteor/meteor';
import s from 'underscore.string';
import { escapeHTML } from '@rocket.chat/string-helpers';
import { Users } from '../../../models';
import { hasPermission } from '../../../authorization';
import { RateLimiter, validateEmailDomain } from '../lib';
import * as Mailer from '../../../mailer';
import { settings } from '../../../settings';
import { escapeHTML } from '../../../../lib/escapeHTML';
import { checkEmailAvailability } from '.';

@ -1,9 +1,9 @@
import moment from 'moment';
import { escapeRegExp } from '@rocket.chat/string-helpers';
import { Rooms, Subscriptions } from '../../../models/server';
import { settings } from '../../../settings/server';
import { callbacks } from '../../../callbacks/server';
import { escapeRegExp } from '../../../../lib/escapeRegExp';
/**
* Chechs if a messages contains a user highlight

@ -1,6 +1,6 @@
import { capitalize } from '@rocket.chat/string-helpers';
import { Meteor } from 'meteor/meteor';
import { check } from 'meteor/check';
import s from 'underscore.string';
import { hasPermission } from '../../../authorization';
import { settings } from '../../../settings';
@ -18,7 +18,7 @@ Meteor.methods({
}
name = name.toLowerCase().replace(/[^a-z0-9_]/g, '');
name = s.capitalize(name);
name = capitalize(name);
settings.removeById(`Accounts_OAuth_Custom-${ name }`);
settings.removeById(`Accounts_OAuth_Custom-${ name }-url`);
settings.removeById(`Accounts_OAuth_Custom-${ name }-token_path`);

@ -1,4 +1,5 @@
import { escapeRegExp } from '../../../../../lib/escapeRegExp';
import { escapeRegExp } from '@rocket.chat/string-helpers';
import { hasPermissionAsync } from '../../../../authorization/server/functions/hasPermission';
import { LivechatCustomField } from '../../../../models/server/raw';

@ -1,4 +1,5 @@
import { escapeRegExp } from '../../../../../lib/escapeRegExp';
import { escapeRegExp } from '@rocket.chat/string-helpers';
import { hasPermissionAsync } from '../../../../authorization/server/functions/hasPermission';
import { LivechatDepartment, LivechatDepartmentAgents } from '../../../../models/server/raw';

@ -1,4 +1,5 @@
import { escapeRegExp } from '../../../../../lib/escapeRegExp';
import { escapeRegExp } from '@rocket.chat/string-helpers';
import { hasAllPermissionAsync } from '../../../../authorization/server/functions/hasPermission';
import { Users } from '../../../../models/server/raw';

@ -1,10 +1,10 @@
import { Meteor } from 'meteor/meteor';
import { EJSON } from 'meteor/ejson';
import { FlowRouter } from 'meteor/kadira:flow-router';
import { escapeHTML } from '@rocket.chat/string-helpers';
import { placeholders } from '../../../utils';
import * as Mailer from '../../../mailer';
import { escapeHTML } from '../../../../lib/escapeHTML';
export const sendMail = function(from, subject, body, dryrun, query) {
Mailer.checkAddressFormatAndThrow(from, 'Mailer.sendMail');

@ -5,9 +5,9 @@ import _ from 'underscore';
import s from 'underscore.string';
import juice from 'juice';
import stripHtml from 'string-strip-html';
import { escapeHTML } from '@rocket.chat/string-helpers';
import { settings } from '../../settings/server';
import { escapeHTML } from '../../../lib/escapeHTML';
import { replaceVariables } from './utils.js';
let contentHeader;

@ -3,13 +3,13 @@
* @param {Object} message - The message object
*/
import { Meteor } from 'meteor/meteor';
import { escapeHTML } from '@rocket.chat/string-helpers';
import { marked } from './parser/marked/marked';
import { original } from './parser/original/original';
import { filtered } from './parser/filtered/filtered';
import { code } from './parser/original/code';
import { settings } from '../../settings';
import { escapeHTML } from '../../../lib/escapeHTML';
const parsers = {
original,

@ -2,10 +2,9 @@ import { Random } from 'meteor/random';
import _ from 'underscore';
import _marked from 'marked';
import createDOMPurify from 'dompurify';
import { unescapeHTML, escapeHTML } from '@rocket.chat/string-helpers';
import hljs from '../../hljs';
import { escapeHTML } from '../../../../../lib/escapeHTML';
import { unescapeHTML } from '../../../../../lib/unescapeHTML';
import { getGlobalWindow } from '../../getGlobalWindow';
const renderer = new _marked.Renderer();

@ -3,8 +3,8 @@
* @param {Object} message - The message object
*/
import { Random } from 'meteor/random';
import { unescapeHTML } from '@rocket.chat/string-helpers';
import { unescapeHTML } from '../../../../../lib/unescapeHTML';
import hljs from '../../hljs';
const inlinecode = (message) => {

@ -3,10 +3,11 @@ import 'babel-polyfill';
import assert from 'assert';
import './client.mocks.js';
import { escapeHTML } from '@rocket.chat/string-helpers';
import { original } from '../lib/parser/original/original';
import { filtered } from '../lib/parser/filtered/filtered';
import { Markdown } from '../lib/markdown';
import { escapeHTML } from '../../../lib/escapeHTML';
const wrapper = (text, tag) => `<span class="copyonly">${ tag }</span>${ text }<span class="copyonly">${ tag }</span>`;
const boldWrapper = (text) => wrapper(`<strong>${ text }</strong>`, '*');

@ -1,4 +1,4 @@
import { escapeHTML } from '../../../lib/escapeHTML';
import { escapeHTML } from '@rocket.chat/string-helpers';
const userTemplateDefault = ({ prefix, className, mention, title, label, type = 'username' }) => `${ prefix }<a class="${ className }" data-${ type }="${ mention }"${ title ? ` title="${ title }"` : '' }>${ label }</a>`;
const roomTemplateDefault = ({ prefix, reference, mention }) => `${ prefix }<a class="mention-link mention-link--room" data-channel="${ reference }">${ `#${ mention }` }</a>`;

@ -1,6 +1,6 @@
import { Meteor } from 'meteor/meteor';
import { escapeHTML } from '@rocket.chat/string-helpers';
import { escapeHTML } from '../../../lib/escapeHTML';
import { MessageTypes } from '../../ui-utils';
Meteor.startup(function() {

@ -5,6 +5,7 @@ import { Random } from 'meteor/random';
import { Accounts } from 'meteor/accounts-base';
import { TAPi18n } from 'meteor/rocketchat:tap-i18n';
import fiber from 'fibers';
import { escapeRegExp, escapeHTML } from '@rocket.chat/string-helpers';
import { settings } from '../../../settings/server';
import { Users, Rooms, CredentialTokens } from '../../../models/server';
@ -16,8 +17,7 @@ import { IServiceProviderOptions } from '../definition/IServiceProviderOptions';
import { ISAMLAction } from '../definition/ISAMLAction';
import { ISAMLUser } from '../definition/ISAMLUser';
import { SAMLUtils } from './Utils';
import { escapeHTML } from '../../../../lib/escapeHTML';
import { escapeRegExp } from '../../../../lib/escapeRegExp';
const showErrorMessage = function(res: ServerResponse, err: string): void {
res.writeHead(200, {

@ -1,10 +1,10 @@
import { Meteor } from 'meteor/meteor';
import _ from 'underscore';
import s from 'underscore.string';
import { escapeRegExp } from '@rocket.chat/string-helpers';
import { Base } from './_Base';
import Settings from './Settings';
import { escapeRegExp } from '../../../../lib/escapeRegExp';
export class LivechatVisitors extends Base {
constructor() {

@ -1,11 +1,11 @@
import _ from 'underscore';
import s from 'underscore.string';
import { escapeRegExp } from '@rocket.chat/string-helpers';
import { Base } from './_Base';
import Messages from './Messages';
import Subscriptions from './Subscriptions';
import { getValidRoomName } from '../../../utils';
import { escapeRegExp } from '../../../../lib/escapeRegExp';
export class Rooms extends Base {
constructor(...args) {

@ -1,9 +1,9 @@
import _ from 'underscore';
import s from 'underscore.string';
import { InstanceStatus } from 'meteor/konecty:multiple-instances-status';
import { escapeRegExp } from '@rocket.chat/string-helpers';
import { Base } from './_Base';
import { escapeRegExp } from '../../../../lib/escapeRegExp';
const fillTypeGroup = (fileData) => {
if (!fileData.type) {

@ -2,11 +2,11 @@ import { Meteor } from 'meteor/meteor';
import { Accounts } from 'meteor/accounts-base';
import _ from 'underscore';
import s from 'underscore.string';
import { escapeRegExp } from '@rocket.chat/string-helpers';
import { Base } from './_Base';
import Subscriptions from './Subscriptions';
import { settings } from '../../../settings/server/functions/settings';
import { escapeRegExp } from '../../../../lib/escapeRegExp';
const queryStatusAgentOnline = (extraFilters = {}) => {
if (settings.get('Livechat_enabled_when_agent_idle') === false) {

@ -3,9 +3,9 @@ import { Promise } from 'meteor/promise';
import { MongoInternals, OplogHandle } from 'meteor/mongo';
import semver from 'semver';
import { MongoClient, Cursor, Timestamp, Db } from 'mongodb';
import { escapeRegExp } from '@rocket.chat/string-helpers';
import { urlParser } from './_oplogUrlParser';
import { escapeRegExp } from '../../../../lib/escapeRegExp';
class CustomOplogHandle {
dbName: string;

@ -1,4 +1,5 @@
import { escapeRegExp } from '../../../../lib/escapeRegExp';
import { escapeRegExp } from '@rocket.chat/string-helpers';
import { BaseRaw } from './BaseRaw';
export class LivechatDepartmentRaw extends BaseRaw {

@ -1,4 +1,5 @@
import { escapeRegExp } from '../../../../lib/escapeRegExp';
import { escapeRegExp } from '@rocket.chat/string-helpers';
import { BaseRaw } from './BaseRaw';
export class LivechatVisitorsRaw extends BaseRaw {

@ -1,4 +1,5 @@
import { escapeRegExp } from '../../../../lib/escapeRegExp';
import { escapeRegExp } from '@rocket.chat/string-helpers';
import { BaseRaw } from './BaseRaw';
export class RoomsRaw extends BaseRaw {

@ -1,4 +1,5 @@
import { escapeRegExp } from '../../../../lib/escapeRegExp';
import { escapeRegExp } from '@rocket.chat/string-helpers';
import { BaseRaw } from './BaseRaw';
export class UsersRaw extends BaseRaw {

@ -1,8 +1,7 @@
import { Blaze } from 'meteor/blaze';
import { Template } from 'meteor/templating';
import _ from 'underscore';
import { unescapeHTML } from '../../../lib/unescapeHTML';
import { unescapeHTML } from '@rocket.chat/string-helpers';
const getTitle = function(self) {
if (self.meta == null) {

@ -1,11 +1,11 @@
import { Meteor } from 'meteor/meteor';
import { escapeHTML } from '@rocket.chat/string-helpers';
import { filterMarkdown } from '../../../markdown/lib/markdown';
import { Users } from '../../../models/client';
import { settings } from '../../../settings/client';
import { MentionsParser } from '../../../mentions/lib/MentionsParser';
import { emojiParser } from '../../../emoji/client/emojiParser.js';
import { escapeHTML } from '../../../../lib/escapeHTML';
export const normalizeThreadTitle = ({ ...message }) => {
if (message.msg) {

@ -1,8 +1,8 @@
import { Meteor } from 'meteor/meteor';
import { Match } from 'meteor/check';
import { escapeHTML } from '@rocket.chat/string-helpers';
import { Rooms } from '../../../models';
import { escapeHTML } from '../../../../lib/escapeHTML';
export const saveRoomTokensMinimumBalance = function(rid, roomTokensMinimumBalance) {
if (!Match.test(rid, String)) {

@ -1,7 +1,7 @@
import { capitalize } from '@rocket.chat/string-helpers';
import { Meteor } from 'meteor/meteor';
import { Template } from 'meteor/templating';
import { ServiceConfiguration } from 'meteor/service-configuration';
import s from 'underscore.string';
import toastr from 'toastr';
import { CustomOAuth } from '../../../custom-oauth';
@ -49,7 +49,7 @@ Template.loginServices.helpers({
icon = service.service;
break;
default:
displayName = s.capitalize(service.service);
displayName = capitalize(String(service.service || ''));
icon = service.service;
}
return {
@ -76,7 +76,7 @@ Template.loginServices.events({
loadingIcon.removeClass('hidden');
serviceIcon.addClass('hidden');
const loginWithService = `loginWith${ loginMethods[this.service.service] || s.capitalize(this.service.service) }`;
const loginWithService = `loginWith${ loginMethods[this.service.service] || capitalize(String(this.service.service || '')) }`;
const serviceConfig = this.service.clientConfig || {};
return Meteor[loginWithService](serviceConfig, function(error) {
loadingIcon.addClass('hidden');

@ -3,8 +3,8 @@ import { Inject } from 'meteor/meteorhacks:inject-initial';
import { ReactiveDict } from 'meteor/reactive-dict';
import { Tracker } from 'meteor/tracker';
import _ from 'underscore';
import { escapeHTML } from '@rocket.chat/string-helpers';
import { escapeHTML } from '../../../lib/escapeHTML';
import { Settings } from '../../models';
import { settings } from '../../settings/server';

@ -4,6 +4,7 @@ import { Tracker } from 'meteor/tracker';
import { Template } from 'meteor/templating';
import { Session } from 'meteor/session';
import { TAPi18n } from 'meteor/rocketchat:tap-i18n';
import { escapeHTML } from '@rocket.chat/string-helpers';
import { timeAgo, formatDateAndTime } from '../../lib/client/lib/formatDate';
import { DateFormat } from '../../lib/client';
@ -14,7 +15,6 @@ import { Markdown } from '../../markdown/client';
import { t, roomTypes } from '../../utils';
import './messageThread';
import { AutoTranslate } from '../../autotranslate/client';
import { escapeHTML } from '../../../lib/escapeHTML';
import { renderMentions } from '../../mentions/client/client';
import { renderMessageBody } from '../../../client/lib/renderMessageBody';
import { settings } from '../../settings/client';

@ -6,6 +6,7 @@ import { Tracker } from 'meteor/tracker';
import { Session } from 'meteor/session';
import { Template } from 'meteor/templating';
import { TAPi18n } from 'meteor/rocketchat:tap-i18n';
import { escapeRegExp } from '@rocket.chat/string-helpers';
import { Messages, Subscriptions } from '../../../models/client';
import { settings } from '../../../settings/client';
@ -17,7 +18,6 @@ import { customMessagePopups } from './customMessagePopups';
import './messagePopupConfig.html';
import './messagePopupSlashCommand.html';
import './messagePopupUser.html';
import { escapeRegExp } from '../../../../lib/escapeRegExp';
const reloadUsersFromRoomMessages = (rid, template) => {
const user = Meteor.userId() && Meteor.users.findOne(Meteor.userId(), { fields: { username: 1 } });

@ -5,6 +5,7 @@ import { Blaze } from 'meteor/blaze';
import { v4 as uuidv4 } from 'uuid';
import differenceInMilliseconds from 'date-fns/differenceInMilliseconds';
import { Emitter } from '@rocket.chat/emitter';
import { escapeHTML } from '@rocket.chat/string-helpers';
import { promises } from '../../../promises/client';
import { RoomManager } from './RoomManager';
@ -14,7 +15,6 @@ import { getConfig } from '../config';
import { ChatMessage, ChatSubscription, ChatRoom } from '../../../models';
import { call } from './callMethod';
import { filterMarkdown } from '../../../markdown/lib/markdown';
import { escapeHTML } from '../../../../lib/escapeHTML';
import { getUserPreference } from '../../../utils/client';
export const normalizeThreadMessage = ({ ...message }) => {

@ -1,10 +1,10 @@
import { TAPi18n } from 'meteor/rocketchat:tap-i18n';
import { Meteor } from 'meteor/meteor';
import s from 'underscore.string';
import { escapeHTML } from '@rocket.chat/string-helpers';
import { MessageTypes } from './MessageTypes';
import { settings } from '../../settings';
import { escapeHTML } from '../../../lib/escapeHTML';
export const Message = {
parse(msg, language) {

@ -6,6 +6,7 @@ import { Random } from 'meteor/random';
import { FlowRouter } from 'meteor/kadira:flow-router';
import { Session } from 'meteor/session';
import { TAPi18n } from 'meteor/rocketchat:tap-i18n';
import { escapeHTML } from '@rocket.chat/string-helpers';
import { KonchatNotification } from './notification';
import { MsgTyping } from './msgTyping';
@ -27,7 +28,6 @@ import { hasAtLeastOnePermission } from '../../../authorization/client';
import { Messages, Rooms, ChatMessage, ChatSubscription } from '../../../models/client';
import { emoji } from '../../../emoji/client';
import { generateTriggerId } from '../../../ui-message/client/ActionManager';
import { escapeHTML } from '../../../../lib/escapeHTML';
const messageBoxState = {

@ -1,8 +1,7 @@
import { Meteor } from 'meteor/meteor';
import { Blaze } from 'meteor/blaze';
import { Template } from 'meteor/templating';
import { escapeHTML } from '../../../../../lib/escapeHTML';
import { escapeHTML } from '@rocket.chat/string-helpers';
Meteor.startup(() => {
let currentGallery = null;

@ -1,8 +1,7 @@
import { TAPi18n } from 'meteor/rocketchat:tap-i18n';
import _ from 'underscore';
import toastr from 'toastr';
import { escapeHTML } from '../../../../lib/escapeHTML';
import { escapeHTML } from '@rocket.chat/string-helpers';
export const handleError = function(error, useToastr = true) {
if (error.xhr) {

@ -1,11 +1,11 @@
import { TextInput, Select, Field } from '@rocket.chat/fuselage';
import { capitalize } from '@rocket.chat/string-helpers';
import React, { useMemo, useEffect, useState } from 'react';
import { useSetting } from '../contexts/SettingsContext';
import { useTranslation } from '../contexts/TranslationContext';
import { useComponentDidUpdate } from '../hooks/useComponentDidUpdate';
import { useForm } from '../hooks/useForm';
import { capitalize } from '../lib/capitalize';
const CustomTextInput = ({
label,

@ -1,7 +1,6 @@
import { capitalize } from '@rocket.chat/string-helpers';
import { useCallback, useReducer, useMemo, ChangeEvent } from 'react';
import { capitalize } from '../lib/capitalize';
type Field = {
name: string;
currentValue: unknown;

@ -1,43 +0,0 @@
import assert from 'assert';
import { describe, it } from 'mocha';
import { capitalize } from './capitalize';
describe('capitalize', () => {
it('should convert "xyz" to "Xyz"', () => {
assert.equal(capitalize('xyz'), 'Xyz');
});
it('should convert "xyz xyz" to "Xyz xyz"', () => {
assert.equal(capitalize('xyz xyz'), 'Xyz xyz');
});
it('should convert " xyz" to " xyz"', () => {
assert.equal(capitalize(' xyz'), ' xyz');
});
it('should convert undefined to ""', () => {
assert.equal(capitalize((undefined as unknown) as string), '');
});
it('should convert null to ""', () => {
assert.equal(capitalize((null as unknown) as string), '');
});
it('should convert false to ""', () => {
assert.equal(capitalize((false as unknown) as string), '');
});
it('should convert true to ""', () => {
assert.equal(capitalize((true as unknown) as string), '');
});
it('should convert 0 to ""', () => {
assert.equal(capitalize((0 as unknown) as string), '');
});
it('should convert 1 to ""', () => {
assert.equal(capitalize((1 as unknown) as string), '');
});
});

@ -1,7 +0,0 @@
export const capitalize = (s: string): string => {
if (typeof s !== 'string') {
return '';
}
return s.charAt(0).toUpperCase() + s.slice(1);
};

@ -1,5 +1,6 @@
import { escapeRegExp } from '@rocket.chat/string-helpers';
import type { IMessage } from '../../../definition/IMessage';
import { escapeRegExp } from '../../../lib/escapeRegExp';
import { MessageList } from './MessageList';
type DiscussionMessage = Omit<IMessage, 'drid'> & Required<Pick<IMessage, 'drid'>>;

@ -1,7 +1,8 @@
import { escapeRegExp } from '@rocket.chat/string-helpers';
import type { IMessage } from '../../../definition/IMessage';
import { ISubscription } from '../../../definition/ISubscription';
import { IUser } from '../../../definition/IUser';
import { escapeRegExp } from '../../../lib/escapeRegExp';
import { MessageList } from './MessageList';
type ThreadMessage = Omit<IMessage, 'tcount'> & Required<Pick<IMessage, 'tcount'>>;

@ -1,6 +1,7 @@
import { escapeHTML } from '@rocket.chat/string-helpers';
import { callbacks } from '../../app/callbacks/lib/callbacks';
import { IMessage } from '../../definition/IMessage';
import { escapeHTML } from '../../lib/escapeHTML';
export const renderMessageBody = <T extends Partial<IMessage> & { html?: string }>(
message: T,

@ -1,5 +1,6 @@
import { escapeHTML } from '@rocket.chat/string-helpers';
import { filterMarkdown } from '../../../app/markdown/lib/markdown';
import { escapeHTML } from '../../../lib/escapeHTML';
export const normalizeSidebarMessage = (message, t) => {
if (message.msg) {

@ -7,12 +7,12 @@ import {
useAutoFocus,
useUniqueId,
} from '@rocket.chat/fuselage-hooks';
import { escapeRegExp } from '@rocket.chat/string-helpers';
import { Meteor } from 'meteor/meteor';
import React, { forwardRef, useState, useMemo, useEffect, useRef } from 'react';
import { Virtuoso } from 'react-virtuoso';
import tinykeys from 'tinykeys';
import { escapeRegExp } from '../../../lib/escapeRegExp';
import { useSetting } from '../../contexts/SettingsContext';
import { useTranslation } from '../../contexts/TranslationContext';
import { useUserPreference, useUserSubscriptions } from '../../contexts/UserContext';

@ -1,9 +1,9 @@
import { escapeHTML } from '@rocket.chat/string-helpers';
import { Meteor } from 'meteor/meteor';
import { MessageTypes } from '../../app/ui-utils/client';
import { t } from '../../app/utils/client';
import { IMessage } from '../../definition/IMessage';
import { escapeHTML } from '../../lib/escapeHTML';
Meteor.startup(() => {
MessageTypes.registerType({

@ -1,7 +1,7 @@
import { Box } from '@rocket.chat/fuselage';
import { capitalize } from '@rocket.chat/string-helpers';
import React from 'react';
import { capitalize } from '../../../lib/capitalize';
import AppSetting from './AppSetting';
const AppSettingsAssembler = ({ settings, values, handlers }) => (

@ -1,9 +1,9 @@
import { Box, Table } from '@rocket.chat/fuselage';
import { capitalize } from '@rocket.chat/string-helpers';
import React from 'react';
import UserAvatar from '../../../components/avatar/UserAvatar';
import { useTranslation } from '../../../contexts/TranslationContext';
import { capitalize } from '../../../lib/capitalize';
const style = {
whiteSpace: 'nowrap',

@ -1,4 +1,5 @@
import { escapeHTML } from '../../../../../lib/escapeHTML';
import { escapeHTML } from '@rocket.chat/string-helpers';
import { renderMessageBody } from '../../../../lib/renderMessageBody';
export const normalizeThreadMessage = ({ ...message }) => {

@ -1,4 +1,5 @@
import { escapeHTML } from '../../../../../lib/escapeHTML';
import { escapeHTML } from '@rocket.chat/string-helpers';
import { renderMessageBody } from '../../../../lib/renderMessageBody';
export const normalizeThreadMessage = ({ ...message }) => {

@ -1,11 +1,11 @@
import { Button, ButtonGroup, Icon, Modal, Box } from '@rocket.chat/fuselage';
import { useAutoFocus, useMutableCallback } from '@rocket.chat/fuselage-hooks';
import { escapeHTML } from '@rocket.chat/string-helpers';
import React, { useCallback, useMemo } from 'react';
import { RoomRoles } from '../../../../app/models/client';
import { roomTypes, RoomMemberActions } from '../../../../app/utils/client';
import { WebRTC } from '../../../../app/webrtc/client';
import { escapeHTML } from '../../../../lib/escapeHTML';
import { usePermission, useAllPermissions } from '../../../contexts/AuthorizationContext';
import { useSetModal } from '../../../contexts/ModalContext';
import { useRoute } from '../../../contexts/RouterContext';

@ -3,10 +3,10 @@ import s from 'underscore.string';
import { check } from 'meteor/check';
import { DDPRateLimiter } from 'meteor/ddp-rate-limiter';
import { TAPi18n } from 'meteor/rocketchat:tap-i18n';
import { escapeRegExp } from '@rocket.chat/string-helpers';
import AuditLog from './auditLog';
import { LivechatRooms, Rooms, Messages, Users } from '../../../../app/models/server';
import { escapeRegExp } from '../../../../lib/escapeRegExp';
import { hasPermission } from '../../../../app/authorization/server';
const getValue = (room) => room && { rids: [room._id], name: room.name };

@ -1,6 +1,7 @@
import { escapeRegExp } from '@rocket.chat/string-helpers';
import { hasPermissionAsync } from '../../../../../../app/authorization/server/functions/hasPermission';
import { Users } from '../../../../../../app/models/server/raw';
import { escapeRegExp } from '../../../../../../lib/escapeRegExp';
export async function findMonitors({ userId, text, pagination: { offset, count, sort } }) {
if (!await hasPermissionAsync(userId, 'manage-livechat-monitors')) {

@ -1,5 +1,6 @@
import { escapeRegExp } from '@rocket.chat/string-helpers';
import { hasPermissionAsync } from '../../../../../../app/authorization/server/functions/hasPermission';
import { escapeRegExp } from '../../../../../../lib/escapeRegExp';
import LivechatPriority from '../../../../models/server/raw/LivechatPriority';
export async function findPriorities({ userId, text, pagination: { offset, count, sort } }) {

@ -1,5 +1,6 @@
import { escapeRegExp } from '@rocket.chat/string-helpers';
import { hasPermissionAsync } from '../../../../../../app/authorization/server/functions/hasPermission';
import { escapeRegExp } from '../../../../../../lib/escapeRegExp';
import LivechatTag from '../../../../models/server/raw/LivechatTag';
export async function findTags({ userId, text, pagination: { offset, count, sort } }) {

@ -1,5 +1,6 @@
import { escapeRegExp } from '@rocket.chat/string-helpers';
import { hasPermissionAsync } from '../../../../../../app/authorization/server/functions/hasPermission';
import { escapeRegExp } from '../../../../../../lib/escapeRegExp';
import LivechatUnit from '../../../../models/server/models/LivechatUnit';
import LivechatUnitMonitors from '../../../../models/server/models/LivechatUnitMonitors';

@ -1,8 +1,9 @@
import { escapeRegExp } from '@rocket.chat/string-helpers';
import { hasPermissionAsync } from '../../../../../../app/authorization/server/functions/hasPermission';
import { LivechatBusinessHours } from '../../../../../../app/models/server/raw';
import { IPaginatedResponse, IPagination } from '../../api/lib/definition';
import { ILivechatBusinessHour } from '../../../../../../definition/ILivechatBusinessHour';
import { escapeRegExp } from '../../../../../../lib/escapeRegExp';
interface IResponse extends IPaginatedResponse {
businessHours: ILivechatBusinessHour[];

@ -0,0 +1,7 @@
module.exports = {
root: true,
extends: '../../../.eslintrc',
rules: {
'import/no-unresolved': 'off',
}
};

@ -1,19 +0,0 @@
import assert from 'assert';
import { describe, it } from 'mocha';
import { escapeHTML } from './escapeHTML';
describe('escapeHTML', () => {
it('works', () => {
assert.strictEqual(escapeHTML('<div>Blah & "blah" & \'blah\'</div>'), '&lt;div&gt;Blah &amp; &quot;blah&quot; &amp; &#39;blah&#39;&lt;/div&gt;');
assert.strictEqual(escapeHTML('&lt;'), '&amp;lt;');
assert.strictEqual(escapeHTML(' '), ' ');
assert.strictEqual(escapeHTML('¢'), '&cent;');
assert.strictEqual(escapeHTML('¢ £ ¥ € © ®'), '&cent; &pound; &yen; &euro; &copy; &reg;');
assert.strictEqual(escapeHTML(5 as unknown as string), '5');
assert.strictEqual(escapeHTML(''), '');
assert.strictEqual(escapeHTML(null as unknown as string), '');
assert.strictEqual(escapeHTML(undefined as unknown as string), '');
});
});

@ -1,27 +0,0 @@
const characterToHtmlEntityCode = {
'¢': 'cent',
'£': 'pound',
'¥': 'yen',
'€': 'euro',
'©': 'copy',
'®': 'reg',
'<': 'lt',
'>': 'gt',
'"': 'quot',
'&': 'amp',
'\'': '#39',
} as const;
const regex = new RegExp(`[${ Object.keys(characterToHtmlEntityCode).join('') }]`, 'g');
const toString = (object: unknown): string =>
(object ? `${ object }` : '');
const isEscapable = (char: string): char is keyof typeof characterToHtmlEntityCode =>
char in characterToHtmlEntityCode;
const escapeChar = (char: string): string =>
(isEscapable(char) ? `&${ characterToHtmlEntityCode[char] };` : '');
export const escapeHTML = (str: string): string =>
toString(str).replace(regex, escapeChar);

@ -1,80 +0,0 @@
import assert from 'assert';
import { describe, it } from 'mocha';
import { escapeRegExp } from './escapeRegExp';
describe('escapeRegExp', () => {
it('should keep strings with letters only unchanged', () => {
assert.strictEqual(escapeRegExp('word'), 'word');
});
it('should escape slashes', () => {
assert.strictEqual(escapeRegExp('/slashes/'), '\\/slashes\\/');
assert.strictEqual(escapeRegExp('\\backslashes\\'), '\\\\backslashes\\\\');
assert.strictEqual(escapeRegExp('\\border of word'), '\\\\border of word');
});
it('should escape special group', () => {
assert.strictEqual(escapeRegExp('(?:non-capturing)'), '\\(\\?:non\\-capturing\\)');
assert.strictEqual(
new RegExp(`${ escapeRegExp('(?:') }([^)]+)`).exec('(?:non-capturing)')?.[1],
'non-capturing',
);
assert.strictEqual(escapeRegExp('(?=positive-lookahead)'), '\\(\\?=positive\\-lookahead\\)');
assert.strictEqual(
new RegExp(`${ escapeRegExp('(?=') }([^)]+)`).exec('(?=positive-lookahead)')?.[1],
'positive-lookahead',
);
assert.strictEqual(escapeRegExp('(?<=positive-lookbehind)'), '\\(\\?<=positive\\-lookbehind\\)');
assert.strictEqual(
new RegExp(`${ escapeRegExp('(?<=') }([^)]+)`).exec('(?<=positive-lookbehind)')?.[1],
'positive-lookbehind',
);
assert.strictEqual(escapeRegExp('(?!negative-lookahead)'), '\\(\\?!negative\\-lookahead\\)');
assert.strictEqual(
new RegExp(`${ escapeRegExp('(?!') }([^)]+)`).exec('(?!negative-lookahead)')?.[1],
'negative-lookahead',
);
assert.strictEqual(escapeRegExp('(?<!negative-lookbehind)'), '\\(\\?<!negative\\-lookbehind\\)');
assert.strictEqual(
new RegExp(`${ escapeRegExp('(?<!') }([^)]+)`).exec('(?<!negative-lookbehind)')?.[1],
'negative-lookbehind',
);
assert.strictEqual(escapeRegExp('[\\w]+'), '\\[\\\\w\\]\\+');
assert.strictEqual(new RegExp(`${ escapeRegExp('[') }([^\\]]+)`).exec('[character class]')?.[1], 'character class');
assert.strictEqual(new RegExp(escapeRegExp('<div>')).exec('<td><div></td>')?.[0], '<div>');
assert.strictEqual(escapeRegExp('{5,2}'), '\\{5,2\\}');
assert.strictEqual(
escapeRegExp('/([.*+?^=!:${}()|[\\]\\/\\\\])/g'),
'\\/\\(\\[\\.\\*\\+\\?\\^=!:\\$\\{\\}\\(\\)\\|\\[\\\\\\]\\\\\\/\\\\\\\\\\]\\)\\/g',
);
});
it('should not escape whitespace', () => {
assert.strictEqual(escapeRegExp('\\n\\r\\t'), '\\\\n\\\\r\\\\t');
assert.strictEqual(escapeRegExp('\n\r\t'), '\n\r\t');
});
it('throws an error for non-string argument', () => {
// @ts-ignore
assert.throws(() => escapeRegExp(false));
// @ts-ignore
assert.throws(() => escapeRegExp());
// @ts-ignore
assert.throws(() => escapeRegExp(null));
// @ts-ignore
assert.throws(() => escapeRegExp(42));
});
});

@ -1,6 +0,0 @@
const toString = (object: unknown): string =>
(object ? `${ object }` : '');
export const escapeRegExp = (input: string): string =>
toString(input)
.replace(/[-.*+?^=!:${}()|[\]\/\\]/g, '\\$&');

@ -1,35 +0,0 @@
import assert from 'assert';
import { describe, it } from 'mocha';
import { unescapeHTML } from './unescapeHTML';
describe('unescapeHTML', () => {
it('works', () => {
assert.strictEqual(unescapeHTML('&lt;div&gt;Blah &amp; &quot;blah&quot; &amp; &apos;blah&#39;&lt;/div&gt;'),
'<div>Blah & "blah" & \'blah\'</div>');
assert.strictEqual(unescapeHTML('&amp;lt;'), '&lt;');
assert.strictEqual(unescapeHTML('&apos;'), '\'');
assert.strictEqual(unescapeHTML('&#39;'), '\'');
assert.strictEqual(unescapeHTML('&#0039;'), '\'');
assert.strictEqual(unescapeHTML('&#x4a;'), 'J');
assert.strictEqual(unescapeHTML('&#x04A;'), 'J');
assert.strictEqual(unescapeHTML('&#X4A;'), '&#X4A;');
assert.strictEqual(unescapeHTML('&_#39;'), '&_#39;');
assert.strictEqual(unescapeHTML('&#39_;'), '&#39_;');
assert.strictEqual(unescapeHTML('&amp;#38;'), '&#38;');
assert.strictEqual(unescapeHTML('&#38;amp;'), '&amp;');
assert.strictEqual(unescapeHTML('&#39;'), '\'');
assert.strictEqual(unescapeHTML(''), '');
assert.strictEqual(unescapeHTML('&nbsp;'), ' ');
assert.strictEqual(unescapeHTML('what is the &yen; to &pound; to &euro; conversion process?'), 'what is the ¥ to £ to € conversion process?');
assert.strictEqual(unescapeHTML('&reg; trademark'), '® trademark');
assert.strictEqual(unescapeHTML('&copy; 1992. License available for 50 &cent;'), '© 1992. License available for 50 ¢');
assert.strictEqual(unescapeHTML('&nbsp;'), ' ');
assert.strictEqual(unescapeHTML('&nbsp;'), ' ');
assert.strictEqual(unescapeHTML(null as unknown as string), '');
assert.strictEqual(unescapeHTML(undefined as unknown as string), '');
assert.strictEqual(unescapeHTML(5 as unknown as string), '5');
});
});

@ -1,42 +0,0 @@
const htmlEntityCodeToCharacter = {
nbsp: ' ',
cent: '¢',
pound: '£',
yen: '¥',
euro: '€',
copy: '©',
reg: '®',
lt: '<',
gt: '>',
quot: '"',
amp: '&',
apos: '\'',
} as const;
const toString = (object: unknown): string =>
(object ? `${ object }` : '');
const isHtmlEntityCode = (htmlEntityCode: string): htmlEntityCode is keyof typeof htmlEntityCodeToCharacter =>
htmlEntityCode in htmlEntityCodeToCharacter;
export const unescapeHTML = (str: string): string =>
toString(str)
.replace(/\&([^;]{1,10});/g, (entity, htmlEntityCode) => {
let match;
if (isHtmlEntityCode(htmlEntityCode)) {
return htmlEntityCodeToCharacter[htmlEntityCode];
}
match = htmlEntityCode.match(/^#x([\da-fA-F]+)$/);
if (match) {
return String.fromCharCode(parseInt(match[1], 16));
}
match = htmlEntityCode.match(/^#(\d+)$/);
if (match) {
return String.fromCharCode(~~match[1]);
}
return entity;
});

125
package-lock.json generated

@ -6282,6 +6282,13 @@
"semver": "^5.5.0",
"stack-trace": "0.0.10",
"uuid": "^3.2.1"
},
"dependencies": {
"adm-zip": {
"version": "0.4.16",
"resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.4.16.tgz",
"integrity": "sha512-TFi4HBKSGfIKsK5YCkKaaFG2m4PEDyViZmEwof3MTIgzimHLto6muaHVpbrljdIvIrFZzEq/p4nafOeLcYegrg=="
}
}
},
"@rocket.chat/css-in-js": {
@ -6427,8 +6434,14 @@
"version": "0.24.0",
"resolved": "https://registry.npmjs.org/@rocket.chat/mp3-encoder/-/mp3-encoder-0.24.0.tgz",
"integrity": "sha512-evrPEZP2FgZxQoHbIZrmOZtlvJ0JAjDnFKGaQBEpt49KJA82+qHOpyfALtWsvROyYUvo/xaia7XB4aXfLc+gxw==",
"dependencies": {
"lamejs": {
"version": "git+https://github.com/zhuker/lamejs.git#564612b5b57336238a5920ba4c301b49f7cb2bab",
"from": "git+https://github.com/zhuker/lamejs.git#564612b5b57336238a5920ba4c301b49f7cb2bab",
"requires": {
"lamejs": "git+https://github.com/zhuker/lamejs.git#564612b5b57336238a5920ba4c301b49f7cb2bab"
"use-strict": "1.0.1"
}
}
}
},
"@rocket.chat/sdk": {
@ -6473,6 +6486,21 @@
}
}
},
"@rocket.chat/string-helpers": {
"version": "0.6.3-dev.245",
"resolved": "https://registry.npmjs.org/@rocket.chat/string-helpers/-/string-helpers-0.6.3-dev.245.tgz",
"integrity": "sha512-Xy4Vrxt//Gkp2bi56DmWl5KTQW/SayKuu6aet91E5ZPle95oa+VKM85Kj6bkNLtKmHC0qKg9N3vvUEaLbvjA/w==",
"requires": {
"tslib": "^2.2.0"
},
"dependencies": {
"tslib": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.2.0.tgz",
"integrity": "sha512-gS9GVHRU+RGn5KQM2rllAlR3dU6m7AcpJKdtH8gFvQiC4Otgk98XnmMU+nZenHt/+VhnBPWwgrJsyrdcw6i23w=="
}
}
},
"@rocket.chat/ui-kit": {
"version": "0.24.0",
"resolved": "https://registry.npmjs.org/@rocket.chat/ui-kit/-/ui-kit-0.24.0.tgz",
@ -22880,7 +22908,8 @@
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
"integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
"dev": true
"dev": true,
"optional": true
},
"aproba": {
"version": "1.2.0",
@ -22904,13 +22933,15 @@
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
"integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
"dev": true
"dev": true,
"optional": true
},
"brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
"dev": true,
"optional": true,
"requires": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
@ -22927,19 +22958,22 @@
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
"integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=",
"dev": true
"dev": true,
"optional": true
},
"concat-map": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
"dev": true
"dev": true,
"optional": true
},
"console-control-strings": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
"integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=",
"dev": true
"dev": true,
"optional": true
},
"core-util-is": {
"version": "1.0.2",
@ -23070,7 +23104,8 @@
"version": "2.0.3",
"resolved": false,
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
"dev": true
"dev": true,
"optional": true
},
"ini": {
"version": "1.3.5",
@ -23084,6 +23119,7 @@
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
"integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
"dev": true,
"optional": true,
"requires": {
"number-is-nan": "^1.0.0"
}
@ -23100,6 +23136,7 @@
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
"dev": true,
"optional": true,
"requires": {
"brace-expansion": "^1.1.7"
}
@ -23108,13 +23145,15 @@
"version": "0.0.8",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
"integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=",
"dev": true
"dev": true,
"optional": true
},
"minipass": {
"version": "2.3.5",
"resolved": false,
"integrity": "sha512-Gi1W4k059gyRbyVUZQ4mEqLm0YIUiGYfvxhF6SIlk3ui1WVxMTGfGdQ2SInh3PDrRTVvPKgULkpJtT4RH10+VA==",
"dev": true,
"optional": true,
"requires": {
"safe-buffer": "^5.1.2",
"yallist": "^3.0.0"
@ -23135,6 +23174,7 @@
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
"integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
"dev": true,
"optional": true,
"requires": {
"minimist": "0.0.8"
}
@ -23230,7 +23270,8 @@
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
"integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=",
"dev": true
"dev": true,
"optional": true
},
"object-assign": {
"version": "4.1.1",
@ -23244,6 +23285,7 @@
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
"dev": true,
"optional": true,
"requires": {
"wrappy": "1"
}
@ -23339,7 +23381,8 @@
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
"dev": true
"dev": true,
"optional": true
},
"safer-buffer": {
"version": "2.1.2",
@ -23381,6 +23424,7 @@
"resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
"integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
"dev": true,
"optional": true,
"requires": {
"code-point-at": "^1.0.0",
"is-fullwidth-code-point": "^1.0.0",
@ -23402,6 +23446,7 @@
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
"integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
"dev": true,
"optional": true,
"requires": {
"ansi-regex": "^2.0.0"
}
@ -23450,13 +23495,15 @@
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
"dev": true
"dev": true,
"optional": true
},
"yallist": {
"version": "3.0.3",
"resolved": false,
"integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==",
"dev": true
"dev": true,
"optional": true
}
}
},
@ -23649,7 +23696,8 @@
},
"ansi-regex": {
"version": "2.1.1",
"bundled": true
"bundled": true,
"optional": true
},
"aproba": {
"version": "1.2.0",
@ -23667,11 +23715,13 @@
},
"balanced-match": {
"version": "1.0.0",
"bundled": true
"bundled": true,
"optional": true
},
"brace-expansion": {
"version": "1.1.11",
"bundled": true,
"optional": true,
"requires": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
@ -23684,15 +23734,18 @@
},
"code-point-at": {
"version": "1.1.0",
"bundled": true
"bundled": true,
"optional": true
},
"concat-map": {
"version": "0.0.1",
"bundled": true
"bundled": true,
"optional": true
},
"console-control-strings": {
"version": "1.1.0",
"bundled": true
"bundled": true,
"optional": true
},
"core-util-is": {
"version": "1.0.2",
@ -23795,7 +23848,8 @@
},
"inherits": {
"version": "2.0.3",
"bundled": true
"bundled": true,
"optional": true
},
"ini": {
"version": "1.3.5",
@ -23805,6 +23859,7 @@
"is-fullwidth-code-point": {
"version": "1.0.0",
"bundled": true,
"optional": true,
"requires": {
"number-is-nan": "^1.0.0"
}
@ -23817,17 +23872,20 @@
"minimatch": {
"version": "3.0.4",
"bundled": true,
"optional": true,
"requires": {
"brace-expansion": "^1.1.7"
}
},
"minimist": {
"version": "0.0.8",
"bundled": true
"bundled": true,
"optional": true
},
"minipass": {
"version": "2.3.5",
"bundled": true,
"optional": true,
"requires": {
"safe-buffer": "^5.1.2",
"yallist": "^3.0.0"
@ -23844,6 +23902,7 @@
"mkdirp": {
"version": "0.5.1",
"bundled": true,
"optional": true,
"requires": {
"minimist": "0.0.8"
}
@ -23922,7 +23981,8 @@
},
"number-is-nan": {
"version": "1.0.1",
"bundled": true
"bundled": true,
"optional": true
},
"object-assign": {
"version": "4.1.1",
@ -23932,6 +23992,7 @@
"once": {
"version": "1.4.0",
"bundled": true,
"optional": true,
"requires": {
"wrappy": "1"
}
@ -24007,7 +24068,8 @@
},
"safe-buffer": {
"version": "5.1.2",
"bundled": true
"bundled": true,
"optional": true
},
"safer-buffer": {
"version": "2.1.2",
@ -24037,6 +24099,7 @@
"string-width": {
"version": "1.0.2",
"bundled": true,
"optional": true,
"requires": {
"code-point-at": "^1.0.0",
"is-fullwidth-code-point": "^1.0.0",
@ -24054,6 +24117,7 @@
"strip-ansi": {
"version": "3.0.1",
"bundled": true,
"optional": true,
"requires": {
"ansi-regex": "^2.0.0"
}
@ -24092,11 +24156,13 @@
},
"wrappy": {
"version": "1.0.2",
"bundled": true
"bundled": true,
"optional": true
},
"yallist": {
"version": "3.0.3",
"bundled": true
"bundled": true,
"optional": true
}
}
},
@ -27366,13 +27432,6 @@
"integrity": "sha512-eYboRV94Vco725nKMlpkn3nV2+96p9c3gKXRsYqAJSswSENvBhN7n5L+uDhY58xQa0UukWsDMTGELzmD8Q+wTA==",
"dev": true
},
"lamejs": {
"version": "git+https://github.com/zhuker/lamejs.git#564612b5b57336238a5920ba4c301b49f7cb2bab",
"from": "git+https://github.com/zhuker/lamejs.git",
"requires": {
"use-strict": "1.0.1"
}
},
"lazy-ass": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/lazy-ass/-/lazy-ass-1.6.0.tgz",
@ -39371,11 +39430,6 @@
"use-isomorphic-layout-effect": "^1.0.0"
}
},
"use-strict": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/use-strict/-/use-strict-1.0.1.tgz",
"integrity": "sha1-C7gNlPSaSgUZK4Sox9NOlfGn46A="
},
"use-subscription": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/use-subscription/-/use-subscription-1.4.1.tgz",
@ -39698,6 +39752,7 @@
"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz",
"integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==",
"dev": true,
"optional": true,
"requires": {
"is-extglob": "^2.1.1"
}

@ -151,6 +151,7 @@
"@rocket.chat/memo": "^0.24.0",
"@rocket.chat/message-parser": "^0.6.3-dev.245",
"@rocket.chat/mp3-encoder": "^0.24.0",
"@rocket.chat/string-helpers": "^0.6.3-dev.245",
"@rocket.chat/ui-kit": "^0.24.0",
"@slack/client": "^4.12.0",
"@types/dompurify": "^2.2.1",

@ -1,4 +1,5 @@
import s from 'underscore.string';
import { escapeRegExp } from '@rocket.chat/string-helpers';
import {
hasAllPermission,
@ -10,7 +11,6 @@ import { Users } from '../../app/models/server/raw';
import { settings } from '../../app/settings/server';
import { searchableRoomTypes } from '../../app/utils/server';
import { readSecondaryPreferred } from '../database/readSecondaryPreferred';
import { escapeRegExp } from '../../lib/escapeRegExp';
export class Spotlight {
fetchRooms(userId, rooms) {

@ -2,6 +2,7 @@ import { Meteor } from 'meteor/meteor';
import { DDPRateLimiter } from 'meteor/ddp-rate-limiter';
import s from 'underscore.string';
import mem from 'mem';
import { escapeRegExp } from '@rocket.chat/string-helpers';
import { hasPermission } from '../../app/authorization/server';
import { Rooms, Users, Subscriptions } from '../../app/models/server';
@ -10,7 +11,6 @@ import { settings } from '../../app/settings/server';
import { getFederationDomain } from '../../app/federation/server/lib/getFederationDomain';
import { isFederationEnabled } from '../../app/federation/server/lib/isFederationEnabled';
import { federationSearchUsers } from '../../app/federation/server/handler';
import { escapeRegExp } from '../../lib/escapeRegExp';
import { Team } from '../sdk';
const sortChannels = function(field, direction) {

@ -1,11 +1,11 @@
import { Meteor } from 'meteor/meteor';
import { Match, check } from 'meteor/check';
import { escapeRegExp } from '@rocket.chat/string-helpers';
import { Subscriptions } from '../../app/models/server';
import { Messages } from '../../app/models/server/raw';
import { settings } from '../../app/settings';
import { readSecondaryPreferred } from '../database/readSecondaryPreferred';
import { escapeRegExp } from '../../lib/escapeRegExp';
Meteor.methods({
messageSearch(text, rid, limit) {

@ -1,4 +1,5 @@
import { Db, FindOneOptions } from 'mongodb';
import { escapeRegExp } from '@rocket.chat/string-helpers';
import { checkUsernameAvailability } from '../../../app/lib/server/functions';
import { addUserToRoom } from '../../../app/lib/server/functions/addUserToRoom';
@ -21,7 +22,6 @@ import {
TEAM_TYPE,
} from '../../../definition/ITeam';
import { IUser } from '../../../definition/IUser';
import { escapeRegExp } from '../../../lib/escapeRegExp';
import { Room } from '../../sdk';
import {
IListRoomsFilter,

@ -1,6 +1,7 @@
import { escapeHTML } from '@rocket.chat/string-helpers';
import { Migrations } from '../../../app/migrations';
import { Rooms, Messages } from '../../../app/models';
import { escapeHTML } from '../../../lib/escapeHTML';
Migrations.add({
version: 55,

@ -1,6 +1,7 @@
import { escapeHTML } from '@rocket.chat/string-helpers';
import { Migrations } from '../../../app/migrations';
import { Messages } from '../../../app/models';
import { escapeHTML } from '../../../lib/escapeHTML';
Migrations.add({
version: 64,

Loading…
Cancel
Save