diff --git a/src/script/backup/BackupRepository.ts b/src/script/backup/BackupRepository.ts index e00d421e00e..8c5fb03f5d2 100644 --- a/src/script/backup/BackupRepository.ts +++ b/src/script/backup/BackupRepository.ts @@ -311,7 +311,7 @@ export class BackupRepository { throw new InvalidMetaDataError(); } - await this.verifyMetadata(user, files); + const archiveVersion = await this.verifyMetadata(user, files); const fileDescriptors = Object.entries(files) .filter(([filename]) => filename !== Filename.METADATA) .map(([filename, content]) => { @@ -326,7 +326,7 @@ export class BackupRepository { const nbEntities = fileDescriptors.reduce((acc, {entities}) => acc + entities.length, 0); initCallback(nbEntities); - await this.importHistoryData(fileDescriptors, progressCallback); + await this.importHistoryData(archiveVersion, fileDescriptors, progressCallback); } private async createDecryptedBackup( @@ -357,6 +357,7 @@ export class BackupRepository { } private async importHistoryData( + archiveVersion: number, fileDescriptors: FileDescriptor[], progressCallback: ProgressCallback, ): Promise { @@ -378,7 +379,7 @@ export class BackupRepository { } // Run all the database migrations on the imported data - await this.backupService.runDbSchemaUpdates(); + await this.backupService.runDbSchemaUpdates(archiveVersion); await this.conversationRepository.updateConversations(importedConversations); await this.conversationRepository.initAllLocal1To1Conversations(); @@ -477,15 +478,16 @@ export class BackupRepository { return omit(entity, 'primary_key'); } - private async verifyMetadata(user: User, files: Record): Promise { + private async verifyMetadata(user: User, files: Record): Promise { const rawData = files[Filename.METADATA]; const metaData = new TextDecoder().decode(rawData); const parsedMetaData = JSON.parse(metaData); - this._verifyMetadata(user, parsedMetaData); + const archiveVersion = this._verifyMetadata(user, parsedMetaData); this.logger.log('Validated metadata during history import', files); + return archiveVersion; } - private _verifyMetadata(user: User, archiveMetadata: Metadata): void { + private _verifyMetadata(user: User, archiveMetadata: Metadata): number { const localMetadata = this.createMetaData(user, ''); const isExpectedUserId = archiveMetadata.user_id === localMetadata.user_id; if (!isExpectedUserId) { @@ -500,6 +502,8 @@ export class BackupRepository { const message = `History created from "${archiveMetadata.platform}" device cannot be imported`; throw new IncompatiblePlatformError(message); } + + return archiveMetadata.version; } private mapDecodingError(decodingError: string) { diff --git a/src/script/backup/BackupService.ts b/src/script/backup/BackupService.ts index 1fc2ed8c7e1..1c8e31f8603 100644 --- a/src/script/backup/BackupService.ts +++ b/src/script/backup/BackupService.ts @@ -67,13 +67,13 @@ export class BackupService { ] as const; } - async runDbSchemaUpdates(): Promise { + async runDbSchemaUpdates(archiveVersion: number): Promise { const {db} = this.storageService; if (!db) { this.logger.warn('Database schema will not run because the database is not initialized'); return; } - return db.runDbSchemaUpdates(); + return db.runDbSchemaUpdates(archiveVersion); } /** diff --git a/src/script/storage/DexieDatabase.ts b/src/script/storage/DexieDatabase.ts index 06340f3eb6c..d04e1425995 100644 --- a/src/script/storage/DexieDatabase.ts +++ b/src/script/storage/DexieDatabase.ts @@ -75,9 +75,10 @@ export class DexieDatabase extends Dexie { }); }; - public readonly runDbSchemaUpdates = async (): Promise => { + public readonly runDbSchemaUpdates = async (archiveVersion: number): Promise => { for (const {upgrade, version} of StorageSchemata.SCHEMATA) { - if (upgrade) { + // If the archive version is greater than the current version, run the upgrade + if (upgrade && version > archiveVersion) { await this.transaction('rw', this.tables, transaction => { this.logger.info(`Running DB schema update for version '${version}'`); upgrade(transaction, this);