Skip to content

Fix #255 #264 #265 #267: tax export, webhook retries, savings validation, SEP-24 HMAC#272

Merged
davedumto merged 2 commits intodavedumto:mainfrom
josephchimebuka:feat/issues-255-264-265-267
Feb 26, 2026
Merged

Fix #255 #264 #265 #267: tax export, webhook retries, savings validation, SEP-24 HMAC#272
davedumto merged 2 commits intodavedumto:mainfrom
josephchimebuka:feat/issues-255-264-265-267

Conversation

@josephchimebuka
Copy link
Contributor

Fix #255 #264 #265 #267: Tax export crash, webhook retries, savings validation, SEP-24 callback security

Summary

This PR resolves 4 issues in one cohesive update focused on reliability, security, and data integrity:

What Changed

1) Webhook Retry Reliability (#264)

  • Upgraded webhook retry workflow to a 7-attempt schedule:
    • Immediate, +1m, +5m, +15m, +1h, +6h, +24h
  • Marks delivery as failed after max retries.
  • Preserved manual retry flow for failed/pending deliveries.
  • Added cron compatibility route:
    • GET /api/cron/process-webhook-retries
  • Updated Vercel cron schedule to run every 5 minutes.
  • Added developer delivery logs endpoint:
    • GET /api/routes-d/developers/webhooks/[id]/deliveries
  • Added auto-disable behavior for webhook endpoints after 10 consecutive failures.

2) Tax Export Null-Date Crash (#255)

  • Prevented null completedAt records from entering tax report datasets.
  • Added defensive CSV fallback (UNKNOWN_DATE) to avoid runtime crashes if malformed records appear.
  • Applied fix in shared tax query + export/annual routes.

3) Savings Percentage Validation Hardening (#265)

  • Extracted reusable validator:
    • validateTotalSavingsPercentage(...)
  • Reused validator across both goal creation and goal reactivation flows.
  • Ensures active in-progress goals cannot exceed 50% aggregate allocation.
  • Updated tests to cover consistent validation behavior.

4) SEP-24 Callback Security (#267)

  • Added lib/sep24-webhook-verify.ts:
    • HMAC-SHA256 verification
    • timing-safe comparison
    • timestamp freshness check (replay protection window)
    • per-anchor secret resolution (Yellow Card / MoneyGram)
  • Added secure callback endpoint:
    • POST /api/webhooks/sep24?anchor=...
  • Supports normalized anchor matching for yellow-card/yellowcard.
  • Added helper script for generating test signatures.
  • Added unit tests for signature verification and replay defense.

Key Files

  • lib/webhooks.ts
  • app/api/cron/retry-webhooks/route.ts
  • app/api/cron/process-webhook-retries/route.ts
  • app/api/routes-d/developers/webhooks/[id]/deliveries/route.ts
  • app/api/routes-d/tax-reports/_shared.ts
  • app/api/routes-d/tax-reports/export/route.ts
  • app/api/routes-d/tax-reports/annual/route.ts
  • app/api/routes-d/savings/_shared.ts
  • app/api/routes-d/savings/goals/route.ts
  • app/api/routes-d/savings/goals/[id]/route.ts
  • lib/sep24-webhook-verify.ts
  • app/api/webhooks/sep24/route.ts
  • scripts/generate-sep24-test-signature.ts
  • tests/lib/sep24-webhook-verify.test.ts
  • tests/savings-goals-logic.test.ts
  • vercel.json

Validation Performed

  • Focused tests:
    • tests/savings-goals-logic.test.ts
    • tests/lib/sep24-webhook-verify.test.ts
  • Broader non-DB tests:
    • npx vitest run --exclude tests/lib/authorization.test.ts
  • Build:
    • NEXT_DISABLE_TURBOPACK=1 npm run build
  • Lint:
    • npm run lint (warnings only; no new blocking errors)

Notes

  • DB-dependent suite (tests/lib/authorization.test.ts) requires DATABASE_URL in CI/runtime.
  • Existing unrelated local modifications (middleware.ts, next.config.ts, package.json) are intentionally not included in this PR.

Closes #255
Closes #264
Closes #265
Closes #267

@vercel
Copy link

vercel bot commented Feb 26, 2026

@josephchimebuka is attempting to deploy a commit to the david's projects Team on Vercel.

A member of the Team first needs to authorize it.

@davedumto davedumto merged commit e47cc6e into davedumto:main Feb 26, 2026
2 of 3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants