aboutsummaryrefslogtreecommitdiffstats
path: root/server/sonar-web/src/main/js/apps
diff options
context:
space:
mode:
Diffstat (limited to 'server/sonar-web/src/main/js/apps')
-rw-r--r--server/sonar-web/src/main/js/apps/coding-rules/components/ActivationFormModal.tsx14
-rw-r--r--server/sonar-web/src/main/js/apps/coding-rules/components/CustomRuleFormModal.tsx14
-rw-r--r--server/sonar-web/src/main/js/apps/coding-rules/components/RuleDetailsDescription.tsx44
-rw-r--r--server/sonar-web/src/main/js/apps/coding-rules/components/RuleDetailsParameters.tsx15
-rw-r--r--server/sonar-web/src/main/js/apps/coding-rules/components/__tests__/__snapshots__/ActivationFormModal-test.tsx.snap64
-rw-r--r--server/sonar-web/src/main/js/apps/coding-rules/components/__tests__/__snapshots__/CustomRuleFormModal-test.tsx.snap32
-rw-r--r--server/sonar-web/src/main/js/apps/coding-rules/components/__tests__/__snapshots__/RuleDetailsParameters-test.tsx.snap26
-rw-r--r--server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotReviewHistory.tsx12
-rw-r--r--server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/__snapshots__/HotspotReviewHistory-test.tsx.snap128
-rw-r--r--server/sonar-web/src/main/js/apps/sessions/components/Login.tsx11
-rw-r--r--server/sonar-web/src/main/js/apps/settings/components/DefinitionRenderer.tsx13
-rw-r--r--server/sonar-web/src/main/js/apps/settings/components/SubCategoryDefinitionsList.tsx18
-rw-r--r--server/sonar-web/src/main/js/apps/settings/components/__tests__/__snapshots__/DefinitionRenderer-test.tsx.snap96
-rw-r--r--server/sonar-web/src/main/js/apps/settings/components/__tests__/__snapshots__/SubCategoryDefinitionsList-test.tsx.snap48
-rw-r--r--server/sonar-web/src/main/js/apps/settings/components/inputs/InputForFormattedText.tsx15
-rw-r--r--server/sonar-web/src/main/js/apps/web-api/components/Action.tsx10
-rw-r--r--server/sonar-web/src/main/js/apps/web-api/components/Domain.tsx10
-rw-r--r--server/sonar-web/src/main/js/apps/web-api/components/Params.tsx10
-rw-r--r--server/sonar-web/src/main/js/apps/web-api/components/__tests__/__snapshots__/Action-test.tsx.snap15
-rw-r--r--server/sonar-web/src/main/js/apps/web-api/components/__tests__/__snapshots__/Domain-test.tsx.snap90
-rw-r--r--server/sonar-web/src/main/js/apps/web-api/components/__tests__/__snapshots__/Params-test.tsx.snap60
21 files changed, 375 insertions, 370 deletions
diff --git a/server/sonar-web/src/main/js/apps/coding-rules/components/ActivationFormModal.tsx b/server/sonar-web/src/main/js/apps/coding-rules/components/ActivationFormModal.tsx
index 70851441576..531c0162257 100644
--- a/server/sonar-web/src/main/js/apps/coding-rules/components/ActivationFormModal.tsx
+++ b/server/sonar-web/src/main/js/apps/coding-rules/components/ActivationFormModal.tsx
@@ -17,6 +17,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+
import classNames from 'classnames';
import * as React from 'react';
import { OptionTypeBase } from 'react-select';
@@ -26,7 +27,7 @@ import Modal from '../../../components/controls/Modal';
import Select from '../../../components/controls/Select';
import { Alert } from '../../../components/ui/Alert';
import { translate } from '../../../helpers/l10n';
-import { sanitizeString } from '../../../helpers/sanitize';
+import { SafeHTMLInjection, SanitizeLevel } from '../../../helpers/sanitize';
import { Dict, Rule, RuleActivation, RuleDetails } from '../../../types/types';
import { sortProfiles } from '../../quality-profiles/utils';
import { SeveritySelect } from './SeveritySelect';
@@ -218,11 +219,12 @@ export default class ActivationFormModal extends React.PureComponent<Props, Stat
/>
)}
{param.htmlDesc !== undefined && (
- <div
- className="note"
- // eslint-disable-next-line react/no-danger
- dangerouslySetInnerHTML={{ __html: sanitizeString(param.htmlDesc) }}
- />
+ <SafeHTMLInjection
+ htmlAsString={param.htmlDesc}
+ sanitizeLevel={SanitizeLevel.FORBID_SVG_MATHML}
+ >
+ <div className="note" />
+ </SafeHTMLInjection>
)}
</div>
))
diff --git a/server/sonar-web/src/main/js/apps/coding-rules/components/CustomRuleFormModal.tsx b/server/sonar-web/src/main/js/apps/coding-rules/components/CustomRuleFormModal.tsx
index 57c8f242761..55d67cebfad 100644
--- a/server/sonar-web/src/main/js/apps/coding-rules/components/CustomRuleFormModal.tsx
+++ b/server/sonar-web/src/main/js/apps/coding-rules/components/CustomRuleFormModal.tsx
@@ -17,6 +17,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+
import * as React from 'react';
import { components, OptionProps, OptionTypeBase, SingleValueProps } from 'react-select';
import { createRule, updateRule } from '../../../api/rules';
@@ -31,7 +32,7 @@ import MandatoryFieldsExplanation from '../../../components/ui/MandatoryFieldsEx
import { RULE_STATUSES, RULE_TYPES } from '../../../helpers/constants';
import { csvEscape } from '../../../helpers/csv';
import { translate } from '../../../helpers/l10n';
-import { sanitizeString } from '../../../helpers/sanitize';
+import { SafeHTMLInjection, SanitizeLevel } from '../../../helpers/sanitize';
import { latinize } from '../../../helpers/strings';
import { Dict, RuleDetails, RuleParameter } from '../../../types/types';
import { SeveritySelect } from './SeveritySelect';
@@ -317,11 +318,12 @@ export default class CustomRuleFormModal extends React.PureComponent<Props, Stat
/>
)}
{param.htmlDesc !== undefined && (
- <div
- className="modal-field-description"
- // eslint-disable-next-line react/no-danger
- dangerouslySetInnerHTML={{ __html: sanitizeString(param.htmlDesc) }}
- />
+ <SafeHTMLInjection
+ htmlAsString={param.htmlDesc}
+ sanitizeLevel={SanitizeLevel.FORBID_SVG_MATHML}
+ >
+ <div className="modal-field-description" />
+ </SafeHTMLInjection>
)}
</div>
);
diff --git a/server/sonar-web/src/main/js/apps/coding-rules/components/RuleDetailsDescription.tsx b/server/sonar-web/src/main/js/apps/coding-rules/components/RuleDetailsDescription.tsx
index a7fd2cb2c89..8fe97276bc6 100644
--- a/server/sonar-web/src/main/js/apps/coding-rules/components/RuleDetailsDescription.tsx
+++ b/server/sonar-web/src/main/js/apps/coding-rules/components/RuleDetailsDescription.tsx
@@ -17,13 +17,14 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+
import * as React from 'react';
import { updateRule } from '../../../api/rules';
import FormattingTips from '../../../components/common/FormattingTips';
import { Button, ResetButtonLink } from '../../../components/controls/buttons';
import RuleTabViewer from '../../../components/rules/RuleTabViewer';
import { translate, translateWithParameters } from '../../../helpers/l10n';
-import { sanitizeString, sanitizeUserInput } from '../../../helpers/sanitize';
+import { SafeHTMLInjection, SanitizeLevel } from '../../../helpers/sanitize';
import { RuleDetails } from '../../../types/types';
import { RuleDescriptionSections } from '../rule';
import RemoveExtendedDescriptionModal from './RemoveExtendedDescriptionModal';
@@ -112,14 +113,14 @@ export default class RuleDetailsDescription extends React.PureComponent<Props, S
renderExtendedDescription = () => (
<div id="coding-rules-detail-description-extra">
{this.props.ruleDetails.htmlNote !== undefined && (
- <div
- className="rule-desc spacer-bottom markdown"
- // eslint-disable-next-line react/no-danger
- dangerouslySetInnerHTML={{
- __html: sanitizeUserInput(this.props.ruleDetails.htmlNote),
- }}
- />
+ <SafeHTMLInjection
+ htmlAsString={this.props.ruleDetails.htmlNote}
+ sanitizeLevel={SanitizeLevel.USER_INPUT}
+ >
+ <div className="rule-desc spacer-bottom markdown" />
+ </SafeHTMLInjection>
)}
+
{this.props.canWrite && (
<Button
id="coding-rules-detail-extend-description"
@@ -216,23 +217,28 @@ export default class RuleDetailsDescription extends React.PureComponent<Props, S
return (
<div className="js-rule-description">
{defaultSection && (
- <section
- className="coding-rules-detail-description markdown"
- key={defaultSection.key}
- /* eslint-disable-next-line react/no-danger */
- dangerouslySetInnerHTML={{ __html: sanitizeString(defaultSection.content) }}
- />
+ <SafeHTMLInjection
+ htmlAsString={defaultSection.content}
+ sanitizeLevel={SanitizeLevel.FORBID_SVG_MATHML}
+ >
+ <section
+ className="coding-rules-detail-description markdown"
+ key={defaultSection.key}
+ />
+ </SafeHTMLInjection>
)}
{hasDescriptionSection && !defaultSection && (
<>
{introductionSection && (
- <div
- className="rule-desc"
- // eslint-disable-next-line react/no-danger
- dangerouslySetInnerHTML={{ __html: sanitizeString(introductionSection) }}
- />
+ <SafeHTMLInjection
+ htmlAsString={introductionSection}
+ sanitizeLevel={SanitizeLevel.FORBID_SVG_MATHML}
+ >
+ <div className="rule-desc" />
+ </SafeHTMLInjection>
)}
+
<RuleTabViewer ruleDetails={ruleDetails} />
</>
)}
diff --git a/server/sonar-web/src/main/js/apps/coding-rules/components/RuleDetailsParameters.tsx b/server/sonar-web/src/main/js/apps/coding-rules/components/RuleDetailsParameters.tsx
index 512219441a3..50a50c4adb5 100644
--- a/server/sonar-web/src/main/js/apps/coding-rules/components/RuleDetailsParameters.tsx
+++ b/server/sonar-web/src/main/js/apps/coding-rules/components/RuleDetailsParameters.tsx
@@ -17,9 +17,10 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+
import * as React from 'react';
import { translate } from '../../../helpers/l10n';
-import { sanitizeString } from '../../../helpers/sanitize';
+import { SafeHTMLInjection, SanitizeLevel } from '../../../helpers/sanitize';
import { RuleParameter } from '../../../types/types';
interface Props {
@@ -30,13 +31,17 @@ export default class RuleDetailsParameters extends React.PureComponent<Props> {
renderParameter = (param: RuleParameter) => (
<tr className="coding-rules-detail-parameter" key={param.key}>
<td className="coding-rules-detail-parameter-name">{param.key}</td>
+
<td className="coding-rules-detail-parameter-description">
{param.htmlDesc !== undefined && (
- <p
- // eslint-disable-next-line react/no-danger
- dangerouslySetInnerHTML={{ __html: sanitizeString(param.htmlDesc) }}
- />
+ <SafeHTMLInjection
+ htmlAsString={param.htmlDesc}
+ sanitizeLevel={SanitizeLevel.FORBID_SVG_MATHML}
+ >
+ <p />
+ </SafeHTMLInjection>
)}
+
{param.defaultValue !== undefined && (
<div className="note spacer-top">
{translate('coding_rules.parameters.default_value')}
diff --git a/server/sonar-web/src/main/js/apps/coding-rules/components/__tests__/__snapshots__/ActivationFormModal-test.tsx.snap b/server/sonar-web/src/main/js/apps/coding-rules/components/__tests__/__snapshots__/ActivationFormModal-test.tsx.snap
index 218e1a3d16e..680fb4d5d02 100644
--- a/server/sonar-web/src/main/js/apps/coding-rules/components/__tests__/__snapshots__/ActivationFormModal-test.tsx.snap
+++ b/server/sonar-web/src/main/js/apps/coding-rules/components/__tests__/__snapshots__/ActivationFormModal-test.tsx.snap
@@ -160,14 +160,14 @@ exports[`should render correctly: default 1`] = `
type="text"
value="1"
/>
- <div
- className="note"
- dangerouslySetInnerHTML={
- {
- "__html": "description",
- }
- }
- />
+ <SafeHTMLInjection
+ htmlAsString="description"
+ sanitizeLevel={1}
+ >
+ <div
+ className="note"
+ />
+ </SafeHTMLInjection>
</div>
<div
className="modal-field"
@@ -281,14 +281,14 @@ exports[`should render correctly: submitting 1`] = `
type="text"
value="1"
/>
- <div
- className="note"
- dangerouslySetInnerHTML={
- {
- "__html": "description",
- }
- }
- />
+ <SafeHTMLInjection
+ htmlAsString="description"
+ sanitizeLevel={1}
+ >
+ <div
+ className="note"
+ />
+ </SafeHTMLInjection>
</div>
<div
className="modal-field"
@@ -400,14 +400,14 @@ exports[`should render correctly: update mode 1`] = `
type="text"
value="1"
/>
- <div
- className="note"
- dangerouslySetInnerHTML={
- {
- "__html": "description",
- }
- }
- />
+ <SafeHTMLInjection
+ htmlAsString="description"
+ sanitizeLevel={1}
+ >
+ <div
+ className="note"
+ />
+ </SafeHTMLInjection>
</div>
<div
className="modal-field"
@@ -555,14 +555,14 @@ exports[`should render correctly: with deep profiles 1`] = `
type="text"
value="1"
/>
- <div
- className="note"
- dangerouslySetInnerHTML={
- {
- "__html": "description",
- }
- }
- />
+ <SafeHTMLInjection
+ htmlAsString="description"
+ sanitizeLevel={1}
+ >
+ <div
+ className="note"
+ />
+ </SafeHTMLInjection>
</div>
<div
className="modal-field"
diff --git a/server/sonar-web/src/main/js/apps/coding-rules/components/__tests__/__snapshots__/CustomRuleFormModal-test.tsx.snap b/server/sonar-web/src/main/js/apps/coding-rules/components/__tests__/__snapshots__/CustomRuleFormModal-test.tsx.snap
index 77ad50e79a5..c376249c83a 100644
--- a/server/sonar-web/src/main/js/apps/coding-rules/components/__tests__/__snapshots__/CustomRuleFormModal-test.tsx.snap
+++ b/server/sonar-web/src/main/js/apps/coding-rules/components/__tests__/__snapshots__/CustomRuleFormModal-test.tsx.snap
@@ -210,14 +210,14 @@ exports[`should handle re-activation 1`] = `
type="text"
value=""
/>
- <div
- className="modal-field-description"
- dangerouslySetInnerHTML={
- {
- "__html": "description",
- }
- }
- />
+ <SafeHTMLInjection
+ htmlAsString="description"
+ sanitizeLevel={1}
+ >
+ <div
+ className="modal-field-description"
+ />
+ </SafeHTMLInjection>
</div>
<div
className="modal-field"
@@ -465,14 +465,14 @@ exports[`should render correctly: default 1`] = `
type="text"
value=""
/>
- <div
- className="modal-field-description"
- dangerouslySetInnerHTML={
- {
- "__html": "description",
- }
- }
- />
+ <SafeHTMLInjection
+ htmlAsString="description"
+ sanitizeLevel={1}
+ >
+ <div
+ className="modal-field-description"
+ />
+ </SafeHTMLInjection>
</div>
<div
className="modal-field"
diff --git a/server/sonar-web/src/main/js/apps/coding-rules/components/__tests__/__snapshots__/RuleDetailsParameters-test.tsx.snap b/server/sonar-web/src/main/js/apps/coding-rules/components/__tests__/__snapshots__/RuleDetailsParameters-test.tsx.snap
index 1c441e4738e..b6f155022ac 100644
--- a/server/sonar-web/src/main/js/apps/coding-rules/components/__tests__/__snapshots__/RuleDetailsParameters-test.tsx.snap
+++ b/server/sonar-web/src/main/js/apps/coding-rules/components/__tests__/__snapshots__/RuleDetailsParameters-test.tsx.snap
@@ -25,13 +25,12 @@ exports[`should render correctly 1`] = `
<td
className="coding-rules-detail-parameter-description"
>
- <p
- dangerouslySetInnerHTML={
- {
- "__html": "description",
- }
- }
- />
+ <SafeHTMLInjection
+ htmlAsString="description"
+ sanitizeLevel={1}
+ >
+ <p />
+ </SafeHTMLInjection>
<div
className="note spacer-top"
>
@@ -57,13 +56,12 @@ exports[`should render correctly 1`] = `
<td
className="coding-rules-detail-parameter-description"
>
- <p
- dangerouslySetInnerHTML={
- {
- "__html": "description",
- }
- }
- />
+ <SafeHTMLInjection
+ htmlAsString="description"
+ sanitizeLevel={1}
+ >
+ <p />
+ </SafeHTMLInjection>
<div
className="note spacer-top"
>
diff --git a/server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotReviewHistory.tsx b/server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotReviewHistory.tsx
index f0dfe918a19..d08a688e1d2 100644
--- a/server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotReviewHistory.tsx
+++ b/server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotReviewHistory.tsx
@@ -17,6 +17,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+
import classNames from 'classnames';
import * as React from 'react';
import { Button, ButtonLink, DeleteButton, EditButton } from '../../../components/controls/buttons';
@@ -27,7 +28,7 @@ import IssueChangelogDiff from '../../../components/issue/components/IssueChange
import Avatar from '../../../components/ui/Avatar';
import { PopupPlacement } from '../../../components/ui/popups';
import { translate, translateWithParameters } from '../../../helpers/l10n';
-import { sanitizeUserInput } from '../../../helpers/sanitize';
+import { SafeHTMLInjection, SanitizeLevel } from '../../../helpers/sanitize';
import { Hotspot, ReviewHistoryType } from '../../../types/security-hotspots';
import { getHotspotReviewHistory } from '../utils';
import HotspotCommentPopup from './HotspotCommentPopup';
@@ -103,11 +104,10 @@ export default function HotspotReviewHistory(props: HotspotReviewHistoryProps) {
{type === ReviewHistoryType.Comment && key && html && markdown && (
<div className="spacer-top display-flex-space-between">
- <div
- className="markdown"
- // eslint-disable-next-line react/no-danger
- dangerouslySetInnerHTML={{ __html: sanitizeUserInput(html) }}
- />
+ <SafeHTMLInjection htmlAsString={html} sanitizeLevel={SanitizeLevel.USER_INPUT}>
+ <div className="markdown" />
+ </SafeHTMLInjection>
+
{updatable && (
<div>
<div className="dropdown">
diff --git a/server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/__snapshots__/HotspotReviewHistory-test.tsx.snap b/server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/__snapshots__/HotspotReviewHistory-test.tsx.snap
index 98e92766989..01b25206020 100644
--- a/server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/__snapshots__/HotspotReviewHistory-test.tsx.snap
+++ b/server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/__snapshots__/HotspotReviewHistory-test.tsx.snap
@@ -113,14 +113,14 @@ exports[`should render correctly: default 1`] = `
<div
className="spacer-top display-flex-space-between"
>
- <div
- className="markdown"
- dangerouslySetInnerHTML={
- {
- "__html": "<strong>TEST</strong>",
- }
- }
- />
+ <SafeHTMLInjection
+ htmlAsString="<strong>TEST</strong>"
+ sanitizeLevel={2}
+ >
+ <div
+ className="markdown"
+ />
+ </SafeHTMLInjection>
</div>
</li>
<li
@@ -155,14 +155,14 @@ exports[`should render correctly: default 1`] = `
<div
className="spacer-top display-flex-space-between"
>
- <div
- className="markdown"
- dangerouslySetInnerHTML={
- {
- "__html": "<strong>TEST</strong>",
- }
- }
- />
+ <SafeHTMLInjection
+ htmlAsString="<strong>TEST</strong>"
+ sanitizeLevel={2}
+ >
+ <div
+ className="markdown"
+ />
+ </SafeHTMLInjection>
</div>
</li>
<li
@@ -197,14 +197,14 @@ exports[`should render correctly: default 1`] = `
<div
className="spacer-top display-flex-space-between"
>
- <div
- className="markdown"
- dangerouslySetInnerHTML={
- {
- "__html": "<strong>TEST</strong>",
- }
- }
- />
+ <SafeHTMLInjection
+ htmlAsString="<strong>TEST</strong>"
+ sanitizeLevel={2}
+ >
+ <div
+ className="markdown"
+ />
+ </SafeHTMLInjection>
</div>
</li>
</ul>
@@ -358,14 +358,14 @@ exports[`should render correctly: show full list 1`] = `
<div
className="spacer-top display-flex-space-between"
>
- <div
- className="markdown"
- dangerouslySetInnerHTML={
- {
- "__html": "<strong>TEST</strong>",
- }
- }
- />
+ <SafeHTMLInjection
+ htmlAsString="<strong>TEST</strong>"
+ sanitizeLevel={2}
+ >
+ <div
+ className="markdown"
+ />
+ </SafeHTMLInjection>
</div>
</li>
<li
@@ -400,14 +400,14 @@ exports[`should render correctly: show full list 1`] = `
<div
className="spacer-top display-flex-space-between"
>
- <div
- className="markdown"
- dangerouslySetInnerHTML={
- {
- "__html": "<strong>TEST</strong>",
- }
- }
- />
+ <SafeHTMLInjection
+ htmlAsString="<strong>TEST</strong>"
+ sanitizeLevel={2}
+ >
+ <div
+ className="markdown"
+ />
+ </SafeHTMLInjection>
</div>
</li>
<li
@@ -442,14 +442,14 @@ exports[`should render correctly: show full list 1`] = `
<div
className="spacer-top display-flex-space-between"
>
- <div
- className="markdown"
- dangerouslySetInnerHTML={
- {
- "__html": "<strong>TEST</strong>",
- }
- }
- />
+ <SafeHTMLInjection
+ htmlAsString="<strong>TEST</strong>"
+ sanitizeLevel={2}
+ >
+ <div
+ className="markdown"
+ />
+ </SafeHTMLInjection>
</div>
</li>
<li
@@ -484,14 +484,14 @@ exports[`should render correctly: show full list 1`] = `
<div
className="spacer-top display-flex-space-between"
>
- <div
- className="markdown"
- dangerouslySetInnerHTML={
- {
- "__html": "<strong>TEST</strong>",
- }
- }
- />
+ <SafeHTMLInjection
+ htmlAsString="<strong>TEST</strong>"
+ sanitizeLevel={2}
+ >
+ <div
+ className="markdown"
+ />
+ </SafeHTMLInjection>
</div>
</li>
<li
@@ -526,14 +526,14 @@ exports[`should render correctly: show full list 1`] = `
<div
className="spacer-top display-flex-space-between"
>
- <div
- className="markdown"
- dangerouslySetInnerHTML={
- {
- "__html": "<strong>TEST</strong>",
- }
- }
- />
+ <SafeHTMLInjection
+ htmlAsString="<strong>TEST</strong>"
+ sanitizeLevel={2}
+ >
+ <div
+ className="markdown"
+ />
+ </SafeHTMLInjection>
<div>
<div
className="dropdown"
diff --git a/server/sonar-web/src/main/js/apps/sessions/components/Login.tsx b/server/sonar-web/src/main/js/apps/sessions/components/Login.tsx
index e6943d126bf..d7b134d53db 100644
--- a/server/sonar-web/src/main/js/apps/sessions/components/Login.tsx
+++ b/server/sonar-web/src/main/js/apps/sessions/components/Login.tsx
@@ -17,12 +17,13 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+
import * as React from 'react';
import { Location } from '../../../components/hoc/withRouter';
import { Alert } from '../../../components/ui/Alert';
import DeferredSpinner from '../../../components/ui/DeferredSpinner';
import { translate } from '../../../helpers/l10n';
-import { sanitizeUserInput } from '../../../helpers/sanitize';
+import { SafeHTMLInjection, SanitizeLevel } from '../../../helpers/sanitize';
import { getReturnUrl } from '../../../helpers/urls';
import { IdentityProvider } from '../../../types/types';
import './Login.css';
@@ -59,11 +60,9 @@ export default function Login(props: LoginProps) {
)}
{message && (
- <div
- className="login-message markdown big-padded spacer-top huge-spacer-bottom"
- // eslint-disable-next-line react/no-danger
- dangerouslySetInnerHTML={{ __html: sanitizeUserInput(message) }}
- />
+ <SafeHTMLInjection htmlAsString={message} sanitizeLevel={SanitizeLevel.USER_INPUT}>
+ <div className="login-message markdown big-padded spacer-top huge-spacer-bottom" />
+ </SafeHTMLInjection>
)}
{identityProviders.length > 0 && (
diff --git a/server/sonar-web/src/main/js/apps/settings/components/DefinitionRenderer.tsx b/server/sonar-web/src/main/js/apps/settings/components/DefinitionRenderer.tsx
index 13163d279ca..3a8a0c43eac 100644
--- a/server/sonar-web/src/main/js/apps/settings/components/DefinitionRenderer.tsx
+++ b/server/sonar-web/src/main/js/apps/settings/components/DefinitionRenderer.tsx
@@ -17,13 +17,14 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+
import classNames from 'classnames';
import * as React from 'react';
import Tooltip from '../../../components/controls/Tooltip';
import AlertErrorIcon from '../../../components/icons/AlertErrorIcon';
import AlertSuccessIcon from '../../../components/icons/AlertSuccessIcon';
import { translate, translateWithParameters } from '../../../helpers/l10n';
-import { sanitizeStringRestricted } from '../../../helpers/sanitize';
+import { SafeHTMLInjection, SanitizeLevel } from '../../../helpers/sanitize';
import { ExtendedSettingDefinition, SettingValue } from '../../../types/settings';
import {
combineDefinitionAndSettingValue,
@@ -52,7 +53,7 @@ export interface DefinitionRendererProps {
const formNoop = (e: React.FormEvent<HTMLFormElement>) => e.preventDefault();
-export default function DefinitionRenderer(props: DefinitionRendererProps) {
+export default function DefinitionRenderer(props: Readonly<DefinitionRendererProps>) {
const { changedValue, loading, validationMessage, settingValue, success, definition, isEditing } =
props;
@@ -78,11 +79,9 @@ export default function DefinitionRenderer(props: DefinitionRendererProps) {
</h3>
{description && (
- <div
- className="markdown small spacer-top"
- // eslint-disable-next-line react/no-danger
- dangerouslySetInnerHTML={{ __html: sanitizeStringRestricted(description) }}
- />
+ <SafeHTMLInjection htmlAsString={description} sanitizeLevel={SanitizeLevel.RESTRICTED}>
+ <div className="markdown small spacer-top" />
+ </SafeHTMLInjection>
)}
<Tooltip overlay={translateWithParameters('settings.key_x', definition.key)}>
diff --git a/server/sonar-web/src/main/js/apps/settings/components/SubCategoryDefinitionsList.tsx b/server/sonar-web/src/main/js/apps/settings/components/SubCategoryDefinitionsList.tsx
index 3267c22cdb9..65664b469ae 100644
--- a/server/sonar-web/src/main/js/apps/settings/components/SubCategoryDefinitionsList.tsx
+++ b/server/sonar-web/src/main/js/apps/settings/components/SubCategoryDefinitionsList.tsx
@@ -17,10 +17,11 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+
import { groupBy, sortBy } from 'lodash';
import * as React from 'react';
import { Location, withRouter } from '../../../components/hoc/withRouter';
-import { sanitizeStringRestricted } from '../../../helpers/sanitize';
+import { SafeHTMLInjection, SanitizeLevel } from '../../../helpers/sanitize';
import { SettingDefinitionAndValue } from '../../../types/settings';
import { Component } from '../../../types/types';
import { getSubCategoryDescription, getSubCategoryName } from '../utils';
@@ -91,15 +92,16 @@ export class SubCategoryDefinitionsList extends React.PureComponent<SubCategoryD
{subCategory.name}
</h2>
)}
+
{subCategory.description != null && (
- <div
- className="settings-sub-category-description markdown"
- // eslint-disable-next-line react/no-danger
- dangerouslySetInnerHTML={{
- __html: sanitizeStringRestricted(subCategory.description),
- }}
- />
+ <SafeHTMLInjection
+ htmlAsString={subCategory.description}
+ sanitizeLevel={SanitizeLevel.RESTRICTED}
+ >
+ <div className="settings-sub-category-description markdown" />
+ </SafeHTMLInjection>
)}
+
<DefinitionsList
component={component}
scrollToDefinition={this.scrollToSubCategoryOrDefinition}
diff --git a/server/sonar-web/src/main/js/apps/settings/components/__tests__/__snapshots__/DefinitionRenderer-test.tsx.snap b/server/sonar-web/src/main/js/apps/settings/components/__tests__/__snapshots__/DefinitionRenderer-test.tsx.snap
index 021e807d1af..31031f47af8 100644
--- a/server/sonar-web/src/main/js/apps/settings/components/__tests__/__snapshots__/DefinitionRenderer-test.tsx.snap
+++ b/server/sonar-web/src/main/js/apps/settings/components/__tests__/__snapshots__/DefinitionRenderer-test.tsx.snap
@@ -14,14 +14,14 @@ exports[`should render correctly: changed value 1`] = `
>
property.foo.name
</h3>
- <div
- className="markdown small spacer-top"
- dangerouslySetInnerHTML={
- {
- "__html": "property.foo.description",
- }
- }
- />
+ <SafeHTMLInjection
+ htmlAsString="property.foo.description"
+ sanitizeLevel={3}
+ >
+ <div
+ className="markdown small spacer-top"
+ />
+ </SafeHTMLInjection>
<Tooltip
overlay="settings.key_x.foo"
>
@@ -105,14 +105,14 @@ exports[`should render correctly: in error 1`] = `
>
property.foo.name
</h3>
- <div
- className="markdown small spacer-top"
- dangerouslySetInnerHTML={
- {
- "__html": "property.foo.description",
- }
- }
- />
+ <SafeHTMLInjection
+ htmlAsString="property.foo.description"
+ sanitizeLevel={3}
+ >
+ <div
+ className="markdown small spacer-top"
+ />
+ </SafeHTMLInjection>
<Tooltip
overlay="settings.key_x.foo"
>
@@ -205,14 +205,14 @@ exports[`should render correctly: loading 1`] = `
>
property.foo.name
</h3>
- <div
- className="markdown small spacer-top"
- dangerouslySetInnerHTML={
- {
- "__html": "property.foo.description",
- }
- }
- />
+ <SafeHTMLInjection
+ htmlAsString="property.foo.description"
+ sanitizeLevel={3}
+ >
+ <div
+ className="markdown small spacer-top"
+ />
+ </SafeHTMLInjection>
<Tooltip
overlay="settings.key_x.foo"
>
@@ -303,14 +303,14 @@ exports[`should render correctly: original value 1`] = `
>
property.foo.name
</h3>
- <div
- className="markdown small spacer-top"
- dangerouslySetInnerHTML={
- {
- "__html": "property.foo.description",
- }
- }
- />
+ <SafeHTMLInjection
+ htmlAsString="property.foo.description"
+ sanitizeLevel={3}
+ >
+ <div
+ className="markdown small spacer-top"
+ />
+ </SafeHTMLInjection>
<Tooltip
overlay="settings.key_x.foo"
>
@@ -395,14 +395,14 @@ exports[`should render correctly: success 1`] = `
>
property.foo.name
</h3>
- <div
- className="markdown small spacer-top"
- dangerouslySetInnerHTML={
- {
- "__html": "property.foo.description",
- }
- }
- />
+ <SafeHTMLInjection
+ htmlAsString="property.foo.description"
+ sanitizeLevel={3}
+ >
+ <div
+ className="markdown small spacer-top"
+ />
+ </SafeHTMLInjection>
<Tooltip
overlay="settings.key_x.foo"
>
@@ -493,14 +493,14 @@ exports[`should render correctly: with description 1`] = `
>
property.foo.name
</h3>
- <div
- className="markdown small spacer-top"
- dangerouslySetInnerHTML={
- {
- "__html": "property.foo.description",
- }
- }
- />
+ <SafeHTMLInjection
+ htmlAsString="property.foo.description"
+ sanitizeLevel={3}
+ >
+ <div
+ className="markdown small spacer-top"
+ />
+ </SafeHTMLInjection>
<Tooltip
overlay="settings.key_x.foo"
>
diff --git a/server/sonar-web/src/main/js/apps/settings/components/__tests__/__snapshots__/SubCategoryDefinitionsList-test.tsx.snap b/server/sonar-web/src/main/js/apps/settings/components/__tests__/__snapshots__/SubCategoryDefinitionsList-test.tsx.snap
index 9e70241ec02..2e7ab454375 100644
--- a/server/sonar-web/src/main/js/apps/settings/components/__tests__/__snapshots__/SubCategoryDefinitionsList-test.tsx.snap
+++ b/server/sonar-web/src/main/js/apps/settings/components/__tests__/__snapshots__/SubCategoryDefinitionsList-test.tsx.snap
@@ -13,14 +13,14 @@ exports[`should render correctly 1`] = `
>
property.category.general.email
</h2>
- <div
- className="settings-sub-category-description markdown"
- dangerouslySetInnerHTML={
- {
- "__html": "property.category.general.email.description",
- }
- }
- />
+ <SafeHTMLInjection
+ htmlAsString="property.category.general.email.description"
+ sanitizeLevel={3}
+ >
+ <div
+ className="settings-sub-category-description markdown"
+ />
+ </SafeHTMLInjection>
<DefinitionsList
scrollToDefinition={[Function]}
settings={
@@ -55,14 +55,14 @@ exports[`should render correctly 1`] = `
>
property.category.general.qg
</h2>
- <div
- className="settings-sub-category-description markdown"
- dangerouslySetInnerHTML={
- {
- "__html": "property.category.general.qg.description",
- }
- }
- />
+ <SafeHTMLInjection
+ htmlAsString="property.category.general.qg.description"
+ sanitizeLevel={3}
+ >
+ <div
+ className="settings-sub-category-description markdown"
+ />
+ </SafeHTMLInjection>
<DefinitionsList
scrollToDefinition={[Function]}
settings={
@@ -101,14 +101,14 @@ exports[`should render correctly: subcategory 1`] = `
>
property.category.general.qg
</h2>
- <div
- className="settings-sub-category-description markdown"
- dangerouslySetInnerHTML={
- {
- "__html": "property.category.general.qg.description",
- }
- }
- />
+ <SafeHTMLInjection
+ htmlAsString="property.category.general.qg.description"
+ sanitizeLevel={3}
+ >
+ <div
+ className="settings-sub-category-description markdown"
+ />
+ </SafeHTMLInjection>
<DefinitionsList
scrollToDefinition={[Function]}
settings={
diff --git a/server/sonar-web/src/main/js/apps/settings/components/inputs/InputForFormattedText.tsx b/server/sonar-web/src/main/js/apps/settings/components/inputs/InputForFormattedText.tsx
index 56ed64d587a..699a9fc56da 100644
--- a/server/sonar-web/src/main/js/apps/settings/components/inputs/InputForFormattedText.tsx
+++ b/server/sonar-web/src/main/js/apps/settings/components/inputs/InputForFormattedText.tsx
@@ -17,12 +17,13 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+
import * as React from 'react';
import FormattingTipsWithLink from '../../../../components/common/FormattingTipsWithLink';
import { Button } from '../../../../components/controls/buttons';
import EditIcon from '../../../../components/icons/EditIcon';
import { translate } from '../../../../helpers/l10n';
-import { sanitizeUserInput } from '../../../../helpers/sanitize';
+import { SafeHTMLInjection, SanitizeLevel } from '../../../../helpers/sanitize';
import { DefaultSpecializedInputProps } from '../../utils';
export default function InputForFormattedText(props: DefaultSpecializedInputProps) {
@@ -51,11 +52,13 @@ export default function InputForFormattedText(props: DefaultSpecializedInputProp
</div>
) : (
<>
- <div
- className="markdown-preview markdown"
- // eslint-disable-next-line react/no-danger
- dangerouslySetInnerHTML={{ __html: sanitizeUserInput(formattedValue ?? '') }}
- />
+ <SafeHTMLInjection
+ htmlAsString={formattedValue ?? ''}
+ sanitizeLevel={SanitizeLevel.USER_INPUT}
+ >
+ <div className="markdown-preview markdown" />
+ </SafeHTMLInjection>
+
<Button className="spacer-top" onClick={props.onEditing}>
<EditIcon className="spacer-right" />
{translate('edit')}
diff --git a/server/sonar-web/src/main/js/apps/web-api/components/Action.tsx b/server/sonar-web/src/main/js/apps/web-api/components/Action.tsx
index 3d0ce681a53..691e2118a82 100644
--- a/server/sonar-web/src/main/js/apps/web-api/components/Action.tsx
+++ b/server/sonar-web/src/main/js/apps/web-api/components/Action.tsx
@@ -17,11 +17,13 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+
import classNames from 'classnames';
import * as React from 'react';
import Link from '../../../components/common/Link';
import LinkIcon from '../../../components/icons/LinkIcon';
import { translate, translateWithParameters } from '../../../helpers/l10n';
+import { SafeHTMLInjection } from '../../../helpers/sanitize';
import { queryToSearch } from '../../../helpers/urls';
import { WebApi } from '../../../types/types';
import { getActionKey, serializeQuery } from '../utils';
@@ -177,11 +179,9 @@ export default class Action extends React.PureComponent<Props, State> {
</header>
<div className="boxed-group-inner">
- <div
- className="web-api-action-description markdown"
- // Safe: comes from the backend
- dangerouslySetInnerHTML={{ __html: action.description }}
- />
+ <SafeHTMLInjection htmlAsString={action.description}>
+ <div className="web-api-action-description markdown" />
+ </SafeHTMLInjection>
{this.renderTabs()}
diff --git a/server/sonar-web/src/main/js/apps/web-api/components/Domain.tsx b/server/sonar-web/src/main/js/apps/web-api/components/Domain.tsx
index aa072b597ce..d7fed0b0053 100644
--- a/server/sonar-web/src/main/js/apps/web-api/components/Domain.tsx
+++ b/server/sonar-web/src/main/js/apps/web-api/components/Domain.tsx
@@ -17,7 +17,9 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+
import * as React from 'react';
+import { SafeHTMLInjection } from '../../../helpers/sanitize';
import { WebApi } from '../../../types/types';
import { actionsFilter, getActionKey, Query } from '../utils';
import Action from './Action';
@@ -51,11 +53,9 @@ export default function Domain({ domain, query }: Props) {
</header>
{domain.description && (
- <div
- className="web-api-domain-description markdown"
- // Safe: comes from the backend
- dangerouslySetInnerHTML={{ __html: domain.description }}
- />
+ <SafeHTMLInjection htmlAsString={domain.description}>
+ <div className="web-api-domain-description markdown" />
+ </SafeHTMLInjection>
)}
<div className="web-api-domain-actions">
diff --git a/server/sonar-web/src/main/js/apps/web-api/components/Params.tsx b/server/sonar-web/src/main/js/apps/web-api/components/Params.tsx
index 71af96386ce..da31aa4a883 100644
--- a/server/sonar-web/src/main/js/apps/web-api/components/Params.tsx
+++ b/server/sonar-web/src/main/js/apps/web-api/components/Params.tsx
@@ -17,8 +17,10 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+
import * as React from 'react';
import { translate, translateWithParameters } from '../../../helpers/l10n';
+import { SafeHTMLInjection } from '../../../helpers/sanitize';
import { WebApi } from '../../../types/types';
import DeprecatedBadge from './DeprecatedBadge';
import InternalBadge from './InternalBadge';
@@ -98,11 +100,9 @@ export default class Params extends React.PureComponent<Props> {
{this.renderKey(param)}
<td>
- <div
- className="markdown"
- // Safe: comes from the backend
- dangerouslySetInnerHTML={{ __html: param.description }}
- />
+ <SafeHTMLInjection htmlAsString={param.description}>
+ <div className="markdown" />
+ </SafeHTMLInjection>
</td>
<td style={{ width: 250 }}>
diff --git a/server/sonar-web/src/main/js/apps/web-api/components/__tests__/__snapshots__/Action-test.tsx.snap b/server/sonar-web/src/main/js/apps/web-api/components/__tests__/__snapshots__/Action-test.tsx.snap
index 6a646251d00..0e9b4f2e5f9 100644
--- a/server/sonar-web/src/main/js/apps/web-api/components/__tests__/__snapshots__/Action-test.tsx.snap
+++ b/server/sonar-web/src/main/js/apps/web-api/components/__tests__/__snapshots__/Action-test.tsx.snap
@@ -119,14 +119,13 @@ exports[`should render correctly 1`] = `
<div
className="boxed-group-inner"
>
- <div
- className="web-api-action-description markdown"
- dangerouslySetInnerHTML={
- {
- "__html": "Foo Desc",
- }
- }
- />
+ <SafeHTMLInjection
+ htmlAsString="Foo Desc"
+ >
+ <div
+ className="web-api-action-description markdown"
+ />
+ </SafeHTMLInjection>
<ul
className="web-api-action-actions tabs"
>
diff --git a/server/sonar-web/src/main/js/apps/web-api/components/__tests__/__snapshots__/Domain-test.tsx.snap b/server/sonar-web/src/main/js/apps/web-api/components/__tests__/__snapshots__/Domain-test.tsx.snap
index 36349a995c9..38aa9c97656 100644
--- a/server/sonar-web/src/main/js/apps/web-api/components/__tests__/__snapshots__/Domain-test.tsx.snap
+++ b/server/sonar-web/src/main/js/apps/web-api/components/__tests__/__snapshots__/Domain-test.tsx.snap
@@ -13,14 +13,13 @@ exports[`should also render actions with a description matching the query 1`] =
api
</h2>
</header>
- <div
- className="web-api-domain-description markdown"
- dangerouslySetInnerHTML={
- {
- "__html": "API Desc",
- }
- }
- />
+ <SafeHTMLInjection
+ htmlAsString="API Desc"
+ >
+ <div
+ className="web-api-domain-description markdown"
+ />
+ </SafeHTMLInjection>
<div
className="web-api-domain-actions"
>
@@ -139,14 +138,13 @@ exports[`should not render deprecated actions 1`] = `
api
</h2>
</header>
- <div
- className="web-api-domain-description markdown"
- dangerouslySetInnerHTML={
- {
- "__html": "API Desc",
- }
- }
- />
+ <SafeHTMLInjection
+ htmlAsString="API Desc"
+ >
+ <div
+ className="web-api-domain-description markdown"
+ />
+ </SafeHTMLInjection>
<div
className="web-api-domain-actions"
/>
@@ -166,14 +164,13 @@ exports[`should not render internal actions 1`] = `
api
</h2>
</header>
- <div
- className="web-api-domain-description markdown"
- dangerouslySetInnerHTML={
- {
- "__html": "API Desc",
- }
- }
- />
+ <SafeHTMLInjection
+ htmlAsString="API Desc"
+ >
+ <div
+ className="web-api-domain-description markdown"
+ />
+ </SafeHTMLInjection>
<div
className="web-api-domain-actions"
/>
@@ -193,14 +190,13 @@ exports[`should render deprecated actions 1`] = `
api
</h2>
</header>
- <div
- className="web-api-domain-description markdown"
- dangerouslySetInnerHTML={
- {
- "__html": "API Desc",
- }
- }
- />
+ <SafeHTMLInjection
+ htmlAsString="API Desc"
+ >
+ <div
+ className="web-api-domain-description markdown"
+ />
+ </SafeHTMLInjection>
<div
className="web-api-domain-actions"
>
@@ -256,14 +252,13 @@ exports[`should render internal actions 1`] = `
api
</h2>
</header>
- <div
- className="web-api-domain-description markdown"
- dangerouslySetInnerHTML={
- {
- "__html": "API Desc",
- }
- }
- />
+ <SafeHTMLInjection
+ htmlAsString="API Desc"
+ >
+ <div
+ className="web-api-domain-description markdown"
+ />
+ </SafeHTMLInjection>
<div
className="web-api-domain-actions"
>
@@ -317,14 +312,13 @@ exports[`should render only actions matching the query 1`] = `
api
</h2>
</header>
- <div
- className="web-api-domain-description markdown"
- dangerouslySetInnerHTML={
- {
- "__html": "API Desc",
- }
- }
- />
+ <SafeHTMLInjection
+ htmlAsString="API Desc"
+ >
+ <div
+ className="web-api-domain-description markdown"
+ />
+ </SafeHTMLInjection>
<div
className="web-api-domain-actions"
>
diff --git a/server/sonar-web/src/main/js/apps/web-api/components/__tests__/__snapshots__/Params-test.tsx.snap b/server/sonar-web/src/main/js/apps/web-api/components/__tests__/__snapshots__/Params-test.tsx.snap
index c38b355494b..338fc2de1f2 100644
--- a/server/sonar-web/src/main/js/apps/web-api/components/__tests__/__snapshots__/Params-test.tsx.snap
+++ b/server/sonar-web/src/main/js/apps/web-api/components/__tests__/__snapshots__/Params-test.tsx.snap
@@ -44,14 +44,13 @@ exports[`should render deprecated and internal parameters 1`] = `
</div>
</td>
<td>
- <div
- className="markdown"
- dangerouslySetInnerHTML={
- {
- "__html": "Foo desc",
- }
- }
- />
+ <SafeHTMLInjection
+ htmlAsString="Foo desc"
+ >
+ <div
+ className="markdown"
+ />
+ </SafeHTMLInjection>
</td>
<td
style={
@@ -94,14 +93,13 @@ exports[`should render deprecated and internal parameters 1`] = `
</div>
</td>
<td>
- <div
- className="markdown"
- dangerouslySetInnerHTML={
- {
- "__html": "Foo desc",
- }
- }
- />
+ <SafeHTMLInjection
+ htmlAsString="Foo desc"
+ >
+ <div
+ className="markdown"
+ />
+ </SafeHTMLInjection>
</td>
<td
style={
@@ -163,14 +161,13 @@ exports[`should render deprecated key 1`] = `
</div>
</td>
<td>
- <div
- className="markdown"
- dangerouslySetInnerHTML={
- {
- "__html": "Foo desc",
- }
- }
- />
+ <SafeHTMLInjection
+ htmlAsString="Foo desc"
+ >
+ <div
+ className="markdown"
+ />
+ </SafeHTMLInjection>
</td>
<td
style={
@@ -212,14 +209,13 @@ exports[`should render different value constraints 1`] = `
</div>
</td>
<td>
- <div
- className="markdown"
- dangerouslySetInnerHTML={
- {
- "__html": "Foo desc",
- }
- }
- />
+ <SafeHTMLInjection
+ htmlAsString="Foo desc"
+ >
+ <div
+ className="markdown"
+ />
+ </SafeHTMLInjection>
</td>
<td
style={