@@ -171,12 +195,14 @@ function ContentView(props: Props) {
- {/* Publish tab - keep mounted, toggle visibility */}
-
- {/* Charts tab - keep mounted, toggle visibility */}
-
+ {/* Publish tab - conditionally rendered */}
+ {!hidePublishPane && (
+
+ )}
+ {/* Charts tab - adjust index based on publish visibility */}
+
diff --git a/app/src/components/Layout/MobileTabs.tsx b/app/src/components/Layout/MobileTabs.tsx
index bae2b40..c660c72 100644
--- a/app/src/components/Layout/MobileTabs.tsx
+++ b/app/src/components/Layout/MobileTabs.tsx
@@ -11,6 +11,7 @@ interface Props {
classes: any
value: number
onChange: (value: number) => void
+ hidePublishPane?: boolean
}
function MobileTabs(props: Props) {
@@ -18,6 +19,8 @@ function MobileTabs(props: Props) {
props.onChange(newValue)
}
+ const hidePublishPane = props.hidePublishPane || false
+
return (
}
@@ -44,21 +47,23 @@ function MobileTabs(props: Props) {
id="mobile-tab-1"
aria-controls="mobile-tabpanel-1"
/>
- }
- label="Publish"
- data-testid="mobile-tab-publish"
- aria-label="Publish messages"
- id="mobile-tab-2"
- aria-controls="mobile-tabpanel-2"
- />
+ {!hidePublishPane && (
+ }
+ label="Publish"
+ data-testid="mobile-tab-publish"
+ aria-label="Publish messages"
+ id="mobile-tab-2"
+ aria-controls="mobile-tabpanel-2"
+ />
+ )}
}
- label="Charts"
+ label={hidePublishPane ? "Charts" : "Charts"}
data-testid="mobile-tab-charts"
aria-label="View charts"
- id="mobile-tab-3"
- aria-controls="mobile-tabpanel-3"
+ id={hidePublishPane ? "mobile-tab-2" : "mobile-tab-3"}
+ aria-controls={hidePublishPane ? "mobile-tabpanel-2" : "mobile-tabpanel-3"}
/>
diff --git a/app/src/components/Sidebar/CodeDiff/index.tsx b/app/src/components/Sidebar/CodeDiff/index.tsx
index b4860c1..27fbb66 100644
--- a/app/src/components/Sidebar/CodeDiff/index.tsx
+++ b/app/src/components/Sidebar/CodeDiff/index.tsx
@@ -1,6 +1,7 @@
import * as diff from 'diff'
import * as Prism from 'prismjs'
import * as React from 'react'
+import DOMPurify from 'dompurify'
import { JsonPropertyLocation, literalsMappedByLines } from '../../../../../backend/src/JsonAstParser'
import { Typography } from '@mui/material'
import { withStyles } from '@mui/styles'
@@ -61,7 +62,7 @@ class CodeDiff extends React.PureComponent
{
const currentLines = styledLines.slice(lineNumber, lineNumber + changedLines)
const lines = currentLines.map((html: string, idx: number) => (
-
+
))
lineNumber += changedLines
diff --git a/app/src/components/Sidebar/Sidebar.tsx b/app/src/components/Sidebar/Sidebar.tsx
index 21d379f..eb53e74 100644
--- a/app/src/components/Sidebar/Sidebar.tsx
+++ b/app/src/components/Sidebar/Sidebar.tsx
@@ -53,6 +53,9 @@ function SidebarNew(props: Props) {
const theme = useTheme()
const isMobile = useMediaQuery(theme.breakpoints.down('sm'))
+ // Check if publish pane should be hidden
+ const hidePublishPane = (typeof window !== 'undefined' && (window as any).mqttExplorerUiConfig?.hidePublishPane) || false
+
const handleTabChange = (event: React.SyntheticEvent, newValue: number) => {
setTabValue(newValue)
}
@@ -69,7 +72,7 @@ function SidebarNew(props: Props) {
)
}
- // Desktop: show tabs for Details/Publish
+ // Desktop: show tabs for Details/Publish (if not hidden)
return (
)
diff --git a/app/src/components/UpdateNotifier.tsx b/app/src/components/UpdateNotifier.tsx
index ec8ae32..94c86cd 100644
--- a/app/src/components/UpdateNotifier.tsx
+++ b/app/src/components/UpdateNotifier.tsx
@@ -2,6 +2,7 @@ import { compareVersions } from 'compare-versions'
import electron from 'electron'
import React from 'react'
import axios from 'axios'
+import DOMPurify from 'dompurify'
import Close from '@mui/icons-material/Close'
import CloudDownload from '@mui/icons-material/CloudDownload'
import { bindActionCreators } from 'redux'
@@ -152,6 +153,9 @@ class UpdateNotifier extends React.PureComponent {
.map(release => `${release.tag_name}
${release.body_html}
`)
.join('
')
+ // Sanitize HTML to prevent XSS attacks
+ const sanitizedReleaseNotes = DOMPurify.sanitize(releaseNotes)
+
return (
@@ -159,7 +163,7 @@ class UpdateNotifier extends React.PureComponent {
Version {latestUpdate.tag_name}
Changelog
-
+
{this.renderDownloads()}