@@ -604,4 +604,51 @@ describe("createNodeMiddleware(webhooks)", () => {
604604
605605 server . close ( ) ;
606606 } ) ;
607+
608+ test ( "Handles invalid signature" , async ( ) => {
609+ expect . assertions ( 3 ) ;
610+
611+ const webhooks = new Webhooks ( {
612+ secret : "mySecret" ,
613+ } ) ;
614+
615+ webhooks . onError ( ( error ) => {
616+ expect ( error . message ) . toContain (
617+ "signature does not match event payload and secret" ,
618+ ) ;
619+ } ) ;
620+
621+ const log = {
622+ debug : jest . fn ( ) ,
623+ info : jest . fn ( ) ,
624+ warn : jest . fn ( ) ,
625+ error : jest . fn ( ) ,
626+ } ;
627+ const middleware = createNodeMiddleware ( webhooks , { log } ) ;
628+ const server = createServer ( middleware ) . listen ( ) ;
629+
630+ // @ts -expect-error complains about { port } although it's included in returned AddressInfo interface
631+ const { port } = server . address ( ) ;
632+
633+ const response = await fetch (
634+ `http://localhost:${ port } /api/github/webhooks` ,
635+ {
636+ method : "POST" ,
637+ headers : {
638+ "Content-Type" : "application/json" ,
639+ "X-GitHub-Delivery" : "1" ,
640+ "X-GitHub-Event" : "push" ,
641+ "X-Hub-Signature-256" : "" ,
642+ } ,
643+ body : pushEventPayload ,
644+ } ,
645+ ) ;
646+
647+ expect ( response . status ) . toEqual ( 400 ) ;
648+ await expect ( response . text ( ) ) . resolves . toBe (
649+ '{"error":"Error: [@octokit/webhooks] signature does not match event payload and secret"}' ,
650+ ) ;
651+
652+ server . close ( ) ;
653+ } ) ;
607654} ) ;
0 commit comments