297 lines
9.8 KiB
JavaScript
297 lines
9.8 KiB
JavaScript
/**
|
||
* Test script to verify PAN API through localhost
|
||
* This script tests the Setu API integration through your local API server
|
||
* Usage: node scripts/test-localhost-pan.js
|
||
*/
|
||
|
||
require('dotenv').config();
|
||
const axios = require('axios');
|
||
const crypto = require('crypto');
|
||
const { query, connectDB } = require('../src/database/connection');
|
||
|
||
// Static Setu API credentials (from your curl command)
|
||
const SETU_CREDENTIALS = {
|
||
PAN_PROVIDER_URL: 'https://dg-sandbox.setu.co/api/verify/pan',
|
||
PAN_CLIENT_ID: '292c6e76-dabf-49c4-8e48-90fba2916673',
|
||
PAN_CLIENT_SECRET: '7IZMe9zvoBBuBukLiCP7n4KLwSOy11oP',
|
||
PAN_PRODUCT_INSTANCE_ID: '439244ff-114e-41a8-ae74-a783f160622d'
|
||
};
|
||
|
||
const LOCALHOST_URL = process.env.LOCALHOST_URL || 'http://localhost:3000';
|
||
const TEST_PAN = 'ABCDE1234A';
|
||
|
||
// Function to generate API key
|
||
function generateApiKey(type = 'test') {
|
||
const prefix = type === 'test' ? 'vf_test_' : 'vf_live_';
|
||
return prefix + crypto.randomBytes(24).toString('hex');
|
||
}
|
||
|
||
// Function to create or get test API key
|
||
async function getOrCreateTestApiKey() {
|
||
try {
|
||
await connectDB();
|
||
|
||
// Check if test user exists
|
||
let testUser = await query(
|
||
'SELECT * FROM users WHERE email = $1',
|
||
['test@example.com']
|
||
);
|
||
|
||
let userId;
|
||
|
||
if (testUser.rows.length === 0) {
|
||
// Create test user
|
||
const bcrypt = require('bcryptjs');
|
||
const passwordHash = await bcrypt.hash('testpassword123', 10);
|
||
|
||
const userResult = await query(
|
||
`INSERT INTO users (email, password_hash, company_name, plan, monthly_quota, quota_reset_date, is_active)
|
||
VALUES ($1, $2, $3, $4, $5, DATE(NOW() + INTERVAL '1 month'), true)
|
||
RETURNING id, email, plan`,
|
||
['test@example.com', passwordHash, 'Test Company', 'free', 10000]
|
||
);
|
||
|
||
userId = userResult.rows[0].id;
|
||
} else {
|
||
userId = testUser.rows[0].id;
|
||
}
|
||
|
||
// Check for existing active test API key
|
||
const existingKeys = await query(
|
||
`SELECT ak.* FROM api_keys ak
|
||
WHERE ak.user_id = $1 AND ak.is_test_key = true AND ak.is_active = true
|
||
ORDER BY ak.created_at DESC
|
||
LIMIT 1`,
|
||
[userId]
|
||
);
|
||
|
||
if (existingKeys.rows.length > 0) {
|
||
// We can't retrieve the original key, so we'll need to create a new one
|
||
// But first, let's try to use the existing one by checking if we can authenticate
|
||
// For now, let's create a new one to be safe
|
||
console.log(' ℹ️ Found existing test API key, creating a new one...');
|
||
|
||
// Deactivate old keys
|
||
await query(
|
||
'UPDATE api_keys SET is_active = false WHERE user_id = $1 AND is_test_key = true',
|
||
[userId]
|
||
);
|
||
}
|
||
|
||
// Generate new API key
|
||
const apiKey = generateApiKey('test');
|
||
const keyHash = crypto.createHash('sha256').update(apiKey).digest('hex');
|
||
|
||
await query(
|
||
`INSERT INTO api_keys (user_id, key_prefix, key_hash, key_hint, name, is_test_key, is_active)
|
||
VALUES ($1, $2, $3, $4, $5, true, true)`,
|
||
[userId, 'vf_test_', keyHash, apiKey.slice(-4), 'Test Key']
|
||
);
|
||
|
||
return apiKey;
|
||
} catch (error) {
|
||
console.error(' ❌ Error creating API key:', error.message);
|
||
throw error;
|
||
}
|
||
}
|
||
|
||
// Function to check if server is running
|
||
async function checkServerRunning() {
|
||
try {
|
||
const response = await axios.get(`${LOCALHOST_URL}/health`, {
|
||
timeout: 3000
|
||
});
|
||
return response.status === 200;
|
||
} catch (error) {
|
||
return false;
|
||
}
|
||
}
|
||
|
||
// Function to update .env file with Setu credentials
|
||
async function updateEnvFile() {
|
||
const fs = require('fs');
|
||
const path = require('path');
|
||
const envPath = path.join(__dirname, '..', '.env');
|
||
|
||
try {
|
||
let envContent = '';
|
||
|
||
// Read existing .env if it exists
|
||
if (fs.existsSync(envPath)) {
|
||
envContent = fs.readFileSync(envPath, 'utf8');
|
||
}
|
||
|
||
// Update or add Setu credentials
|
||
const updates = {
|
||
'PAN_PROVIDER_URL': SETU_CREDENTIALS.PAN_PROVIDER_URL,
|
||
'PAN_CLIENT_ID': SETU_CREDENTIALS.PAN_CLIENT_ID,
|
||
'PAN_CLIENT_SECRET': SETU_CREDENTIALS.PAN_CLIENT_SECRET,
|
||
'PAN_PRODUCT_INSTANCE_ID': SETU_CREDENTIALS.PAN_PRODUCT_INSTANCE_ID
|
||
};
|
||
|
||
let updated = false;
|
||
for (const [key, value] of Object.entries(updates)) {
|
||
const regex = new RegExp(`^${key}=.*$`, 'm');
|
||
if (regex.test(envContent)) {
|
||
envContent = envContent.replace(regex, `${key}=${value}`);
|
||
updated = true;
|
||
} else {
|
||
// Add new line if file doesn't end with newline
|
||
if (envContent && !envContent.endsWith('\n')) {
|
||
envContent += '\n';
|
||
}
|
||
envContent += `${key}=${value}\n`;
|
||
updated = true;
|
||
}
|
||
}
|
||
|
||
if (updated) {
|
||
fs.writeFileSync(envPath, envContent, 'utf8');
|
||
console.log(' ✅ Updated .env file with Setu credentials');
|
||
return true;
|
||
}
|
||
|
||
return false;
|
||
} catch (error) {
|
||
console.log(' ⚠️ Could not update .env file:', error.message);
|
||
console.log(' ℹ️ Please manually add these to your .env file:');
|
||
console.log(` PAN_PROVIDER_URL=${SETU_CREDENTIALS.PAN_PROVIDER_URL}`);
|
||
console.log(` PAN_CLIENT_ID=${SETU_CREDENTIALS.PAN_CLIENT_ID}`);
|
||
console.log(` PAN_CLIENT_SECRET=${SETU_CREDENTIALS.PAN_CLIENT_SECRET}`);
|
||
console.log(` PAN_PRODUCT_INSTANCE_ID=${SETU_CREDENTIALS.PAN_PRODUCT_INSTANCE_ID}`);
|
||
return false;
|
||
}
|
||
}
|
||
|
||
// Main test function
|
||
async function testLocalhostPAN() {
|
||
console.log('\n🧪 Testing PAN API through Localhost\n');
|
||
console.log('='.repeat(70));
|
||
|
||
// Step 1: Check server is running
|
||
console.log('\n📡 Step 1: Checking if server is running...');
|
||
const serverRunning = await checkServerRunning();
|
||
|
||
if (!serverRunning) {
|
||
console.log(' ❌ Server is not running!');
|
||
console.log('\n Please start the server first:');
|
||
console.log(' npm start');
|
||
console.log(' or');
|
||
console.log(' npm run dev');
|
||
process.exit(1);
|
||
}
|
||
console.log(' ✅ Server is running on', LOCALHOST_URL);
|
||
|
||
// Step 2: Update .env file with Setu credentials
|
||
console.log('\n⚙️ Step 2: Setting up Setu API credentials...');
|
||
const envUpdated = await updateEnvFile();
|
||
if (envUpdated) {
|
||
console.log(' ⚠️ Note: If your server was already running, restart it to load new credentials');
|
||
console.log(' Restart command: Press Ctrl+C and run "npm start" again');
|
||
}
|
||
|
||
// Step 3: Create/get API key
|
||
console.log('\n🔑 Step 3: Creating test API key...');
|
||
let apiKey;
|
||
try {
|
||
apiKey = await getOrCreateTestApiKey();
|
||
console.log(' ✅ Test API key created:', apiKey);
|
||
} catch (error) {
|
||
console.log(' ❌ Failed to create API key:', error.message);
|
||
console.log(' Make sure your database is running and migrations are applied');
|
||
process.exit(1);
|
||
}
|
||
|
||
// Step 4: Test the API endpoint
|
||
console.log('\n🚀 Step 4: Testing PAN verification endpoint...');
|
||
console.log(` URL: ${LOCALHOST_URL}/v1/pan/verify`);
|
||
console.log(` PAN: ${TEST_PAN}`);
|
||
|
||
try {
|
||
const startTime = Date.now();
|
||
|
||
const response = await axios.post(
|
||
`${LOCALHOST_URL}/v1/pan/verify`,
|
||
{
|
||
pan: TEST_PAN,
|
||
consent: 'Y',
|
||
reason: 'Testing'
|
||
},
|
||
{
|
||
headers: {
|
||
'Content-Type': 'application/json',
|
||
'x-api-key': apiKey
|
||
},
|
||
timeout: 30000
|
||
}
|
||
);
|
||
|
||
const endTime = Date.now();
|
||
const duration = endTime - startTime;
|
||
|
||
console.log('\n ✅ SUCCESS! API is working correctly!\n');
|
||
console.log('='.repeat(70));
|
||
console.log('\n📊 Response Details:');
|
||
console.log(` Status Code: ${response.status} ${response.statusText}`);
|
||
console.log(` Response Time: ${duration}ms`);
|
||
console.log(`\n📦 Response Body:`);
|
||
console.log(JSON.stringify(response.data, null, 2));
|
||
|
||
if (response.data.success && response.data.data) {
|
||
console.log('\n✅ PAN Verification Successful!');
|
||
if (response.data.data.full_name) {
|
||
console.log(` PAN Holder: ${response.data.data.full_name}`);
|
||
}
|
||
if (response.data.data.status) {
|
||
console.log(` Status: ${response.data.data.status}`);
|
||
}
|
||
}
|
||
|
||
console.log('\n' + '='.repeat(70));
|
||
console.log('\n✅ All tests passed! Your localhost API is working correctly!\n');
|
||
|
||
} catch (error) {
|
||
console.log('\n ❌ ERROR! API request failed!\n');
|
||
console.log('='.repeat(70));
|
||
|
||
if (error.response) {
|
||
console.log('\n📊 Error Response:');
|
||
console.log(` Status Code: ${error.response.status} ${error.response.statusText}`);
|
||
console.log(`\n📦 Error Body:`);
|
||
console.log(JSON.stringify(error.response.data, null, 2));
|
||
|
||
console.log('\n⚠️ Possible Issues:');
|
||
if (error.response.status === 401) {
|
||
console.log(' - Invalid API key (try running this script again to create a new key)');
|
||
} else if (error.response.status === 500) {
|
||
console.log(' - Server error (check server logs)');
|
||
console.log(' - Make sure Setu credentials are in .env file');
|
||
console.log(' - Restart the server after updating .env');
|
||
} else if (error.response.status === 400) {
|
||
console.log(' - Bad request (check PAN format)');
|
||
}
|
||
} else if (error.request) {
|
||
console.log('\n⚠️ No response received from server');
|
||
console.log(` Error: ${error.message}`);
|
||
console.log('\n Possible Issues:');
|
||
console.log(' - Server is not running');
|
||
console.log(' - Wrong URL (check LOCALHOST_URL)');
|
||
console.log(' - Network connectivity problem');
|
||
} else {
|
||
console.log(`\n⚠️ Request setup error: ${error.message}`);
|
||
}
|
||
|
||
console.log('\n' + '='.repeat(70));
|
||
console.log('\n❌ Test failed!\n');
|
||
process.exit(1);
|
||
}
|
||
}
|
||
|
||
// Run the test
|
||
testLocalhostPAN().catch(error => {
|
||
console.error('\n❌ Unexpected error:', error.message);
|
||
console.error(error);
|
||
process.exit(1);
|
||
});
|
||
|