ayushcodes27 opened a new issue, #232:
URL: https://github.com/apache/fineract-consumer-facing/issues/232

   ### Where it happens
   
   Both, or not sure
   
   ### What happened
   
   In `TransfersCommandServiceImpl.initiate` and 
`TransfersCommandServiceImpl.confirm`, transfer requests between savings 
accounts do not validate that the source and destination account identifiers 
are distinct (`fromAccountId != toAccountId`).
   
   ### What happened
   When a consumer initiates a transfer from a savings account to the exact 
same savings account:
   1. Destination authorization passes because the consumer owns the account 
(`accessPolicyEvaluator.ownsResource(...)` returns true).
   2. An OTP is generated and emailed to the consumer, and a Step-Up challenge 
token is issued.
   3. Upon OTP confirmation, upstream Fineract core 
(`AccountTransfersWritePlatformServiceImpl`) executes a withdrawal followed by 
an immediate deposit on the identical account.
   4. This results in duplicate debit and credit transactions on the ledger and 
can deduct withdrawal fees if configured on the savings product.
   
   ### What was expected
   A transfer between identical savings accounts should fail fast during both 
`initiate` and `confirm` with a `400 Bad Request` 
(`TransferSameAccountException`) before sending an OTP or dispatching upstream 
calls.
   
   ### Context & Solution
   - I have reproduced this with a failing test in 
`TransfersCommandServiceImplTest`.
   - Added an early `requireDistinctAccounts` check in 
`TransfersCommandServiceImpl`.
   - Added `TransferSameAccountException` and i18n error translations in 
`frontend/public/i18n/`.
   - Verified all quality gates (`spotbugsMain`, `modernizer`, 
`LayeringArchitectureTest`, `i18n:check`).
   
   I have a branch and PR ready to submit once this issue is logged.
   
   ### Steps to reproduce
   
   1. Sign in as a consumer who has an active savings account (e.g. Account ID 
`1`).
   2. Call `POST /api/v1/transfers/initiate` with:
      ```json
      {
        "fromAccountId": 1,
        "toAccountId": 1,
        "toAccountType": "savings",
        "amount": 10.00
      }
      ```
   3. Observe that initiation succeeds (returns 200 OK with a `stepUpToken` and 
emails an OTP).
   4. Enter the received OTP and call `POST /api/v1/transfers/confirm`.
   5. Observe that confirmation executes, causing Fineract core to create a 
withdrawal and an immediate deposit on the exact same account.
   
   ### Error code, correlation ID and logs
   
   ```text
   No error code is currently returned because the request erroneously succeeds 
(HTTP 200 OK) at both `/initiate` and `/confirm`. 
   
   Expected error response:
   HTTP 400 Bad Request
   Code: error.msg.consumer.transfers.command.account.same
   Message: "source and destination accounts must not be the same"
   ```
   
   ### How you ran it
   
   Docker Compose e2e stack (docker-compose.e2e.yml)
   
   ### Fineract image
   
   4a61d7c218413eca8310d30b098722047e891bb7
   
   ### Commit
   
   b07ad67
   
   ### Browser and version
   
   N/A (BFF / API level issue, also verified via unit tests in 
TransfersCommandServiceImplTest)
   
   ### Before submitting
   
   - [x] I searched the existing issues.
   - [x] This is not a security vulnerability, and it is not a bug in Fineract 
Core.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to