[MM-59552] Remove unsafe-inline
from internal CSP, replace with nonce and rework some dynamic styling (#3120)
* Remove unsafe-inline * Fix dynamic dark mode loading * Include nonce generator for CSP for styles * Add nonce provider for react-select * Fix test
This commit is contained in:
@@ -6,6 +6,9 @@
|
||||
|
||||
import 'renderer/css/settings.css';
|
||||
|
||||
import createCache from '@emotion/cache';
|
||||
import {CacheProvider} from '@emotion/react';
|
||||
import type {EmotionCache} from '@emotion/react';
|
||||
import React from 'react';
|
||||
import {FormCheck, Col, FormGroup, FormText, Container, Row, Button, FormControl, Modal} from 'react-bootstrap';
|
||||
import type {IntlShape} from 'react-intl';
|
||||
@@ -39,6 +42,7 @@ type State = DeepPartial<CombinedConfig> & {
|
||||
availableLanguages: Array<{label: string; value: string}>;
|
||||
availableSpellcheckerLanguages: Array<{label: string; value: string}>;
|
||||
canUpgrade?: boolean;
|
||||
cache?: EmotionCache;
|
||||
}
|
||||
|
||||
type SavingStateItems = {
|
||||
@@ -127,6 +131,13 @@ class SettingsPage extends React.PureComponent<Props, State> {
|
||||
availableLanguages.sort((a, b) => a.label.localeCompare(b.label));
|
||||
this.setState({availableLanguages});
|
||||
});
|
||||
|
||||
window.desktop.getNonce().then((nonce) => {
|
||||
this.setState({cache: createCache({
|
||||
key: 'react-select-cache',
|
||||
nonce,
|
||||
})});
|
||||
});
|
||||
}
|
||||
|
||||
getConfig = () => {
|
||||
@@ -426,6 +437,10 @@ class SettingsPage extends React.PureComponent<Props, State> {
|
||||
render() {
|
||||
const {intl} = this.props;
|
||||
|
||||
if (!this.state.cache) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const settingsPage = {
|
||||
close: {
|
||||
textDecoration: 'none',
|
||||
@@ -581,22 +596,24 @@ class SettingsPage extends React.PureComponent<Props, State> {
|
||||
</FormText>
|
||||
</FormCheck>
|
||||
{this.state.useSpellChecker &&
|
||||
<ReactSelect
|
||||
inputId='inputSpellCheckerLocalesDropdown'
|
||||
className='SettingsPage__spellCheckerLocalesDropdown'
|
||||
classNamePrefix='SettingsPage__spellCheckerLocalesDropdown'
|
||||
options={this.state.availableSpellcheckerLanguages}
|
||||
isMulti={true}
|
||||
isClearable={false}
|
||||
onChange={this.handleChangeSpellCheckerLocales}
|
||||
value={this.selectedSpellCheckerLocales}
|
||||
placeholder={
|
||||
<FormattedMessage
|
||||
id='renderer.components.settingsPage.checkSpelling.preferredLanguages'
|
||||
defaultMessage='Select preferred language(s)'
|
||||
/>
|
||||
}
|
||||
/>
|
||||
<CacheProvider value={this.state.cache}>
|
||||
<ReactSelect
|
||||
inputId='inputSpellCheckerLocalesDropdown'
|
||||
className='SettingsPage__spellCheckerLocalesDropdown'
|
||||
classNamePrefix='SettingsPage__spellCheckerLocalesDropdown'
|
||||
options={this.state.availableSpellcheckerLanguages}
|
||||
isMulti={true}
|
||||
isClearable={false}
|
||||
onChange={this.handleChangeSpellCheckerLocales}
|
||||
value={this.selectedSpellCheckerLocales}
|
||||
placeholder={
|
||||
<FormattedMessage
|
||||
id='renderer.components.settingsPage.checkSpelling.preferredLanguages'
|
||||
defaultMessage='Select preferred language(s)'
|
||||
/>
|
||||
}
|
||||
/>
|
||||
</CacheProvider>
|
||||
}
|
||||
</>,
|
||||
);
|
||||
|
@@ -32,6 +32,10 @@ type Props = {
|
||||
intl: IntlShape;
|
||||
};
|
||||
|
||||
type State = {
|
||||
nonce?: string;
|
||||
}
|
||||
|
||||
function getStyle(style?: DraggingStyle | NotDraggingStyle) {
|
||||
if (style?.transform) {
|
||||
const axisLockX = `${style.transform.slice(0, style.transform.indexOf(','))}, 0px)`;
|
||||
@@ -43,7 +47,12 @@ function getStyle(style?: DraggingStyle | NotDraggingStyle) {
|
||||
return style;
|
||||
}
|
||||
|
||||
class TabBar extends React.PureComponent<Props> {
|
||||
class TabBar extends React.PureComponent<Props, State> {
|
||||
constructor(props: Props) {
|
||||
super(props);
|
||||
this.state = {};
|
||||
}
|
||||
|
||||
onCloseTab = (id: string) => {
|
||||
return (event: React.MouseEvent<HTMLButtonElement>) => {
|
||||
event.stopPropagation();
|
||||
@@ -51,7 +60,19 @@ class TabBar extends React.PureComponent<Props> {
|
||||
};
|
||||
};
|
||||
|
||||
componentDidMount(): void {
|
||||
window.desktop.getNonce().then((nonce) => {
|
||||
this.setState({
|
||||
nonce,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
if (!this.state.nonce) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const tabs = this.props.tabs.map((tab, index) => {
|
||||
const sessionExpired = this.props.sessionsExpired[tab.id!];
|
||||
const hasUnreads = this.props.unreadCounts[tab.id!];
|
||||
@@ -145,7 +166,10 @@ class TabBar extends React.PureComponent<Props> {
|
||||
});
|
||||
|
||||
return (
|
||||
<DragDropContext onDragEnd={this.props.onDrop}>
|
||||
<DragDropContext
|
||||
nonce={this.state.nonce}
|
||||
onDragEnd={this.props.onDrop}
|
||||
>
|
||||
<Droppable
|
||||
isDropDisabled={this.props.tabsDisabled}
|
||||
droppableId='tabBar'
|
||||
|
Reference in New Issue
Block a user