| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161 |
- #!/usr/bin/env node
- /**
- * Test script for webhook signature verification
- * Tests both valid and invalid signatures to ensure security is working
- */
- import crypto from 'crypto';
- import http from 'http';
- const TEST_PORT = 3099;
- const TEST_SECRET = 'test-secret-12345';
- // Test payload
- const payload = JSON.stringify({
- ref: 'refs/heads/main',
- repository: {
- name: 'test-repo',
- full_name: 'user/test-repo'
- },
- pusher: {
- username: 'testuser'
- }
- });
- // Generate valid signature
- function generateSignature(payload, secret) {
- const hmac = crypto.createHmac('sha256', secret);
- hmac.update(payload, 'utf8');
- return hmac.digest('hex');
- }
- // Send webhook request
- async function sendWebhook(port, payload, signature, description) {
- return new Promise((resolve, reject) => {
- const options = {
- hostname: '127.0.0.1',
- port: port,
- path: '/webhook',
- method: 'POST',
- headers: {
- 'Content-Type': 'application/json',
- 'Content-Length': Buffer.byteLength(payload),
- 'X-Gogs-Event': 'push',
- 'X-Gogs-Delivery': '12345'
- }
- };
- if (signature) {
- options.headers['X-Gogs-Signature'] = signature;
- }
- const req = http.request(options, (res) => {
- let data = '';
- res.on('data', chunk => data += chunk);
- res.on('end', () => {
- resolve({
- statusCode: res.statusCode,
- body: data,
- description
- });
- });
- });
- req.on('error', reject);
- req.write(payload);
- req.end();
- });
- }
- // Start test server
- async function startTestServer() {
- const { WebhookServer } = await import('./src/server.js');
- const server = new WebhookServer({
- host: '127.0.0.1',
- port: TEST_PORT,
- secret: TEST_SECRET
- });
- return new Promise((resolve) => {
- server.start();
- // Give server time to start
- setTimeout(() => resolve(server), 500);
- });
- }
- // Run tests
- async function runTests() {
- console.log('🧪 Starting signature verification tests...\n');
- const server = await startTestServer();
- try {
- // Test 1: Valid signature
- const validSignature = generateSignature(payload, TEST_SECRET);
- const test1 = await sendWebhook(
- TEST_PORT,
- payload,
- validSignature,
- 'Valid signature'
- );
- console.log(`✓ Test 1: ${test1.description}`);
- console.log(` Status: ${test1.statusCode} ${test1.statusCode === 200 ? '✓ PASS' : '✗ FAIL'}`);
- console.log(` Response: ${test1.body}\n`);
- // Test 2: Invalid signature
- const test2 = await sendWebhook(
- TEST_PORT,
- payload,
- 'invalid-signature-123',
- 'Invalid signature'
- );
- console.log(`✓ Test 2: ${test2.description}`);
- console.log(` Status: ${test2.statusCode} ${test2.statusCode === 401 ? '✓ PASS' : '✗ FAIL'}`);
- console.log(` Response: ${test2.body}\n`);
- // Test 3: Missing signature
- const test3 = await sendWebhook(
- TEST_PORT,
- payload,
- null,
- 'Missing signature'
- );
- console.log(`✓ Test 3: ${test3.description}`);
- console.log(` Status: ${test3.statusCode} ${test3.statusCode === 401 ? '✓ PASS' : '✗ FAIL'}`);
- console.log(` Response: ${test3.body}\n`);
- // Summary
- const results = [test1, test2, test3];
- const passed = results.filter((r, i) => {
- if (i === 0) return r.statusCode === 200;
- return r.statusCode === 401;
- }).length;
- console.log('═══════════════════════════════════════');
- console.log(`Results: ${passed}/3 tests passed`);
- console.log('═══════════════════════════════════════\n');
- if (passed === 3) {
- console.log('✅ All signature verification tests passed!');
- console.log(' - Valid signatures are accepted (200)');
- console.log(' - Invalid signatures are rejected (401)');
- console.log(' - Missing signatures are rejected (401)');
- } else {
- console.log('❌ Some tests failed!');
- process.exitCode = 1;
- }
- } finally {
- await server.stop();
- console.log('\n🛑 Test server stopped');
- }
- }
- runTests().catch(err => {
- console.error('❌ Test error:', err);
- process.exit(1);
- });
|