exchange

Base system with REST service to issue digital coins, run by the payment service provider
Log | Files | Refs | Submodules | README | LICENSE

commit 4739d5f7e91cb36b6d884bd942229a104c3a281c
parent 70aac6857983ce6aaf1efff2e4f194f83f7e3525
Author: Florian Dold <dold@taler.net>
Date:   Tue, 28 Jul 2026 12:49:42 +0200

kyclogic: expire SMS/postal rules after the documented validity period

The expiry was taken from the challenger's address validation lifetime, so a
validation that had already aged out produced a rule set that expired before
it was written and the exchange silently reverted to the default rules.

Diffstat:
Msrc/kyclogic/taler-exchange-helper-measure-tops-postal-check | 9++++++++-
Msrc/kyclogic/taler-exchange-helper-measure-tops-sms-check | 9++++++++-
2 files changed, 16 insertions(+), 2 deletions(-)

diff --git a/src/kyclogic/taler-exchange-helper-measure-tops-postal-check b/src/kyclogic/taler-exchange-helper-measure-tops-postal-check @@ -95,7 +95,14 @@ COUNTRY=$(echo "$INPUTS" | jq -r '.attributes.ADDRESS_COUNTRY // null') # Get current rules. CURRENT_RULES=$(echo "$INPUTS" | jq '.current_rules // null') # Get context values. -EXPIRATION_TIME=$(echo "$INPUTS" | jq '.context.expiration_time // .attributes.expires // .current_rules.expiration_time // null') +# How long the rules we emit are valid. This must NOT be derived from +# .attributes.expires: that is the challenger's address validation lifetime, +# and a validation that has already aged out yields a rule set which expired +# before it was written. The exchange applies such a set, immediately falls +# back to the default rules, and asks for this very same check again. +VALIDITY_YEARS=$(echo "$INPUTS" | jq -r '.context.validity_years // 5') +EXPIRATION_STAMP=$((VALIDITY_YEARS * 365 * 24 * 60 * 60 + $(date +%s))) +EXPIRATION_TIME=$(echo "$INPUTS" | jq --argjson es "$EXPIRATION_STAMP" '.context.expiration_time // {"t_s":$es}') SUCCESSOR_MEASURE=$(echo "$INPUTS" | jq '.context.successor_measure // .current_rules.successor_measure // null') CUSTOM_MEASURES=$(echo "$INPUTS" | jq '.context.custom_measures // null') diff --git a/src/kyclogic/taler-exchange-helper-measure-tops-sms-check b/src/kyclogic/taler-exchange-helper-measure-tops-sms-check @@ -93,7 +93,14 @@ PHONE_NUMBER=$(echo "$INPUTS" | jq -r '.attributes.CONTACT_PHONE // null') # Get current rules. CURRENT_RULES=$(echo "$INPUTS" | jq '.current_rules // null') # Get context values. -EXPIRATION_TIME=$(echo "$INPUTS" | jq '.context.expiration_time // .attributes.expires // .current_rules.expiration_time // null') +# How long the rules we emit are valid. This must NOT be derived from +# .attributes.expires: that is the challenger's address validation lifetime, +# and a validation that has already aged out yields a rule set which expired +# before it was written. The exchange applies such a set, immediately falls +# back to the default rules, and asks for this very same check again. +VALIDITY_YEARS=$(echo "$INPUTS" | jq -r '.context.validity_years // 2') +EXPIRATION_STAMP=$((VALIDITY_YEARS * 365 * 24 * 60 * 60 + $(date +%s))) +EXPIRATION_TIME=$(echo "$INPUTS" | jq --argjson es "$EXPIRATION_STAMP" '.context.expiration_time // {"t_s":$es}') SUCCESSOR_MEASURE=$(echo "$INPUTS" | jq '.context.successor_measure // .current_rules.successor_measure // null') CUSTOM_MEASURES=$(echo "$INPUTS" | jq '.context.custom_measures // null')