summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorian Dold <florian@dold.me>2024-02-19 00:09:09 +0100
committerFlorian Dold <florian@dold.me>2024-02-19 00:09:20 +0100
commitdc2361edb3f401731f2099526ed93a6e963ecc45 (patch)
tree05e625c3a871db60a95cc4689b6a42117a3c7c32
parentb55bf0779946b6a1554a687e05841d131b9951b3 (diff)
downloadwallet-core-dc2361edb3f401731f2099526ed93a6e963ecc45.tar.gz
wallet-core-dc2361edb3f401731f2099526ed93a6e963ecc45.tar.bz2
wallet-core-dc2361edb3f401731f2099526ed93a6e963ecc45.zip
improve error message for templates with currency-only amount
-rw-r--r--packages/taler-util/src/amounts.ts13
-rw-r--r--packages/taler-util/src/taleruri.ts7
-rw-r--r--packages/taler-util/src/wallet-types.ts8
-rw-r--r--packages/taler-wallet-core/src/operations/pay-merchant.ts27
4 files changed, 41 insertions, 14 deletions
diff --git a/packages/taler-util/src/amounts.ts b/packages/taler-util/src/amounts.ts
index c3770a393..16774f376 100644
--- a/packages/taler-util/src/amounts.ts
+++ b/packages/taler-util/src/amounts.ts
@@ -22,12 +22,12 @@
* Imports.
*/
import {
- buildCodecForObject,
- codecForString,
- codecForNumber,
Codec,
Context,
DecodingError,
+ buildCodecForObject,
+ codecForNumber,
+ codecForString,
renderContext,
} from "./codec.js";
import { CurrencySpecification } from "./index.js";
@@ -369,6 +369,13 @@ export class Amounts {
}
/**
+ * Check whether a string is a valid currency for a Taler amount.
+ */
+ static isCurrency(s: string): boolean {
+ return /^[a-zA-Z]{1,11}/.test(s);
+ }
+
+ /**
* Parse an amount like 'EUR:20.5' for 20 Euros and 50 ct.
*
* Currency name size limit is 11 of ASCII letters
diff --git a/packages/taler-util/src/taleruri.ts b/packages/taler-util/src/taleruri.ts
index 22846c7a4..db21f0ad6 100644
--- a/packages/taler-util/src/taleruri.ts
+++ b/packages/taler-util/src/taleruri.ts
@@ -75,11 +75,16 @@ export interface PayUriResult {
noncePriv?: string;
}
+export type TemplateParams = {
+ amount?: string;
+ summary?: string;
+}
+
export interface PayTemplateUriResult {
type: TalerUriAction.PayTemplate;
merchantBaseUrl: string;
templateId: string;
- templateParams: Record<string, string>;
+ templateParams: TemplateParams;
}
export interface WithdrawUriResult {
diff --git a/packages/taler-util/src/wallet-types.ts b/packages/taler-util/src/wallet-types.ts
index e6a66ac9d..4e3e8ac30 100644
--- a/packages/taler-util/src/wallet-types.ts
+++ b/packages/taler-util/src/wallet-types.ts
@@ -46,7 +46,11 @@ import {
codecOptional,
renderContext,
} from "./codec.js";
-import { CurrencySpecification, WithdrawalOperationStatus } from "./index.js";
+import {
+ CurrencySpecification,
+ TemplateParams,
+ WithdrawalOperationStatus,
+} from "./index.js";
import { VersionMatchResult } from "./libtool-version.js";
import { PaytoUri } from "./payto.js";
import { AgeCommitmentProof } from "./taler-crypto.js";
@@ -1927,7 +1931,7 @@ export const codecForSharePaymentResult = (): Codec<SharePaymentResult> =>
export interface PreparePayTemplateRequest {
talerPayTemplateUri: string;
- templateParams?: Record<string, string>;
+ templateParams?: TemplateParams;
}
export const codecForPreparePayTemplateRequest =
diff --git a/packages/taler-wallet-core/src/operations/pay-merchant.ts b/packages/taler-wallet-core/src/operations/pay-merchant.ts
index 63bef3add..1039ac95e 100644
--- a/packages/taler-wallet-core/src/operations/pay-merchant.ts
+++ b/packages/taler-wallet-core/src/operations/pay-merchant.ts
@@ -640,7 +640,8 @@ async function processDownloadProposal(
if (proposal.purchaseStatus != PurchaseStatus.PendingDownloadingProposal) {
logger.error(
- `unexpected state ${proposal.purchaseStatus}/${PurchaseStatus[proposal.purchaseStatus]
+ `unexpected state ${proposal.purchaseStatus}/${
+ PurchaseStatus[proposal.purchaseStatus]
} for ${ctx.transactionId} in processDownloadProposal`,
);
return TaskRunResult.finished();
@@ -899,7 +900,8 @@ async function createOrReusePurchase(
oldProposal.claimToken === claimToken
) {
logger.info(
- `Found old proposal (status=${PurchaseStatus[oldProposal.purchaseStatus]
+ `Found old proposal (status=${
+ PurchaseStatus[oldProposal.purchaseStatus]
}) for order ${orderId} at ${merchantBaseUrl}`,
);
if (oldProposal.purchaseStatus === PurchaseStatus.DialogShared) {
@@ -1567,12 +1569,21 @@ export async function preparePayForTemplate(
throw Error("invalid taler-template URI");
}
logger.trace(`parsed URI: ${j2s(parsedUri)}`);
- if (
- parsedUri.templateParams.amount !== undefined &&
- typeof parsedUri.templateParams.amount === "string"
- ) {
- templateDetails.amount = (req.templateParams?.amount ??
- parsedUri.templateParams.amount) as AmountString | undefined;
+
+ const amountFromUri = parsedUri.templateParams.amount;
+ if (amountFromUri != null) {
+ const templateParamsAmount = req.templateParams?.amount;
+ if (templateParamsAmount != null) {
+ templateDetails.amount = templateParamsAmount as AmountString;
+ } else {
+ if (Amounts.isCurrency(amountFromUri)) {
+ throw Error(
+ "Amount from template URI only has a currency without value. The value must be provided in the templateParams.",
+ );
+ } else {
+ templateDetails.amount = amountFromUri as AmountString;
+ }
+ }
}
if (
parsedUri.templateParams.summary !== undefined &&