16 Commits

Author SHA1 Message Date
igodwin eda033ff9b fix: clear golangci-lint backlog and make lint job blocking
CI / Lint (push) Successful in 2m29s
Build and Publish Container / build-and-publish (push) Successful in 2m58s
CI / Vulnerability scan (push) Successful in 44s
CI / Test (push) Successful in 1m45s
Addresses errcheck, gosec, revive, staticcheck, and unused findings
across the codebase (unchecked error returns, unsafe file inclusion
warnings on operator/test-controlled paths, missing package comments,
unused parameters, deprecated API usage). Also fixes two suppression
comments that were silently no-ops due to wrong syntax (#nosec needs
a leading '#', nolint reasons need '//' not '--').

With the backlog clear, drop continue-on-error from the CI lint job
per the plan left in b4b4806.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-18 10:32:51 -07:00
igodwin ee82522b7c feat(rest,config): wire CORS, real readiness, TLS options, error hygiene
- CORS config is now actually applied to the router (the middleware
  existed but was never wired); preflight returns 204 for allowed
  origins and 403 with no CORS headers for disallowed ones.
- /readyz runs real dependency checks (queue, auth database) and
  returns 503 with per-component detail when not ready; exported
  handlers support dedicated health listeners.
- Optional server.tls (cert_file/key_file) for REST and gRPC, validated
  at config load.
- 5xx responses no longer echo internal error details; not-found and
  already-sent map to 404/409 on cancel/retry.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-18 09:15:57 -07:00
igodwin 172c240d1b fix(auth): repair persistence layer and stop storing plaintext keys
- Store SHA-256 digests (key_hash + key_preview) instead of raw keys, in
  both the in-memory store and Postgres; migrate legacy plaintext rows in
  place and drop the plaintext column.
- Fix TEXT[] scans that failed at runtime (missing pq.Array) in
  GetKey/ListKeys/LoadAllKeys.
- Load persisted keys at startup (InitializeFromDatabase was never called)
  and fall back to the database on cache miss, so issued keys survive
  restarts.
- Make HybridKeyStore.CreateKey genuinely write-through: cache is only
  updated after a successful DB write.
- Guard nil database backend (auth enabled without DB previously panicked
  on key creation) and degrade to in-memory operation.
- Persist bootstrap admin keys when a database is configured.
- Record real audit-log details as JSON and log audit failures instead of
  silently dropping them; add DB pool limits and ping timeout.
- Sentinel errors matched with errors.Is; unit tests for hashing,
  write-through ordering, DB fallback, and nil-DB operation.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-17 20:27:49 -07:00
igodwin ac3ba35736 Add html_body field for multipart email notifications
Callers can now supply a plain-text Body alongside an HTML html_body;
the SMTP sender emits multipart/alternative using both verbatim instead
of auto-stripping HTML to derive the plain-text fallback. The legacy
content_type=HTML path is preserved (deprecated) for existing callers.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-06 23:59:12 -07:00
igodwin 298c960808 Fix 8 high-severity audit findings across security, Go, API, and container domains
- 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>
2026-03-26 20:17:51 -07:00
igodwin 71b02758d7 Fix HTML content type handling with case-insensitive validation
- 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>
2025-10-31 01:49:38 -07:00
igodwin 56bfcb59d3 Fix missing imports and restore CORS middleware for tests
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
2025-10-30 23:47:53 -07:00
igodwin 81d11e01bb Further auth and authz configuration 2025-10-30 23:35:28 -07:00
igodwin 9a43af27ad Implement secure CORS configuration system 2025-10-30 22:28:03 -07:00
igodwin abe7b6beee Refactor auth and authz 2025-10-26 02:25:24 -07:00
igodwin a3365c303a Add API token auth and issues doc 2025-10-25 22:19:45 -07:00
igodwin 35b6c8aed3 Enhance notification APIs with HTML email support, CC/BCC, and structured logging
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>
2025-10-22 23:31:32 -07:00
igodwin 8229944149 Change logging and implement gRPC 2025-10-18 23:12:25 -07:00
igodwin eb9e107f65 Add support for multiple instances of the same notifier type 2025-10-17 16:39:33 -07:00
igodwin 9087a710e5 Basic impl added 2025-10-16 21:22:51 -07:00
igodwin 46d3b66feb Add basic project layout 2024-11-01 19:36:58 -07:00