Skip to content

Pushover integrations from the dashboard never deliver: form, sender and encryption use different setting keys #494

Description

@fclairamb

Summary

A Pushover integration created from the dashboard can never deliver.
Three layers each use their own names for the same two settings:

Layer File User key API token
Dashboard form (writes) web/dash0/src/components/integrations/integration-form.tsx (ch-pushover-user / ch-pushover-token) user token
Sender (reads) server/internal/notifications/pushover.go (pushoverSettings) userKey apiToken
Secret encryption list server/internal/crypto/credentials/conn_secrets.go user_key api_token

Two consequences:

  1. Delivery always fails. parseSettings finds apiToken empty and
    returns ErrPushoverAPITokenNotConfigured before any network call. That
    affects every "Send test" and every real incident notification routed to
    that integration.
  2. The credentials are stored in plaintext. Neither user nor token is
    in the encryption list, so they land in integrations.settings instead of
    settings_private.

Seen in production

A new user created a Pushover integration and pressed Send test about 25
times over 10 minutes. PostHog recorded 3 $rageclick on that button. In
between they re-entered the token, toggled Enabled and Default
off and on, deleted the integration and recreated it twice. All three rows in
prod have settings keys user,token, with an empty settings_private_keys.
The one test request still in the logs completed in 6.7 ms, which is too
fast to have reached api.pushover.net, so it failed on the missing-key path.
The user then left (and later deleted their organization).

Every Pushover integration in prod has this shape, so the type has never
worked from the dashboard.

Proposed fix

  1. Pick one canonical pair. The encryption list's user_key / api_token
    matches the snake_case of other secret settings (api_key, app_token,
    routing_key). Use it in the form, the sender and the docs
    (web/docs/docs/configuration/notifications.md § Pushover).
  2. Make the sender tolerant during the transition. Read the canonical keys and
    fall back to user/token and userKey/apiToken, so existing rows work
    before the migration runs.
  3. Add a migration that renames the keys on existing pushover rows and moves
    the secrets into settings_private (encrypted), so nothing stays in
    plaintext.
  4. Check the user-level Pushover contact (models/user_contact.go) and the
    escalation-step sender (jobtypes/job_escalation_step.go) for the same
    drift.
  5. Add a guard test: for every integration type, the keys the dashboard form
    writes must cover what the sender requires, and every secret field the form
    writes must be in conn_secrets.go. This class of drift should fail CI, not
    a customer.

Separate UX gap seen in the same session

The test result badge tells the user it failed, but nothing pointed at why
in a way they could act on: they kept retyping a token that was correct.
Once (1) is fixed this goes away for Pushover. Still, a "not configured" error
from the sender should be shown as a configuration bug ("this integration is
missing its API token"), not as a delivery failure.

Acceptance

  • Create Pushover from the dashboard, then Send test: a push arrives, and
    the badge says delivered.
  • The settings row has no user/token in clear; settings_private_keys
    lists both.
  • Existing rows are migrated, and the CI guard test fails if a form and its
    sender drift again.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions