Skip to content

Commit

Permalink
feat(subscription): add an validateSignature method
Browse files Browse the repository at this point in the history
  • Loading branch information
Charles Coeurderoy committed Jun 25, 2020
1 parent 9118ce9 commit ee65d78
Show file tree
Hide file tree
Showing 2 changed files with 84 additions and 0 deletions.
18 changes: 18 additions & 0 deletions src/core/Subscription.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { createHmac } from 'crypto';

import { EventName, SubscriptionStatus, ISubscription, PostSubscriptionDTO, PatchSubscriptionDTO } from '../lib';
import { RequestBuilder } from '../RequestBuilder';

Expand Down Expand Up @@ -76,4 +78,20 @@ export class Subscription {

this.status = body.status;
}

/**
* Validates an Algoan Resthook with the "x-hub-signature" header
* More information here: https://developers.algoan.com/public/docs/algoan_documentation/resthooks_and_events/resthooks.html#validating-resthook-events
* @param signatureHeader Signature header received
* @param payload Payload sent
*/
public validateSignature(signatureHeader: string, payload: { [key: string]: string }): boolean {
if (this.secret === undefined) {
return true;
}

const expectedHash: string = createHmac('sha256', this.secret).update(JSON.stringify(payload)).digest('hex');

return expectedHash === signatureHeader;
}
}
66 changes: 66 additions & 0 deletions test/subscription.test.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { createHmac } from 'crypto';
import * as nock from 'nock';

import { RequestBuilder } from '../src/RequestBuilder';
Expand Down Expand Up @@ -139,4 +140,69 @@ describe('Tests related to the Subscription class', () => {
expect(subscription.status).toEqual('ACTIVE');
});
});

describe('validateSignature()', () => {
const baseUrl: string = 'http://localhost:3000';
let requestBuilder: RequestBuilder;
const secret: string = 'random_secret';
const fakePayloadSent: {} = {
banksUserId: 'id',
};
const hash: string = createHmac('sha256', secret).update(JSON.stringify(fakePayloadSent)).digest('hex');

beforeEach(() => {
requestBuilder = new RequestBuilder(baseUrl, {
clientId: 'a',
clientSecret: 's',
});
});

afterEach(() => {
jest.clearAllMocks();
nock.cleanAll();
});
it('SB030 - should be valid - no secret defined', () => {
const subscription: Subscription = new Subscription(
{
target: baseUrl,
id: '1',
eventName: EventName.APPLICATION_UPDATED,
status: 'DISABLE',
},
requestBuilder,
);

expect(subscription.validateSignature(hash, fakePayloadSent)).toBeTruthy();
});

it('SB031 - should be valid', () => {
const subscription: Subscription = new Subscription(
{
target: baseUrl,
id: '1',
eventName: EventName.APPLICATION_UPDATED,
status: 'DISABLE',
secret,
},
requestBuilder,
);

expect(subscription.validateSignature(hash, fakePayloadSent)).toBeTruthy();
});

it('SB032 - should not be valid', () => {
const subscription: Subscription = new Subscription(
{
target: baseUrl,
id: '1',
eventName: EventName.APPLICATION_UPDATED,
status: 'DISABLE',
secret: 'other_secret',
},
requestBuilder,
);

expect(subscription.validateSignature(hash, fakePayloadSent)).toBeFalsy();
});
});
});

0 comments on commit ee65d78

Please sign in to comment.