diff options
author | Florian Dold <florian@dold.me> | 2024-02-27 17:39:58 +0100 |
---|---|---|
committer | Florian Dold <florian@dold.me> | 2024-02-27 17:40:03 +0100 |
commit | 523280b3862b528512ff93c651bc0d9ed632fbf6 (patch) | |
tree | b99f866db59b572685c8c7215136270e22210ca2 /packages/taler-wallet-core/src/backup/index.ts | |
parent | 3a889c177dd35a114d2c95efd296274cd185ce52 (diff) | |
download | wallet-core-523280b3862b528512ff93c651bc0d9ed632fbf6.tar.xz |
wallet-core: thread through wallet execution context
Diffstat (limited to 'packages/taler-wallet-core/src/backup/index.ts')
-rw-r--r-- | packages/taler-wallet-core/src/backup/index.ts | 117 |
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; } |