[v8.2.x] Sanitized NavBar children links to remove angular interpolation (#41283)
* Sanitized nav bar links to remove angular interpolation * NavBar: Add sanitize to children items (cherry picked from commita3dc30546f) (cherry picked from commit561ca52ab3) * use replaceAll when sanitizing urls (cherry picked from commit8081dc9ee9) (cherry picked from commitc86d520821) * switch to global regexp (cherry picked from commit1c7ce348ce) (cherry picked from commit28e2be2a8a) * Resolve conflicts Co-authored-by: Alexandra Vargas <alexa1866@gmail.com> Co-authored-by: Dan Cech <dcech@grafana.com>
This commit is contained in:
co-authored by
Alexandra Vargas
Dan Cech
parent
120689b3c6
commit
d52f25825b
@@ -1,11 +1,12 @@
|
||||
export * from './string';
|
||||
export * from './markdown';
|
||||
export * from './text';
|
||||
import { escapeHtml, hasAnsiCodes, sanitize, sanitizeUrl } from './sanitize';
|
||||
import { escapeHtml, hasAnsiCodes, sanitize, sanitizeUrl, sanitizeAngularInterpolation } from './sanitize';
|
||||
|
||||
export const textUtil = {
|
||||
escapeHtml,
|
||||
hasAnsiCodes,
|
||||
sanitize,
|
||||
sanitizeUrl,
|
||||
sanitizeAngularInterpolation,
|
||||
};
|
||||
|
||||
@@ -38,3 +38,7 @@ export function hasAnsiCodes(input: string): boolean {
|
||||
export function escapeHtml(str: string): string {
|
||||
return String(str).replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"');
|
||||
}
|
||||
|
||||
export function sanitizeAngularInterpolation(url: string): string {
|
||||
return url.replace(/\{\{/g, '%7B%7B').replace(/\}\}/g, '%7D%7D');
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React from 'react';
|
||||
import { css } from '@emotion/css';
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
import { GrafanaTheme2, textUtil } from '@grafana/data';
|
||||
import { Icon, IconName, Link, useTheme2 } from '@grafana/ui';
|
||||
|
||||
export interface Props {
|
||||
@@ -29,13 +29,15 @@ const DropdownChild = ({ isDivider = false, icon, onClick, target, text, url }:
|
||||
</button>
|
||||
);
|
||||
if (url) {
|
||||
const sanitizedUrl = textUtil.sanitizeAngularInterpolation(url);
|
||||
|
||||
element =
|
||||
!target && url.startsWith('/') ? (
|
||||
<Link className={styles.element} onClick={onClick} href={url}>
|
||||
<Link className={styles.element} onClick={onClick} href={sanitizedUrl}>
|
||||
{linkContent}
|
||||
</Link>
|
||||
) : (
|
||||
<a className={styles.element} href={url} target={target} rel="noopener" onClick={onClick}>
|
||||
<a className={styles.element} href={sanitizedUrl} target={target} rel="noopener" onClick={onClick}>
|
||||
{linkContent}
|
||||
</a>
|
||||
);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React, { ReactNode } from 'react';
|
||||
import { css, cx } from '@emotion/css';
|
||||
import { GrafanaTheme2, NavModelItem } from '@grafana/data';
|
||||
import { GrafanaTheme2, NavModelItem, textUtil } from '@grafana/data';
|
||||
import { Link, useTheme2 } from '@grafana/ui';
|
||||
import NavBarDropdown from './NavBarDropdown';
|
||||
|
||||
@@ -34,13 +34,14 @@ const NavBarItem = ({
|
||||
<span className={styles.icon}>{children}</span>
|
||||
</button>
|
||||
);
|
||||
const sanitizedUrl = textUtil.sanitizeAngularInterpolation(url ?? '');
|
||||
|
||||
if (url) {
|
||||
element =
|
||||
!target && url.startsWith('/') ? (
|
||||
!target && sanitizedUrl.startsWith('/') ? (
|
||||
<Link
|
||||
className={styles.element}
|
||||
href={url}
|
||||
href={sanitizedUrl}
|
||||
target={target}
|
||||
aria-label={label}
|
||||
onClick={onClick}
|
||||
@@ -49,7 +50,7 @@ const NavBarItem = ({
|
||||
<span className={styles.icon}>{children}</span>
|
||||
</Link>
|
||||
) : (
|
||||
<a href={url} target={target} className={styles.element} onClick={onClick} aria-label={label}>
|
||||
<a href={sanitizedUrl} target={target} className={styles.element} onClick={onClick} aria-label={label}>
|
||||
<span className={styles.icon}>{children}</span>
|
||||
</a>
|
||||
);
|
||||
@@ -61,7 +62,7 @@ const NavBarItem = ({
|
||||
<NavBarDropdown
|
||||
headerTarget={target}
|
||||
headerText={label}
|
||||
headerUrl={url}
|
||||
headerUrl={sanitizedUrl}
|
||||
items={menuItems}
|
||||
onHeaderClick={onClick}
|
||||
reverseDirection={reverseMenuDirection}
|
||||
|
||||
Reference in New Issue
Block a user