UNPKG

vhook-js

Version:

Verifyable Webhooks

119 lines (99 loc) 4.9 kB
// test/vhook-import.test.js import assert from 'assert'; import vhook from '../vhook.mjs'; // Adjust the path as necessary import jwt from 'jsonwebtoken'; describe('VHooks Module Import Test', function () { let keys, privateKey, publicKey, now, payload, token; before(async function () { // Generate key pair before running tests keys = await vhook.create_vhook_keypair(); privateKey = keys.privateKey.pem; publicKey = keys.publicKey.pem; now = Math.floor(Date.now()/1000); }); describe('vhook import', function () { it('should have all the expected functions', function () { assert.ok(typeof vhook.create_vhook_keypair === 'function', 'create_vhook_keypair is not a function'); assert.ok(typeof vhook.create_vhook === 'function', 'create_vhook is not a function'); assert.ok(typeof vhook.decode_vhook === 'function', 'decode_vhook is not a function'); assert.ok(typeof vhook.decode_vhook_without_validation === 'function', 'decode_vhook_without_validation is not a function'); assert.ok(typeof vhook.prepare_vhook_payload === 'function', 'prepare_vhook_payload is not a function'); assert.ok(typeof vhook.extract_vhook_payload === 'function', 'extract_vhook_payload is not a function'); }); }); describe('create_vhook_keypair()', function () { it('should generate a valid RSA key pair', function () { assert.ok(keys.privateKey); assert.ok(keys.publicKey); assert.ok(keys.privateKey.pem); assert.ok(keys.publicKey.pem); // Check that keys are in PEM format assert.ok(keys.privateKey.pem.includes('-----BEGIN RSA PRIVATE KEY-----')); assert.ok(keys.publicKey.pem.includes('-----BEGIN PUBLIC KEY-----')); }); }); describe('create_vhook()', function () { it('should create a signed VHook token', function () { payload = { issuer: 'https://yourservice.com', audience: 'https://receiver-service.com/webhook-endpoint', origin: 'customer', event: 'customer.updated', data: { customer_id: '12345', name: 'Jane Doe', email: 'jane.doe@example.com', }, issued_at: now, expiration: now + 60, // Expires in 60 seconds message_id: 'test-message-id', }; token = vhook.create_vhook(payload, privateKey); assert.strictEqual(typeof token, 'string'); // Token should have three parts separated by dots assert.strictEqual(token.split('.').length, 3); }); it('should include msg_id in the payload', function () { const decoded = jwt.decode(token); assert.ok(decoded.jti); assert.strictEqual(typeof decoded.jti, 'string'); }); }); describe('decode_vhook()', function () { it('should decode and verify the VHook token', function () { const decodedPayload = vhook.decode_vhook(token, publicKey); // Check that the decoded payload matches the original payload assert.deepStrictEqual(decodedPayload.origin, payload.origin); assert.deepStrictEqual(decodedPayload.event, payload.event); assert.deepStrictEqual(decodedPayload.data, payload.data); // Check that standard claims are present assert.strictEqual(decodedPayload.issuer, payload.issuer); assert.strictEqual(decodedPayload.audience, payload.audience); // Compare date fields as Date objects assert.deepStrictEqual(decodedPayload.expiration, new Date(payload.expiration * 1000)); assert.deepStrictEqual(decodedPayload.issued_at, new Date(payload.issued_at * 1000)); // Ensure message_id is present and matches assert.strictEqual(decodedPayload.message_id, payload.message_id); }); }); describe('decode_vhook_without_validation()', function () { it('should decode the VHook token without verifying the signature', function () { const decodedPayload = vhook.decode_vhook_without_validation(token); assert.deepStrictEqual(decodedPayload.origin, payload.origin); assert.deepStrictEqual(decodedPayload.event, payload.event); assert.deepStrictEqual(decodedPayload.data, payload.data); assert.ok(decodedPayload.message_id); }); it('should decode a tampered token without error', function () { // Use the previously tampered token const parts = token.split('.'); const tamperedPayload = Buffer.from(parts[1], 'base64').toString('utf8'); const tamperedPayloadObj = JSON.parse(tamperedPayload); tamperedPayloadObj.origin = 'attacker'; const newPayload = Buffer.from(JSON.stringify(tamperedPayloadObj)).toString('base64').replace(/=/g, ''); const tamperedToken = `${parts[0]}.${newPayload}.${parts[2]}`; const decodedPayload = vhook.decode_vhook_without_validation(tamperedToken); assert.strictEqual(decodedPayload.origin, 'attacker'); }); }); });