File tree Expand file tree Collapse file tree
packages/wallet/backend/src Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -8,6 +8,7 @@ RATE_API_KEY=
88
99GATEHUB_ACCESS_KEY =
1010GATEHUB_SECRET_KEY =
11+ GATEHUB_WEBHOOK_SECRET =
1112GATEHUB_GATEWAY_UUID =
1213GATEHUB_VAULT_UUID_EUR =
1314GATEHUB_VAULT_UUID_USD =
Original file line number Diff line number Diff line change @@ -52,6 +52,7 @@ services:
5252 KRATOS_ADMIN_URL : ' http://kratos:4434/admin'
5353 GATEHUB_ACCESS_KEY : ${GATEHUB_ACCESS_KEY}
5454 GATEHUB_SECRET_KEY : ${GATEHUB_SECRET_KEY}
55+ GATEHUB_WEBHOOK_SECRET : ${GATEHUB_WEBHOOK_SECRET}
5556 GATEHUB_GATEWAY_UUID : ${GATEHUB_GATEWAY_UUID}
5657 GATEHUB_VAULT_UUID_EUR : ${GATEHUB_VAULT_UUID_EUR}
5758 GATEHUB_VAULT_UUID_USD : ${GATEHUB_VAULT_UUID_USD}
Original file line number Diff line number Diff line change @@ -29,6 +29,7 @@ WALLET_BACKEND_AUTH_DOMAIN=
2929WALLET_BACKEND_GATEHUB_ENV =
3030WALLET_BACKEND_GATEHUB_ACCESS_KEY =
3131WALLET_BACKEND_GATEHUB_SECRET_KEY =
32+ WALLET_BACKEND_GATEHUB_WEBHOOK_SECRET =
3233WALLET_BACKEND_GATEHUB_GATEWAY_UUID =
3334WALLET_BACKEND_GATEHUB_VAULT_UUID_EUR =
3435WALLET_BACKEND_GATEHUB_VAULT_UUID_USD =
Original file line number Diff line number Diff line change @@ -64,6 +64,7 @@ services:
6464 GATEHUB_ENV : ${WALLET_BACKEND_GATEHUB_ENV}
6565 GATEHUB_ACCESS_KEY : ${WALLET_BACKEND_GATEHUB_ACCESS_KEY}
6666 GATEHUB_SECRET_KEY : ${WALLET_BACKEND_GATEHUB_SECRET_KEY}
67+ GATEHUB_WEBHOOK_SECRET : ${WALLET_BACKEND_GATEHUB_WEBHOOK_SECRET}
6768 GATEHUB_GATEWAY_UUID : ${WALLET_BACKEND_GATEHUB_GATEWAY_UUID}
6869 GATEHUB_VAULT_UUID_EUR : ${WALLET_BACKEND_GATEHUB_VAULT_UUID_EUR}
6970 GATEHUB_VAULT_UUID_USD : ${WALLET_BACKEND_GATEHUB_VAULT_UUID_USD}
Original file line number Diff line number Diff line change @@ -44,6 +44,7 @@ import { GateHubService } from '@/gatehub/service'
4444import { CardController } from './card/controller'
4545import { CardService } from './card/service'
4646import { isRafikiSignedWebhook } from '@/middleware/isRafikiSignedWebhook'
47+ import { isGateHubSignedWebhook } from '@/middleware/isGateHubSignedWebhook'
4748
4849export interface Bindings {
4950 env : Env
@@ -309,7 +310,11 @@ export class App {
309310
310311 // GateHub
311312 router . get ( '/iframe-urls/:type' , isAuth , gateHubController . getIframeUrl )
312- router . post ( '/gatehub-webhooks' , gateHubController . webhook )
313+ router . post (
314+ '/gatehub-webhooks' ,
315+ isGateHubSignedWebhook ,
316+ gateHubController . webhook
317+ )
313318 router . post (
314319 '/gatehub/add-user-to-gateway' ,
315320 isAuth ,
Original file line number Diff line number Diff line change @@ -15,6 +15,7 @@ const envSchema = z.object({
1515 GATEHUB_ENV : z . enum ( [ 'production' , 'sandbox' ] ) . default ( 'sandbox' ) ,
1616 GATEHUB_ACCESS_KEY : z . string ( ) . default ( 'GATEHUB_ACCESS_KEY' ) ,
1717 GATEHUB_SECRET_KEY : z . string ( ) . default ( 'GATEHUB_SECRET_KEY' ) ,
18+ GATEHUB_WEBHOOK_SECRET : z . string ( ) . default ( 'GATEHUB_WEBHOOK_SECRET' ) ,
1819 GATEHUB_GATEWAY_UUID : z . string ( ) . default ( 'GATEHUB_GATEWAY_UUID' ) ,
1920 GATEHUB_VAULT_UUID_EUR : z . string ( ) . default ( 'GATEHUB_VAULT_UUID_EUR' ) ,
2021 GATEHUB_VAULT_UUID_USD : z . string ( ) . default ( 'GATEHUB_VAULT_UUID_USD' ) ,
Original file line number Diff line number Diff line change @@ -52,8 +52,8 @@ export class GateHubController implements IGateHubController {
5252 next : NextFunction
5353 ) => {
5454 try {
55- // TODO: implement signature check
5655 if ( ! req . body . uuid ) {
56+ res . status ( 200 ) . json ( )
5757 return
5858 }
5959
Original file line number Diff line number Diff line change 1+ import type { NextFunction , Request , Response } from 'express'
2+ import { Unauthorized } from '@shared/backend'
3+ import { env } from '@/config/env'
4+ import { createHmac } from 'crypto'
5+
6+ const TOLERANCE_MILLISECONDS = 5000
7+ export const isGateHubSignedWebhook = async (
8+ req : Request ,
9+ res : Response ,
10+ next : NextFunction
11+ ) : Promise < void > => {
12+ try {
13+ if ( ! req . body . timestamp ) {
14+ // Respond with 200 on initial setup call
15+ res . status ( 200 ) . json ( )
16+ return
17+ }
18+
19+ const body = JSON . stringify ( req . body )
20+ const key = Buffer . from ( env . GATEHUB_WEBHOOK_SECRET , 'hex' )
21+ const messageBuffer = Buffer . from ( body , 'utf-8' )
22+
23+ const requestSignature = createHmac ( 'sha256' , key )
24+ . update ( messageBuffer )
25+ . digest ( 'hex' )
26+
27+ const timeDiffMilliseconds =
28+ new Date ( ) . getTime ( ) - parseFloat ( req . body . timestamp )
29+
30+ // Check the difference of the received and current timestamp based on your tolerance
31+ const timestampIsValid = timeDiffMilliseconds < TOLERANCE_MILLISECONDS
32+ const signatureIsValid =
33+ requestSignature === req . headers [ 'x-gh-webhook-signature' ]
34+
35+ const isSignatureValid = timestampIsValid && signatureIsValid
36+
37+ if ( ! isSignatureValid ) {
38+ throw new Unauthorized ( 'Invalid signature header' )
39+ }
40+ } catch ( e ) {
41+ next ( e )
42+ }
43+
44+ next ( )
45+ }
You can’t perform that action at this time.
0 commit comments