1
0
mirror of https://github.com/kremalicious/metamask-extension.git synced 2024-12-23 09:52:26 +01:00
metamask-extension/ui/app/pages/permissions-connect/permissions-connect.component.js
Mark Stacey e4410724e9
Show origin in connect flow rather than site name (#8885)
The designs for the connect flow show the site `origin` below the site
icon rather than the site name. This was done for security reasons,
and because the site name is often set to an unwieldy long string.

This was accidentally undone in #8815 in the process of fixing a
separate bug. The origin has now been restored. More specific PropTypes
have been set on each use of the `domainMetadata` prop as well.
2020-07-02 14:08:43 -03:00

276 lines
8.3 KiB
JavaScript

import PropTypes from 'prop-types'
import React, { Component } from 'react'
import { Switch, Route } from 'react-router-dom'
import { getEnvironmentType } from '../../../../app/scripts/lib/util'
import { ENVIRONMENT_TYPE_NOTIFICATION } from '../../../../app/scripts/lib/enums'
import { DEFAULT_ROUTE } from '../../helpers/constants/routes'
import PermissionPageContainer from '../../components/app/permission-page-container'
import ChooseAccount from './choose-account'
import PermissionsRedirect from './redirect'
const APPROVE_TIMEOUT = 1200
export default class PermissionConnect extends Component {
static propTypes = {
approvePermissionsRequest: PropTypes.func.isRequired,
rejectPermissionsRequest: PropTypes.func.isRequired,
getRequestAccountTabIds: PropTypes.func.isRequired,
getCurrentWindowTab: PropTypes.func.isRequired,
accounts: PropTypes.array.isRequired,
currentAddress: PropTypes.string.isRequired,
origin: PropTypes.string,
showNewAccountModal: PropTypes.func.isRequired,
newAccountNumber: PropTypes.number.isRequired,
nativeCurrency: PropTypes.string,
permissionsRequest: PropTypes.object,
addressLastConnectedMap: PropTypes.object.isRequired,
lastConnectedInfo: PropTypes.object.isRequired,
permissionsRequestId: PropTypes.string,
hasPendingPermissionsRequests: PropTypes.bool.isRequired,
history: PropTypes.object.isRequired,
connectPath: PropTypes.string.isRequired,
confirmPermissionPath: PropTypes.string.isRequired,
page: PropTypes.string.isRequired,
targetDomainMetadata: PropTypes.shape({
extensionId: PropTypes.string,
icon: PropTypes.string,
host: PropTypes.string.isRequired,
name: PropTypes.string.isRequired,
origin: PropTypes.string.isRequired,
}),
}
static defaultProps = {
origin: '',
nativeCurrency: '',
permissionsRequest: undefined,
permissionsRequestId: '',
}
static contextTypes = {
t: PropTypes.func,
}
state = {
redirecting: false,
selectedAccountAddresses: new Set([this.props.currentAddress]),
permissionsApproved: null,
origin: this.props.origin,
targetDomainMetadata: this.props.targetDomainMetadata || {},
}
beforeUnload = () => {
const { permissionsRequestId, rejectPermissionsRequest } = this.props
const { permissionsApproved } = this.state
if (permissionsApproved === null && permissionsRequestId) {
rejectPermissionsRequest(permissionsRequestId)
}
}
removeBeforeUnload = () => {
const environmentType = getEnvironmentType()
if (environmentType === ENVIRONMENT_TYPE_NOTIFICATION) {
window.removeEventListener('beforeunload', this.beforeUnload)
}
}
componentDidMount () {
const {
getCurrentWindowTab,
getRequestAccountTabIds,
permissionsRequest,
history,
} = this.props
getCurrentWindowTab()
getRequestAccountTabIds()
if (!permissionsRequest) {
return history.push(DEFAULT_ROUTE)
}
const environmentType = getEnvironmentType()
if (environmentType === ENVIRONMENT_TYPE_NOTIFICATION) {
window.addEventListener('beforeunload', this.beforeUnload)
}
}
static getDerivedStateFromProps (props, state) {
const { permissionsRequest, targetDomainMetadata } = props
const { targetDomainMetadata: savedMetadata } = state
if (
permissionsRequest &&
savedMetadata.origin !== targetDomainMetadata?.origin
) {
return { targetDomainMetadata }
}
return null
}
componentDidUpdate (prevProps) {
const { permissionsRequest, lastConnectedInfo } = this.props
const { redirecting, origin } = this.state
if (!permissionsRequest && prevProps.permissionsRequest && !redirecting) {
const accountsLastApprovedTime = lastConnectedInfo[origin]?.lastApproved || 0
const initialAccountsLastApprovedTime = prevProps.lastConnectedInfo[origin]?.lastApproved || 0
const approved = accountsLastApprovedTime > initialAccountsLastApprovedTime
this.redirect(approved)
}
}
selectAccounts = (addresses) => {
this.setState({
selectedAccountAddresses: addresses,
}, () => this.props.history.push(this.props.confirmPermissionPath))
}
redirect (approved) {
this.setState({
redirecting: true,
permissionsApproved: approved,
})
this.removeBeforeUnload()
if (approved) {
setTimeout(this._doRedirect.bind(this), APPROVE_TIMEOUT)
} else {
this._doRedirect()
}
}
_doRedirect () {
const { history, hasPendingPermissionsRequests } = this.props
if (
!hasPendingPermissionsRequests &&
getEnvironmentType() === ENVIRONMENT_TYPE_NOTIFICATION
) {
global.platform.closeCurrentWindow()
} else {
history.push(DEFAULT_ROUTE)
}
}
cancelPermissionsRequest = async (requestId) => {
const { rejectPermissionsRequest } = this.props
if (requestId) {
await rejectPermissionsRequest(requestId)
this.redirect(false)
}
}
goBack () {
const { history, connectPath } = this.props
history.push(connectPath)
}
renderTopBar () {
const { redirecting } = this.state
const { page } = this.props
const { t } = this.context
return !redirecting
? (
<div
className="permissions-connect__top-bar"
>
{ page === '2'
? (
<div className="permissions-connect__back" onClick={() => this.goBack()}>
<i className="fas fa-chevron-left" />
{ t('back') }
</div>
)
: null
}
<div className="permissions-connect__page-count">
{ t('xOfY', [ page, '2' ]) }
</div>
</div>
)
: null
}
render () {
const {
approvePermissionsRequest,
accounts,
showNewAccountModal,
newAccountNumber,
nativeCurrency,
permissionsRequest,
addressLastConnectedMap,
permissionsRequestId,
connectPath,
confirmPermissionPath,
} = this.props
const {
selectedAccountAddresses,
permissionsApproved,
redirecting,
targetDomainMetadata,
} = this.state
return (
<div className="permissions-connect">
{ this.renderTopBar() }
{
redirecting && permissionsApproved
? (
<PermissionsRedirect
domainMetadata={targetDomainMetadata}
/>
)
: (
<Switch>
<Route
path={connectPath}
exact
render={() => (
<ChooseAccount
accounts={accounts}
nativeCurrency={nativeCurrency}
selectAccounts={(addresses) => this.selectAccounts(addresses)}
selectNewAccountViaModal={(handleAccountClick) => {
showNewAccountModal({
onCreateNewAccount: (address) => handleAccountClick(address),
newAccountNumber,
})
}}
addressLastConnectedMap={addressLastConnectedMap}
cancelPermissionsRequest={(requestId) => this.cancelPermissionsRequest(requestId)}
permissionsRequestId={permissionsRequestId}
selectedAccountAddresses={selectedAccountAddresses}
targetDomainMetadata={targetDomainMetadata}
/>
)}
/>
<Route
path={confirmPermissionPath}
exact
render={() => (
<PermissionPageContainer
request={permissionsRequest || {}}
approvePermissionsRequest={(request, accounts) => {
approvePermissionsRequest(request, accounts)
this.redirect(true)
}}
rejectPermissionsRequest={(requestId) => this.cancelPermissionsRequest(requestId)}
selectedIdentities={accounts.filter((account) => selectedAccountAddresses.has(account.address))}
targetDomainMetadata={targetDomainMetadata}
/>
)}
/>
</Switch>
)
}
</div>
)
}
}