From 5f24e7285e941b44e05cec5be32bee4589f4963c Mon Sep 17 00:00:00 2001 From: Aman Harwara Date: Fri, 30 Sep 2022 21:33:30 +0530 Subject: [PATCH] fix: downloading backups in mobile webview (#1703) --- packages/mobile/src/Lib/Interface.ts | 9 +-- .../ui-services/src/Archive/ArchiveManager.ts | 20 +++--- .../Components/NotesOptions/NotesOptions.tsx | 8 +-- .../Preferences/Panes/Backups/DataBackups.tsx | 30 ++++++++- .../NativeMobileWeb/DownloadBlobOnAndroid.tsx | 28 ++++++++ .../DownloadSelectedItemsOnAndroid.tsx | 67 ------------------- .../DownloadSelectedNotesOnAndroid.tsx | 32 +++++++++ .../NativeMobileWeb/ShareBlobOnMobile.ts | 10 +++ ...lectedItems.tsx => ShareSelectedNotes.tsx} | 13 ++-- .../Utils/DownloadOrShareBasedOnPlatform.ts | 21 ++++++ 10 files changed, 138 insertions(+), 100 deletions(-) create mode 100644 packages/web/src/javascripts/NativeMobileWeb/DownloadBlobOnAndroid.tsx delete mode 100644 packages/web/src/javascripts/NativeMobileWeb/DownloadSelectedItemsOnAndroid.tsx create mode 100644 packages/web/src/javascripts/NativeMobileWeb/DownloadSelectedNotesOnAndroid.tsx create mode 100644 packages/web/src/javascripts/NativeMobileWeb/ShareBlobOnMobile.ts rename packages/web/src/javascripts/NativeMobileWeb/{ShareSelectedItems.tsx => ShareSelectedNotes.tsx} (74%) create mode 100644 packages/web/src/javascripts/Utils/DownloadOrShareBasedOnPlatform.ts diff --git a/packages/mobile/src/Lib/Interface.ts b/packages/mobile/src/Lib/Interface.ts index e59f02117..e7acfb114 100644 --- a/packages/mobile/src/Lib/Interface.ts +++ b/packages/mobile/src/Lib/Interface.ts @@ -28,7 +28,6 @@ import { hide, show } from 'react-native-privacy-snapshot' import Share from 'react-native-share' import { AppStateObserverService } from './../AppStateObserverService' import Keychain from './Keychain' -import { SNReactNativeCrypto } from './ReactNativeCrypto' import { IsMobileWeb } from './Utils' export type BiometricsType = 'Fingerprint' | 'Face ID' | 'Biometrics' | 'Touch ID' @@ -79,14 +78,11 @@ export class MobileDevice implements MobileDeviceInterface { platform: SNPlatform.Ios | SNPlatform.Android = Platform.OS === 'ios' ? SNPlatform.Ios : SNPlatform.Android private eventObservers: MobileDeviceEventHandler[] = [] public isDarkMode = false - private crypto: SNReactNativeCrypto constructor( private stateObserverService?: AppStateObserverService, private androidBackHandlerService?: AndroidBackHandlerService, - ) { - this.crypto = new SNReactNativeCrypto() - } + ) {} deinit() { this.stateObserverService?.deinit() @@ -541,8 +537,7 @@ export class MobileDevice implements MobileDeviceInterface { try { const path = this.getFileDestinationPath(filename, saveInTempLocation) void this.deleteFileAtPathIfExists(path) - const decodedContents = this.crypto.base64Decode(base64.replace(/data.*base64,/, '')) - await writeFile(path, decodedContents) + await writeFile(path, base64.replace(/data.*base64,/, ''), 'base64') return path } catch (error) { this.consoleLog(`${error}`) diff --git a/packages/ui-services/src/Archive/ArchiveManager.ts b/packages/ui-services/src/Archive/ArchiveManager.ts index 329cb64c5..d12e4423c 100644 --- a/packages/ui-services/src/Archive/ArchiveManager.ts +++ b/packages/ui-services/src/Archive/ArchiveManager.ts @@ -71,7 +71,7 @@ export class ArchiveManager { return string } - private async downloadZippedDecryptedItems(data: BackupFile) { + async getZippedDecryptedItemsBlob(data: BackupFile) { const zip = await import('@zip.js/zip.js') const zipWriter = new zip.ZipWriter(new zip.BlobWriter('application/zip')) const items = data.items @@ -83,8 +83,7 @@ export class ArchiveManager { const fileName = zippableFileName('Standard Notes Backup and Import File') await zipWriter.add(fileName, new zip.BlobReader(blob)) - let index = 0 - const nextFile = async () => { + for (let index = 0; index < items.length; index++) { const item = items[index] let name, contents @@ -105,17 +104,14 @@ export class ArchiveManager { const fileName = `Items/${sanitizeFileName(item.content_type)}/` + zippableFileName(name, `-${item.uuid.split('-')[0]}`) await zipWriter.add(fileName, new zip.BlobReader(blob)) - - index++ - if (index < items.length) { - await nextFile() - } else { - const finalBlob = await zipWriter.close() - this.downloadData(finalBlob, `Standard Notes Backup - ${this.formattedDateForExports()}.zip`) - } } - await nextFile() + return await zipWriter.close() + } + + private async downloadZippedDecryptedItems(data: BackupFile) { + const zippedDecryptedItemsBlob = await this.getZippedDecryptedItemsBlob(data) + this.downloadData(zippedDecryptedItemsBlob, `Standard Notes Backup - ${this.formattedDateForExports()}.zip`) } async zipData(data: ZippableData): Promise { diff --git a/packages/web/src/javascripts/Components/NotesOptions/NotesOptions.tsx b/packages/web/src/javascripts/Components/NotesOptions/NotesOptions.tsx index aa57522a3..431401144 100644 --- a/packages/web/src/javascripts/Components/NotesOptions/NotesOptions.tsx +++ b/packages/web/src/javascripts/Components/NotesOptions/NotesOptions.tsx @@ -16,8 +16,8 @@ import { formatDateForContextMenu } from '@/Utils/DateUtils' import { useResponsiveAppPane } from '../ResponsivePane/ResponsivePaneProvider' import { AppPaneId } from '../ResponsivePane/AppPaneMetadata' import { getNoteBlob, getNoteFileName } from '@/Utils/NoteExportUtils' -import { shareSelectedItems } from '@/NativeMobileWeb/ShareSelectedItems' -import { downloadSelectedItemsOnAndroid } from '@/NativeMobileWeb/DownloadSelectedItemsOnAndroid' +import { shareSelectedNotes } from '@/NativeMobileWeb/ShareSelectedNotes' +import { downloadSelectedNotesOnAndroid } from '@/NativeMobileWeb/DownloadSelectedNotesOnAndroid' type DeletePermanentlyButtonProps = { onClick: () => void @@ -355,7 +355,7 @@ const NotesOptions = ({