Skip to content

Fix/open source issuesfix(auth): verify challenge nonces, use configurable network passphrase, and bound /api/routes results - #234

Merged
wagmiiii merged 23 commits into
accensa:mainfrom
Ojukwu-Chinedu:fix/open-source-issues
Aug 26, 2026
Merged

Fix/open source issuesfix(auth): verify challenge nonces, use configurable network passphrase, and bound /api/routes results#234
wagmiiii merged 23 commits into
accensa:mainfrom
Ojukwu-Chinedu:fix/open-source-issues

Conversation

@Ojukwu-Chinedu

Copy link
Copy Markdown
Contributor

Closes #221
Closes #222
Closes #224
What changed

  • closes /api/auth/verify never checks the challenge it issued, so any merchant-signed transaction logs in #221 — Auth verify never checks the challenge it issued
  • Added a challenge_nonces table to lib/db.ts with nonce, issued_at, and consumed columns
  • Added storeNonce(), consumeNonce(), and sweepExpiredNonces() helper functions
  • /api/auth/challenge now persists the issued nonce to the database and sweeps expired nonces on each call
  • /api/auth/verify now verifies the transaction contains exactly one manageData operation with key Accensa Auth, extracts the nonce, and consumes it — preventing replay of unrelated signed transactions and double-use of the same challenge
  • Added 9 tests for verify and 4 tests for challenge covering: valid auth, wrong structure, unknown nonce, replay, expiry, wrong network passphrase, and missing config
    closes Both auth routes hardcode Networks.TESTNET, so the dashboard cannot authenticate on pubnet #222 — Both auth routes hardcode Networks.TESTNET
  • Replaced Networks.TESTNET literals with a networkPassphrase() getter that reads STELLAR_NETWORK_PASSPHRASE at runtime (falling back to testnet)
  • Same pattern used in both /api/auth/challenge and /api/auth/verify
  • Documented STELLAR_NETWORK_PASSPHRASE in DEPLOYMENT.md's environment table
  • Confirmed all other Networks. references in receipt-anchor.ts, refund-vault.ts, and refund-submit.ts already read from env vars
    closes /api/routes aggregates the whole payments table with no limit or pagination #224 — /api/routes aggregates the whole payments table with no limit or pagination
  • Added a limit parameter (default 50, max 200) following the /api/payments validation pattern
  • Added a default 30-day time window when no from/to is provided, so the aggregate no longer scans the full table on every dashboard load
  • When results exceed the limit, the tail is rolled into an aggregated (other) row so totals remain correct
  • Response now includes truncated (boolean) and default_window_days (number or null) metadata
    closes apps/indexer and apps/demo contain nothing but node_modules #225 — Uses the existing idx_payments_ts index for the windowed query
  • Added 10 tests covering: default limit, truncation with (other) row, limit validation, time window defaults, custom from/to, and missing config
    Files changed
    File Change
    apps/web/src/lib/db.ts Add challenge_nonces table + nonce store/consume/sweep helpers
    apps/web/src/app/api/auth/challenge/route.ts Persist nonce, use configurable passphrase
    apps/web/src/app/api/auth/verify/route.ts Verify operation structure, consume nonce, use configurable passphrase
    apps/web/src/app/api/auth/challenge/route.test.ts New — 4 tests for challenge endpoint
    apps/web/src/app/api/auth/verify/route.test.ts New — 9 tests for verify endpoint
    apps/web/src/app/api/routes/route.ts Add limit, default time window, (other) aggregation row
    apps/web/src/app/api/routes/route.test.ts New — 10 tests for routes endpoint
    DEPLOYMENT.md Document STELLAR_NETWORK_PASSPHRASE env var
    Verification
  • All 221 tests pass (pnpm --filter web test)
  • Build succeeds (pnpm --filter web build)
  • Lint passes (0 errors, only pre-existing warnings)

Adds database schema and helper functions for persisting auth challenge
nonces. This is part of the SEP-10-style challenge/response flow
(accensa#221) where nonces must be stored server-side to prevent replay of
unrelated signed transactions.
- Persist nonces to the database so verify can confirm they were issued
  here and have not been consumed (accensa#221)
- Replace hardcoded Networks.TESTNET with STELLAR_NETWORK_PASSPHRASE env
  var, read at runtime to support pubnet deployments (accensa#222)
- Sweep expired nonces opportunistically on each challenge issuance
- Verify the transaction contains exactly one manageData operation with
  key 'Accensa Auth' (accensa#221)
- Consume the nonce on first successful use, rejecting replays (accensa#221)
- Replace hardcoded Networks.TESTNET with configurable passphrase (accensa#222)
- Reject transactions with extra operations or wrong data key
Tests that the challenge endpoint:
- Returns a valid XDR and the configured network passphrase
- Defaults to testnet when STELLAR_NETWORK_PASSPHRASE is unset
- Persists the nonce to the database
- Returns 500 when MERCHANT_ADDRESS is not configured
Tests that the verify endpoint:
- Accepts a valid challenge and issues a session
- Rejects transactions with no manageData operation
- Rejects transactions with multiple operations
- Rejects challenges with unknown nonces
- Rejects replayed challenges (replay protection)
- Rejects expired challenges
- Uses the configured network passphrase
Add the new optional environment variable to the deployment docs so
operators know how to configure pubnet authentication (accensa#222).
- Default limit of 50 groups (max 200), following /api/payments pattern
- Default 30-day time window to prevent full-table scans on every load
- Aggregated (other) row for the tail when results are truncated
- Returns truncated flag and default_window_days in response
- Uses existing idx_payments_ts index for the windowed query
Tests that the endpoint:
- Returns routes with default limit of 50
- Truncates results and adds (other) row when exceeding limit
- Validates limit bounds (1-200)
- Applies default 30-day window when no from/to given
- Respects custom from/to parameters
- Returns 500 when DATABASE_URL is missing
@drips-wave

drips-wave Bot commented Aug 25, 2026

Copy link
Copy Markdown

@Ojukwu-Chinedu Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

@vercel

vercel Bot commented Aug 25, 2026

Copy link
Copy Markdown

@Ojukwu-Chinedu is attempting to deploy a commit to the ACCENSA Team on Vercel.

A member of the Team first needs to authorize it.

@wagmiiii
wagmiiii self-requested a review August 25, 2026 19:56
@wagmiiii
wagmiiii merged commit f752669 into accensa:main Aug 26, 2026
6 of 8 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