diff --git a/packages/frontend/package.json b/packages/frontend/package.json index 78443675e1..3f69d9a90d 100644 --- a/packages/frontend/package.json +++ b/packages/frontend/package.json @@ -39,6 +39,7 @@ "react-google-recaptcha": "^2.1.0", "react-google-recaptcha-v3-near": "^2.0.0", "react-helmet": "^6.1.0", + "react-idle-timer": "^4.6.4", "react-localize-redux": "^3.5.3", "react-phone-number-input": "2.3.11", "react-redux": "^7.2.4", diff --git a/packages/frontend/src/components/Routing.js b/packages/frontend/src/components/Routing.js index cd406117e4..0f3d0b205a 100644 --- a/packages/frontend/src/components/Routing.js +++ b/packages/frontend/src/components/Routing.js @@ -5,6 +5,7 @@ import PropTypes from 'prop-types'; import { stringify } from 'query-string'; import React, { Component } from 'react'; import ReactDOMServer from 'react-dom/server'; +import IdleTimer from 'react-idle-timer'; import { withLocalize } from 'react-localize-redux'; import { connect } from 'react-redux'; import { Redirect, Switch } from 'react-router-dom'; @@ -19,12 +20,15 @@ import * as accountActions from '../redux/actions/account'; import { handleClearAlert } from '../redux/reducers/status'; import { selectAccountSlice } from '../redux/slices/account'; import { actions as tokenFiatValueActions } from '../redux/slices/tokenFiatValues'; +import ChangePassword from '../routes/ChangePassword'; import { CreateImplicitAccountWrapper } from '../routes/CreateImplicitAccountWrapper'; import { LoginWrapper } from '../routes/LoginWrapper'; +import SetPassword from '../routes/SetPassword'; import { SetupLedgerNewAccountWrapper } from '../routes/SetupLedgerNewAccountWrapper'; import { SetupPassphraseNewAccountWrapper } from '../routes/SetupPassphraseNewAccountWrapper'; import { SetupRecoveryImplicitAccountWrapper } from '../routes/SetupRecoveryImplicitAccountWrapper'; import { SignWrapper } from '../routes/SignWrapper'; +import UnlockWallet from '../routes/UnlockWallet'; import translations_en from '../translations/en.global.json'; import translations_pt from '../translations/pt.global.json'; import translations_ru from '../translations/ru.global.json'; @@ -77,6 +81,7 @@ import Navigation from './navigation/Navigation'; import { PageNotFound } from './page-not-found/PageNotFound'; import { Profile } from './profile/Profile'; import { ReceiveContainerWrapper } from './receive-money/ReceiveContainerWrapper'; +import InactivityLockModal from './security/InactivityLockModal'; import { SendContainerWrapper } from './send/SendContainerWrapper'; import { StakingContainer } from './staking/StakingContainer'; import Terms from './terms/Terms'; @@ -84,9 +89,8 @@ import { Wallet } from './wallet/Wallet'; import '../index.css'; -const { - fetchTokenFiatValues -} = tokenFiatValueActions; + +const { fetchTokenFiatValues } = tokenFiatValueActions; const { getAccountHelperWalletState, @@ -134,7 +138,8 @@ class Routing extends Component { super(props); this.state = { - isInactiveAccount: null + isInactiveAccount: null, + isUserActive: true }; this.pollTokenFiatValue = null; @@ -249,6 +254,14 @@ class Routing extends Component { this.stopPollingTokenFiatValue(); } + handleSetUserActive = () => { + return this.setState({...this.state,isUserActive: true }); + } + + handleSetUserIdle = () => { + return this.setState({...this.state, isUserActive: false }); + } + startPollingTokenFiatValue = () => { const { fetchTokenFiatValues } = this.props; @@ -313,6 +326,14 @@ class Routing extends Component { + + {!this.state.isUserActive && + + } { account.requestPending !== null && + + + {!isInactiveAccount && { - const { accountId, fundingAmount } = this.state; - const { - fundingContract, fundingKey, - fundingAccountId, - } = this.props; + // const { accountId, fundingAmount } = this.state; + // const { + // fundingContract, fundingKey, + // fundingAccountId, + // } = this.props; - this.setState({ loader: true }); + // this.setState({ loader: true }); - let queryString = ''; - if (fundingAccountId || fundingContract) { - const fundingOptions = fundingAccountId ? { fundingAccountId } : { fundingContract, fundingKey, fundingAmount }; - queryString = `?fundingOptions=${encodeURIComponent(JSON.stringify(fundingOptions))}`; - } + // let queryString = ''; + // if (fundingAccountId || fundingContract) { + // const fundingOptions = fundingAccountId ? { fundingAccountId } : { fundingContract, fundingKey, fundingAmount }; + // queryString = `?fundingOptions=${encodeURIComponent(JSON.stringify(fundingOptions))}`; + // } Mixpanel.track('CA Click create account button'); - this.props.history.push(`/set-recovery/${accountId}${queryString}`); + this.props.history.push(`/set-recovery/${'accountId'}${'queryString'}`); } render() { const { - loader, - accountId, invalidNearDrop, termsAccepted, whereToBuy } = this.state; const { - localAlert, - mainLoader, - checkNewAccount, - resetAccount, - clearLocalAlert, fundingContract, fundingKey, nearTokenFiatValueUSD, - locationSearch, activeAccountIdIsImplicit } = this.props; const isLinkDrop = fundingContract && fundingKey; - const useLocalAlert = accountId.length > 0 ? localAlert : undefined; const showTermsPage = IS_MAINNET && !isLinkDrop && !termsAccepted && !ENABLE_IDENTITY_VERIFIED_ACCOUNT; if (showTermsPage) { @@ -253,37 +241,21 @@ class CreateAccount extends Component { />

-

- - - - - + + {!termsAccepted &&
} -
+ {/*
{ Mixpanel.track('IE Click import existing account button'); }}> -
+ */} diff --git a/packages/frontend/src/components/accounts/SetupSeedPhraseForm.js b/packages/frontend/src/components/accounts/SetupSeedPhraseForm.js index e84323747d..6ff2693a06 100644 --- a/packages/frontend/src/components/accounts/SetupSeedPhraseForm.js +++ b/packages/frontend/src/components/accounts/SetupSeedPhraseForm.js @@ -124,7 +124,7 @@ const SetupSeedPhraseForm = ({ color='blue' data-test-id="continueToSeedPhraseVerificationButton" > - + ); diff --git a/packages/frontend/src/components/accounts/recovery_setup/SetupRecoveryMethod.js b/packages/frontend/src/components/accounts/recovery_setup/SetupRecoveryMethod.js index 0f077e6d30..bc258d9e2a 100644 --- a/packages/frontend/src/components/accounts/recovery_setup/SetupRecoveryMethod.js +++ b/packages/frontend/src/components/accounts/recovery_setup/SetupRecoveryMethod.js @@ -528,7 +528,7 @@ class SetupRecoveryMethod extends Component { trackingId='SR Click submit button' data-test-id="submitSelectedRecoveryOption" > - + {isNewAccount && diff --git a/packages/frontend/src/components/accounts/recovery_setup/new_account/ConfirmPassphrase.js b/packages/frontend/src/components/accounts/recovery_setup/new_account/ConfirmPassphrase.js index 53990b07b8..6ca5aea425 100644 --- a/packages/frontend/src/components/accounts/recovery_setup/new_account/ConfirmPassphrase.js +++ b/packages/frontend/src/components/accounts/recovery_setup/new_account/ConfirmPassphrase.js @@ -39,8 +39,10 @@ export default ({ wordIndex, handleChangeWord, handleStartOver, - userInputValueWrongWord + userInputValueWrongWord, + passPhrase }) => { + console.log(passPhrase); return (
- {userInputValueWrongWord && -
- } + { userInputValueWrongWord &&
} { handleConfirmPassphrase({ implicitAccountId, recoveryKeyPair }); Mixpanel.track('SR-SP Verify finish'); }} + passPhrase={passPhrase} /> ); } diff --git a/packages/frontend/src/components/common/Button.js b/packages/frontend/src/components/common/Button.js index ed9145948a..86288d0fd0 100644 --- a/packages/frontend/src/components/common/Button.js +++ b/packages/frontend/src/components/common/Button.js @@ -2,6 +2,26 @@ import PropTypes from 'prop-types'; import React from 'react'; import styled from 'styled-components'; +const backgroundColorMap = { + primary: '#0072CE', + secondary: '#ffffff', + destructive: '#FC5B5B' +}; +const backgroundColorHoverMap = { + primary: '#007fe6', + secondary: '#cccccc', + destructive: '#FC5B5B' +}; +const colorMap = { + primary: '#FFFFFF', + secondary: '#888888', + destructive: '#FFFFFF' +}; +const borderColorMap = { + primary: '#0072CE', + secondary: '#cccccc', + destructive: '#FC5B5B' +}; const StyledButton = styled.button` border-radius: 40px; padding: 5px 32px; @@ -15,14 +35,14 @@ const StyledButton = styled.button` align-items: center; justify-content: center; transition: all 150ms ease; - background-color: ${(props) => props.theme === 'secondary' ? '#ffffff' : '#0072CE'}; - border: 2px solid ${(props) => props.theme === 'secondary' ? '#cccccc' : '#0072CE'}; - color: ${(props) => props.theme === 'secondary' ? '#888888' : 'white'}; + background-color: ${(props) => backgroundColorMap[props.theme]}; + border: 2px solid ${(props) => borderColorMap[props.theme]}; + color: ${(props) => colorMap[props.theme]}; @media (min-width: 768px) { &:enabled { &:hover { - background-color: ${(props) => props.theme === 'secondary' ? '#cccccc' : '#007fe6'}; + background-color: ${(props) => backgroundColorHoverMap[props.theme]}; color: white; } } @@ -50,7 +70,7 @@ const Button = (props) => ( Button.propTypes = { disabled: PropTypes.bool, - theme: PropTypes.oneOf(['primary', 'secondary']), + theme: PropTypes.oneOf(['primary', 'secondary', 'destructive']), fullWidth: PropTypes.bool, }; diff --git a/packages/frontend/src/components/common/modal/Modal.js b/packages/frontend/src/components/common/modal/Modal.js index 62ef288607..006d6cfb6e 100644 --- a/packages/frontend/src/components/common/modal/Modal.js +++ b/packages/frontend/src/components/common/modal/Modal.js @@ -1,6 +1,7 @@ import React, { useState, useEffect } from 'react'; import ReactDom from 'react-dom'; + import classNames from '../../../utils/classNames'; import isMobile from '../../../utils/isMobile'; import CloseButton from './CloseButton'; diff --git a/packages/frontend/src/components/profile/Profile.js b/packages/frontend/src/components/profile/Profile.js index db5673416d..af69d2e5bb 100644 --- a/packages/frontend/src/components/profile/Profile.js +++ b/packages/frontend/src/components/profile/Profile.js @@ -34,6 +34,7 @@ import UserIcon from '../svg/UserIcon'; import AuthorizedApp from './authorized_apps/AuthorizedApp'; import BalanceContainer from './balances/BalanceContainer'; import LockupAvailTransfer from './balances/LockupAvailTransfer'; +import BrowserPassword from './browser-password/BrowserPassword'; import HardwareDevices from './hardware_devices/HardwareDevices'; import MobileSharingWrapper from './mobile_sharing/MobileSharingWrapper'; import RecoveryContainer from './Recovery/RecoveryContainer'; @@ -267,6 +268,12 @@ export function Profile({ match }) {

+
+
+

+
+ +
{!account.ledgerKey && <>
diff --git a/packages/frontend/src/components/profile/browser-password/BrowserPassword.js b/packages/frontend/src/components/profile/browser-password/BrowserPassword.js new file mode 100644 index 0000000000..0171152938 --- /dev/null +++ b/packages/frontend/src/components/profile/browser-password/BrowserPassword.js @@ -0,0 +1,70 @@ +import React from 'react'; +import {Link} from 'react-router-dom'; +import styled from 'styled-components'; + +import Button from '../../common/Button'; +import Card from '../../common/styled/Card.css'; + +const Container = styled(Card)` + margin-top: 30px; + padding: 16px; + + p{ + font-size: 14px; + line-height: 150%; + color: #A2A2A8; + } + .topSection { + display: flex; + align-items: center; + justify-content: space-between; + + div{ + .ttl{ + font-size: 14px; + line-height: 150%; + color: #3F4045; + } + .desc{ + margin-top: 4px; + } + } + + button { + height: 40px; + width: 100px; + display: flex; + align-items: center; + justify-content: center; + padding: 0; + margin: 0; + color: #0072CE; + background: #F0F0F1; + font-size: 14px; + border: none; + } + } +`; + +const BrowserPassword = () => { + return ( + +
+
+

Brave Browser

+

Desktop • v23.13

+
+ + + + +
+

Enabled Jan 08, 2020

+
+ ); +}; + +export default BrowserPassword; + diff --git a/packages/frontend/src/components/security/InactivityLockModal.js b/packages/frontend/src/components/security/InactivityLockModal.js new file mode 100644 index 0000000000..10a256312c --- /dev/null +++ b/packages/frontend/src/components/security/InactivityLockModal.js @@ -0,0 +1,60 @@ +import React from 'react'; +import { Translate } from 'react-localize-redux'; +import styled from 'styled-components'; + +import Button from '../common/Button'; +import Modal from '../common/modal/Modal'; + +const Container = styled.section` + width: 100%; + text-align:center; + + .header { + padding: 24px 16px; + border-bottom: 1px solid #F0F0F1; + + .ttl { + color: #24272A; + } + + .desc { + margin-top:16px; + font-size: 16px; + line-height: 150%; + text-align: center; + color: #72727A; + } + } + + .ctaBtn{ + margin-top: 16px; + } + + + +`; + +const InactivityLockModal = ({ isOpen, onClose }) => { + + return ( + + +
+

+

+
+ +
+
+ ); +}; + +export default InactivityLockModal; diff --git a/packages/frontend/src/components/security/IntroducingPasswordsModal.js b/packages/frontend/src/components/security/IntroducingPasswordsModal.js new file mode 100644 index 0000000000..0446b37df9 --- /dev/null +++ b/packages/frontend/src/components/security/IntroducingPasswordsModal.js @@ -0,0 +1,59 @@ +import React from 'react'; +import { Translate } from 'react-localize-redux'; +import styled from 'styled-components'; + +import Button from '../common/Button'; +import Modal from '../common/modal/Modal'; + +const Container = styled.section` + width: 100%; + text-align:center; + + .header { + padding: 24px 16px; + border-bottom: 1px solid #F0F0F1; + + .ttl { + color: #24272A; + } + + .desc { + margin-top:16px; + font-size: 16px; + line-height: 150%; + text-align: center; + color: #72727A; + } + } + + .ctaBtn{ + margin-top: 16px; + } + + + +`; + +const IntroducingPasswordsModal = ({ isOpen, onClose }) => { + return ( + + +
+

+

+
+ +
+
+ ); +}; + +export default IntroducingPasswordsModal; diff --git a/packages/frontend/src/components/security/KeepPasswordsSafeModal.js b/packages/frontend/src/components/security/KeepPasswordsSafeModal.js new file mode 100644 index 0000000000..d14b327623 --- /dev/null +++ b/packages/frontend/src/components/security/KeepPasswordsSafeModal.js @@ -0,0 +1,59 @@ +import React from 'react'; +import { Translate } from 'react-localize-redux'; +import styled from 'styled-components'; + +import Button from '../common/Button'; +import Modal from '../common/modal/Modal'; + +const Container = styled.section` + width: 100%; + text-align:center; + + .header { + padding: 24px 16px; + border-bottom: 1px solid #F0F0F1; + + .ttl { + color: #24272A; + } + + .desc { + margin-top:16px; + font-size: 16px; + line-height: 150%; + text-align: center; + color: #72727A; + } + } + + .ctaBtn{ + margin-top: 16px; + } + + + +`; + +const KeepPasswordsSafeModal = ({ isOpen, onClose }) => { + return ( + + +
+

+

+
+ +
+
+ ); +}; + +export default KeepPasswordsSafeModal; diff --git a/packages/frontend/src/components/security/ResetWalletPasswordModal.js b/packages/frontend/src/components/security/ResetWalletPasswordModal.js new file mode 100644 index 0000000000..50105d65ee --- /dev/null +++ b/packages/frontend/src/components/security/ResetWalletPasswordModal.js @@ -0,0 +1,74 @@ +import React, {useState} from 'react'; +import { Translate } from 'react-localize-redux'; +import styled from 'styled-components'; + +import Button from '../common/Button'; +import Checkbox from '../common/Checkbox'; +import Modal from '../common/modal/Modal'; + +const Container = styled.section` + width: 100%; + text-align:center; + + .header { + padding: 24px 16px; + + .ttl { + color: #24272A; + } + + .desc { + margin-top:16px; + font-size: 16px; + line-height: 150%; + text-align: center; + color: #72727A; + } + } + + .consentWrapper{ + background: #FFDEDF; + display: flex; + padding: 16px; + } + + .ctaBtn{ + margin-top: 16px; + } +`; + +const ResetWalletPasswordModal = ({ isOpen, onClose }) => { + const [ consentGranted, setConsentGranted ]=useState(true); + return ( + + +
+

+

+
+
+ +
+ + +
+
+ ); +}; + +export default ResetWalletPasswordModal; diff --git a/packages/frontend/src/images/icon-lock-outline.svg b/packages/frontend/src/images/icon-lock-outline.svg new file mode 100644 index 0000000000..8f4d7c77f2 --- /dev/null +++ b/packages/frontend/src/images/icon-lock-outline.svg @@ -0,0 +1,4 @@ + + + + diff --git a/packages/frontend/src/routes/ChangePassword.js b/packages/frontend/src/routes/ChangePassword.js new file mode 100644 index 0000000000..47f57281a4 --- /dev/null +++ b/packages/frontend/src/routes/ChangePassword.js @@ -0,0 +1,80 @@ +import React from 'react'; +import {Translate} from 'react-localize-redux'; +import styled from 'styled-components'; + +import Button from '../components/common/Button'; +import Container from '../components/common/styled/Container.css'; + + + +const StyledContainer = styled(Container)` + form{ + header{ + .ttl{ + + } + .desc{ + margin-top: 16px; + font-size: 16px; + color: #72727A; + } + } + + .inputWrapper{ + margin-top: 52px; + + input { + + } + } + + .btn{ + margin-top: 24px; + } + + .forgotPassword{ + text-align: center; + margin-top: 20px; + color: #0072CE; + cursor: pointer; + } + } +`; + + +const ChangePassword = () => { + // const initialState ={ + // newPassword: "", + // confirmPassword: "", + // }; + // const [state,setState]=useState(initialState); + // const handleStateUpdate = (data)=>{ + // return setState({...state, ...data}); + // }; + return ( + + +
+

+ +

+

+
+
+ + +
+
+ + + {/*

Incorrect password. 2 attempts remaining.

*/} +
+ + +
+ ); +}; + +export default ChangePassword; diff --git a/packages/frontend/src/routes/SetPassword.js b/packages/frontend/src/routes/SetPassword.js new file mode 100644 index 0000000000..cf35fa1fc4 --- /dev/null +++ b/packages/frontend/src/routes/SetPassword.js @@ -0,0 +1,80 @@ +import React from 'react'; +import {Translate} from 'react-localize-redux'; +import styled from 'styled-components'; + +import Button from '../components/common/Button'; +import Container from '../components/common/styled/Container.css'; + + + +const StyledContainer = styled(Container)` + form{ + header{ + .ttl{ + + } + .desc{ + margin-top: 16px; + font-size: 16px; + color: #72727A; + } + } + + .inputWrapper{ + margin-top: 52px; + + input { + + } + } + + .btn{ + margin-top: 24px; + } + + .forgotPassword{ + text-align: center; + margin-top: 20px; + color: #0072CE; + cursor: pointer; + } + } +`; + + +const SetPassword = () => { + // const initialState ={ + // newPassword: "", + // confirmPassword: "", + // }; + // const [state,setState]=useState(initialState); + // const handleStateUpdate = (data)=>{ + // return setState({...state, ...data}); + // }; + return ( + +
+
+

+ +

+

+
+
+ + +
+
+ + + {/*

Incorrect password. 2 attempts remaining.

*/} +
+ +
+
+ ); +}; + +export default SetPassword; diff --git a/packages/frontend/src/routes/UnlockWallet.js b/packages/frontend/src/routes/UnlockWallet.js new file mode 100644 index 0000000000..91565fa0d7 --- /dev/null +++ b/packages/frontend/src/routes/UnlockWallet.js @@ -0,0 +1,109 @@ +import React, { useState } from 'react'; +import styled from 'styled-components'; + +import Button from '../components/common/Button'; +import Container from '../components/common/styled/Container.css'; +import ResetWalletPasswordModal from '../components/security/ResetWalletPasswordModal'; +import EmailIcon from '../images/icon-lock-outline.svg'; + + + +const StyledContainer = styled(Container)` + form{ + header{ + text-align: center; + .iconWrapper{ + background: #F0F0F1; + border-radius: 50px; + width: 56px; + height: 56px; + margin: auto; + display: flex; + align-items: center; + justify-content: center; + img{ + width: 24px; + height: 24px; + } + } + .ttl{ + + } + .desc{ + margin-top: 16px; + font-size: 16px; + color: #72727A; + } + } + + .inputWrapper{ + margin-top: 52px; + + input { + + } + } + + .btn{ + margin-top: 24px; + } + + .forgotPassword{ + text-align: center; + margin-top: 20px; + color: #0072CE; + cursor: pointer; + } + } +`; + + +const UnlockWallet = () => { + const initialState ={ + showPasswordResetModal: false + }; + const [state,setState]=useState(initialState); + const handleStateUpdate = (data)=>{ + return setState({...state, ...data}); + }; + return ( + +
+
+
+ email icon +
+

Unlock wallet

+

Your wallet was locked due to inactivity. Enter your browser password to unlock it.

+
+
+ + +

Incorrect password. 2 attempts remaining.

+
+ + +
{handleStateUpdate({showPasswordResetModal:true});}} + > + I forgot my password +
+
+ { state.showPasswordResetModal && + {handleStateUpdate({showPasswordResetModal:false});}}/> + } +
+ ); +}; + +export default UnlockWallet; diff --git a/packages/frontend/src/translations/en.global.json b/packages/frontend/src/translations/en.global.json index eabaa525cc..ffaa7681b3 100644 --- a/packages/frontend/src/translations/en.global.json +++ b/packages/frontend/src/translations/en.global.json @@ -240,6 +240,7 @@ "moreInformation": "More information", "needToEditGoBack": "Need to edit? Go Back", "next": "Next", + "okIveSavedItSomewhere": "OK, I saved it somewhere", "protectAccount": "Protect Account", "receive": "Receive", "recoverAccount": "Recover Account", @@ -291,6 +292,13 @@ "supportedExchanges": "Supported Exchanges", "title": "Top Up" }, + "changePassword": { + "confirmPassword": "Confirm Password", + "consentText": "I understand that NEAR Wallet cannot recover this password for me. Learn more", + "desc": "Enter a new password for securing your wallet while using Brave Browser on this device.", + "newPassword": "New Password", + "ttl": "Change Your Browser Password" + }, "confirmLedgerModal": { "header": { "confirm": "Please confirm the operation on your device...", @@ -330,8 +338,8 @@ "minCharacters": "Fewer than 2 characters", "separators": "Characters (_-) can be used as separators" }, - "pageText": "Enter an Account ID to use with your NEAR account. Your Account ID will be used for all NEAR operations, including sending and receiving assets.", - "pageTitle": "Reserve Account ID", + "pageText": "NEAR Wallet is a secure wallet and account manager for your accounts on the NEAR blockchain. Once you create an account, you’ll need it to interact with applications on NEAR, and to securely store your various tokens and collectibles (NFTs).", + "pageTitle": "Create Your Account", "recoverItHere": "Import Existing Account", "setupPassphrase": { "generatePassphrase": { @@ -495,6 +503,11 @@ "withId": "Importing account: ${accountId}", "withIdFailed": "Failed to import account: ${accountId}" }, + "inactivityLockModal": { + "buttonCta": "I’m still here", + "desc": "Your wallet will soon be locked due to inactivity. Would you like to continue your session?", + "ttl": "Are you still there?" + }, "initialDeposit": { "claimAccount": { "desc": "Your deposit was received! Once claimed, your deposit will be transferred to your new account.", @@ -525,6 +538,14 @@ "title": "Word #${wordId}" } }, + "introducingPasswordsModal": { + "desc": "NEAR Wallet now uses browser passwords to provide additional security to your accounts on the web.\n\nContinue to set up a browser password for your wallet.", + "ttl": "Introducing Browser Passwords!" + }, + "keepPasswordsSafeModal": { + "desc": "NEAR Wallet is not able to recover your password for you.\n\nIf you lose it, you’ll have to reset your wallet and recover any accounts you may have previously imported.", + "ttl": "Keep Your Password Safe!" + }, "landing": { "banner": "NEAR Wallet is in Private Beta", "desc": "Securely store and stake your NEAR tokens and compatible assets with NEAR Wallet.", @@ -728,6 +749,10 @@ "authorizedApps": { "title": "Authorized Apps" }, + "browserPassword": { + "desc": "Change the password used to secure your wallet while using Brave Browser on this device.", + "ttl": "Browser Password" + }, "details": { "availableBalance": "Available Balance", "locked": "Locked", @@ -951,6 +976,12 @@ "title": "Release Notes" }, "reservedForFeesInfo": "Up to ${data} NEAR is reserved to cover the cost of transactions.", + "resetWalletModal": { + "buttonCta": "Reset & Recover", + "consentText": "I’ve confirmed that I have access to the recovery information for my accounts.", + "desc": "NEAR Wallet is not able to recover your browser password for you.
If you’ve lost it, you’ll need to reset your wallet and manually recover any accounts you may have previously added. Make sure you have your recovery information for each account before resetting.", + "ttl": "Reset Your Wallet?" + }, "selectAccountDropdown": { "account": "Account", "createAccount": "Create New Account", @@ -1050,6 +1081,14 @@ } } }, + "setPassword": { + "buttonCta": "Set password", + "confirmPassword": "Confirm Password", + "consentText": "I understand that NEAR Wallet cannot recover this password for me. Learn more", + "desc": "Set a password to secure your wallet while using Brave Browser on this device.", + "newPassword": "New Password", + "ttl": "Set a Browser Password" + }, "setRecoveryConfirm": { "didNotReceive": "Didn't receive your code?", "email": "email address", @@ -1117,7 +1156,7 @@ "emailTitle": "Email", "existingPhraseDesc": "Protect your new address by sharing an existing passphrase.", "existingPhraseTitle": "Use an Existing Passphrase", - "header": "Choose a Security Method", + "header": "Choose a Recovery Method", "ledgerDesc": "Secure your account with a Ledger hardware device.", "ledgerTitle": "Ledger Hardware Wallet", "newPhraseDesc": "Protect your new address with a new and unique passphrase.", @@ -1128,11 +1167,11 @@ "phoneTitle": "Phone", "phraseDesc": "Generate and safely store a unique passphrase.", "phraseTitle": "Secure Passphrase", - "subHeader": "Select a method to secure and recover your account. This will be used to verify important activity, recover your account and access your account from other devices." + "subHeader": "Select a method to secure and recover your account, and to access it on other devices." }, "setupSeedPhrase": { - "pageText": "Write down the following words in order and keep them somewhere safe. Anyone with access to it will also have access to your account! You’ll be asked to verify your passphrase next.", - "pageTitle": "Setup Your Secure Passphrase", + "pageText": "This passphrase is the master-key for your account. Store it somewhere safe and do not share it. Anyone with these words will have full access to your account.", + "pageTitle": "Safely Store Your Secure Passphrase", "snackbarCopyImplicitAddress": "Funding Address Copied!", "snackbarCopySuccess": "Passphrase copied!" }, @@ -1143,8 +1182,8 @@ }, "setupSeedPhraseVerify": { "inputError": "Please check your passphrase and try again.", - "pageText": "Enter the following word from your recovery phrase to complete the setup process.", - "pageTitle": "Verify Phrase", + "pageText": "Click or tap each word in the correct order to complete your passphrase.", + "pageTitle": "Verify Passphrase", "startOverText": "Didn't write it down?" }, "sign": { @@ -1415,9 +1454,9 @@ "desc": "Protect your account by requiring confirmation via SMS or email when authorizing transactions.", "disable": { "desc": "Keep in mind that transactions won't have to be confirmed with 2FA once it's disabled.", - "phoneDesc": "The SMS option for two-factor authentication is being deprecated, and cannot be re-enbaled.", "disable": "Disable 2FA", "keep": "No, keep 2FA", + "phoneDesc": "The SMS option for two-factor authentication is being deprecated, and cannot be re-enbaled.", "title": "Are you sure you want to disable 2FA?" }, "email": "Email", diff --git a/yarn.lock b/yarn.lock index 950d936c89..b306ae68fd 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1119,14 +1119,6 @@ resolved "https://registry.yarnpkg.com/@hutson/parse-repository-url/-/parse-repository-url-3.0.2.tgz#98c23c950a3d9b6c8f0daed06da6c3af06981340" integrity sha512-H9XAx3hc0BQHY6l+IFSWHDySypcXsvsuLhgYLUGywmJ5pswRVQJUHpOsobnLYp2ZUaUlKiKDrgWWhosOwAEM8Q== -"@hypnosphi/create-react-context@^0.3.1": - version "0.3.1" - resolved "https://registry.yarnpkg.com/@hypnosphi/create-react-context/-/create-react-context-0.3.1.tgz#f8bfebdc7665f5d426cba3753e0e9c7d3154d7c6" - integrity sha512-V1klUed202XahrWJLLOT3EXNeCpFHCcJntdFGI15ntCwau+jfT386w7OFTMaCqOgXUH1fa0w/I1oZs+i/Rfr0A== - dependencies: - gud "^1.0.0" - warning "^4.0.3" - "@iarna/toml@^2.2.0": version "2.2.5" resolved "https://registry.yarnpkg.com/@iarna/toml/-/toml-2.2.5.tgz#b32366c89b43c6f8cefbdefac778b9c828e3ba8c" @@ -2041,7 +2033,7 @@ integrity sha512-TUu1io4U1CzvV5gGzLMGwQLFuA7Hj/RmRD1y0Ys1MdCcyErBced/cLIymQJtC5zZTYW6JlbJTQ3EmZb+HUaG4g== dependencies: fs-extra "^10.0.0" - ini "^1.3.4" + ini "^2.0.0" inquirer "^8.2.0" "@nodelib/fs.scandir@2.1.5": @@ -2356,7 +2348,6 @@ estree-walker "^1.0.1" picomatch "^2.2.2" - "@sentry/browser@^6.4.1": version "6.16.1" resolved "https://registry.yarnpkg.com/@sentry/browser/-/browser-6.16.1.tgz#4270ab0fbd1de425e339b3e7a364feb09f470a87" @@ -2435,23 +2426,6 @@ dependencies: "@sinonjs/commons" "^1.7.0" -"@stardust-ui/react-component-event-listener@~0.38.0": - version "0.38.0" - resolved "https://registry.yarnpkg.com/@stardust-ui/react-component-event-listener/-/react-component-event-listener-0.38.0.tgz#1787faded94b40ad41226e6289baf13e701c6e7f" - integrity sha512-sIP/e0dyOrrlb8K7KWumfMxj/gAifswTBC4o68Aa+C/GA73ccRp/6W1VlHvF/dlOR4KLsA+5SKnhjH36xzPsWg== - dependencies: - "@babel/runtime" "^7.1.2" - prop-types "^15.7.2" - -"@stardust-ui/react-component-ref@~0.38.0": - version "0.38.0" - resolved "https://registry.yarnpkg.com/@stardust-ui/react-component-ref/-/react-component-ref-0.38.0.tgz#52d555f2d5edd213c923c93a106f7de940e427ef" - integrity sha512-xjs6WnvJVueSIXMWw0C3oWIgAPpcD03qw43oGOjUXqFktvpNkB73JoKIhS4sCrtQxBdct75qqr4ZL6JiyPcESw== - dependencies: - "@babel/runtime" "^7.1.2" - prop-types "^15.7.2" - react-is "^16.6.3" - "@tootallnate/once@1": version "1.1.2" resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-1.1.2.tgz#ccb91445360179a04e7fe6aff78c00ffc1eeaf82" @@ -3873,7 +3847,7 @@ class-utils@^0.3.5: isobject "^3.0.0" static-extend "^0.1.1" -classnames@^2.2.5, classnames@^2.2.6: +classnames@^2.2.5: version "2.3.1" resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.3.1.tgz#dfcfa3891e306ec1dad105d0e88f4417b8535e8e" integrity sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA== @@ -4836,18 +4810,6 @@ dedent@0.7.0, dedent@^0.7.0: resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c" integrity sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw= -deep-equal@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.1.1.tgz#b5c98c942ceffaf7cb051e24e1434a25a2e6076a" - integrity sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g== - dependencies: - is-arguments "^1.0.4" - is-date-object "^1.0.1" - is-regex "^1.0.4" - object-is "^1.0.1" - object-keys "^1.1.1" - regexp.prototype.flags "^1.2.0" - deep-extend@^0.6.0: version "0.6.0" resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" @@ -5722,7 +5684,7 @@ execa@^5.0.0: signal-exit "^3.0.3" strip-final-newline "^2.0.0" -exenv@^1.2.0, exenv@^1.2.2: +exenv@^1.2.0: version "1.2.2" resolved "https://registry.yarnpkg.com/exenv/-/exenv-1.2.2.tgz#2ae78e85d9894158670b03d47bec1f03bd91bb9d" integrity sha1-KueOhdmJQVhnCwPUe+wfA72Ru50= @@ -6070,7 +6032,7 @@ find-root@1.1.0: resolved "https://registry.yarnpkg.com/find-root/-/find-root-1.1.0.tgz#abcfc8ba76f708c42a97b3d685b7e9450bfb9ce4" integrity sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng== -find-up@^2.0.0, find-up@^2.1.0: +find-up@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" integrity sha1-RdG35QbHF93UgndaK3eSCjwMV6c= @@ -7149,14 +7111,6 @@ is-accessor-descriptor@^1.0.0: dependencies: kind-of "^6.0.0" -is-arguments@^1.0.4: - version "1.1.1" - resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.1.1.tgz#15b3f88fda01f2a97fec84ca761a560f123efa9b" - integrity sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA== - dependencies: - call-bind "^1.0.2" - has-tostringtag "^1.0.0" - is-arrayish@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" @@ -7421,7 +7375,7 @@ is-reference@^1.2.1: dependencies: "@types/estree" "*" -is-regex@^1.0.4, is-regex@^1.0.5, is-regex@^1.1.0, is-regex@^1.1.3, is-regex@^1.1.4: +is-regex@^1.0.5, is-regex@^1.1.0, is-regex@^1.1.3, is-regex@^1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958" integrity sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg== @@ -8049,11 +8003,6 @@ jpeg-js@^0.4.2: resolved "https://registry.yarnpkg.com/jpeg-js/-/jpeg-js-0.4.3.tgz#6158e09f1983ad773813704be80680550eff977b" integrity sha512-ru1HWKek8octvUHFHvE5ZzQ1yAsJmIvRdGWvSoKV52XKyuyYA437QWDttXT8eZXDSbuMpHlLzPDZUPd6idIz+Q== -jquery@x.*: - version "3.6.0" - resolved "https://registry.yarnpkg.com/jquery/-/jquery-3.6.0.tgz#c72a09f15c1bdce142f49dbf1170bdf8adac2470" - integrity sha512-JVzAR/AjBvVt2BmYhxRCSYysDsPcssdmTFnzyLEts9qNwmjmu4JTAMYubEfwVOSwpQ1I1sKKFcxhZCI2buerfw== - js-sha256@^0.9.0: version "0.9.0" resolved "https://registry.yarnpkg.com/js-sha256/-/js-sha256-0.9.0.tgz#0b89ac166583e91ef9123644bd3c5334ce9d0966" @@ -8240,11 +8189,6 @@ just-curry-it@^3.1.0: resolved "https://registry.yarnpkg.com/just-curry-it/-/just-curry-it-3.2.1.tgz#7bb18284c8678ed816bfc5c19e44400605fbe461" integrity sha512-Q8206k8pTY7krW32cdmPsP+DqqLgWx/hYPSj9/+7SYqSqz7UuwPbfSe07lQtvuuaVyiSJveXk0E5RydOuWwsEg== -keyboard-key@^1.0.4: - version "1.1.0" - resolved "https://registry.yarnpkg.com/keyboard-key/-/keyboard-key-1.1.0.tgz#6f2e8e37fa11475bb1f1d65d5174f1b35653f5b7" - integrity sha512-qkBzPTi3rlAKvX7k0/ub44sqOfXeLc/jcnGGmj5c7BJpU8eDrEVPyhCvNYAaoubbsLm9uGWwQJO1ytQK1a9/dQ== - keypress@0.1.x: version "0.1.0" resolved "https://registry.yarnpkg.com/keypress/-/keypress-0.1.0.tgz#4a3188d4291b66b4f65edb99f806aa9ae293592a" @@ -9552,7 +9496,7 @@ object-inspect@~1.4.0: resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.4.1.tgz#37ffb10e71adaf3748d05f713b4c9452f402cbc4" integrity sha512-wqdhLpfCUbEsoEwl3FXwGyv8ief1k/1aUdIPCqVnupM6e8l63BEJdiF/0swtn04/8p05tG/T0FrpTlfwvljOdw== -object-is@^1.0.1, object-is@^1.0.2, object-is@^1.1.2: +object-is@^1.0.2, object-is@^1.1.2: version "1.1.5" resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.1.5.tgz#b9deeaa5fc7f1846a0faecdceec138e5778f53ac" integrity sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw== @@ -10291,11 +10235,6 @@ pngjs@^5.0.0: resolved "https://registry.yarnpkg.com/pngjs/-/pngjs-5.0.0.tgz#e79dd2b215767fd9c04561c01236df960bce7fbb" integrity sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw== -popper.js@^1.14.4: - version "1.16.1" - resolved "https://registry.yarnpkg.com/popper.js/-/popper.js-1.16.1.tgz#2a223cb3dc7b6213d740e40372be40de43e65b1b" - integrity sha512-Wb4p1J4zyFTbM+u6WuO4XstYx4Ky9Cewe4DWrel7B0w6VVICvPwdOpotjzcf6eD8TsckVnIMNONQyPIUFOUbCQ== - posix-character-classes@^0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" @@ -11073,7 +11012,12 @@ react-helmet@^6.1.0: react-fast-compare "^3.1.1" react-side-effect "^2.1.0" -react-is@^16.13.1, react-is@^16.6.0, react-is@^16.6.3, react-is@^16.7.0, react-is@^16.8.1, react-is@^16.8.6: +react-idle-timer@^4.6.4: + version "4.6.4" + resolved "https://registry.yarnpkg.com/react-idle-timer/-/react-idle-timer-4.6.4.tgz#71ba954ba6f464df24d46a94e63c5ef19f7319dc" + integrity sha512-iq61dPud8fgj7l1KOJEY5pyiD532fW0KcIe/5XUe/0lB/4Vytoy4tZBlLGSiYodPzKxTL6HyKoOmG6tyzjD7OQ== + +react-is@^16.13.1, react-is@^16.6.0, react-is@^16.7.0, react-is@^16.8.1, react-is@^16.8.6: version "16.13.1" resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== @@ -11121,19 +11065,6 @@ react-phone-number-input@2.3.11: react-lifecycles-compat "^3.0.4" react-responsive-ui "^0.14.123" -react-popper@^1.3.4: - version "1.3.11" - resolved "https://registry.yarnpkg.com/react-popper/-/react-popper-1.3.11.tgz#a2cc3f0a67b75b66cfa62d2c409f9dd1fcc71ffd" - integrity sha512-VSA/bS+pSndSF2fiasHK/PTEEAyOpX60+H5EPAjoArr8JGm+oihu4UbrqcEBpQibJxBVCpYyjAX7abJ+7DoYVg== - dependencies: - "@babel/runtime" "^7.1.2" - "@hypnosphi/create-react-context" "^0.3.1" - deep-equal "^1.1.1" - popper.js "^1.14.4" - prop-types "^15.6.1" - typed-styles "^0.0.7" - warning "^4.0.2" - react-redux@^7.2.4: version "7.2.6" resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-7.2.6.tgz#49633a24fe552b5f9caf58feb8a138936ddfe9aa" @@ -11270,9 +11201,6 @@ read-pkg-up@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-3.0.0.tgz#3ed496685dba0f8fe118d0691dc51f4a1ff96f07" integrity sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc= - dependencies: - find-up "^2.0.0" - read-pkg "^3.0.0" read-pkg-up@^7.0.1: version "7.0.1" @@ -11433,7 +11361,7 @@ regex-not@^1.0.0, regex-not@^1.0.2: extend-shallow "^3.0.2" safe-regex "^1.1.0" -regexp.prototype.flags@^1.2.0, regexp.prototype.flags@^1.3.1: +regexp.prototype.flags@^1.3.1: version "1.3.1" resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.3.1.tgz#7ef352ae8d159e758c0eadca6f8fcb4eef07be26" integrity sha512-JiBdRBq91WlY7uRJ0ds7R+dU02i6LKi8r3BuQhNXn+kmeLN+EfHhfjqMRis1zJxnlu88hq/4dx0P2OP3APRTOA== @@ -11820,7 +11748,6 @@ seamless-immutable@^7.1.3: resolved "https://registry.yarnpkg.com/seamless-immutable/-/seamless-immutable-7.1.4.tgz#6e9536def083ddc4dea0207d722e0e80d0f372f8" integrity sha512-XiUO1QP4ki4E2PHegiGAlu6r82o5A+6tRh7IkGGTVg/h+UoeX4nFBeCGPOhb4CYjvkqsfm/TUtvOMYC1xmV30A== - "semver@2 || 3 || 4 || 5", semver@^5.4.1, semver@^5.5.0, semver@^5.5.1, semver@^5.6.0, semver@^5.7.0, semver@^5.7.1: version "5.7.1" resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" @@ -13014,11 +12941,6 @@ type-is@~1.6.18: media-typer "0.3.0" mime-types "~2.1.24" -typed-styles@^0.0.7: - version "0.0.7" - resolved "https://registry.yarnpkg.com/typed-styles/-/typed-styles-0.0.7.tgz#93392a008794c4595119ff62dde6809dbc40a3d9" - integrity sha512-pzP0PWoZUhsECYjABgCGQlRGL1n7tOHsgwYv3oIiEpJwGhFTuty/YNeduxQYzXXa3Ge5BdT6sHYIQYpl4uJ+5Q== - typedarray-to-buffer@^3.1.5: version "3.1.5" resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080" @@ -13368,7 +13290,7 @@ walker@^1.0.7: dependencies: makeerror "1.0.12" -warning@^4.0.2, warning@^4.0.3: +warning@^4.0.3: version "4.0.3" resolved "https://registry.yarnpkg.com/warning/-/warning-4.0.3.tgz#16e9e077eb8a86d6af7d64aa1e05fd85b4678ca3" integrity sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w== @@ -13706,4 +13628,4 @@ yazl@^2.5.1: yn@3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50" - integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q== \ No newline at end of file + integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==