This document describes the comprehensive validation implemented across all API endpoints.
All API endpoints now include robust input validation to ensure data integrity and security. Validation is implemented through:
- Validation Utilities (
src/utils/validators.js) - Core validation functions - Validation Middleware (
src/middleware/validation.js) - Express middleware for route protection - Consistent Error Responses - Standardized error format across all endpoints
- Must be a positive number
- Must be greater than 0
- Cannot be NaN, Infinity, or negative
- Accepts both numeric and string representations
// Valid
amount: 10
amount: "10.5"
amount: 0.01
// Invalid
amount: 0
amount: -5
amount: "abc"Public keys must:
- Start with 'G'
- Be exactly 56 characters long
- Contain only valid base32 characters (A-Z, 2-7)
// Valid
"GBRPYHIL2CI3FNQ4BXLFMNDLFJUNPU2HY3ZMFSHONUCEOASW7QC7OX2H"
// Invalid
"SBRPYHIL..." // Starts with S (secret key)
"GBRPYHIL" // Too short
"GBRPYHIL2CI3FNQ4BXLFMNDLFJUNPU2HY3ZMFSHONUCEOASW7QC7OX2!" // Invalid char- Must be exactly 64 characters
- Must contain only hexadecimal characters (0-9, a-f, A-F)
// Valid
"a1b2c3d4e5f6..." // 64 hex chars
// Invalid
"abc123" // Too short
"xyz..." // Non-hex characters- Both startDate and endDate required
- Must be valid ISO date format
- startDate must be before or equal to endDate
// Valid
startDate: "2024-01-01"
endDate: "2024-12-31"
// Invalid
startDate: "invalid"
startDate: "2024-12-31", endDate: "2024-01-01" // Reversed- Must exist in the database
- Returns 404 if wallet not found
Validates:
amount- Required, must be > 0recipient- Required, validated as Stellar address if starts with 'G'donor- Optional, validated as Stellar address if starts with 'G'- Ensures donor and recipient are different
Error Codes:
MISSING_FIELD- Required field missingINVALID_AMOUNT- Amount validation failedINVALID_STELLAR_ADDRESS- Invalid Stellar public key formatINVALID_TRANSACTION- Donor and recipient are the same
Validates:
transactionHash- Required, must be 64-char hex string
Error Codes:
MISSING_FIELD- Transaction hash missingINVALID_TRANSACTION_HASH- Invalid hash format
Validates:
startDate- Required query parameterendDate- Required query parameter- Date range validity
Error Codes:
MISSING_PARAMETERS- Missing date parametersINVALID_DATE_RANGE- Invalid date format or range
Validates:
name- RequiredwalletAddress- Required, must be valid Stellar public key- Checks for duplicate wallet addresses
Error Codes:
MISSING_FIELD- Required field missingINVALID_STELLAR_ADDRESS- Invalid Stellar address formatWALLET_EXISTS- Wallet address already registered (409 status)
Validates:
id- Must exist in database
Error Codes:
MISSING_PARAMETER- ID parameter missingWALLET_NOT_FOUND- Wallet doesn't exist (404 status)
Validates:
walletAddress- Required, must be valid Stellar public key
Error Codes:
MISSING_FIELD- Wallet address missingINVALID_STELLAR_ADDRESS- Invalid address formatWALLET_NOT_FOUND- No wallet with this address (404 status)
All validation errors follow a consistent format:
{
"success": false,
"error": {
"code": "ERROR_CODE",
"message": "Human-readable error message",
"field": "fieldName"
}
}HTTP Status Codes:
400- Bad Request (validation failed)404- Not Found (resource doesn't exist)409- Conflict (duplicate resource)500- Internal Server Error
Comprehensive test suites are provided:
-
Unit Tests (
tests/validation.test.js)- Tests all validation utility functions
- Covers edge cases and boundary conditions
-
Integration Tests (
tests/validation-middleware.test.js)- Tests validation middleware on actual routes
- Verifies error responses and status codes
Run tests:
npm test
npm test -- tests/validation.test.js
npm test -- tests/validation-middleware.test.js// Valid request
POST /donations
{
"amount": 10.5,
"donor": "GBRPYHIL2CI3FNQ4BXLFMNDLFJUNPU2HY3ZMFSHONUCEOASW7QC7OX2H",
"recipient": "GDQP2KPQGKIHYJGXNUIYOMHARUARCA7DJT5FO2FFOOKY3B2WSQHG4W37"
}
// Response: 201 Created
{
"success": true,
"data": {
"id": "1234567890",
"amount": 10.5,
"donor": "GBRP...",
"recipient": "GDQP...",
"timestamp": "2024-01-01T00:00:00.000Z",
"status": "completed"
}
}POST /donations
{
"amount": -5,
"recipient": "test-recipient"
}
// Response: 400 Bad Request
{
"success": false,
"error": {
"code": "INVALID_AMOUNT",
"message": "Amount must be a positive number greater than 0",
"field": "amount"
}
}POST /wallets
{
"name": "Test User",
"walletAddress": "INVALID123"
}
// Response: 400 Bad Request
{
"success": false,
"error": {
"code": "INVALID_STELLAR_ADDRESS",
"message": "Invalid Stellar public key format. Must start with G and be 56 characters",
"field": "walletAddress"
}
}Validation middleware is applied before route handlers:
router.post('/', validateDonationCreate, (req, res) => {
// Only executes if validation passes
});Common validation logic is extracted into reusable functions:
const { isValidStellarPublicKey, isValidAmount } = require('../utils/validators');
if (!isValidAmount(amount)) {
// Handle error
}Create custom validators for specific needs:
const validatePublicKey = (fieldName = 'publicKey') => {
return (req, res, next) => {
// Validation logic
};
};- Input Sanitization - All string inputs are trimmed
- Type Checking - Strict type validation prevents type coercion attacks
- Format Validation - Regex patterns ensure correct format
- Existence Checks - Database lookups verify resource existence
- Duplicate Prevention - Checks prevent duplicate wallet registrations
Potential improvements:
- Rate limiting per wallet address
- Advanced amount validation (min/max limits)
- Memo field validation for transactions
- Multi-signature validation
- Asset type validation (beyond XLM)