From eb5c46e8707fe30ff5d75c31c542ef2503c198e9 Mon Sep 17 00:00:00 2001 From: ArceDanielShok Date: Thu, 29 Aug 2024 13:42:19 -0300 Subject: [PATCH 1/6] delete queue manager persist after logout --- src/apps/main/remote-sync/handlers.ts | 9 ++++++--- src/apps/sync-engine/BindingManager.ts | 8 ++++++++ .../dependency-injection/common/QueueManager.ts | 15 +++++++++++---- .../files/application/FilesPlaceholderUpdater.ts | 2 ++ .../files/domain/file-systems/LocalFileSystem.ts | 2 +- .../infrastructure/NodeWinLocalFileSystem.ts | 4 ++-- .../folders/application/FolderDeleter.ts | 4 ++-- .../application/FolderPlaceholderConverter.ts | 4 ++-- .../application/FolderPlaceholderDeleter.ts | 4 ++-- .../application/FolderSyncStatusUpdater.ts | 6 +++--- .../application/FoldersFatherSyncStatusUpdater.ts | 6 +++--- .../application/FoldersPlaceholderCreator.ts | 4 ++-- .../application/UpdatePlaceholderFolder.ts | 6 ++++-- .../{LocalFileSystem.ts => LocalFolderSystem.ts} | 4 ++-- .../infrastructure/NodeWinLocalFileSystem.ts | 8 ++++---- .../__mocks__/FolderLocalFileSystemMock.ts | 4 ++-- 16 files changed, 56 insertions(+), 34 deletions(-) rename src/context/virtual-drive/folders/domain/file-systems/{LocalFileSystem.ts => LocalFolderSystem.ts} (75%) diff --git a/src/apps/main/remote-sync/handlers.ts b/src/apps/main/remote-sync/handlers.ts index 478f609ab..f9dde2927 100644 --- a/src/apps/main/remote-sync/handlers.ts +++ b/src/apps/main/remote-sync/handlers.ts @@ -128,10 +128,13 @@ remoteSyncManager.onStatusChange((newStatus) => { }); remoteSyncManager.onStatusChange((newStatus) => { - if (newStatus === 'SYNCED') { - return setTrayStatus('IDLE'); + if (newStatus === 'SYNCING') { + return setTrayStatus('SYNCING'); } - setTrayStatus('SYNCING'); + if (newStatus === 'SYNC_FAILED') { + return setTrayStatus('ALERT'); + } + setTrayStatus('IDLE'); }); ipcMain.handle('get-remote-sync-status', () => diff --git a/src/apps/sync-engine/BindingManager.ts b/src/apps/sync-engine/BindingManager.ts index 36e9977dd..c874847ea 100644 --- a/src/apps/sync-engine/BindingManager.ts +++ b/src/apps/sync-engine/BindingManager.ts @@ -36,6 +36,7 @@ export class BindingsManager { private progressBuffer = 0; private controllers: IControllers; + private queueManager: QueueManager | null = null; private lastHydrated = ''; constructor( @@ -405,6 +406,7 @@ export class BindingsManager { notify, persistQueueManager ); + this.queueManager = queueManager; const logWatcherPath = DependencyInjectionLogWatcherPath.get(); this.container.virtualDrive.watchAndWait( this.paths.root, @@ -461,6 +463,12 @@ export class BindingsManager { // }); } + async cleanQueue() { + if (this.queueManager) { + await this.queueManager.clearQueue(); + } + } + async update() { Logger.info('[SYNC ENGINE]: Updating placeholders'); ipcRendererSyncEngine.send('SYNCING'); diff --git a/src/apps/sync-engine/dependency-injection/common/QueueManager.ts b/src/apps/sync-engine/dependency-injection/common/QueueManager.ts index a4c62aa49..fd9e0c8a3 100644 --- a/src/apps/sync-engine/dependency-injection/common/QueueManager.ts +++ b/src/apps/sync-engine/dependency-injection/common/QueueManager.ts @@ -58,7 +58,6 @@ export class QueueManager implements IQueueManager { }; this.notify = notify; this.persistPath = persistPath; - // creamos el archivo de persistencia si no existe if (!fs.existsSync(this.persistPath)) { fs.writeFileSync(this.persistPath, JSON.stringify(this.queues)); } else { @@ -87,16 +86,24 @@ export class QueueManager implements IQueueManager { private loadQueueStateFromFile(): void { Logger.debug('Loading queue state from file:' + this.persistPath); if (this.persistPath) { - // Si el archivo no existe, se crea y se guarda el estado inicial de las colas. if (!fs.existsSync(this.persistPath)) { - this.saveQueueStateToFile(); // Guarda el estado inicial en el archivo + this.saveQueueStateToFile(); } - // Si el archivo existe, carga los datos desde él. const data = fs.readFileSync(this.persistPath, 'utf-8'); this.queues = JSON.parse(data); } } + public clearQueue(): void { + this.queues = { + add: [], + hydrate: [], + dehydrate: [], + change: [], + changeSize: [], + }; + this.saveQueueStateToFile(); + } public enqueue(task: QueueItem): void { Logger.debug(`Task enqueued: ${JSON.stringify(task)}`); diff --git a/src/context/virtual-drive/files/application/FilesPlaceholderUpdater.ts b/src/context/virtual-drive/files/application/FilesPlaceholderUpdater.ts index 3e672c5e6..aac016a3a 100644 --- a/src/context/virtual-drive/files/application/FilesPlaceholderUpdater.ts +++ b/src/context/virtual-drive/files/application/FilesPlaceholderUpdater.ts @@ -77,6 +77,8 @@ export class FilesPlaceholderUpdater { ); await fs.unlink(win32AbsolutePath); } + + await this.localFileSystem.updateSyncStatus(remote, false); } async run(remotes: Array): Promise { diff --git a/src/context/virtual-drive/files/domain/file-systems/LocalFileSystem.ts b/src/context/virtual-drive/files/domain/file-systems/LocalFileSystem.ts index 5090349a2..4b03c3de3 100644 --- a/src/context/virtual-drive/files/domain/file-systems/LocalFileSystem.ts +++ b/src/context/virtual-drive/files/domain/file-systems/LocalFileSystem.ts @@ -8,7 +8,7 @@ export interface LocalFileSystem { getLocalFileId(file: File): Promise<`${string}-${string}`>; - updateSyncStatus(file: File): Promise; + updateSyncStatus(file: File, status: boolean): Promise; getFileIdentity(path: File['path']): Promise; diff --git a/src/context/virtual-drive/files/infrastructure/NodeWinLocalFileSystem.ts b/src/context/virtual-drive/files/infrastructure/NodeWinLocalFileSystem.ts index 3c3c51863..6a3d56951 100644 --- a/src/context/virtual-drive/files/infrastructure/NodeWinLocalFileSystem.ts +++ b/src/context/virtual-drive/files/infrastructure/NodeWinLocalFileSystem.ts @@ -55,11 +55,11 @@ export class NodeWinLocalFileSystem implements LocalFileSystem { await this.virtualDrive.deleteFileSyncRoot(path); } - async updateSyncStatus(file: File): Promise { + async updateSyncStatus(file: File, status = true): Promise { const win32AbsolutePath = this.relativePathToAbsoluteConverter.run( file.path ); - return this.virtualDrive.updateSyncStatus(win32AbsolutePath, false); + return this.virtualDrive.updateSyncStatus(win32AbsolutePath, false, status); } async convertToPlaceholder(file: File): Promise { diff --git a/src/context/virtual-drive/folders/application/FolderDeleter.ts b/src/context/virtual-drive/folders/application/FolderDeleter.ts index d829086b1..2eede9b9e 100644 --- a/src/context/virtual-drive/folders/application/FolderDeleter.ts +++ b/src/context/virtual-drive/folders/application/FolderDeleter.ts @@ -5,13 +5,13 @@ import { FolderNotFoundError } from '../domain/errors/FolderNotFoundError'; import { AllParentFoldersStatusIsExists } from './AllParentFoldersStatusIsExists'; import { FolderRepository } from '../domain/FolderRepository'; import { RemoteFileSystem } from '../domain/file-systems/RemoteFileSystem'; -import { LocalFileSystem } from '../domain/file-systems/LocalFileSystem'; +import { LocalFolderSystem } from '../domain/file-systems/LocalFolderSystem'; export class FolderDeleter { constructor( private readonly repository: FolderRepository, private readonly remote: RemoteFileSystem, - private readonly local: LocalFileSystem, + private readonly local: LocalFolderSystem, private readonly allParentFoldersStatusIsExists: AllParentFoldersStatusIsExists ) {} diff --git a/src/context/virtual-drive/folders/application/FolderPlaceholderConverter.ts b/src/context/virtual-drive/folders/application/FolderPlaceholderConverter.ts index b3d84f30c..d45e35ca8 100644 --- a/src/context/virtual-drive/folders/application/FolderPlaceholderConverter.ts +++ b/src/context/virtual-drive/folders/application/FolderPlaceholderConverter.ts @@ -1,8 +1,8 @@ import { Folder } from '../domain/Folder'; -import { LocalFileSystem } from '../domain/file-systems/LocalFileSystem'; +import { LocalFolderSystem } from '../domain/file-systems/LocalFolderSystem'; export class FolderPlaceholderConverter { - constructor(private readonly localFileSystem: LocalFileSystem) {} + constructor(private readonly localFileSystem: LocalFolderSystem) {} async run(folder: Folder) { await this.localFileSystem.convertToPlaceholder(folder); diff --git a/src/context/virtual-drive/folders/application/FolderPlaceholderDeleter.ts b/src/context/virtual-drive/folders/application/FolderPlaceholderDeleter.ts index 1a821e7ba..410ffb110 100644 --- a/src/context/virtual-drive/folders/application/FolderPlaceholderDeleter.ts +++ b/src/context/virtual-drive/folders/application/FolderPlaceholderDeleter.ts @@ -2,7 +2,7 @@ import { RelativePathToAbsoluteConverter } from '../../shared/application/Relati import { Folder } from '../domain/Folder'; import { FolderStatuses } from '../domain/FolderStatus'; import { RemoteFileSystem } from '../domain/file-systems/RemoteFileSystem'; -import { LocalFileSystem } from '../domain/file-systems/LocalFileSystem'; +import { LocalFolderSystem } from '../domain/file-systems/LocalFolderSystem'; import Logger from 'electron-log'; import { sleep } from '../../../../apps/main/util'; @@ -10,7 +10,7 @@ export class FolderPlaceholderDeleter { constructor( private readonly relativePathToAbsoluteConverter: RelativePathToAbsoluteConverter, private readonly remoteFileSystem: RemoteFileSystem, - private readonly local: LocalFileSystem + private readonly local: LocalFolderSystem ) {} private async hasToBeDeleted(remote: Folder): Promise { diff --git a/src/context/virtual-drive/folders/application/FolderSyncStatusUpdater.ts b/src/context/virtual-drive/folders/application/FolderSyncStatusUpdater.ts index d333caf4c..daa8b2942 100644 --- a/src/context/virtual-drive/folders/application/FolderSyncStatusUpdater.ts +++ b/src/context/virtual-drive/folders/application/FolderSyncStatusUpdater.ts @@ -1,10 +1,10 @@ import { Folder } from '../domain/Folder'; -import { LocalFileSystem } from '../domain/file-systems/LocalFileSystem'; +import { LocalFolderSystem } from '../domain/file-systems/LocalFolderSystem'; export class FolderSyncStatusUpdater { - constructor(private readonly localFileSystem: LocalFileSystem) {} + constructor(private readonly localFileSystem: LocalFolderSystem) {} async run(folder: Folder) { - await this.localFileSystem.updateSyncStatus(folder); + await this.localFileSystem.updateSyncStatus(folder, true); } } diff --git a/src/context/virtual-drive/folders/application/FoldersFatherSyncStatusUpdater.ts b/src/context/virtual-drive/folders/application/FoldersFatherSyncStatusUpdater.ts index 6b94883df..4286e2d86 100644 --- a/src/context/virtual-drive/folders/application/FoldersFatherSyncStatusUpdater.ts +++ b/src/context/virtual-drive/folders/application/FoldersFatherSyncStatusUpdater.ts @@ -2,12 +2,12 @@ import { File } from '../../files/domain/File'; import { PlatformPathConverter } from '../../shared/application/PlatformPathConverter'; import { Folder } from '../domain/Folder'; import { FolderRepository } from '../domain/FolderRepository'; -import { LocalFileSystem } from '../domain/file-systems/LocalFileSystem'; +import { LocalFolderSystem } from '../domain/file-systems/LocalFolderSystem'; import Logger from 'electron-log'; export class FoldersFatherSyncStatusUpdater { constructor( - private readonly localFileSystem: LocalFileSystem, + private readonly localFileSystem: LocalFolderSystem, private readonly repository: FolderRepository ) {} @@ -23,7 +23,7 @@ export class FoldersFatherSyncStatusUpdater { const folder = await this.repository.searchByPartial({ path: posixDir }); if (folder) { Logger.debug(`Updating sync status for ${folder.path}`); - await this.localFileSystem.updateSyncStatus(folder); + await this.localFileSystem.updateSyncStatus(folder, true); } this.update(posixDir); } diff --git a/src/context/virtual-drive/folders/application/FoldersPlaceholderCreator.ts b/src/context/virtual-drive/folders/application/FoldersPlaceholderCreator.ts index 62bbf1fb5..855b5a9f2 100644 --- a/src/context/virtual-drive/folders/application/FoldersPlaceholderCreator.ts +++ b/src/context/virtual-drive/folders/application/FoldersPlaceholderCreator.ts @@ -1,8 +1,8 @@ import { Folder } from '../domain/Folder'; -import { LocalFileSystem } from '../domain/file-systems/LocalFileSystem'; +import { LocalFolderSystem } from '../domain/file-systems/LocalFolderSystem'; export class FoldersPlaceholderCreator { - constructor(private readonly local: LocalFileSystem) {} + constructor(private readonly local: LocalFolderSystem) {} async run(folders: Array): Promise { const createPromises = folders.map((folder) => diff --git a/src/context/virtual-drive/folders/application/UpdatePlaceholderFolder.ts b/src/context/virtual-drive/folders/application/UpdatePlaceholderFolder.ts index 13b6a5da2..78617c8b4 100644 --- a/src/context/virtual-drive/folders/application/UpdatePlaceholderFolder.ts +++ b/src/context/virtual-drive/folders/application/UpdatePlaceholderFolder.ts @@ -5,12 +5,12 @@ import Logger from 'electron-log'; import path from 'path'; import { FolderStatuses } from '../domain/FolderStatus'; import { FolderRepository } from '../domain/FolderRepository'; -import { LocalFileSystem } from '../domain/file-systems/LocalFileSystem'; import * as Sentry from '@sentry/electron/renderer'; +import { LocalFolderSystem } from '../domain/file-systems/LocalFolderSystem'; export class FolderPlaceholderUpdater { constructor( private readonly repository: FolderRepository, - private readonly local: LocalFileSystem, + private readonly local: LocalFolderSystem, private readonly relativePathToAbsoluteConverter: RelativePathToAbsoluteConverter ) {} @@ -135,6 +135,8 @@ export class FolderPlaceholderUpdater { await fs.rm(win32AbsolutePath, { recursive: true }); return; } + + await this.local.updateSyncStatus(remote, false); } async run(remotes: Array): Promise { diff --git a/src/context/virtual-drive/folders/domain/file-systems/LocalFileSystem.ts b/src/context/virtual-drive/folders/domain/file-systems/LocalFolderSystem.ts similarity index 75% rename from src/context/virtual-drive/folders/domain/file-systems/LocalFileSystem.ts rename to src/context/virtual-drive/folders/domain/file-systems/LocalFolderSystem.ts index c9b140306..ebed48c82 100644 --- a/src/context/virtual-drive/folders/domain/file-systems/LocalFileSystem.ts +++ b/src/context/virtual-drive/folders/domain/file-systems/LocalFolderSystem.ts @@ -1,9 +1,9 @@ import { Folder } from '../Folder'; -export interface LocalFileSystem { +export interface LocalFolderSystem { createPlaceHolder(folder: Folder): Promise; - updateSyncStatus(folder: Folder): Promise; + updateSyncStatus(folder: Folder, status: boolean): Promise; convertToPlaceholder(folder: Folder): Promise; diff --git a/src/context/virtual-drive/folders/infrastructure/NodeWinLocalFileSystem.ts b/src/context/virtual-drive/folders/infrastructure/NodeWinLocalFileSystem.ts index 39ca67e4a..5dc7a4853 100644 --- a/src/context/virtual-drive/folders/infrastructure/NodeWinLocalFileSystem.ts +++ b/src/context/virtual-drive/folders/infrastructure/NodeWinLocalFileSystem.ts @@ -1,10 +1,10 @@ import { VirtualDrive } from 'virtual-drive/dist'; import { Folder } from '../domain/Folder'; import { FolderStatuses } from '../domain/FolderStatus'; -import { LocalFileSystem } from '../domain/file-systems/LocalFileSystem'; +import { LocalFolderSystem } from '../domain/file-systems/LocalFolderSystem'; import { RelativePathToAbsoluteConverter } from '../../shared/application/RelativePathToAbsoluteConverter'; -export class NodeWinLocalFileSystem implements LocalFileSystem { +export class NodeWinLocalFileSystem implements LocalFolderSystem { constructor( private readonly virtualDrive: VirtualDrive, private readonly relativePathToAbsoluteConverter: RelativePathToAbsoluteConverter @@ -26,12 +26,12 @@ export class NodeWinLocalFileSystem implements LocalFileSystem { ); } - async updateSyncStatus(folder: Folder): Promise { + async updateSyncStatus(folder: Folder, status = true): Promise { const folderPath = `${folder.path}/`; const win32AbsolutePath = this.relativePathToAbsoluteConverter.run(folderPath); - return this.virtualDrive.updateSyncStatus(win32AbsolutePath, true); + return this.virtualDrive.updateSyncStatus(win32AbsolutePath, true, status); } async getFileIdentity(path: File['path']): Promise { diff --git a/tests/context/virtual-drive/folders/__mocks__/FolderLocalFileSystemMock.ts b/tests/context/virtual-drive/folders/__mocks__/FolderLocalFileSystemMock.ts index f494e88bd..2028559ee 100644 --- a/tests/context/virtual-drive/folders/__mocks__/FolderLocalFileSystemMock.ts +++ b/tests/context/virtual-drive/folders/__mocks__/FolderLocalFileSystemMock.ts @@ -1,7 +1,7 @@ import { Folder } from '../../../../../src/context/virtual-drive/folders/domain/Folder'; -import { LocalFileSystem } from '../../../../../src/context/virtual-drive/folders/domain/file-systems/LocalFileSystem'; +import { LocalFolderSystem } from '../../../../../src/context/virtual-drive/folders/domain/file-systems/LocalFolderSystem'; -export class FolderLocalFileSystemMock implements LocalFileSystem { +export class FolderLocalFileSystemMock implements LocalFolderSystem { public readonly createPlaceHolderMock = jest.fn(); public readonly getLocalFolderIdMock = jest.fn(); public readonly updateSyncStatusMock = jest.fn(); From 67cb45e3b301e20e6a96e87981afec3973e616d8 Mon Sep 17 00:00:00 2001 From: ArceDanielShok Date: Tue, 3 Sep 2024 13:28:34 -0300 Subject: [PATCH 2/6] fix some smell issues --- src/apps/shared/HttpClient/HttpClient.ts | 7 +++++-- src/apps/sync-engine/BindingManager.ts | 13 +------------ .../dependency-injection/common/QueueManager.ts | 3 +++ .../application/FileSyncOrchestrator.ts | 12 ++++++++---- .../files/application/FilesPlaceholderUpdater.ts | 2 -- .../files/domain/file-systems/LocalFileSystem.ts | 2 +- .../folders/application/UpdatePlaceholderFolder.ts | 2 -- 7 files changed, 18 insertions(+), 23 deletions(-) diff --git a/src/apps/shared/HttpClient/HttpClient.ts b/src/apps/shared/HttpClient/HttpClient.ts index a422e9310..2d7f67d5f 100644 --- a/src/apps/shared/HttpClient/HttpClient.ts +++ b/src/apps/shared/HttpClient/HttpClient.ts @@ -15,9 +15,12 @@ export class AuthorizedHttpClient { private handleUnauthorizedResponse(error: AxiosError) { if (error?.response?.status === 401) { Logger.warn('[AUTH] Request unauthorized'); - // this.unauthorizedNotifier(); + try { + this.unauthorizedNotifier(); + } catch (error) { + Logger.error('[AUTH] Unauthorized notifier failed', error); + } } - // Prevent the token from being displayed in the logs if (error.config.headers?.Authorization) { error.config.headers['Authorization'] = 'Bearer ****************'; diff --git a/src/apps/sync-engine/BindingManager.ts b/src/apps/sync-engine/BindingManager.ts index c874847ea..b47a52d53 100644 --- a/src/apps/sync-engine/BindingManager.ts +++ b/src/apps/sync-engine/BindingManager.ts @@ -303,18 +303,7 @@ export class BindingsManager { const callbacks = { handleAdd: async (task: QueueItem) => { try { - Logger.debug( - 'Path received from callback', - task.path.replace(/\\/g, '/') - ); - - const filePath = new FilePath(task.path.replace(/\\/g, '/')); - - const file = await this.container.fileFinder.findFromFilePath( - filePath - ); - - Logger.debug('File found', file); + Logger.debug('Path received from handle add', task.path); const itemId = await this.controllers.addFile.execute(task.path); if (!itemId) { diff --git a/src/apps/sync-engine/dependency-injection/common/QueueManager.ts b/src/apps/sync-engine/dependency-injection/common/QueueManager.ts index fd9e0c8a3..ce803b5cc 100644 --- a/src/apps/sync-engine/dependency-injection/common/QueueManager.ts +++ b/src/apps/sync-engine/dependency-injection/common/QueueManager.ts @@ -91,6 +91,9 @@ export class QueueManager implements IQueueManager { } const data = fs.readFileSync(this.persistPath, 'utf-8'); + if (!data) { + return; + } this.queues = JSON.parse(data); } } diff --git a/src/context/virtual-drive/boundaryBridge/application/FileSyncOrchestrator.ts b/src/context/virtual-drive/boundaryBridge/application/FileSyncOrchestrator.ts index d6f342379..7d09a9e40 100644 --- a/src/context/virtual-drive/boundaryBridge/application/FileSyncOrchestrator.ts +++ b/src/context/virtual-drive/boundaryBridge/application/FileSyncOrchestrator.ts @@ -9,10 +9,14 @@ export class FileSyncOrchestrator { async run(absolutePaths: string[]): Promise { for (const absolutePath of absolutePaths) { - await this.fileSyncronizer.run( - absolutePath, - this.contentsUploader.run.bind(this.contentsUploader) - ); + try { + await this.fileSyncronizer.run( + absolutePath, + this.contentsUploader.run.bind(this.contentsUploader) + ); + } catch (error) { + console.error(error); + } } } } diff --git a/src/context/virtual-drive/files/application/FilesPlaceholderUpdater.ts b/src/context/virtual-drive/files/application/FilesPlaceholderUpdater.ts index aac016a3a..3e672c5e6 100644 --- a/src/context/virtual-drive/files/application/FilesPlaceholderUpdater.ts +++ b/src/context/virtual-drive/files/application/FilesPlaceholderUpdater.ts @@ -77,8 +77,6 @@ export class FilesPlaceholderUpdater { ); await fs.unlink(win32AbsolutePath); } - - await this.localFileSystem.updateSyncStatus(remote, false); } async run(remotes: Array): Promise { diff --git a/src/context/virtual-drive/files/domain/file-systems/LocalFileSystem.ts b/src/context/virtual-drive/files/domain/file-systems/LocalFileSystem.ts index 4b03c3de3..5090349a2 100644 --- a/src/context/virtual-drive/files/domain/file-systems/LocalFileSystem.ts +++ b/src/context/virtual-drive/files/domain/file-systems/LocalFileSystem.ts @@ -8,7 +8,7 @@ export interface LocalFileSystem { getLocalFileId(file: File): Promise<`${string}-${string}`>; - updateSyncStatus(file: File, status: boolean): Promise; + updateSyncStatus(file: File): Promise; getFileIdentity(path: File['path']): Promise; diff --git a/src/context/virtual-drive/folders/application/UpdatePlaceholderFolder.ts b/src/context/virtual-drive/folders/application/UpdatePlaceholderFolder.ts index 78617c8b4..3426b026d 100644 --- a/src/context/virtual-drive/folders/application/UpdatePlaceholderFolder.ts +++ b/src/context/virtual-drive/folders/application/UpdatePlaceholderFolder.ts @@ -135,8 +135,6 @@ export class FolderPlaceholderUpdater { await fs.rm(win32AbsolutePath, { recursive: true }); return; } - - await this.local.updateSyncStatus(remote, false); } async run(remotes: Array): Promise { From 3dfd35f1e31d3f4a90bf7537878778912b919717 Mon Sep 17 00:00:00 2001 From: ArceDanielShok Date: Wed, 4 Sep 2024 13:50:23 -0300 Subject: [PATCH 3/6] Implemented the changes for ticket PB-2692. Integrated the new endpoint to retrieve folder metadata during creation. This update ensures that when a folder is created, the correct metadata is fetched and stored, addressing the issues related to folder persistence and synchronization. --- src/apps/main/auth/handlers.ts | 4 +- src/apps/main/auth/refresh-token.ts | 39 +++++++++++++++- src/apps/main/auth/service.ts | 7 +-- src/apps/main/preload.d.ts | 7 +++ src/apps/main/preload.js | 7 +++ .../main/remote-sync/RemoteSyncManager.ts | 4 +- src/apps/main/types.ts | 1 + .../dependency-injection/common/traverser.ts | 3 +- .../dependency-injection/folders/builder.ts | 14 +++--- .../dependency-injection/items/builder.ts | 6 ++- src/context/shared/domain/ServerFolder.ts | 1 + .../folders/application/FolderCreator.ts | 4 +- .../folders/application/FolderDeleter.ts | 2 +- .../folders/application/FolderMover.ts | 2 +- .../application/FolderPlaceholderDeleter.ts | 2 +- .../folders/application/FolderRenamer.ts | 2 +- .../Offline/OfflineFolderCreator.ts | 7 ++- .../folders/domain/OfflineFolder.ts | 19 +++++++- ...oteFileSystem.ts => RemoteFolderSystem.ts} | 2 +- ...ileSystem.ts => HttpRemoteFolderSystem.ts} | 44 ++++++++++++++++++- .../items/application/Traverser.ts | 14 +++--- .../__mocks__/FolderRemoteFileSystemMock.ts | 2 +- 22 files changed, 157 insertions(+), 36 deletions(-) rename src/context/virtual-drive/folders/domain/file-systems/{RemoteFileSystem.ts => RemoteFolderSystem.ts} (91%) rename src/context/virtual-drive/folders/infrastructure/{HttpRemoteFileSystem.ts => HttpRemoteFolderSystem.ts} (72%) diff --git a/src/apps/main/auth/handlers.ts b/src/apps/main/auth/handlers.ts index 077d18da3..ff0570ab6 100644 --- a/src/apps/main/auth/handlers.ts +++ b/src/apps/main/auth/handlers.ts @@ -6,7 +6,7 @@ import { applicationOpened } from '../analytics/service'; import eventBus from '../event-bus'; import { setupRootFolder } from '../virtual-root-folder/service'; import { getWidget } from '../windows/widget'; -import { createTokenSchedule } from './refresh-token'; +import { checkUserData, createTokenSchedule } from './refresh-token'; import { canHisConfigBeRestored, encryptToken, @@ -79,7 +79,7 @@ eventBus.on('APP_IS_READY', async () => { if (!isLoggedIn) { return; } - + await checkUserData(); encryptToken(); applicationOpened(); await createTokenSchedule(); diff --git a/src/apps/main/auth/refresh-token.ts b/src/apps/main/auth/refresh-token.ts index 50a94a251..8099ee2a6 100644 --- a/src/apps/main/auth/refresh-token.ts +++ b/src/apps/main/auth/refresh-token.ts @@ -1,14 +1,21 @@ import Logger from 'electron-log'; -import { getClient } from '../../shared/HttpClient/main-process-client'; +import { + getClient, + getNewTokenClient, +} from '../../shared/HttpClient/main-process-client'; import { TokenScheduler } from '../token-scheduler/TokenScheduler'; import { onUserUnauthorized } from './handlers'; import { + getUser, obtainTokens as obtainStoredTokens, + setUser, updateCredentials, } from './service'; +import axios from 'axios'; const authorizedClient = getClient(); +const newAuthorizedClient = getNewTokenClient(); async function obtainTokens() { try { @@ -48,3 +55,33 @@ export async function createTokenSchedule(refreshedTokens?: Array) { createTokenSchedule(await refreshToken()); } } + +async function getRootFolderMetadata(rootFolderid: number) { + try { + const res = await newAuthorizedClient.get( + `${process.env.NEW_DRIVE_URL}/drive/folders/${rootFolderid}/metadata` + ); + + Logger.info('[AUTH] Got root folder metadata', res.data); + return res.data; + } catch (err) { + Logger.error('[AUTH] Could not get root folder metadata', err); + if (axios.isAxiosError(err)) { + Logger.error('[Is Axios Error]', err.response?.data); + } + return null; + } +} + +export async function checkUserData(): Promise { + const user = getUser(); + if (user?.root_folder_id && !user?.rootFolderId) { + const rootFolderMetadata = await getRootFolderMetadata(user.root_folder_id); + if (rootFolderMetadata) { + setUser({ + ...user, + rootFolderId: rootFolderMetadata.uuid, + }); + } + } +} diff --git a/src/apps/main/auth/service.ts b/src/apps/main/auth/service.ts index fb56ce325..167d2b3ee 100644 --- a/src/apps/main/auth/service.ts +++ b/src/apps/main/auth/service.ts @@ -86,6 +86,10 @@ export function setCredentials( ConfigStore.set('newTokenEncrypted', isSafeStorageAvailable); } +export function setUser(userData: User) { + ConfigStore.set('userData', userData); +} + export function updateCredentials( bearerToken: string, newBearerToken?: string @@ -146,7 +150,6 @@ export function getUser(): User | null { return user && Object.keys(user).length ? user : null; } - export function obtainTokens(): Array { return tokensKeys.map(obtainToken); } @@ -220,5 +223,3 @@ export function logout() { resetCredentials(); Logger.info('[AUTH] User logged out'); } - - diff --git a/src/apps/main/preload.d.ts b/src/apps/main/preload.d.ts index 6028d6622..12822ee49 100644 --- a/src/apps/main/preload.d.ts +++ b/src/apps/main/preload.d.ts @@ -11,6 +11,13 @@ declare interface Window { pathChanged(path: string): void; + logger: { + info: (...message: unknown[]) => void; + error: (...message: unknown[]) => void; + warn: (...message: unknown[]) => void; + debug: (...message: unknown[]) => void; + }; + getGeneralIssues: () => Promise< import('../../apps/shared/types').GeneralIssue[] >; diff --git a/src/apps/main/preload.js b/src/apps/main/preload.js index fce37a19c..1115029fc 100644 --- a/src/apps/main/preload.js +++ b/src/apps/main/preload.js @@ -1,5 +1,6 @@ const { contextBridge, ipcRenderer } = require('electron'); const path = require('path'); +const Logger = require('electron-log'); contextBridge.exposeInMainWorld('electron', { getConfigKey(key) { @@ -16,6 +17,12 @@ contextBridge.exposeInMainWorld('electron', { return () => ipcRenderer.removeListener(eventName, callback); }, + logger: { + info: (...message) => Logger.info(message), + error: (...message) => Logger.error(message), + warn: (...message) => Logger.warn(message), + }, + pathChanged(pathname) { ipcRenderer.send('path-changed', pathname); }, diff --git a/src/apps/main/remote-sync/RemoteSyncManager.ts b/src/apps/main/remote-sync/RemoteSyncManager.ts index cb130787c..7daf24b41 100644 --- a/src/apps/main/remote-sync/RemoteSyncManager.ts +++ b/src/apps/main/remote-sync/RemoteSyncManager.ts @@ -676,7 +676,7 @@ export class RemoteSyncManager { ); Logger.info( `Fetching item ${type} response: ${JSON.stringify( - response.data[0], + response.data?.length, null, 2 )}` @@ -700,7 +700,7 @@ export class RemoteSyncManager { ); Logger.info( `Fetching by folder ${type} by folder response: ${JSON.stringify( - response.data.result[0], + response.data.result?.length, null, 2 )}` diff --git a/src/apps/main/types.ts b/src/apps/main/types.ts index cab195049..8e06531c9 100644 --- a/src/apps/main/types.ts +++ b/src/apps/main/types.ts @@ -14,6 +14,7 @@ export type User = { registerCompleted: boolean; revocateKey: string; root_folder_id: number; + rootFolderId: string; sharedWorkspace: boolean; teams: boolean; userId: string; diff --git a/src/apps/sync-engine/dependency-injection/common/traverser.ts b/src/apps/sync-engine/dependency-injection/common/traverser.ts index be17a4e0c..f7b3017df 100644 --- a/src/apps/sync-engine/dependency-injection/common/traverser.ts +++ b/src/apps/sync-engine/dependency-injection/common/traverser.ts @@ -16,7 +16,8 @@ export class DependencyInjectionTraverserProvider { const traverser = Traverser.existingItems( crypt, ipcRendererSyncEngine, - user.root_folder_id + user.root_folder_id, + user.rootFolderId ); DependencyInjectionTraverserProvider.traverser = traverser; diff --git a/src/apps/sync-engine/dependency-injection/folders/builder.ts b/src/apps/sync-engine/dependency-injection/folders/builder.ts index f3cc0c4ee..7d7cbb933 100644 --- a/src/apps/sync-engine/dependency-injection/folders/builder.ts +++ b/src/apps/sync-engine/dependency-injection/folders/builder.ts @@ -17,7 +17,7 @@ import { RetrieveAllFolders } from '../../../../context/virtual-drive/folders/ap import { SynchronizeOfflineModifications } from '../../../../context/virtual-drive/folders/application/SynchronizeOfflineModifications'; import { SynchronizeOfflineModificationsOnFolderCreated } from '../../../../context/virtual-drive/folders/application/SynchronizeOfflineModificationsOnFolderCreated'; import { FolderPlaceholderUpdater } from '../../../../context/virtual-drive/folders/application/UpdatePlaceholderFolder'; -import { HttpRemoteFileSystem } from '../../../../context/virtual-drive/folders/infrastructure/HttpRemoteFileSystem'; +import { HttpRemoteFolderSystem } from '../../../../context/virtual-drive/folders/infrastructure/HttpRemoteFolderSystem'; import { InMemoryFolderRepository } from '../../../../context/virtual-drive/folders/infrastructure/InMemoryFolderRepository'; import { InMemoryOfflineFolderRepository } from '../../../../context/virtual-drive/folders/infrastructure/InMemoryOfflineFolderRepository'; import { ipcRendererSyncEngine } from '../../ipcRendererSyncEngine'; @@ -48,7 +48,7 @@ export async function buildFoldersContainer( virtualDrive, shredContainer.relativePathToAbsoluteConverter ); - const remoteFileSystem = new HttpRemoteFileSystem( + const remoteFolderSystem = new HttpRemoteFolderSystem( clients.drive, clients.newDrive ); @@ -67,7 +67,7 @@ export async function buildFoldersContainer( const folderDeleter = new FolderDeleter( repository, - remoteFileSystem, + remoteFolderSystem, localFileSystem, allParentFoldersStatusIsExists ); @@ -76,7 +76,7 @@ export async function buildFoldersContainer( const folderCreator = new FolderCreator( repository, - remoteFileSystem, + remoteFolderSystem, ipcRendererSyncEngine, eventBus, folderPlaceholderConverter @@ -84,12 +84,12 @@ export async function buildFoldersContainer( const folderMover = new FolderMover( repository, - remoteFileSystem, + remoteFolderSystem, folderFinder ); const folderRenamer = new FolderRenamer( repository, - remoteFileSystem, + remoteFolderSystem, ipcRendererSyncEngine ); @@ -144,7 +144,7 @@ export async function buildFoldersContainer( const folderPlaceholderDeleter = new FolderPlaceholderDeleter( shredContainer.relativePathToAbsoluteConverter, - remoteFileSystem, + remoteFolderSystem, localFileSystem ); diff --git a/src/apps/sync-engine/dependency-injection/items/builder.ts b/src/apps/sync-engine/dependency-injection/items/builder.ts index 20a7c7ffd..7be801d59 100644 --- a/src/apps/sync-engine/dependency-injection/items/builder.ts +++ b/src/apps/sync-engine/dependency-injection/items/builder.ts @@ -20,12 +20,14 @@ export function buildItemsContainer(): ItemsContainer { const existingItemsTraverser = Traverser.existingItems( nameDecryptor, ipcRendererSyncEngine, - user.root_folder_id + user.root_folder_id, + user.rootFolderId ); const allStatusesTraverser = Traverser.allItems( nameDecryptor, ipcRendererSyncEngine, - user.root_folder_id + user.root_folder_id, + user.rootFolderId ); const treeBuilder = new TreeBuilder( remoteItemsGenerator, diff --git a/src/context/shared/domain/ServerFolder.ts b/src/context/shared/domain/ServerFolder.ts index e1ca1ff35..7af7e6a7d 100644 --- a/src/context/shared/domain/ServerFolder.ts +++ b/src/context/shared/domain/ServerFolder.ts @@ -15,4 +15,5 @@ export type ServerFolder = { plain_name: string | null; status: ServerFolderStatus; uuid: string; + removed: boolean; }; diff --git a/src/context/virtual-drive/folders/application/FolderCreator.ts b/src/context/virtual-drive/folders/application/FolderCreator.ts index 0b64008dc..202a170a4 100644 --- a/src/context/virtual-drive/folders/application/FolderCreator.ts +++ b/src/context/virtual-drive/folders/application/FolderCreator.ts @@ -3,13 +3,13 @@ import { EventBus } from '../../shared/domain/EventBus'; import { Folder } from '../domain/Folder'; import { FolderRepository } from '../domain/FolderRepository'; import { OfflineFolder } from '../domain/OfflineFolder'; -import { RemoteFileSystem } from '../domain/file-systems/RemoteFileSystem'; +import { RemoteFolderSystem } from '../domain/file-systems/RemoteFolderSystem'; import { FolderPlaceholderConverter } from './FolderPlaceholderConverter'; export class FolderCreator { constructor( private readonly repository: FolderRepository, - private readonly remote: RemoteFileSystem, + private readonly remote: RemoteFolderSystem, private readonly ipc: SyncEngineIpc, private readonly eventBus: EventBus, private readonly folderPlaceholderConverter: FolderPlaceholderConverter diff --git a/src/context/virtual-drive/folders/application/FolderDeleter.ts b/src/context/virtual-drive/folders/application/FolderDeleter.ts index 2eede9b9e..3293e753a 100644 --- a/src/context/virtual-drive/folders/application/FolderDeleter.ts +++ b/src/context/virtual-drive/folders/application/FolderDeleter.ts @@ -4,7 +4,7 @@ import { ActionNotPermittedError } from '../domain/errors/ActionNotPermittedErro import { FolderNotFoundError } from '../domain/errors/FolderNotFoundError'; import { AllParentFoldersStatusIsExists } from './AllParentFoldersStatusIsExists'; import { FolderRepository } from '../domain/FolderRepository'; -import { RemoteFileSystem } from '../domain/file-systems/RemoteFileSystem'; +import { RemoteFileSystem } from '../domain/file-systems/RemoteFolderSystem'; import { LocalFolderSystem } from '../domain/file-systems/LocalFolderSystem'; export class FolderDeleter { diff --git a/src/context/virtual-drive/folders/application/FolderMover.ts b/src/context/virtual-drive/folders/application/FolderMover.ts index f185e9fd8..d0038b70d 100644 --- a/src/context/virtual-drive/folders/application/FolderMover.ts +++ b/src/context/virtual-drive/folders/application/FolderMover.ts @@ -3,7 +3,7 @@ import { FolderPath } from '../domain/FolderPath'; import { Folder } from '../domain/Folder'; import { FolderFinder } from './FolderFinder'; import { FolderRepository } from '../domain/FolderRepository'; -import { RemoteFileSystem } from '../domain/file-systems/RemoteFileSystem'; +import { RemoteFileSystem } from '../domain/file-systems/RemoteFolderSystem'; export class FolderMover { constructor( diff --git a/src/context/virtual-drive/folders/application/FolderPlaceholderDeleter.ts b/src/context/virtual-drive/folders/application/FolderPlaceholderDeleter.ts index 410ffb110..835ec297d 100644 --- a/src/context/virtual-drive/folders/application/FolderPlaceholderDeleter.ts +++ b/src/context/virtual-drive/folders/application/FolderPlaceholderDeleter.ts @@ -1,7 +1,7 @@ import { RelativePathToAbsoluteConverter } from '../../shared/application/RelativePathToAbsoluteConverter'; import { Folder } from '../domain/Folder'; import { FolderStatuses } from '../domain/FolderStatus'; -import { RemoteFileSystem } from '../domain/file-systems/RemoteFileSystem'; +import { RemoteFileSystem } from '../domain/file-systems/RemoteFolderSystem'; import { LocalFolderSystem } from '../domain/file-systems/LocalFolderSystem'; import Logger from 'electron-log'; import { sleep } from '../../../../apps/main/util'; diff --git a/src/context/virtual-drive/folders/application/FolderRenamer.ts b/src/context/virtual-drive/folders/application/FolderRenamer.ts index 8304e025c..ea4a198a9 100644 --- a/src/context/virtual-drive/folders/application/FolderRenamer.ts +++ b/src/context/virtual-drive/folders/application/FolderRenamer.ts @@ -1,7 +1,7 @@ import { FolderPath } from '../domain/FolderPath'; import { Folder } from '../domain/Folder'; import { FolderRepository } from '../domain/FolderRepository'; -import { RemoteFileSystem } from '../domain/file-systems/RemoteFileSystem'; +import { RemoteFileSystem } from '../domain/file-systems/RemoteFolderSystem'; import { SyncEngineIpc } from '../../../../apps/sync-engine/ipcRendererSyncEngine'; export class FolderRenamer { diff --git a/src/context/virtual-drive/folders/application/Offline/OfflineFolderCreator.ts b/src/context/virtual-drive/folders/application/Offline/OfflineFolderCreator.ts index 9bd900a35..458dd588a 100644 --- a/src/context/virtual-drive/folders/application/Offline/OfflineFolderCreator.ts +++ b/src/context/virtual-drive/folders/application/Offline/OfflineFolderCreator.ts @@ -1,3 +1,4 @@ +import Logger from 'electron-log'; import { FolderPath } from '../../domain/FolderPath'; import { OfflineFolder } from '../../domain/OfflineFolder'; import { OfflineFolderRepository } from '../../domain/OfflineFolderRepository'; @@ -26,7 +27,11 @@ export class OfflineFolderCreator { const parent = this.folderFinder.run(folderPath.dirname()); - const folder = OfflineFolder.create(folderPath, parent.id); + Logger.debug('[DEBUG IN OFFLINEFOLDERCREATOR STEEP 1]'); + + Logger.debug(parent); + + const folder = OfflineFolder.create(folderPath, parent.id, parent.uuid); this.offlineRepository.update(folder); diff --git a/src/context/virtual-drive/folders/domain/OfflineFolder.ts b/src/context/virtual-drive/folders/domain/OfflineFolder.ts index 3d72c4855..d923b794f 100644 --- a/src/context/virtual-drive/folders/domain/OfflineFolder.ts +++ b/src/context/virtual-drive/folders/domain/OfflineFolder.ts @@ -8,6 +8,7 @@ import { FolderRenamedDomainEvent } from './events/FolderRenamedDomainEvent'; export type OfflineFolderAttributes = { uuid: string; parentId: number; + parentUuid: string; path: string; updatedAt: string; createdAt: string; @@ -19,6 +20,7 @@ export class OfflineFolder extends AggregateRoot { private _uuid: FolderUuid, private _path: FolderPath, private _parentId: number, + private _parentUuid: FolderUuid, public createdAt: Date, public updatedAt: Date, private _status: FolderStatus @@ -50,6 +52,10 @@ export class OfflineFolder extends AggregateRoot { return this._parentId; } + public get parentUuid() { + return this._parentUuid.value; + } + public get status() { return this._status; } @@ -64,18 +70,27 @@ export class OfflineFolder extends AggregateRoot { new FolderUuid(attributes.uuid), new FolderPath(attributes.path), attributes.parentId, + attributes.parentUuid + ? new FolderUuid(attributes.parentUuid) + : FolderUuid.random(), new Date(attributes.updatedAt), new Date(attributes.createdAt), FolderStatus.fromValue(attributes.status) ); } - static create(path: FolderPath, parentId: number): OfflineFolder { + static create( + path: FolderPath, + parentId: number, + parentUuid: string + ): OfflineFolder { return new OfflineFolder( FolderUuid.random(), path, parentId, + new FolderUuid(parentUuid), new Date(), + new Date(), FolderStatus.Exists ); @@ -83,6 +98,7 @@ export class OfflineFolder extends AggregateRoot { moveTo(destinationFolder: Folder) { this._parentId = destinationFolder.id; + this._parentUuid = new FolderUuid(destinationFolder.uuid); } rename(destination: FolderPath) { @@ -116,6 +132,7 @@ export class OfflineFolder extends AggregateRoot { const attributes: OfflineFolderAttributes = { uuid: this.uuid, parentId: this._parentId, + parentUuid: this._parentUuid.value, path: this._path.value, updatedAt: this.updatedAt.toISOString(), createdAt: this.createdAt.toISOString(), diff --git a/src/context/virtual-drive/folders/domain/file-systems/RemoteFileSystem.ts b/src/context/virtual-drive/folders/domain/file-systems/RemoteFolderSystem.ts similarity index 91% rename from src/context/virtual-drive/folders/domain/file-systems/RemoteFileSystem.ts rename to src/context/virtual-drive/folders/domain/file-systems/RemoteFolderSystem.ts index 613a1d87e..e5cf78417 100644 --- a/src/context/virtual-drive/folders/domain/file-systems/RemoteFileSystem.ts +++ b/src/context/virtual-drive/folders/domain/file-systems/RemoteFolderSystem.ts @@ -2,7 +2,7 @@ import { Folder, FolderAttributes } from '../Folder'; import { FolderStatuses } from '../FolderStatus'; import { OfflineFolder } from '../OfflineFolder'; -export interface RemoteFileSystem { +export interface RemoteFolderSystem { persist(offline: OfflineFolder): Promise; trash(id: Folder['id']): Promise; diff --git a/src/context/virtual-drive/folders/infrastructure/HttpRemoteFileSystem.ts b/src/context/virtual-drive/folders/infrastructure/HttpRemoteFolderSystem.ts similarity index 72% rename from src/context/virtual-drive/folders/infrastructure/HttpRemoteFileSystem.ts rename to src/context/virtual-drive/folders/infrastructure/HttpRemoteFolderSystem.ts index ece8186c6..1e350c13d 100644 --- a/src/context/virtual-drive/folders/infrastructure/HttpRemoteFileSystem.ts +++ b/src/context/virtual-drive/folders/infrastructure/HttpRemoteFolderSystem.ts @@ -4,13 +4,13 @@ import * as uuid from 'uuid'; import { Folder, FolderAttributes } from '../domain/Folder'; import { FolderStatuses } from '../domain/FolderStatus'; import { UpdateFolderNameDTO } from './dtos/UpdateFolderNameDTO'; -import { RemoteFileSystem } from '../domain/file-systems/RemoteFileSystem'; +import { RemoteFolderSystem } from '../domain/file-systems/RemoteFolderSystem'; import { OfflineFolder } from '../domain/OfflineFolder'; import { ServerFolder } from '../../../shared/domain/ServerFolder'; import { CreateFolderDTO } from './dtos/CreateFolderDTO'; import * as Sentry from '@sentry/electron/renderer'; -export class HttpRemoteFileSystem implements RemoteFileSystem { +export class HttpRemoteFolderSystem implements RemoteFolderSystem { public folders: Record = {}; constructor( @@ -57,7 +57,47 @@ export class HttpRemoteFileSystem implements RemoteFileSystem { Sentry.captureException(error); if (axios.isAxiosError(error)) { Logger.error('[Is Axios Error]', error.response?.data); + const existing = await this.existFolder(offline); + return existing.status !== FolderStatuses.EXISTS + ? Promise.reject(error) + : existing; } + + throw error; + } + } + + private async existFolder(offline: OfflineFolder): Promise { + try { + const response = await this.trashClient.get( + `${process.env.NEW_DRIVE_URL}/drive/folders/content/${offline.parentUuid}/folders/existence?plainName=${offline.basename}` + ); + Logger.debug('[FOLDER FILE SYSTEM] Folder already exists', response.data); + + const serverFolder = response.data + .existentFolders[0] as ServerFolder | null; + + if (!serverFolder) { + throw new Error('Folder creation failed, no data returned'); + } + return { + id: serverFolder.id, + uuid: serverFolder.uuid, + parentId: serverFolder.parentId, + updatedAt: serverFolder.updatedAt, + createdAt: serverFolder.createdAt, + path: offline.path.value, + status: serverFolder.removed + ? FolderStatuses.TRASHED + : FolderStatuses.EXISTS, + }; + } catch (error) { + Logger.error('[FOLDER FILE SYSTEM] Error creating folder'); + Sentry.captureException(error); + if (axios.isAxiosError(error)) { + Logger.error('[Is Axios Error]', error.response?.data); + } + throw error; } } diff --git a/src/context/virtual-drive/items/application/Traverser.ts b/src/context/virtual-drive/items/application/Traverser.ts index f8beb3a00..f06927eda 100644 --- a/src/context/virtual-drive/items/application/Traverser.ts +++ b/src/context/virtual-drive/items/application/Traverser.ts @@ -29,6 +29,7 @@ export class Traverser { private readonly decrypt: NameDecrypt, private readonly ipc: SyncEngineIpc, private readonly baseFolderId: number, + private readonly baseFolderUuid: string, private fileStatusesToFilter: Array, private folderStatusesToFilter: Array ) {} @@ -36,12 +37,14 @@ export class Traverser { static existingItems( decrypt: NameDecrypt, ipc: SyncEngineIpc, - baseFolderId: number + baseFolderId: number, + baseFolderUuid: string ): Traverser { return new Traverser( decrypt, ipc, baseFolderId, + baseFolderUuid, [ServerFileStatus.EXISTS], [ServerFolderStatus.EXISTS] ); @@ -50,9 +53,10 @@ export class Traverser { static allItems( decrypt: NameDecrypt, ipc: SyncEngineIpc, - baseFolderId: number + baseFolderId: number, + baseFolderUuid: string ): Traverser { - return new Traverser(decrypt, ipc, baseFolderId, [], []); + return new Traverser(decrypt, ipc, baseFolderId, baseFolderUuid, [], []); } public setFileStatusesToFilter(statuses: Array): void { @@ -64,11 +68,9 @@ export class Traverser { } private createRootFolder(): Folder { - const rootFolderUuid = '43711926-15c2-5ebf-8c24-5099fa9af3c3'; - return Folder.from({ id: this.baseFolderId, - uuid: rootFolderUuid, + uuid: this.baseFolderUuid, parentId: null, updatedAt: new Date().toISOString(), createdAt: new Date().toISOString(), diff --git a/tests/context/virtual-drive/folders/__mocks__/FolderRemoteFileSystemMock.ts b/tests/context/virtual-drive/folders/__mocks__/FolderRemoteFileSystemMock.ts index 4a43211c3..0549e6b1a 100644 --- a/tests/context/virtual-drive/folders/__mocks__/FolderRemoteFileSystemMock.ts +++ b/tests/context/virtual-drive/folders/__mocks__/FolderRemoteFileSystemMock.ts @@ -3,7 +3,7 @@ import { FolderAttributes, } from '../../../../../src/context/virtual-drive/folders/domain/Folder'; import { OfflineFolder } from '../../../../../src/context/virtual-drive/folders/domain/OfflineFolder'; -import { RemoteFileSystem } from '../../../../../src/context/virtual-drive/folders/domain/file-systems/RemoteFileSystem'; +import { RemoteFileSystem } from '../../../../../src/context/virtual-drive/folders/domain/file-systems/RemoteFolderSystem'; export class FolderRemoteFileSystemMock implements RemoteFileSystem { public readonly persistMock = jest.fn(); From 7609c84444bd0d05b0579d1aa470bb88321601f4 Mon Sep 17 00:00:00 2001 From: ArceDanielShok Date: Wed, 4 Sep 2024 13:51:27 -0300 Subject: [PATCH 4/6] update package json --- package.json | 2 +- release/app/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index bad57b139..a571159f4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "internxt-drive", - "version": "2.1.1", + "version": "2.1.2-qa", "author": "Internxt ", "description": "Internxt Drive client UI", "license": "AGPL-3.0", diff --git a/release/app/package.json b/release/app/package.json index 2afbcc492..99a4d10b1 100644 --- a/release/app/package.json +++ b/release/app/package.json @@ -1,6 +1,6 @@ { "name": "internxt-drive", - "version": "2.1.1", + "version": "2.1.2-qa", "description": "Internxt Drive client UI", "main": "./dist/main/main.js", "author": "Internxt ", From 50aa25546de705f5e6de6ba98217453196f66802 Mon Sep 17 00:00:00 2001 From: ArceDanielShok Date: Fri, 6 Sep 2024 13:38:13 -0300 Subject: [PATCH 5/6] Worked on a fix for the download process, resolved the refresh token error, and fixed the logout bug. --- src/apps/main/auth/handlers.ts | 1 + src/apps/main/auth/refresh-token.ts | 12 ++--- .../main/background-processes/sync-engine.ts | 4 ++ src/apps/main/main.ts | 1 - src/apps/main/remote-sync/handlers.ts | 1 + src/apps/main/virtual-root-folder/service.ts | 34 ++++++++------ .../shared/HttpClient/main-process-client.ts | 4 +- src/apps/sync-engine/BindingManager.ts | 17 +++++-- src/apps/sync-engine/index.ts | 8 ++++ .../application/ContentsDownloader.ts | 8 ---- .../NotifyMainProcessHydrationFinished.ts | 47 ++++++++++++------- 11 files changed, 87 insertions(+), 50 deletions(-) diff --git a/src/apps/main/auth/handlers.ts b/src/apps/main/auth/handlers.ts index ff0570ab6..323b19cd2 100644 --- a/src/apps/main/auth/handlers.ts +++ b/src/apps/main/auth/handlers.ts @@ -49,6 +49,7 @@ ipcMain.handle('get-token', () => { export function onUserUnauthorized() { eventBus.emit('USER_WAS_UNAUTHORIZED'); + eventBus.emit('USER_LOGGED_OUT'); logout(); Logger.info('[AUTH] User has been logged out because it was unauthorized'); diff --git a/src/apps/main/auth/refresh-token.ts b/src/apps/main/auth/refresh-token.ts index 8099ee2a6..880d38045 100644 --- a/src/apps/main/auth/refresh-token.ts +++ b/src/apps/main/auth/refresh-token.ts @@ -1,9 +1,6 @@ import Logger from 'electron-log'; -import { - getClient, - getNewTokenClient, -} from '../../shared/HttpClient/main-process-client'; +import { getNewTokenClient } from '../../shared/HttpClient/main-process-client'; import { TokenScheduler } from '../token-scheduler/TokenScheduler'; import { onUserUnauthorized } from './handlers'; import { @@ -14,14 +11,13 @@ import { } from './service'; import axios from 'axios'; -const authorizedClient = getClient(); const newAuthorizedClient = getNewTokenClient(); async function obtainTokens() { try { Logger.debug('[TOKEN] Obtaining new tokens'); - const res = await authorizedClient.get( - `${process.env.API_URL}/user/refresh` + const res = await newAuthorizedClient.get( + `${process.env.NEW_DRIVE_URL}/drive/users/refresh` ); return res.data; @@ -41,6 +37,7 @@ async function refreshToken() { updateCredentials(token, newToken); + Logger.debug('[TOKEN] Refreshed tokens', token, newToken); return [token, newToken]; } @@ -83,5 +80,6 @@ export async function checkUserData(): Promise { rootFolderId: rootFolderMetadata.uuid, }); } + refreshToken(); } } diff --git a/src/apps/main/background-processes/sync-engine.ts b/src/apps/main/background-processes/sync-engine.ts index 358e47ca6..0fab779af 100644 --- a/src/apps/main/background-processes/sync-engine.ts +++ b/src/apps/main/background-processes/sync-engine.ts @@ -5,6 +5,7 @@ import eventBus from '../event-bus'; import nodeSchedule from 'node-schedule'; import * as Sentry from '@sentry/electron/main'; import { checkSyncEngineInProcess } from '../remote-sync/handlers'; +import { clearRootVirtualDrive } from '../virtual-root-folder/service'; let worker: BrowserWindow | null = null; let workerIsRunning = false; @@ -188,6 +189,8 @@ async function stopAndClearSyncEngineWatcher() { Logger.info('[MAIN] WORKER WAS NOT RUNNING'); worker?.destroy(); worker = null; + await clearRootVirtualDrive(); + return; } @@ -229,6 +232,7 @@ async function stopAndClearSyncEngineWatcher() { worker?.destroy(); workerIsRunning = false; worker = null; + await clearRootVirtualDrive(); } } diff --git a/src/apps/main/main.ts b/src/apps/main/main.ts index 2cafa8338..fd8e140a7 100644 --- a/src/apps/main/main.ts +++ b/src/apps/main/main.ts @@ -121,7 +121,6 @@ eventBus.on('USER_LOGGED_IN', async () => { nativeTheme.themeSource = (configStore.get('preferedTheme') || 'system') as Theme; - setTrayStatus('IDLE'); const widget = await getOrCreateWidged(); const tray = getTray(); if (widget && tray) { diff --git a/src/apps/main/remote-sync/handlers.ts b/src/apps/main/remote-sync/handlers.ts index f9dde2927..fc0a33457 100644 --- a/src/apps/main/remote-sync/handlers.ts +++ b/src/apps/main/remote-sync/handlers.ts @@ -203,6 +203,7 @@ eventBus.on('USER_LOGGED_IN', async () => { Logger.info('Received user logged in event'); try { remoteSyncManager.isProcessRunning = true; + setTrayStatus('SYNCING'); const userData = configStore.get('userData'); const lastFilesSyncAt = await remoteSyncManager.getFileCheckpoint(); Logger.info('Last files sync at', lastFilesSyncAt); diff --git a/src/apps/main/virtual-root-folder/service.ts b/src/apps/main/virtual-root-folder/service.ts index 298abf591..c4bcd8399 100644 --- a/src/apps/main/virtual-root-folder/service.ts +++ b/src/apps/main/virtual-root-folder/service.ts @@ -1,3 +1,4 @@ +import Logger from 'electron-log'; import { app, dialog, shell } from 'electron'; import fs from 'fs/promises'; import path from 'path'; @@ -76,26 +77,31 @@ export function getRootVirtualDrive(): string { return configStore.get('syncRoot'); } -export async function setupRootFolder(n = 0): Promise { - setSyncRoot(VIRTUAL_DRIVE_FOLDER); - return; - const folderName = ROOT_FOLDER_NAME; +export async function clearRootVirtualDrive(): Promise { + try { + const syncFolderPath = getRootVirtualDrive(); + + const queue = path.join( + app.getPath('appData'), + 'internxt-drive', + 'queue-manager.json' + ); - const rootFolderName = folderName + (n ? ` (${n})` : ''); - const rootFolderPath = path.join(HOME_FOLDER_PATH, rootFolderName); + await fs.rm(queue, { recursive: true, force: true }); - const notExistsOrIsEmpty = - !(await existsFolder(rootFolderPath)) || - (await isEmptyFolder(rootFolderPath)); + await fs.rm(syncFolderPath, { recursive: true, force: true }); - if (notExistsOrIsEmpty) { - await fs.mkdir(rootFolderPath, { recursive: true }); - setSyncRoot(rootFolderPath); - } else { - return setupRootFolder(n + 1); + Logger.info(`Directory contents cleared: ${syncFolderPath}`); + } catch (err) { + Logger.error('Error clearing root virtual drive', err); } } +export async function setupRootFolder(n = 0): Promise { + setSyncRoot(VIRTUAL_DRIVE_FOLDER); + return; +} + export async function chooseSyncRootWithDialog(): Promise { const result = await dialog.showOpenDialog({ properties: ['openDirectory'] }); if (!result.canceled) { diff --git a/src/apps/shared/HttpClient/main-process-client.ts b/src/apps/shared/HttpClient/main-process-client.ts index cc07d288d..09d1a823e 100644 --- a/src/apps/shared/HttpClient/main-process-client.ts +++ b/src/apps/shared/HttpClient/main-process-client.ts @@ -1,9 +1,11 @@ import { Axios } from 'axios'; -import { onUserUnauthorized } from '../../main/auth/handlers'; import { getHeaders, getNewApiHeaders } from '../../main/auth/service'; import { AuthorizedClients } from './Clients'; import { AuthorizedHttpClient } from './HttpClient'; +import { ipcMain } from 'electron'; + +const onUserUnauthorized = () => ipcMain.emit('user-is-unauthorized'); const headersProvider = () => Promise.resolve(getHeaders(false)); const newHeadersProvider = () => Promise.resolve(getNewApiHeaders()); diff --git a/src/apps/sync-engine/BindingManager.ts b/src/apps/sync-engine/BindingManager.ts index b47a52d53..43d330d18 100644 --- a/src/apps/sync-engine/BindingManager.ts +++ b/src/apps/sync-engine/BindingManager.ts @@ -136,6 +136,7 @@ export class BindingsManager { ) => { try { Logger.debug('[Fetch Data Callback] Donwloading begins'); + const startTime = Date.now(); const path = await this.controllers.downloadFile.execute( contentsId, callback @@ -184,9 +185,19 @@ export class BindingsManager { }); } this.progressBuffer = 0; - await this.controllers.notifyPlaceholderHydrationFinished.execute( - contentsId - ); + // await this.controllers.notifyPlaceholderHydrationFinished.execute( + // contentsId + // ); + + const finishTime = Date.now(); + + ipcRendererSyncEngine.send('FILE_DOWNLOADED', { + name: file.name, + extension: file.type, + nameWithExtension: file.nameWithExtension, + size: file.size, + processInfo: { elapsedTime: finishTime - startTime }, + }); } catch (error) { Logger.error('notify: ', error); Sentry.captureException(error); diff --git a/src/apps/sync-engine/index.ts b/src/apps/sync-engine/index.ts index ab80a7702..99e3f8525 100644 --- a/src/apps/sync-engine/index.ts +++ b/src/apps/sync-engine/index.ts @@ -43,6 +43,14 @@ async function setUp() { icon: iconPath, }); + ipcRenderer.on('USER_LOGGED_OUT', async () => { + bindings.cleanQueue(); + }); + + ipcRenderer.on('CLEAR_QUEUE', async () => { + bindings.cleanQueue(); + }); + ipcRenderer.on('CHECK_SYNC_ENGINE_RESPONSE', async (event) => { Logger.info('[SYNC ENGINE] Checking sync engine response'); const placeholderStatuses = await container.filesCheckerStatusInRoot.run(); diff --git a/src/context/virtual-drive/contents/application/ContentsDownloader.ts b/src/context/virtual-drive/contents/application/ContentsDownloader.ts index f13e2a663..6f204f060 100644 --- a/src/context/virtual-drive/contents/application/ContentsDownloader.ts +++ b/src/context/virtual-drive/contents/application/ContentsDownloader.ts @@ -112,14 +112,6 @@ export class ContentsDownloader { const events = localContents.pullDomainEvents(); await this.eventBus.publish(events); - // this.ipc.send('FILE_DOWNLOADED', { - // name: file.name, - // extension: file.type, - // nameWithExtension: file.nameWithExtension, - // size: file.size, - // processInfo: { elapsedTime: downloader.elapsedTime() }, - // }); - return write; } diff --git a/src/context/virtual-drive/contents/application/NotifyMainProcessHydrationFinished.ts b/src/context/virtual-drive/contents/application/NotifyMainProcessHydrationFinished.ts index faff126b9..01bcd27d7 100644 --- a/src/context/virtual-drive/contents/application/NotifyMainProcessHydrationFinished.ts +++ b/src/context/virtual-drive/contents/application/NotifyMainProcessHydrationFinished.ts @@ -10,25 +10,40 @@ export class NotifyMainProcessHydrationFinished { ) {} async run(contentsId: string) { - const events = await this.eventRepository.search(contentsId); + try { + const events = await this.eventRepository.search(contentsId); - const downloadCompletionEvent = events.find( - (event) => event.eventName === 'contents.downloaded' - ); + const downloadCompletionEvent = events.find( + (event) => event.eventName === 'contents.downloaded' + ); - if (!downloadCompletionEvent) { - Logger.debug('Download completion event not found'); - return; - } + if (!downloadCompletionEvent) { + Logger.debug( + `Download completion event not found for content ID: ${contentsId}` + ); + return; + } - const event = downloadCompletionEvent as ContentsDownloadedDomainEvent; + const event = downloadCompletionEvent as ContentsDownloadedDomainEvent; - this.ipc.send('FILE_DOWNLOADED', { - name: event.name, - extension: event.extension, - nameWithExtension: event.nameWithExtension, - size: event.size, - processInfo: { elapsedTime: event.elapsedTime }, - }); + // Verificar si la conexión sigue activa antes de enviar el mensaje + if (this.ipc) { + this.ipc.send('FILE_DOWNLOADED', { + name: event.name, + extension: event.extension, + nameWithExtension: event.nameWithExtension, + size: event.size, + processInfo: { elapsedTime: event.elapsedTime }, + }); + Logger.info(`Notification sent for file: ${event.nameWithExtension}`); + } else { + Logger.warn('IPC connection is not active or process is not available'); + } + } catch (error) { + Logger.error( + 'Error notifying main process about hydration completion', + error + ); + } } } From 3a4702424ab1c6ce5f72c7dcde02a66608f0e246 Mon Sep 17 00:00:00 2001 From: ArceDanielShok Date: Mon, 9 Sep 2024 09:42:43 -0300 Subject: [PATCH 6/6] fix logout error and update package version --- package.json | 2 +- release/app/package.json | 2 +- src/apps/main/auth/handlers.ts | 6 ++++- src/apps/main/virtual-root-folder/service.ts | 2 +- src/apps/renderer/pages/Widget/Logout.tsx | 6 ++--- src/apps/sync-engine/BindingManager.ts | 26 ++++++++++---------- 6 files changed, 23 insertions(+), 21 deletions(-) diff --git a/package.json b/package.json index a571159f4..db1f5a3ee 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "internxt-drive", - "version": "2.1.2-qa", + "version": "2.1.2", "author": "Internxt ", "description": "Internxt Drive client UI", "license": "AGPL-3.0", diff --git a/release/app/package.json b/release/app/package.json index 99a4d10b1..1b9c48bd8 100644 --- a/release/app/package.json +++ b/release/app/package.json @@ -1,6 +1,6 @@ { "name": "internxt-drive", - "version": "2.1.2-qa", + "version": "2.1.2", "description": "Internxt Drive client UI", "main": "./dist/main/main.js", "author": "Internxt ", diff --git a/src/apps/main/auth/handlers.ts b/src/apps/main/auth/handlers.ts index 323b19cd2..fc6b49d0d 100644 --- a/src/apps/main/auth/handlers.ts +++ b/src/apps/main/auth/handlers.ts @@ -4,7 +4,10 @@ import Logger from 'electron-log'; import { AccessResponse } from '../../renderer/pages/Login/service'; import { applicationOpened } from '../analytics/service'; import eventBus from '../event-bus'; -import { setupRootFolder } from '../virtual-root-folder/service'; +import { + clearRootVirtualDrive, + setupRootFolder, +} from '../virtual-root-folder/service'; import { getWidget } from '../windows/widget'; import { checkUserData, createTokenSchedule } from './refresh-token'; import { @@ -63,6 +66,7 @@ ipcMain.on('user-logged-in', async (_, data: AccessResponse) => { if (!canHisConfigBeRestored(data.user.uuid)) { await setupRootFolder(); } + await await clearRootVirtualDrive(); setIsLoggedIn(true); eventBus.emit('USER_LOGGED_IN'); diff --git a/src/apps/main/virtual-root-folder/service.ts b/src/apps/main/virtual-root-folder/service.ts index c4bcd8399..a4ec53def 100644 --- a/src/apps/main/virtual-root-folder/service.ts +++ b/src/apps/main/virtual-root-folder/service.ts @@ -79,7 +79,7 @@ export function getRootVirtualDrive(): string { export async function clearRootVirtualDrive(): Promise { try { - const syncFolderPath = getRootVirtualDrive(); + const syncFolderPath = configStore.get('syncRoot'); const queue = path.join( app.getPath('appData'), diff --git a/src/apps/renderer/pages/Widget/Logout.tsx b/src/apps/renderer/pages/Widget/Logout.tsx index 561cadd96..d8cffbe99 100644 --- a/src/apps/renderer/pages/Widget/Logout.tsx +++ b/src/apps/renderer/pages/Widget/Logout.tsx @@ -35,10 +35,8 @@ const ModalLogout: React.FC = ({ return syncPending || wasSyncing || existFileUnsync.length > 0; }; - window.electron.updateUnsycFileInSyncEngine().then(() => { - checkSyncPending().then((value) => { - setIsSyncPending(value); - }); + checkSyncPending().then((value) => { + setIsSyncPending(value); }); }, [syncStatus]); diff --git a/src/apps/sync-engine/BindingManager.ts b/src/apps/sync-engine/BindingManager.ts index 43d330d18..c98480b18 100644 --- a/src/apps/sync-engine/BindingManager.ts +++ b/src/apps/sync-engine/BindingManager.ts @@ -424,24 +424,24 @@ export class BindingsManager { async cleanUp() { await VirtualDrive.unregisterSyncRoot(this.paths.root); - const files = await this.container.retrieveAllFiles.run(); - const folders = await this.container.retrieveAllFolders.run(); + // const files = await this.container.retrieveAllFiles.run(); + // const folders = await this.container.retrieveAllFolders.run(); - const items = [...files, ...folders]; + // const items = [...files, ...folders]; - const win32AbsolutePaths = items.map((item) => { - const posixRelativePath = item.path; - // este path es relativo al root y en formato posix + // const win32AbsolutePaths = items.map((item) => { + // const posixRelativePath = item.path; + // // este path es relativo al root y en formato posix - const win32RelativePaths = - PlatformPathConverter.posixToWin(posixRelativePath); + // const win32RelativePaths = + // PlatformPathConverter.posixToWin(posixRelativePath); - return this.container.relativePathToAbsoluteConverter.run( - win32RelativePaths - ); - }); + // return this.container.relativePathToAbsoluteConverter.run( + // win32RelativePaths + // ); + // }); - Logger.debug('win32AbsolutePaths', win32AbsolutePaths); + // Logger.debug('win32AbsolutePaths', win32AbsolutePaths); // find all common string in remainingItems and win32AbsolutePaths // and delete them