diff --git a/packages/loot-core/src/server/api.ts b/packages/loot-core/src/server/api.ts index d66c5071d5dd7058096823a69dfcfffc502f02d8..93457027fd51cc22667bdb98067ee6fd46d190e6 100644 --- a/packages/loot-core/src/server/api.ts +++ b/packages/loot-core/src/server/api.ts @@ -27,6 +27,7 @@ import { } from './api-models'; import { runQuery as aqlQuery } from './aql'; import * as cloudStorage from './cloud-storage'; +import { type RemoteFile } from './cloud-storage'; import * as db from './db'; import { APIError } from './errors'; import { runMutator } from './mutators'; @@ -164,16 +165,12 @@ handlers['api/download-budget'] = async function ({ syncId, password }) { await handlers['close-budget'](); } - const localBudget = (await handlers['get-budgets']()).find( - b => b.groupId === syncId, - ); - if (localBudget) { - await handlers['load-budget']({ id: localBudget.id }); - const result = await handlers['sync-budget'](); - if (result.error) { - throw new Error(getSyncError(result.error, localBudget.id)); - } - } else { + const budgets = await handlers['get-budgets'](); + const localBudget = budgets.find(b => b.groupId === syncId); + let remoteBudget: RemoteFile; + + // Load a remote file if we could not find the file locally + if (!localBudget) { const files = await handlers['get-remote-files'](); if (!files) { throw new Error('Could not get remote files'); @@ -184,28 +181,48 @@ handlers['api/download-budget'] = async function ({ syncId, password }) { `Budget “${syncId}†not found. Check the sync id of your budget in the Advanced section of the settings page.`, ); } - if (file.encryptKeyId && !password) { + + remoteBudget = file; + } + + const activeFile = remoteBudget ? remoteBudget : localBudget; + + // Set the e2e encryption keys + if (activeFile.encryptKeyId) { + if (!password) { throw new Error( - `File ${file.name} is encrypted. Please provide a password.`, + `File ${activeFile.name} is encrypted. Please provide a password.`, ); } - if (password) { - const result = await handlers['key-test']({ - fileId: file.fileId, - password, - }); - if (result.error) { - throw new Error(getTestKeyError(result.error)); - } + + const result = await handlers['key-test']({ + fileId: remoteBudget ? remoteBudget.fileId : localBudget.cloudFileId, + password, + }); + if (result.error) { + throw new Error(getTestKeyError(result.error)); } + } - const result = await handlers['download-budget']({ fileId: file.fileId }); + // Sync the local budget file + if (localBudget) { + await handlers['load-budget']({ id: localBudget.id }); + const result = await handlers['sync-budget'](); if (result.error) { - console.log('Full error details', result.error); - throw new Error(getDownloadError(result.error)); + throw new Error(getSyncError(result.error, localBudget.id)); } - await handlers['load-budget']({ id: result.id }); + return; + } + + // Download the remote file (no need to perform a sync as the file will already be up-to-date) + const result = await handlers['download-budget']({ + fileId: remoteBudget.fileId, + }); + if (result.error) { + console.log('Full error details', result.error); + throw new Error(getDownloadError(result.error)); } + await handlers['load-budget']({ id: result.id }); }; handlers['api/sync'] = async function () { diff --git a/packages/loot-core/src/server/main.ts b/packages/loot-core/src/server/main.ts index 01ec57e502d53c2822db1b2ef25a963b87db7933..5b0ee4f93065155b7deb31933ebc91110af0ce90 100644 --- a/packages/loot-core/src/server/main.ts +++ b/packages/loot-core/src/server/main.ts @@ -1592,6 +1592,9 @@ handlers['get-budgets'] = async function () { return { id: name, ...(prefs.cloudFileId ? { cloudFileId: prefs.cloudFileId } : {}), + ...(prefs.encryptKeyId + ? { encryptKeyId: prefs.encryptKeyId } + : {}), ...(prefs.groupId ? { groupId: prefs.groupId } : {}), name: prefs.budgetName || '(no name)', } satisfies Budget; diff --git a/packages/loot-core/src/types/budget.d.ts b/packages/loot-core/src/types/budget.d.ts index f77d9acf5ca5b2490ae39a83bb7758a65c06a871..5d8e394fdb428be6171a4e502e428431bde119d6 100644 --- a/packages/loot-core/src/types/budget.d.ts +++ b/packages/loot-core/src/types/budget.d.ts @@ -1,6 +1,7 @@ export type Budget = { id: string; cloudFileId?: string; + encryptKeyId?: string; groupId?: string; name: string; }; diff --git a/upcoming-release-notes/2698.md b/upcoming-release-notes/2698.md new file mode 100644 index 0000000000000000000000000000000000000000..38b91b665ac308aff383826fc227361c8883bfa9 --- /dev/null +++ b/upcoming-release-notes/2698.md @@ -0,0 +1,6 @@ +--- +category: Bugfix +authors: [MatissJanis] +--- + +Fix API remote-server sync for budget files that are e2e encrypted.