Skip to content

Commit

Permalink
refactor: give constructEvent utility outside of project SDK (but sti…
Browse files Browse the repository at this point in the history
…ll offer it)
  • Loading branch information
Looskie committed Oct 3, 2023
1 parent b923673 commit f28ef86
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 20 deletions.
23 changes: 4 additions & 19 deletions src/sdks/projects.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import type {API, Endpoints, Event, Id} from '../rest/index.ts';
import {constructEvent} from '../index.ts';
import type {API, Endpoints, Id} from '../rest/index.ts';
import {Request} from '../util/fetch.ts';
import {sdk} from './create.ts';
import type {PossibleWebhookIDs} from '../util/types.ts';
import {verifyHmac} from '../index.ts';
import {sdk} from './create.ts';

/**
* Projects SDK client
Expand Down Expand Up @@ -98,22 +98,7 @@ export const projects = sdk(client => {
};

const webhooks = {
/**
* Utility function that returns a type-safe webhook event, throws if signature is invalid.
*
* @param body The stringed body received from the request
* @param signature The signature from the X-Hop-Hooks-Signature
* @param secret The secret provided upon webhook creation to verify the signature. (e.x: whsec_xxxxx)
*/
async constructEvent(body: string, signature: string, secret: string) {
const hmacVerified = await verifyHmac(body, signature, secret);
if (!hmacVerified) {
throw new Error('Invalid signature');
}

const event = JSON.parse(body) as Event;
return event;
},
constructEvent,
async getAll(projectId?: Id<'project'>) {
if (client.authType !== 'ptk' && !projectId) {
throw new Error(
Expand Down
31 changes: 30 additions & 1 deletion src/util/webhooks.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import type {Event} from '..';
import {crypto} from './crypto';

export const POSSIBLE_EVENTS = {
Expand Down Expand Up @@ -161,6 +162,15 @@ export const POSSIBLE_EVENTS = {
],
} as const;

// Todo: maybe add type-fest/readonly-deep to keep the as const but also keep a structure type

/**
* Utility function to verify hmac signatures
*
* @param body The stringed body received from the request
* @param signature The signature from the X-Hop-Hooks-Signature
* @param secret The secret provided upon webhook creation to verify the signature. (e.x: whsec_xxxxx)
*/
export async function verifyHmac(
body: string,
signature: string,
Expand All @@ -186,4 +196,23 @@ export async function verifyHmac(
return signature.toLowerCase() === finalSig;
}

// Todo: maybe add type-fest/readonly-deep to keep the as const but also keep a structure type
/**
* Utility function that returns a type-safe webhook event, throws if signature is invalid.
*
* @param body The stringed body received from the request
* @param signature The signature from the X-Hop-Hooks-Signature
* @param secret The secret provided upon webhook creation to verify the signature. (e.x: whsec_xxxxx)
*/
export async function constructEvent(
body: string,
signature: string,
secret: string,
) {
const hmacVerified = await verifyHmac(body, signature, secret);
if (!hmacVerified) {
throw new Error('Invalid signature');
}

const event = JSON.parse(body) as Event;
return event;
}

0 comments on commit f28ef86

Please sign in to comment.