-
Notifications
You must be signed in to change notification settings - Fork 124
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add schema checks for addresses in url endpoints #2692
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -4,6 +4,7 @@ import { | |||||||||||||||||||||||||||||||||||||||||||
MAX_PARENT_SUBACCOUNTS, | ||||||||||||||||||||||||||||||||||||||||||||
CHILD_SUBACCOUNT_MULTIPLIER, | ||||||||||||||||||||||||||||||||||||||||||||
} from '@dydxprotocol-indexer/postgres'; | ||||||||||||||||||||||||||||||||||||||||||||
import { decode } from 'bech32'; | ||||||||||||||||||||||||||||||||||||||||||||
import { body, checkSchema, ParamSchema } from 'express-validator'; | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
import config from '../../config'; | ||||||||||||||||||||||||||||||||||||||||||||
|
@@ -12,6 +13,10 @@ export const CheckSubaccountSchema = checkSchema({ | |||||||||||||||||||||||||||||||||||||||||||
address: { | ||||||||||||||||||||||||||||||||||||||||||||
in: ['params', 'query'], | ||||||||||||||||||||||||||||||||||||||||||||
isString: true, | ||||||||||||||||||||||||||||||||||||||||||||
custom: { | ||||||||||||||||||||||||||||||||||||||||||||
options: isValidAddress, | ||||||||||||||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||||||||||||
errorMessage: 'address must be a valid dydx address', | ||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+16
to
+19
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Inconsistency between error message and validation logic. The error message states "address must be a valid dydx address", but
Example fix: address: {
in: ['params', 'query'],
isString: true,
custom: {
- options: isValidAddress,
+ options: isValidDydxAddress,
},
errorMessage: 'address must be a valid dydx address',
}, Or: address: {
in: ['params', 'query'],
isString: true,
custom: {
options: isValidAddress,
},
- errorMessage: 'address must be a valid dydx address',
+ errorMessage: 'address must be alphanumeric and not exceed 90 characters',
}, Also applies to: 34-37, 52-55 💡 Codebase verification Review comment is correct - schemas should use stricter validation The codebase confirms that while
Switching to 🔗 Analysis chainAlign implementation with PR objectives. The PR's objective is to add bech32 schema checks for addresses, but the current implementation uses a more lenient validation ( Consider using Let's verify the impact of this change: Also applies to: 34-37, 52-55, 289-292 🏁 Scripts executedThe following scripts were executed for the analysis: Script: #!/bin/bash
# Find all files that might be affected by this change
echo "Files potentially using these schemas:"
rg -l "CheckSubaccountSchema|CheckParentSubaccountSchema|CheckAddressSchema" --type ts
echo -e "\nEndpoints using these schemas:"
rg -A 2 "\.use\((Check(Subaccount|ParentSubaccount|Address)Schema)" --type ts
Length of output: 1108 Script: #!/bin/bash
# Find implementation of validation functions
echo "=== Validation function implementations ==="
ast-grep --pattern 'function isValidAddress'
ast-grep --pattern 'function isValidDydxAddress'
echo -e "\n=== Usage in controllers ==="
# Look for schema usage in controllers with context
rg "CheckSubaccountSchema|CheckParentSubaccountSchema|CheckAddressSchema" "indexer/services/comlink/src/controllers/api/v4/*.ts" -B 1 -A 1
echo -e "\n=== Test coverage ==="
# Check test coverage for these validations
rg "isValidAddress|isValidDydxAddress" "indexer/services/comlink/__tests__/" -A 2
Length of output: 642 Script: #!/bin/bash
# Find validation function implementations with broader patterns
echo "=== Validation implementations ==="
rg "isValidAddress|isValidDydxAddress" "indexer/services/comlink/src/" -A 2
echo -e "\n=== Exports and imports ==="
rg "export.*isValid|import.*isValid" "indexer/services/comlink/src/" -A 1
echo -e "\n=== Schema usage in controllers ==="
# Fixed controller path
rg "CheckSubaccountSchema|CheckParentSubaccountSchema|CheckAddressSchema" "indexer/services/comlink/src/controllers/" -B 1 -A 1
echo -e "\n=== Schema definitions ==="
rg "CheckSubaccountSchema|CheckParentSubaccountSchema|CheckAddressSchema" "indexer/services/comlink/src/lib/validation/" -B 1 -A 3
Length of output: 13609 |
||||||||||||||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||||||||||||
subaccountNumber: { | ||||||||||||||||||||||||||||||||||||||||||||
in: ['params', 'query'], | ||||||||||||||||||||||||||||||||||||||||||||
|
@@ -26,6 +31,10 @@ export const CheckParentSubaccountSchema = checkSchema({ | |||||||||||||||||||||||||||||||||||||||||||
address: { | ||||||||||||||||||||||||||||||||||||||||||||
in: ['params', 'query'], | ||||||||||||||||||||||||||||||||||||||||||||
isString: true, | ||||||||||||||||||||||||||||||||||||||||||||
custom: { | ||||||||||||||||||||||||||||||||||||||||||||
options: isValidAddress, | ||||||||||||||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||||||||||||
errorMessage: 'address must be a valid dydx address', | ||||||||||||||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||||||||||||
parentSubaccountNumber: { | ||||||||||||||||||||||||||||||||||||||||||||
in: ['params', 'query'], | ||||||||||||||||||||||||||||||||||||||||||||
|
@@ -40,6 +49,10 @@ export const checkAddressSchemaRecord: Record<string, ParamSchema> = { | |||||||||||||||||||||||||||||||||||||||||||
address: { | ||||||||||||||||||||||||||||||||||||||||||||
in: ['params'], | ||||||||||||||||||||||||||||||||||||||||||||
isString: true, | ||||||||||||||||||||||||||||||||||||||||||||
custom: { | ||||||||||||||||||||||||||||||||||||||||||||
options: isValidAddress, | ||||||||||||||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||||||||||||
errorMessage: 'address must be a valid address', | ||||||||||||||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||||||||||||
}; | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
|
@@ -262,3 +275,23 @@ export const RegisterTokenValidationSchema = [ | |||||||||||||||||||||||||||||||||||||||||||
return true; | ||||||||||||||||||||||||||||||||||||||||||||
}), | ||||||||||||||||||||||||||||||||||||||||||||
]; | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
function verifyIsBech32(address: string): Error | undefined { | ||||||||||||||||||||||||||||||||||||||||||||
try { | ||||||||||||||||||||||||||||||||||||||||||||
decode(address); | ||||||||||||||||||||||||||||||||||||||||||||
} catch (error) { | ||||||||||||||||||||||||||||||||||||||||||||
return error; | ||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
return undefined; | ||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+279
to
+287
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Add input validation to verifyIsBech32. The function should validate its input before attempting to decode. function verifyIsBech32(address: string): Error | undefined {
+ if (!address || typeof address !== 'string') {
+ return new Error('Invalid input: address must be a non-empty string');
+ }
try {
decode(address);
} catch (error) {
- return error;
+ return error instanceof Error ? error : new Error('Invalid bech32 format');
}
return undefined;
} 📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
export function isValidDydxAddress(address: string): boolean { | ||||||||||||||||||||||||||||||||||||||||||||
// An address is valid if it starts with `dydx1` and is Bech32 format. | ||||||||||||||||||||||||||||||||||||||||||||
return address.startsWith('dydx1') && (verifyIsBech32(address) === undefined); | ||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+289
to
+292
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Add input validation to isValidDydxAddress. The function should validate its input and handle edge cases. export function isValidDydxAddress(address: string): boolean {
+ if (!address || typeof address !== 'string') {
+ return false;
+ }
// An address is valid if it starts with `dydx1` and is Bech32 format.
return address.startsWith('dydx1') && (verifyIsBech32(address) === undefined);
} 📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
export function isValidAddress(address: string): boolean { | ||||||||||||||||||||||||||||||||||||||||||||
// Address is valid if its under 90 characters and alphanumeric | ||||||||||||||||||||||||||||||||||||||||||||
return address.length <= 90 && /^[a-zA-Z0-9]*$/.test(address); | ||||||||||||||||||||||||||||||||||||||||||||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Enhance test coverage for address validation.
The test's error message suggests bech32 validation ("must be a valid dydx address"), but it only tests for a missing address. Additional test cases are needed to verify bech32 validation once the schemas are updated to use
isValidDydxAddress
.Add these test cases: