1
0
mirror of https://github.com/kremalicious/metamask-extension.git synced 2024-10-22 11:22:43 +02:00
metamask-extension/ui/ducks/app/app.ts
David Drazic f788121c3b
[FLASK] Add Snaps privacy warning on snap install (#18835)
* Add Snaps privacy warning on snap install

Add snap install warning status to storage

Add storybook

Add test for snap-privacy-warning

Resolve button type issue

Fix popup display logic

Update fixture

Update popup information and read more handling

Replace deprecated button

Update unit test

* Update buttons and add cancel flow

* Refactoring (review 1)

* Add more unit tests
2023-05-31 14:43:39 +02:00

507 lines
12 KiB
TypeScript

import { AnyAction, Action } from 'redux';
import { PayloadAction } from '@reduxjs/toolkit';
import {
WebHIDConnectedStatuses,
HardwareTransportStates,
} from '../../../shared/constants/hardware-wallets';
import * as actionConstants from '../../store/actionConstants';
interface AppState {
shouldClose: boolean;
menuOpen: boolean;
modal: {
open: boolean;
modalState: {
name: string | null;
props: Record<string, any>;
};
previousModalState: {
name: string | null;
};
};
alertOpen: boolean;
alertMessage: string | null;
qrCodeData: {
type?: string | null;
values?: { address?: string | null };
} | null;
networkDropdownOpen: boolean;
accountDetail: {
subview?: string;
accountExport?: string;
privateKey?: string;
};
isLoading: boolean;
loadingMessage: string | null;
scrollToBottom: boolean;
warning: string | null | undefined;
buyView: Record<string, any>;
isMouseUser: boolean;
defaultHdPaths: {
trezor: string;
ledger: string;
lattice: string;
};
networksTabSelectedRpcUrl: string | null;
requestAccountTabs: Record<string, number>; // [url.origin]: tab.id
openMetaMaskTabs: Record<string, boolean>; // openMetamaskTabsIDs[tab.id]): true/false
currentWindowTab: Record<string, any>; // tabs.tab https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs/Tab
showWhatsNewPopup: boolean;
showTermsOfUsePopup: boolean;
singleExceptions: {
testKey: string | null;
};
gasLoadingAnimationIsShowing: boolean;
smartTransactionsError: string | null;
smartTransactionsErrorMessageDismissed: boolean;
ledgerWebHidConnectedStatus: WebHIDConnectedStatuses;
ledgerTransportStatus: HardwareTransportStates;
newNftAddedMessage: string;
removeNftMessage: string;
newNetworkAddedName: string;
newNetworkAddedConfigurationId: string;
selectedNetworkConfigurationId: string;
sendInputCurrencySwitched: boolean;
newTokensImported: string;
onboardedInThisUISession: boolean;
customTokenAmount: string;
txId: number | null;
accountDetailsAddress: string;
///: BEGIN:ONLY_INCLUDE_IN(snaps)
snapsInstallPrivacyWarningShown: boolean;
///: END:ONLY_INCLUDE_IN
}
interface AppSliceState {
appState: AppState;
}
// default state
const initialState: AppState = {
shouldClose: false,
menuOpen: false,
modal: {
open: false,
modalState: {
name: null,
props: {},
},
previousModalState: {
name: null,
},
},
alertOpen: false,
alertMessage: null,
qrCodeData: null,
networkDropdownOpen: false,
accountDetail: {
privateKey: '',
},
// Used to display loading indicator
isLoading: false,
loadingMessage: null,
// Used to display error text
warning: null,
buyView: {},
isMouseUser: false,
defaultHdPaths: {
trezor: `m/44'/60'/0'/0`,
ledger: `m/44'/60'/0'/0/0`,
lattice: `m/44'/60'/0'/0`,
},
networksTabSelectedRpcUrl: '',
requestAccountTabs: {},
openMetaMaskTabs: {},
currentWindowTab: {},
showWhatsNewPopup: true,
showTermsOfUsePopup: true,
singleExceptions: {
testKey: null,
},
gasLoadingAnimationIsShowing: false,
smartTransactionsError: null,
smartTransactionsErrorMessageDismissed: false,
ledgerWebHidConnectedStatus: WebHIDConnectedStatuses.unknown,
ledgerTransportStatus: HardwareTransportStates.none,
newNftAddedMessage: '',
removeNftMessage: '',
newNetworkAddedName: '',
newNetworkAddedConfigurationId: '',
selectedNetworkConfigurationId: '',
sendInputCurrencySwitched: false,
newTokensImported: '',
onboardedInThisUISession: false,
customTokenAmount: '',
scrollToBottom: true,
txId: null,
accountDetailsAddress: '',
///: BEGIN:ONLY_INCLUDE_IN(snaps)
snapsInstallPrivacyWarningShown: false,
///: END:ONLY_INCLUDE_IN
};
export default function reduceApp(
state: AppState,
action: AnyAction,
): AppState {
const appState: AppState = {
...initialState,
...state,
};
switch (action.type) {
// dropdown methods
case actionConstants.NETWORK_DROPDOWN_OPEN:
return {
...appState,
networkDropdownOpen: true,
};
case actionConstants.NETWORK_DROPDOWN_CLOSE:
return {
...appState,
networkDropdownOpen: false,
};
// alert methods
case actionConstants.ALERT_OPEN:
return {
...appState,
alertOpen: true,
alertMessage: action.payload,
};
case actionConstants.ALERT_CLOSE:
return {
...appState,
alertOpen: false,
alertMessage: null,
};
case actionConstants.SET_ACCOUNT_DETAILS_ADDRESS: {
return {
...appState,
accountDetailsAddress: action.payload,
};
}
// qr scanner methods
case actionConstants.QR_CODE_DETECTED:
return {
...appState,
qrCodeData: action.value,
};
// Smart Transactions errors.
case actionConstants.SET_SMART_TRANSACTIONS_ERROR:
return {
...appState,
smartTransactionsError: action.payload,
};
case actionConstants.DISMISS_SMART_TRANSACTIONS_ERROR_MESSAGE:
return {
...appState,
smartTransactionsErrorMessageDismissed: true,
};
// modal methods:
case actionConstants.MODAL_OPEN: {
const { name, ...modalProps } = action.payload;
return {
...appState,
modal: {
open: true,
modalState: {
name,
props: { ...modalProps },
},
previousModalState: { ...appState.modal.modalState },
},
};
}
case actionConstants.MODAL_CLOSE:
return {
...appState,
modal: Object.assign(
appState.modal,
{ open: false },
{ modalState: { name: null, props: {} } },
{ previousModalState: appState.modal.modalState },
),
};
case actionConstants.CLEAR_ACCOUNT_DETAILS:
return {
...appState,
accountDetail: {
privateKey: '',
},
};
case actionConstants.SHOW_SEND_TOKEN_PAGE:
return {
...appState,
warning: null,
};
case actionConstants.LOCK_METAMASK:
return {
...appState,
warning: null,
};
// accounts
case actionConstants.GO_HOME:
return {
...appState,
accountDetail: {
privateKey: '',
},
warning: null,
};
case actionConstants.SHOW_ACCOUNTS_PAGE:
return {
...appState,
isLoading: false,
warning: null,
scrollToBottom: false,
};
case actionConstants.SHOW_CONF_TX_PAGE:
return {
...appState,
txId: action.id,
warning: null,
isLoading: false,
};
case actionConstants.COMPLETED_TX:
return {
...appState,
warning: null,
txId: null,
};
case actionConstants.UNLOCK_FAILED:
return {
...appState,
warning: action.value || 'Incorrect password. Try again.',
};
case actionConstants.UNLOCK_SUCCEEDED:
return {
...appState,
warning: '',
};
case actionConstants.SET_HARDWARE_WALLET_DEFAULT_HD_PATH: {
const { device, path } = action.payload;
const newDefaults = { ...appState.defaultHdPaths } as any;
newDefaults[device] = path;
return {
...appState,
defaultHdPaths: newDefaults,
};
}
case actionConstants.SHOW_LOADING:
return {
...appState,
isLoading: true,
loadingMessage: action.payload,
};
case actionConstants.HIDE_LOADING:
return {
...appState,
isLoading: false,
};
case actionConstants.DISPLAY_WARNING:
return {
...appState,
warning: action.payload,
isLoading: false,
};
case actionConstants.HIDE_WARNING:
return {
...appState,
warning: undefined,
};
case actionConstants.SHOW_PRIVATE_KEY:
return {
...appState,
accountDetail: {
privateKey: action.payload,
},
};
case actionConstants.SET_MOUSE_USER_STATE:
return {
...appState,
isMouseUser: action.payload,
};
case actionConstants.SET_SELECTED_NETWORK_CONFIGURATION_ID:
return {
...appState,
selectedNetworkConfigurationId: action.payload,
};
case actionConstants.SET_NEW_NETWORK_ADDED: {
const { networkConfigurationId, nickname } = action.payload;
return {
...appState,
newNetworkAddedName: nickname,
newNetworkAddedConfigurationId: networkConfigurationId,
};
}
case actionConstants.SET_NEW_TOKENS_IMPORTED:
return {
...appState,
newTokensImported: action.payload,
};
case actionConstants.SET_NEW_NFT_ADDED_MESSAGE:
return {
...appState,
newNftAddedMessage: action.payload,
};
case actionConstants.SET_REMOVE_NFT_MESSAGE:
return {
...appState,
removeNftMessage: action.payload,
};
case actionConstants.SET_REQUEST_ACCOUNT_TABS:
return {
...appState,
requestAccountTabs: action.value,
};
case actionConstants.SET_OPEN_METAMASK_TAB_IDS:
return {
...appState,
openMetaMaskTabs: action.payload,
};
case actionConstants.HIDE_WHATS_NEW_POPUP:
return {
...appState,
showWhatsNewPopup: false,
};
case actionConstants.CAPTURE_SINGLE_EXCEPTION:
return {
...appState,
singleExceptions: {
...appState.singleExceptions,
[action.value]: null,
},
};
case actionConstants.TOGGLE_GAS_LOADING_ANIMATION:
return {
...appState,
gasLoadingAnimationIsShowing: action.payload,
};
case actionConstants.SET_WEBHID_CONNECTED_STATUS:
return {
...appState,
ledgerWebHidConnectedStatus: action.payload,
};
case actionConstants.SET_LEDGER_TRANSPORT_STATUS:
return {
...appState,
ledgerTransportStatus: action.payload,
};
case actionConstants.TOGGLE_CURRENCY_INPUT_SWITCH:
return {
...appState,
sendInputCurrencySwitched: !appState.sendInputCurrencySwitched,
};
case actionConstants.ONBOARDED_IN_THIS_UI_SESSION:
return {
...appState,
onboardedInThisUISession: action.payload,
};
case actionConstants.SET_CUSTOM_TOKEN_AMOUNT:
return {
...appState,
customTokenAmount: action.payload,
};
default:
return appState;
}
}
// Action Creators
export function hideWhatsNewPopup(): Action {
return {
type: actionConstants.HIDE_WHATS_NEW_POPUP,
};
}
export function toggleGasLoadingAnimation(
payload: boolean,
): PayloadAction<boolean> {
return { type: actionConstants.TOGGLE_GAS_LOADING_ANIMATION, payload };
}
export function setLedgerWebHidConnectedStatus(
payload: WebHIDConnectedStatuses,
): PayloadAction<WebHIDConnectedStatuses> {
return { type: actionConstants.SET_WEBHID_CONNECTED_STATUS, payload };
}
export function setLedgerTransportStatus(
payload: HardwareTransportStates,
): PayloadAction<HardwareTransportStates> {
return { type: actionConstants.SET_LEDGER_TRANSPORT_STATUS, payload };
}
export function toggleCurrencySwitch(): Action {
return { type: actionConstants.TOGGLE_CURRENCY_INPUT_SWITCH };
}
export function setOnBoardedInThisUISession(
payload: boolean,
): PayloadAction<boolean> {
return { type: actionConstants.ONBOARDED_IN_THIS_UI_SESSION, payload };
}
export function setCustomTokenAmount(payload: string): PayloadAction<string> {
return { type: actionConstants.SET_CUSTOM_TOKEN_AMOUNT, payload };
}
// Selectors
export function getQrCodeData(state: AppSliceState): {
type?: string | null;
values?: { address?: string | null };
} | null {
return state.appState.qrCodeData;
}
export function getGasLoadingAnimationIsShowing(state: AppSliceState): boolean {
return state.appState.gasLoadingAnimationIsShowing;
}
export function getLedgerWebHidConnectedStatus(
state: AppSliceState,
): string | null {
return state.appState.ledgerWebHidConnectedStatus;
}
export function getLedgerTransportStatus(state: AppSliceState): string | null {
return state.appState.ledgerTransportStatus;
}