Skip to content

Commit

Permalink
🐛 (api) fix performing api operations for local e2e encrypted files (a…
Browse files Browse the repository at this point in the history
  • Loading branch information
MatissJanis authored and MikesGlitch committed May 15, 2024
1 parent 5b1d8cc commit de9b1d1
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 24 deletions.
65 changes: 41 additions & 24 deletions packages/loot-core/src/server/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -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');
Expand All @@ -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 () {
Expand Down
3 changes: 3 additions & 0 deletions packages/loot-core/src/server/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
1 change: 1 addition & 0 deletions packages/loot-core/src/types/budget.d.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
export type Budget = {
id: string;
cloudFileId?: string;
encryptKeyId?: string;
groupId?: string;
name: string;
};
6 changes: 6 additions & 0 deletions upcoming-release-notes/2698.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
category: Bugfix
authors: [MatissJanis]
---

Fix API remote-server sync for budget files that are e2e encrypted.

0 comments on commit de9b1d1

Please sign in to comment.