- Add DD_API_KEY and DD_SITE to Zod validation schema (config.ts)
- Truncate API key before storing in user.id to prevent Sentry leak (auth.middleware.ts)
Import datadog-init as first module to ensure dd-trace .init()
runs before any other imports, fixing P1 auto-instrumentation issue.
Removed redundant manual initDatadog/initSentry calls since
datadog-init.ts already invokes all three init functions.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
P1: Load dd-trace before other modules via datadog-init.ts entry point
P1: Batch all CloudWatch metrics into single PutMetricDataCommand per request
P2: Deduplicate warning logs with else-if for high latency vs error
P3: Add response.ok check to Datadog log forwarding fetch
P3: Update getSentryHub() to use getCurrentScope() for Sentry SDK 8.x
Co-Authored-By: Paperclip <noreply@paperclip.ing>
P1 fixes:
- Fix import paths in background/index.ts (./ -> ../lib/)
- Fix Promise-in-string bug in api-client.ts authenticate()
- Add missing background/service_worker key to manifest
- Copy HTML to public/ so Vite places them in dist
P2 fixes:
- Add notifications permission to manifest
- Make showWarningNotification async with proper await
Co-Authored-By: Paperclip <noreply@paperclip.ing>
P1-1: Replace non-deterministic Math.random() with buffer-variance score
P1-7: Fix findSimilar result ordering by using Map instead of index zip
P2-2: Replace weak hashes with SHA-256 for both embedding and audio
Co-Authored-By: Paperclip <noreply@paperclip.ing>
P3-1: Replace envSchema.parse() with safeParse() + default fallback to
avoid module-level crash when env vars are missing.
P3-3: Add fs.existsSync check on ECAPA_TDNN_MODEL_PATH at startup
with warning log when model path is missing.
P3-4: Add Zod strict() mode to env schema to catch typos in env
var names (extra keys now produce validation errors).
P1-6: Confirmed resolved - voiceprint.service.ts already imports
VoiceEnrollment/VoiceAnalysis from @shieldai/db (consolidated package).
P1-2: Add onRequest auth hook to reject anonymous requests on all 7
VoicePrint endpoints. Previously, the auth middleware always attached
a placeholder user (id='anonymous'), so per-route userId checks passed
for unauthenticated clients.
P1-3: Replace JSON body parsing with @fastify/multipart for POST
/endpoints (/enroll, /analyze, /batch). Fastify JSON parser cannot
produce Buffer from request.body; multipart/form-data is required
for audio file uploads. Added 50MB file size limit.
- Report service: data collection from all three engines, HTML rendering (Handlebars), PDF generation (pdfkit)
- REST API: /reports endpoints for generate, history, view, PDF download, scheduling
- BullMQ workers: queued report generation with retry, monthly/annual scheduler triggers
- DB: SecurityReport model with Prisma schema and type exports
- Email: report_ready template in shared-notifications
- All dependencies wired through existing packages
Co-Authored-By: Paperclip <noreply@paperclip.ing>
- Add ALLOWED_ORIGINS env var with comma-separated origin list
- Validate origins at startup in production: reject wildcards, empty values,
and malformed URLs (non-http/https protocol)
- Update both server entry points (server.ts, index.ts) to use getCorsOrigins()
- Development mode retains existing localhost fallback behavior
Co-Authored-By: Paperclip <noreply@paperclip.ing>
The test mock for spamshield.config was missing defaultScores and
metadataLimits exports that are imported by spamshield.service.ts,
causing 8 tests to fail with 'No defaultScores export is defined'.
Documentation for integration test suite including:
- Test file descriptions and coverage
- External provider mock configuration
- Running tests commands
- CI integration requirements
- Environment variables needed
- Test strategy and error scenarios
Security findings from April 30 review were claimed fixed but never committed.
Applied all remediations:
HIGH:
- WebhookHandler: fail fast when DARKWATCH_WEBHOOK_SECRET missing instead of defaulting to hardcoded secret
- field-encryption.service: require PII_ENCRYPTION_KEY at startup instead of defaulting
MEDIUM:
- WebhookHandler: make signature required (was optional, accepted unsigned events)
- WebhookHandler: reject unknown event types instead of silently defaulting to SCAN_TRIGGER
- scheduler.routes + webhook.routes: add ownership checks on /:userId endpoints (IDOR)
LOW:
- webhook.routes: generic error responses, full error logged server-side
Co-Authored-By: Paperclip <noreply@paperclip.ing>
- Max-length guard (256 chars) on incoming request IDs to prevent log bloat
- Format whitelist (alphanumeric, hyphen, underscore) to prevent log injection
- Replace Math.random() with crypto.randomBytes in fallback for CSPRNG
- Create regex-validation utility with ReDoS detection (nested quantifiers,
overlapping alternations, complexity limits)
- Add @db.VarChar(500) constraint on pattern field in Prisma schema
- Integrate validation in rule-engine at load time and evaluation time
- Add 46 unit tests covering syntax, ReDoS patterns, complexity, edge cases
Co-Authored-By: Paperclip <noreply@paperclip.ing>
- Fix HTML injection vulnerability with proper entity encoding
- Fix rate limit cleanup bug (count vs timestamp confusion)
- Add URL validation to prevent open redirect attacks
- Add expiration to in-memory deduplication entries
- Use Zod schema for config validation
- Add email format validation
All 29 tests passing. Ready for Code Reviewer final review.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
- Add ioredis dependency for Redis connection pooling
- Create RedisService singleton with connection management
- Add Redis config (url, dedupWindowSeconds) to notification.config.ts
- Implement NotificationService.checkRateLimit using Redis INCR+EXPIRE
- Implement NotificationService.deduplicateNotification using Redis SET/NX
- Add configurable rate limit windows and thresholds via env vars
- Add 29 unit tests covering Redis operations, rate limiting, and dedup
- All tests pass, TypeScript compiles cleanly for new files