diff --git a/src/cmd/root.go b/src/cmd/root.go index 27fe650..d99fc69 100644 --- a/src/cmd/root.go +++ b/src/cmd/root.go @@ -3,6 +3,11 @@ package cmd import ( "embed" "fmt" + "log" + "net/http" + "os" + "strings" + "github.com/aldinokemal/go-whatsapp-web-multidevice/config" "github.com/aldinokemal/go-whatsapp-web-multidevice/internal/rest" "github.com/aldinokemal/go-whatsapp-web-multidevice/internal/rest/helpers" @@ -20,10 +25,6 @@ import ( "github.com/gofiber/template/html/v2" _ "github.com/mattn/go-sqlite3" "github.com/spf13/cobra" - "log" - "net/http" - "os" - "strings" ) var ( @@ -47,6 +48,7 @@ func init() { rootCmd.PersistentFlags().StringVarP(&config.AppBasicAuthCredential, "basic-auth", "b", config.AppBasicAuthCredential, "basic auth credential | -b=yourUsername:yourPassword") rootCmd.PersistentFlags().StringVarP(&config.WhatsappAutoReplyMessage, "autoreply", "", config.WhatsappAutoReplyMessage, `auto reply when received message --autoreply | example: --autoreply="Don't reply this message"`) rootCmd.PersistentFlags().StringVarP(&config.WhatsappWebhook, "webhook", "w", config.WhatsappWebhook, `forward event to webhook --webhook | example: --webhook="https://yourcallback.com/callback"`) + rootCmd.PersistentFlags().StringVarP(&config.WhatsappWebhookSecret, "webhook-secret", "", config.WhatsappWebhookSecret, `secure webhook request --webhook-secret | example: --webhook-secret="super-secret-key"`) rootCmd.PersistentFlags().BoolVarP(&config.WhatsappAccountValidation, "account-validation", "", config.WhatsappAccountValidation, `enable or disable account validation --account-validation | example: --account-validation=true`) } diff --git a/src/config/settings.go b/src/config/settings.go index 08f5e66..b072625 100644 --- a/src/config/settings.go +++ b/src/config/settings.go @@ -21,6 +21,7 @@ var ( WhatsappAutoReplyMessage string WhatsappWebhook string + WhatsappWebhookSecret = "secret" WhatsappLogLevel = "ERROR" WhatsappSettingMaxFileSize int64 = 50000000 // 50MB WhatsappSettingMaxVideoSize int64 = 100000000 // 100MB diff --git a/src/pkg/whatsapp/whatsapp.go b/src/pkg/whatsapp/whatsapp.go index 7570d70..d0f4953 100644 --- a/src/pkg/whatsapp/whatsapp.go +++ b/src/pkg/whatsapp/whatsapp.go @@ -3,8 +3,19 @@ package whatsapp import ( "bytes" "context" + "crypto/hmac" + "crypto/sha256" + "encoding/hex" "encoding/json" "fmt" + "mime" + "net/http" + "os" + "regexp" + "strings" + "sync/atomic" + "time" + "github.com/aldinokemal/go-whatsapp-web-multidevice/config" "github.com/aldinokemal/go-whatsapp-web-multidevice/internal/websocket" pkgError "github.com/aldinokemal/go-whatsapp-web-multidevice/pkg/error" @@ -19,13 +30,6 @@ import ( "go.mau.fi/whatsmeow/types/events" waLog "go.mau.fi/whatsmeow/util/log" "google.golang.org/protobuf/proto" - "mime" - "net/http" - "os" - "regexp" - "strings" - "sync/atomic" - "time" ) var ( @@ -299,6 +303,15 @@ func handler(rawEvt interface{}) { } } +func getMessageDigestOrSignature(msg, key []byte) (string, error) { + mac := hmac.New(sha256.New, key) + _, err := mac.Write(msg) + if err != nil { + return "", err + } + return hex.EncodeToString(mac.Sum(nil)), nil +} + // forwardToWebhook is a helper function to forward event to webhook url func forwardToWebhook(evt *events.Message) error { logrus.Info("Forwarding event to webhook:", config.WhatsappWebhook) @@ -400,7 +413,16 @@ func forwardToWebhook(evt *events.Message) error { if err != nil { return pkgError.WebhookError(fmt.Sprintf("error when create http object %v", err)) } + + secretKey := []byte(config.WhatsappWebhookSecret) + signature, err := getMessageDigestOrSignature(postBody, secretKey) + if err != nil { + return pkgError.WebhookError(fmt.Sprintf("error when create signature %v", err)) + } + req.Header.Set("Content-Type", "application/json") + req.Header.Set("X-Hub-Signature-256", fmt.Sprintf("sha256=%s", signature)) + if _, err = client.Do(req); err != nil { return pkgError.WebhookError(fmt.Sprintf("error when submit webhook %v", err)) }