fix(support): match compliance search address case-insensitively#3824
fix(support): match compliance search address case-insensitively#3824TaprootFreak wants to merge 2 commits into
Conversation
davidleomay
left a comment
There was a problem hiding this comment.
The three dedicated IgnoreCase methods could be avoided entirely. MSSQL used a case-insensitive collation, so address lookups always matched regardless of case — this bug only appeared after the Postgres migration. Making getByKey use ILIKE for the address column would restore pre-Postgres behaviour rather than introduce a new one, and avoids duplicating the query logic three times. Something like replacing = :param with ILIKE :param in getUserByKey, getSellByKey, and getSwapByKey when the key is an address field. The three new dedicated methods could then be dropped.
|
|
||
| if (Config.formats.address.test(key)) { | ||
| const user = await this.userService.getUserByKey('address', key, true); | ||
| const user = await this.userService.getUserByAddressIgnoreCase(key); |
There was a problem hiding this comment.
MSSQL used a case-insensitive collation, so address lookups worked regardless of case before the Postgres migration — this is a regression, not a new requirement. Instead of three dedicated IgnoreCase methods, consider using ILIKE :param in place of = :param in getUserByKey, getSellByKey, and getSwapByKey. That restores pre-Postgres behaviour across the board and avoids duplicating the query logic.
Problem
The compliance database search returns "No user or bankTx found" when an EVM address is entered in a different letter case than it is stored. Addresses are persisted in EIP-55 checksummed form, so a non-checksummed (e.g. all-lowercase) address — as commonly copied from block explorers — is never found.
Root cause
The address branch of
SupportService.getUniqueUserDataByKeylooked addresses up with exact, case-sensitive=comparisons (WHERE user.address = :param,WHERE deposit.address = :param). On Postgres these are case-sensitive, so a lowercase input does not match the stored checksummed value and the search falls through to the not-found error. This affected both lookups in that branch:Fix
Case-insensitive matching for the compliance search address branch only, via dedicated methods:
UserService.getUserByAddressIgnoreCase(address)SellService.getSellByDepositAddressIgnoreCase(address)SwapService.getSwapByDepositAddressIgnoreCase(address)Each uses
LOWER(<col>) = LOWER(:address)and loads the exact same relations as the previous lookup, so downstream behaviour is unchanged apart from being case-insensitive.The shared
getUserByKey,getUserByAddress,getSellByKeyandgetSwapByKeystay untouched, so authentication, KYC, history and every other caller keep their existing exact-match behaviour.Tests
WHEREclause for each of the three new methods.Scope
Read-only admin search only — no change to authentication or any address-write path.