Security/admin endpoints - #645
Merged
nonsobethel0-dev merged 3 commits intoSep 28, 2026
Merged
Conversation
…update related tests
…th JSON and NDJSON responses
|
@Nursca 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! 🚀 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
About this PR
Summary
Admin endpoints not gated (security) — PolicyController admin routes (register/update/remove product) accepted any operator token. Added AdminRoleGuard (src/auth/admin-role.guard.ts) requiring an admin role claim or ADMIN_API_KEY; ORACLE_OPERATOR_API_KEY accepted only when ADMIN_API_KEY is unset, and the guard fails closed. OperatorAuthGuard now records authVia/apiKeySource. Docs/.env.example updated.
WebhooksService uses Math.random() for webhook IDs (Low) — not reproducible. No generateWebhookId exists now or anywhere in history; the Math.random() ID pattern only lived in the original in-memory version (removed by Stellar network health check, idempotency locking, persisted webhooks, crypto import #502/[security] Webhook registrations stored in-memory, lost on restart #482). IDs come from Prisma @default(uuid()), generated client-side with crypto.randomUUID(). Remaining Math.random() uses are retry/batch jitter only. No code change.
X-Total-Count missing on non-streaming responses (Low) — pagination headers were only set on the NDJSON path. StreamingInterceptor now applies X-Total-Count/X-Page/X-Limit on both paths (new applyPaginationHeaders), including total: 0. New spec: 6 tests.
No rate limit on webhook registration (Medium) — global throttler already covered the route at 60/min, but registrations had no tighter window. Added @Throttle({ limit: 10, ttl: 60000 }) on POST /webhooks/register (per-wallet with JWT, per-IP otherwise) + documented 429. New spec drives a real ThrottlerGuard: 10 OK / 11th → 429.
Verification: tsc --noEmit unchanged at 26 pre-existing errors (none in touched files); jest 21 failed / 28 passed — same 21 baseline-broken suites, +2 new passing suites.
Issue Closure
This PR closes the following issues using GitHub keyword syntax: