From 69c2cd3a94619c29203d9a5afbc30c79bcd45d51 Mon Sep 17 00:00:00 2001 From: Ariella Vu <20778143+digiwand@users.noreply.github.com> Date: Mon, 14 Mar 2022 15:26:02 -0300 Subject: [PATCH] Permissions: convert hook to util (#13906) * Permissions: convert hook into helper util - instantiate once - freeze - alphabetize - add additional comments to @param https://github.com/MetaMask/metamask-extension/pull/13906#pullrequestreview-906554847 --- .../connected-accounts-permissions.js | 6 +- .../permissions-connect-permission-list.js | 6 +- ui/helpers/utils/permission.js | 92 +++++++++++++++++ ui/hooks/usePermissionDescriptions.js | 98 ------------------- 4 files changed, 98 insertions(+), 104 deletions(-) create mode 100644 ui/helpers/utils/permission.js delete mode 100644 ui/hooks/usePermissionDescriptions.js diff --git a/ui/components/app/connected-accounts-permissions/connected-accounts-permissions.js b/ui/components/app/connected-accounts-permissions/connected-accounts-permissions.js index feb781ab7..dce984c47 100644 --- a/ui/components/app/connected-accounts-permissions/connected-accounts-permissions.js +++ b/ui/components/app/connected-accounts-permissions/connected-accounts-permissions.js @@ -3,14 +3,12 @@ import PropTypes from 'prop-types'; import React, { useState } from 'react'; import CheckBox from '../../ui/check-box'; import { useI18nContext } from '../../../hooks/useI18nContext'; -import { usePermissionDescriptions } from '../../../hooks/usePermissionDescriptions'; +import { getPermissionDescription } from '../../../helpers/utils/permission'; const ConnectedAccountsPermissions = ({ permissions }) => { const t = useI18nContext(); const [expanded, setExpanded] = useState(false); - const getPermissionDescription = usePermissionDescriptions(); - const toggleExpanded = () => { setExpanded((_expanded) => !_expanded); }; @@ -56,7 +54,7 @@ const ConnectedAccountsPermissions = ({ permissions }) => { className="connected-accounts-permissions__checkbox" /> ))} diff --git a/ui/components/app/permissions-connect-permission-list/permissions-connect-permission-list.js b/ui/components/app/permissions-connect-permission-list/permissions-connect-permission-list.js index 49ab4c003..d2459025d 100644 --- a/ui/components/app/permissions-connect-permission-list/permissions-connect-permission-list.js +++ b/ui/components/app/permissions-connect-permission-list/permissions-connect-permission-list.js @@ -1,14 +1,16 @@ import React from 'react'; import PropTypes from 'prop-types'; -import { usePermissionDescriptions } from '../../../hooks/usePermissionDescriptions'; +import { getPermissionDescription } from '../../../helpers/utils/permission'; +import { useI18nContext } from '../../../hooks/useI18nContext'; export default function PermissionsConnectPermissionList({ permissions }) { - const getPermissionDescription = usePermissionDescriptions(); + const t = useI18nContext(); return (
{Object.keys(permissions).map((permission) => { const { label, leftIcon, rightIcon } = getPermissionDescription( + t, permission, ); diff --git a/ui/helpers/utils/permission.js b/ui/helpers/utils/permission.js new file mode 100644 index 000000000..baa21dc18 --- /dev/null +++ b/ui/helpers/utils/permission.js @@ -0,0 +1,92 @@ +import deepFreeze from 'deep-freeze-strict'; +import { + RestrictedMethods, + ///: BEGIN:ONLY_INCLUDE_IN(flask) + EndowmentPermissions, + PermissionNamespaces, + ///: END:ONLY_INCLUDE_IN +} from '../../../shared/constants/permissions'; +///: BEGIN:ONLY_INCLUDE_IN(flask) +import { coinTypeToProtocolName } from './util'; +///: END:ONLY_INCLUDE_IN + +const UNKNOWN_PERMISSION = Symbol('unknown'); + +const PERMISSION_DESCRIPTIONS = deepFreeze({ + [RestrictedMethods.eth_accounts]: { + label: (t) => t('permission_ethereumAccounts'), + leftIcon: 'fas fa-eye', + rightIcon: null, + }, + ///: BEGIN:ONLY_INCLUDE_IN(flask) + [RestrictedMethods.snap_confirm]: { + label: (t) => t('permission_customConfirmation'), + leftIcon: 'fas fa-user-check', + rightIcon: null, + }, + [RestrictedMethods['snap_getBip44Entropy_*']]: { + label: (t, permissionName) => { + const coinType = permissionName.split('_').slice(-1); + return t('permission_manageBip44Keys', [ + coinTypeToProtocolName(coinType) || + `${coinType} (Unrecognized protocol)`, + ]); + }, + leftIcon: 'fas fa-door-open', + rightIcon: null, + }, + [RestrictedMethods.snap_manageState]: { + label: (t) => t('permission_manageState'), + leftIcon: 'fas fa-download', + rightIcon: null, + }, + [RestrictedMethods['wallet_snap_*']]: { + label: (t, permissionName) => { + const snapId = permissionName.split('_').slice(-1); + return t('permission_accessSnap', [snapId]); + }, + leftIcon: 'fas fa-bolt', + rightIcon: null, + }, + [EndowmentPermissions['endowment:network-access']]: { + label: (t) => t('permission_accessNetwork'), + leftIcon: 'fas fa-wifi', + rightIcon: null, + }, + ///: END:ONLY_INCLUDE_IN + [UNKNOWN_PERMISSION]: { + label: (t, permissionName) => + t('permission_unknown', [permissionName ?? 'undefined']), + leftIcon: 'fas fa-times-circle', + rightIcon: null, + }, +}); + +/** + * @typedef {Object} PermissionLabelObject + * @property {string} label - The text label. + * @property {string} leftIcon - The left icon. + * @property {string} rightIcon - The right icon. + */ + +/** + * @param {Function} t - The translation function + * @param {string} permissionName - The name of the permission to request + * @returns {(permissionName:string) => PermissionLabelObject} + */ +export const getPermissionDescription = (t, permissionName) => { + let value = PERMISSION_DESCRIPTIONS[UNKNOWN_PERMISSION]; + + if (Object.hasOwnProperty.call(PERMISSION_DESCRIPTIONS, permissionName)) { + value = PERMISSION_DESCRIPTIONS[permissionName]; + } + ///: BEGIN:ONLY_INCLUDE_IN(flask) + for (const namespace of Object.keys(PermissionNamespaces)) { + if (permissionName.startsWith(namespace)) { + value = PERMISSION_DESCRIPTIONS[PermissionNamespaces[namespace]]; + } + } + ///: END:ONLY_INCLUDE_IN + + return { ...value, label: value.label(t, permissionName) }; +}; diff --git a/ui/hooks/usePermissionDescriptions.js b/ui/hooks/usePermissionDescriptions.js deleted file mode 100644 index 054f47bfe..000000000 --- a/ui/hooks/usePermissionDescriptions.js +++ /dev/null @@ -1,98 +0,0 @@ -import { useMemo } from 'react'; -import { - RestrictedMethods, - ///: BEGIN:ONLY_INCLUDE_IN(flask) - EndowmentPermissions, - PermissionNamespaces, - ///: END:ONLY_INCLUDE_IN -} from '../../shared/constants/permissions'; -///: BEGIN:ONLY_INCLUDE_IN(flask) -import { coinTypeToProtocolName } from '../helpers/utils/util'; -///: END:ONLY_INCLUDE_IN -import { useI18nContext } from './useI18nContext'; - -const UNKNOWN_PERMISSION = Symbol('unknown'); - -/** - * @typedef {Object} PermissionLabelObject - * @property {string} label - The text label. - * @property {string} leftIcon - The left icon. - * @property {string} rightIcon - The right icon. - */ - -/** - * @returns {(permissionName:string) => PermissionLabelObject} - */ -export const usePermissionDescriptions = () => { - const t = useI18nContext(); - - return useMemo(() => { - const permissionDescriptions = { - [RestrictedMethods.eth_accounts]: { - leftIcon: 'fas fa-eye', - label: t('permission_ethereumAccounts'), - rightIcon: null, - }, - ///: BEGIN:ONLY_INCLUDE_IN(flask) - [RestrictedMethods.snap_confirm]: { - leftIcon: 'fas fa-user-check', - label: t('permission_customConfirmation'), - rightIcon: null, - }, - [RestrictedMethods['snap_getBip44Entropy_*']]: (permissionName) => { - const coinType = permissionName.split('_').slice(-1); - return { - leftIcon: 'fas fa-door-open', - label: t('permission_manageBip44Keys', [ - coinTypeToProtocolName(coinType) || - `${coinType} (Unrecognized protocol)`, - ]), - rightIcon: null, - }; - }, - [RestrictedMethods.snap_manageState]: { - leftIcon: 'fas fa-download', - label: t('permission_manageState'), - rightIcon: null, - }, - [RestrictedMethods['wallet_snap_*']]: (permissionName) => { - const snapId = permissionName.split('_').slice(-1); - return { - leftIcon: 'fas fa-bolt', - label: t('permission_accessSnap', [snapId]), - rightIcon: null, - }; - }, - [EndowmentPermissions['endowment:network-access']]: { - leftIcon: 'fas fa-wifi', - label: t('permission_accessNetwork'), - rightIcon: null, - }, - ///: END:ONLY_INCLUDE_IN - [UNKNOWN_PERMISSION]: (permissionName) => { - return { - leftIcon: 'fas fa-times-circle', - label: t('permission_unknown', [permissionName ?? 'undefined']), - rightIcon: null, - }; - }, - }; - - return (permissionName) => { - let value = permissionDescriptions[UNKNOWN_PERMISSION]; - - if (Object.hasOwnProperty.call(permissionDescriptions, permissionName)) { - value = permissionDescriptions[permissionName]; - } - ///: BEGIN:ONLY_INCLUDE_IN(flask) - for (const namespace of Object.keys(PermissionNamespaces)) { - if (permissionName.startsWith(namespace)) { - value = permissionDescriptions[PermissionNamespaces[namespace]]; - } - } - ///: END:ONLY_INCLUDE_IN - - return typeof value === 'function' ? value(permissionName) : value; - }; - }, [t]); -};