Skip to content

Commit

Permalink
feat: ui toggle
Browse files Browse the repository at this point in the history
  • Loading branch information
itsyoboieltr committed Nov 4, 2024
1 parent 31c2349 commit 75e16be
Show file tree
Hide file tree
Showing 13 changed files with 142 additions and 1 deletion.
6 changes: 6 additions & 0 deletions app/_locales/en/messages.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 5 additions & 1 deletion app/scripts/background.js
Original file line number Diff line number Diff line change
Expand Up @@ -510,7 +510,11 @@ async function initialize() {
// Workaround for Bug #1446231 to override page CSP for inline script nodes injected by extension content scripts
// https://bugzilla.mozilla.org/show_bug.cgi?id=1446231
const platformName = getPlatform();
if (platformName === PLATFORM_FIREFOX) {
if (
platformName === PLATFORM_FIREFOX &&
controller.preferencesController.state
.overrideContentSecurityPolicyHeader
) {
overrideContentSecurityPolicyHeader();
}
}
Expand Down
1 change: 1 addition & 0 deletions app/scripts/constants/sentry-state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,7 @@ export const SENTRY_BACKGROUND_STATE = {
advancedGasFee: true,
currentLocale: true,
dismissSeedBackUpReminder: true,
overrideContentSecurityPolicyHeader: true,
featureFlags: true,
forgottenPassword: true,
identities: false,
Expand Down
17 changes: 17 additions & 0 deletions app/scripts/controllers/preferences-controller.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -837,6 +837,23 @@ describe('preferences controller', () => {
});
});

describe('overrideContentSecurityPolicyHeader', () => {
it('defaults overrideContentSecurityPolicyHeader to true', () => {
const { controller } = setupController({});
expect(
controller.state.overrideContentSecurityPolicyHeader,
).toStrictEqual(true);
});

it('set overrideContentSecurityPolicyHeader to false', () => {
const { controller } = setupController({});
controller.setOverrideContentSecurityPolicyHeader(false);
expect(
controller.state.overrideContentSecurityPolicyHeader,
).toStrictEqual(false);
});
});

describe('snapsAddSnapAccountModalDismissed', () => {
it('defaults snapsAddSnapAccountModalDismissed to false', () => {
const { controller } = setupController({});
Expand Down
20 changes: 20 additions & 0 deletions app/scripts/controllers/preferences-controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ export type PreferencesControllerState = Omit<
useNonceField: boolean;
usePhishDetect: boolean;
dismissSeedBackUpReminder: boolean;
overrideContentSecurityPolicyHeader: boolean;
useMultiAccountBalanceChecker: boolean;
useSafeChainsListValidation: boolean;
use4ByteResolution: boolean;
Expand Down Expand Up @@ -172,6 +173,7 @@ export const getDefaultPreferencesControllerState =
useNonceField: false,
usePhishDetect: true,
dismissSeedBackUpReminder: false,
overrideContentSecurityPolicyHeader: true,
useMultiAccountBalanceChecker: true,
useSafeChainsListValidation: true,
// set to true means the dynamic list from the API is being used
Expand Down Expand Up @@ -300,6 +302,10 @@ const controllerMetadata = {
persist: true,
anonymous: true,
},
overrideContentSecurityPolicyHeader: {
persist: true,
anonymous: true,
},
useMultiAccountBalanceChecker: {
persist: true,
anonymous: true,
Expand Down Expand Up @@ -985,6 +991,20 @@ export class PreferencesController extends BaseController<
});
}

/**
* A setter for the user preference to override the Content-Security-Policy header
*
* @param overrideContentSecurityPolicyHeader - User preference for overriding the Content-Security-Policy header.
*/
setOverrideContentSecurityPolicyHeader(
overrideContentSecurityPolicyHeader: boolean,
): void {
this.update((state) => {
state.overrideContentSecurityPolicyHeader =
overrideContentSecurityPolicyHeader;
});
}

/**
* A setter for the incomingTransactions in preference to be updated
*
Expand Down
1 change: 1 addition & 0 deletions app/scripts/lib/backup.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ const jsonData = JSON.stringify({
useNonceField: false,
usePhishDetect: true,
dismissSeedBackUpReminder: false,
overrideContentSecurityPolicyHeader: true,
useTokenDetection: false,
useCollectibleDetection: false,
openSeaEnabled: false,
Expand Down
4 changes: 4 additions & 0 deletions app/scripts/metamask-controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -3485,6 +3485,10 @@ export default class MetamaskController extends EventEmitter {
preferencesController.setDismissSeedBackUpReminder.bind(
preferencesController,
),
setOverrideContentSecurityPolicyHeader:
preferencesController.setOverrideContentSecurityPolicyHeader.bind(
preferencesController,
),
setAdvancedGasFee: preferencesController.setAdvancedGasFee.bind(
preferencesController,
),
Expand Down
9 changes: 9 additions & 0 deletions ui/helpers/constants/settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,15 @@ const SETTINGS_CONSTANTS = [
route: `${ADVANCED_ROUTE}#export-data`,
icon: 'fas fa-download',
},
// advanced settingsRefs[11]
{
tabMessage: (t) => t('advanced'),
sectionMessage: (t) => t('overrideContentSecurityPolicyHeader'),
descriptionMessage: (t) =>
t('overrideContentSecurityPolicyHeaderDescription'),
route: `${ADVANCED_ROUTE}#override-content-security-policy-header`,
icon: 'fas fa-sliders-h',
},
{
tabMessage: (t) => t('contacts'),
sectionMessage: (t) => t('contacts'),
Expand Down
4 changes: 4 additions & 0 deletions ui/helpers/utils/settings-search.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,10 @@ const t = (key) => {
return 'Dismiss Secret Recovery Phrase backup reminder';
case 'dismissReminderDescriptionField':
return 'Turn this on to dismiss the Secret Recovery Phrase backup reminder message. We highly recommend that you back up your Secret Recovery Phrase to avoid loss of funds';
case 'overrideContentSecurityPolicyHeader':
return 'Override Content-Security-Policy header';
case 'overrideContentSecurityPolicyHeaderDescription':
return 'This option is a workaround for a known issue in Firefox, where the Content-Security-Policy header may not be bypassed, causing the extension to fail to load properly. Disabling this option is not recommended unless required for specific web page compatibility.';
case 'Contacts':
return 'Contacts';
case 'securityAndPrivacy':
Expand Down
39 changes: 39 additions & 0 deletions ui/pages/settings/advanced-tab/advanced-tab.component.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ export default class AdvancedTab extends PureComponent {
backupUserData: PropTypes.func.isRequired,
showExtensionInFullSizeView: PropTypes.bool,
setShowExtensionInFullSizeView: PropTypes.func.isRequired,
overrideContentSecurityPolicyHeader: PropTypes.bool,
setOverrideContentSecurityPolicyHeader: PropTypes.func.isRequired,
};

state = {
Expand Down Expand Up @@ -575,6 +577,42 @@ export default class AdvancedTab extends PureComponent {
);
}

renderOverrideContentSecurityPolicyHeader() {
const { t } = this.context;
const {
overrideContentSecurityPolicyHeader,
setOverrideContentSecurityPolicyHeader,
} = this.props;

return (
<Box
ref={this.settingsRefs[11]}
className="settings-page__content-row"
data-testid="advanced-setting-override-content-security-policy-header"
display={Display.Flex}
flexDirection={FlexDirection.Row}
justifyContent={JustifyContent.spaceBetween}
gap={4}
>
<div className="settings-page__content-item">
<span>{t('overrideContentSecurityPolicyHeader')}</span>
<div className="settings-page__content-description">
{t('overrideContentSecurityPolicyHeaderDescription')}
</div>
</div>

<div className="settings-page__content-item-col">
<ToggleButton
value={overrideContentSecurityPolicyHeader}
onToggle={(value) => setOverrideContentSecurityPolicyHeader(!value)}
offLabel={t('off')}
onLabel={t('on')}
/>
</div>
</Box>
);
}

render() {
const { warning } = this.props;
// When adding/removing/editing the order of renders, double-check the order of the settingsRefs. This affects settings-search.js
Expand All @@ -592,6 +630,7 @@ export default class AdvancedTab extends PureComponent {
{this.renderAutoLockTimeLimit()}
{this.renderUserDataBackup()}
{this.renderDismissSeedBackupReminderControl()}
{this.renderOverrideContentSecurityPolicyHeader()}
</div>
);
}
Expand Down
6 changes: 6 additions & 0 deletions ui/pages/settings/advanced-tab/advanced-tab.container.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
displayWarning,
setAutoLockTimeLimit,
setDismissSeedBackUpReminder,
setOverrideContentSecurityPolicyHeader,
setFeatureFlag,
setShowExtensionInFullSizeView,
setShowFiatConversionOnTestnetsPreference,
Expand All @@ -28,6 +29,7 @@ export const mapStateToProps = (state) => {
featureFlags: { sendHexData } = {},
useNonceField,
dismissSeedBackUpReminder,
overrideContentSecurityPolicyHeader,
} = metamask;
const {
showFiatInTestnets,
Expand All @@ -46,6 +48,7 @@ export const mapStateToProps = (state) => {
autoLockTimeLimit,
useNonceField,
dismissSeedBackUpReminder,
overrideContentSecurityPolicyHeader,
};
};

Expand Down Expand Up @@ -76,6 +79,9 @@ export const mapDispatchToProps = (dispatch) => {
setDismissSeedBackUpReminder: (value) => {
return dispatch(setDismissSeedBackUpReminder(value));
},
setOverrideContentSecurityPolicyHeader: (value) => {
return dispatch(setOverrideContentSecurityPolicyHeader(value));
},
};
};

Expand Down
18 changes: 18 additions & 0 deletions ui/pages/settings/advanced-tab/advanced-tab.stories.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export default {
showFiatInTestnets: { control: 'boolean' },
useLedgerLive: { control: 'boolean' },
dismissSeedBackUpReminder: { control: 'boolean' },
overrideContentSecurityPolicyHeader: { control: 'boolean' },
setAutoLockTimeLimit: { action: 'setAutoLockTimeLimit' },
setShowFiatConversionOnTestnetsPreference: {
action: 'setShowFiatConversionOnTestnetsPreference',
Expand All @@ -20,6 +21,9 @@ export default {
setIpfsGateway: { action: 'setIpfsGateway' },
setIsIpfsGatewayEnabled: { action: 'setIsIpfsGatewayEnabled' },
setDismissSeedBackUpReminder: { action: 'setDismissSeedBackUpReminder' },
setOverrideContentSecurityPolicyHeader: {
action: 'setOverrideContentSecurityPolicyHeader',
},
setUseNonceField: { action: 'setUseNonceField' },
setHexDataFeatureFlag: { action: 'setHexDataFeatureFlag' },
displayWarning: { action: 'displayWarning' },
Expand All @@ -37,6 +41,7 @@ export const DefaultStory = (args) => {
sendHexData,
showFiatInTestnets,
dismissSeedBackUpReminder,
overrideContentSecurityPolicyHeader,
},
updateArgs,
] = useArgs();
Expand Down Expand Up @@ -64,6 +69,12 @@ export const DefaultStory = (args) => {
dismissSeedBackUpReminder: !dismissSeedBackUpReminder,
});
};

const handleOverrideContentSecurityPolicyHeader = () => {
updateArgs({
overrideContentSecurityPolicyHeader: !overrideContentSecurityPolicyHeader,
});
};
return (
<div style={{ flex: 1, height: 500 }}>
<AdvancedTab
Expand All @@ -76,6 +87,12 @@ export const DefaultStory = (args) => {
setShowFiatConversionOnTestnetsPreference={handleShowFiatInTestnets}
dismissSeedBackUpReminder={dismissSeedBackUpReminder}
setDismissSeedBackUpReminder={handleDismissSeedBackUpReminder}
overrideContentSecurityPolicyHeader={
overrideContentSecurityPolicyHeader
}
setOverrideContentSecurityPolicyHeader={
handleOverrideContentSecurityPolicyHeader
}
ipfsGateway="ipfs-gateway"
/>
</div>
Expand All @@ -90,4 +107,5 @@ DefaultStory.args = {
showFiatInTestnets: false,
useLedgerLive: false,
dismissSeedBackUpReminder: false,
overrideContentSecurityPolicyHeader: true,
};
12 changes: 12 additions & 0 deletions ui/store/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4218,6 +4218,18 @@ export function setDismissSeedBackUpReminder(
};
}

export function setOverrideContentSecurityPolicyHeader(
value: boolean,
): ThunkAction<void, MetaMaskReduxState, unknown, AnyAction> {
return async (dispatch: MetaMaskReduxDispatch) => {
dispatch(showLoadingIndication());
await submitRequestToBackground('setOverrideContentSecurityPolicyHeader', [
value,
]);
dispatch(hideLoadingIndication());
};
}

export function getRpcMethodPreferences(): ThunkAction<
void,
MetaMaskReduxState,
Expand Down

0 comments on commit 75e16be

Please sign in to comment.