diff --git a/core/src/main/java/org/stellar/anchor/sep24/InteractiveUrlConstructor.java b/core/src/main/java/org/stellar/anchor/sep24/InteractiveUrlConstructor.java index 589c2a4330..f7f99e76b6 100644 --- a/core/src/main/java/org/stellar/anchor/sep24/InteractiveUrlConstructor.java +++ b/core/src/main/java/org/stellar/anchor/sep24/InteractiveUrlConstructor.java @@ -1,12 +1,10 @@ package org.stellar.anchor.sep24; -import java.net.MalformedURLException; -import java.net.URISyntaxException; import java.util.Map; import org.stellar.anchor.api.sep.AssetInfo; +import org.stellar.anchor.auth.Sep10Jwt; public abstract class InteractiveUrlConstructor { public abstract String construct( - Sep24Transaction txn, Map sep9Fields, AssetInfo asset, String homeDomain) - throws URISyntaxException, MalformedURLException; + Sep24Transaction txn, Map request, AssetInfo asset, Sep10Jwt jwt); } diff --git a/core/src/main/java/org/stellar/anchor/sep24/Sep24Service.java b/core/src/main/java/org/stellar/anchor/sep24/Sep24Service.java index 06c23c2e07..dff3ca5766 100644 --- a/core/src/main/java/org/stellar/anchor/sep24/Sep24Service.java +++ b/core/src/main/java/org/stellar/anchor/sep24/Sep24Service.java @@ -268,7 +268,7 @@ public InteractiveTransactionResponse withdraw( InteractiveTransactionResponse response = new InteractiveTransactionResponse( "interactive_customer_info_needed", - interactiveUrlConstructor.construct(txn, withdrawRequest, asset, token.getHomeDomain()), + interactiveUrlConstructor.construct(txn, withdrawRequest, asset, token), txn.getTransactionId()); // increment counter @@ -429,7 +429,7 @@ public InteractiveTransactionResponse deposit(Sep10Jwt token, Map request, AssetInfo asset, String homeDomain) { + Sep24Transaction txn, Map request, AssetInfo asset, Sep10Jwt jwt) { // If there are KYC fields in the request, they will be forwarded to PUT /customer before // returning the token. - forwardKycFields(request); + forwardKycFields(request, jwt); // construct the token - String token = constructToken(txn, request, asset, homeDomain); + String token = constructToken(txn, request, asset, jwt.getHomeDomain()); // construct the URL String baseUrl = sep24Config.getInteractiveUrl().getBaseUrl(); @@ -104,7 +105,7 @@ String constructToken( return jwtService.encode(token); } - void forwardKycFields(Map request) throws AnchorException { + void forwardKycFields(Map request, Sep10Jwt jwt) throws AnchorException { if (sep24Config.getKycFieldsForwarding().isEnabled()) { // Get sep-9 fields from request Map sep9 = extractSep9Fields(request); @@ -115,6 +116,11 @@ void forwardKycFields(Map request) throws AnchorException { PutCustomerRequest putCustomerRequest = gson.fromJson(gsonRequest, PutCustomerRequest.class); putCustomerRequest.setType(FORWARD_KYC_CUSTOMER_TYPE); + putCustomerRequest.setAccount(jwt.getAccount()); + if (jwt.getAccountMemo() != null) { + putCustomerRequest.setMemo(jwt.getAccountMemo()); + putCustomerRequest.setMemoType("id"); + } // forward kyc fields to PUT /customer customerIntegration.putCustomer(putCustomerRequest); } diff --git a/platform/src/test/kotlin/org/stellar/anchor/platform/service/SimpleInteractiveUrlConstructorTest.kt b/platform/src/test/kotlin/org/stellar/anchor/platform/service/SimpleInteractiveUrlConstructorTest.kt index 77b61c8489..2f7d2a10ee 100644 --- a/platform/src/test/kotlin/org/stellar/anchor/platform/service/SimpleInteractiveUrlConstructorTest.kt +++ b/platform/src/test/kotlin/org/stellar/anchor/platform/service/SimpleInteractiveUrlConstructorTest.kt @@ -19,6 +19,7 @@ import org.stellar.anchor.api.exception.SepValidationException import org.stellar.anchor.api.sep.AssetInfo import org.stellar.anchor.auth.JwtService import org.stellar.anchor.auth.JwtService.* +import org.stellar.anchor.auth.Sep10Jwt import org.stellar.anchor.auth.Sep24InteractiveUrlJwt import org.stellar.anchor.config.ClientsConfig.ClientConfig import org.stellar.anchor.config.ClientsConfig.ClientType.CUSTODIAL @@ -47,6 +48,7 @@ class SimpleInteractiveUrlConstructorTest { @MockK(relaxed = true) private lateinit var custodySecretConfig: CustodySecretConfig @MockK(relaxed = true) private lateinit var customerIntegration: CustomerIntegration @MockK(relaxed = true) private lateinit var testAsset: AssetInfo + @MockK(relaxed = true) private lateinit var sep10Jwt: Sep10Jwt private lateinit var jwtService: JwtService private lateinit var sep24Config: PropertySep24Config @@ -88,6 +90,7 @@ class SimpleInteractiveUrlConstructorTest { ) every { testAsset.sep38AssetName } returns "stellar:USDC:GDQOE23CFSUMSVQK4Y5JHPPYK73VYCNHZHA7ENKCV37P6SUEO6XQBKPP" + every { sep10Jwt.homeDomain } returns TEST_HOME_DOMAIN jwtService = JwtService(secretConfig, custodySecretConfig) sep24Config = gson.fromJson(SEP24_CONFIG_JSON_1, PropertySep24Config::class.java) @@ -107,12 +110,7 @@ class SimpleInteractiveUrlConstructorTest { var jwt = parseJwtFromUrl( - constructor.construct( - testTxn, - testRequest as HashMap?, - testAsset, - TEST_HOME_DOMAIN - ) + constructor.construct(testTxn, testRequest as HashMap?, testAsset, sep10Jwt) ) testJwt(jwt) var claims = jwt.claims @@ -124,7 +122,7 @@ class SimpleInteractiveUrlConstructorTest { // Unknown client domain testTxn.sep10AccountMemo = null testTxn.clientDomain = "unknown.com" - jwt = parseJwtFromUrl(constructor.construct(testTxn, testRequest, testAsset, TEST_HOME_DOMAIN)) + jwt = parseJwtFromUrl(constructor.construct(testTxn, testRequest, testAsset, sep10Jwt)) claims = jwt.claims testJwt(jwt) assertEquals("GBLGJA4TUN5XOGTV6WO2BWYUI2OZR5GYQ5PDPCRMQ5XEPJOYWB2X4CJO", jwt.sub) @@ -136,7 +134,7 @@ class SimpleInteractiveUrlConstructorTest { testTxn.sep10Account = "GDQOE23CFSUMSVQK4Y5JHPPYK73VYCNHZHA7ENKCV37P6SUEO6XQBKPP" testTxn.sep10AccountMemo = "1234" testTxn.clientDomain = null - jwt = parseJwtFromUrl(constructor.construct(testTxn, testRequest, testAsset, TEST_HOME_DOMAIN)) + jwt = parseJwtFromUrl(constructor.construct(testTxn, testRequest, testAsset, sep10Jwt)) claims = jwt.claims testJwt(jwt) assertEquals("GDQOE23CFSUMSVQK4Y5JHPPYK73VYCNHZHA7ENKCV37P6SUEO6XQBKPP:1234", jwt.sub) @@ -156,12 +154,7 @@ class SimpleInteractiveUrlConstructorTest { testTxn.clientDomain = null assertThrows { - constructor.construct( - testTxn, - testRequest as HashMap?, - testAsset, - TEST_HOME_DOMAIN - ) + constructor.construct(testTxn, testRequest as HashMap?, testAsset, sep10Jwt) } } @@ -174,11 +167,16 @@ class SimpleInteractiveUrlConstructorTest { val constructor = SimpleInteractiveUrlConstructor(clientsConfig, sep24Config, customerIntegration, jwtService) sep24Config.kycFieldsForwarding.isEnabled = true - constructor.construct(txn, request as HashMap?, testAsset, TEST_HOME_DOMAIN) + every { sep10Jwt.account }.returns("test_account") + every { sep10Jwt.accountMemo }.returns("123") + constructor.construct(txn, request as HashMap?, testAsset, sep10Jwt) assertEquals(capturedPutCustomerRequest.captured.type, FORWARD_KYC_CUSTOMER_TYPE) assertEquals(capturedPutCustomerRequest.captured.firstName, request.get("first_name")) assertEquals(capturedPutCustomerRequest.captured.lastName, request.get("last_name")) assertEquals(capturedPutCustomerRequest.captured.emailAddress, request.get("email_address")) + assertEquals("test_account", capturedPutCustomerRequest.captured.account) + assertEquals("123", capturedPutCustomerRequest.captured.memo) + assertEquals("id", capturedPutCustomerRequest.captured.memoType) } @Test @@ -187,7 +185,12 @@ class SimpleInteractiveUrlConstructorTest { val constructor = SimpleInteractiveUrlConstructor(clientsConfig, sep24Config, customerIntegration, jwtService) sep24Config.kycFieldsForwarding.isEnabled = false - constructor.construct(txn, request as HashMap?, testAsset, TEST_HOME_DOMAIN) + constructor.construct( + txn, + request as HashMap?, + testAsset, + sep10Jwt, + ) verify(exactly = 0) { customerIntegration.putCustomer(any()) } }