mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-11-23 02:10:12 +01:00
ff36e32fb0
* add todo comments * add snaps-connect component * added new messages * added component scss files to main scss files * remove dead code and add snap-connect-cell * update snaps connect * updated messages and styling * update messages and css * update css * moved snaps privacy warning into snaps connect, moved snaps connect error into snap install * added story and removed unused import * fix style linting and move snaps connect error css * removed unused message * ran lavamoat policy generation * fix fencing * some more css changes * Fix scrolling and box shadow * added comment, fixed quote * Align more with Figma * Regen LavaMoat policies * bring back privacy logic to permission page container * Revert scrolling changes + fix snaps icon * fix linting, reintroduced dedupe logic and additionally addressed a corner case * made some fixes * Fix scrolling with multiple snaps * add dedupe logic to snaps connect and fix spacing issue * policy regen * lint fix * fix fencing * replaced with new icon design, trimmed origin urls in certain places * remove unused imports * badge icon size * Revert LM policy changes * Use SnapAvatar for snaps-connect * Use InstallError for connection failed * Delete unused CSS file * Remove unused CSS * Use useOriginMetadata * addressed PR comments * fix linting errors * add explicit condition * fix fencing * fix some more fencing * fix util fencing issue * fix storybook file, prevent null destructuring * Fix storybook origin URLs * Fix wrong prop name --------- Co-authored-by: Frederik Bolding <frederik.bolding@gmail.com> Co-authored-by: Guillaume Roux <guillaumeroux123@gmail.com> Co-authored-by: Erik Nilsson <eriks@mail.se>
227 lines
6.5 KiB
JavaScript
227 lines
6.5 KiB
JavaScript
import PropTypes from 'prop-types';
|
|
import React, { Component } from 'react';
|
|
import { isEqual } from 'lodash';
|
|
///: BEGIN:ONLY_INCLUDE_IN(snaps)
|
|
import {
|
|
SnapCaveatType,
|
|
WALLET_SNAP_PERMISSION_KEY,
|
|
} from '@metamask/rpc-methods';
|
|
///: END:ONLY_INCLUDE_IN
|
|
import { MetaMetricsEventCategory } from '../../../../shared/constants/metametrics';
|
|
import { PageContainerFooter } from '../../ui/page-container';
|
|
import PermissionsConnectFooter from '../permissions-connect-footer';
|
|
///: BEGIN:ONLY_INCLUDE_IN(snaps)
|
|
import { RestrictedMethods } from '../../../../shared/constants/permissions';
|
|
import SnapPrivacyWarning from '../snaps/snap-privacy-warning';
|
|
import { getDedupedSnaps } from '../../../helpers/utils/util';
|
|
///: END:ONLY_INCLUDE_IN
|
|
import { PermissionPageContainerContent } from '.';
|
|
|
|
export default class PermissionPageContainer extends Component {
|
|
static propTypes = {
|
|
approvePermissionsRequest: PropTypes.func.isRequired,
|
|
rejectPermissionsRequest: PropTypes.func.isRequired,
|
|
selectedIdentities: PropTypes.array,
|
|
allIdentitiesSelected: PropTypes.bool,
|
|
///: BEGIN:ONLY_INCLUDE_IN(snaps)
|
|
currentPermissions: PropTypes.object,
|
|
snapsInstallPrivacyWarningShown: PropTypes.bool.isRequired,
|
|
setSnapsInstallPrivacyWarningShownStatus: PropTypes.func,
|
|
///: END:ONLY_INCLUDE_IN
|
|
request: PropTypes.object,
|
|
requestMetadata: PropTypes.object,
|
|
targetSubjectMetadata: PropTypes.shape({
|
|
name: PropTypes.string,
|
|
origin: PropTypes.string.isRequired,
|
|
subjectType: PropTypes.string.isRequired,
|
|
extensionId: PropTypes.string,
|
|
iconUrl: PropTypes.string,
|
|
}),
|
|
};
|
|
|
|
static defaultProps = {
|
|
request: {},
|
|
requestMetadata: {},
|
|
selectedIdentities: [],
|
|
allIdentitiesSelected: false,
|
|
///: BEGIN:ONLY_INCLUDE_IN(snaps)
|
|
currentPermissions: {},
|
|
///: END:ONLY_INCLUDE_IN
|
|
};
|
|
|
|
static contextTypes = {
|
|
t: PropTypes.func,
|
|
trackEvent: PropTypes.func,
|
|
};
|
|
|
|
state = {
|
|
selectedPermissions: this.getRequestedMethodState(
|
|
this.getRequestedMethodNames(this.props),
|
|
),
|
|
};
|
|
|
|
componentDidUpdate() {
|
|
const newMethodNames = this.getRequestedMethodNames(this.props);
|
|
|
|
if (!isEqual(Object.keys(this.state.selectedPermissions), newMethodNames)) {
|
|
// this should be a new request, so just overwrite
|
|
this.setState({
|
|
selectedPermissions: this.getRequestedMethodState(newMethodNames),
|
|
});
|
|
}
|
|
}
|
|
|
|
getRequestedMethodState(methodNames) {
|
|
return methodNames.reduce((acc, methodName) => {
|
|
///: BEGIN:ONLY_INCLUDE_IN(snaps)
|
|
if (methodName === RestrictedMethods.wallet_snap) {
|
|
acc[methodName] = this.getDedupedSnapPermissions();
|
|
return acc;
|
|
}
|
|
///: END:ONLY_INCLUDE_IN
|
|
acc[methodName] = true;
|
|
return acc;
|
|
}, {});
|
|
}
|
|
|
|
///: BEGIN:ONLY_INCLUDE_IN(snaps)
|
|
getDedupedSnapPermissions() {
|
|
const { request, currentPermissions } = this.props;
|
|
const snapKeys = getDedupedSnaps(request, currentPermissions);
|
|
const permission = request?.permissions?.[WALLET_SNAP_PERMISSION_KEY] || {};
|
|
return {
|
|
...permission,
|
|
caveats: [
|
|
{
|
|
type: SnapCaveatType.SnapIds,
|
|
value: snapKeys.reduce((caveatValue, snapId) => {
|
|
caveatValue[snapId] = {};
|
|
return caveatValue;
|
|
}, {}),
|
|
},
|
|
],
|
|
};
|
|
}
|
|
|
|
showSnapsPrivacyWarning() {
|
|
this.setState({
|
|
isShowingSnapsPrivacyWarning: true,
|
|
});
|
|
}
|
|
///: END:ONLY_INCLUDE_IN
|
|
|
|
getRequestedMethodNames(props) {
|
|
return Object.keys(props.request.permissions || {});
|
|
}
|
|
|
|
componentDidMount() {
|
|
this.context.trackEvent({
|
|
category: MetaMetricsEventCategory.Auth,
|
|
event: 'Tab Opened',
|
|
properties: {
|
|
action: 'Connect',
|
|
legacy_event: true,
|
|
},
|
|
});
|
|
|
|
///: BEGIN:ONLY_INCLUDE_IN(snaps)
|
|
if (this.props.request.permissions[WALLET_SNAP_PERMISSION_KEY]) {
|
|
if (this.props.snapsInstallPrivacyWarningShown === false) {
|
|
this.showSnapsPrivacyWarning();
|
|
}
|
|
}
|
|
///: END:ONLY_INCLUDE_IN
|
|
}
|
|
|
|
onCancel = () => {
|
|
const { request, rejectPermissionsRequest } = this.props;
|
|
rejectPermissionsRequest(request.metadata.id);
|
|
};
|
|
|
|
onSubmit = () => {
|
|
const {
|
|
request: _request,
|
|
approvePermissionsRequest,
|
|
rejectPermissionsRequest,
|
|
selectedIdentities,
|
|
} = this.props;
|
|
|
|
const request = {
|
|
..._request,
|
|
permissions: { ..._request.permissions },
|
|
approvedAccounts: selectedIdentities.map(
|
|
(selectedIdentity) => selectedIdentity.address,
|
|
),
|
|
};
|
|
|
|
Object.keys(this.state.selectedPermissions).forEach((key) => {
|
|
if (!this.state.selectedPermissions[key]) {
|
|
delete request.permissions[key];
|
|
}
|
|
});
|
|
|
|
if (Object.keys(request.permissions).length > 0) {
|
|
approvePermissionsRequest(request);
|
|
} else {
|
|
rejectPermissionsRequest(request.metadata.id);
|
|
}
|
|
};
|
|
|
|
render() {
|
|
const {
|
|
requestMetadata,
|
|
targetSubjectMetadata,
|
|
selectedIdentities,
|
|
allIdentitiesSelected,
|
|
} = this.props;
|
|
|
|
///: BEGIN:ONLY_INCLUDE_IN(snaps)
|
|
const setIsShowingSnapsPrivacyWarning = (value) => {
|
|
this.setState({
|
|
isShowingSnapsPrivacyWarning: value,
|
|
});
|
|
};
|
|
|
|
const confirmSnapsPrivacyWarning = () => {
|
|
setIsShowingSnapsPrivacyWarning(false);
|
|
this.props.setSnapsInstallPrivacyWarningShownStatus(true);
|
|
};
|
|
///: END:ONLY_INCLUDE_IN
|
|
|
|
return (
|
|
<div className="page-container permission-approval-container">
|
|
{
|
|
///: BEGIN:ONLY_INCLUDE_IN(snaps)
|
|
<>
|
|
{this.state.isShowingSnapsPrivacyWarning && (
|
|
<SnapPrivacyWarning
|
|
onAccepted={() => confirmSnapsPrivacyWarning()}
|
|
onCanceled={() => this.onCancel()}
|
|
/>
|
|
)}
|
|
</>
|
|
///: END:ONLY_INCLUDE_IN
|
|
}
|
|
<PermissionPageContainerContent
|
|
requestMetadata={requestMetadata}
|
|
subjectMetadata={targetSubjectMetadata}
|
|
selectedPermissions={this.state.selectedPermissions}
|
|
selectedIdentities={selectedIdentities}
|
|
allIdentitiesSelected={allIdentitiesSelected}
|
|
/>
|
|
<div className="permission-approval-container__footers">
|
|
<PermissionsConnectFooter />
|
|
<PageContainerFooter
|
|
cancelButtonType="default"
|
|
onCancel={() => this.onCancel()}
|
|
cancelText={this.context.t('cancel')}
|
|
onSubmit={() => this.onSubmit()}
|
|
submitText={this.context.t('connect')}
|
|
buttonSizeLarge={false}
|
|
/>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
}
|