Skip to content

Commit

Permalink
feat: Render pending 2FA actions in <TwoFactorVerifyModal />
Browse files Browse the repository at this point in the history
  • Loading branch information
morgsmccauley committed Mar 17, 2022
1 parent 7da13ee commit 66b9b52
Show file tree
Hide file tree
Showing 3 changed files with 117 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import styled from 'styled-components';
const Container = styled.div`
max-width: 350px;
width: 100%;
margin: 40px 0;
margin-bottom: 40px;
.color-black {
font-weight: 500;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,32 +1,125 @@
import BN from 'bn.js';
import { utils } from 'near-api-js';
import React, { useEffect, useState } from 'react';
import { Translate } from 'react-localize-redux';
import { useDispatch, useSelector } from 'react-redux';
import styled from 'styled-components';

import { Mixpanel } from '../../../mixpanel/index';
import { resendTwoFactor, get2faMethod } from '../../../redux/actions/account';
import { selectAccountSlice } from '../../../redux/slices/account';
import { resendTwoFactor, get2faMethod, getMultisigRequest } from '../../../redux/actions/account';
import { selectAccountSlice, selectAccountMultisigRequest } from '../../../redux/slices/account';
import { selectActionsPending, selectStatusSlice } from '../../../redux/slices/status';
import { WalletError } from '../../../utils/walletError';
import AlertBanner from '../../common/AlertBanner';
import FormButton from '../../common/FormButton';
import Modal from '../../common/modal/Modal';
import ModalTheme from '../ledger/ModalTheme';
import TwoFactorVerifyInput from './TwoFactorVerifyInput';

const {
format: {
formatNearAmount
},
key_pair: {
PublicKey,
KeyType
},
} = utils;

const Form = styled.form`
display: flex;
flex-direction: column;
align-items: center;
width: 100%;
`;

const formatNear = (amount) => {
try {
return formatNearAmount(amount, 4);
} catch {
// Near amount may be stored as hex rather than decimal
return formatNearAmount(new BN(amount, 16).toString(), 4);
}
};

const getTranslationsFromMultisigRequest = ({ actions, receiverId, accountId }) => {
const fullAccessKeyAction = actions.find(({ enum: type, permission }) => type === 'addKey' && !permission);
if (fullAccessKeyAction) {
const publicKey = new PublicKey({
keyType: KeyType.ED25519,
data: fullAccessKeyAction.addKey.publicKey.data
});
return [
{
id: 'twoFactor.action.addKey.full',
data: {
accountId,
publicKey: publicKey.toString(),
}
}
];
}

return actions
.map(({ enum: actionType, [actionType]: action }) => {
switch (actionType) {
case 'addKey':
return {
id: 'twoFactor.action.addKey.limited',
data: {
receiverId,
methodNames: action.permission.functionCall.methodNames.join(', '),
allowance: formatNearAmount(action.permission.functionCall.allowance, 4),
publicKey: new PublicKey({ keyType: KeyType.ED25519, data: action.publicKey.data }).toString(),
}
};
case 'deleteKey':
return {
id: 'twoFactor.action.deleteKey',
data: {
publicKey: new PublicKey({ keyType: KeyType.ED25519, data: action.publicKey.data }).toString(),
}
};
case 'functionCall':
return {
id: 'twoFactor.action.functionCall',
data: {
receiverId,
methodName: action.methodName,
deposit: formatNear(action.deposit, 4),
args: Buffer.from(action.args).toString(),
}
};
case 'transfer':
return {
id: 'twoFactor.action.transfer',
data:{
receiverId,
deposit: formatNearAmount(action.deposit, 4),
}
};
case 'stake':
return {
id: 'twoFactor.action.stake',
data: {
receiverId,
deposit: formatNearAmount(action.deposit, 4),
}
};
default:
return {};
}
});
};

const TwoFactorVerifyModal = ({ open, onClose }) => {

const [method, setMethod] = useState();
const [code, setCode] = useState('');
const [resendCode, setResendCode] = useState();
const dispatch = useDispatch();
const account = useSelector(selectAccountSlice);
const multisigRequest = useSelector(selectAccountMultisigRequest);
const status = useSelector(selectStatusSlice);
const loading = useSelector((state) => selectActionsPending(state, { types: ['VERIFY_TWO_FACTOR'] }));

Expand All @@ -39,6 +132,7 @@ const TwoFactorVerifyModal = ({ open, onClose }) => {

if (isMounted) {
handleGetTwoFactor();
dispatch(getMultisigRequest());
}

return () => { isMounted = false; };
Expand Down Expand Up @@ -85,6 +179,16 @@ const TwoFactorVerifyModal = ({ open, onClose }) => {
<h2 className='title'><Translate id='twoFactor.verify.title'/></h2>
<p className='font-bw'><Translate id='twoFactor.verify.desc'/></p>
<p className='color-black font-bw' style={{ marginTop: '-10px', fontWeight: '500', height: '19px'}}>{method && method.detail}</p>
{multisigRequest && (
<AlertBanner theme="alert">
{getTranslationsFromMultisigRequest(multisigRequest).map(({ id, data }) => (
<>
<Translate id={id} data={data} />
<br />
</>
))}
</AlertBanner>
)}
<Form onSubmit={(e) => {handleVerifyCode(); e.preventDefault();}}>
<TwoFactorVerifyInput
code={code}
Expand Down
10 changes: 10 additions & 0 deletions packages/frontend/src/translations/en.global.json
Original file line number Diff line number Diff line change
Expand Up @@ -1469,6 +1469,16 @@
"resending": "Sending...",
"resent": "Code sent!",
"title": "Enter Two-Factor Verification Code"
},
"action": {
"addKey": {
"limited": "Adding key ${publicKey} limited to call ${methodNames} on ${receiverId} and spend up to ${allowance} on gas",
"full": "WARNING: Entering the code below will authorize full access to your NEAR account: ${accountId}. If you did not initiate this action, please DO NOT continue.<br /><br />This should only be done if you are adding a new seed phrase to your account. In all other cases, this is very dangerous.<br /><br /> The public key you are adding is: ${publicKey} ",
},
"deleteKey": "Deleting key ${publicKey}",
"functionCall": "Calling method: ${methodName} in contract: ${receiverId} with amount ${deposit} and with args ${args}",
"stake": "Staking: ${deposit} to validator: ${receiverId}",
"transfer": "Transferring: ${deposit}Ⓝ to ${receiverId}"
}
},
"unlockedAvailTransfer": "This NEAR is unlocked, and can be transferred out of your lockup contract.",
Expand Down

0 comments on commit 66b9b52

Please sign in to comment.