Guard against nil result before accessing result.Error in processNotification,
and add NtfyNotifier.Validate override so DefaultTopic is considered before
rejecting notifications with zero recipients.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Use typed context key for auth context to prevent collisions (auth.go)
- Eliminate nested locking in CheckRateLimit to prevent potential deadlock (auth.go)
- Add 1MB request body size limit middleware to prevent DoS (router.go)
- Return proper gRPC status codes instead of nil errors on failures (handler.go)
- Use key name instead of raw API key in admin URL paths to prevent secret leakage (keys.go, router.go, keystore_db.go, keystore_hybrid.go)
- Enforce RBAC authorization in service Send/SendBatch for both REST and gRPC (service.go)
- Pin runtime Docker image to alpine:3.21 for reproducible builds (Dockerfile)
- Enable readOnlyRootFilesystem with /tmp emptyDir in k8s deployment (deployment.yaml)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Normalize content_type to lowercase before processing to handle case-insensitive input (e.g., "HTML", "Html")
- Add validation in Validate() to ensure only valid content types are accepted
- Return descriptive error message if invalid content type is provided
- Fix condition in ToNotification() to properly detect and default content type
- Update SMTP notifier auto-detection to work correctly when content type is not explicitly set
Issues fixed:
1. Dynamically detecting content type now works correctly (was always defaulting to "text")
2. Client can now specify content type in request as "HTML", "html", or "Html" - all work
3. Invalid content types are rejected with clear error messages
4. Auto-detection still works if neither explicit type nor valid HTML markers are found
Example scenarios:
- No content_type field: auto-detects based on body (checks for <, <html, <!DOCTYPE, <p>, <div>, <br>)
- content_type: "html": sends as HTML with multipart/alternative
- content_type: "HTML": normalized to "html", sends as HTML
- content_type: "invalid": returns validation error
- content_type: "text": explicitly sends as plain text, skips auto-detection
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Change IsAuthorized() to use deny-by-default when RBAC is enabled
- If ANY authorization rules are configured, only notifiers with explicit allowed_roles are accessible
- Notifiers without rules are denied access when RBAC is active
- If NO rules are configured, maintain open access for backward compatibility
- Add HasRules() helper method to check if RBAC is enabled
This fixes the issue where notifiers WITHOUT allowed_roles were being returned instead of
the notifiers WITH matching allowed_roles. Now when RBAC is configured:
- Only notifiers with explicit rules that match the user's roles are returned
- All other notifiers are hidden from the client
Example: If only email has allowed_roles=['admin'] and user has role 'admin':
- OLD: email ✓, stdout ✓ (WRONG - stdout should be hidden)
- NEW: email ✓, stdout ✗ (CORRECT - only email is returned)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add SanitizeDatabaseURL() function to config package that redacts passwords from database connection URLs
- Handles various URL formats: postgresql, mysql, etc.
- Correctly handles passwords containing special characters including @ symbols by using LastIndex
- Update startup logging in cmd/server/main.go to use sanitized database URL
- Add comprehensive tests covering various URL formats and edge cases
This ensures sensitive database credentials are not exposed in application logs.
- Add LDFLAGS_BASE for version info only, LDFLAGS for production (with -s -w optimization), and LDFLAGS_DEV for development
- Create 'build' target (production) that strips symbols, reducing binary size by ~30% (56MB -> 39MB)
- Create 'build-dev' target (development) that keeps debug symbols for profiling
- Update 'docker-build' to pass BUILD_FLAGS="-s -w" for optimized production images
- Create 'docker-build-dev' target that builds development images with notifier:latest-dev tag and no optimization
- Update Dockerfile to accept and use BUILD_FLAGS argument in build stage
- All targets now clearly indicate their optimization level in output messages
After conflict resolution from rebase, some imports were accidentally
removed and the CORS middleware function was eliminated but still
referenced by tests. This commit:
- Adds fmt import to api/rest/keys.go (used for error messages)
- Adds gorilla/mux import to cmd/server/main.go (used for router type)
- Restores newCORSMiddleware function to api/rest/router.go for test compatibility
- Formats code with gofmt
The Docker build was failing because protobuf-generated code wasn't
available during compilation. Changes made:
- Added protoc and protobuf-dev packages to build dependencies
- Installed protoc-gen-go and protoc-gen-go-grpc plugins
- Added make proto-gen step to generate pb files before build
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Add comprehensive improvements across REST and gRPC APIs:
- Add structured logging for all notification operations
- Implement HTML email support with multipart/alternative MIME
- Add CC and BCC recipient support for email notifications
- Add GetNotifiers endpoint to query available notifier configurations
- Support configurable From name in SMTP configuration
- Auto-detect content type (text vs HTML) in notification bodies
- Improve error handling and validation across all endpoints
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>