From 6fc9a052b7f8e3ef0bd1b26279b11dc6bc12f5e4 Mon Sep 17 00:00:00 2001 From: Florian Dold Date: Thu, 20 May 2021 16:24:41 +0200 Subject: implement deletion of withdrawal transactions --- .../src/operations/transactions.ts | 55 +++++++++++++++++++++- 1 file changed, 54 insertions(+), 1 deletion(-) (limited to 'packages/taler-wallet-core/src/operations') diff --git a/packages/taler-wallet-core/src/operations/transactions.ts b/packages/taler-wallet-core/src/operations/transactions.ts index dcd3ddbd9..48d0ffec5 100644 --- a/packages/taler-wallet-core/src/operations/transactions.ts +++ b/packages/taler-wallet-core/src/operations/transactions.ts @@ -24,6 +24,7 @@ import { RefundState, ReserveRecordStatus, AbortStatus, + ReserveRecord, } from "../db.js"; import { AmountJson, Amounts, timestampCmp } from "@gnu-taler/taler-util"; import { @@ -42,7 +43,7 @@ import { getFundingPaytoUris } from "./reserves"; * Create an event ID from the type and the primary key for the event. */ function makeEventId(type: TransactionType, ...args: string[]): string { - return type + ";" + args.map((x) => encodeURIComponent(x)).join(";"); + return type + ":" + args.map((x) => encodeURIComponent(x)).join(":"); } function shouldSkipCurrency( @@ -365,3 +366,55 @@ export async function getTransactions( return { transactions: [...txNotPending, ...txPending] }; } + +export enum TombstoneTag { + WithdrawalGroup = "withdrawal-group", + Reserve = "reserve", +} + +/** + * Permanentely delete a transaction based on the transaction ID. + */ +export async function deleteTransaction( + ws: InternalWalletState, + transactionId: string, +): Promise { + const [type, ...rest] = transactionId.split(":"); + + if (type === TransactionType.Withdrawal) { + const withdrawalGroupId = rest[0]; + ws.db.runWithWriteTransaction( + [Stores.withdrawalGroups, Stores.reserves, Stores.tombstones], + async (tx) => { + const withdrawalGroupRecord = await tx.get( + Stores.withdrawalGroups, + withdrawalGroupId, + ); + if (withdrawalGroupRecord) { + await tx.delete(Stores.withdrawalGroups, withdrawalGroupId); + await tx.put(Stores.tombstones, { + id: TombstoneTag.WithdrawalGroup + ":" + withdrawalGroupId, + }); + return; + } + const reserveRecord: ReserveRecord | undefined = await tx.getIndexed( + Stores.reserves.byInitialWithdrawalGroupId, + withdrawalGroupId, + ); + if (reserveRecord && !reserveRecord.initialWithdrawalStarted) { + const reservePub = reserveRecord.reservePub; + await tx.delete(Stores.reserves, reservePub); + await tx.put(Stores.tombstones, { + id: TombstoneTag.Reserve + ":" + reservePub, + }); + } + }, + ); + } else if (type === TransactionType.Refund) { + // To delete refund transactions, the whole + // purchase should be deleted. + throw Error("refunds cannot be deleted"); + } else { + throw Error(`can't delete a '${type}' transaction`); + } +} -- cgit v1.2.3