Security hardening: authentication, input validation, OWASP compliance, architecture improvements, and CSP fixes for browser mode (#942)

This commit is contained in:
Copilot
2025-12-22 16:52:42 +01:00
committed by GitHub
parent a7136bd572
commit 6c041cba02
50 changed files with 1943 additions and 734 deletions

View File

@@ -6,7 +6,23 @@ import { bindActionCreators } from 'redux'
import { connect } from 'react-redux'
import { globalActions } from '../../actions'
const copy = require('copy-text-to-clipboard')
// Fallback for older browsers or when clipboard API is not available
const copyTextFallback = require('copy-text-to-clipboard')
async function copyToClipboard(text: string): Promise<boolean> {
try {
// Try modern Clipboard API first (works in browser with HTTPS)
if (navigator.clipboard && navigator.clipboard.writeText) {
await navigator.clipboard.writeText(text)
return true
}
} catch (error) {
console.warn('Clipboard API failed, using fallback:', error)
}
// Fallback to copy-text-to-clipboard library
return copyTextFallback(text)
}
interface Props {
value?: string
@@ -26,15 +42,24 @@ class Copy extends React.PureComponent<Props, State> {
this.state = { didCopy: false }
}
private handleClick = (event: React.MouseEvent) => {
private handleClick = async (event: React.MouseEvent) => {
event.stopPropagation()
copy(this.props.value ?? this.props.getValue?.())
this.props.actions.global.showNotification('Copied to clipboard')
this.setState({ didCopy: true })
setTimeout(() => {
this.setState({ didCopy: false })
}, 1500)
const text = this.props.value ?? this.props.getValue?.()
if (!text) {
return
}
const success = await copyToClipboard(text)
if (success) {
this.props.actions.global.showNotification('Copied to clipboard')
this.setState({ didCopy: true })
setTimeout(() => {
this.setState({ didCopy: false })
}, 1500)
} else {
this.props.actions.global.showNotification('Failed to copy to clipboard')
}
}
public render() {
@@ -45,7 +70,7 @@ class Copy extends React.PureComponent<Props, State> {
)
return (
<CustomIconButton onClick={this.handleClick} tooltip="Copy to clipboard">
<CustomIconButton onClick={this.handleClick} tooltip="Copy to clipboard" data-testid="copy-button">
<div style={{ marginTop: '2px' }}>{icon}</div>
</CustomIconButton>
)

View File

@@ -9,6 +9,7 @@ interface Props {
classes: any
style?: React.CSSProperties
children?: React.ReactNode
'data-testid'?: string
}
const styles = (theme: Theme) => ({
@@ -38,7 +39,12 @@ class CustomIconButton extends React.PureComponent<Props, {}> {
public render() {
return (
<IconButton className={this.props.classes.button} style={this.props.style} onClick={this.onClick}>
<IconButton
className={this.props.classes.button}
style={this.props.style}
onClick={this.onClick}
data-testid={this.props['data-testid']}
>
<Tooltip title={this.props.tooltip} classes={{ popper: this.props.classes.tooltip }}>
<span className={this.props.classes.label}>{this.props.children}</span>
</Tooltip>