mirror of
https://github.com/Qortal/Qortal-Hub.git
synced 2025-04-27 13:27:52 +00:00
added the option to change the wallet's password
This commit is contained in:
parent
9a227e4e53
commit
4e8eb3b2c3
@ -31,7 +31,13 @@
|
||||
"return_to_list": "zurück zur Liste",
|
||||
"wallet": {
|
||||
"password_confirmation": "Wallet-Passwort bestätigen",
|
||||
"password": "Wallet-Passwort"
|
||||
"password": "Wallet-Passwort",
|
||||
"keep_password": "aktuelles Passwort beibehalten",
|
||||
"new_password": "neues Passwort",
|
||||
"error": {
|
||||
"missing_new_password": "bitte neues Passwort eingeben",
|
||||
"missing_password": "bitte Passwort eingeben"
|
||||
}
|
||||
},
|
||||
"welcome": "willkommen bei"
|
||||
}
|
||||
|
@ -31,7 +31,13 @@
|
||||
"return_to_list": "return to list",
|
||||
"wallet": {
|
||||
"password_confirmation": "confirm wallet password",
|
||||
"password": "wallet password"
|
||||
"password": "wallet password",
|
||||
"keep_password": "keep current password",
|
||||
"new_password": "new password",
|
||||
"error": {
|
||||
"missing_new_password": "please enter a new password",
|
||||
"missing_password": "please enter your password"
|
||||
}
|
||||
},
|
||||
"welcome": "welcome to"
|
||||
}
|
||||
|
@ -31,7 +31,13 @@
|
||||
"return_to_list": "volver a la lista",
|
||||
"wallet": {
|
||||
"password_confirmation": "confirmar contraseña del monedero",
|
||||
"password": "contraseña del monedero"
|
||||
"password": "contraseña del monedero",
|
||||
"keep_password": "mantener la contraseña actual",
|
||||
"new_password": "nueva contraseña",
|
||||
"error": {
|
||||
"missing_new_password": "por favor ingresa una nueva contraseña",
|
||||
"missing_password": "por favor ingresa tu contraseña"
|
||||
}
|
||||
},
|
||||
"welcome": "bienvenido a"
|
||||
}
|
||||
|
@ -31,7 +31,13 @@
|
||||
"return_to_list": "retour à la liste",
|
||||
"wallet": {
|
||||
"password_confirmation": "confirmer le mot de passe du portefeuille",
|
||||
"password": "mot de passe du portefeuille"
|
||||
"password": "mot de passe du portefeuille",
|
||||
"keep_password": "garder le mot de passe actuel",
|
||||
"new_password": "nouveau mot de passe",
|
||||
"error": {
|
||||
"missing_new_password": "veuillez entrer un nouveau mot de passe",
|
||||
"missing_password": "veuillez entrer votre mot de passe"
|
||||
}
|
||||
},
|
||||
"welcome": "bienvenue sur"
|
||||
}
|
||||
|
@ -30,7 +30,13 @@
|
||||
"password": "password",
|
||||
"wallet": {
|
||||
"password_confirmation": "conferma la password del wallet",
|
||||
"password": "password del wallet"
|
||||
"password": "password del wallet",
|
||||
"keep_password": "mantieni la password attuale",
|
||||
"new_password": "nuova password",
|
||||
"error": {
|
||||
"missing_new_password": "per favore inserisci una nuova password",
|
||||
"missing_password": "per favore inserisci la tua password"
|
||||
}
|
||||
},
|
||||
"return_to_list": "ritorna alla lista",
|
||||
"welcome": "benvenuto in"
|
||||
|
@ -31,7 +31,13 @@
|
||||
"return_to_list": "вернуться к списку",
|
||||
"wallet": {
|
||||
"password_confirmation": "подтвердите пароль кошелька",
|
||||
"password": "пароль кошелька"
|
||||
"password": "пароль кошелька",
|
||||
"keep_password": "сохранить текущий пароль",
|
||||
"new_password": "новый пароль",
|
||||
"error": {
|
||||
"missing_new_password": "пожалуйста, введите новый пароль",
|
||||
"missing_password": "пожалуйста, введите ваш пароль"
|
||||
}
|
||||
},
|
||||
"welcome": "добро пожаловать в"
|
||||
}
|
||||
|
136
src/App.tsx
136
src/App.tsx
@ -137,6 +137,7 @@ import { GeneralNotifications } from './components/GeneralNotifications';
|
||||
import { PdfViewer } from './common/PdfViewer';
|
||||
import ThemeSelector from './components/Theme/ThemeSelector.tsx';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { DownloadWallet } from './components/Auth/DownloadWallet.tsx';
|
||||
|
||||
type extStates =
|
||||
| 'not-authenticated'
|
||||
@ -919,27 +920,6 @@ function App() {
|
||||
}
|
||||
}, [authenticatedMode]);
|
||||
|
||||
const confirmPasswordToDownload = async () => {
|
||||
try {
|
||||
setWalletToBeDownloadedError('');
|
||||
if (!walletToBeDownloadedPassword) {
|
||||
setSendPaymentError('Please enter your password');
|
||||
return;
|
||||
}
|
||||
setIsLoading(true);
|
||||
await new Promise<void>((res) => {
|
||||
setTimeout(() => {
|
||||
res();
|
||||
}, 250);
|
||||
});
|
||||
const res = await saveWalletFunc(walletToBeDownloadedPassword);
|
||||
} catch (error: any) {
|
||||
setWalletToBeDownloadedError(error?.message);
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
const saveFileToDiskFunc = async () => {
|
||||
try {
|
||||
await saveFileToDisk(
|
||||
@ -1676,7 +1656,7 @@ function App() {
|
||||
textTransform: 'uppercase',
|
||||
}}
|
||||
>
|
||||
{t('core:wallet_other')}
|
||||
{t('core:wallet.wallet_other')}
|
||||
</span>
|
||||
}
|
||||
placement="left"
|
||||
@ -2692,110 +2672,14 @@ function App() {
|
||||
</>
|
||||
)}
|
||||
{extState === 'download-wallet' && (
|
||||
<>
|
||||
<Spacer height="22px" />
|
||||
<Box
|
||||
sx={{
|
||||
boxSizing: 'border-box',
|
||||
display: 'flex',
|
||||
justifyContent: 'flex-start',
|
||||
maxWidth: '700px',
|
||||
paddingLeft: '22px',
|
||||
width: '100%',
|
||||
}}
|
||||
>
|
||||
<Return
|
||||
style={{
|
||||
cursor: 'pointer',
|
||||
height: '24px',
|
||||
}}
|
||||
onClick={returnToMain}
|
||||
/>
|
||||
</Box>
|
||||
|
||||
<Spacer height="10px" />
|
||||
|
||||
<div
|
||||
className="image-container"
|
||||
style={{
|
||||
width: '136px',
|
||||
height: '154px',
|
||||
}}
|
||||
>
|
||||
<img src={Logo1Dark} className="base-image" />
|
||||
</div>
|
||||
|
||||
<Spacer height="35px" />
|
||||
|
||||
<Box
|
||||
sx={{
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
alignItems: 'flex-start',
|
||||
}}
|
||||
>
|
||||
<TextP
|
||||
sx={{
|
||||
textAlign: 'start',
|
||||
lineHeight: '24px',
|
||||
fontSize: '20px',
|
||||
fontWeight: 600,
|
||||
}}
|
||||
>
|
||||
{t('auth:download_account', { postProcess: 'capitalize' })}
|
||||
</TextP>
|
||||
</Box>
|
||||
|
||||
<Spacer height="35px" />
|
||||
|
||||
{!walletToBeDownloaded && (
|
||||
<>
|
||||
<CustomLabel htmlFor="standard-adornment-password">
|
||||
{t('auth:wallet.password_confirmation', {
|
||||
postProcess: 'capitalize',
|
||||
})}
|
||||
</CustomLabel>
|
||||
|
||||
<Spacer height="5px" />
|
||||
|
||||
<PasswordField
|
||||
id="standard-adornment-password"
|
||||
value={walletToBeDownloadedPassword}
|
||||
onChange={(e) =>
|
||||
setWalletToBeDownloadedPassword(e.target.value)
|
||||
}
|
||||
/>
|
||||
|
||||
<Spacer height="20px" />
|
||||
|
||||
<CustomButton onClick={confirmPasswordToDownload}>
|
||||
{t('auth:password_confirmation', {
|
||||
postProcess: 'capitalize',
|
||||
})}
|
||||
</CustomButton>
|
||||
<ErrorText>{walletToBeDownloadedError}</ErrorText>
|
||||
</>
|
||||
)}
|
||||
|
||||
{walletToBeDownloaded && (
|
||||
<>
|
||||
<CustomButton
|
||||
onClick={async () => {
|
||||
await saveFileToDiskFunc();
|
||||
await showInfo({
|
||||
message: t('auth:keep_secure', {
|
||||
postProcess: 'capitalize',
|
||||
}),
|
||||
});
|
||||
}}
|
||||
>
|
||||
{t('auth:download_account', {
|
||||
postProcess: 'capitalize',
|
||||
})}
|
||||
</CustomButton>
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
<DownloadWallet
|
||||
returnToMain={returnToMain}
|
||||
setIsLoading={setIsLoading}
|
||||
showInfo={showInfo}
|
||||
rawWallet={rawWallet}
|
||||
setWalletToBeDownloaded={setWalletToBeDownloaded}
|
||||
walletToBeDownloaded={walletToBeDownloaded}
|
||||
/>
|
||||
)}
|
||||
{extState === 'create-wallet' && (
|
||||
<>
|
||||
|
@ -703,7 +703,7 @@ export const NotAuthenticated = ({
|
||||
visibility: importedApiKey ? 'visible' : 'hidden',
|
||||
}}
|
||||
>
|
||||
{t('auth:apikey.key', { postProcess: 'capitalize' })}: $
|
||||
{t('auth:apikey.key', { postProcess: 'capitalize' })}:{' '}
|
||||
{importedApiKey}
|
||||
</Typography>
|
||||
</>
|
||||
|
248
src/components/Auth/DownloadWallet.tsx
Normal file
248
src/components/Auth/DownloadWallet.tsx
Normal file
@ -0,0 +1,248 @@
|
||||
import { Box, Checkbox, FormControlLabel, Typography } from '@mui/material';
|
||||
import { Spacer } from '../../common/Spacer';
|
||||
import { Return } from '../../assets/Icons/Return';
|
||||
import { CustomButton, CustomLabel, TextP } from '../../styles/App-styles';
|
||||
import { PasswordField } from '../PasswordField/PasswordField';
|
||||
import { ErrorText } from '../ErrorText/ErrorText';
|
||||
import Logo1Dark from '../../assets/svgs/Logo1Dark.svg';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { saveFileToDisk } from '../../utils/generateWallet/generateWallet';
|
||||
import { useState } from 'react';
|
||||
import { decryptStoredWallet } from '../../utils/decryptWallet';
|
||||
import PhraseWallet from '../../utils/generateWallet/phrase-wallet';
|
||||
import { crypto, walletVersion } from '../../constants/decryptWallet';
|
||||
|
||||
export const DownloadWallet = ({
|
||||
returnToMain,
|
||||
setIsLoading,
|
||||
showInfo,
|
||||
rawWallet,
|
||||
setWalletToBeDownloaded,
|
||||
walletToBeDownloaded,
|
||||
}) => {
|
||||
const [walletToBeDownloadedPassword, setWalletToBeDownloadedPassword] =
|
||||
useState<string>('');
|
||||
const [newPassword, setNewPassword] = useState<string>('');
|
||||
const [keepCurrentPassword, setKeepCurrentPassword] = useState<boolean>(true);
|
||||
|
||||
const [walletToBeDownloadedError, setWalletToBeDownloadedError] =
|
||||
useState<string>('');
|
||||
|
||||
const { t } = useTranslation(['auth']);
|
||||
|
||||
const saveFileToDiskFunc = async () => {
|
||||
try {
|
||||
await saveFileToDisk(
|
||||
walletToBeDownloaded.wallet,
|
||||
walletToBeDownloaded.qortAddress
|
||||
);
|
||||
} catch (error: any) {
|
||||
setWalletToBeDownloadedError(error?.message);
|
||||
}
|
||||
};
|
||||
|
||||
const saveWalletFunc = async (password: string, newPassword) => {
|
||||
let wallet = structuredClone(rawWallet);
|
||||
|
||||
const res = await decryptStoredWallet(password, wallet);
|
||||
const wallet2 = new PhraseWallet(res, wallet?.version || walletVersion);
|
||||
const passwordToUse = newPassword || password;
|
||||
wallet = await wallet2.generateSaveWalletData(
|
||||
passwordToUse,
|
||||
crypto.kdfThreads,
|
||||
() => {}
|
||||
);
|
||||
|
||||
setWalletToBeDownloaded({
|
||||
wallet,
|
||||
qortAddress: rawWallet.address0,
|
||||
});
|
||||
return {
|
||||
wallet,
|
||||
qortAddress: rawWallet.address0,
|
||||
};
|
||||
};
|
||||
|
||||
const confirmPasswordToDownload = async () => {
|
||||
try {
|
||||
setWalletToBeDownloadedError('');
|
||||
if (!keepCurrentPassword && !newPassword) {
|
||||
setWalletToBeDownloadedError(
|
||||
t('auth:wallet.error.missing_new_password', {
|
||||
postProcess: 'capitalize',
|
||||
})
|
||||
);
|
||||
return;
|
||||
}
|
||||
if (!walletToBeDownloadedPassword) {
|
||||
setWalletToBeDownloadedError(
|
||||
t('auth:wallet.error.missing_password', { postProcess: 'capitalize' })
|
||||
);
|
||||
return;
|
||||
}
|
||||
setIsLoading(true);
|
||||
await new Promise<void>((res) => {
|
||||
setTimeout(() => {
|
||||
res();
|
||||
}, 250);
|
||||
});
|
||||
const newPasswordForWallet = !keepCurrentPassword ? newPassword : null;
|
||||
const res = await saveWalletFunc(
|
||||
walletToBeDownloadedPassword,
|
||||
newPasswordForWallet
|
||||
);
|
||||
} catch (error: any) {
|
||||
setWalletToBeDownloadedError(error?.message);
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<Spacer height="22px" />
|
||||
<Box
|
||||
sx={{
|
||||
boxSizing: 'border-box',
|
||||
display: 'flex',
|
||||
justifyContent: 'flex-start',
|
||||
maxWidth: '700px',
|
||||
paddingLeft: '22px',
|
||||
width: '100%',
|
||||
}}
|
||||
>
|
||||
<Return
|
||||
style={{
|
||||
cursor: 'pointer',
|
||||
height: '24px',
|
||||
}}
|
||||
onClick={returnToMain}
|
||||
/>
|
||||
</Box>
|
||||
|
||||
<Spacer height="10px" />
|
||||
|
||||
<div
|
||||
className="image-container"
|
||||
style={{
|
||||
width: '136px',
|
||||
height: '154px',
|
||||
}}
|
||||
>
|
||||
<img src={Logo1Dark} className="base-image" />
|
||||
</div>
|
||||
|
||||
<Spacer height="35px" />
|
||||
|
||||
<Box
|
||||
sx={{
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
alignItems: 'flex-start',
|
||||
}}
|
||||
>
|
||||
<TextP
|
||||
sx={{
|
||||
textAlign: 'start',
|
||||
lineHeight: '24px',
|
||||
fontSize: '20px',
|
||||
fontWeight: 600,
|
||||
}}
|
||||
>
|
||||
{t('auth:download_account', { postProcess: 'capitalize' })}
|
||||
</TextP>
|
||||
</Box>
|
||||
|
||||
<Spacer height="35px" />
|
||||
|
||||
{!walletToBeDownloaded && (
|
||||
<>
|
||||
<CustomLabel htmlFor="standard-adornment-password">
|
||||
{t('auth:wallet.password_confirmation', {
|
||||
postProcess: 'capitalize',
|
||||
})}
|
||||
</CustomLabel>
|
||||
|
||||
<Spacer height="5px" />
|
||||
|
||||
<PasswordField
|
||||
id="standard-adornment-password"
|
||||
value={walletToBeDownloadedPassword}
|
||||
onChange={(e) => setWalletToBeDownloadedPassword(e.target.value)}
|
||||
/>
|
||||
|
||||
<Spacer height="20px" />
|
||||
|
||||
<FormControlLabel
|
||||
sx={{
|
||||
margin: 0,
|
||||
}}
|
||||
control={
|
||||
<Checkbox
|
||||
onChange={(e) => setKeepCurrentPassword(e.target.checked)}
|
||||
checked={keepCurrentPassword}
|
||||
edge="start"
|
||||
tabIndex={-1}
|
||||
disableRipple
|
||||
/>
|
||||
}
|
||||
label={
|
||||
<Box sx={{ display: 'flex', alignItems: 'center' }}>
|
||||
<Typography sx={{ fontSize: '14px' }}>
|
||||
{t('auth:wallet.keep_password', {
|
||||
postProcess: 'capitalize',
|
||||
})}
|
||||
</Typography>
|
||||
</Box>
|
||||
}
|
||||
/>
|
||||
<Spacer height="20px" />
|
||||
{!keepCurrentPassword && (
|
||||
<>
|
||||
<CustomLabel htmlFor="standard-adornment-password">
|
||||
{t('auth:wallet.new_password', {
|
||||
postProcess: 'capitalize',
|
||||
})}
|
||||
</CustomLabel>
|
||||
|
||||
<Spacer height="5px" />
|
||||
<PasswordField
|
||||
id="standard-adornment-password"
|
||||
value={newPassword}
|
||||
onChange={(e) => setNewPassword(e.target.value)}
|
||||
/>
|
||||
<Spacer height="20px" />
|
||||
</>
|
||||
)}
|
||||
|
||||
<CustomButton onClick={confirmPasswordToDownload}>
|
||||
{t('auth:password_confirmation', {
|
||||
postProcess: 'capitalize',
|
||||
})}
|
||||
</CustomButton>
|
||||
|
||||
<ErrorText>{walletToBeDownloadedError}</ErrorText>
|
||||
</>
|
||||
)}
|
||||
|
||||
{walletToBeDownloaded && (
|
||||
<>
|
||||
<CustomButton
|
||||
onClick={async () => {
|
||||
await saveFileToDiskFunc();
|
||||
await showInfo({
|
||||
message: t('auth:keep_secure', {
|
||||
postProcess: 'capitalize',
|
||||
}),
|
||||
});
|
||||
}}
|
||||
>
|
||||
{t('auth:download_account', {
|
||||
postProcess: 'capitalize',
|
||||
})}
|
||||
</CustomButton>
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
@ -124,7 +124,7 @@ export const Explore = ({ setDesktopViewMode }) => {
|
||||
fontSize: '1rem',
|
||||
}}
|
||||
>
|
||||
{t('core:wallet_other', { postProcess: 'capitalize' })}
|
||||
{t('core:wallet.wallet_other', { postProcess: 'capitalize' })}
|
||||
</Typography>
|
||||
</ButtonBase>
|
||||
</Box>
|
||||
|
Loading…
x
Reference in New Issue
Block a user