summaryrefslogtreecommitdiff
path: root/packages/taler-wallet-core/src/backup/index.ts
diff options
context:
space:
mode:
Diffstat (limited to 'packages/taler-wallet-core/src/backup/index.ts')
-rw-r--r--packages/taler-wallet-core/src/backup/index.ts117
1 files changed, 60 insertions, 57 deletions
diff --git a/packages/taler-wallet-core/src/backup/index.ts b/packages/taler-wallet-core/src/backup/index.ts
index a5d7eee80..04c53526d 100644
--- a/packages/taler-wallet-core/src/backup/index.ts
+++ b/packages/taler-wallet-core/src/backup/index.ts
@@ -90,7 +90,7 @@ import {
timestampPreciseToDb,
} from "../db.js";
import { preparePayForUri } from "../pay-merchant.js";
-import { InternalWalletState } from "../wallet.js";
+import { InternalWalletState, WalletExecutionContext } from "../wallet.js";
const logger = new Logger("operations/backup.ts");
@@ -179,10 +179,10 @@ function getNextBackupTimestamp(): TalerPreciseTimestamp {
}
async function runBackupCycleForProvider(
- ws: InternalWalletState,
+ wex: WalletExecutionContext,
args: BackupForProviderArgs,
): Promise<TaskRunResult> {
- const provider = await ws.db.runReadOnlyTx(
+ const provider = await wex.db.runReadOnlyTx(
["backupProviders"],
async (tx) => {
return tx.backupProviders.get(args.backupProviderBaseUrl);
@@ -197,7 +197,7 @@ async function runBackupCycleForProvider(
//const backupJson = await exportBackup(ws);
// FIXME: re-implement backup
const backupJson = {};
- const backupConfig = await provideBackupState(ws);
+ const backupConfig = await provideBackupState(wex);
const encBackup = await encryptBackup(backupConfig, backupJson);
const currentBackupHash = hash(encBackup);
@@ -209,7 +209,7 @@ async function runBackupCycleForProvider(
logger.trace(`trying to upload backup to ${provider.baseUrl}`);
logger.trace(`old hash ${oldHash}, new hash ${newHash}`);
- const syncSigResp = await ws.cryptoApi.makeSyncSignature({
+ const syncSigResp = await wex.cryptoApi.makeSyncSignature({
newHash: encodeCrock(currentBackupHash),
oldHash: provider.lastBackupHash,
accountPriv: encodeCrock(accountKeyPair.eddsaPriv),
@@ -226,7 +226,7 @@ async function runBackupCycleForProvider(
accountBackupUrl.searchParams.set("fresh", "yes");
}
- const resp = await ws.http.fetch(accountBackupUrl.href, {
+ const resp = await wex.http.fetch(accountBackupUrl.href, {
method: "POST",
body: encBackup,
headers: {
@@ -244,7 +244,7 @@ async function runBackupCycleForProvider(
logger.trace(`sync response status: ${resp.status}`);
if (resp.status === HttpStatusCode.NotModified) {
- await ws.db.runReadWriteTx(["backupProviders"], async (tx) => {
+ await wex.db.runReadWriteTx(["backupProviders"], async (tx) => {
const prov = await tx.backupProviders.get(provider.baseUrl);
if (!prov) {
return;
@@ -259,7 +259,7 @@ async function runBackupCycleForProvider(
await tx.backupProviders.put(prov);
});
- removeAttentionRequest(ws, {
+ removeAttentionRequest(wex, {
entityId: provider.baseUrl,
type: AttentionType.BackupUnpaid,
});
@@ -279,7 +279,7 @@ async function runBackupCycleForProvider(
//FIXME: check download errors
let res: PreparePayResult | undefined = undefined;
try {
- res = await preparePayForUri(ws, talerUri);
+ res = await preparePayForUri(wex, talerUri);
} catch (e) {
const error = TalerError.fromException(e);
if (!error.hasErrorCode(TalerErrorCode.WALLET_ORDER_ALREADY_CLAIMED)) {
@@ -290,7 +290,7 @@ async function runBackupCycleForProvider(
if (res === undefined) {
//claimed
- await ws.db.runReadWriteTx(["backupProviders"], async (tx) => {
+ await wex.db.runReadWriteTx(["backupProviders"], async (tx) => {
const prov = await tx.backupProviders.get(provider.baseUrl);
if (!prov) {
logger.warn("backup provider not found anymore");
@@ -310,7 +310,7 @@ async function runBackupCycleForProvider(
}
const result = res;
- await ws.db.runReadWriteTx(["backupProviders"], async (tx) => {
+ await wex.db.runReadWriteTx(["backupProviders"], async (tx) => {
const prov = await tx.backupProviders.get(provider.baseUrl);
if (!prov) {
logger.warn("backup provider not found anymore");
@@ -327,7 +327,7 @@ async function runBackupCycleForProvider(
});
addAttentionRequest(
- ws,
+ wex,
{
type: AttentionType.BackupUnpaid,
provider_base_url: provider.baseUrl,
@@ -343,7 +343,7 @@ async function runBackupCycleForProvider(
}
if (resp.status === HttpStatusCode.NoContent) {
- await ws.db.runReadWriteTx(["backupProviders"], async (tx) => {
+ await wex.db.runReadWriteTx(["backupProviders"], async (tx) => {
const prov = await tx.backupProviders.get(provider.baseUrl);
if (!prov) {
return;
@@ -359,7 +359,7 @@ async function runBackupCycleForProvider(
await tx.backupProviders.put(prov);
});
- removeAttentionRequest(ws, {
+ removeAttentionRequest(wex, {
entityId: provider.baseUrl,
type: AttentionType.BackupUnpaid,
});
@@ -372,11 +372,11 @@ async function runBackupCycleForProvider(
if (resp.status === HttpStatusCode.Conflict) {
logger.info("conflicting backup found");
const backupEnc = new Uint8Array(await resp.bytes());
- const backupConfig = await provideBackupState(ws);
+ const backupConfig = await provideBackupState(wex);
// const blob = await decryptBackup(backupConfig, backupEnc);
// FIXME: Re-implement backup import with merging
// await importBackup(ws, blob, cryptoData);
- await ws.db.runReadWriteTx(["backupProviders"], async (tx) => {
+ await wex.db.runReadWriteTx(["backupProviders"], async (tx) => {
const prov = await tx.backupProviders.get(provider.baseUrl);
if (!prov) {
logger.warn("backup provider not found anymore");
@@ -394,7 +394,7 @@ async function runBackupCycleForProvider(
});
logger.info("processed existing backup");
// Now upload our own, merged backup.
- return await runBackupCycleForProvider(ws, args);
+ return await runBackupCycleForProvider(wex, args);
}
// Some other response that we did not expect!
@@ -410,10 +410,10 @@ async function runBackupCycleForProvider(
}
export async function processBackupForProvider(
- ws: InternalWalletState,
+ wex: WalletExecutionContext,
backupProviderBaseUrl: string,
): Promise<TaskRunResult> {
- const provider = await ws.db.runReadOnlyTx(
+ const provider = await wex.db.runReadOnlyTx(
["backupProviders"],
async (tx) => {
return await tx.backupProviders.get(backupProviderBaseUrl);
@@ -425,7 +425,7 @@ export async function processBackupForProvider(
logger.info(`running backup for provider ${backupProviderBaseUrl}`);
- return await runBackupCycleForProvider(ws, {
+ return await runBackupCycleForProvider(wex, {
backupProviderBaseUrl: provider.baseUrl,
});
}
@@ -441,10 +441,10 @@ export const codecForRemoveBackupProvider =
.build("RemoveBackupProviderRequest");
export async function removeBackupProvider(
- ws: InternalWalletState,
+ wex: WalletExecutionContext,
req: RemoveBackupProviderRequest,
): Promise<void> {
- await ws.db.runReadWriteTx(["backupProviders"], async (tx) => {
+ await wex.db.runReadWriteTx(["backupProviders"], async (tx) => {
await tx.backupProviders.delete(req.provider);
});
}
@@ -469,10 +469,10 @@ export const codecForRunBackupCycle = (): Codec<RunBackupCycleRequest> =>
* 3. Upload the updated backup blob.
*/
export async function runBackupCycle(
- ws: InternalWalletState,
+ wex: WalletExecutionContext,
req: RunBackupCycleRequest,
): Promise<void> {
- const providers = await ws.db.runReadOnlyTx(
+ const providers = await wex.db.runReadOnlyTx(
["backupProviders"],
async (tx) => {
if (req.providers) {
@@ -486,7 +486,7 @@ export async function runBackupCycle(
);
for (const provider of providers) {
- await runBackupCycleForProvider(ws, {
+ await runBackupCycleForProvider(wex, {
backupProviderBaseUrl: provider.baseUrl,
});
}
@@ -547,13 +547,13 @@ export const codecForAddBackupProviderResponse =
.build("AddBackupProviderResponse");
export async function addBackupProvider(
- ws: InternalWalletState,
+ wex: WalletExecutionContext,
req: AddBackupProviderRequest,
): Promise<AddBackupProviderResponse> {
logger.info(`adding backup provider ${j2s(req)}`);
- await provideBackupState(ws);
+ await provideBackupState(wex);
const canonUrl = canonicalizeBaseUrl(req.backupProviderBaseUrl);
- await ws.db.runReadWriteTx(["backupProviders"], async (tx) => {
+ await wex.db.runReadWriteTx(["backupProviders"], async (tx) => {
const oldProv = await tx.backupProviders.get(canonUrl);
if (oldProv) {
logger.info("old backup provider found");
@@ -571,12 +571,12 @@ export async function addBackupProvider(
}
});
const termsUrl = new URL("config", canonUrl);
- const resp = await ws.http.fetch(termsUrl.href);
+ const resp = await wex.http.fetch(termsUrl.href);
const terms = await readSuccessResponseJsonOrThrow(
resp,
codecForSyncTermsOfServiceResponse(),
);
- await ws.db.runReadWriteTx(["backupProviders"], async (tx) => {
+ await wex.db.runReadWriteTx(["backupProviders"], async (tx) => {
let state: BackupProviderState;
//FIXME: what is the difference provisional and ready?
if (req.activate) {
@@ -604,13 +604,13 @@ export async function addBackupProvider(
});
});
- return await runFirstBackupCycleForProvider(ws, {
+ return await runFirstBackupCycleForProvider(wex, {
backupProviderBaseUrl: canonUrl,
});
}
async function runFirstBackupCycleForProvider(
- ws: InternalWalletState,
+ wex: WalletExecutionContext,
args: BackupForProviderArgs,
): Promise<AddBackupProviderResponse> {
throw Error("not implemented");
@@ -647,7 +647,7 @@ export interface BackupInfo {
}
async function getProviderPaymentInfo(
- ws: InternalWalletState,
+ wex: WalletExecutionContext,
provider: BackupProviderRecord,
): Promise<ProviderPaymentStatus> {
throw Error("not implemented");
@@ -702,10 +702,10 @@ async function getProviderPaymentInfo(
* Get information about the current state of wallet backups.
*/
export async function getBackupInfo(
- ws: InternalWalletState,
+ wex: WalletExecutionContext,
): Promise<BackupInfo> {
- const backupConfig = await provideBackupState(ws);
- const providerRecords = await ws.db.runReadOnlyTx(
+ const backupConfig = await provideBackupState(wex);
+ const providerRecords = await wex.db.runReadOnlyTx(
["backupProviders", "operationRetries"],
async (tx) => {
return await tx.backupProviders.iter().mapAsync(async (bp) => {
@@ -731,7 +731,7 @@ export async function getBackupInfo(
x.provider.state.tag === BackupProviderStateTag.Retrying
? x.retryRecord?.lastError
: undefined,
- paymentStatus: await getProviderPaymentInfo(ws, x.provider),
+ paymentStatus: await getProviderPaymentInfo(wex, x.provider),
terms: x.provider.terms,
name: x.provider.name,
});
@@ -748,10 +748,10 @@ export async function getBackupInfo(
* private key.
*/
export async function getBackupRecovery(
- ws: InternalWalletState,
+ wex: WalletExecutionContext,
): Promise<BackupRecovery> {
- const bs = await provideBackupState(ws);
- const providers = await ws.db.runReadOnlyTx(
+ const bs = await provideBackupState(wex);
+ const providers = await wex.db.runReadOnlyTx(
["backupProviders"],
async (tx) => {
return await tx.backupProviders.iter().toArray();
@@ -771,10 +771,10 @@ export async function getBackupRecovery(
}
async function backupRecoveryTheirs(
- ws: InternalWalletState,
+ wex: WalletExecutionContext,
br: BackupRecovery,
) {
- await ws.db.runReadWriteTx(["backupProviders", "config"], async (tx) => {
+ await wex.db.runReadWriteTx(["backupProviders", "config"], async (tx) => {
let backupStateEntry: ConfigRecord | undefined = await tx.config.get(
ConfigRecordKey.WalletBackupState,
);
@@ -818,16 +818,19 @@ async function backupRecoveryTheirs(
});
}
-async function backupRecoveryOurs(ws: InternalWalletState, br: BackupRecovery) {
+async function backupRecoveryOurs(
+ wex: WalletExecutionContext,
+ br: BackupRecovery,
+) {
throw Error("not implemented");
}
export async function loadBackupRecovery(
- ws: InternalWalletState,
+ wex: WalletExecutionContext,
br: RecoveryLoadRequest,
): Promise<void> {
- const bs = await provideBackupState(ws);
- const providers = await ws.db.runReadOnlyTx(
+ const bs = await provideBackupState(wex);
+ const providers = await wex.db.runReadOnlyTx(
["backupProviders"],
async (tx) => {
return await tx.backupProviders.iter().toArray();
@@ -847,9 +850,9 @@ export async function loadBackupRecovery(
strategy = RecoveryMergeStrategy.Theirs;
}
if (strategy === RecoveryMergeStrategy.Theirs) {
- return backupRecoveryTheirs(ws, br.recovery);
+ return backupRecoveryTheirs(wex, br.recovery);
} else {
- return backupRecoveryOurs(ws, br.recovery);
+ return backupRecoveryOurs(wex, br.recovery);
}
}
@@ -873,9 +876,9 @@ export async function decryptBackup(
}
export async function provideBackupState(
- ws: InternalWalletState,
+ wex: WalletExecutionContext,
): Promise<WalletBackupConfState> {
- const bs: ConfigRecord | undefined = await ws.db.runReadOnlyTx(
+ const bs: ConfigRecord | undefined = await wex.db.runReadOnlyTx(
["config"],
async (tx) => {
return await tx.config.get(ConfigRecordKey.WalletBackupState);
@@ -887,12 +890,12 @@ export async function provideBackupState(
}
// We need to generate the key outside of the transaction
// due to how IndexedDB works.
- const k = await ws.cryptoApi.createEddsaKeypair({});
+ const k = await wex.cryptoApi.createEddsaKeypair({});
const d = getRandomBytes(5);
// FIXME: device ID should be configured when wallet is initialized
// and be based on hostname
const deviceId = `wallet-core-${encodeCrock(d)}`;
- return await ws.db.runReadWriteTx(["config"], async (tx) => {
+ return await wex.db.runReadWriteTx(["config"], async (tx) => {
let backupStateEntry: ConfigRecord | undefined = await tx.config.get(
ConfigRecordKey.WalletBackupState,
);
@@ -926,11 +929,11 @@ export async function getWalletBackupState(
}
export async function setWalletDeviceId(
- ws: InternalWalletState,
+ wex: WalletExecutionContext,
deviceId: string,
): Promise<void> {
- await provideBackupState(ws);
- await ws.db.runReadWriteTx(["config"], async (tx) => {
+ await provideBackupState(wex);
+ await wex.db.runReadWriteTx(["config"], async (tx) => {
let backupStateEntry: ConfigRecord | undefined = await tx.config.get(
ConfigRecordKey.WalletBackupState,
);
@@ -946,8 +949,8 @@ export async function setWalletDeviceId(
}
export async function getWalletDeviceId(
- ws: InternalWalletState,
+ wex: WalletExecutionContext,
): Promise<string> {
- const bs = await provideBackupState(ws);
+ const bs = await provideBackupState(wex);
return bs.deviceId;
}