diff --git a/deploy/app/webhooked/base/configmap.yaml b/deploy/app/webhooked/base/configmap.yaml
index 07a8b68f..45788497 100644
--- a/deploy/app/webhooked/base/configmap.yaml
+++ b/deploy/app/webhooked/base/configmap.yaml
@@ -178,5 +178,4 @@ data:
envRef: RABBITMQ_DATABASE_URL
queueName: webhooks-deliveries
contentType: application/json
- durable: true
- exchange: delayed
\ No newline at end of file
+ durable: true
\ No newline at end of file
diff --git a/internal/webhooks/serve.go b/internal/webhooks/serve.go
index 79ca2db7..5030bf3a 100644
--- a/internal/webhooks/serve.go
+++ b/internal/webhooks/serve.go
@@ -108,18 +108,33 @@ func (p *processor) Serve(amqpUrl, channel string) error {
return nil
}
+// metadataWebhooked is the structure of the webhook metadata sent by the
+// webhooked project formatted following this schema:
+type metadataWebhooked struct {
+ Metadata struct {
+ // For duoapi webhooks the strcut is the type of the object with additionnal
+ // fields
+ duoapi.WebhookMetadata
+ // SpecName represents the spec name on wehooked configuration.
+ // Internally usage only.
+ SpecName string `json:"specName"`
+ } `json:"metadata"`
+ //Payload
+ Payload map[string]interface{} `json:"payload"`
+}
+
// handler is the main function that processes the webhooks. It parses the
// webhook metadata and calls the appropriate processor function.
// This function is called by the Serve function on each incoming message.
func (p *processor) handler(data []byte) error {
- md := &duoapi.Webhook{}
+ md := &metadataWebhooked{}
if err := json.Unmarshal(data, &md); err != nil {
log.Error().Err(err).Msg("Failed to unmarshal webhook metadata")
}
- if md == nil || md.Metadata == nil {
- log.Error().Str("payload", string(data)).Msg("Webhook metadata is nil")
+ if md == nil || md.Metadata.SpecName == "" {
+ log.Error().Str("payload", string(data)).Msg("Webhook metadata is invalid")
return ErrInvalidWebhook
}
log.Debug().Msgf("Received a message(%s.%s): %+v", md.Metadata.Model, md.Metadata.Event, md.Payload)
@@ -130,21 +145,10 @@ func (p *processor) handler(data []byte) error {
return p.githubHandler(data)
}
- var err error
- switch md.Metadata.Model {
- case "location":
- err = md.Payload.ProcessWebhook(p.ctx, md.Metadata, &locationProcessor{processor: p})
- case "user":
- err = md.Payload.ProcessWebhook(p.ctx, md.Metadata, &userProcessor{processor: p})
- }
- if err != nil {
- log.Error().Err(err).Str("model", md.Metadata.Model).Str("event", md.Metadata.Event).Msg("Failed to process webhook")
- return err
- }
-
- return nil
+ return p.duoHandler(data)
}
+// githubHandler is the processor for the github webhooks.
func (p *processor) githubHandler(data []byte) error {
webhookPayload := &GithubSponsorshipWebhook{}
if err := json.Unmarshal(data, &webhookPayload); err != nil {
@@ -177,8 +181,7 @@ func (p *processor) githubHandler(data []byte) error {
var flagsList = user.FlagsList
switch webhookPayload.Action {
- case "created":
- case "edited":
+ case "created", "edited":
if webhookPayload.Sponsorship.Tier.MonthlyPriceInDollars >= 5 {
flagsList = append(flagsList, typesgen.FlagBeta.String(), typesgen.FlagDiscord.String())
}
@@ -191,6 +194,28 @@ func (p *processor) githubHandler(data []byte) error {
)
}
- _, err = p.db.User.UpdateOne(user).SetFlagsList(flagsList).Save(p.ctx)
+ _, err = p.db.User.UpdateOne(user).SetFlagsList(utils.Uniq(flagsList)).Save(p.ctx)
return err
}
+
+// duoHandler is the processor for the duo webhooks.
+func (p *processor) duoHandler(data []byte) error {
+ mdDuo := &duoapi.Webhook{}
+ if err := json.Unmarshal(data, &mdDuo); err != nil {
+ log.Error().Err(err).Msg("Failed to unmarshal webhook metadata")
+ }
+
+ var err error
+ switch mdDuo.Metadata.Model {
+ case "location":
+ err = mdDuo.Payload.ProcessWebhook(p.ctx, mdDuo.Metadata, &locationProcessor{processor: p})
+ case "user":
+ err = mdDuo.Payload.ProcessWebhook(p.ctx, mdDuo.Metadata, &userProcessor{processor: p})
+ }
+ if err != nil {
+ log.Error().Err(err).Str("model", mdDuo.Metadata.Model).Str("event", mdDuo.Metadata.Event).Msg("Failed to process webhook")
+ return err
+ }
+
+ return nil
+}
diff --git a/pkg/duoapi/webhooks.go b/pkg/duoapi/webhooks.go
index 5f7c047b..f085cfcc 100644
--- a/pkg/duoapi/webhooks.go
+++ b/pkg/duoapi/webhooks.go
@@ -42,9 +42,6 @@ type IWebhookPayload interface {
// This informations is sended originally by the 42 API on the Header of the
// webhook.
type WebhookMetadata struct {
- // SpecName represents the spec name on wehooked configuration.
- // Internally usage only.
- SpecName string `json:"specName"`
// Event is the event that triggered the webhook. (Header: X-Event)
// Possible values are listed on the interface {Model}WebhookProcessor.
Event string `json:"event"`
diff --git a/pkg/utils/slice.go b/pkg/utils/slice.go
index 6049b026..ecd55737 100644
--- a/pkg/utils/slice.go
+++ b/pkg/utils/slice.go
@@ -19,3 +19,16 @@ func Contains[T comparable](slice []T, item T) bool {
}
return false
}
+
+// Uniq returns a new slice with unique items from the given slice
+func Uniq[T comparable](slice []T) []T {
+ var unique []T
+ for _, element := range slice {
+ if Contains(unique, element) {
+ continue
+ }
+
+ unique = append(unique, element)
+ }
+ return unique
+}
diff --git a/web/ui/package.json b/web/ui/package.json
index 38a66087..7401733a 100644
--- a/web/ui/package.json
+++ b/web/ui/package.json
@@ -30,8 +30,8 @@
"@apollo/react-hooks": "^4.0.0",
"@grpc/grpc-js": "^1.6.7",
"@headlessui/react": "^1.6.4",
- "@sentry/nextjs": "^7.4.1",
- "@sentry/tracing": "^7.4.1",
+ "@sentry/nextjs": "^7.7.0",
+ "@sentry/tracing": "^7.7.0",
"axios": "^0.26.1",
"classnames": "^2.3.1",
"google-protobuf": "^3.20.1-rc.1",
@@ -70,8 +70,8 @@
"@types/google-protobuf": "^3.15.6",
"@types/node": "17.0.33",
"@types/react": "^18.0.5",
- "@typescript-eslint/eslint-plugin": "^5.27.1",
- "@typescript-eslint/parser": "^5.23.0",
+ "@typescript-eslint/eslint-plugin": "^5.30.6",
+ "@typescript-eslint/parser": "^5.30.6",
"autoprefixer": "^10.4.7",
"babel-jest": "^28.1.0",
"babel-loader": "^8.2.3",
diff --git a/web/ui/sentry.client.config.ts b/web/ui/sentry.client.config.ts
index ff04cbd7..40f2b718 100644
--- a/web/ui/sentry.client.config.ts
+++ b/web/ui/sentry.client.config.ts
@@ -13,6 +13,7 @@ if (process.env.NODE_ENV && process.env.NODE_ENV !== 'development') {
integrations: [new BrowserTracing()],
// Adjust this value in production, or use tracesSampler for greater control
tracesSampleRate: process.env.NODE_ENV === 'production' ? 0.2 : 0,
+ sampleRate: 1,
// ...
// Note: if you want to override the automatic release value, do not set a
// `release` value here - use the environment variable `SENTRY_RELEASE`, so
diff --git a/web/ui/sentry.server.config.ts b/web/ui/sentry.server.config.ts
index f6a9614e..1fc8e8e9 100644
--- a/web/ui/sentry.server.config.ts
+++ b/web/ui/sentry.server.config.ts
@@ -13,6 +13,7 @@ if (process.env.NODE_ENV && process.env.NODE_ENV !== 'development') {
integrations: [new BrowserTracing()],
// Adjust this value in production, or use tracesSampler for greater control
tracesSampleRate: process.env.NODE_ENV === 'production' ? 0.2 : 0,
+ sampleRate: 1,
// ...
// Note: if you want to override the automatic release value, do not set a
// `release` value here - use the environment variable `SENTRY_RELEASE`, so
diff --git a/web/ui/src/components/Sidebar/Sidebar.tsx b/web/ui/src/components/Sidebar/Sidebar.tsx
index cbc1f055..b890f69c 100644
--- a/web/ui/src/components/Sidebar/Sidebar.tsx
+++ b/web/ui/src/components/Sidebar/Sidebar.tsx
@@ -113,6 +113,11 @@ export const Sidebar = ({
+
{
+ return (
+
+
+
+
+ Under construction
+
+
+ This part is not developed yet. Will be available during the beta phase.{' '}
+
+ You can help us by contributing to the idea on Discord.
+
+
+ Talk about it on Discord
+
+
You have unlocked a new feature!
@@ -56,30 +53,43 @@ const SponsorGithubPart = ({
)}
- );
- }
- return (
-
-
+
- Get early-access to the Discord by becoming a sponsor
+ {(hasSponsored && 'You have the power !') ||
+ 'Get early-access to the beta by becoming a sponsor'}
-
+
- Becoming a sponsor means access to the Discord, to the code, to the beta
+ Becoming a sponsor means access to the beta and the code
and to participate in new features before anyone else!
-
- Sponsor on Github
-
+ {(hasSponsored && (
+
+
+ Go to the future
+
+
+ )) || (
+
+ Sponsor on Github
+
+ )}
+
After sponsoring come back on this page, refresh and see
@@ -178,14 +188,14 @@ interface PageProps {
}
export const IndexPage: NextPage = ({ me }) => {
- const hasDiscordAccess = me.flags?.some((f) => f === Flag.DISCORD);
+ const hasSponsored = me.flags?.some((f) => f === Flag.SPONSOR);
let currentStep =
(me.accounts?.filter(
(a) => a?.provider === Provider.GITHUB || a?.provider === Provider.DISCORD
).length || 0) + 1;
- if (currentStep == 3 && hasDiscordAccess) currentStep = 4;
+ if (currentStep == 3 && hasSponsored) currentStep = 4;
if (!me) {
return <>OUPS>;
@@ -270,7 +280,7 @@ export const IndexPage: NextPage = ({ me }) => {