From 6e11b69cf5beb25fec1dfdff281877a76bf195a4 Mon Sep 17 00:00:00 2001 From: Florian Dold Date: Mon, 14 Jun 2021 11:21:29 +0200 Subject: allow changing the wallet device ID --- .../src/operations/backup/export.ts | 2 +- .../src/operations/backup/index.ts | 16 ++--- .../src/operations/backup/state.ts | 79 ++++++++++++---------- 3 files changed, 53 insertions(+), 44 deletions(-) (limited to 'packages/taler-wallet-core/src/operations/backup') diff --git a/packages/taler-wallet-core/src/operations/backup/export.ts b/packages/taler-wallet-core/src/operations/backup/export.ts index a6b2ff2a7..8d57ecd80 100644 --- a/packages/taler-wallet-core/src/operations/backup/export.ts +++ b/packages/taler-wallet-core/src/operations/backup/export.ts @@ -53,7 +53,6 @@ import { InternalWalletState } from "../state"; import { provideBackupState, getWalletBackupState, - WALLET_BACKUP_STATE_KEY, } from "./state"; import { Amounts, getTimestampNow } from "@gnu-taler/taler-util"; import { @@ -62,6 +61,7 @@ import { RefundState, AbortStatus, ProposalStatus, + WALLET_BACKUP_STATE_KEY, } from "../../db.js"; import { encodeCrock, stringToBytes, getRandomBytes } from "../../index.js"; import { canonicalizeBaseUrl, canonicalJson } from "@gnu-taler/taler-util"; diff --git a/packages/taler-wallet-core/src/operations/backup/index.ts b/packages/taler-wallet-core/src/operations/backup/index.ts index bb067dfb5..86f1df541 100644 --- a/packages/taler-wallet-core/src/operations/backup/index.ts +++ b/packages/taler-wallet-core/src/operations/backup/index.ts @@ -35,6 +35,8 @@ import { BackupProviderRecord, BackupProviderTerms, ConfigRecord, + WalletBackupConfState, + WALLET_BACKUP_STATE_KEY, } from "../../db.js"; import { checkDbInvariant, checkLogicInvariant } from "../../util/invariants"; import { @@ -85,12 +87,7 @@ import { secretbox, secretbox_open } from "../../crypto/primitives/nacl-fast"; import { checkPaymentByProposalId, confirmPay, preparePayForUri } from "../pay"; import { exportBackup } from "./export"; import { BackupCryptoPrecomputedData, importBackup } from "./import"; -import { - provideBackupState, - WALLET_BACKUP_STATE_KEY, - getWalletBackupState, - WalletBackupConfState, -} from "./state"; +import { provideBackupState, getWalletBackupState } from "./state"; const logger = new Logger("operations/backup.ts"); @@ -720,10 +717,11 @@ async function backupRecoveryTheirs( await ws.db .mktx((x) => ({ config: x.config, backupProviders: x.backupProviders })) .runReadWrite(async (tx) => { - let backupStateEntry: - | ConfigRecord - | undefined = await tx.config.get(WALLET_BACKUP_STATE_KEY); + let backupStateEntry: ConfigRecord | undefined = await tx.config.get( + WALLET_BACKUP_STATE_KEY, + ); checkDbInvariant(!!backupStateEntry); + checkDbInvariant(backupStateEntry.key === WALLET_BACKUP_STATE_KEY); backupStateEntry.value.lastBackupNonce = undefined; backupStateEntry.value.lastBackupTimestamp = undefined; backupStateEntry.value.lastBackupCheckTimestamp = undefined; diff --git a/packages/taler-wallet-core/src/operations/backup/state.ts b/packages/taler-wallet-core/src/operations/backup/state.ts index 226880439..1ab0c027e 100644 --- a/packages/taler-wallet-core/src/operations/backup/state.ts +++ b/packages/taler-wallet-core/src/operations/backup/state.ts @@ -14,50 +14,29 @@ GNU Taler; see the file COPYING. If not, see */ -import { Timestamp } from "@gnu-taler/taler-util"; -import { ConfigRecord, WalletStoresV1 } from "../../db.js"; +import { + ConfigRecord, + WalletBackupConfState, + WalletStoresV1, + WALLET_BACKUP_STATE_KEY, +} from "../../db.js"; import { getRandomBytes, encodeCrock } from "../../index.js"; import { checkDbInvariant } from "../../util/invariants"; import { GetReadOnlyAccess } from "../../util/query.js"; -import { Wallet } from "../../wallet.js"; import { InternalWalletState } from "../state"; -export interface WalletBackupConfState { - deviceId: string; - walletRootPub: string; - walletRootPriv: string; - clocks: { [device_id: string]: number }; - - /** - * Last hash of the canonicalized plain-text backup. - */ - lastBackupPlainHash?: string; - - /** - * Timestamp stored in the last backup. - */ - lastBackupTimestamp?: Timestamp; - - /** - * Last time we tried to do a backup. - */ - lastBackupCheckTimestamp?: Timestamp; - lastBackupNonce?: string; -} - -export const WALLET_BACKUP_STATE_KEY = "walletBackupState"; - export async function provideBackupState( ws: InternalWalletState, ): Promise { - const bs: ConfigRecord | undefined = await ws.db + const bs: ConfigRecord | undefined = await ws.db .mktx((x) => ({ config: x.config, })) .runReadOnly(async (tx) => { - return tx.config.get(WALLET_BACKUP_STATE_KEY); + return await tx.config.get(WALLET_BACKUP_STATE_KEY); }); if (bs) { + checkDbInvariant(bs.key === WALLET_BACKUP_STATE_KEY); return bs.value; } // We need to generate the key outside of the transaction @@ -72,15 +51,14 @@ export async function provideBackupState( config: x.config, })) .runReadWrite(async (tx) => { - let backupStateEntry: - | ConfigRecord - | undefined = await tx.config.get(WALLET_BACKUP_STATE_KEY); + let backupStateEntry: ConfigRecord | undefined = await tx.config.get( + WALLET_BACKUP_STATE_KEY, + ); if (!backupStateEntry) { backupStateEntry = { key: WALLET_BACKUP_STATE_KEY, value: { deviceId, - clocks: { [deviceId]: 1 }, walletRootPub: k.pub, walletRootPriv: k.priv, lastBackupPlainHash: undefined, @@ -88,6 +66,7 @@ export async function provideBackupState( }; await tx.config.put(backupStateEntry); } + checkDbInvariant(backupStateEntry.key === WALLET_BACKUP_STATE_KEY); return backupStateEntry.value; }); } @@ -98,5 +77,37 @@ export async function getWalletBackupState( ): Promise { const bs = await tx.config.get(WALLET_BACKUP_STATE_KEY); checkDbInvariant(!!bs, "wallet backup state should be in DB"); + checkDbInvariant(bs.key === WALLET_BACKUP_STATE_KEY); return bs.value; } + +export async function setWalletDeviceId( + ws: InternalWalletState, + deviceId: string, +): Promise { + await provideBackupState(ws); + await ws.db + .mktx((x) => ({ + config: x.config, + })) + .runReadWrite(async (tx) => { + let backupStateEntry: ConfigRecord | undefined = await tx.config.get( + WALLET_BACKUP_STATE_KEY, + ); + if ( + !backupStateEntry || + backupStateEntry.key !== WALLET_BACKUP_STATE_KEY + ) { + return; + } + backupStateEntry.value.deviceId = deviceId; + await tx.config.put(backupStateEntry); + }); +} + +export async function getWalletDeviceId( + ws: InternalWalletState, +): Promise { + const bs = await provideBackupState(ws); + return bs.deviceId; +} -- cgit v1.2.3