taler-typescript-core

Wallet core logic and WebUIs for various components
Log | Files | Refs | Submodules | README | LICENSE

commit c673e775b442f2dff0f8398bcb7ef8d74100311f
parent 2cbb2d4405890418a612d30619b1eb4a4369a475
Author: Florian Dold <florian@dold.me>
Date:   Wed, 26 Mar 2025 23:32:37 +0100

harness: new kyc-decision-events test

Diffstat:
Mpackages/taler-harness/src/harness/environments.ts | 2++
Apackages/taler-harness/src/integrationtests/test-kyc-decision-events.ts | 142+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mpackages/taler-harness/src/integrationtests/testrunner.ts | 2++
Mpackages/taler-util/src/types-taler-exchange.ts | 6++++++
4 files changed, 152 insertions(+), 0 deletions(-)

diff --git a/packages/taler-harness/src/harness/environments.ts b/packages/taler-harness/src/harness/environments.ts @@ -1036,6 +1036,7 @@ export async function postAmlDecision( properties?: AccountProperties; attributes?: Object; attributes_expiration?: TalerProtocolTimestamp; + events?: string[]; }, ) { const { exchangeBaseUrl, paytoHash, amlPriv, amlPub } = req; @@ -1058,6 +1059,7 @@ export async function postAmlDecision( ...sigData, officer_sig: encodeCrock(sig), payto_uri: req.paytoUri, + events: req.events, }; const reqUrl = new URL(`aml/${amlPub}/decision`, exchangeBaseUrl); diff --git a/packages/taler-harness/src/integrationtests/test-kyc-decision-events.ts b/packages/taler-harness/src/integrationtests/test-kyc-decision-events.ts @@ -0,0 +1,142 @@ +/* + This file is part of GNU Taler + (C) 2024 Taler Systems S.A. + + GNU Taler is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ + +/** + * Imports. + */ +import { + codecForAny, + Configuration, + decodeCrock, + Duration, + encodeCrock, + hashNormalizedPaytoUri, + j2s, + LimitOperationType, + signAmlQuery, + TalerProtocolTimestamp, +} from "@gnu-taler/taler-util"; +import { readSuccessResponseJsonOrThrow } from "@gnu-taler/taler-util/http"; +import { createSyncCryptoApi } from "@gnu-taler/taler-wallet-core"; +import { + configureCommonKyc, + createKycTestkudosEnvironment, + postAmlDecision, +} from "../harness/environments.js"; +import { + getTestHarnessPaytoForLabel, + GlobalTestState, + harnessHttpLib, +} from "../harness/harness.js"; + +function adjustExchangeConfig(config: Configuration) { + configureCommonKyc(config); + + config.setString("KYC-RULE-R1", "operation_type", "withdraw"); + config.setString("KYC-RULE-R1", "enabled", "yes"); + config.setString("KYC-RULE-R1", "exposed", "yes"); + config.setString("KYC-RULE-R1", "is_and_combinator", "no"); + config.setString("KYC-RULE-R1", "threshold", "TESTKUDOS:100"); + config.setString("KYC-RULE-R1", "timeframe", "1d"); + config.setString("KYC-RULE-R1", "next_measures", "verboten"); +} + +/** + * Tests for making AML decisions. + * - Test making decisions on unknown accounts. + * - Test making decisions with default rules. + */ +export async function runKycDecisionEventsTest(t: GlobalTestState) { + // Set up test environment + + // FIXME: Reduced test environment without merchant suffices + const { + walletClient, + bankClient, + exchange, + amlKeypair, + exchangeBankAccount, + } = await createKycTestkudosEnvironment(t, { adjustExchangeConfig }); + + const merchantPayto = getTestHarnessPaytoForLabel("merchant-default"); + + const cryptoApi = createSyncCryptoApi(); + + const kycPaytoHash = encodeCrock(hashNormalizedPaytoUri(merchantPayto)); + + await postAmlDecision(t, { + amlPriv: amlKeypair.priv, + amlPub: amlKeypair.pub, + exchangeBaseUrl: exchange.baseUrl, + paytoHash: kycPaytoHash, + paytoUri: merchantPayto, + attributes: { foo: 42 }, + attributes_expiration: TalerProtocolTimestamp.never(), + events: ["bla", "spam", "eggs"], + newRules: { + expiration_time: TalerProtocolTimestamp.now(), + custom_measures: {}, + rules: [ + { + operation_type: LimitOperationType.deposit, + display_priority: 1, + exposed: true, + measures: ["verboten"], + threshold: "TESTKUDOS:10", + timeframe: Duration.toTalerProtocolDuration( + Duration.fromSpec({ + days: 1, + }), + ), + }, + { + operation_type: LimitOperationType.withdraw, + display_priority: 1, + exposed: true, + measures: ["verboten"], + threshold: "TESTKUDOS:0", + timeframe: Duration.toTalerProtocolDuration( + Duration.fromSpec({ + days: 1, + }), + ), + }, + ], + }, + }); + + const sig = signAmlQuery(decodeCrock(amlKeypair.priv)); + + const attributesResp = await harnessHttpLib.fetch( + new URL(`aml/${amlKeypair.pub}/kyc-statistics/bla`, exchange.baseUrl).href, + { + headers: { + "Taler-AML-Officer-Signature": encodeCrock(sig), + }, + }, + ); + + const evtResp = await readSuccessResponseJsonOrThrow( + attributesResp, + codecForAny(), + ); + + console.log(j2s(evtResp)); + + t.assertDeepEqual(evtResp.counter, 1); +} + +runKycDecisionEventsTest.suites = ["wallet"]; diff --git a/packages/taler-harness/src/integrationtests/testrunner.ts b/packages/taler-harness/src/integrationtests/testrunner.ts @@ -55,6 +55,7 @@ import { runKycAmpFailureTest } from "./test-kyc-amp-failure.js"; import { runKycAmpTimeoutTest } from "./test-kyc-amp-timeout.js"; import { runKycBalanceWithdrawalTest } from "./test-kyc-balance-withdrawal.js"; import { runKycDecisionAttrTest } from "./test-kyc-decision-attr.js"; +import { runKycDecisionEventsTest } from "./test-kyc-decision-events.js"; import { runKycDecisionsTest } from "./test-kyc-decisions.js"; import { runKycDepositAggregateImplicitAuthTest } from "./test-kyc-deposit-aggregate-implicit-auth.js"; import { runKycDepositAggregateTest } from "./test-kyc-deposit-aggregate.js"; @@ -308,6 +309,7 @@ const allTests: TestMainFunction[] = [ runAgeRestrictionsMixedMerchantTest, runAgeRestrictionsPeerTest, runAgeRestrictionsDepositTest, + runKycDecisionEventsTest, ]; export interface TestRunSpec { diff --git a/packages/taler-util/src/types-taler-exchange.ts b/packages/taler-util/src/types-taler-exchange.ts @@ -2011,6 +2011,12 @@ export interface AmlDecisionRequest { // Expiration timestamp of the attributes. // Mandatory if attributes are present. attributes_expiration?: Timestamp; + + // Array of AML/KYC events to trigger for statistics. + // Note that this information is not covered by the signature + // (which is OK as events are just for statistics). + // New since protocol **v24**. + events?: string[]; } export interface KycRule {