Skip to content

feat(admin): add GET/PATCH /admin/notifications API - #784

Open
Ferryx349 wants to merge 1 commit into
mainfrom
feat/admin-notifications-api
Open

Ferryx349 wants to merge 1 commit into
mainfrom
feat/admin-notifications-api

Conversation

@Ferryx349

Copy link
Copy Markdown
Collaborator

Description

This PR adds admin HTTP API for operator notifications on top of the backend from #759 / #781:

  • GET /admin/notifications — current admin.notifications config with webhook URLs and tokens redacted
  • PATCH /admin/notifications — update enabled, targets, event toggles, retry policy, and retention; validates like settings; preserves secrets when the client sends *** for url / botToken
  • GET /admin/notifications/deliveries — optional status and eventType query filters (limit validation unchanged)
  • POST /admin/notifications/test — test message text uses the relay name: Test notification from <name|relay_url>

Related Issue

Closes :- #760

Motivation and Context

How Has This Been Tested?

Screenshots (if appropriate):

Types of changes

  • Non-functional change (docs, style, minor refactor)
  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)

Checklist:

  • My code follows the code style of this project.
  • My change requires a change to the documentation.
  • I have updated the documentation accordingly.
  • I have read the CONTRIBUTING document.
  • I have added tests to cover my code changes.
  • I added a changeset, or this is docs-only and I added an empty changeset.
  • All new and existing tests passed.

Expose operator notification config with secret redaction, validated PATCH
updates, delivery log filters, and relay-named test messages. Closes #760.
@changeset-bot

changeset-bot Bot commented Sep 20, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: dc3cbcb

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
nostream Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@greptile-apps

greptile-apps Bot commented Sep 20, 2026

Copy link
Copy Markdown

RetriggerConfidence Score: 4/5

The PR should not merge until unmatched redaction placeholders are rejected instead of being persisted as Telegram credentials.

Findings

  1. P1 Placeholder Becomes Telegram Token
  2. P2 PATCH Behavior Lacks Coverage
Summary

This PR adds authenticated administration APIs for reading and updating operator-notification settings, extends delivery-log filtering, and includes the relay identity in test messages.

  • Adds redacted GET /admin/notifications and validated PATCH /admin/notifications.
  • Adds status and event-type filters to notification delivery history.
  • Preserves redacted credentials for existing target IDs and emits a settings-change event after updates.
  • One credential-placeholder edge case can persist an invalid Telegram token and should be corrected before merge.
Diagram
sequenceDiagram
  participant Admin
  participant Route as Admin Router
  participant Controller as Notifications Controller
  participant Config as Settings Store
  participant Outbox as Notification Outbox

  Admin->>Route: GET /admin/notifications
  Route->>Controller: Authenticated request
  Controller->>Config: Load merged settings
  Config-->>Controller: Notification configuration
  Controller-->>Admin: Redacted configuration

  Admin->>Route: PATCH /admin/notifications
  Route->>Controller: Authenticated JSON body
  Controller->>Config: Load and merge current settings
  Controller->>Controller: Restore stored secrets and validate
  Controller->>Config: Save updated settings
  Controller->>Outbox: Enqueue settings.changed
  Controller-->>Admin: Updated redacted configuration
Loading

Reviews (1) · Last reviewed commit: "feat(admin): add GET/PATCH /admin/notifi..."

Comment on lines +41 to +48
if (existing) {
if (isRedactedSecret(incoming.url) || (incoming.url === undefined && existing.url)) {
merged.url = existing.url
}
if (isRedactedSecret(incoming.botToken) || (incoming.botToken === undefined && existing.botToken)) {
merged.botToken = existing.botToken
}
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Placeholder Becomes Telegram Token

When a new or renamed Telegram target sends the redacted *** value, this code restores the secret only if an existing target has the same ID. Otherwise, it saves *** as the real bot token because validation only checks that the token is non-empty. The update succeeds, but later Telegram test and notification deliveries fail with unusable credentials. Reject the placeholder when there is no matching stored secret.

Comment on lines +31 to +36
const validation = validateSchema(adminNotificationsPatchBodySchema)(request.body)
if (validation.error) {
response.status(400).setHeader('content-type', 'application/json').send({ error: 'Invalid request' })
return
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 PATCH Behavior Lacks Coverage

This new write endpoint has no controller-level tests for request validation, persistence, redacted-secret round trips, or outbox failures. The added merge test covers only an existing Discord target, so cases such as a new Telegram target receiving *** are not protected against regressions. As a non-blocking improvement, add PATCH controller tests for valid partial updates, invalid bodies, new and existing secret-bearing targets, and enqueue failures.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

@coveralls

Copy link
Copy Markdown
Collaborator

Coverage Status

coverage: 72.076% (-0.3%) from 72.378% — feat/admin-notifications-api into main

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants