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:
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')