1
0
mirror of https://github.com/kremalicious/metamask-extension.git synced 2024-12-23 09:52:26 +01:00

Fix permissions connect close and redirect behavior (#8751)

* fix permissions connect close/redirect behavior

* improve permissions connect fullscreen close behavior

* fix multi ui perm conf redirect; consolidate perm selectors
This commit is contained in:
Erik Marks 2020-06-05 13:24:38 -07:00 committed by GitHub
parent 9a1f27fe04
commit bb78512bd6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 79 additions and 69 deletions

View File

@ -6,7 +6,6 @@ import { getEnvironmentType } from '../../../../app/scripts/lib/util'
import { import {
ENVIRONMENT_TYPE_FULLSCREEN, ENVIRONMENT_TYPE_FULLSCREEN,
ENVIRONMENT_TYPE_NOTIFICATION, ENVIRONMENT_TYPE_NOTIFICATION,
ENVIRONMENT_TYPE_POPUP,
} from '../../../../app/scripts/lib/enums' } from '../../../../app/scripts/lib/enums'
import { import {
DEFAULT_ROUTE, DEFAULT_ROUTE,
@ -20,30 +19,29 @@ export default class PermissionConnect extends Component {
getRequestAccountTabIds: PropTypes.func.isRequired, getRequestAccountTabIds: PropTypes.func.isRequired,
getCurrentWindowTab: PropTypes.func.isRequired, getCurrentWindowTab: PropTypes.func.isRequired,
accounts: PropTypes.array.isRequired, accounts: PropTypes.array.isRequired,
originName: PropTypes.string, origin: PropTypes.string,
showNewAccountModal: PropTypes.func.isRequired, showNewAccountModal: PropTypes.func.isRequired,
newAccountNumber: PropTypes.number.isRequired, newAccountNumber: PropTypes.number.isRequired,
nativeCurrency: PropTypes.string, nativeCurrency: PropTypes.string,
permissionsRequest: PropTypes.object, permissionsRequest: PropTypes.object,
addressLastConnectedMap: PropTypes.object, addressLastConnectedMap: PropTypes.object.isRequired,
lastConnectedInfo: PropTypes.object.isRequired,
permissionsRequestId: PropTypes.string, permissionsRequestId: PropTypes.string,
domains: PropTypes.object,
history: PropTypes.object.isRequired, history: PropTypes.object.isRequired,
connectPath: PropTypes.string.isRequired, connectPath: PropTypes.string.isRequired,
confirmPermissionPath: PropTypes.string.isRequired, confirmPermissionPath: PropTypes.string.isRequired,
page: PropTypes.string.isRequired, page: PropTypes.string.isRequired,
redirecting: PropTypes.bool,
targetDomainMetadata: PropTypes.object, targetDomainMetadata: PropTypes.object,
location: PropTypes.shape({
pathname: PropTypes.string,
}).isRequired,
} }
static defaultProps = { static defaultProps = {
originName: '', origin: '',
nativeCurrency: '', nativeCurrency: '',
permissionsRequest: undefined, permissionsRequest: undefined,
addressLastConnectedMap: {},
permissionsRequestId: '', permissionsRequestId: '',
domains: {},
redirecting: false,
} }
static contextTypes = { static contextTypes = {
@ -56,7 +54,7 @@ export default class PermissionConnect extends Component {
? new Set([this.props.accounts[0].address]) ? new Set([this.props.accounts[0].address])
: new Set(), : new Set(),
permissionAccepted: null, permissionAccepted: null,
originName: this.props.originName, origin: this.props.origin,
} }
beforeUnload = () => { beforeUnload = () => {
@ -69,22 +67,25 @@ export default class PermissionConnect extends Component {
} }
removeBeforeUnload = () => { removeBeforeUnload = () => {
if (getEnvironmentType() === ENVIRONMENT_TYPE_FULLSCREEN || getEnvironmentType() === ENVIRONMENT_TYPE_NOTIFICATION) { const environmentType = getEnvironmentType()
if (
environmentType === ENVIRONMENT_TYPE_FULLSCREEN ||
environmentType === ENVIRONMENT_TYPE_NOTIFICATION
) {
window.removeEventListener('beforeunload', this.beforeUnload) window.removeEventListener('beforeunload', this.beforeUnload)
} }
} }
componentDidUpdate (prevProps) { componentDidUpdate (prevProps) {
const { domains, permissionsRequest, redirecting } = this.props const { permissionsRequest, lastConnectedInfo } = this.props
const { originName } = this.state const { redirecting, origin } = this.state
if (!permissionsRequest && prevProps.permissionsRequest && !redirecting) { if (!permissionsRequest && prevProps.permissionsRequest && !redirecting) {
const permissionDataForDomain = (domains && domains[originName]) || {}
const permissionsForDomain = permissionDataForDomain.permissions || [] const accountsLastApprovedTime = lastConnectedInfo[origin]?.lastApproved || 0
const prevPermissionDataForDomain = (prevProps.domains && prevProps.domains[originName]) || {} const initialAccountsLastApprovedTime = prevProps.lastConnectedInfo[origin]?.lastApproved || 0
const prevPermissionsForDomain = prevPermissionDataForDomain.permissions || []
const addedAPermission = permissionsForDomain.length > prevPermissionsForDomain.length if (accountsLastApprovedTime > initialAccountsLastApprovedTime) {
if (addedAPermission) {
this.redirectFlow(true) this.redirectFlow(true)
} else { } else {
this.redirectFlow(false) this.redirectFlow(false)
@ -99,7 +100,7 @@ export default class PermissionConnect extends Component {
} }
redirectFlow (accepted) { redirectFlow (accepted) {
const { history } = this.props const { history, location, confirmPermissionPath } = this.props
this.setState({ this.setState({
redirecting: true, redirecting: true,
@ -107,16 +108,15 @@ export default class PermissionConnect extends Component {
}) })
this.removeBeforeUnload() this.removeBeforeUnload()
if (getEnvironmentType() === ENVIRONMENT_TYPE_FULLSCREEN) { if (getEnvironmentType() === ENVIRONMENT_TYPE_NOTIFICATION) {
setTimeout(async () => {
const currentTab = await global.platform.currentTab()
global.platform.closeTab(currentTab.id)
}, 2000)
} else if (getEnvironmentType() === ENVIRONMENT_TYPE_NOTIFICATION) {
setTimeout(async () => { setTimeout(async () => {
global.platform.closeCurrentWindow() global.platform.closeCurrentWindow()
}, 2000) }, 1500)
} else if (getEnvironmentType() === ENVIRONMENT_TYPE_POPUP) { } else if (location.pathname === confirmPermissionPath) {
setTimeout(async () => {
history.push(DEFAULT_ROUTE)
}, 1500)
} else {
history.push(DEFAULT_ROUTE) history.push(DEFAULT_ROUTE)
} }
} }
@ -135,19 +135,25 @@ export default class PermissionConnect extends Component {
return history.push(DEFAULT_ROUTE) return history.push(DEFAULT_ROUTE)
} }
if (getEnvironmentType() === ENVIRONMENT_TYPE_FULLSCREEN || getEnvironmentType() === ENVIRONMENT_TYPE_NOTIFICATION) { const environmentType = getEnvironmentType()
if (
environmentType === ENVIRONMENT_TYPE_FULLSCREEN ||
environmentType === ENVIRONMENT_TYPE_NOTIFICATION
) {
window.addEventListener('beforeunload', this.beforeUnload) window.addEventListener('beforeunload', this.beforeUnload)
} }
} }
cancelPermissionsRequest = async (requestId) => { cancelPermissionsRequest = async (requestId) => {
const { history, rejectPermissionsRequest } = this.props const { history, rejectPermissionsRequest } = this.props
if (requestId) { if (requestId) {
await rejectPermissionsRequest(requestId) await rejectPermissionsRequest(requestId)
if (getEnvironmentType() === ENVIRONMENT_TYPE_FULLSCREEN || getEnvironmentType() === ENVIRONMENT_TYPE_NOTIFICATION) { if (getEnvironmentType() === ENVIRONMENT_TYPE_NOTIFICATION) {
window.close() window.close()
} else if (getEnvironmentType() === ENVIRONMENT_TYPE_POPUP) { } else {
history.push(DEFAULT_ROUTE) history.push(DEFAULT_ROUTE)
} }
} }
@ -202,7 +208,7 @@ export default class PermissionConnect extends Component {
const { const {
selectedAccountAddresses, selectedAccountAddresses,
permissionAccepted, permissionAccepted,
originName, origin,
redirecting, redirecting,
} = this.state } = this.state
@ -216,7 +222,6 @@ export default class PermissionConnect extends Component {
render={() => ( render={() => (
<ChooseAccount <ChooseAccount
accounts={accounts} accounts={accounts}
originName={originName}
nativeCurrency={nativeCurrency} nativeCurrency={nativeCurrency}
selectAccounts={(addresses) => this.selectAccounts(addresses)} selectAccounts={(addresses) => this.selectAccounts(addresses)}
selectNewAccountViaModal={(handleAccountClick) => { selectNewAccountViaModal={(handleAccountClick) => {
@ -250,7 +255,7 @@ export default class PermissionConnect extends Component {
selectedIdentities={accounts.filter((account) => selectedAccountAddresses.has(account.address))} selectedIdentities={accounts.filter((account) => selectedAccountAddresses.has(account.address))}
redirect={redirecting} redirect={redirecting}
permissionRejected={ permissionAccepted === false } permissionRejected={ permissionAccepted === false }
cachedOrigin={originName} cachedOrigin={origin}
/> />
)} )}
/> />

View File

@ -7,11 +7,16 @@ import {
getAccountsWithLabels, getAccountsWithLabels,
getLastConnectedInfo, getLastConnectedInfo,
getTargetDomainMetadata, getTargetDomainMetadata,
getPermissionDomains,
} from '../../selectors' } from '../../selectors'
import { formatDate } from '../../helpers/utils/util' import { formatDate } from '../../helpers/utils/util'
import { approvePermissionsRequest, rejectPermissionsRequest, showModal, getCurrentWindowTab, getRequestAccountTabIds } from '../../store/actions' import {
approvePermissionsRequest,
rejectPermissionsRequest,
showModal,
getCurrentWindowTab,
getRequestAccountTabIds,
} from '../../store/actions'
import { import {
CONNECT_ROUTE, CONNECT_ROUTE,
CONNECT_CONFIRM_PERMISSIONS_ROUTE, CONNECT_CONFIRM_PERMISSIONS_ROUTE,
@ -34,7 +39,7 @@ const mapStateToProps = (state, ownProps) => {
const accountsWithLabels = getAccountsWithLabels(state) const accountsWithLabels = getAccountsWithLabels(state)
const lastConnectedInfo = getLastConnectedInfo(state) || {} const lastConnectedInfo = getLastConnectedInfo(state) || {}
const addressLastConnectedMap = lastConnectedInfo[origin] || {} const addressLastConnectedMap = lastConnectedInfo[origin]?.accounts || {}
Object.keys(addressLastConnectedMap).forEach((key) => { Object.keys(addressLastConnectedMap).forEach((key) => {
addressLastConnectedMap[key] = formatDate(addressLastConnectedMap[key], 'yyyy-MM-dd') addressLastConnectedMap[key] = formatDate(addressLastConnectedMap[key], 'yyyy-MM-dd')
@ -58,11 +63,11 @@ const mapStateToProps = (state, ownProps) => {
permissionsRequest, permissionsRequest,
permissionsRequestId, permissionsRequestId,
accounts: accountsWithLabels, accounts: accountsWithLabels,
originName: origin, origin,
newAccountNumber: accountsWithLabels.length + 1, newAccountNumber: accountsWithLabels.length + 1,
nativeCurrency, nativeCurrency,
addressLastConnectedMap, addressLastConnectedMap,
domains: getPermissionDomains(state), lastConnectedInfo,
connectPath, connectPath,
confirmPermissionPath, confirmPermissionPath,
page, page,

View File

@ -249,3 +249,32 @@ export function getPermissionsForActiveTab (state) {
} }
}) })
} }
export function getLastConnectedInfo (state) {
const { permissionsHistory = {} } = state.metamask
return Object.keys(permissionsHistory).reduce((acc, origin) => {
const ethAccountsHistory = JSON.parse(JSON.stringify(permissionsHistory[origin]['eth_accounts']))
return {
...acc,
[origin]: ethAccountsHistory,
}
}, {})
}
export function getPermissionsRequests (state) {
return state.metamask.permissionsRequests || []
}
export function getPermissionsRequestCount (state) {
const permissionsRequests = getPermissionsRequests(state)
return permissionsRequests.length
}
export function getFirstPermissionRequest (state) {
const requests = getPermissionsRequests(state)
return requests && requests[0] ? requests[0] : null
}
export function hasPermissionRequests (state) {
return Boolean(getFirstPermissionRequest(state))
}

View File

@ -6,6 +6,7 @@ import {
checksumAddress, checksumAddress,
getAccountByAddress, getAccountByAddress,
} from '../helpers/utils/util' } from '../helpers/utils/util'
import { getPermissionsRequestCount } from './permissions'
export function getNetworkIdentifier (state) { export function getNetworkIdentifier (state) {
const { metamask: { provider: { type, nickname, rpcTarget } } } = state const { metamask: { provider: { type, nickname, rpcTarget } } } = state
@ -282,15 +283,6 @@ export function getCustomNonceValue (state) {
return String(state.metamask.customNonceValue) return String(state.metamask.customNonceValue)
} }
export function getPermissionsRequests (state) {
return state.metamask.permissionsRequests || []
}
export function getPermissionsRequestCount (state) {
const permissionsRequests = getPermissionsRequests(state)
return permissionsRequests.length
}
export function getDomainMetadata (state) { export function getDomainMetadata (state) {
return state.metamask.domainMetadata return state.metamask.domainMetadata
} }
@ -339,31 +331,10 @@ export function getFeatureFlags (state) {
return state.metamask.featureFlags return state.metamask.featureFlags
} }
export function getFirstPermissionRequest (state) {
const requests = getPermissionsRequests(state)
return requests && requests[0] ? requests[0] : null
}
export function hasPermissionRequests (state) {
return Boolean(getFirstPermissionRequest(state))
}
export function getOriginOfCurrentTab (state) { export function getOriginOfCurrentTab (state) {
return state.activeTab?.origin return state.activeTab?.origin
} }
export function getLastConnectedInfo (state) {
const { permissionsHistory = {} } = state.metamask
const lastConnectedInfoData = Object.keys(permissionsHistory).reduce((acc, origin) => {
const ethAccountsHistory = JSON.parse(JSON.stringify(permissionsHistory[origin]['eth_accounts']))
return {
...acc,
[origin]: ethAccountsHistory.accounts,
}
}, {})
return lastConnectedInfoData
}
export function getIpfsGateway (state) { export function getIpfsGateway (state) {
return state.metamask.ipfsGateway return state.metamask.ipfsGateway
} }