From b8a73e1cf7d10d0b709768f1a450331067e2ddd7 Mon Sep 17 00:00:00 2001 From: "koreaplayer99@gmail.com" Date: Wed, 15 Jan 2025 16:03:14 +0000 Subject: [PATCH] feat: Jandi Notify --- cmd/integration-test/test-config.yaml | 4 +++ pkg/providers/jandi/jandi.go | 52 +++++++++++++++++++++++++++ pkg/providers/jandi/jandi_api.go | 36 +++++++++++++++++++ pkg/providers/jandi/jandi_types.go | 11 ++++++ pkg/providers/providers.go | 11 ++++++ 5 files changed, 114 insertions(+) create mode 100644 pkg/providers/jandi/jandi.go create mode 100644 pkg/providers/jandi/jandi_api.go create mode 100644 pkg/providers/jandi/jandi_types.go diff --git a/cmd/integration-test/test-config.yaml b/cmd/integration-test/test-config.yaml index ea83b29..7abf6a0 100644 --- a/cmd/integration-test/test-config.yaml +++ b/cmd/integration-test/test-config.yaml @@ -47,3 +47,7 @@ gotify: gotify_token: "${GOTIFY_APP_TOKEN}" gotify_format: "{{data}}" gotify_disabletls: true +jandi: + - id: "jandi-integration-test" + jandi_webhook_url: "${JANDI_WEBHOOK_URL}" + jandi_format: "{{data}}" diff --git a/pkg/providers/jandi/jandi.go b/pkg/providers/jandi/jandi.go new file mode 100644 index 0000000..c39b673 --- /dev/null +++ b/pkg/providers/jandi/jandi.go @@ -0,0 +1,52 @@ +package jandi + +import ( + "github.com/oriser/regroup" + "github.com/pkg/errors" + "go.uber.org/multierr" + + "github.com/projectdiscovery/gologger" + "github.com/projectdiscovery/notify/pkg/utils" + sliceutil "github.com/projectdiscovery/utils/slice" +) + +var reJandiWebhook = regroup.MustCompile(`(?Phttps?):\/\/(?P(?:ptb\.|canary\.)?Jandi(?:app)?\.com)\/api(?:\/)?(?Pv\d{1,2})?\/webhooks\/(?P\d{17,19})\/(?P[\w\-]{68})`) + +type Provider struct { + Jandi []*Options `yaml:"jandi,omitempty"` + counter int +} + +type Options struct { + ID string `yaml:"id,omitempty"` + JandiWebHookURL string `yaml:"jandi_webhook_url,omitempty"` + JandiFormat string `yaml:"jandi_format,omitempty"` +} + +func New(options []*Options, ids []string) (*Provider, error) { + provider := &Provider{} + + for _, o := range options { + if len(ids) == 0 || sliceutil.Contains(ids, o.ID) { + provider.Jandi = append(provider.Jandi, o) + } + } + + provider.counter = 0 + + return provider, nil +} +func (p *Provider) Send(message, CliFormat string) error { + var errs []error + for _, pr := range p.Jandi { + msg := utils.FormatMessage(message, utils.SelectFormat(CliFormat, pr.JandiFormat), p.counter) + + if err := pr.SendMessage(msg); err != nil { + errs = append(errs, errors.Wrapf(err, "failed to send jandi notification for id: %s ", pr.ID)) + continue + } + + gologger.Verbose().Msgf("jandi notification sent for id: %s", pr.ID) + } + return multierr.Combine(errs...) +} \ No newline at end of file diff --git a/pkg/providers/jandi/jandi_api.go b/pkg/providers/jandi/jandi_api.go new file mode 100644 index 0000000..2b0f239 --- /dev/null +++ b/pkg/providers/jandi/jandi_api.go @@ -0,0 +1,36 @@ +package jandi + +import ( + "bytes" + "encoding/json" + "net/http" + + "github.com/projectdiscovery/notify/pkg/utils/httpreq" +) + +func (options *Options) SendMessage(message string) error { + payload := APIRequest{ + Body: message, + } + + encoded, err := json.Marshal(payload) + if err != nil { + return err + } + + body := bytes.NewReader(encoded) + req, err := http.NewRequest(http.MethodPost, options.JandiWebHookURL, body) + if err != nil { + return err + } + + req.Header.Set("Accept", "application/vnd.tosslab.jandi-v2+json") + req.Header.Set("Content-Type", "application/json") + + _, err = httpreq.NewClient().Do(req) + if err != nil { + return err + } + + return nil +} diff --git a/pkg/providers/jandi/jandi_types.go b/pkg/providers/jandi/jandi_types.go new file mode 100644 index 0000000..d32242d --- /dev/null +++ b/pkg/providers/jandi/jandi_types.go @@ -0,0 +1,11 @@ +package jandi + +type APIRequest struct { + Body string `json:"body"` + ConnectInfo []ConnectInfo `json:"connectInfo,omitempty"` +} + +type ConnectInfo struct { + Title string `json:"title,omitempty"` + Description string `json:"description,omitempty"` +} diff --git a/pkg/providers/providers.go b/pkg/providers/providers.go index f90856c..acfd735 100644 --- a/pkg/providers/providers.go +++ b/pkg/providers/providers.go @@ -15,6 +15,7 @@ import ( "github.com/projectdiscovery/notify/pkg/providers/smtp" "github.com/projectdiscovery/notify/pkg/providers/teams" "github.com/projectdiscovery/notify/pkg/providers/telegram" + "github.com/projectdiscovery/notify/pkg/providers/jandi" "github.com/projectdiscovery/notify/pkg/types" sliceutil "github.com/projectdiscovery/utils/slice" ) @@ -30,6 +31,7 @@ type ProviderOptions struct { GoogleChat []*googlechat.Options `yaml:"googlechat,omitempty"` Custom []*custom.Options `yaml:"custom,omitempty"` Gotify []*gotify.Options `yaml:"gotify,omitempty"` + Jandi []*jandi.Options `yaml:"jandi,omitempty"` } // Provider is an interface implemented by providers @@ -123,6 +125,15 @@ func New(providerOptions *ProviderOptions, options *types.Options) (*Client, err client.providers = append(client.providers, provider) } + if providerOptions.Jandi != nil && (len(options.Providers) == 0 || sliceutil.Contains(options.Providers, "jandi")) { + + provider, err := jandi.New(providerOptions.Jandi, options.IDs) + if err != nil { + return nil, errors.Wrap(err, "could not create jandi provider client") + } + client.providers = append(client.providers, provider) + } + return client, nil }