1- const crypto = require ( "node:crypto " ) ;
1+ const base64 = require ( "@hexagon/base64 " ) ;
22
33const ApiError = require ( "./error" ) ;
44
@@ -72,12 +72,10 @@ async function validateWebhook(requestData, secret) {
7272
7373 const signedContent = `${ id } .${ timestamp } .${ body } ` ;
7474
75- const secretBytes = Buffer . from ( signingSecret . split ( "_" ) [ 1 ] , "base64" ) ;
76-
77- const computedSignature = crypto
78- . createHmac ( "sha256" , secretBytes )
79- . update ( signedContent )
80- . digest ( "base64" ) ;
75+ const computedSignature = await createHMACSHA256 (
76+ signingSecret . split ( "_" ) . pop ( ) ,
77+ signedContent
78+ ) ;
8179
8280 const expectedSignatures = signature
8381 . split ( " " )
@@ -88,6 +86,24 @@ async function validateWebhook(requestData, secret) {
8886 ) ;
8987}
9088
89+ /**
90+ * @param {string } secret - base64 encoded string
91+ * @param {string } data - text body of request
92+ */
93+ async function createHMACSHA256 ( secret , data ) {
94+ const encoder = new TextEncoder ( ) ;
95+ const key = await crypto . subtle . importKey (
96+ "raw" ,
97+ base64 . toArrayBuffer ( secret ) ,
98+ { name : "HMAC" , hash : "SHA-256" } ,
99+ false ,
100+ [ "sign" ]
101+ ) ;
102+
103+ const signature = await crypto . subtle . sign ( "HMAC" , key , encoder . encode ( data ) ) ;
104+ return base64 . fromArrayBuffer ( signature ) ;
105+ }
106+
91107/**
92108 * Automatically retry a request if it fails with an appropriate status code.
93109 *
0 commit comments