Skip to content

Commit

Permalink
Merge pull request #2653 from myxmaster/trim_input_data_in_handleAnyt…
Browse files Browse the repository at this point in the history
…hing

Trim input data in handleAnything
  • Loading branch information
kaloudis authored Dec 27, 2024
2 parents b707328 + 8c89625 commit e9d99c6
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 29 deletions.
95 changes: 66 additions & 29 deletions utils/handleAnything.test.ts
Original file line number Diff line number Diff line change
@@ -1,43 +1,68 @@
import stores from '../stores/Stores';
import handleAnything from './handleAnything';

let mockProcessBIP21Uri = jest.fn();
let mockIsValidBitcoinAddress = false;
let mockIsValidLightningPubKey = false;
let mockIsValidLightningPaymentRequest = false;
let mockSupportsOnchainSends = true;
let mockGetLnurlParams = {};

jest.mock('./AddressUtils', () => ({
processBIP21Uri: () => mockProcessedSendAddress,
processBIP21Uri: (...args: string[]) => mockProcessBIP21Uri(...args),
isValidBitcoinAddress: () => mockIsValidBitcoinAddress,
isValidLightningPubKey: () => mockIsValidLightningPubKey,
isValidLightningPaymentRequest: () => mockIsValidLightningPaymentRequest
isValidLightningPaymentRequest: () => mockIsValidLightningPaymentRequest,
isValidLightningOffer: () => false,
isValidLNDHubAddress: () => false,
processLNDHubAddress: () => ({}),
isValidNpub: () => false,
isPsbt: () => false,
isValidTxHex: () => false
}));
jest.mock('./TorUtils', () => ({}));
jest.mock('./BackendUtils', () => ({
supportsOnchainSends: () => mockSupportsOnchainSends
supportsOnchainSends: () => mockSupportsOnchainSends,
supportsAccounts: () => false
}));
jest.mock('../stores/Stores', () => ({
nodeInfoStore: { nodeInfo: {} },
invoicesStore: { getPayReq: jest.fn() }
invoicesStore: { getPayReq: jest.fn() },
settingsStore: { settings: { locale: 'en' } }
}));
jest.mock('react-native-blob-util', () => ({}));
jest.mock('react-native-encrypted-storage', () => ({}));
jest.mock('react-native-fs', () => ({}));
jest.mock('js-lnurl', () => ({
getParams: () => mockGetLnurlParams
getParams: () => mockGetLnurlParams,
findlnurl: () => null
}));
import stores from '../stores/Stores';
import handleAnything from './handleAnything';
let mockProcessedSendAddress = {};
let mockIsValidBitcoinAddress = false;
let mockIsValidLightningPubKey = false;
let mockIsValidLightningPaymentRequest = false;
let mockSupportsOnchainSends = true;
let mockGetLnurlParams = {};

describe('handleAnything', () => {
beforeEach(() => {
mockProcessBIP21Uri.mockReset();
mockIsValidBitcoinAddress = false;
mockIsValidLightningPubKey = false;
mockIsValidLightningPaymentRequest = false;
});

describe('input sanitization', () => {
it('should trim whitespace before processing', async () => {
mockIsValidBitcoinAddress = true;
mockProcessBIP21Uri.mockReturnValue({ value: 'some address' });

await handleAnything(' some address ');
expect(mockProcessBIP21Uri).toHaveBeenCalledWith('some address');
});
});

describe('bitcoin address', () => {
it('should return Send screen if not from clipboard', async () => {
const data = 'test data';
mockProcessedSendAddress = { value: 'some address', amount: 123 };
mockProcessBIP21Uri.mockReturnValue({
value: 'some address',
amount: 123
});
mockIsValidBitcoinAddress = true;

const result = await handleAnything(data);
Expand All @@ -55,7 +80,10 @@ describe('handleAnything', () => {

it('should return true if from clipboard', async () => {
const data = 'test data';
mockProcessedSendAddress = { value: 'some address', amount: 123 };
mockProcessBIP21Uri.mockReturnValue({
value: 'some address',
amount: 123
});
mockIsValidBitcoinAddress = true;

const result = await handleAnything(data, undefined, true);
Expand All @@ -67,7 +95,7 @@ describe('handleAnything', () => {
describe('lightning public key', () => {
it('should return Send screen if not from clipboard', async () => {
const data = 'test data';
mockProcessedSendAddress = { value: 'some public key' };
mockProcessBIP21Uri.mockReturnValue({ value: 'some public key' });
mockIsValidLightningPubKey = true;

const result = await handleAnything(data);
Expand All @@ -84,7 +112,7 @@ describe('handleAnything', () => {

it('should return true if from clipboard', async () => {
const data = 'test data';
mockProcessedSendAddress = { value: 'some public key' };
mockProcessBIP21Uri.mockReturnValue({ value: 'some public key' });
mockIsValidLightningPubKey = true;

const result = await handleAnything(data, undefined, true);
Expand All @@ -96,7 +124,9 @@ describe('handleAnything', () => {
describe('lightning payment request', () => {
it('should return PaymentRequest screen and call getPayReq if not from clipboard', async () => {
const data = 'test data';
mockProcessedSendAddress = { value: 'some payment request' };
mockProcessBIP21Uri.mockReturnValue({
value: 'some payment request'
});
mockIsValidLightningPaymentRequest = true;

const result = await handleAnything(data);
Expand All @@ -109,7 +139,9 @@ describe('handleAnything', () => {

it('should return true if from clipboard', async () => {
const data = 'test data';
mockProcessedSendAddress = { value: 'some payment request' };
mockProcessBIP21Uri.mockReturnValue({
value: 'some payment request'
});
mockIsValidLightningPaymentRequest = true;

const result = await handleAnything(data, undefined, true);
Expand All @@ -119,16 +151,14 @@ describe('handleAnything', () => {
});

describe('bitcoin URI with lnurl and backend not supporting on-chain sends', () => {
// test needs to be mocked out more as endpoint at https://ts.dergigi.com/BTC/UILNURL/pay/i/Wg7JV2ZFHs4cschM6bG5PT
// returns {"status":"ERROR","reason":"Invoice not in a valid payable state"} and throws on handleAnything.ts:54
it('should return LnurlPay screen if not from clipboard', async () => {
const data =
'bitcoin:BC1QUXCS7V556UTNUKU93HSZ7LHHFFLWN9NF2UTQ6N?pj=https://ts.dergigi.com/BTC/pj&lightning=LNURL1DP68GURN8GHJ7ARN9EJX2UN8D9NKJTNRDAKJ7SJ5GVH42J2VFE24YNP0WPSHJTMF9ATKWD622CE953JGWV6XXUMRDPXNVCJ8X4G9GF2CHDF';
mockProcessedSendAddress = {
mockProcessBIP21Uri.mockReturnValue({
value: 'BC1QUXCS7V556UTNUKU93HSZ7LHHFFLWN9NF2UTQ6N',
lightning:
'LNURL1DP68GURN8GHJ7ARN9EJX2UN8D9NKJTNRDAKJ7SJ5GVH42J2VFE24YNP0WPSHJTMF9ATKWD622CE953JGWV6XXUMRDPXNVCJ8X4G9GF2CHDF'
};
});
mockIsValidBitcoinAddress = true;
mockSupportsOnchainSends = false;
mockGetLnurlParams = {
Expand All @@ -153,11 +183,11 @@ describe('handleAnything', () => {
it('should return true if from clipboard', async () => {
const data =
'bitcoin:BC1QUXCS7V556UTNUKU93HSZ7LHHFFLWN9NF2UTQ6N?pj=https://ts.dergigi.com/BTC/pj&lightning=LNURL1DP68GURN8GHJ7ARN9EJX2UN8D9NKJTNRDAKJ7SJ5GVH42J2VFE24YNP0WPSHJTMF9ATKWD622CE953JGWV6XXUMRDPXNVCJ8X4G9GF2CHDF';
mockProcessedSendAddress = {
mockProcessBIP21Uri.mockReturnValue({
value: 'BC1QUXCS7V556UTNUKU93HSZ7LHHFFLWN9NF2UTQ6N',
lightning:
'LNURL1DP68GURN8GHJ7ARN9EJX2UN8D9NKJTNRDAKJ7SJ5GVH42J2VFE24YNP0WPSHJTMF9ATKWD622CE953JGWV6XXUMRDPXNVCJ8X4G9GF2CHDF'
};
});
mockIsValidBitcoinAddress = true;
mockSupportsOnchainSends = false;

Expand All @@ -171,6 +201,13 @@ describe('handleAnything', () => {
it('should return PaymentRequest screen and call getPayReq if not from clipboard', async () => {
const data =
'bitcoin:BC1QYLH3U67J673H6Y6ALV70M0PL2YZ53TZHVXGG7U?amount=0.00001&label=sbddesign%3A%20For%20lunch%20Tuesday&message=For%20lunch%20Tuesday&lightning=LNBC10U1P3PJ257PP5YZTKWJCZ5FTL5LAXKAV23ZMZEKAW37ZK6KMV80PK4XAEV5QHTZ7QDPDWD3XGER9WD5KWM36YPRX7U3QD36KUCMGYP282ETNV3SHJCQZPGXQYZ5VQSP5USYC4LK9CHSFP53KVCNVQ456GANH60D89REYKDNGSMTJ6YW3NHVQ9QYYSSQJCEWM5CJWZ4A6RFJX77C490YCED6PEMK0UPKXHY89CMM7SCT66K8GNEANWYKZGDRWRFJE69H9U5U0W57RRCSYSAS7GADWMZXC8C6T0SPJAZUP6';
mockProcessBIP21Uri.mockReturnValue({
value: 'BC1QYLH3U67J673H6Y6ALV70M0PL2YZ53TZHVXGG7U',
lightning:
'LNBC10U1P3PJ257PP5YZTKWJCZ5FTL5LAXKAV23ZMZEKAW37ZK6KMV80PK4XAEV5QHTZ7QDPDWD3XGER9WD5KWM36YPRX7U3QD36KUCMGYP282ETNV3SHJCQZPGXQYZ5VQSP5USYC4LK9CHSFP53KVCNVQ456GANH60D89REYKDNGSMTJ6YW3NHVQ9QYYSSQJCEWM5CJWZ4A6RFJX77C490YCED6PEMK0UPKXHY89CMM7SCT66K8GNEANWYKZGDRWRFJE69H9U5U0W57RRCSYSAS7GADWMZXC8C6T0SPJAZUP6'
});
mockIsValidBitcoinAddress = true;
mockSupportsOnchainSends = false;

const result = await handleAnything(data);

Expand All @@ -179,21 +216,21 @@ describe('handleAnything', () => {
{
amount: undefined,
lightning:
'LNURL1DP68GURN8GHJ7ARN9EJX2UN8D9NKJTNRDAKJ7SJ5GVH42J2VFE24YNP0WPSHJTMF9ATKWD622CE953JGWV6XXUMRDPXNVCJ8X4G9GF2CHDF',
'LNBC10U1P3PJ257PP5YZTKWJCZ5FTL5LAXKAV23ZMZEKAW37ZK6KMV80PK4XAEV5QHTZ7QDPDWD3XGER9WD5KWM36YPRX7U3QD36KUCMGYP282ETNV3SHJCQZPGXQYZ5VQSP5USYC4LK9CHSFP53KVCNVQ456GANH60D89REYKDNGSMTJ6YW3NHVQ9QYYSSQJCEWM5CJWZ4A6RFJX77C490YCED6PEMK0UPKXHY89CMM7SCT66K8GNEANWYKZGDRWRFJE69H9U5U0W57RRCSYSAS7GADWMZXC8C6T0SPJAZUP6',
offer: undefined,
value: 'BC1QUXCS7V556UTNUKU93HSZ7LHHFFLWN9NF2UTQ6N'
value: 'BC1QYLH3U67J673H6Y6ALV70M0PL2YZ53TZHVXGG7U'
}
]);
});

it('should return true if from clipboard', async () => {
const data =
'bitcoin:BC1QYLH3U67J673H6Y6ALV70M0PL2YZ53TZHVXGG7U?amount=0.00001&label=sbddesign%3A%20For%20lunch%20Tuesday&message=For%20lunch%20Tuesday&lightning=LNBC10U1P3PJ257PP5YZTKWJCZ5FTL5LAXKAV23ZMZEKAW37ZK6KMV80PK4XAEV5QHTZ7QDPDWD3XGER9WD5KWM36YPRX7U3QD36KUCMGYP282ETNV3SHJCQZPGXQYZ5VQSP5USYC4LK9CHSFP53KVCNVQ456GANH60D89REYKDNGSMTJ6YW3NHVQ9QYYSSQJCEWM5CJWZ4A6RFJX77C490YCED6PEMK0UPKXHY89CMM7SCT66K8GNEANWYKZGDRWRFJE69H9U5U0W57RRCSYSAS7GADWMZXC8C6T0SPJAZUP6';
mockProcessedSendAddress = {
mockProcessBIP21Uri.mockReturnValue({
value: 'BC1QYLH3U67J673H6Y6ALV70M0PL2YZ53TZHVXGG7U',
lightning:
'LNBC10U1P3PJ257PP5YZTKWJCZ5FTL5LAXKAV23ZMZEKAW37ZK6KMV80PK4XAEV5QHTZ7QDPDWD3XGER9WD5KWM36YPRX7U3QD36KUCMGYP282ETNV3SHJCQZPGXQYZ5VQSP5USYC4LK9CHSFP53KVCNVQ456GANH60D89REYKDNGSMTJ6YW3NHVQ9QYYSSQJCEWM5CJWZ4A6RFJX77C490YCED6PEMK0UPKXHY89CMM7SCT66K8GNEANWYKZGDRWRFJE69H9U5U0W57RRCSYSAS7GADWMZXC8C6T0SPJAZUP6'
};
});
mockIsValidBitcoinAddress = true;
mockSupportsOnchainSends = false;

Expand Down
1 change: 1 addition & 0 deletions utils/handleAnything.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ const handleAnything = async (
setAmount?: string,
isClipboardValue?: boolean
): Promise<any> => {
data = data.trim();
const { nodeInfo } = nodeInfoStore;
const { isTestNet, isRegTest, isSigNet } = nodeInfo;
const { value, amount, lightning, offer }: any =
Expand Down

0 comments on commit e9d99c6

Please sign in to comment.