Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import { Trans } from '@lingui/react/macro'
import { encryptBackup } from '@masknet/backup-format'
import { Icons } from '@masknet/icons'
import { InjectedDialog, LoadingStatus } from '@masknet/shared'
import type { BackupAccountType } from '@masknet/shared-base'
import { DashboardRoutes } from '@masknet/shared-base'
import { ActionButton, makeStyles, useCustomSnackbar } from '@masknet/theme'
import { encode } from '@msgpack/msgpack'
Expand All @@ -14,7 +13,6 @@ import { memo, useCallback, useMemo, useRef } from 'react'
import { Controller } from 'react-hook-form'
import { useNavigate } from 'react-router-dom'
import { useAsyncFn, useUpdateEffect } from 'react-use'
import { UserContext } from '../../../shared-ui/index.js'
import { PersonasBackupPreview, WalletsBackupPreview } from '../../components/BackupPreview/index.js'
import PasswordField from '../../components/PasswordField/index.js'
import { useBackupFormState, type BackupFormInputs } from '../../hooks/useBackupFormState.js'
Expand Down Expand Up @@ -59,10 +57,12 @@ const useStyles = makeStyles()((theme) => ({
export interface BackupPreviewDialogProps {
open: boolean
isUpload?: boolean
code: string
type: BackupAccountType
account: string
abstract?: string
/**
* MaskNetwork backup use account + password as password since legacy version.
* Will be removed in the future when we remove MaskNetwork backup.
*/
encryptWithAccount: boolean
title?: React.ReactNode | string
uploadButtonLabel?: React.ReactNode | string
onClose: () => void
Expand All @@ -71,10 +71,8 @@ export interface BackupPreviewDialogProps {
export const BackupPreviewDialog = memo<BackupPreviewDialogProps>(function BackupPreviewDialog({
open,
isUpload,
code,
type,
account,
abstract,
encryptWithAccount,
title,
uploadButtonLabel,
onClose,
Expand All @@ -84,7 +82,6 @@ export const BackupPreviewDialog = memo<BackupPreviewDialogProps>(function Backu
const controllerRef = useRef<AbortController | null>(null)
const { classes, theme } = useStyles()
const navigate = useNavigate()
const { updateUser } = UserContext.useContainer()
const {
hasPassword,
backupWallets,
Expand Down Expand Up @@ -117,7 +114,8 @@ export const BackupPreviewDialog = memo<BackupPreviewDialogProps>(function Backu
excludeWallet: !backupWallets,
})

const encrypted = await encryptBackup(encode(account + data.backupPassword), encode(file))
const password = encryptWithAccount ? account + data.backupPassword : data.backupPassword
const encrypted = await encryptBackup(encode(password), encode(file))
const controller = new AbortController()
controllerRef.current = controller
await onUpload?.(encrypted, controller.signal)
Expand All @@ -132,7 +130,18 @@ export const BackupPreviewDialog = memo<BackupPreviewDialogProps>(function Backu
if ((error as any).status === 400) navigate(DashboardRoutes.BackupCloud, { replace: true })
}
},
[code, hasPassword, backupWallets, abstract, code, account, type, _, navigate, updateUser],
[
backupWallets,
hasPassword,
encryptWithAccount,
account,
onUpload,
showSnackbar,
onClose,
setError,
_,
navigate,
],
)

const handleClose = useCallback(() => {
Expand Down Expand Up @@ -207,19 +216,21 @@ export const BackupPreviewDialog = memo<BackupPreviewDialogProps>(function Backu
</Box>
: <LoadingStatus minHeight={320} />
}, [
uploadLoading,
classes.container,
classes.icon,
loading,
previewInfo,
control,
_,
errors.backupPassword?.message,
errors.paymentPassword?.message,
backupWallets,
setBackupWallets,
hasPassword,
isUpload,
theme,
value,
uploadLoading,
classes,
theme.palette.maskColor.danger,
_,
errors.backupPassword?.message,
errors.paymentPassword?.message,
clearErrors,
])

const action = useMemo(() => {
Expand All @@ -246,18 +257,16 @@ export const BackupPreviewDialog = memo<BackupPreviewDialogProps>(function Backu
</ActionButton>
)
}, [
backupWallets,
isUpload,
isDirty,
isValid,
hasPassword,
backupWallets,
value,
onClose,
uploadLoading,
handleClose,
handleSubmit,
handleUploadBackup,
onClose,
isUpload,
isDirty,
isValid,
uploadButtonLabel,
])

return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,11 @@ export interface RestoreBackupDialogProps {
strategy?: 'import' | 'merge'
restoreSuccessMessage?: ReactNode
restoreErrorMessage?: ReactNode
/**
* MaskNetwork backup use account + password as password since legacy version.
* Will be removed in the future when we remove MaskNetwork backup.
*/
decryptWithAccount: boolean
/**
* A generator that yield progress of download,
* and return the content of the downloaded file at the end
Expand All @@ -61,6 +66,7 @@ export const RestoreBackupDialog = memo<RestoreBackupDialogProps>(function Resto
open,
fileName,
account,
decryptWithAccount,
uploadedAt,
size,
strategy = 'import',
Expand Down Expand Up @@ -96,13 +102,14 @@ export const RestoreBackupDialog = memo<RestoreBackupDialogProps>(function Resto
handleClose()
throw err
}
}, [handleClose, open, download])
}, [open, download, showSnackbar, handleClose])

const isImport = strategy === 'import'
const [{ loading }, handleRestore] = useAsyncFn(async () => {
try {
if (!encrypted) return
const decrypted = await decryptBackup(encode(account + backupPassword), encrypted)
const password = decryptWithAccount ? account + backupPassword : backupPassword
const decrypted = await decryptBackup(encode(password), encrypted)
const backupJson = JSON.stringify(decode(decrypted))
const summary = await Services.Backup.generateBackupSummary(backupJson)
if (summary.isErr()) {
Expand Down Expand Up @@ -141,13 +148,14 @@ export const RestoreBackupDialog = memo<RestoreBackupDialogProps>(function Resto
}
}, [
encrypted,
backupPassword,
decryptWithAccount,
account,
isImport,
backupPassword,
showSnackbar,
isImport,
restoreSuccessMessage,
restoreErrorMessage,
onClose,
restoreErrorMessage,
])

return (
Expand Down Expand Up @@ -190,7 +198,7 @@ export const RestoreBackupDialog = memo<RestoreBackupDialogProps>(function Resto
fontSize={12}
lineHeight="16px"
color={theme.palette.maskColor.third}>
{formatDateTime(new Date(Number(uploadedAt)), 'yyyy-mm-dd HH:mm')}
{formatDateTime(new Date(Number(uploadedAt)), 'yyyy-MM-dd HH:mm')}
</Typography>
</>
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Trans } from '@lingui/react/macro'
import { Icons } from '@masknet/icons'
import { BackupAccountType, EMPTY_LIST } from '@masknet/shared-base'
import { EMPTY_LIST } from '@masknet/shared-base'
import { ActionButton, makeStyles } from '@masknet/theme'
import { GoogleDriveClient, type DriveFile } from '@masknet/web3-providers'
import { Box, Typography } from '@mui/material'
Expand Down Expand Up @@ -89,7 +89,7 @@ export const Component = memo(function GoogleDriveBackup() {
})
refetch()
},
[googleDriveClient],
[googleDriveClient, refetch],
)

const [{ loading: logoutLoading }, logout] = useAsyncFn(async () => {
Expand All @@ -98,7 +98,7 @@ export const Component = memo(function GoogleDriveBackup() {
googleAccount: '',
googleToken: '',
})
}, [googleDriveClient])
}, [googleDriveClient, updateUser])

const mergedFiles = useMemo(() => uniqBy(compact([...files, uploadedFile]), (x) => x.id), [files, uploadedFile])

Expand All @@ -108,6 +108,7 @@ export const Component = memo(function GoogleDriveBackup() {

const downloadAndMerge = async (file: DriveFile) => {
await RestoreBackupModal.openAndWaitForClose({
decryptWithAccount: false,
strategy: 'merge',
download: () => {
return progressDownload(() => googleDriveClient.requestFile(file.id), file.size ? +file.size : 0)
Expand Down Expand Up @@ -162,8 +163,7 @@ export const Component = memo(function GoogleDriveBackup() {
onClick={() => {
if (!user.googleAccount) return
BackupPreviewModal.open({
code: 'google-drive',
type: BackupAccountType.Email,
encryptWithAccount: false,
account: user.googleAccount!,
isUpload: true,
title: <Trans>Backup to Google Drive</Trans>,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { Trans } from '@lingui/react/macro'
import { Icons } from '@masknet/icons'
import { EmptyStatus, formatFileSize } from '@masknet/shared'
import type { BackupAccountType } from '@masknet/shared-base'
import { DashboardRoutes } from '@masknet/shared-base'
import { ActionButton, TextOverflowTooltip, makeStyles } from '@masknet/theme'
import { Box, Button, Typography } from '@mui/material'
Expand Down Expand Up @@ -84,6 +83,7 @@ export const Component = memo(function CloudBackupPreview() {
const [{ loading: mergeLoading }, handleMergeClick] = useAsyncFn(async () => {
if (!previewInfo.downloadLink || !previewInfo.account || !previewInfo.size || !previewInfo.uploadedAt) return
await RestoreBackupModal.openAndWaitForClose({
decryptWithAccount: true,
strategy: 'merge',
download: () => progressDownload(previewInfo.downloadLink),
fileName: getFileName(previewInfo.downloadLink) || createBackupName(),
Expand All @@ -96,10 +96,8 @@ export const Component = memo(function CloudBackupPreview() {
const handleBackupClick = useCallback(() => {
if (!previewInfo.type || !previewInfo.account || !previewInfo.code) return
BackupPreviewModal.open({
encryptWithAccount: true,
isUpload: false,
code: previewInfo.code,
abstract: previewInfo.abstract ? previewInfo.abstract : undefined,
type: previewInfo.type as BackupAccountType,
account: previewInfo.account,
})
}, [previewInfo])
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { Trans } from '@lingui/react/macro'
import { Icons } from '@masknet/icons'
import { EmptyStatus, formatFileSize } from '@masknet/shared'
import type { BackupAccountType } from '@masknet/shared-base'
import { DashboardRoutes } from '@masknet/shared-base'
import { ActionButton, TextOverflowTooltip, makeStyles } from '@masknet/theme'
import { Box, Typography } from '@mui/material'
Expand Down Expand Up @@ -79,6 +78,7 @@ export const Component = memo(function CloudBackupPreview() {
)
return
await RestoreBackupModal.openAndWaitForClose({
decryptWithAccount: true,
strategy: 'merge',
download: () => progressDownload(previewInfo.downloadLink),
fileName: getFileName(previewInfo.downloadLink) || createBackupName(),
Expand All @@ -91,10 +91,8 @@ export const Component = memo(function CloudBackupPreview() {
const handleBackupClick = useCallback(() => {
if (!previewInfo.type || !previewInfo.account || !previewInfo.code) return
BackupPreviewModal.open({
encryptWithAccount: true,
isUpload: false,
code: previewInfo.code,
abstract: previewInfo.abstract ? previewInfo.abstract : undefined,
type: previewInfo.type as BackupAccountType,
account: previewInfo.account,
})
}, [previewInfo])
Expand All @@ -113,10 +111,8 @@ export const Component = memo(function CloudBackupPreview() {
if (!previewInfo.type || !previewInfo.account || !previewInfo.code) return

BackupPreviewModal.open({
encryptWithAccount: true,
isUpload: true,
code: previewInfo.code,
abstract: previewInfo.abstract ? previewInfo.abstract : undefined,
type: previewInfo.type as BackupAccountType,
account: previewInfo.account,
})
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ export const Component = memo(function GoogleDriveRecovery() {

const downloadAndMerge = async (file: DriveFile) => {
await RestoreBackupModal.openAndWaitForClose({
decryptWithAccount: false,
strategy: 'merge',
download: () => {
return progressDownload(() => googleDriveClient.requestFile(file.id), file.size ? +file.size : 0)
Expand Down Expand Up @@ -125,14 +126,12 @@ export const Component = memo(function GoogleDriveRecovery() {
selectable
selectedFileId={selectedFile?.id}
onSelect={setSelectedFile}
onDownload={downloadAndMerge}
onMerge={async (file) => {
onMerge={downloadAndMerge}
onDownload={async (file) => {
const blob = await googleDriveClient.downloadFile(file.id)
const url = URL.createObjectURL(blob)
downloadBackup(url, file.name)
Promise.resolve().then(() => {
URL.revokeObjectURL(url)
})
URL.revokeObjectURL(url)
}}
/>
</Box>
Expand All @@ -146,6 +145,7 @@ export const Component = memo(function GoogleDriveRecovery() {
onClick={async () => {
if (!user.googleAccount || !selectedFile?.id) return
const result = await RestoreBackupModal.openAndWaitForClose({
decryptWithAccount: false,
download: () => {
return progressDownload(
() => googleDriveClient.requestFile(selectedFile.id),
Expand Down