commit 43858fc6c67cc0c602e59c54377e3cb06ced27b4
parent 0aa8254d84d35ed8945724153340c036ceaf6e76
Author: Florian Dold <dold@taler.net>
Date: Wed, 22 Jul 2026 20:44:08 +0200
util: validate the donau donation units instead of accepting anything
Diffstat:
1 file changed, 41 insertions(+), 19 deletions(-)
diff --git a/packages/taler-util/src/types-donau.ts b/packages/taler-util/src/types-donau.ts
@@ -22,10 +22,12 @@ import {
buildCodecForUnion,
Codec,
codecForAny,
+ codecForBoolean,
codecForConstString,
codecForList,
codecForNumber,
codecForString,
+ codecOptional,
} from "./codec.js";
import { codecForTimestamp, TalerProtocolTimestamp } from "./time.js";
import {
@@ -121,9 +123,9 @@ export interface DonauKeysResponse {
signkeys: DonauSignKeyJson[];
}
-export type DonationUnitKeyGroup =
- | DonationUnitKeyGroupRsa
- | DonationUnitKeyGroupCs;
+export interface DonationUnitKeyGroup extends DonationUnitKeyGroupCommon {
+ donation_unit_pub: DonationUnitPub;
+}
export interface DonationUnitKeyGroupCommon {
// How much are coins of this denomination worth?
@@ -157,19 +159,16 @@ export type DonationUnitPub =
cs_public_key: Cs25519Point;
};
-export interface DonationUnitKeyGroupRsa extends DonationUnitKeyGroupCommon {
- donation_unit_pub: {
- cipher: "RSA";
- rsa_public_key: RsaPublicKeyString;
- };
-}
+export type DonationUnitPubRsa = Extract<DonationUnitPub, { cipher: "RSA" }>;
+export type DonationUnitPubCs = Extract<DonationUnitPub, { cipher: "CS" }>;
-export interface DonationUnitKeyGroupCs extends DonationUnitKeyGroupCommon {
- donation_unit_pub: {
- cipher: "CS";
- cs_public_key: Cs25519Point;
- };
-}
+export type DonationUnitKeyGroupRsa = DonationUnitKeyGroupCommon & {
+ donation_unit_pub: DonationUnitPubRsa;
+};
+
+export type DonationUnitKeyGroupCs = DonationUnitKeyGroupCommon & {
+ donation_unit_pub: DonationUnitPubCs;
+};
/**
* Hash of a donation unit public key, as the donau computes it: the hash of
@@ -186,9 +185,32 @@ export function hashDonationUnitPub(pub: DonationUnitPub): HashCodeString {
}
}
-// FIXME: Validate properly!
-export const codecForDonationUnitKeyGroup: Codec<DonationUnitKeyGroup> =
- codecForAny();
+export const codecForDonationUnitPubRsa = (): Codec<DonationUnitPubRsa> =>
+ buildCodecForObject<DonationUnitPubRsa>()
+ .property("cipher", codecForConstString("RSA"))
+ .property("rsa_public_key", codecForString())
+ .build("DonationUnitPub.RSA");
+
+export const codecForDonationUnitPubCs = (): Codec<DonationUnitPubCs> =>
+ buildCodecForObject<DonationUnitPubCs>()
+ .property("cipher", codecForConstString("CS"))
+ .property("cs_public_key", codecForString())
+ .build("DonationUnitPub.CS");
+
+export const codecForDonationUnitPub = (): Codec<DonationUnitPub> =>
+ buildCodecForUnion<DonationUnitPub>()
+ .discriminateOn("cipher")
+ .alternative("RSA", codecForDonationUnitPubRsa())
+ .alternative("CS", codecForDonationUnitPubCs())
+ .build("DonationUnitPub");
+
+export const codecForDonationUnitKeyGroup = (): Codec<DonationUnitKeyGroup> =>
+ buildCodecForObject<DonationUnitKeyGroup>()
+ .property("donation_unit_pub", codecForDonationUnitPub())
+ .property("value", codecForAmountString())
+ .property("year", codecForNumber())
+ .property("lost", codecOptional(codecForBoolean()))
+ .build("DonationUnitKeyGroup");
export const codecForDonauKeysResponse = (): Codec<DonauKeysResponse> =>
buildCodecForObject<DonauKeysResponse>()
@@ -197,7 +219,7 @@ export const codecForDonauKeysResponse = (): Codec<DonauKeysResponse> =>
.property("currency", codecForString())
//.property("domain", codecForString())
.property("signkeys", codecForAny())
- .property("donation_units", codecForList(codecForDonationUnitKeyGroup))
+ .property("donation_units", codecForList(codecForDonationUnitKeyGroup()))
//.property("currency_fraction_digits", codecForNumber())
.build("DonauApi.DonauKeysResponse");